2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)
3 * Copyright (C) 2011 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
11 * Jalview is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty
13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along with Jalview. If not, see <http://www.gnu.org/licenses/>.
20 import java.awt.Rectangle;
22 import java.lang.reflect.InvocationTargetException;
25 import java.util.Map.Entry;
26 import java.util.jar.*;
30 import org.exolab.castor.xml.*;
32 import uk.ac.vamsas.objects.utils.MapList;
33 import jalview.bin.Cache;
34 import jalview.datamodel.Alignment;
35 import jalview.datamodel.AlignmentAnnotation;
36 import jalview.datamodel.AlignmentI;
37 import jalview.datamodel.SequenceI;
38 import jalview.schemabinding.version2.*;
39 import jalview.schemes.*;
40 import jalview.structure.StructureSelectionManager;
41 import jalview.util.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.alignment;
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.alignment.getHiddenSequences().isHidden(jds));
505 if (av.hiddenRepSequences != null
506 && av.hiddenRepSequences.containsKey(jal.getSequenceAt(i)))
508 jalview.datamodel.SequenceI[] reps = ((jalview.datamodel.SequenceGroup) av.hiddenRepSequences
509 .get(jal.getSequenceAt(i))).getSequencesInOrder(jal);
511 for (int h = 0; h < reps.length; h++)
513 if (reps[h] != jal.getSequenceAt(i))
515 jseq.addHiddenSequences(jal.findIndex(reps[h]));
521 if (jds.getDatasetSequence().getSequenceFeatures() != null)
523 jalview.datamodel.SequenceFeature[] sf = jds.getDatasetSequence()
524 .getSequenceFeatures();
526 while (index < sf.length)
528 Features features = new Features();
530 features.setBegin(sf[index].getBegin());
531 features.setEnd(sf[index].getEnd());
532 features.setDescription(sf[index].getDescription());
533 features.setType(sf[index].getType());
534 features.setFeatureGroup(sf[index].getFeatureGroup());
535 features.setScore(sf[index].getScore());
536 if (sf[index].links != null)
538 for (int l = 0; l < sf[index].links.size(); l++)
540 OtherData keyValue = new OtherData();
541 keyValue.setKey("LINK_" + l);
542 keyValue.setValue(sf[index].links.elementAt(l).toString());
543 features.addOtherData(keyValue);
546 if (sf[index].otherDetails != null)
549 Enumeration keys = sf[index].otherDetails.keys();
550 while (keys.hasMoreElements())
552 key = keys.nextElement().toString();
553 OtherData keyValue = new OtherData();
554 keyValue.setKey(key);
555 keyValue.setValue(sf[index].otherDetails.get(key).toString());
556 features.addOtherData(keyValue);
560 jseq.addFeatures(features);
565 if (jds.getDatasetSequence().getPDBId() != null)
567 Enumeration en = jds.getDatasetSequence().getPDBId().elements();
568 while (en.hasMoreElements())
570 Pdbids pdb = new Pdbids();
571 jalview.datamodel.PDBEntry entry = (jalview.datamodel.PDBEntry) en
574 pdb.setId(entry.getId());
575 pdb.setType(entry.getType());
578 // This must have been loaded, is it still visible?
579 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
580 String matchedFile = null;
581 for (int f = frames.length - 1; f > -1; f--)
583 if (frames[f] instanceof AppJmol)
585 jmol = (AppJmol) frames[f];
586 for (int peid = 0; peid < jmol.jmb.pdbentry.length; peid++)
588 if (!jmol.jmb.pdbentry[peid].getId().equals(entry.getId())
589 && !(entry.getId().length() > 4 && entry
593 jmol.jmb.pdbentry[peid].getId()
596 if (matchedFile == null)
598 matchedFile = jmol.jmb.pdbentry[peid].getFile();
600 else if (!matchedFile.equals(jmol.jmb.pdbentry[peid]
604 .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
605 + jmol.jmb.pdbentry[peid].getFile());
609 // can get at it if the ID
610 // match is ambiguous (e.g.
612 String statestring = jmol.jmb.viewer.getStateInfo();
614 for (int smap = 0; smap < jmol.jmb.sequence[peid].length; smap++)
616 // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
617 if (jds==jmol.jmb.sequence[peid][smap])
619 StructureState state = new StructureState();
620 state.setVisible(true);
621 state.setXpos(jmol.getX());
622 state.setYpos(jmol.getY());
623 state.setWidth(jmol.getWidth());
624 state.setHeight(jmol.getHeight());
625 state.setViewId(jmol.getViewId());
626 state.setAlignwithAlignPanel(jmol.isUsedforaligment(ap));
627 state.setColourwithAlignPanel(jmol
628 .isUsedforcolourby(ap));
629 state.setColourByJmol(jmol.isColouredByJmol());
630 if (!jmolViewIds.contains(state.getViewId()))
632 // Make sure we only store a Jmol state once in each XML
634 jmolViewIds.addElement(state.getViewId());
635 state.setContent(statestring.replaceAll("\n", ""));
639 state.setContent("# duplicate state");
641 pdb.addStructureState(state);
648 if (matchedFile != null || entry.getFile() != null)
650 if (entry.getFile() != null)
653 matchedFile = entry.getFile();
655 pdb.setFile(matchedFile); // entry.getFile());
656 if (pdbfiles == null)
658 pdbfiles = new Vector();
661 if (!pdbfiles.contains(entry.getId()))
663 pdbfiles.addElement(entry.getId());
666 File file = new File(matchedFile);
667 if (file.exists() && jout != null)
669 byte[] data = new byte[(int) file.length()];
670 jout.putNextEntry(new JarEntry(entry.getId()));
671 DataInputStream dis = new DataInputStream(
672 new FileInputStream(file));
675 DataOutputStream dout = new DataOutputStream(jout);
676 dout.write(data, 0, data.length);
680 } catch (Exception ex)
682 ex.printStackTrace();
688 if (entry.getProperty() != null)
690 PdbentryItem item = new PdbentryItem();
691 Hashtable properties = entry.getProperty();
692 Enumeration en2 = properties.keys();
693 while (en2.hasMoreElements())
695 Property prop = new Property();
696 String key = en2.nextElement().toString();
698 prop.setValue(properties.get(key).toString());
699 item.addProperty(prop);
701 pdb.addPdbentryItem(item);
711 if (av.hasHiddenRows)
716 if (jal.getCodonFrames() != null && jal.getCodonFrames().length > 0)
718 jalview.datamodel.AlignedCodonFrame[] jac = jal.getCodonFrames();
719 for (int i = 0; i < jac.length; i++)
721 AlcodonFrame alc = new AlcodonFrame();
722 vamsasSet.addAlcodonFrame(alc);
723 for (int p = 0; p < jac[i].aaWidth; p++)
725 Alcodon cmap = new Alcodon();
726 if (jac[i].codons[p] != null)
728 // Null codons indicate a gapped column in the translated peptide
730 cmap.setPos1(jac[i].codons[p][0]);
731 cmap.setPos2(jac[i].codons[p][1]);
732 cmap.setPos3(jac[i].codons[p][2]);
734 alc.addAlcodon(cmap);
736 if (jac[i].getProtMappings() != null
737 && jac[i].getProtMappings().length > 0)
739 SequenceI[] dnas = jac[i].getdnaSeqs();
740 jalview.datamodel.Mapping[] pmaps = jac[i].getProtMappings();
741 for (int m = 0; m < pmaps.length; m++)
743 AlcodMap alcmap = new AlcodMap();
744 alcmap.setDnasq(seqHash(dnas[m]));
745 alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
747 alc.addAlcodMap(alcmap);
754 // /////////////////////////////////
755 if (av.currentTree != null)
757 // FIND ANY ASSOCIATED TREES
758 // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
759 if (Desktop.desktop != null)
761 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
763 for (int t = 0; t < frames.length; t++)
765 if (frames[t] instanceof TreePanel)
767 TreePanel tp = (TreePanel) frames[t];
769 if (tp.treeCanvas.av.alignment == jal)
771 Tree tree = new Tree();
772 tree.setTitle(tp.getTitle());
773 tree.setCurrentTree((av.currentTree == tp.getTree()));
774 tree.setNewick(tp.getTree().toString());
775 tree.setThreshold(tp.treeCanvas.threshold);
777 tree.setFitToWindow(tp.fitToWindow.getState());
778 tree.setFontName(tp.getTreeFont().getName());
779 tree.setFontSize(tp.getTreeFont().getSize());
780 tree.setFontStyle(tp.getTreeFont().getStyle());
781 tree.setMarkUnlinked(tp.placeholdersMenu.getState());
783 tree.setShowBootstrap(tp.bootstrapMenu.getState());
784 tree.setShowDistances(tp.distanceMenu.getState());
786 tree.setHeight(tp.getHeight());
787 tree.setWidth(tp.getWidth());
788 tree.setXpos(tp.getX());
789 tree.setYpos(tp.getY());
790 tree.setId(makeHashCode(tp, null));
800 * store forward refs from an annotationRow to any groups
802 IdentityHashMap groupRefs = new IdentityHashMap();
803 if (jal.getAlignmentAnnotation() != null)
805 jalview.datamodel.AlignmentAnnotation[] aa = jal
806 .getAlignmentAnnotation();
808 for (int i = 0; i < aa.length; i++)
810 Annotation an = new Annotation();
812 if (aa[i].annotationId != null)
814 annotationIds.put(aa[i].annotationId, aa[i]);
817 an.setId(aa[i].annotationId);
819 an.setVisible(aa[i].visible);
821 an.setDescription(aa[i].description);
823 if (aa[i].sequenceRef != null)
825 // TODO later annotation sequenceRef should be the XML ID of the
826 // sequence rather than its display name
827 an.setSequenceRef(aa[i].sequenceRef.getName());
829 if (aa[i].groupRef != null)
831 Object groupIdr = groupRefs.get(aa[i].groupRef);
832 if (groupIdr == null)
834 // make a locally unique String
835 groupRefs.put(aa[i].groupRef,
836 groupIdr = ("" + System.currentTimeMillis()
837 + aa[i].groupRef.getName() + groupRefs.size()));
839 an.setGroupRef(groupIdr.toString());
842 // store all visualization attributes for annotation
843 an.setGraphHeight(aa[i].graphHeight);
844 an.setCentreColLabels(aa[i].centreColLabels);
845 an.setScaleColLabels(aa[i].scaleColLabel);
846 an.setShowAllColLabels(aa[i].showAllColLabels);
851 an.setGraphType(aa[i].graph);
852 an.setGraphGroup(aa[i].graphGroup);
853 if (aa[i].getThreshold() != null)
855 ThresholdLine line = new ThresholdLine();
856 line.setLabel(aa[i].getThreshold().label);
857 line.setValue(aa[i].getThreshold().value);
858 line.setColour(aa[i].getThreshold().colour.getRGB());
859 an.setThresholdLine(line);
867 an.setLabel(aa[i].label);
869 if (aa[i] == av.quality || aa[i] == av.conservation
870 || aa[i] == av.consensus || aa[i].autoCalculated)
872 // new way of indicating autocalculated annotation -
873 an.setAutoCalculated(aa[i].autoCalculated);
875 if (aa[i].hasScore())
877 an.setScore(aa[i].getScore());
879 AnnotationElement ae;
880 if (aa[i].annotations != null)
882 an.setScoreOnly(false);
883 for (int a = 0; a < aa[i].annotations.length; a++)
885 if ((aa[i] == null) || (aa[i].annotations[a] == null))
890 ae = new AnnotationElement();
891 if (aa[i].annotations[a].description != null)
892 ae.setDescription(aa[i].annotations[a].description);
893 if (aa[i].annotations[a].displayCharacter != null)
894 ae.setDisplayCharacter(aa[i].annotations[a].displayCharacter);
896 if (!Float.isNaN(aa[i].annotations[a].value))
897 ae.setValue(aa[i].annotations[a].value);
900 if (aa[i].annotations[a].secondaryStructure != ' '
901 && aa[i].annotations[a].secondaryStructure != '\0')
902 ae.setSecondaryStructure(aa[i].annotations[a].secondaryStructure
905 if (aa[i].annotations[a].colour != null
906 && aa[i].annotations[a].colour != java.awt.Color.black)
908 ae.setColour(aa[i].annotations[a].colour.getRGB());
911 an.addAnnotationElement(ae);
912 if (aa[i].autoCalculated)
914 // only write one non-null entry into the annotation row -
915 // sufficient to get the visualization attributes necessary to
923 an.setScoreOnly(true);
925 vamsasSet.addAnnotation(an);
929 if (jal.getGroups() != null)
931 JGroup[] groups = new JGroup[jal.getGroups().size()];
933 for (int i = 0; i < groups.length; i++)
935 groups[i] = new JGroup();
937 jalview.datamodel.SequenceGroup sg = (jalview.datamodel.SequenceGroup) jal
938 .getGroups().elementAt(i);
939 groups[i].setStart(sg.getStartRes());
940 groups[i].setEnd(sg.getEndRes());
941 groups[i].setName(sg.getName());
942 if (groupRefs.containsKey(sg))
944 // group has references so set it's ID field
945 groups[i].setId(groupRefs.get(sg).toString());
949 if (sg.cs.conservationApplied())
951 groups[i].setConsThreshold(sg.cs.getConservationInc());
953 if (sg.cs instanceof jalview.schemes.UserColourScheme)
955 groups[i].setColour(SetUserColourScheme(sg.cs, userColours,
961 .setColour(ColourSchemeProperty.getColourName(sg.cs));
964 else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient)
967 .setColour(ColourSchemeProperty
968 .getColourName(((jalview.schemes.AnnotationColourGradient) sg.cs)
971 else if (sg.cs instanceof jalview.schemes.UserColourScheme)
974 .setColour(SetUserColourScheme(sg.cs, userColours, jms));
978 groups[i].setColour(ColourSchemeProperty.getColourName(sg.cs));
981 groups[i].setPidThreshold(sg.cs.getThreshold());
984 groups[i].setOutlineColour(sg.getOutlineColour().getRGB());
985 groups[i].setDisplayBoxes(sg.getDisplayBoxes());
986 groups[i].setDisplayText(sg.getDisplayText());
987 groups[i].setColourText(sg.getColourText());
988 groups[i].setTextCol1(sg.textColour.getRGB());
989 groups[i].setTextCol2(sg.textColour2.getRGB());
990 groups[i].setTextColThreshold(sg.thresholdTextColour);
991 groups[i].setShowUnconserved(sg.getShowNonconserved());
992 groups[i].setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
993 groups[i].setShowConsensusHistogram(sg.isShowConsensusHistogram());
994 groups[i].setShowSequenceLogo(sg.isShowSequenceLogo());
995 for (int s = 0; s < sg.getSize(); s++)
997 jalview.datamodel.Sequence seq = (jalview.datamodel.Sequence) sg
999 groups[i].addSeq(seqHash(seq));
1003 jms.setJGroup(groups);
1006 // /////////SAVE VIEWPORT
1007 Viewport view = new Viewport();
1008 view.setTitle(ap.alignFrame.getTitle());
1009 view.setSequenceSetId(makeHashCode(av.getSequenceSetId(),
1010 av.getSequenceSetId()));
1011 view.setId(av.getViewId());
1012 view.setViewName(av.viewName);
1013 view.setGatheredViews(av.gatherViewsHere);
1015 if (ap.av.explodedPosition != null)
1017 view.setXpos(av.explodedPosition.x);
1018 view.setYpos(av.explodedPosition.y);
1019 view.setWidth(av.explodedPosition.width);
1020 view.setHeight(av.explodedPosition.height);
1024 view.setXpos(ap.alignFrame.getBounds().x);
1025 view.setYpos(ap.alignFrame.getBounds().y);
1026 view.setWidth(ap.alignFrame.getBounds().width);
1027 view.setHeight(ap.alignFrame.getBounds().height);
1030 view.setStartRes(av.startRes);
1031 view.setStartSeq(av.startSeq);
1033 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1035 view.setBgColour(SetUserColourScheme(av.getGlobalColourScheme(),
1038 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1040 jalview.schemes.AnnotationColourGradient acg = (jalview.schemes.AnnotationColourGradient) av
1041 .getGlobalColourScheme();
1043 AnnotationColours ac = new AnnotationColours();
1044 ac.setAboveThreshold(acg.getAboveThreshold());
1045 ac.setThreshold(acg.getAnnotationThreshold());
1046 ac.setAnnotation(acg.getAnnotation());
1047 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1049 ac.setColourScheme(SetUserColourScheme(acg.getBaseColour(),
1054 ac.setColourScheme(ColourSchemeProperty.getColourName(acg
1058 ac.setMaxColour(acg.getMaxColour().getRGB());
1059 ac.setMinColour(acg.getMinColour().getRGB());
1060 view.setAnnotationColours(ac);
1061 view.setBgColour("AnnotationColourGradient");
1065 view.setBgColour(ColourSchemeProperty.getColourName(av
1066 .getGlobalColourScheme()));
1069 ColourSchemeI cs = av.getGlobalColourScheme();
1073 if (cs.conservationApplied())
1075 view.setConsThreshold(cs.getConservationInc());
1076 if (cs instanceof jalview.schemes.UserColourScheme)
1078 view.setBgColour(SetUserColourScheme(cs, userColours, jms));
1082 if (cs instanceof ResidueColourScheme)
1084 view.setPidThreshold(cs.getThreshold());
1088 view.setConservationSelected(av.getConservationSelected());
1089 view.setPidSelected(av.getAbovePIDThreshold());
1090 view.setFontName(av.font.getName());
1091 view.setFontSize(av.font.getSize());
1092 view.setFontStyle(av.font.getStyle());
1093 view.setRenderGaps(av.renderGaps);
1094 view.setShowAnnotation(av.getShowAnnotation());
1095 view.setShowBoxes(av.getShowBoxes());
1096 view.setShowColourText(av.getColourText());
1097 view.setShowFullId(av.getShowJVSuffix());
1098 view.setRightAlignIds(av.rightAlignIds);
1099 view.setShowSequenceFeatures(av.showSequenceFeatures);
1100 view.setShowText(av.getShowText());
1101 view.setShowUnconserved(av.getShowUnconserved());
1102 view.setWrapAlignment(av.getWrapAlignment());
1103 view.setTextCol1(av.textColour.getRGB());
1104 view.setTextCol2(av.textColour2.getRGB());
1105 view.setTextColThreshold(av.thresholdTextColour);
1106 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1107 view.setShowSequenceLogo(av.isShowSequenceLogo());
1108 view.setShowGroupConsensus(av.isShowGroupConsensus());
1109 view.setShowGroupConservation(av.isShowGroupConservation());
1110 view.setShowNPfeatureTooltip(av.isShowNpFeats());
1111 view.setShowDbRefTooltip(av.isShowDbRefs());
1112 view.setFollowHighlight(av.followHighlight);
1113 view.setFollowSelection(av.followSelection);
1114 view.setIgnoreGapsinConsensus(av.getIgnoreGapsConsensus());
1115 if (av.featuresDisplayed != null)
1117 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1119 String[] renderOrder = ap.seqPanel.seqCanvas.getFeatureRenderer().renderOrder;
1121 Vector settingsAdded = new Vector();
1122 Object gstyle = null;
1123 GraduatedColor gcol = null;
1124 if (renderOrder != null)
1126 for (int ro = 0; ro < renderOrder.length; ro++)
1128 gstyle = ap.seqPanel.seqCanvas.getFeatureRenderer()
1129 .getFeatureStyle(renderOrder[ro]);
1130 Setting setting = new Setting();
1131 setting.setType(renderOrder[ro]);
1132 if (gstyle instanceof GraduatedColor)
1134 gcol = (GraduatedColor) gstyle;
1135 setting.setColour(gcol.getMaxColor().getRGB());
1136 setting.setMincolour(gcol.getMinColor().getRGB());
1137 setting.setMin(gcol.getMin());
1138 setting.setMax(gcol.getMax());
1139 setting.setColourByLabel(gcol.isColourByLabel());
1140 setting.setAutoScale(gcol.isAutoScale());
1141 setting.setThreshold(gcol.getThresh());
1142 setting.setThreshstate(gcol.getThreshType());
1146 setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer()
1147 .getColour(renderOrder[ro]).getRGB());
1150 setting.setDisplay(av.featuresDisplayed
1151 .containsKey(renderOrder[ro]));
1152 float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer()
1153 .getOrder(renderOrder[ro]);
1156 setting.setOrder(rorder);
1158 fs.addSetting(setting);
1159 settingsAdded.addElement(renderOrder[ro]);
1163 // Make sure we save none displayed feature settings
1164 Enumeration en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureColours
1166 while (en.hasMoreElements())
1168 String key = en.nextElement().toString();
1169 if (settingsAdded.contains(key))
1174 Setting setting = new Setting();
1175 setting.setType(key);
1176 setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer()
1177 .getColour(key).getRGB());
1179 setting.setDisplay(false);
1180 float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer().getOrder(
1184 setting.setOrder(rorder);
1186 fs.addSetting(setting);
1187 settingsAdded.addElement(key);
1189 en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups.keys();
1190 Vector groupsAdded = new Vector();
1191 while (en.hasMoreElements())
1193 String grp = en.nextElement().toString();
1194 if (groupsAdded.contains(grp))
1198 Group g = new Group();
1200 g.setDisplay(((Boolean) ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups
1201 .get(grp)).booleanValue());
1203 groupsAdded.addElement(grp);
1205 jms.setFeatureSettings(fs);
1209 if (av.hasHiddenColumns)
1211 if (av.getColumnSelection() == null
1212 || av.getColumnSelection().getHiddenColumns() == null)
1214 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1218 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1221 int[] region = (int[]) av.getColumnSelection().getHiddenColumns()
1223 HiddenColumns hc = new HiddenColumns();
1224 hc.setStart(region[0]);
1225 hc.setEnd(region[1]);
1226 view.addHiddenColumns(hc);
1231 jms.addViewport(view);
1233 object.setJalviewModelSequence(jms);
1234 object.getVamsasModel().addSequenceSet(vamsasSet);
1236 if (jout != null && fileName != null)
1238 // We may not want to write the object to disk,
1239 // eg we can copy the alignViewport to a new view object
1240 // using save and then load
1243 JarEntry entry = new JarEntry(fileName);
1244 jout.putNextEntry(entry);
1245 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1247 org.exolab.castor.xml.Marshaller marshaller = new org.exolab.castor.xml.Marshaller(
1249 marshaller.marshal(object);
1252 } catch (Exception ex)
1254 // TODO: raise error in GUI if marshalling failed.
1255 ex.printStackTrace();
1262 * External mapping between jalview objects and objects yielding a valid and
1263 * unique object ID string. This is null for normal Jalview project IO, but
1264 * non-null when a jalview project is being read or written as part of a
1267 IdentityHashMap jv2vobj = null;
1270 * Construct a unique ID for jvobj using either existing bindings or if none
1271 * exist, the result of the hashcode call for the object.
1274 * jalview data object
1275 * @return unique ID for referring to jvobj
1277 private String makeHashCode(Object jvobj, String altCode)
1279 if (jv2vobj != null)
1281 Object id = jv2vobj.get(jvobj);
1284 return id.toString();
1286 // check string ID mappings
1287 if (jvids2vobj != null && jvobj instanceof String)
1289 id = jvids2vobj.get(jvobj);
1293 return id.toString();
1295 // give up and warn that something has gone wrong
1296 warn("Cannot find ID for object in external mapping : " + jvobj);
1302 * return local jalview object mapped to ID, if it exists
1306 * @return null or object bound to idcode
1308 private Object retrieveExistingObj(String idcode)
1310 if (idcode != null && vobj2jv != null)
1312 return vobj2jv.get(idcode);
1318 * binding from ID strings from external mapping table to jalview data model
1321 private Hashtable vobj2jv;
1323 private Sequence createVamsasSequence(String id, SequenceI jds)
1325 return createVamsasSequence(true, id, jds, null);
1328 private Sequence createVamsasSequence(boolean recurse, String id,
1329 SequenceI jds, SequenceI parentseq)
1331 Sequence vamsasSeq = new Sequence();
1332 vamsasSeq.setId(id);
1333 vamsasSeq.setName(jds.getName());
1334 vamsasSeq.setSequence(jds.getSequenceAsString());
1335 vamsasSeq.setDescription(jds.getDescription());
1336 jalview.datamodel.DBRefEntry[] dbrefs = null;
1337 if (jds.getDatasetSequence() != null)
1339 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
1340 if (jds.getDatasetSequence().getDBRef() != null)
1342 dbrefs = jds.getDatasetSequence().getDBRef();
1347 vamsasSeq.setDsseqid(id); // so we can tell which sequences really are
1348 // dataset sequences only
1349 dbrefs = jds.getDBRef();
1353 for (int d = 0; d < dbrefs.length; d++)
1355 DBRef dbref = new DBRef();
1356 dbref.setSource(dbrefs[d].getSource());
1357 dbref.setVersion(dbrefs[d].getVersion());
1358 dbref.setAccessionId(dbrefs[d].getAccessionId());
1359 if (dbrefs[d].hasMap())
1361 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
1363 dbref.setMapping(mp);
1365 vamsasSeq.addDBRef(dbref);
1371 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
1372 SequenceI parentseq, SequenceI jds, boolean recurse)
1375 if (jmp.getMap() != null)
1379 jalview.util.MapList mlst = jmp.getMap();
1380 int r[] = mlst.getFromRanges();
1381 for (int s = 0; s < r.length; s += 2)
1383 MapListFrom mfrom = new MapListFrom();
1384 mfrom.setStart(r[s]);
1385 mfrom.setEnd(r[s + 1]);
1386 mp.addMapListFrom(mfrom);
1388 r = mlst.getToRanges();
1389 for (int s = 0; s < r.length; s += 2)
1391 MapListTo mto = new MapListTo();
1393 mto.setEnd(r[s + 1]);
1394 mp.addMapListTo(mto);
1396 mp.setMapFromUnit(mlst.getFromRatio());
1397 mp.setMapToUnit(mlst.getToRatio());
1398 if (jmp.getTo() != null)
1400 MappingChoice mpc = new MappingChoice();
1402 && (parentseq != jmp.getTo() || parentseq
1403 .getDatasetSequence() != jmp.getTo()))
1405 mpc.setSequence(createVamsasSequence(false, seqHash(jmp.getTo()),
1411 SequenceI ps = null;
1412 if (parentseq != jmp.getTo()
1413 && parentseq.getDatasetSequence() != jmp.getTo())
1415 // chaining dbref rather than a handshaking one
1416 jmpid = seqHash(ps = jmp.getTo());
1420 jmpid = seqHash(ps = parentseq);
1422 mpc.setDseqFor(jmpid);
1423 if (!seqRefIds.containsKey(mpc.getDseqFor()))
1425 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
1426 seqRefIds.put(mpc.getDseqFor(), ps);
1430 jalview.bin.Cache.log.debug("reusing DseqFor ID");
1433 mp.setMappingChoice(mpc);
1439 String SetUserColourScheme(jalview.schemes.ColourSchemeI cs,
1440 Vector userColours, JalviewModelSequence jms)
1443 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
1444 boolean newucs = false;
1445 if (!userColours.contains(ucs))
1447 userColours.add(ucs);
1450 id = "ucs" + userColours.indexOf(ucs);
1453 // actually create the scheme's entry in the XML model
1454 java.awt.Color[] colours = ucs.getColours();
1455 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
1456 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
1458 for (int i = 0; i < colours.length; i++)
1460 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1461 col.setName(ResidueProperties.aa[i]);
1462 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1463 jbucs.addColour(col);
1465 if (ucs.getLowerCaseColours() != null)
1467 colours = ucs.getLowerCaseColours();
1468 for (int i = 0; i < colours.length; i++)
1470 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1471 col.setName(ResidueProperties.aa[i].toLowerCase());
1472 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1473 jbucs.addColour(col);
1478 uc.setUserColourScheme(jbucs);
1479 jms.addUserColours(uc);
1485 jalview.schemes.UserColourScheme GetUserColourScheme(
1486 JalviewModelSequence jms, String id)
1488 UserColours[] uc = jms.getUserColours();
1489 UserColours colours = null;
1491 for (int i = 0; i < uc.length; i++)
1493 if (uc[i].getId().equals(id))
1501 java.awt.Color[] newColours = new java.awt.Color[24];
1503 for (int i = 0; i < 24; i++)
1505 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1506 .getUserColourScheme().getColour(i).getRGB(), 16));
1509 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
1512 if (colours.getUserColourScheme().getColourCount() > 24)
1514 newColours = new java.awt.Color[23];
1515 for (int i = 0; i < 23; i++)
1517 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1518 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
1520 ucs.setLowerCaseColours(newColours);
1527 * contains last error message (if any) encountered by XML loader.
1529 String errorMessage = null;
1532 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
1533 * exceptions are raised during project XML parsing
1535 public boolean attemptversion1parse = true;
1538 * Load a jalview project archive from a jar file
1541 * - HTTP URL or filename
1543 public AlignFrame LoadJalviewAlign(final String file)
1546 jalview.gui.AlignFrame af = null;
1550 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
1551 // Workaround is to make sure caller implements the JarInputStreamProvider
1553 // so we can re-open the jar input stream for each entry.
1555 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
1556 af = LoadJalviewAlign(jprovider);
1557 } catch (MalformedURLException e)
1559 errorMessage = "Invalid URL format for '" + file + "'";
1565 private jarInputStreamProvider createjarInputStreamProvider(
1566 final String file) throws MalformedURLException
1569 errorMessage = null;
1570 uniqueSetSuffix = null;
1572 viewportsAdded = null;
1573 frefedSequence = null;
1575 if (file.startsWith("http://"))
1577 url = new URL(file);
1579 final URL _url = url;
1580 return new jarInputStreamProvider()
1583 public JarInputStream getJarInputStream() throws IOException
1587 return new JarInputStream(_url.openStream());
1591 return new JarInputStream(new FileInputStream(file));
1595 public String getFilename()
1603 * Recover jalview session from a jalview project archive. Caller may
1604 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
1605 * themselves. Any null fields will be initialised with default values,
1606 * non-null fields are left alone.
1611 public AlignFrame LoadJalviewAlign(final jarInputStreamProvider jprovider)
1613 errorMessage = null;
1614 if (uniqueSetSuffix == null)
1616 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
1618 if (seqRefIds == null)
1620 seqRefIds = new Hashtable();
1622 if (viewportsAdded == null)
1624 viewportsAdded = new Hashtable();
1626 if (frefedSequence == null)
1628 frefedSequence = new Vector();
1631 jalview.gui.AlignFrame af = null;
1632 Hashtable gatherToThisFrame = new Hashtable();
1633 final String file = jprovider.getFilename();
1636 JarInputStream jin = null;
1637 JarEntry jarentry = null;
1642 jin = jprovider.getJarInputStream();
1643 for (int i = 0; i < entryCount; i++)
1645 jarentry = jin.getNextJarEntry();
1648 if (jarentry != null && jarentry.getName().endsWith(".xml"))
1650 InputStreamReader in = new InputStreamReader(jin, "UTF-8");
1651 JalviewModel object = new JalviewModel();
1653 Unmarshaller unmar = new Unmarshaller(object);
1654 unmar.setValidation(false);
1655 object = (JalviewModel) unmar.unmarshal(in);
1656 if (true) // !skipViewport(object))
1658 af = LoadFromObject(object, file, true, jprovider);
1659 if (af.viewport.gatherViewsHere)
1661 gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
1666 else if (jarentry != null)
1668 // Some other file here.
1671 } while (jarentry != null);
1672 resolveFrefedSequences();
1673 } catch (java.io.FileNotFoundException ex)
1675 ex.printStackTrace();
1676 errorMessage = "Couldn't locate Jalview XML file : " + file;
1677 System.err.println("Exception whilst loading jalview XML file : "
1679 } catch (java.net.UnknownHostException ex)
1681 ex.printStackTrace();
1682 errorMessage = "Couldn't locate Jalview XML file : " + file;
1683 System.err.println("Exception whilst loading jalview XML file : "
1685 } catch (Exception ex)
1687 System.err.println("Parsing as Jalview Version 2 file failed.");
1688 ex.printStackTrace(System.err);
1689 if (attemptversion1parse)
1691 // Is Version 1 Jar file?
1694 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
1695 } catch (Exception ex2)
1697 System.err.println("Exception whilst loading as jalviewXMLV1:");
1698 ex2.printStackTrace();
1702 if (Desktop.instance != null)
1704 Desktop.instance.stopLoading();
1708 System.out.println("Successfully loaded archive file");
1711 ex.printStackTrace();
1713 System.err.println("Exception whilst loading jalview XML file : "
1715 } catch (OutOfMemoryError e)
1717 // Don't use the OOM Window here
1718 errorMessage = "Out of memory loading jalview XML file";
1719 System.err.println("Out of memory whilst loading jalview XML file");
1720 e.printStackTrace();
1723 if (Desktop.instance != null)
1725 Desktop.instance.stopLoading();
1728 Enumeration en = gatherToThisFrame.elements();
1729 while (en.hasMoreElements())
1731 Desktop.instance.gatherViews((AlignFrame) en.nextElement());
1733 if (errorMessage != null)
1741 * check errorMessage for a valid error message and raise an error box in the
1742 * GUI or write the current errorMessage to stderr and then clear the error
1745 protected void reportErrors()
1747 reportErrors(false);
1750 protected void reportErrors(final boolean saving)
1752 if (errorMessage != null)
1754 final String finalErrorMessage = errorMessage;
1757 javax.swing.SwingUtilities.invokeLater(new Runnable()
1761 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1762 finalErrorMessage, "Error "
1763 + (saving ? "saving" : "loading")
1764 + " Jalview file", JOptionPane.WARNING_MESSAGE);
1770 System.err.println("Problem loading Jalview file: " + errorMessage);
1773 errorMessage = null;
1776 Hashtable alreadyLoadedPDB;
1779 * when set, local views will be updated from view stored in JalviewXML
1780 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
1781 * sync if this is set to true.
1783 private boolean updateLocalViews = false;
1785 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
1787 if (alreadyLoadedPDB == null)
1788 alreadyLoadedPDB = new Hashtable();
1790 if (alreadyLoadedPDB.containsKey(pdbId))
1791 return alreadyLoadedPDB.get(pdbId).toString();
1795 JarInputStream jin = jprovider.getJarInputStream();
1797 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
1798 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
1799 * FileInputStream(jprovider)); }
1802 JarEntry entry = null;
1805 entry = jin.getNextJarEntry();
1806 } while (entry != null && !entry.getName().equals(pdbId));
1809 BufferedReader in = new BufferedReader(new InputStreamReader(jin));
1810 File outFile = File.createTempFile("jalview_pdb", ".txt");
1811 outFile.deleteOnExit();
1812 PrintWriter out = new PrintWriter(new FileOutputStream(outFile));
1815 while ((data = in.readLine()) != null)
1822 } catch (Exception foo)
1827 String t=outFile.getAbsolutePath();
1828 alreadyLoadedPDB.put(pdbId, t);
1833 warn("Couldn't find PDB file entry in Jalview Jar for " + pdbId);
1835 } catch (Exception ex)
1837 ex.printStackTrace();
1843 private class JvAnnotRow
1845 public JvAnnotRow(int i, AlignmentAnnotation jaa)
1852 * persisted version of annotation row from which to take vis properties
1854 public jalview.datamodel.AlignmentAnnotation template;
1857 * original position of the annotation row in the alignment
1863 * Load alignment frame from jalview XML DOM object
1868 * filename source string
1869 * @param loadTreesAndStructures
1870 * when false only create Viewport
1872 * data source provider
1873 * @return alignment frame created from view stored in DOM
1875 AlignFrame LoadFromObject(JalviewModel object, String file,
1876 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
1878 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
1879 Sequence[] vamsasSeq = vamsasSet.getSequence();
1881 JalviewModelSequence jms = object.getJalviewModelSequence();
1883 Viewport view = jms.getViewport(0);
1884 // ////////////////////////////////
1887 Vector hiddenSeqs = null;
1888 jalview.datamodel.Sequence jseq;
1890 ArrayList tmpseqs = new ArrayList();
1892 boolean multipleView = false;
1894 JSeq[] JSEQ = object.getJalviewModelSequence().getJSeq();
1895 int vi = 0; // counter in vamsasSeq array
1896 for (int i = 0; i < JSEQ.length; i++)
1898 String seqId = JSEQ[i].getId();
1900 if (seqRefIds.get(seqId) != null)
1902 tmpseqs.add((jalview.datamodel.Sequence) seqRefIds.get(seqId));
1903 multipleView = true;
1907 jseq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
1908 vamsasSeq[vi].getSequence());
1909 jseq.setDescription(vamsasSeq[vi].getDescription());
1910 jseq.setStart(JSEQ[i].getStart());
1911 jseq.setEnd(JSEQ[i].getEnd());
1912 jseq.setVamsasId(uniqueSetSuffix + seqId);
1913 seqRefIds.put(vamsasSeq[vi].getId(), jseq);
1918 if (JSEQ[i].getHidden())
1920 if (hiddenSeqs == null)
1922 hiddenSeqs = new Vector();
1925 hiddenSeqs.addElement((jalview.datamodel.Sequence) seqRefIds
1932 // Create the alignment object from the sequence set
1933 // ///////////////////////////////
1934 jalview.datamodel.Sequence[] orderedSeqs = new jalview.datamodel.Sequence[tmpseqs
1937 tmpseqs.toArray(orderedSeqs);
1939 jalview.datamodel.Alignment al = new jalview.datamodel.Alignment(
1942 // / Add the alignment properties
1943 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
1945 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
1946 al.setProperty(ssp.getKey(), ssp.getValue());
1950 // SequenceFeatures are added to the DatasetSequence,
1951 // so we must create or recover the dataset before loading features
1952 // ///////////////////////////////
1953 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
1955 // older jalview projects do not have a dataset id.
1956 al.setDataset(null);
1960 recoverDatasetFor(vamsasSet, al);
1962 // ///////////////////////////////
1964 Hashtable pdbloaded = new Hashtable();
1967 // load sequence features, database references and any associated PDB
1968 // structures for the alignment
1969 for (int i = 0; i < vamsasSeq.length; i++)
1971 if (JSEQ[i].getFeaturesCount() > 0)
1973 Features[] features = JSEQ[i].getFeatures();
1974 for (int f = 0; f < features.length; f++)
1976 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
1977 features[f].getType(), features[f].getDescription(),
1978 features[f].getStatus(), features[f].getBegin(),
1979 features[f].getEnd(), features[f].getFeatureGroup());
1981 sf.setScore(features[f].getScore());
1982 for (int od = 0; od < features[f].getOtherDataCount(); od++)
1984 OtherData keyValue = features[f].getOtherData(od);
1985 if (keyValue.getKey().startsWith("LINK"))
1987 sf.addLink(keyValue.getValue());
1991 sf.setValue(keyValue.getKey(), keyValue.getValue());
1996 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
1999 if (vamsasSeq[i].getDBRefCount() > 0)
2001 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2003 if (JSEQ[i].getPdbidsCount() > 0)
2005 Pdbids[] ids = JSEQ[i].getPdbids();
2006 for (int p = 0; p < ids.length; p++)
2008 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2009 entry.setId(ids[p].getId());
2010 entry.setType(ids[p].getType());
2011 if (ids[p].getFile() != null)
2013 if (!pdbloaded.containsKey(ids[p].getFile()))
2015 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2019 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2023 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2027 } // end !multipleview
2029 // ///////////////////////////////
2030 // LOAD SEQUENCE MAPPINGS
2032 if (vamsasSet.getAlcodonFrameCount() > 0)
2034 // TODO Potentially this should only be done once for all views of an
2036 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2037 for (int i = 0; i < alc.length; i++)
2039 jalview.datamodel.AlignedCodonFrame cf = new jalview.datamodel.AlignedCodonFrame(
2040 alc[i].getAlcodonCount());
2041 if (alc[i].getAlcodonCount() > 0)
2043 Alcodon[] alcods = alc[i].getAlcodon();
2044 for (int p = 0; p < cf.codons.length; p++)
2046 if (alcods[p].hasPos1() && alcods[p].hasPos2()
2047 && alcods[p].hasPos3())
2049 // translated codons require three valid positions
2050 cf.codons[p] = new int[3];
2051 cf.codons[p][0] = (int) alcods[p].getPos1();
2052 cf.codons[p][1] = (int) alcods[p].getPos2();
2053 cf.codons[p][2] = (int) alcods[p].getPos3();
2057 cf.codons[p] = null;
2061 if (alc[i].getAlcodMapCount() > 0)
2063 AlcodMap[] maps = alc[i].getAlcodMap();
2064 for (int m = 0; m < maps.length; m++)
2066 SequenceI dnaseq = (SequenceI) seqRefIds
2067 .get(maps[m].getDnasq());
2069 jalview.datamodel.Mapping mapping = null;
2070 // attach to dna sequence reference.
2071 if (maps[m].getMapping() != null)
2073 mapping = addMapping(maps[m].getMapping());
2077 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
2082 frefedSequence.add(new Object[]
2083 { maps[m].getDnasq(), cf, mapping });
2087 al.addCodonFrame(cf);
2092 // ////////////////////////////////
2094 ArrayList<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
2096 * store any annotations which forward reference a group's ID
2098 Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>>();
2100 if (vamsasSet.getAnnotationCount() > 0)
2102 Annotation[] an = vamsasSet.getAnnotation();
2104 for (int i = 0; i < an.length; i++)
2107 * test if annotation is automatically calculated for this view only
2109 boolean autoForView = false;
2110 if (an[i].getLabel().equals("Quality")
2111 || an[i].getLabel().equals("Conservation")
2112 || an[i].getLabel().equals("Consensus"))
2114 // Kludge for pre 2.5 projects which lacked the autocalculated flag
2116 if (!an[i].hasAutoCalculated())
2118 an[i].setAutoCalculated(true);
2122 || (an[i].hasAutoCalculated() && an[i].isAutoCalculated()))
2124 // remove ID - we don't recover annotation from other views for
2125 // view-specific annotation
2129 // set visiblity for other annotation in this view
2130 if (an[i].getId() != null
2131 && annotationIds.containsKey(an[i].getId()))
2133 jalview.datamodel.AlignmentAnnotation jda = (jalview.datamodel.AlignmentAnnotation) annotationIds
2134 .get(an[i].getId());
2135 // in principle Visible should always be true for annotation displayed
2136 // in multiple views
2137 if (an[i].hasVisible())
2138 jda.visible = an[i].getVisible();
2140 al.addAnnotation(jda);
2144 // Construct new annotation from model.
2145 AnnotationElement[] ae = an[i].getAnnotationElement();
2146 jalview.datamodel.Annotation[] anot = null;
2148 if (!an[i].getScoreOnly())
2150 anot = new jalview.datamodel.Annotation[al.getWidth()];
2151 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
2153 if (ae[aa].getPosition() >= anot.length)
2156 anot[ae[aa].getPosition()] = new jalview.datamodel.Annotation(
2158 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
2159 (ae[aa].getSecondaryStructure() == null || ae[aa]
2160 .getSecondaryStructure().length() == 0) ? ' '
2161 : ae[aa].getSecondaryStructure().charAt(0),
2165 // JBPNote: Consider verifying dataflow for IO of secondary
2166 // structure annotation read from Stockholm files
2167 // this was added to try to ensure that
2168 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
2170 // anot[ae[aa].getPosition()].displayCharacter = "";
2172 anot[ae[aa].getPosition()].colour = new java.awt.Color(
2173 ae[aa].getColour());
2176 jalview.datamodel.AlignmentAnnotation jaa = null;
2178 if (an[i].getGraph())
2180 float llim = 0, hlim = 0;
2181 // if (autoForView || an[i].isAutoCalculated()) {
2184 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2185 an[i].getDescription(), anot, llim, hlim,
2186 an[i].getGraphType());
2188 jaa.graphGroup = an[i].getGraphGroup();
2190 if (an[i].getThresholdLine() != null)
2192 jaa.setThreshold(new jalview.datamodel.GraphLine(an[i]
2193 .getThresholdLine().getValue(), an[i]
2194 .getThresholdLine().getLabel(), new java.awt.Color(
2195 an[i].getThresholdLine().getColour())));
2198 if (autoForView || an[i].isAutoCalculated())
2200 // Hardwire the symbol display line to ensure that labels for
2201 // histograms are displayed
2207 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2208 an[i].getDescription(), anot);
2212 // register new annotation
2213 if (an[i].getId() != null)
2215 annotationIds.put(an[i].getId(), jaa);
2216 jaa.annotationId = an[i].getId();
2218 // recover sequence association
2219 if (an[i].getSequenceRef() != null)
2221 if (al.findName(an[i].getSequenceRef()) != null)
2223 jaa.createSequenceMapping(
2224 al.findName(an[i].getSequenceRef()), 1, true);
2225 al.findName(an[i].getSequenceRef()).addAlignmentAnnotation(
2230 // and make a note of any group association
2231 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
2233 ArrayList<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
2234 .get(an[i].getGroupRef());
2237 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
2238 groupAnnotRefs.put(an[i].getGroupRef(), aal);
2243 if (an[i].hasScore())
2245 jaa.setScore(an[i].getScore());
2247 if (an[i].hasVisible())
2248 jaa.visible = an[i].getVisible();
2250 if (an[i].hasCentreColLabels())
2251 jaa.centreColLabels = an[i].getCentreColLabels();
2253 if (an[i].hasScaleColLabels())
2255 jaa.scaleColLabel = an[i].getScaleColLabels();
2257 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
2259 // newer files have an 'autoCalculated' flag and store calculation
2260 // state in viewport properties
2261 jaa.autoCalculated = true; // means annotation will be marked for
2262 // update at end of load.
2264 if (an[i].hasGraphHeight())
2266 jaa.graphHeight = an[i].getGraphHeight();
2268 if (jaa.autoCalculated)
2270 autoAlan.add(new JvAnnotRow(i, jaa));
2273 // if (!autoForView)
2275 // add autocalculated group annotation and any user created annotation
2277 al.addAnnotation(jaa);
2282 // ///////////////////////
2284 // Create alignment markup and styles for this view
2285 if (jms.getJGroupCount() > 0)
2287 JGroup[] groups = jms.getJGroup();
2289 for (int i = 0; i < groups.length; i++)
2291 ColourSchemeI cs = null;
2293 if (groups[i].getColour() != null)
2295 if (groups[i].getColour().startsWith("ucs"))
2297 cs = GetUserColourScheme(jms, groups[i].getColour());
2301 cs = ColourSchemeProperty.getColour(al, groups[i].getColour());
2306 cs.setThreshold(groups[i].getPidThreshold(), true);
2310 Vector seqs = new Vector();
2312 for (int s = 0; s < groups[i].getSeqCount(); s++)
2314 String seqId = groups[i].getSeq(s) + "";
2315 jalview.datamodel.SequenceI ts = (jalview.datamodel.SequenceI) seqRefIds
2320 seqs.addElement(ts);
2324 if (seqs.size() < 1)
2329 jalview.datamodel.SequenceGroup sg = new jalview.datamodel.SequenceGroup(
2330 seqs, groups[i].getName(), cs, groups[i].getDisplayBoxes(),
2331 groups[i].getDisplayText(), groups[i].getColourText(),
2332 groups[i].getStart(), groups[i].getEnd());
2334 sg.setOutlineColour(new java.awt.Color(groups[i].getOutlineColour()));
2336 sg.textColour = new java.awt.Color(groups[i].getTextCol1());
2337 sg.textColour2 = new java.awt.Color(groups[i].getTextCol2());
2338 sg.setShowNonconserved(groups[i].hasShowUnconserved() ? groups[i]
2339 .isShowUnconserved() : false);
2340 sg.thresholdTextColour = groups[i].getTextColThreshold();
2341 if (groups[i].hasShowConsensusHistogram())
2343 sg.setShowConsensusHistogram(groups[i].isShowConsensusHistogram());
2346 if (groups[i].hasShowSequenceLogo())
2348 sg.setshowSequenceLogo(groups[i].isShowSequenceLogo());
2350 if (groups[i].hasIgnoreGapsinConsensus())
2352 sg.setIgnoreGapsConsensus(groups[i].getIgnoreGapsinConsensus());
2354 if (groups[i].getConsThreshold() != 0)
2356 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
2357 "All", ResidueProperties.propHash, 3,
2358 sg.getSequences(null), 0, sg.getWidth() - 1);
2360 c.verdict(false, 25);
2361 sg.cs.setConservation(c);
2364 if (groups[i].getId() != null && groupAnnotRefs.size() > 0)
2366 // re-instate unique group/annotation row reference
2367 ArrayList<jalview.datamodel.AlignmentAnnotation> jaal = groupAnnotRefs
2368 .get(groups[i].getId());
2371 for (jalview.datamodel.AlignmentAnnotation jaa : jaal)
2374 if (jaa.autoCalculated)
2376 // match up and try to set group autocalc alignment row for this
2378 if (jaa.label.startsWith("Consensus for "))
2380 sg.setConsensus(jaa);
2382 // match up and try to set group autocalc alignment row for this
2384 if (jaa.label.startsWith("Conservation for "))
2386 sg.setConservationRow(jaa);
2397 // ///////////////////////////////
2400 // If we just load in the same jar file again, the sequenceSetId
2401 // will be the same, and we end up with multiple references
2402 // to the same sequenceSet. We must modify this id on load
2403 // so that each load of the file gives a unique id
2404 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
2405 String viewId = (view.getId() == null ? null : view.getId()
2407 AlignFrame af = null;
2408 AlignViewport av = null;
2409 // now check to see if we really need to create a new viewport.
2410 if (multipleView && viewportsAdded.size() == 0)
2412 // We recovered an alignment for which a viewport already exists.
2413 // TODO: fix up any settings necessary for overlaying stored state onto
2414 // state recovered from another document. (may not be necessary).
2415 // we may need a binding from a viewport in memory to one recovered from
2417 // and then recover its containing af to allow the settings to be applied.
2418 // TODO: fix for vamsas demo
2420 .println("About to recover a viewport for existing alignment: Sequence set ID is "
2422 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
2423 if (seqsetobj != null)
2425 if (seqsetobj instanceof String)
2427 uniqueSeqSetId = (String) seqsetobj;
2429 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
2435 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
2440 AlignmentPanel ap = null;
2441 boolean isnewview = true;
2444 // Check to see if this alignment already has a view id == viewId
2445 jalview.gui.AlignmentPanel views[] = Desktop
2446 .getAlignmentPanels(uniqueSeqSetId);
2447 if (views != null && views.length > 0)
2449 for (int v = 0; v < views.length; v++)
2451 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
2453 // recover the existing alignpanel, alignframe, viewport
2454 af = views[v].alignFrame;
2457 // TODO: could even skip resetting view settings if we don't want to
2458 // change the local settings from other jalview processes
2467 af = loadViewport(file, JSEQ, hiddenSeqs, al, jms, view,
2468 uniqueSeqSetId, viewId, autoAlan);
2473 // /////////////////////////////////////
2474 if (loadTreesAndStructures && jms.getTreeCount() > 0)
2478 for (int t = 0; t < jms.getTreeCount(); t++)
2481 Tree tree = jms.getTree(t);
2483 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
2486 tp = af.ShowNewickTree(
2487 new jalview.io.NewickFile(tree.getNewick()),
2488 tree.getTitle(), tree.getWidth(), tree.getHeight(),
2489 tree.getXpos(), tree.getYpos());
2490 if (tree.getId() != null)
2492 // perhaps bind the tree id to something ?
2497 // update local tree attributes ?
2498 // TODO: should check if tp has been manipulated by user - if so its
2499 // settings shouldn't be modified
2500 tp.setTitle(tree.getTitle());
2501 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
2502 .getWidth(), tree.getHeight()));
2503 tp.av = av; // af.viewport; // TODO: verify 'associate with all
2506 tp.treeCanvas.av = av; // af.viewport;
2507 tp.treeCanvas.ap = ap; // af.alignPanel;
2512 warn("There was a problem recovering stored Newick tree: \n"
2513 + tree.getNewick());
2517 tp.fitToWindow.setState(tree.getFitToWindow());
2518 tp.fitToWindow_actionPerformed(null);
2520 if (tree.getFontName() != null)
2522 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
2523 .getFontStyle(), tree.getFontSize()));
2527 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
2528 .getFontStyle(), tree.getFontSize()));
2531 tp.showPlaceholders(tree.getMarkUnlinked());
2532 tp.showBootstrap(tree.getShowBootstrap());
2533 tp.showDistances(tree.getShowDistances());
2535 tp.treeCanvas.threshold = tree.getThreshold();
2537 if (tree.getCurrentTree())
2539 af.viewport.setCurrentTree(tp.getTree());
2543 } catch (Exception ex)
2545 ex.printStackTrace();
2549 // //LOAD STRUCTURES
2550 if (loadTreesAndStructures)
2552 // run through all PDB ids on the alignment, and collect mappings between
2553 // jmol view ids and all sequences referring to it
2554 Hashtable<String, Object[]> jmolViewIds = new Hashtable();
2556 for (int i = 0; i < JSEQ.length; i++)
2558 if (JSEQ[i].getPdbidsCount() > 0)
2560 Pdbids[] ids = JSEQ[i].getPdbids();
2561 for (int p = 0; p < ids.length; p++)
2563 for (int s = 0; s < ids[p].getStructureStateCount(); s++)
2565 // check to see if we haven't already created this structure view
2566 String sviewid = (ids[p].getStructureState(s).getViewId() == null) ? null
2567 : ids[p].getStructureState(s).getViewId()
2569 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
2570 // Originally : ids[p].getFile()
2571 // : TODO: verify external PDB file recovery still works in normal
2572 // jalview project load
2573 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
2574 jpdb.setId(ids[p].getId());
2576 int x = ids[p].getStructureState(s).getXpos();
2577 int y = ids[p].getStructureState(s).getYpos();
2578 int width = ids[p].getStructureState(s).getWidth();
2579 int height = ids[p].getStructureState(s).getHeight();
2581 // Probably don't need to do this anymore...
2582 // Desktop.desktop.getComponentAt(x, y);
2583 // TODO: NOW: check that this recovers the PDB file correctly.
2584 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
2585 jalview.datamodel.SequenceI seq = (jalview.datamodel.SequenceI) seqRefIds
2586 .get(JSEQ[i].getId() + "");
2587 if (sviewid == null)
2589 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
2592 if (!jmolViewIds.containsKey(sviewid))
2594 jmolViewIds.put(sviewid, new Object[]
2596 { x, y, width, height }, "",
2597 new Hashtable<String, Object[]>(), new boolean[]
2598 { false, false, true } });
2599 // Legacy pre-2.7 conversion JAL-823 :
2600 // do not assume any view has to be linked for colour by
2604 // assemble String[] { pdb files }, String[] { id for each
2605 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
2606 // seqs_file 2}, boolean[] {
2607 // linkAlignPanel,superposeWithAlignpanel}} from hash
2608 Object[] jmoldat = (Object[]) jmolViewIds.get(sviewid);
2609 ((boolean[]) jmoldat[3])[0] |= ids[p].getStructureState(s)
2610 .hasAlignwithAlignPanel() ? ids[p].getStructureState(
2611 s).getAlignwithAlignPanel() : false;
2612 // never colour by linked panel if not specified
2613 ((boolean[]) jmoldat[3])[1] |= ids[p].getStructureState(s)
2614 .hasColourwithAlignPanel() ? ids[p]
2615 .getStructureState(s).getColourwithAlignPanel()
2617 // default for pre-2.7 projects is that Jmol colouring is enabled
2618 ((boolean[]) jmoldat[3])[2] &= ids[p].getStructureState(s)
2619 .hasColourByJmol() ? ids[p].getStructureState(s)
2620 .getColourByJmol() : true;
2622 if (((String) jmoldat[1]).length() < ids[p]
2623 .getStructureState(s).getContent().length())
2626 jmoldat[1] = ids[p].getStructureState(s).getContent();
2629 if (ids[p].getFile() != null)
2631 File mapkey=new File(ids[p].getFile());
2632 Object[] seqstrmaps = (Object[]) ((Hashtable) jmoldat[2])
2634 if (seqstrmaps == null)
2636 ((Hashtable) jmoldat[2]).put(
2638 seqstrmaps = new Object[]
2639 { pdbFile, ids[p].getId(), new Vector(),
2642 if (!((Vector) seqstrmaps[2]).contains(seq))
2644 ((Vector) seqstrmaps[2]).addElement(seq);
2645 // ((Vector)seqstrmaps[3]).addElement(n) :
2646 // in principle, chains
2647 // should be stored here : do we need to
2648 // TODO: store and recover seq/pdb_id :
2654 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");
2663 // Instantiate the associated Jmol views
2664 for (Entry<String, Object[]> entry : jmolViewIds.entrySet())
2666 String sviewid = entry.getKey();
2667 Object[] svattrib = entry.getValue();
2668 int[] geom = (int[]) svattrib[0];
2669 String state = (String) svattrib[1];
2670 Hashtable<File, Object[]> oldFiles = (Hashtable<File, Object[]>) svattrib[2];
2671 final boolean useinJmolsuperpos = ((boolean[]) svattrib[3])[0], usetoColourbyseq = ((boolean[]) svattrib[3])[1], jmolColouring = ((boolean[]) svattrib[3])[2];
2672 int x = geom[0], y = geom[1], width = geom[2], height = geom[3];
2673 // collate the pdbfile -> sequence mappings from this view
2674 Vector<String> pdbfilenames = new Vector<String>();
2675 Vector<SequenceI[]> seqmaps = new Vector<SequenceI[]>();
2676 Vector<String> pdbids = new Vector<String>();
2678 // Search to see if we've already created this Jmol view
2679 AppJmol comp = null;
2680 JInternalFrame[] frames = null;
2685 frames = Desktop.desktop.getAllFrames();
2686 } catch (ArrayIndexOutOfBoundsException e)
2688 // occasional No such child exceptions are thrown here...
2693 } catch (Exception f)
2698 } while (frames == null);
2699 // search for any Jmol windows already open from other
2700 // alignment views that exactly match the stored structure state
2701 for (int f = 0; comp == null && f < frames.length; f++)
2703 if (frames[f] instanceof AppJmol)
2706 && ((AppJmol) frames[f]).getViewId().equals(sviewid))
2708 // post jalview 2.4 schema includes structure view id
2709 comp = (AppJmol) frames[f];
2711 else if (frames[f].getX() == x && frames[f].getY() == y
2712 && frames[f].getHeight() == height
2713 && frames[f].getWidth() == width)
2715 comp = (AppJmol) frames[f];
2722 // create a new Jmol window.
2723 // First parse the Jmol state to translate filenames loaded into the
2724 // view, and record the order in which files are shown in the Jmol
2725 // view, so we can add the sequence mappings in same order.
2726 StringBuffer newFileLoc = null;
2727 int cp = 0, ncp, ecp;
2728 while ((ncp = state.indexOf("load ", cp)) > -1)
2730 if (newFileLoc == null)
2732 newFileLoc = new StringBuffer();
2735 // look for next filename in load statement
2736 newFileLoc.append(state.substring(cp,
2737 ncp = (state.indexOf("\"", ncp + 1) + 1)));
2738 String oldfilenam = state.substring(ncp,
2739 ecp = state.indexOf("\"", ncp));
2740 // recover the new mapping data for this old filename
2741 // have to normalize filename - since Jmol and jalview do filename
2742 // translation differently.
2743 Object[] filedat = oldFiles.get(new File(oldfilenam));
2744 newFileLoc.append(Platform.escapeString((String) filedat[0]));
2745 pdbfilenames.addElement((String) filedat[0]);
2746 pdbids.addElement((String) filedat[1]);
2747 seqmaps.addElement((SequenceI[]) ((Vector<SequenceI>) filedat[2])
2748 .toArray(new SequenceI[0]));
2749 newFileLoc.append("\"");
2750 cp = ecp + 1; // advance beyond last \" and set cursor so we can
2751 // look for next file statement.
2752 } while ((ncp=state.indexOf("/*file*/",cp))>-1);
2756 // just append rest of state
2757 newFileLoc.append(state.substring(cp));
2762 .print("Ignoring incomplete Jmol state for PDB ids: ");
2763 newFileLoc = new StringBuffer(state);
2764 newFileLoc.append("; load append ");
2765 for (File id : oldFiles.keySet())
2767 // add this and any other pdb files that should be present in
2769 Object[] filedat = oldFiles.get(id);
2771 newFileLoc.append(((String) filedat[0]));
2772 pdbfilenames.addElement((String) filedat[0]);
2773 pdbids.addElement((String) filedat[1]);
2774 seqmaps.addElement((SequenceI[]) ((Vector<SequenceI>) filedat[2])
2775 .toArray(new SequenceI[0]));
2776 newFileLoc.append(" \"");
2777 newFileLoc.append((String) filedat[0]);
2778 newFileLoc.append("\"");
2781 newFileLoc.append(";");
2784 if (newFileLoc != null)
2786 int histbug = newFileLoc.indexOf("history = ");
2788 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";",
2790 String val = (diff == -1) ? null : newFileLoc.substring(
2792 if (val != null && val.length() >= 4)
2794 if (val.contains("e"))
2796 if (val.trim().equals("true"))
2804 newFileLoc.replace(histbug, diff, val);
2807 // TODO: assemble String[] { pdb files }, String[] { id for each
2808 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
2809 // seqs_file 2}} from hash
2810 final String[] pdbf = (String[]) pdbfilenames
2811 .toArray(new String[pdbfilenames.size()]), id = (String[]) pdbids
2812 .toArray(new String[pdbids.size()]);
2813 final SequenceI[][] sq = (SequenceI[][]) seqmaps
2814 .toArray(new SequenceI[seqmaps.size()][]);
2815 final String fileloc = newFileLoc.toString(), vid = sviewid;
2816 final AlignFrame alf = af;
2817 final java.awt.Rectangle rect = new java.awt.Rectangle(x, y,
2821 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
2825 AppJmol sview = null;
2828 sview = new AppJmol(pdbf, id, sq, alf.alignPanel,
2829 useinJmolsuperpos, usetoColourbyseq,
2830 jmolColouring, fileloc, rect, vid);
2831 } catch (OutOfMemoryError ex)
2833 new OOMWarning("restoring structure view for PDB id "
2834 + id, (OutOfMemoryError) ex.getCause());
2835 if (sview != null && sview.isVisible())
2837 sview.closeViewer();
2838 sview.setVisible(false);
2844 } catch (InvocationTargetException ex)
2846 warn("Unexpected error when opening Jmol view.", ex);
2848 } catch (InterruptedException e)
2850 // e.printStackTrace();
2856 // if (comp != null)
2858 // NOTE: if the jalview project is part of a shared session then
2859 // view synchronization should/could be done here.
2861 // add mapping for sequences in this view to an already open Jmol
2863 for (File id : oldFiles.keySet())
2865 // add this and any other pdb files that should be present in the
2867 Object[] filedat = oldFiles.get(id);
2868 String pdbFile = (String) filedat[0];
2869 SequenceI[] seq = (SequenceI[]) ((Vector<SequenceI>) filedat[2])
2870 .toArray(new SequenceI[0]);
2871 ((AppJmol) comp).jmb.ssm.setMapping(seq, null, pdbFile,
2872 jalview.io.AppletFormatAdapter.FILE);
2873 ((AppJmol) comp).jmb.addSequenceForStructFile(pdbFile, seq);
2875 // and add the AlignmentPanel's reference to the Jmol view
2876 ((AppJmol) comp).addAlignmentPanel(ap);
2877 if (useinJmolsuperpos)
2879 ((AppJmol) comp).useAlignmentPanelForSuperposition(ap);
2883 ((AppJmol) comp).excludeAlignmentPanelForSuperposition(ap);
2885 if (usetoColourbyseq)
2887 ((AppJmol) comp).useAlignmentPanelForColourbyseq(ap,
2892 ((AppJmol) comp).excludeAlignmentPanelForColourbyseq(ap);
2898 // and finally return.
2902 AlignFrame loadViewport(String file, JSeq[] JSEQ, Vector hiddenSeqs,
2903 Alignment al, JalviewModelSequence jms, Viewport view,
2904 String uniqueSeqSetId, String viewId,
2905 ArrayList<JvAnnotRow> autoAlan)
2907 AlignFrame af = null;
2908 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
2909 uniqueSeqSetId, viewId);
2911 af.setFileName(file, "Jalview");
2913 for (int i = 0; i < JSEQ.length; i++)
2915 af.viewport.setSequenceColour(af.viewport.alignment.getSequenceAt(i),
2916 new java.awt.Color(JSEQ[i].getColour()));
2919 af.viewport.gatherViewsHere = view.getGatheredViews();
2921 if (view.getSequenceSetId() != null)
2923 jalview.gui.AlignViewport av = (jalview.gui.AlignViewport) viewportsAdded
2924 .get(uniqueSeqSetId);
2926 af.viewport.sequenceSetID = uniqueSeqSetId;
2929 // propagate shared settings to this new view
2930 af.viewport.historyList = av.historyList;
2931 af.viewport.redoList = av.redoList;
2935 viewportsAdded.put(uniqueSeqSetId, af.viewport);
2937 // TODO: check if this method can be called repeatedly without
2938 // side-effects if alignpanel already registered.
2939 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
2941 // apply Hidden regions to view.
2942 if (hiddenSeqs != null)
2944 for (int s = 0; s < JSEQ.length; s++)
2946 jalview.datamodel.SequenceGroup hidden = new jalview.datamodel.SequenceGroup();
2948 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
2951 al.getSequenceAt(JSEQ[s].getHiddenSequences(r)), false);
2953 af.viewport.hideRepSequences(al.getSequenceAt(s), hidden);
2956 jalview.datamodel.SequenceI[] hseqs = new jalview.datamodel.SequenceI[hiddenSeqs
2959 for (int s = 0; s < hiddenSeqs.size(); s++)
2961 hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s);
2964 af.viewport.hideSequence(hseqs);
2967 // recover view properties and display parameters
2968 if (view.getViewName() != null)
2970 af.viewport.viewName = view.getViewName();
2971 af.setInitialTabVisible();
2973 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
2976 af.viewport.setShowAnnotation(view.getShowAnnotation());
2977 af.viewport.setAbovePIDThreshold(view.getPidSelected());
2979 af.viewport.setColourText(view.getShowColourText());
2981 af.viewport.setConservationSelected(view.getConservationSelected());
2982 af.viewport.setShowJVSuffix(view.getShowFullId());
2983 af.viewport.rightAlignIds = view.getRightAlignIds();
2984 af.viewport.setFont(new java.awt.Font(view.getFontName(), view
2985 .getFontStyle(), view.getFontSize()));
2986 af.alignPanel.fontChanged();
2987 af.viewport.setRenderGaps(view.getRenderGaps());
2988 af.viewport.setWrapAlignment(view.getWrapAlignment());
2989 af.alignPanel.setWrapAlignment(view.getWrapAlignment());
2990 af.viewport.setShowAnnotation(view.getShowAnnotation());
2991 af.alignPanel.setAnnotationVisible(view.getShowAnnotation());
2993 af.viewport.setShowBoxes(view.getShowBoxes());
2995 af.viewport.setShowText(view.getShowText());
2997 af.viewport.textColour = new java.awt.Color(view.getTextCol1());
2998 af.viewport.textColour2 = new java.awt.Color(view.getTextCol2());
2999 af.viewport.thresholdTextColour = view.getTextColThreshold();
3000 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
3001 .isShowUnconserved() : false);
3002 af.viewport.setStartRes(view.getStartRes());
3003 af.viewport.setStartSeq(view.getStartSeq());
3005 ColourSchemeI cs = null;
3006 // apply colourschemes
3007 if (view.getBgColour() != null)
3009 if (view.getBgColour().startsWith("ucs"))
3011 cs = GetUserColourScheme(jms, view.getBgColour());
3013 else if (view.getBgColour().startsWith("Annotation"))
3015 // int find annotation
3016 if (af.viewport.alignment.getAlignmentAnnotation() != null)
3018 for (int i = 0; i < af.viewport.alignment
3019 .getAlignmentAnnotation().length; i++)
3021 if (af.viewport.alignment.getAlignmentAnnotation()[i].label
3022 .equals(view.getAnnotationColours().getAnnotation()))
3024 if (af.viewport.alignment.getAlignmentAnnotation()[i]
3025 .getThreshold() == null)
3027 af.viewport.alignment.getAlignmentAnnotation()[i]
3028 .setThreshold(new jalview.datamodel.GraphLine(view
3029 .getAnnotationColours().getThreshold(),
3030 "Threshold", java.awt.Color.black)
3035 if (view.getAnnotationColours().getColourScheme()
3038 cs = new AnnotationColourGradient(
3039 af.viewport.alignment.getAlignmentAnnotation()[i],
3040 new java.awt.Color(view.getAnnotationColours()
3041 .getMinColour()), new java.awt.Color(view
3042 .getAnnotationColours().getMaxColour()),
3043 view.getAnnotationColours().getAboveThreshold());
3045 else if (view.getAnnotationColours().getColourScheme()
3048 cs = new AnnotationColourGradient(
3049 af.viewport.alignment.getAlignmentAnnotation()[i],
3050 GetUserColourScheme(jms, view
3051 .getAnnotationColours().getColourScheme()),
3052 view.getAnnotationColours().getAboveThreshold());
3056 cs = new AnnotationColourGradient(
3057 af.viewport.alignment.getAlignmentAnnotation()[i],
3058 ColourSchemeProperty.getColour(al, view
3059 .getAnnotationColours().getColourScheme()),
3060 view.getAnnotationColours().getAboveThreshold());
3063 // Also use these settings for all the groups
3064 if (al.getGroups() != null)
3066 for (int g = 0; g < al.getGroups().size(); g++)
3068 jalview.datamodel.SequenceGroup sg = (jalview.datamodel.SequenceGroup) al
3069 .getGroups().elementAt(g);
3078 * (view.getAnnotationColours().getColourScheme().equals("None"
3079 * )) { sg.cs = new AnnotationColourGradient(
3080 * af.viewport.alignment.getAlignmentAnnotation()[i], new
3081 * java.awt.Color(view.getAnnotationColours().
3082 * getMinColour()), new
3083 * java.awt.Color(view.getAnnotationColours().
3085 * view.getAnnotationColours().getAboveThreshold()); } else
3088 sg.cs = new AnnotationColourGradient(
3089 af.viewport.alignment.getAlignmentAnnotation()[i],
3090 sg.cs, view.getAnnotationColours()
3091 .getAboveThreshold());
3105 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
3110 cs.setThreshold(view.getPidThreshold(), true);
3111 cs.setConsensus(af.viewport.hconsensus);
3115 af.viewport.setGlobalColourScheme(cs);
3116 af.viewport.setColourAppliesToAllGroups(false);
3118 if (view.getConservationSelected() && cs != null)
3120 cs.setConservationInc(view.getConsThreshold());
3123 af.changeColour(cs);
3125 af.viewport.setColourAppliesToAllGroups(true);
3127 if (view.getShowSequenceFeatures())
3129 af.viewport.showSequenceFeatures = true;
3131 if (view.hasCentreColumnLabels())
3133 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
3135 if (view.hasIgnoreGapsinConsensus())
3137 af.viewport.ignoreGapsInConsensusCalculation = view
3138 .getIgnoreGapsinConsensus();
3140 if (view.hasFollowHighlight())
3142 af.viewport.followHighlight = view.getFollowHighlight();
3144 if (view.hasFollowSelection())
3146 af.viewport.followSelection = view.getFollowSelection();
3148 if (view.hasShowConsensusHistogram())
3150 af.viewport.setShowConsensusHistogram(view
3151 .getShowConsensusHistogram());
3155 af.viewport.setShowConsensusHistogram(true);
3157 if (view.hasShowSequenceLogo())
3159 af.viewport.showSequenceLogo = view.getShowSequenceLogo();
3163 af.viewport.showSequenceLogo = false;
3165 if (view.hasShowDbRefTooltip())
3167 af.viewport.setShowDbRefs(view.getShowDbRefTooltip());
3169 if (view.hasShowNPfeatureTooltip())
3171 af.viewport.setShowNpFeats(view.hasShowNPfeatureTooltip());
3173 if (view.hasShowGroupConsensus())
3175 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
3179 af.viewport.setShowGroupConsensus(false);
3181 if (view.hasShowGroupConservation())
3183 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
3187 af.viewport.setShowGroupConservation(false);
3190 // recover featre settings
3191 if (jms.getFeatureSettings() != null)
3193 af.viewport.featuresDisplayed = new Hashtable();
3194 String[] renderOrder = new String[jms.getFeatureSettings()
3195 .getSettingCount()];
3196 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
3198 Setting setting = jms.getFeatureSettings().getSetting(fs);
3199 if (setting.hasMincolour())
3201 GraduatedColor gc = setting.hasMin() ? new GraduatedColor(
3202 new java.awt.Color(setting.getMincolour()),
3203 new java.awt.Color(setting.getColour()),
3204 setting.getMin(), setting.getMax()) : new GraduatedColor(
3205 new java.awt.Color(setting.getMincolour()),
3206 new java.awt.Color(setting.getColour()), 0, 1);
3207 if (setting.hasThreshold())
3209 gc.setThresh(setting.getThreshold());
3210 gc.setThreshType(setting.getThreshstate());
3212 gc.setAutoScaled(true); // default
3213 if (setting.hasAutoScale())
3215 gc.setAutoScaled(setting.getAutoScale());
3217 if (setting.hasColourByLabel())
3219 gc.setColourByLabel(setting.getColourByLabel());
3221 // and put in the feature colour table.
3222 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3223 setting.getType(), gc);
3227 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3229 new java.awt.Color(setting.getColour()));
3231 renderOrder[fs] = setting.getType();
3232 if (setting.hasOrder())
3233 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3234 setting.getType(), setting.getOrder());
3236 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3238 fs / jms.getFeatureSettings().getSettingCount());
3239 if (setting.getDisplay())
3241 af.viewport.featuresDisplayed.put(setting.getType(), new Integer(
3242 setting.getColour()));
3245 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().renderOrder = renderOrder;
3247 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().featureGroups = fgtable = new Hashtable();
3248 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
3250 Group grp = jms.getFeatureSettings().getGroup(gs);
3251 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
3255 if (view.getHiddenColumnsCount() > 0)
3257 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
3259 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
3260 .getHiddenColumns(c).getEnd() // +1
3265 af.setMenusFromViewport(af.viewport);
3266 // TODO: we don't need to do this if the viewport is aready visible.
3267 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
3269 af.alignPanel.updateAnnotation(false); // recompute any autoannotation
3270 reorderAutoannotation(af, al, autoAlan);
3274 private void reorderAutoannotation(AlignFrame af, Alignment al,
3275 ArrayList<JvAnnotRow> autoAlan)
3277 // copy over visualization settings for autocalculated annotation in the
3279 if (al.getAlignmentAnnotation() != null)
3282 * Kludge for magic autoannotation names (see JAL-811)
3284 String[] magicNames = new String[]
3285 { "Consensus", "Quality", "Conservation" };
3286 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
3287 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
3288 for (String nm : magicNames)
3290 visan.put(nm, nullAnnot);
3292 for (JvAnnotRow auan : autoAlan)
3294 visan.put(auan.template.label, auan);
3296 int hSize = al.getAlignmentAnnotation().length;
3297 ArrayList<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
3298 for (int h = 0; h < hSize; h++)
3300 jalview.datamodel.AlignmentAnnotation jalan = al
3301 .getAlignmentAnnotation()[h];
3302 if (jalan.autoCalculated)
3304 JvAnnotRow valan = visan.get(jalan.label);
3307 // delete the auto calculated row from the alignment
3308 al.deleteAnnotation(al.getAlignmentAnnotation()[h], false);
3311 if (valan != nullAnnot)
3313 if (jalan != valan.template)
3315 // newly created autoannotation row instance
3316 // so keep a reference to the visible annotation row
3317 // and copy over all relevant attributes
3318 if (valan.template.graphHeight >= 0)
3321 jalan.graphHeight = valan.template.graphHeight;
3323 jalan.visible = valan.template.visible;
3325 reorder.add(new JvAnnotRow(valan.order, jalan));
3330 int s = 0, srt[] = new int[reorder.size()];
3331 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
3332 for (JvAnnotRow jvar : reorder)
3335 srt[s++] = jvar.order;
3338 jalview.util.QuickSort.sort(srt, rws);
3339 // and re-insert the annotation at its correct position
3340 for (JvAnnotRow jvar : rws)
3342 al.addAnnotation(jvar.template, jvar.order);
3344 af.alignPanel.adjustAnnotationHeight();
3348 Hashtable skipList = null;
3351 * TODO remove this method
3354 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
3355 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
3356 * throw new Error("Implementation Error. No skipList defined for this
3357 * Jalview2XML instance."); } return (AlignFrame)
3358 * skipList.get(view.getSequenceSetId()); }
3362 * Check if the Jalview view contained in object should be skipped or not.
3365 * @return true if view's sequenceSetId is a key in skipList
3367 private boolean skipViewport(JalviewModel object)
3369 if (skipList == null)
3374 if (skipList.containsKey(id = object.getJalviewModelSequence()
3375 .getViewport()[0].getSequenceSetId()))
3377 if (Cache.log != null && Cache.log.isDebugEnabled())
3379 Cache.log.debug("Skipping seuqence set id " + id);
3386 public void AddToSkipList(AlignFrame af)
3388 if (skipList == null)
3390 skipList = new Hashtable();
3392 skipList.put(af.getViewport().getSequenceSetId(), af);
3395 public void clearSkipList()
3397 if (skipList != null)
3404 private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al)
3406 jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId());
3407 Vector dseqs = null;
3410 // create a list of new dataset sequences
3411 dseqs = new Vector();
3413 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
3415 Sequence vamsasSeq = vamsasSet.getSequence(i);
3416 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs);
3418 // create a new dataset
3421 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
3422 dseqs.copyInto(dsseqs);
3423 ds = new jalview.datamodel.Alignment(dsseqs);
3424 debug("Created new dataset " + vamsasSet.getDatasetId()
3425 + " for alignment " + System.identityHashCode(al));
3426 addDatasetRef(vamsasSet.getDatasetId(), ds);
3428 // set the dataset for the newly imported alignment.
3429 if (al.getDataset() == null)
3438 * sequence definition to create/merge dataset sequence for
3442 * vector to add new dataset sequence to
3444 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
3445 AlignmentI ds, Vector dseqs)
3447 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
3449 jalview.datamodel.Sequence sq = (jalview.datamodel.Sequence) seqRefIds
3450 .get(vamsasSeq.getId());
3451 jalview.datamodel.SequenceI dsq = null;
3452 if (sq != null && sq.getDatasetSequence() != null)
3454 dsq = (jalview.datamodel.SequenceI) sq.getDatasetSequence();
3457 String sqid = vamsasSeq.getDsseqid();
3460 // need to create or add a new dataset sequence reference to this sequence
3463 dsq = (jalview.datamodel.SequenceI) seqRefIds.get(sqid);
3468 // make a new dataset sequence
3469 dsq = sq.createDatasetSequence();
3472 // make up a new dataset reference for this sequence
3473 sqid = seqHash(dsq);
3475 dsq.setVamsasId(uniqueSetSuffix + sqid);
3476 seqRefIds.put(sqid, dsq);
3481 dseqs.addElement(dsq);
3486 ds.addSequence(dsq);
3492 { // make this dataset sequence sq's dataset sequence
3493 sq.setDatasetSequence(dsq);
3497 // TODO: refactor this as a merge dataset sequence function
3498 // now check that sq (the dataset sequence) sequence really is the union of
3499 // all references to it
3500 // boolean pre = sq.getStart() < dsq.getStart();
3501 // boolean post = sq.getEnd() > dsq.getEnd();
3505 StringBuffer sb = new StringBuffer();
3506 String newres = jalview.analysis.AlignSeq.extractGaps(
3507 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
3508 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
3509 && newres.length() > dsq.getLength())
3511 // Update with the longer sequence.
3515 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
3516 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
3517 * sb.append(newres.substring(newres.length() - sq.getEnd() -
3518 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
3520 dsq.setSequence(sb.toString());
3522 // TODO: merges will never happen if we 'know' we have the real dataset
3523 // sequence - this should be detected when id==dssid
3524 System.err.println("DEBUG Notice: Merged dataset sequence"); // ("
3525 // + (pre ? "prepended" : "") + " "
3526 // + (post ? "appended" : ""));
3531 java.util.Hashtable datasetIds = null;
3533 java.util.IdentityHashMap dataset2Ids = null;
3535 private Alignment getDatasetFor(String datasetId)
3537 if (datasetIds == null)
3539 datasetIds = new Hashtable();
3542 if (datasetIds.containsKey(datasetId))
3544 return (Alignment) datasetIds.get(datasetId);
3549 private void addDatasetRef(String datasetId, Alignment dataset)
3551 if (datasetIds == null)
3553 datasetIds = new Hashtable();
3555 datasetIds.put(datasetId, dataset);
3559 * make a new dataset ID for this jalview dataset alignment
3564 private String getDatasetIdRef(jalview.datamodel.Alignment dataset)
3566 if (dataset.getDataset() != null)
3568 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
3570 String datasetId = makeHashCode(dataset, null);
3571 if (datasetId == null)
3573 // make a new datasetId and record it
3574 if (dataset2Ids == null)
3576 dataset2Ids = new IdentityHashMap();
3580 datasetId = (String) dataset2Ids.get(dataset);
3582 if (datasetId == null)
3584 datasetId = "ds" + dataset2Ids.size() + 1;
3585 dataset2Ids.put(dataset, datasetId);
3591 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
3593 for (int d = 0; d < sequence.getDBRefCount(); d++)
3595 DBRef dr = sequence.getDBRef(d);
3596 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
3597 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
3598 .getVersion(), sequence.getDBRef(d).getAccessionId());
3599 if (dr.getMapping() != null)
3601 entry.setMap(addMapping(dr.getMapping()));
3603 datasetSequence.addDBRef(entry);
3607 private jalview.datamodel.Mapping addMapping(Mapping m)
3609 SequenceI dsto = null;
3610 // Mapping m = dr.getMapping();
3611 int fr[] = new int[m.getMapListFromCount() * 2];
3612 Enumeration f = m.enumerateMapListFrom();
3613 for (int _i = 0; f.hasMoreElements(); _i += 2)
3615 MapListFrom mf = (MapListFrom) f.nextElement();
3616 fr[_i] = mf.getStart();
3617 fr[_i + 1] = mf.getEnd();
3619 int fto[] = new int[m.getMapListToCount() * 2];
3620 f = m.enumerateMapListTo();
3621 for (int _i = 0; f.hasMoreElements(); _i += 2)
3623 MapListTo mf = (MapListTo) f.nextElement();
3624 fto[_i] = mf.getStart();
3625 fto[_i + 1] = mf.getEnd();
3627 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
3628 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
3629 if (m.getMappingChoice() != null)
3631 MappingChoice mc = m.getMappingChoice();
3632 if (mc.getDseqFor() != null)
3634 String dsfor = "" + mc.getDseqFor();
3635 if (seqRefIds.containsKey(dsfor))
3640 jmap.setTo((SequenceI) seqRefIds.get(dsfor));
3644 frefedSequence.add(new Object[]
3651 * local sequence definition
3653 Sequence ms = mc.getSequence();
3654 jalview.datamodel.Sequence djs = null;
3655 String sqid = ms.getDsseqid();
3656 if (sqid != null && sqid.length() > 0)
3659 * recover dataset sequence
3661 djs = (jalview.datamodel.Sequence) seqRefIds.get(sqid);
3666 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
3667 sqid = ((Object) ms).toString(); // make up a new hascode for
3668 // undefined dataset sequence hash
3669 // (unlikely to happen)
3675 * make a new dataset sequence and add it to refIds hash
3677 djs = new jalview.datamodel.Sequence(ms.getName(),
3679 djs.setStart(jmap.getMap().getToLowest());
3680 djs.setEnd(jmap.getMap().getToHighest());
3681 djs.setVamsasId(uniqueSetSuffix + sqid);
3683 seqRefIds.put(sqid, djs);
3686 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
3695 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
3696 boolean keepSeqRefs)
3699 jalview.schemabinding.version2.JalviewModel jm = SaveState(ap, null,
3705 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
3709 uniqueSetSuffix = "";
3710 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
3715 if (this.frefedSequence == null)
3717 frefedSequence = new Vector();
3720 viewportsAdded = new Hashtable();
3722 AlignFrame af = LoadFromObject(jm, null, false, null);
3723 af.alignPanels.clear();
3724 af.closeMenuItem_actionPerformed(true);
3727 * if(ap.av.alignment.getAlignmentAnnotation()!=null) { for(int i=0;
3728 * i<ap.av.alignment.getAlignmentAnnotation().length; i++) {
3729 * if(!ap.av.alignment.getAlignmentAnnotation()[i].autoCalculated) {
3730 * af.alignPanel.av.alignment.getAlignmentAnnotation()[i] =
3731 * ap.av.alignment.getAlignmentAnnotation()[i]; } } }
3734 return af.alignPanel;
3738 * flag indicating if hashtables should be cleared on finalization TODO this
3739 * flag may not be necessary
3741 private boolean _cleartables = true;
3743 private Hashtable jvids2vobj;
3748 * @see java.lang.Object#finalize()
3750 protected void finalize() throws Throwable
3752 // really make sure we have no buried refs left.
3757 this.seqRefIds = null;
3758 this.seqsToIds = null;
3762 private void warn(String msg)
3767 private void warn(String msg, Exception e)
3769 if (Cache.log != null)
3773 Cache.log.warn(msg, e);
3777 Cache.log.warn(msg);
3782 System.err.println("Warning: " + msg);
3785 e.printStackTrace();
3790 private void debug(String string)
3792 debug(string, null);
3795 private void debug(String msg, Exception e)
3797 if (Cache.log != null)
3801 Cache.log.debug(msg, e);
3805 Cache.log.debug(msg);
3810 System.err.println("Warning: " + msg);
3813 e.printStackTrace();
3819 * set the object to ID mapping tables used to write/recover objects and XML
3820 * ID strings for the jalview project. If external tables are provided then
3821 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
3822 * object goes out of scope. - also populates the datasetIds hashtable with
3823 * alignment objects containing dataset sequences
3826 * Map from ID strings to jalview datamodel
3828 * Map from jalview datamodel to ID strings
3832 public void setObjectMappingTables(Hashtable vobj2jv,
3833 IdentityHashMap jv2vobj)
3835 this.jv2vobj = jv2vobj;
3836 this.vobj2jv = vobj2jv;
3837 Iterator ds = jv2vobj.keySet().iterator();
3839 while (ds.hasNext())
3841 Object jvobj = ds.next();
3842 id = jv2vobj.get(jvobj).toString();
3843 if (jvobj instanceof jalview.datamodel.Alignment)
3845 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
3847 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
3850 else if (jvobj instanceof jalview.datamodel.Sequence)
3852 // register sequence object so the XML parser can recover it.
3853 if (seqRefIds == null)
3855 seqRefIds = new Hashtable();
3857 if (seqsToIds == null)
3859 seqsToIds = new IdentityHashMap();
3861 seqRefIds.put(jv2vobj.get(jvobj).toString(), jvobj);
3862 seqsToIds.put(jvobj, id);
3864 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
3866 if (annotationIds == null)
3868 annotationIds = new Hashtable();
3871 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvobj);
3872 jalview.datamodel.AlignmentAnnotation jvann = (jalview.datamodel.AlignmentAnnotation) jvobj;
3873 if (jvann.annotationId == null)
3875 jvann.annotationId = anid;
3877 if (!jvann.annotationId.equals(anid))
3879 // TODO verify that this is the correct behaviour
3880 this.warn("Overriding Annotation ID for " + anid
3881 + " from different id : " + jvann.annotationId);
3882 jvann.annotationId = anid;
3885 else if (jvobj instanceof String)
3887 if (jvids2vobj == null)
3889 jvids2vobj = new Hashtable();
3890 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
3894 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
3899 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
3900 * objects created from the project archive. If string is null (default for
3901 * construction) then suffix will be set automatically.
3905 public void setUniqueSetSuffix(String string)
3907 uniqueSetSuffix = string;
3912 * uses skipList2 as the skipList for skipping views on sequence sets
3913 * associated with keys in the skipList
3917 public void setSkipList(Hashtable skipList2)
3919 skipList = skipList2;