2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)
3 * Copyright (C) 2011 J Procter, AM Waterhouse, J Engelhardt, LM Lui, G Barton, M Clamp, S Searle
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
11 * Jalview is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty
13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along with Jalview. If not, see <http://www.gnu.org/licenses/>.
20 import java.awt.Rectangle;
22 import java.lang.reflect.InvocationTargetException;
25 import java.util.Map.Entry;
26 import java.util.jar.*;
30 import org.exolab.castor.xml.*;
32 import uk.ac.vamsas.objects.utils.MapList;
33 import jalview.bin.Cache;
34 import jalview.datamodel.Alignment;
35 import jalview.datamodel.AlignmentAnnotation;
36 import jalview.datamodel.AlignmentI;
37 import jalview.datamodel.SequenceI;
38 import jalview.schemabinding.version2.*;
39 import jalview.schemes.*;
40 import jalview.structure.StructureSelectionManager;
41 import jalview.util.Platform;
42 import jalview.util.jarInputStreamProvider;
45 * Write out the current jalview desktop state as a Jalview XML stream.
47 * Note: the vamsas objects referred to here are primitive versions of the
48 * VAMSAS project schema elements - they are not the same and most likely never
52 * @version $Revision: 1.134 $
54 public class Jalview2XML
57 * create/return unique hash string for sq
60 * @return new or existing unique string for sq
62 String seqHash(SequenceI sq)
64 if (seqsToIds == null)
68 if (seqsToIds.containsKey(sq))
70 return (String) seqsToIds.get(sq);
74 // create sequential key
75 String key = "sq" + (seqsToIds.size() + 1);
76 key = makeHashCode(sq, key); // check we don't have an external reference
78 seqsToIds.put(sq, key);
87 if (seqRefIds != null)
91 if (seqsToIds != null)
101 warn("clearSeqRefs called when _cleartables was not set. Doing nothing.");
102 // seqRefIds = new Hashtable();
103 // seqsToIds = new IdentityHashMap();
109 if (seqsToIds == null)
111 seqsToIds = new IdentityHashMap();
113 if (seqRefIds == null)
115 seqRefIds = new Hashtable();
120 * SequenceI reference -> XML ID string in jalview XML. Populated as XML reps
121 * of sequence objects are created.
123 java.util.IdentityHashMap seqsToIds = null;
126 * jalview XML Sequence ID to jalview sequence object reference (both dataset
127 * and alignment sequences. Populated as XML reps of sequence objects are
130 java.util.Hashtable seqRefIds = null; // key->SequenceI resolution
132 Vector frefedSequence = null;
134 boolean raiseGUI = true; // whether errors are raised in dialog boxes or not
140 public Jalview2XML(boolean raiseGUI)
142 this.raiseGUI = raiseGUI;
145 public void resolveFrefedSequences()
147 if (frefedSequence.size() > 0)
149 int r = 0, rSize = frefedSequence.size();
152 Object[] ref = (Object[]) frefedSequence.elementAt(r);
155 String sref = (String) ref[0];
156 if (seqRefIds.containsKey(sref))
158 if (ref[1] instanceof jalview.datamodel.Mapping)
160 SequenceI seq = (SequenceI) seqRefIds.get(sref);
161 while (seq.getDatasetSequence() != null)
163 seq = seq.getDatasetSequence();
165 ((jalview.datamodel.Mapping) ref[1]).setTo(seq);
169 if (ref[1] instanceof jalview.datamodel.AlignedCodonFrame)
171 SequenceI seq = (SequenceI) seqRefIds.get(sref);
172 while (seq.getDatasetSequence() != null)
174 seq = seq.getDatasetSequence();
177 && ref[2] instanceof jalview.datamodel.Mapping)
179 jalview.datamodel.Mapping mp = (jalview.datamodel.Mapping) ref[2];
180 ((jalview.datamodel.AlignedCodonFrame) ref[1]).addMap(
181 seq, mp.getTo(), mp.getMap());
186 .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for AlcodonFrames involving "
187 + ref[2].getClass() + " type objects.");
193 .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for "
194 + ref[1].getClass() + " type objects.");
197 frefedSequence.remove(r);
203 .println("IMPLEMENTATION WARNING: Unresolved forward reference for hash string "
205 + " with objecttype "
206 + ref[1].getClass());
213 frefedSequence.remove(r);
221 * This maintains a list of viewports, the key being the seqSetId. Important
222 * to set historyItem and redoList for multiple views
224 Hashtable viewportsAdded;
226 Hashtable annotationIds = new Hashtable();
228 String uniqueSetSuffix = "";
231 * List of pdbfiles added to Jar
233 Vector pdbfiles = null;
235 // SAVES SEVERAL ALIGNMENT WINDOWS TO SAME JARFILE
236 public void SaveState(File statefile)
240 FileOutputStream fos = new FileOutputStream(statefile);
241 JarOutputStream jout = new JarOutputStream(fos);
244 } catch (Exception e)
246 // TODO: inform user of the problem - they need to know if their data was
248 if (errorMessage == null)
250 errorMessage = "Couldn't write Jalview Archive to output file '"
251 + statefile + "' - See console error log for details";
255 errorMessage += "(output file was '" + statefile + "')";
263 * Writes a jalview project archive to the given Jar output stream.
267 public void SaveState(JarOutputStream jout)
269 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
279 // NOTE UTF-8 MUST BE USED FOR WRITING UNICODE CHARS
280 // //////////////////////////////////////////////////
281 // NOTE ALSO new PrintWriter must be used for each new JarEntry
282 PrintWriter out = null;
284 Vector shortNames = new Vector();
287 for (int i = frames.length - 1; i > -1; i--)
289 if (frames[i] instanceof AlignFrame)
291 AlignFrame af = (AlignFrame) frames[i];
294 && skipList.containsKey(af.getViewport()
295 .getSequenceSetId()))
300 String shortName = af.getTitle();
302 if (shortName.indexOf(File.separatorChar) > -1)
304 shortName = shortName.substring(shortName
305 .lastIndexOf(File.separatorChar) + 1);
310 while (shortNames.contains(shortName))
312 if (shortName.endsWith("_" + (count - 1)))
314 shortName = shortName
315 .substring(0, shortName.lastIndexOf("_"));
318 shortName = shortName.concat("_" + count);
322 shortNames.addElement(shortName);
324 if (!shortName.endsWith(".xml"))
326 shortName = shortName + ".xml";
329 int ap, apSize = af.alignPanels.size();
330 for (ap = 0; ap < apSize; ap++)
332 AlignmentPanel apanel = (AlignmentPanel) af.alignPanels
334 String fileName = apSize == 1 ? shortName : ap + shortName;
335 if (!fileName.endsWith(".xml"))
337 fileName = fileName + ".xml";
340 SaveState(apanel, fileName, jout);
347 } catch (Exception foo)
352 } catch (Exception ex)
354 // TODO: inform user of the problem - they need to know if their data was
356 if (errorMessage == null)
358 errorMessage = "Couldn't write Jalview Archive - see error output for details";
360 ex.printStackTrace();
364 // USE THIS METHOD TO SAVE A SINGLE ALIGNMENT WINDOW
365 public boolean SaveAlignment(AlignFrame af, String jarFile,
370 int ap, apSize = af.alignPanels.size();
371 FileOutputStream fos = new FileOutputStream(jarFile);
372 JarOutputStream jout = new JarOutputStream(fos);
373 for (ap = 0; ap < apSize; ap++)
375 AlignmentPanel apanel = (AlignmentPanel) af.alignPanels
377 String jfileName = apSize == 1 ? fileName : fileName + ap;
378 if (!jfileName.endsWith(".xml"))
380 jfileName = jfileName + ".xml";
382 SaveState(apanel, jfileName, jout);
388 } catch (Exception foo)
394 } catch (Exception ex)
396 errorMessage = "Couldn't Write alignment view to Jalview Archive - see error output for details";
397 ex.printStackTrace();
403 * create a JalviewModel from an algnment view and marshall it to a
407 * panel to create jalview model for
409 * name of alignment panel written to output stream
415 public JalviewModel SaveState(AlignmentPanel ap, String fileName,
416 JarOutputStream jout)
419 Vector jmolViewIds = new Vector(); //
420 Vector userColours = new Vector();
422 AlignViewport av = ap.av;
424 JalviewModel object = new JalviewModel();
425 object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel());
427 object.setCreationDate(new java.util.Date(System.currentTimeMillis()));
428 object.setVersion(jalview.bin.Cache.getProperty("VERSION"));
430 jalview.datamodel.AlignmentI jal = av.getAlignment();
432 if (av.hasHiddenRows())
434 jal = jal.getHiddenSequences().getFullAlignment();
437 SequenceSet vamsasSet = new SequenceSet();
439 JalviewModelSequence jms = new JalviewModelSequence();
441 vamsasSet.setGapChar(jal.getGapCharacter() + "");
443 if (jal.getDataset() != null)
445 // dataset id is the dataset's hashcode
446 vamsasSet.setDatasetId(getDatasetIdRef(jal.getDataset()));
448 if (jal.getProperties() != null)
450 Enumeration en = jal.getProperties().keys();
451 while (en.hasMoreElements())
453 String key = en.nextElement().toString();
454 SequenceSetProperties ssp = new SequenceSetProperties();
456 ssp.setValue(jal.getProperties().get(key).toString());
457 vamsasSet.addSequenceSetProperties(ssp);
465 jalview.datamodel.SequenceI jds;
466 for (int i = 0; i < jal.getHeight(); i++)
468 jds = jal.getSequenceAt(i);
471 if (seqRefIds.get(id) != null)
473 // This happens for two reasons: 1. multiple views are being serialised.
474 // 2. the hashCode has collided with another sequence's code. This DOES
475 // HAPPEN! (PF00072.15.stk does this)
476 // JBPNote: Uncomment to debug writing out of files that do not read
477 // back in due to ArrayOutOfBoundExceptions.
478 // System.err.println("vamsasSeq backref: "+id+"");
479 // System.err.println(jds.getName()+"
480 // "+jds.getStart()+"-"+jds.getEnd()+" "+jds.getSequenceAsString());
481 // System.err.println("Hashcode: "+seqHash(jds));
482 // SequenceI rsq = (SequenceI) seqRefIds.get(id + "");
483 // System.err.println(rsq.getName()+"
484 // "+rsq.getStart()+"-"+rsq.getEnd()+" "+rsq.getSequenceAsString());
485 // System.err.println("Hashcode: "+seqHash(rsq));
489 vamsasSeq = createVamsasSequence(id, jds);
490 vamsasSet.addSequence(vamsasSeq);
491 seqRefIds.put(id, jds);
495 jseq.setStart(jds.getStart());
496 jseq.setEnd(jds.getEnd());
497 jseq.setColour(av.getSequenceColour(jds).getRGB());
499 jseq.setId(id); // jseq id should be a string not a number
501 if (av.hasHiddenRows())
503 jseq.setHidden(av.getAlignment().getHiddenSequences().isHidden(jds));
505 if (av.isHiddenRepSequence(jal.getSequenceAt(i)))
507 jalview.datamodel.SequenceI[] reps = av.getRepresentedSequences(jal.getSequenceAt(i)).getSequencesInOrder(jal);
509 for (int h = 0; h < reps.length; h++)
511 if (reps[h] != jal.getSequenceAt(i))
513 jseq.addHiddenSequences(jal.findIndex(reps[h]));
519 if (jds.getDatasetSequence().getSequenceFeatures() != null)
521 jalview.datamodel.SequenceFeature[] sf = jds.getDatasetSequence()
522 .getSequenceFeatures();
524 while (index < sf.length)
526 Features features = new Features();
528 features.setBegin(sf[index].getBegin());
529 features.setEnd(sf[index].getEnd());
530 features.setDescription(sf[index].getDescription());
531 features.setType(sf[index].getType());
532 features.setFeatureGroup(sf[index].getFeatureGroup());
533 features.setScore(sf[index].getScore());
534 if (sf[index].links != null)
536 for (int l = 0; l < sf[index].links.size(); l++)
538 OtherData keyValue = new OtherData();
539 keyValue.setKey("LINK_" + l);
540 keyValue.setValue(sf[index].links.elementAt(l).toString());
541 features.addOtherData(keyValue);
544 if (sf[index].otherDetails != null)
547 Enumeration keys = sf[index].otherDetails.keys();
548 while (keys.hasMoreElements())
550 key = keys.nextElement().toString();
551 OtherData keyValue = new OtherData();
552 keyValue.setKey(key);
553 keyValue.setValue(sf[index].otherDetails.get(key).toString());
554 features.addOtherData(keyValue);
558 jseq.addFeatures(features);
563 if (jds.getDatasetSequence().getPDBId() != null)
565 Enumeration en = jds.getDatasetSequence().getPDBId().elements();
566 while (en.hasMoreElements())
568 Pdbids pdb = new Pdbids();
569 jalview.datamodel.PDBEntry entry = (jalview.datamodel.PDBEntry) en
572 pdb.setId(entry.getId());
573 pdb.setType(entry.getType());
576 // This must have been loaded, is it still visible?
577 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
578 String matchedFile = null;
579 for (int f = frames.length - 1; f > -1; f--)
581 if (frames[f] instanceof AppJmol)
583 jmol = (AppJmol) frames[f];
584 for (int peid = 0; peid < jmol.jmb.pdbentry.length; peid++)
586 if (!jmol.jmb.pdbentry[peid].getId().equals(entry.getId())
587 && !(entry.getId().length() > 4 && entry
591 jmol.jmb.pdbentry[peid].getId()
594 if (matchedFile == null)
596 matchedFile = jmol.jmb.pdbentry[peid].getFile();
598 else if (!matchedFile.equals(jmol.jmb.pdbentry[peid]
602 .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
603 + jmol.jmb.pdbentry[peid].getFile());
607 // can get at it if the ID
608 // match is ambiguous (e.g.
610 String statestring = jmol.jmb.viewer.getStateInfo();
612 for (int smap = 0; smap < jmol.jmb.sequence[peid].length; smap++)
614 // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
615 if (jds==jmol.jmb.sequence[peid][smap])
617 StructureState state = new StructureState();
618 state.setVisible(true);
619 state.setXpos(jmol.getX());
620 state.setYpos(jmol.getY());
621 state.setWidth(jmol.getWidth());
622 state.setHeight(jmol.getHeight());
623 state.setViewId(jmol.getViewId());
624 state.setAlignwithAlignPanel(jmol.isUsedforaligment(ap));
625 state.setColourwithAlignPanel(jmol
626 .isUsedforcolourby(ap));
627 state.setColourByJmol(jmol.isColouredByJmol());
628 if (!jmolViewIds.contains(state.getViewId()))
630 // Make sure we only store a Jmol state once in each XML
632 jmolViewIds.addElement(state.getViewId());
633 state.setContent(statestring.replaceAll("\n", ""));
637 state.setContent("# duplicate state");
639 pdb.addStructureState(state);
646 if (matchedFile != null || entry.getFile() != null)
648 if (entry.getFile() != null)
651 matchedFile = entry.getFile();
653 pdb.setFile(matchedFile); // entry.getFile());
654 if (pdbfiles == null)
656 pdbfiles = new Vector();
659 if (!pdbfiles.contains(entry.getId()))
661 pdbfiles.addElement(entry.getId());
664 File file = new File(matchedFile);
665 if (file.exists() && jout != null)
667 byte[] data = new byte[(int) file.length()];
668 jout.putNextEntry(new JarEntry(entry.getId()));
669 DataInputStream dis = new DataInputStream(
670 new FileInputStream(file));
673 DataOutputStream dout = new DataOutputStream(jout);
674 dout.write(data, 0, data.length);
678 } catch (Exception ex)
680 ex.printStackTrace();
686 if (entry.getProperty() != null)
688 PdbentryItem item = new PdbentryItem();
689 Hashtable properties = entry.getProperty();
690 Enumeration en2 = properties.keys();
691 while (en2.hasMoreElements())
693 Property prop = new Property();
694 String key = en2.nextElement().toString();
696 prop.setValue(properties.get(key).toString());
697 item.addProperty(prop);
699 pdb.addPdbentryItem(item);
709 if (av.hasHiddenRows())
711 jal = av.getAlignment();
714 if (jal.getCodonFrames() != null && jal.getCodonFrames().length > 0)
716 jalview.datamodel.AlignedCodonFrame[] jac = jal.getCodonFrames();
717 for (int i = 0; i < jac.length; i++)
719 AlcodonFrame alc = new AlcodonFrame();
720 vamsasSet.addAlcodonFrame(alc);
721 for (int p = 0; p < jac[i].aaWidth; p++)
723 Alcodon cmap = new Alcodon();
724 if (jac[i].codons[p] != null)
726 // Null codons indicate a gapped column in the translated peptide
728 cmap.setPos1(jac[i].codons[p][0]);
729 cmap.setPos2(jac[i].codons[p][1]);
730 cmap.setPos3(jac[i].codons[p][2]);
732 alc.addAlcodon(cmap);
734 if (jac[i].getProtMappings() != null
735 && jac[i].getProtMappings().length > 0)
737 SequenceI[] dnas = jac[i].getdnaSeqs();
738 jalview.datamodel.Mapping[] pmaps = jac[i].getProtMappings();
739 for (int m = 0; m < pmaps.length; m++)
741 AlcodMap alcmap = new AlcodMap();
742 alcmap.setDnasq(seqHash(dnas[m]));
743 alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
745 alc.addAlcodMap(alcmap);
752 // /////////////////////////////////
753 if (av.currentTree != null)
755 // FIND ANY ASSOCIATED TREES
756 // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
757 if (Desktop.desktop != null)
759 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
761 for (int t = 0; t < frames.length; t++)
763 if (frames[t] instanceof TreePanel)
765 TreePanel tp = (TreePanel) frames[t];
767 if (tp.treeCanvas.av.getAlignment() == jal)
769 Tree tree = new Tree();
770 tree.setTitle(tp.getTitle());
771 tree.setCurrentTree((av.currentTree == tp.getTree()));
772 tree.setNewick(tp.getTree().toString());
773 tree.setThreshold(tp.treeCanvas.threshold);
775 tree.setFitToWindow(tp.fitToWindow.getState());
776 tree.setFontName(tp.getTreeFont().getName());
777 tree.setFontSize(tp.getTreeFont().getSize());
778 tree.setFontStyle(tp.getTreeFont().getStyle());
779 tree.setMarkUnlinked(tp.placeholdersMenu.getState());
781 tree.setShowBootstrap(tp.bootstrapMenu.getState());
782 tree.setShowDistances(tp.distanceMenu.getState());
784 tree.setHeight(tp.getHeight());
785 tree.setWidth(tp.getWidth());
786 tree.setXpos(tp.getX());
787 tree.setYpos(tp.getY());
788 tree.setId(makeHashCode(tp, null));
798 * store forward refs from an annotationRow to any groups
800 IdentityHashMap groupRefs = new IdentityHashMap();
801 if (jal.getAlignmentAnnotation() != null)
803 jalview.datamodel.AlignmentAnnotation[] aa = jal
804 .getAlignmentAnnotation();
806 for (int i = 0; i < aa.length; i++)
808 Annotation an = new Annotation();
810 if (aa[i].annotationId != null)
812 annotationIds.put(aa[i].annotationId, aa[i]);
815 an.setId(aa[i].annotationId);
817 an.setVisible(aa[i].visible);
819 an.setDescription(aa[i].description);
821 if (aa[i].sequenceRef != null)
823 // TODO later annotation sequenceRef should be the XML ID of the
824 // sequence rather than its display name
825 an.setSequenceRef(aa[i].sequenceRef.getName());
827 if (aa[i].groupRef != null)
829 Object groupIdr = groupRefs.get(aa[i].groupRef);
830 if (groupIdr == null)
832 // make a locally unique String
833 groupRefs.put(aa[i].groupRef,
834 groupIdr = ("" + System.currentTimeMillis()
835 + aa[i].groupRef.getName() + groupRefs.size()));
837 an.setGroupRef(groupIdr.toString());
840 // store all visualization attributes for annotation
841 an.setGraphHeight(aa[i].graphHeight);
842 an.setCentreColLabels(aa[i].centreColLabels);
843 an.setScaleColLabels(aa[i].scaleColLabel);
844 an.setShowAllColLabels(aa[i].showAllColLabels);
845 an.setBelowAlignment(aa[i].belowAlignment);
850 an.setGraphType(aa[i].graph);
851 an.setGraphGroup(aa[i].graphGroup);
852 if (aa[i].getThreshold() != null)
854 ThresholdLine line = new ThresholdLine();
855 line.setLabel(aa[i].getThreshold().label);
856 line.setValue(aa[i].getThreshold().value);
857 line.setColour(aa[i].getThreshold().colour.getRGB());
858 an.setThresholdLine(line);
866 an.setLabel(aa[i].label);
868 if (aa[i] == av.getAlignmentQualityAnnot() || aa[i] == av.getAlignmentConservationAnnotation()
869 || aa[i] == av.getAlignmentConsensusAnnotation() || aa[i].autoCalculated)
871 // new way of indicating autocalculated annotation -
872 an.setAutoCalculated(aa[i].autoCalculated);
874 if (aa[i].hasScore())
876 an.setScore(aa[i].getScore());
879 if (aa[i].getCalcId()!=null)
881 an.setCalcId(aa[i].getCalcId());
884 AnnotationElement ae;
885 if (aa[i].annotations != null)
887 an.setScoreOnly(false);
888 for (int a = 0; a < aa[i].annotations.length; a++)
890 if ((aa[i] == null) || (aa[i].annotations[a] == null))
895 ae = new AnnotationElement();
896 if (aa[i].annotations[a].description != null)
897 ae.setDescription(aa[i].annotations[a].description);
898 if (aa[i].annotations[a].displayCharacter != null)
899 ae.setDisplayCharacter(aa[i].annotations[a].displayCharacter);
901 if (!Float.isNaN(aa[i].annotations[a].value))
902 ae.setValue(aa[i].annotations[a].value);
905 if (aa[i].annotations[a].secondaryStructure != ' '
906 && aa[i].annotations[a].secondaryStructure != '\0')
907 ae.setSecondaryStructure(aa[i].annotations[a].secondaryStructure
910 if (aa[i].annotations[a].colour != null
911 && aa[i].annotations[a].colour != java.awt.Color.black)
913 ae.setColour(aa[i].annotations[a].colour.getRGB());
916 an.addAnnotationElement(ae);
917 if (aa[i].autoCalculated)
919 // only write one non-null entry into the annotation row -
920 // sufficient to get the visualization attributes necessary to
928 an.setScoreOnly(true);
930 vamsasSet.addAnnotation(an);
934 if (jal.getGroups() != null)
936 JGroup[] groups = new JGroup[jal.getGroups().size()];
938 for (jalview.datamodel.SequenceGroup sg:jal.getGroups())
940 groups[++i] = new JGroup();
942 groups[i].setStart(sg.getStartRes());
943 groups[i].setEnd(sg.getEndRes());
944 groups[i].setName(sg.getName());
945 if (groupRefs.containsKey(sg))
947 // group has references so set it's ID field
948 groups[i].setId(groupRefs.get(sg).toString());
952 if (sg.cs.conservationApplied())
954 groups[i].setConsThreshold(sg.cs.getConservationInc());
956 if (sg.cs instanceof jalview.schemes.UserColourScheme)
958 groups[i].setColour(SetUserColourScheme(sg.cs, userColours,
964 .setColour(ColourSchemeProperty.getColourName(sg.cs));
967 else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient)
970 .setColour(ColourSchemeProperty
971 .getColourName(((jalview.schemes.AnnotationColourGradient) sg.cs)
974 else if (sg.cs instanceof jalview.schemes.UserColourScheme)
977 .setColour(SetUserColourScheme(sg.cs, userColours, jms));
981 groups[i].setColour(ColourSchemeProperty.getColourName(sg.cs));
984 groups[i].setPidThreshold(sg.cs.getThreshold());
987 groups[i].setOutlineColour(sg.getOutlineColour().getRGB());
988 groups[i].setDisplayBoxes(sg.getDisplayBoxes());
989 groups[i].setDisplayText(sg.getDisplayText());
990 groups[i].setColourText(sg.getColourText());
991 groups[i].setTextCol1(sg.textColour.getRGB());
992 groups[i].setTextCol2(sg.textColour2.getRGB());
993 groups[i].setTextColThreshold(sg.thresholdTextColour);
994 groups[i].setShowUnconserved(sg.getShowNonconserved());
995 groups[i].setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
996 groups[i].setShowConsensusHistogram(sg.isShowConsensusHistogram());
997 groups[i].setShowSequenceLogo(sg.isShowSequenceLogo());
998 for (int s = 0; s < sg.getSize(); s++)
1000 jalview.datamodel.Sequence seq = (jalview.datamodel.Sequence) sg
1002 groups[i].addSeq(seqHash(seq));
1006 jms.setJGroup(groups);
1009 // /////////SAVE VIEWPORT
1010 Viewport view = new Viewport();
1011 view.setTitle(ap.alignFrame.getTitle());
1012 view.setSequenceSetId(makeHashCode(av.getSequenceSetId(),
1013 av.getSequenceSetId()));
1014 view.setId(av.getViewId());
1015 view.setViewName(av.viewName);
1016 view.setGatheredViews(av.gatherViewsHere);
1018 if (ap.av.explodedPosition != null)
1020 view.setXpos(av.explodedPosition.x);
1021 view.setYpos(av.explodedPosition.y);
1022 view.setWidth(av.explodedPosition.width);
1023 view.setHeight(av.explodedPosition.height);
1027 view.setXpos(ap.alignFrame.getBounds().x);
1028 view.setYpos(ap.alignFrame.getBounds().y);
1029 view.setWidth(ap.alignFrame.getBounds().width);
1030 view.setHeight(ap.alignFrame.getBounds().height);
1033 view.setStartRes(av.startRes);
1034 view.setStartSeq(av.startSeq);
1036 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1038 view.setBgColour(SetUserColourScheme(av.getGlobalColourScheme(),
1041 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1043 jalview.schemes.AnnotationColourGradient acg = (jalview.schemes.AnnotationColourGradient) av
1044 .getGlobalColourScheme();
1046 AnnotationColours ac = new AnnotationColours();
1047 ac.setAboveThreshold(acg.getAboveThreshold());
1048 ac.setThreshold(acg.getAnnotationThreshold());
1049 ac.setAnnotation(acg.getAnnotation());
1050 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1052 ac.setColourScheme(SetUserColourScheme(acg.getBaseColour(),
1057 ac.setColourScheme(ColourSchemeProperty.getColourName(acg
1061 ac.setMaxColour(acg.getMaxColour().getRGB());
1062 ac.setMinColour(acg.getMinColour().getRGB());
1063 view.setAnnotationColours(ac);
1064 view.setBgColour("AnnotationColourGradient");
1068 view.setBgColour(ColourSchemeProperty.getColourName(av
1069 .getGlobalColourScheme()));
1072 ColourSchemeI cs = av.getGlobalColourScheme();
1076 if (cs.conservationApplied())
1078 view.setConsThreshold(cs.getConservationInc());
1079 if (cs instanceof jalview.schemes.UserColourScheme)
1081 view.setBgColour(SetUserColourScheme(cs, userColours, jms));
1085 if (cs instanceof ResidueColourScheme)
1087 view.setPidThreshold(cs.getThreshold());
1091 view.setConservationSelected(av.getConservationSelected());
1092 view.setPidSelected(av.getAbovePIDThreshold());
1093 view.setFontName(av.font.getName());
1094 view.setFontSize(av.font.getSize());
1095 view.setFontStyle(av.font.getStyle());
1096 view.setRenderGaps(av.renderGaps);
1097 view.setShowAnnotation(av.getShowAnnotation());
1098 view.setShowBoxes(av.getShowBoxes());
1099 view.setShowColourText(av.getColourText());
1100 view.setShowFullId(av.getShowJVSuffix());
1101 view.setRightAlignIds(av.rightAlignIds);
1102 view.setShowSequenceFeatures(av.showSequenceFeatures);
1103 view.setShowText(av.getShowText());
1104 view.setShowUnconserved(av.getShowUnconserved());
1105 view.setWrapAlignment(av.getWrapAlignment());
1106 view.setTextCol1(av.textColour.getRGB());
1107 view.setTextCol2(av.textColour2.getRGB());
1108 view.setTextColThreshold(av.thresholdTextColour);
1109 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1110 view.setShowSequenceLogo(av.isShowSequenceLogo());
1111 view.setShowGroupConsensus(av.isShowGroupConsensus());
1112 view.setShowGroupConservation(av.isShowGroupConservation());
1113 view.setShowNPfeatureTooltip(av.isShowNpFeats());
1114 view.setShowDbRefTooltip(av.isShowDbRefs());
1115 view.setFollowHighlight(av.followHighlight);
1116 view.setFollowSelection(av.followSelection);
1117 view.setIgnoreGapsinConsensus(av.getIgnoreGapsConsensus());
1118 if (av.featuresDisplayed != null)
1120 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1122 String[] renderOrder = ap.seqPanel.seqCanvas.getFeatureRenderer().renderOrder;
1124 Vector settingsAdded = new Vector();
1125 Object gstyle = null;
1126 GraduatedColor gcol = null;
1127 if (renderOrder != null)
1129 for (int ro = 0; ro < renderOrder.length; ro++)
1131 gstyle = ap.seqPanel.seqCanvas.getFeatureRenderer()
1132 .getFeatureStyle(renderOrder[ro]);
1133 Setting setting = new Setting();
1134 setting.setType(renderOrder[ro]);
1135 if (gstyle instanceof GraduatedColor)
1137 gcol = (GraduatedColor) gstyle;
1138 setting.setColour(gcol.getMaxColor().getRGB());
1139 setting.setMincolour(gcol.getMinColor().getRGB());
1140 setting.setMin(gcol.getMin());
1141 setting.setMax(gcol.getMax());
1142 setting.setColourByLabel(gcol.isColourByLabel());
1143 setting.setAutoScale(gcol.isAutoScale());
1144 setting.setThreshold(gcol.getThresh());
1145 setting.setThreshstate(gcol.getThreshType());
1149 setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer()
1150 .getColour(renderOrder[ro]).getRGB());
1153 setting.setDisplay(av.featuresDisplayed
1154 .containsKey(renderOrder[ro]));
1155 float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer()
1156 .getOrder(renderOrder[ro]);
1159 setting.setOrder(rorder);
1161 fs.addSetting(setting);
1162 settingsAdded.addElement(renderOrder[ro]);
1166 // Make sure we save none displayed feature settings
1167 Enumeration en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureColours
1169 while (en.hasMoreElements())
1171 String key = en.nextElement().toString();
1172 if (settingsAdded.contains(key))
1177 Setting setting = new Setting();
1178 setting.setType(key);
1179 setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer()
1180 .getColour(key).getRGB());
1182 setting.setDisplay(false);
1183 float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer().getOrder(
1187 setting.setOrder(rorder);
1189 fs.addSetting(setting);
1190 settingsAdded.addElement(key);
1192 en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups.keys();
1193 Vector groupsAdded = new Vector();
1194 while (en.hasMoreElements())
1196 String grp = en.nextElement().toString();
1197 if (groupsAdded.contains(grp))
1201 Group g = new Group();
1203 g.setDisplay(((Boolean) ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups
1204 .get(grp)).booleanValue());
1206 groupsAdded.addElement(grp);
1208 jms.setFeatureSettings(fs);
1212 if (av.hasHiddenColumns())
1214 if (av.getColumnSelection() == null
1215 || av.getColumnSelection().getHiddenColumns() == null)
1217 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1221 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1224 int[] region = (int[]) av.getColumnSelection().getHiddenColumns()
1226 HiddenColumns hc = new HiddenColumns();
1227 hc.setStart(region[0]);
1228 hc.setEnd(region[1]);
1229 view.addHiddenColumns(hc);
1234 jms.addViewport(view);
1236 object.setJalviewModelSequence(jms);
1237 object.getVamsasModel().addSequenceSet(vamsasSet);
1239 if (jout != null && fileName != null)
1241 // We may not want to write the object to disk,
1242 // eg we can copy the alignViewport to a new view object
1243 // using save and then load
1246 JarEntry entry = new JarEntry(fileName);
1247 jout.putNextEntry(entry);
1248 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1250 org.exolab.castor.xml.Marshaller marshaller = new org.exolab.castor.xml.Marshaller(
1252 marshaller.marshal(object);
1255 } catch (Exception ex)
1257 // TODO: raise error in GUI if marshalling failed.
1258 ex.printStackTrace();
1265 * External mapping between jalview objects and objects yielding a valid and
1266 * unique object ID string. This is null for normal Jalview project IO, but
1267 * non-null when a jalview project is being read or written as part of a
1270 IdentityHashMap jv2vobj = null;
1273 * Construct a unique ID for jvobj using either existing bindings or if none
1274 * exist, the result of the hashcode call for the object.
1277 * jalview data object
1278 * @return unique ID for referring to jvobj
1280 private String makeHashCode(Object jvobj, String altCode)
1282 if (jv2vobj != null)
1284 Object id = jv2vobj.get(jvobj);
1287 return id.toString();
1289 // check string ID mappings
1290 if (jvids2vobj != null && jvobj instanceof String)
1292 id = jvids2vobj.get(jvobj);
1296 return id.toString();
1298 // give up and warn that something has gone wrong
1299 warn("Cannot find ID for object in external mapping : " + jvobj);
1305 * return local jalview object mapped to ID, if it exists
1309 * @return null or object bound to idcode
1311 private Object retrieveExistingObj(String idcode)
1313 if (idcode != null && vobj2jv != null)
1315 return vobj2jv.get(idcode);
1321 * binding from ID strings from external mapping table to jalview data model
1324 private Hashtable vobj2jv;
1326 private Sequence createVamsasSequence(String id, SequenceI jds)
1328 return createVamsasSequence(true, id, jds, null);
1331 private Sequence createVamsasSequence(boolean recurse, String id,
1332 SequenceI jds, SequenceI parentseq)
1334 Sequence vamsasSeq = new Sequence();
1335 vamsasSeq.setId(id);
1336 vamsasSeq.setName(jds.getName());
1337 vamsasSeq.setSequence(jds.getSequenceAsString());
1338 vamsasSeq.setDescription(jds.getDescription());
1339 jalview.datamodel.DBRefEntry[] dbrefs = null;
1340 if (jds.getDatasetSequence() != null)
1342 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
1343 if (jds.getDatasetSequence().getDBRef() != null)
1345 dbrefs = jds.getDatasetSequence().getDBRef();
1350 vamsasSeq.setDsseqid(id); // so we can tell which sequences really are
1351 // dataset sequences only
1352 dbrefs = jds.getDBRef();
1356 for (int d = 0; d < dbrefs.length; d++)
1358 DBRef dbref = new DBRef();
1359 dbref.setSource(dbrefs[d].getSource());
1360 dbref.setVersion(dbrefs[d].getVersion());
1361 dbref.setAccessionId(dbrefs[d].getAccessionId());
1362 if (dbrefs[d].hasMap())
1364 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
1366 dbref.setMapping(mp);
1368 vamsasSeq.addDBRef(dbref);
1374 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
1375 SequenceI parentseq, SequenceI jds, boolean recurse)
1378 if (jmp.getMap() != null)
1382 jalview.util.MapList mlst = jmp.getMap();
1383 int r[] = mlst.getFromRanges();
1384 for (int s = 0; s < r.length; s += 2)
1386 MapListFrom mfrom = new MapListFrom();
1387 mfrom.setStart(r[s]);
1388 mfrom.setEnd(r[s + 1]);
1389 mp.addMapListFrom(mfrom);
1391 r = mlst.getToRanges();
1392 for (int s = 0; s < r.length; s += 2)
1394 MapListTo mto = new MapListTo();
1396 mto.setEnd(r[s + 1]);
1397 mp.addMapListTo(mto);
1399 mp.setMapFromUnit(mlst.getFromRatio());
1400 mp.setMapToUnit(mlst.getToRatio());
1401 if (jmp.getTo() != null)
1403 MappingChoice mpc = new MappingChoice();
1405 && (parentseq != jmp.getTo() || parentseq
1406 .getDatasetSequence() != jmp.getTo()))
1408 mpc.setSequence(createVamsasSequence(false, seqHash(jmp.getTo()),
1414 SequenceI ps = null;
1415 if (parentseq != jmp.getTo()
1416 && parentseq.getDatasetSequence() != jmp.getTo())
1418 // chaining dbref rather than a handshaking one
1419 jmpid = seqHash(ps = jmp.getTo());
1423 jmpid = seqHash(ps = parentseq);
1425 mpc.setDseqFor(jmpid);
1426 if (!seqRefIds.containsKey(mpc.getDseqFor()))
1428 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
1429 seqRefIds.put(mpc.getDseqFor(), ps);
1433 jalview.bin.Cache.log.debug("reusing DseqFor ID");
1436 mp.setMappingChoice(mpc);
1442 String SetUserColourScheme(jalview.schemes.ColourSchemeI cs,
1443 Vector userColours, JalviewModelSequence jms)
1446 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
1447 boolean newucs = false;
1448 if (!userColours.contains(ucs))
1450 userColours.add(ucs);
1453 id = "ucs" + userColours.indexOf(ucs);
1456 // actually create the scheme's entry in the XML model
1457 java.awt.Color[] colours = ucs.getColours();
1458 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
1459 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
1461 for (int i = 0; i < colours.length; i++)
1463 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1464 col.setName(ResidueProperties.aa[i]);
1465 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1466 jbucs.addColour(col);
1468 if (ucs.getLowerCaseColours() != null)
1470 colours = ucs.getLowerCaseColours();
1471 for (int i = 0; i < colours.length; i++)
1473 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1474 col.setName(ResidueProperties.aa[i].toLowerCase());
1475 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1476 jbucs.addColour(col);
1481 uc.setUserColourScheme(jbucs);
1482 jms.addUserColours(uc);
1488 jalview.schemes.UserColourScheme GetUserColourScheme(
1489 JalviewModelSequence jms, String id)
1491 UserColours[] uc = jms.getUserColours();
1492 UserColours colours = null;
1494 for (int i = 0; i < uc.length; i++)
1496 if (uc[i].getId().equals(id))
1504 java.awt.Color[] newColours = new java.awt.Color[24];
1506 for (int i = 0; i < 24; i++)
1508 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1509 .getUserColourScheme().getColour(i).getRGB(), 16));
1512 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
1515 if (colours.getUserColourScheme().getColourCount() > 24)
1517 newColours = new java.awt.Color[23];
1518 for (int i = 0; i < 23; i++)
1520 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1521 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
1523 ucs.setLowerCaseColours(newColours);
1530 * contains last error message (if any) encountered by XML loader.
1532 String errorMessage = null;
1535 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
1536 * exceptions are raised during project XML parsing
1538 public boolean attemptversion1parse = true;
1541 * Load a jalview project archive from a jar file
1544 * - HTTP URL or filename
1546 public AlignFrame LoadJalviewAlign(final String file)
1549 jalview.gui.AlignFrame af = null;
1553 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
1554 // Workaround is to make sure caller implements the JarInputStreamProvider
1556 // so we can re-open the jar input stream for each entry.
1558 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
1559 af = LoadJalviewAlign(jprovider);
1560 } catch (MalformedURLException e)
1562 errorMessage = "Invalid URL format for '" + file + "'";
1568 private jarInputStreamProvider createjarInputStreamProvider(
1569 final String file) throws MalformedURLException
1572 errorMessage = null;
1573 uniqueSetSuffix = null;
1575 viewportsAdded = null;
1576 frefedSequence = null;
1578 if (file.startsWith("http://"))
1580 url = new URL(file);
1582 final URL _url = url;
1583 return new jarInputStreamProvider()
1586 public JarInputStream getJarInputStream() throws IOException
1590 return new JarInputStream(_url.openStream());
1594 return new JarInputStream(new FileInputStream(file));
1598 public String getFilename()
1606 * Recover jalview session from a jalview project archive. Caller may
1607 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
1608 * themselves. Any null fields will be initialised with default values,
1609 * non-null fields are left alone.
1614 public AlignFrame LoadJalviewAlign(final jarInputStreamProvider jprovider)
1616 errorMessage = null;
1617 if (uniqueSetSuffix == null)
1619 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
1621 if (seqRefIds == null)
1623 seqRefIds = new Hashtable();
1625 if (viewportsAdded == null)
1627 viewportsAdded = new Hashtable();
1629 if (frefedSequence == null)
1631 frefedSequence = new Vector();
1634 jalview.gui.AlignFrame af = null;
1635 Hashtable gatherToThisFrame = new Hashtable();
1636 final String file = jprovider.getFilename();
1639 JarInputStream jin = null;
1640 JarEntry jarentry = null;
1645 jin = jprovider.getJarInputStream();
1646 for (int i = 0; i < entryCount; i++)
1648 jarentry = jin.getNextJarEntry();
1651 if (jarentry != null && jarentry.getName().endsWith(".xml"))
1653 InputStreamReader in = new InputStreamReader(jin, "UTF-8");
1654 JalviewModel object = new JalviewModel();
1656 Unmarshaller unmar = new Unmarshaller(object);
1657 unmar.setValidation(false);
1658 object = (JalviewModel) unmar.unmarshal(in);
1659 if (true) // !skipViewport(object))
1661 af = LoadFromObject(object, file, true, jprovider);
1662 if (af.viewport.gatherViewsHere)
1664 gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
1669 else if (jarentry != null)
1671 // Some other file here.
1674 } while (jarentry != null);
1675 resolveFrefedSequences();
1676 } catch (java.io.FileNotFoundException ex)
1678 ex.printStackTrace();
1679 errorMessage = "Couldn't locate Jalview XML file : " + file;
1680 System.err.println("Exception whilst loading jalview XML file : "
1682 } catch (java.net.UnknownHostException ex)
1684 ex.printStackTrace();
1685 errorMessage = "Couldn't locate Jalview XML file : " + file;
1686 System.err.println("Exception whilst loading jalview XML file : "
1688 } catch (Exception ex)
1690 System.err.println("Parsing as Jalview Version 2 file failed.");
1691 ex.printStackTrace(System.err);
1692 if (attemptversion1parse)
1694 // Is Version 1 Jar file?
1697 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
1698 } catch (Exception ex2)
1700 System.err.println("Exception whilst loading as jalviewXMLV1:");
1701 ex2.printStackTrace();
1705 if (Desktop.instance != null)
1707 Desktop.instance.stopLoading();
1711 System.out.println("Successfully loaded archive file");
1714 ex.printStackTrace();
1716 System.err.println("Exception whilst loading jalview XML file : "
1718 } catch (OutOfMemoryError e)
1720 // Don't use the OOM Window here
1721 errorMessage = "Out of memory loading jalview XML file";
1722 System.err.println("Out of memory whilst loading jalview XML file");
1723 e.printStackTrace();
1726 if (Desktop.instance != null)
1728 Desktop.instance.stopLoading();
1731 Enumeration en = gatherToThisFrame.elements();
1732 while (en.hasMoreElements())
1734 Desktop.instance.gatherViews((AlignFrame) en.nextElement());
1736 if (errorMessage != null)
1744 * check errorMessage for a valid error message and raise an error box in the
1745 * GUI or write the current errorMessage to stderr and then clear the error
1748 protected void reportErrors()
1750 reportErrors(false);
1753 protected void reportErrors(final boolean saving)
1755 if (errorMessage != null)
1757 final String finalErrorMessage = errorMessage;
1760 javax.swing.SwingUtilities.invokeLater(new Runnable()
1764 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1765 finalErrorMessage, "Error "
1766 + (saving ? "saving" : "loading")
1767 + " Jalview file", JOptionPane.WARNING_MESSAGE);
1773 System.err.println("Problem loading Jalview file: " + errorMessage);
1776 errorMessage = null;
1779 Hashtable alreadyLoadedPDB;
1782 * when set, local views will be updated from view stored in JalviewXML
1783 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
1784 * sync if this is set to true.
1786 private boolean updateLocalViews = false;
1788 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
1790 if (alreadyLoadedPDB == null)
1791 alreadyLoadedPDB = new Hashtable();
1793 if (alreadyLoadedPDB.containsKey(pdbId))
1794 return alreadyLoadedPDB.get(pdbId).toString();
1798 JarInputStream jin = jprovider.getJarInputStream();
1800 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
1801 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
1802 * FileInputStream(jprovider)); }
1805 JarEntry entry = null;
1808 entry = jin.getNextJarEntry();
1809 } while (entry != null && !entry.getName().equals(pdbId));
1812 BufferedReader in = new BufferedReader(new InputStreamReader(jin));
1813 File outFile = File.createTempFile("jalview_pdb", ".txt");
1814 outFile.deleteOnExit();
1815 PrintWriter out = new PrintWriter(new FileOutputStream(outFile));
1818 while ((data = in.readLine()) != null)
1825 } catch (Exception foo)
1830 String t=outFile.getAbsolutePath();
1831 alreadyLoadedPDB.put(pdbId, t);
1836 warn("Couldn't find PDB file entry in Jalview Jar for " + pdbId);
1838 } catch (Exception ex)
1840 ex.printStackTrace();
1846 private class JvAnnotRow
1848 public JvAnnotRow(int i, AlignmentAnnotation jaa)
1855 * persisted version of annotation row from which to take vis properties
1857 public jalview.datamodel.AlignmentAnnotation template;
1860 * original position of the annotation row in the alignment
1866 * Load alignment frame from jalview XML DOM object
1871 * filename source string
1872 * @param loadTreesAndStructures
1873 * when false only create Viewport
1875 * data source provider
1876 * @return alignment frame created from view stored in DOM
1878 AlignFrame LoadFromObject(JalviewModel object, String file,
1879 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
1881 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
1882 Sequence[] vamsasSeq = vamsasSet.getSequence();
1884 JalviewModelSequence jms = object.getJalviewModelSequence();
1886 Viewport view = jms.getViewport(0);
1887 // ////////////////////////////////
1890 Vector hiddenSeqs = null;
1891 jalview.datamodel.Sequence jseq;
1893 ArrayList tmpseqs = new ArrayList();
1895 boolean multipleView = false;
1897 JSeq[] JSEQ = object.getJalviewModelSequence().getJSeq();
1898 int vi = 0; // counter in vamsasSeq array
1899 for (int i = 0; i < JSEQ.length; i++)
1901 String seqId = JSEQ[i].getId();
1903 if (seqRefIds.get(seqId) != null)
1905 tmpseqs.add((jalview.datamodel.Sequence) seqRefIds.get(seqId));
1906 multipleView = true;
1910 jseq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
1911 vamsasSeq[vi].getSequence());
1912 jseq.setDescription(vamsasSeq[vi].getDescription());
1913 jseq.setStart(JSEQ[i].getStart());
1914 jseq.setEnd(JSEQ[i].getEnd());
1915 jseq.setVamsasId(uniqueSetSuffix + seqId);
1916 seqRefIds.put(vamsasSeq[vi].getId(), jseq);
1921 if (JSEQ[i].getHidden())
1923 if (hiddenSeqs == null)
1925 hiddenSeqs = new Vector();
1928 hiddenSeqs.addElement((jalview.datamodel.Sequence) seqRefIds
1935 // Create the alignment object from the sequence set
1936 // ///////////////////////////////
1937 jalview.datamodel.Sequence[] orderedSeqs = new jalview.datamodel.Sequence[tmpseqs
1940 tmpseqs.toArray(orderedSeqs);
1942 jalview.datamodel.Alignment al = new jalview.datamodel.Alignment(
1945 // / Add the alignment properties
1946 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
1948 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
1949 al.setProperty(ssp.getKey(), ssp.getValue());
1953 // SequenceFeatures are added to the DatasetSequence,
1954 // so we must create or recover the dataset before loading features
1955 // ///////////////////////////////
1956 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
1958 // older jalview projects do not have a dataset id.
1959 al.setDataset(null);
1963 recoverDatasetFor(vamsasSet, al);
1965 // ///////////////////////////////
1967 Hashtable pdbloaded = new Hashtable();
1970 // load sequence features, database references and any associated PDB
1971 // structures for the alignment
1972 for (int i = 0; i < vamsasSeq.length; i++)
1974 if (JSEQ[i].getFeaturesCount() > 0)
1976 Features[] features = JSEQ[i].getFeatures();
1977 for (int f = 0; f < features.length; f++)
1979 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
1980 features[f].getType(), features[f].getDescription(),
1981 features[f].getStatus(), features[f].getBegin(),
1982 features[f].getEnd(), features[f].getFeatureGroup());
1984 sf.setScore(features[f].getScore());
1985 for (int od = 0; od < features[f].getOtherDataCount(); od++)
1987 OtherData keyValue = features[f].getOtherData(od);
1988 if (keyValue.getKey().startsWith("LINK"))
1990 sf.addLink(keyValue.getValue());
1994 sf.setValue(keyValue.getKey(), keyValue.getValue());
1999 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
2002 if (vamsasSeq[i].getDBRefCount() > 0)
2004 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2006 if (JSEQ[i].getPdbidsCount() > 0)
2008 Pdbids[] ids = JSEQ[i].getPdbids();
2009 for (int p = 0; p < ids.length; p++)
2011 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2012 entry.setId(ids[p].getId());
2013 entry.setType(ids[p].getType());
2014 if (ids[p].getFile() != null)
2016 if (!pdbloaded.containsKey(ids[p].getFile()))
2018 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2022 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2026 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2030 } // end !multipleview
2032 // ///////////////////////////////
2033 // LOAD SEQUENCE MAPPINGS
2035 if (vamsasSet.getAlcodonFrameCount() > 0)
2037 // TODO Potentially this should only be done once for all views of an
2039 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2040 for (int i = 0; i < alc.length; i++)
2042 jalview.datamodel.AlignedCodonFrame cf = new jalview.datamodel.AlignedCodonFrame(
2043 alc[i].getAlcodonCount());
2044 if (alc[i].getAlcodonCount() > 0)
2046 Alcodon[] alcods = alc[i].getAlcodon();
2047 for (int p = 0; p < cf.codons.length; p++)
2049 if (alcods[p].hasPos1() && alcods[p].hasPos2()
2050 && alcods[p].hasPos3())
2052 // translated codons require three valid positions
2053 cf.codons[p] = new int[3];
2054 cf.codons[p][0] = (int) alcods[p].getPos1();
2055 cf.codons[p][1] = (int) alcods[p].getPos2();
2056 cf.codons[p][2] = (int) alcods[p].getPos3();
2060 cf.codons[p] = null;
2064 if (alc[i].getAlcodMapCount() > 0)
2066 AlcodMap[] maps = alc[i].getAlcodMap();
2067 for (int m = 0; m < maps.length; m++)
2069 SequenceI dnaseq = (SequenceI) seqRefIds
2070 .get(maps[m].getDnasq());
2072 jalview.datamodel.Mapping mapping = null;
2073 // attach to dna sequence reference.
2074 if (maps[m].getMapping() != null)
2076 mapping = addMapping(maps[m].getMapping());
2080 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
2085 frefedSequence.add(new Object[]
2086 { maps[m].getDnasq(), cf, mapping });
2090 al.addCodonFrame(cf);
2095 // ////////////////////////////////
2097 ArrayList<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
2099 * store any annotations which forward reference a group's ID
2101 Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>>();
2103 if (vamsasSet.getAnnotationCount() > 0)
2105 Annotation[] an = vamsasSet.getAnnotation();
2107 for (int i = 0; i < an.length; i++)
2110 * test if annotation is automatically calculated for this view only
2112 boolean autoForView = false;
2113 if (an[i].getLabel().equals("Quality")
2114 || an[i].getLabel().equals("Conservation")
2115 || an[i].getLabel().equals("Consensus"))
2117 // Kludge for pre 2.5 projects which lacked the autocalculated flag
2119 if (!an[i].hasAutoCalculated())
2121 an[i].setAutoCalculated(true);
2125 || (an[i].hasAutoCalculated() && an[i].isAutoCalculated()))
2127 // remove ID - we don't recover annotation from other views for
2128 // view-specific annotation
2132 // set visiblity for other annotation in this view
2133 if (an[i].getId() != null
2134 && annotationIds.containsKey(an[i].getId()))
2136 jalview.datamodel.AlignmentAnnotation jda = (jalview.datamodel.AlignmentAnnotation) annotationIds
2137 .get(an[i].getId());
2138 // in principle Visible should always be true for annotation displayed
2139 // in multiple views
2140 if (an[i].hasVisible())
2141 jda.visible = an[i].getVisible();
2143 al.addAnnotation(jda);
2147 // Construct new annotation from model.
2148 AnnotationElement[] ae = an[i].getAnnotationElement();
2149 jalview.datamodel.Annotation[] anot = null;
2151 if (!an[i].getScoreOnly())
2153 anot = new jalview.datamodel.Annotation[al.getWidth()];
2154 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
2156 if (ae[aa].getPosition() >= anot.length)
2159 anot[ae[aa].getPosition()] = new jalview.datamodel.Annotation(
2161 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
2162 (ae[aa].getSecondaryStructure() == null || ae[aa]
2163 .getSecondaryStructure().length() == 0) ? ' '
2164 : ae[aa].getSecondaryStructure().charAt(0),
2168 // JBPNote: Consider verifying dataflow for IO of secondary
2169 // structure annotation read from Stockholm files
2170 // this was added to try to ensure that
2171 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
2173 // anot[ae[aa].getPosition()].displayCharacter = "";
2175 anot[ae[aa].getPosition()].colour = new java.awt.Color(
2176 ae[aa].getColour());
2179 jalview.datamodel.AlignmentAnnotation jaa = null;
2181 if (an[i].getGraph())
2183 float llim = 0, hlim = 0;
2184 // if (autoForView || an[i].isAutoCalculated()) {
2187 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2188 an[i].getDescription(), anot, llim, hlim,
2189 an[i].getGraphType());
2191 jaa.graphGroup = an[i].getGraphGroup();
2193 if (an[i].getThresholdLine() != null)
2195 jaa.setThreshold(new jalview.datamodel.GraphLine(an[i]
2196 .getThresholdLine().getValue(), an[i]
2197 .getThresholdLine().getLabel(), new java.awt.Color(
2198 an[i].getThresholdLine().getColour())));
2201 if (autoForView || an[i].isAutoCalculated())
2203 // Hardwire the symbol display line to ensure that labels for
2204 // histograms are displayed
2210 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2211 an[i].getDescription(), anot);
2215 // register new annotation
2216 if (an[i].getId() != null)
2218 annotationIds.put(an[i].getId(), jaa);
2219 jaa.annotationId = an[i].getId();
2221 // recover sequence association
2222 if (an[i].getSequenceRef() != null)
2224 if (al.findName(an[i].getSequenceRef()) != null)
2226 jaa.createSequenceMapping(
2227 al.findName(an[i].getSequenceRef()), 1, true);
2228 al.findName(an[i].getSequenceRef()).addAlignmentAnnotation(
2233 // and make a note of any group association
2234 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
2236 ArrayList<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
2237 .get(an[i].getGroupRef());
2240 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
2241 groupAnnotRefs.put(an[i].getGroupRef(), aal);
2246 if (an[i].hasScore())
2248 jaa.setScore(an[i].getScore());
2250 if (an[i].hasVisible())
2251 jaa.visible = an[i].getVisible();
2253 if (an[i].hasCentreColLabels())
2254 jaa.centreColLabels = an[i].getCentreColLabels();
2256 if (an[i].hasScaleColLabels())
2258 jaa.scaleColLabel = an[i].getScaleColLabels();
2260 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
2262 // newer files have an 'autoCalculated' flag and store calculation
2263 // state in viewport properties
2264 jaa.autoCalculated = true; // means annotation will be marked for
2265 // update at end of load.
2267 if (an[i].hasGraphHeight())
2269 jaa.graphHeight = an[i].getGraphHeight();
2271 if (an[i].hasBelowAlignment())
2273 jaa.belowAlignment=an[i].isBelowAlignment();
2275 jaa.setCalcId(an[i].getCalcId());
2277 if (jaa.autoCalculated)
2279 autoAlan.add(new JvAnnotRow(i, jaa));
2282 // if (!autoForView)
2284 // add autocalculated group annotation and any user created annotation
2286 al.addAnnotation(jaa);
2291 // ///////////////////////
2293 // Create alignment markup and styles for this view
2294 if (jms.getJGroupCount() > 0)
2296 JGroup[] groups = jms.getJGroup();
2298 for (int i = 0; i < groups.length; i++)
2300 ColourSchemeI cs = null;
2302 if (groups[i].getColour() != null)
2304 if (groups[i].getColour().startsWith("ucs"))
2306 cs = GetUserColourScheme(jms, groups[i].getColour());
2310 cs = ColourSchemeProperty.getColour(al, groups[i].getColour());
2315 cs.setThreshold(groups[i].getPidThreshold(), true);
2319 Vector seqs = new Vector();
2321 for (int s = 0; s < groups[i].getSeqCount(); s++)
2323 String seqId = groups[i].getSeq(s) + "";
2324 jalview.datamodel.SequenceI ts = (jalview.datamodel.SequenceI) seqRefIds
2329 seqs.addElement(ts);
2333 if (seqs.size() < 1)
2338 jalview.datamodel.SequenceGroup sg = new jalview.datamodel.SequenceGroup(
2339 seqs, groups[i].getName(), cs, groups[i].getDisplayBoxes(),
2340 groups[i].getDisplayText(), groups[i].getColourText(),
2341 groups[i].getStart(), groups[i].getEnd());
2343 sg.setOutlineColour(new java.awt.Color(groups[i].getOutlineColour()));
2345 sg.textColour = new java.awt.Color(groups[i].getTextCol1());
2346 sg.textColour2 = new java.awt.Color(groups[i].getTextCol2());
2347 sg.setShowNonconserved(groups[i].hasShowUnconserved() ? groups[i]
2348 .isShowUnconserved() : false);
2349 sg.thresholdTextColour = groups[i].getTextColThreshold();
2350 if (groups[i].hasShowConsensusHistogram())
2352 sg.setShowConsensusHistogram(groups[i].isShowConsensusHistogram());
2355 if (groups[i].hasShowSequenceLogo())
2357 sg.setshowSequenceLogo(groups[i].isShowSequenceLogo());
2359 if (groups[i].hasIgnoreGapsinConsensus())
2361 sg.setIgnoreGapsConsensus(groups[i].getIgnoreGapsinConsensus());
2363 if (groups[i].getConsThreshold() != 0)
2365 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
2366 "All", ResidueProperties.propHash, 3,
2367 sg.getSequences(null), 0, sg.getWidth() - 1);
2369 c.verdict(false, 25);
2370 sg.cs.setConservation(c);
2373 if (groups[i].getId() != null && groupAnnotRefs.size() > 0)
2375 // re-instate unique group/annotation row reference
2376 ArrayList<jalview.datamodel.AlignmentAnnotation> jaal = groupAnnotRefs
2377 .get(groups[i].getId());
2380 for (jalview.datamodel.AlignmentAnnotation jaa : jaal)
2383 if (jaa.autoCalculated)
2385 // match up and try to set group autocalc alignment row for this
2387 if (jaa.label.startsWith("Consensus for "))
2389 sg.setConsensus(jaa);
2391 // match up and try to set group autocalc alignment row for this
2393 if (jaa.label.startsWith("Conservation for "))
2395 sg.setConservationRow(jaa);
2406 // ///////////////////////////////
2409 // If we just load in the same jar file again, the sequenceSetId
2410 // will be the same, and we end up with multiple references
2411 // to the same sequenceSet. We must modify this id on load
2412 // so that each load of the file gives a unique id
2413 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
2414 String viewId = (view.getId() == null ? null : view.getId()
2416 AlignFrame af = null;
2417 AlignViewport av = null;
2418 // now check to see if we really need to create a new viewport.
2419 if (multipleView && viewportsAdded.size() == 0)
2421 // We recovered an alignment for which a viewport already exists.
2422 // TODO: fix up any settings necessary for overlaying stored state onto
2423 // state recovered from another document. (may not be necessary).
2424 // we may need a binding from a viewport in memory to one recovered from
2426 // and then recover its containing af to allow the settings to be applied.
2427 // TODO: fix for vamsas demo
2429 .println("About to recover a viewport for existing alignment: Sequence set ID is "
2431 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
2432 if (seqsetobj != null)
2434 if (seqsetobj instanceof String)
2436 uniqueSeqSetId = (String) seqsetobj;
2438 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
2444 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
2449 AlignmentPanel ap = null;
2450 boolean isnewview = true;
2453 // Check to see if this alignment already has a view id == viewId
2454 jalview.gui.AlignmentPanel views[] = Desktop
2455 .getAlignmentPanels(uniqueSeqSetId);
2456 if (views != null && views.length > 0)
2458 for (int v = 0; v < views.length; v++)
2460 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
2462 // recover the existing alignpanel, alignframe, viewport
2463 af = views[v].alignFrame;
2466 // TODO: could even skip resetting view settings if we don't want to
2467 // change the local settings from other jalview processes
2476 af = loadViewport(file, JSEQ, hiddenSeqs, al, jms, view,
2477 uniqueSeqSetId, viewId, autoAlan);
2482 // /////////////////////////////////////
2483 if (loadTreesAndStructures && jms.getTreeCount() > 0)
2487 for (int t = 0; t < jms.getTreeCount(); t++)
2490 Tree tree = jms.getTree(t);
2492 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
2495 tp = af.ShowNewickTree(
2496 new jalview.io.NewickFile(tree.getNewick()),
2497 tree.getTitle(), tree.getWidth(), tree.getHeight(),
2498 tree.getXpos(), tree.getYpos());
2499 if (tree.getId() != null)
2501 // perhaps bind the tree id to something ?
2506 // update local tree attributes ?
2507 // TODO: should check if tp has been manipulated by user - if so its
2508 // settings shouldn't be modified
2509 tp.setTitle(tree.getTitle());
2510 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
2511 .getWidth(), tree.getHeight()));
2512 tp.av = av; // af.viewport; // TODO: verify 'associate with all
2515 tp.treeCanvas.av = av; // af.viewport;
2516 tp.treeCanvas.ap = ap; // af.alignPanel;
2521 warn("There was a problem recovering stored Newick tree: \n"
2522 + tree.getNewick());
2526 tp.fitToWindow.setState(tree.getFitToWindow());
2527 tp.fitToWindow_actionPerformed(null);
2529 if (tree.getFontName() != null)
2531 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
2532 .getFontStyle(), tree.getFontSize()));
2536 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
2537 .getFontStyle(), tree.getFontSize()));
2540 tp.showPlaceholders(tree.getMarkUnlinked());
2541 tp.showBootstrap(tree.getShowBootstrap());
2542 tp.showDistances(tree.getShowDistances());
2544 tp.treeCanvas.threshold = tree.getThreshold();
2546 if (tree.getCurrentTree())
2548 af.viewport.setCurrentTree(tp.getTree());
2552 } catch (Exception ex)
2554 ex.printStackTrace();
2558 // //LOAD STRUCTURES
2559 if (loadTreesAndStructures)
2561 // run through all PDB ids on the alignment, and collect mappings between
2562 // jmol view ids and all sequences referring to it
2563 Hashtable<String, Object[]> jmolViewIds = new Hashtable();
2565 for (int i = 0; i < JSEQ.length; i++)
2567 if (JSEQ[i].getPdbidsCount() > 0)
2569 Pdbids[] ids = JSEQ[i].getPdbids();
2570 for (int p = 0; p < ids.length; p++)
2572 for (int s = 0; s < ids[p].getStructureStateCount(); s++)
2574 // check to see if we haven't already created this structure view
2575 String sviewid = (ids[p].getStructureState(s).getViewId() == null) ? null
2576 : ids[p].getStructureState(s).getViewId()
2578 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
2579 // Originally : ids[p].getFile()
2580 // : TODO: verify external PDB file recovery still works in normal
2581 // jalview project load
2582 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
2583 jpdb.setId(ids[p].getId());
2585 int x = ids[p].getStructureState(s).getXpos();
2586 int y = ids[p].getStructureState(s).getYpos();
2587 int width = ids[p].getStructureState(s).getWidth();
2588 int height = ids[p].getStructureState(s).getHeight();
2590 // Probably don't need to do this anymore...
2591 // Desktop.desktop.getComponentAt(x, y);
2592 // TODO: NOW: check that this recovers the PDB file correctly.
2593 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
2594 jalview.datamodel.SequenceI seq = (jalview.datamodel.SequenceI) seqRefIds
2595 .get(JSEQ[i].getId() + "");
2596 if (sviewid == null)
2598 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
2601 if (!jmolViewIds.containsKey(sviewid))
2603 jmolViewIds.put(sviewid, new Object[]
2605 { x, y, width, height }, "",
2606 new Hashtable<String, Object[]>(), new boolean[]
2607 { false, false, true } });
2608 // Legacy pre-2.7 conversion JAL-823 :
2609 // do not assume any view has to be linked for colour by
2613 // assemble String[] { pdb files }, String[] { id for each
2614 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
2615 // seqs_file 2}, boolean[] {
2616 // linkAlignPanel,superposeWithAlignpanel}} from hash
2617 Object[] jmoldat = (Object[]) jmolViewIds.get(sviewid);
2618 ((boolean[]) jmoldat[3])[0] |= ids[p].getStructureState(s)
2619 .hasAlignwithAlignPanel() ? ids[p].getStructureState(
2620 s).getAlignwithAlignPanel() : false;
2621 // never colour by linked panel if not specified
2622 ((boolean[]) jmoldat[3])[1] |= ids[p].getStructureState(s)
2623 .hasColourwithAlignPanel() ? ids[p]
2624 .getStructureState(s).getColourwithAlignPanel()
2626 // default for pre-2.7 projects is that Jmol colouring is enabled
2627 ((boolean[]) jmoldat[3])[2] &= ids[p].getStructureState(s)
2628 .hasColourByJmol() ? ids[p].getStructureState(s)
2629 .getColourByJmol() : true;
2631 if (((String) jmoldat[1]).length() < ids[p]
2632 .getStructureState(s).getContent().length())
2635 jmoldat[1] = ids[p].getStructureState(s).getContent();
2638 if (ids[p].getFile() != null)
2640 File mapkey=new File(ids[p].getFile());
2641 Object[] seqstrmaps = (Object[]) ((Hashtable) jmoldat[2])
2643 if (seqstrmaps == null)
2645 ((Hashtable) jmoldat[2]).put(
2647 seqstrmaps = new Object[]
2648 { pdbFile, ids[p].getId(), new Vector(),
2651 if (!((Vector) seqstrmaps[2]).contains(seq))
2653 ((Vector) seqstrmaps[2]).addElement(seq);
2654 // ((Vector)seqstrmaps[3]).addElement(n) :
2655 // in principle, chains
2656 // should be stored here : do we need to
2657 // TODO: store and recover seq/pdb_id :
2663 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");
2672 // Instantiate the associated Jmol views
2673 for (Entry<String, Object[]> entry : jmolViewIds.entrySet())
2675 String sviewid = entry.getKey();
2676 Object[] svattrib = entry.getValue();
2677 int[] geom = (int[]) svattrib[0];
2678 String state = (String) svattrib[1];
2679 Hashtable<File, Object[]> oldFiles = (Hashtable<File, Object[]>) svattrib[2];
2680 final boolean useinJmolsuperpos = ((boolean[]) svattrib[3])[0], usetoColourbyseq = ((boolean[]) svattrib[3])[1], jmolColouring = ((boolean[]) svattrib[3])[2];
2681 int x = geom[0], y = geom[1], width = geom[2], height = geom[3];
2682 // collate the pdbfile -> sequence mappings from this view
2683 Vector<String> pdbfilenames = new Vector<String>();
2684 Vector<SequenceI[]> seqmaps = new Vector<SequenceI[]>();
2685 Vector<String> pdbids = new Vector<String>();
2687 // Search to see if we've already created this Jmol view
2688 AppJmol comp = null;
2689 JInternalFrame[] frames = null;
2694 frames = Desktop.desktop.getAllFrames();
2695 } catch (ArrayIndexOutOfBoundsException e)
2697 // occasional No such child exceptions are thrown here...
2702 } catch (Exception f)
2707 } while (frames == null);
2708 // search for any Jmol windows already open from other
2709 // alignment views that exactly match the stored structure state
2710 for (int f = 0; comp == null && f < frames.length; f++)
2712 if (frames[f] instanceof AppJmol)
2715 && ((AppJmol) frames[f]).getViewId().equals(sviewid))
2717 // post jalview 2.4 schema includes structure view id
2718 comp = (AppJmol) frames[f];
2720 else if (frames[f].getX() == x && frames[f].getY() == y
2721 && frames[f].getHeight() == height
2722 && frames[f].getWidth() == width)
2724 comp = (AppJmol) frames[f];
2731 // create a new Jmol window.
2732 // First parse the Jmol state to translate filenames loaded into the
2733 // view, and record the order in which files are shown in the Jmol
2734 // view, so we can add the sequence mappings in same order.
2735 StringBuffer newFileLoc = null;
2736 int cp = 0, ncp, ecp;
2737 while ((ncp = state.indexOf("load ", cp)) > -1)
2739 if (newFileLoc == null)
2741 newFileLoc = new StringBuffer();
2744 // look for next filename in load statement
2745 newFileLoc.append(state.substring(cp,
2746 ncp = (state.indexOf("\"", ncp + 1) + 1)));
2747 String oldfilenam = state.substring(ncp,
2748 ecp = state.indexOf("\"", ncp));
2749 // recover the new mapping data for this old filename
2750 // have to normalize filename - since Jmol and jalview do filename
2751 // translation differently.
2752 Object[] filedat = oldFiles.get(new File(oldfilenam));
2753 newFileLoc.append(Platform.escapeString((String) filedat[0]));
2754 pdbfilenames.addElement((String) filedat[0]);
2755 pdbids.addElement((String) filedat[1]);
2756 seqmaps.addElement((SequenceI[]) ((Vector<SequenceI>) filedat[2])
2757 .toArray(new SequenceI[0]));
2758 newFileLoc.append("\"");
2759 cp = ecp + 1; // advance beyond last \" and set cursor so we can
2760 // look for next file statement.
2761 } while ((ncp=state.indexOf("/*file*/",cp))>-1);
2765 // just append rest of state
2766 newFileLoc.append(state.substring(cp));
2771 .print("Ignoring incomplete Jmol state for PDB ids: ");
2772 newFileLoc = new StringBuffer(state);
2773 newFileLoc.append("; load append ");
2774 for (File id : oldFiles.keySet())
2776 // add this and any other pdb files that should be present in
2778 Object[] filedat = oldFiles.get(id);
2780 newFileLoc.append(((String) filedat[0]));
2781 pdbfilenames.addElement((String) filedat[0]);
2782 pdbids.addElement((String) filedat[1]);
2783 seqmaps.addElement((SequenceI[]) ((Vector<SequenceI>) filedat[2])
2784 .toArray(new SequenceI[0]));
2785 newFileLoc.append(" \"");
2786 newFileLoc.append((String) filedat[0]);
2787 newFileLoc.append("\"");
2790 newFileLoc.append(";");
2793 if (newFileLoc != null)
2795 int histbug = newFileLoc.indexOf("history = ");
2797 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";",
2799 String val = (diff == -1) ? null : newFileLoc.substring(
2801 if (val != null && val.length() >= 4)
2803 if (val.contains("e"))
2805 if (val.trim().equals("true"))
2813 newFileLoc.replace(histbug, diff, val);
2816 // TODO: assemble String[] { pdb files }, String[] { id for each
2817 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
2818 // seqs_file 2}} from hash
2819 final String[] pdbf = (String[]) pdbfilenames
2820 .toArray(new String[pdbfilenames.size()]), id = (String[]) pdbids
2821 .toArray(new String[pdbids.size()]);
2822 final SequenceI[][] sq = (SequenceI[][]) seqmaps
2823 .toArray(new SequenceI[seqmaps.size()][]);
2824 final String fileloc = newFileLoc.toString(), vid = sviewid;
2825 final AlignFrame alf = af;
2826 final java.awt.Rectangle rect = new java.awt.Rectangle(x, y,
2830 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
2834 AppJmol sview = null;
2837 sview = new AppJmol(pdbf, id, sq, alf.alignPanel,
2838 useinJmolsuperpos, usetoColourbyseq,
2839 jmolColouring, fileloc, rect, vid);
2840 } catch (OutOfMemoryError ex)
2842 new OOMWarning("restoring structure view for PDB id "
2843 + id, (OutOfMemoryError) ex.getCause());
2844 if (sview != null && sview.isVisible())
2846 sview.closeViewer();
2847 sview.setVisible(false);
2853 } catch (InvocationTargetException ex)
2855 warn("Unexpected error when opening Jmol view.", ex);
2857 } catch (InterruptedException e)
2859 // e.printStackTrace();
2865 // if (comp != null)
2867 // NOTE: if the jalview project is part of a shared session then
2868 // view synchronization should/could be done here.
2870 // add mapping for sequences in this view to an already open Jmol
2872 for (File id : oldFiles.keySet())
2874 // add this and any other pdb files that should be present in the
2876 Object[] filedat = oldFiles.get(id);
2877 String pdbFile = (String) filedat[0];
2878 SequenceI[] seq = (SequenceI[]) ((Vector<SequenceI>) filedat[2])
2879 .toArray(new SequenceI[0]);
2880 ((AppJmol) comp).jmb.ssm.setMapping(seq, null, pdbFile,
2881 jalview.io.AppletFormatAdapter.FILE);
2882 ((AppJmol) comp).jmb.addSequenceForStructFile(pdbFile, seq);
2884 // and add the AlignmentPanel's reference to the Jmol view
2885 ((AppJmol) comp).addAlignmentPanel(ap);
2886 if (useinJmolsuperpos)
2888 ((AppJmol) comp).useAlignmentPanelForSuperposition(ap);
2892 ((AppJmol) comp).excludeAlignmentPanelForSuperposition(ap);
2894 if (usetoColourbyseq)
2896 ((AppJmol) comp).useAlignmentPanelForColourbyseq(ap,
2901 ((AppJmol) comp).excludeAlignmentPanelForColourbyseq(ap);
2907 // and finally return.
2911 AlignFrame loadViewport(String file, JSeq[] JSEQ, Vector hiddenSeqs,
2912 Alignment al, JalviewModelSequence jms, Viewport view,
2913 String uniqueSeqSetId, String viewId,
2914 ArrayList<JvAnnotRow> autoAlan)
2916 AlignFrame af = null;
2917 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
2918 uniqueSeqSetId, viewId);
2920 af.setFileName(file, "Jalview");
2922 for (int i = 0; i < JSEQ.length; i++)
2924 af.viewport.setSequenceColour(af.viewport.getAlignment().getSequenceAt(i),
2925 new java.awt.Color(JSEQ[i].getColour()));
2928 af.viewport.gatherViewsHere = view.getGatheredViews();
2930 if (view.getSequenceSetId() != null)
2932 jalview.gui.AlignViewport av = (jalview.gui.AlignViewport) viewportsAdded
2933 .get(uniqueSeqSetId);
2935 af.viewport.setSequenceSetId(uniqueSeqSetId);
2938 // propagate shared settings to this new view
2939 af.viewport.historyList = av.historyList;
2940 af.viewport.redoList = av.redoList;
2944 viewportsAdded.put(uniqueSeqSetId, af.viewport);
2946 // TODO: check if this method can be called repeatedly without
2947 // side-effects if alignpanel already registered.
2948 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
2950 // apply Hidden regions to view.
2951 if (hiddenSeqs != null)
2953 for (int s = 0; s < JSEQ.length; s++)
2955 jalview.datamodel.SequenceGroup hidden = new jalview.datamodel.SequenceGroup();
2957 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
2960 al.getSequenceAt(JSEQ[s].getHiddenSequences(r)), false);
2962 af.viewport.hideRepSequences(al.getSequenceAt(s), hidden);
2965 jalview.datamodel.SequenceI[] hseqs = new jalview.datamodel.SequenceI[hiddenSeqs
2968 for (int s = 0; s < hiddenSeqs.size(); s++)
2970 hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s);
2973 af.viewport.hideSequence(hseqs);
2976 // recover view properties and display parameters
2977 if (view.getViewName() != null)
2979 af.viewport.viewName = view.getViewName();
2980 af.setInitialTabVisible();
2982 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
2985 af.viewport.setShowAnnotation(view.getShowAnnotation());
2986 af.viewport.setAbovePIDThreshold(view.getPidSelected());
2988 af.viewport.setColourText(view.getShowColourText());
2990 af.viewport.setConservationSelected(view.getConservationSelected());
2991 af.viewport.setShowJVSuffix(view.getShowFullId());
2992 af.viewport.rightAlignIds = view.getRightAlignIds();
2993 af.viewport.setFont(new java.awt.Font(view.getFontName(), view
2994 .getFontStyle(), view.getFontSize()));
2995 af.alignPanel.fontChanged();
2996 af.viewport.setRenderGaps(view.getRenderGaps());
2997 af.viewport.setWrapAlignment(view.getWrapAlignment());
2998 af.alignPanel.setWrapAlignment(view.getWrapAlignment());
2999 af.viewport.setShowAnnotation(view.getShowAnnotation());
3000 af.alignPanel.setAnnotationVisible(view.getShowAnnotation());
3002 af.viewport.setShowBoxes(view.getShowBoxes());
3004 af.viewport.setShowText(view.getShowText());
3006 af.viewport.textColour = new java.awt.Color(view.getTextCol1());
3007 af.viewport.textColour2 = new java.awt.Color(view.getTextCol2());
3008 af.viewport.thresholdTextColour = view.getTextColThreshold();
3009 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
3010 .isShowUnconserved() : false);
3011 af.viewport.setStartRes(view.getStartRes());
3012 af.viewport.setStartSeq(view.getStartSeq());
3014 ColourSchemeI cs = null;
3015 // apply colourschemes
3016 if (view.getBgColour() != null)
3018 if (view.getBgColour().startsWith("ucs"))
3020 cs = GetUserColourScheme(jms, view.getBgColour());
3022 else if (view.getBgColour().startsWith("Annotation"))
3024 // int find annotation
3025 if (af.viewport.getAlignment().getAlignmentAnnotation() != null)
3027 for (int i = 0; i < af.viewport.getAlignment()
3028 .getAlignmentAnnotation().length; i++)
3030 if (af.viewport.getAlignment().getAlignmentAnnotation()[i].label
3031 .equals(view.getAnnotationColours().getAnnotation()))
3033 if (af.viewport.getAlignment().getAlignmentAnnotation()[i]
3034 .getThreshold() == null)
3036 af.viewport.getAlignment().getAlignmentAnnotation()[i]
3037 .setThreshold(new jalview.datamodel.GraphLine(view
3038 .getAnnotationColours().getThreshold(),
3039 "Threshold", java.awt.Color.black)
3044 if (view.getAnnotationColours().getColourScheme()
3047 cs = new AnnotationColourGradient(
3048 af.viewport.getAlignment().getAlignmentAnnotation()[i],
3049 new java.awt.Color(view.getAnnotationColours()
3050 .getMinColour()), new java.awt.Color(view
3051 .getAnnotationColours().getMaxColour()),
3052 view.getAnnotationColours().getAboveThreshold());
3054 else if (view.getAnnotationColours().getColourScheme()
3057 cs = new AnnotationColourGradient(
3058 af.viewport.getAlignment().getAlignmentAnnotation()[i],
3059 GetUserColourScheme(jms, view
3060 .getAnnotationColours().getColourScheme()),
3061 view.getAnnotationColours().getAboveThreshold());
3065 cs = new AnnotationColourGradient(
3066 af.viewport.getAlignment().getAlignmentAnnotation()[i],
3067 ColourSchemeProperty.getColour(al, view
3068 .getAnnotationColours().getColourScheme()),
3069 view.getAnnotationColours().getAboveThreshold());
3072 // Also use these settings for all the groups
3073 if (al.getGroups() != null)
3075 for (int g = 0; g < al.getGroups().size(); g++)
3077 jalview.datamodel.SequenceGroup sg = (jalview.datamodel.SequenceGroup) al
3078 .getGroups().elementAt(g);
3087 * (view.getAnnotationColours().getColourScheme().equals("None"
3088 * )) { sg.cs = new AnnotationColourGradient(
3089 * af.viewport.getAlignment().getAlignmentAnnotation()[i], new
3090 * java.awt.Color(view.getAnnotationColours().
3091 * getMinColour()), new
3092 * java.awt.Color(view.getAnnotationColours().
3094 * view.getAnnotationColours().getAboveThreshold()); } else
3097 sg.cs = new AnnotationColourGradient(
3098 af.viewport.getAlignment().getAlignmentAnnotation()[i],
3099 sg.cs, view.getAnnotationColours()
3100 .getAboveThreshold());
3114 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
3119 cs.setThreshold(view.getPidThreshold(), true);
3120 cs.setConsensus(af.viewport.getSequenceConsensusHash());
3124 af.viewport.setGlobalColourScheme(cs);
3125 af.viewport.setColourAppliesToAllGroups(false);
3127 if (view.getConservationSelected() && cs != null)
3129 cs.setConservationInc(view.getConsThreshold());
3132 af.changeColour(cs);
3134 af.viewport.setColourAppliesToAllGroups(true);
3136 if (view.getShowSequenceFeatures())
3138 af.viewport.showSequenceFeatures = true;
3140 if (view.hasCentreColumnLabels())
3142 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
3144 if (view.hasIgnoreGapsinConsensus())
3146 af.viewport.setIgnoreGapsConsensus(view
3147 .getIgnoreGapsinConsensus(), null);
3149 if (view.hasFollowHighlight())
3151 af.viewport.followHighlight = view.getFollowHighlight();
3153 if (view.hasFollowSelection())
3155 af.viewport.followSelection = view.getFollowSelection();
3157 if (view.hasShowConsensusHistogram())
3159 af.viewport.setShowConsensusHistogram(view
3160 .getShowConsensusHistogram());
3164 af.viewport.setShowConsensusHistogram(true);
3166 if (view.hasShowSequenceLogo())
3168 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
3172 af.viewport.setShowSequenceLogo(false);
3174 if (view.hasShowDbRefTooltip())
3176 af.viewport.setShowDbRefs(view.getShowDbRefTooltip());
3178 if (view.hasShowNPfeatureTooltip())
3180 af.viewport.setShowNpFeats(view.hasShowNPfeatureTooltip());
3182 if (view.hasShowGroupConsensus())
3184 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
3188 af.viewport.setShowGroupConsensus(false);
3190 if (view.hasShowGroupConservation())
3192 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
3196 af.viewport.setShowGroupConservation(false);
3199 // recover featre settings
3200 if (jms.getFeatureSettings() != null)
3202 af.viewport.featuresDisplayed = new Hashtable();
3203 String[] renderOrder = new String[jms.getFeatureSettings()
3204 .getSettingCount()];
3205 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
3207 Setting setting = jms.getFeatureSettings().getSetting(fs);
3208 if (setting.hasMincolour())
3210 GraduatedColor gc = setting.hasMin() ? new GraduatedColor(
3211 new java.awt.Color(setting.getMincolour()),
3212 new java.awt.Color(setting.getColour()),
3213 setting.getMin(), setting.getMax()) : new GraduatedColor(
3214 new java.awt.Color(setting.getMincolour()),
3215 new java.awt.Color(setting.getColour()), 0, 1);
3216 if (setting.hasThreshold())
3218 gc.setThresh(setting.getThreshold());
3219 gc.setThreshType(setting.getThreshstate());
3221 gc.setAutoScaled(true); // default
3222 if (setting.hasAutoScale())
3224 gc.setAutoScaled(setting.getAutoScale());
3226 if (setting.hasColourByLabel())
3228 gc.setColourByLabel(setting.getColourByLabel());
3230 // and put in the feature colour table.
3231 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3232 setting.getType(), gc);
3236 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3238 new java.awt.Color(setting.getColour()));
3240 renderOrder[fs] = setting.getType();
3241 if (setting.hasOrder())
3242 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3243 setting.getType(), setting.getOrder());
3245 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3247 fs / jms.getFeatureSettings().getSettingCount());
3248 if (setting.getDisplay())
3250 af.viewport.featuresDisplayed.put(setting.getType(), new Integer(
3251 setting.getColour()));
3254 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().renderOrder = renderOrder;
3256 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().featureGroups = fgtable = new Hashtable();
3257 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
3259 Group grp = jms.getFeatureSettings().getGroup(gs);
3260 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
3264 if (view.getHiddenColumnsCount() > 0)
3266 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
3268 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
3269 .getHiddenColumns(c).getEnd() // +1
3274 af.setMenusFromViewport(af.viewport);
3275 // TODO: we don't need to do this if the viewport is aready visible.
3276 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
3278 af.alignPanel.updateAnnotation(false); // recompute any autoannotation
3279 reorderAutoannotation(af, al, autoAlan);
3283 private void reorderAutoannotation(AlignFrame af, Alignment al,
3284 ArrayList<JvAnnotRow> autoAlan)
3286 // copy over visualization settings for autocalculated annotation in the
3288 if (al.getAlignmentAnnotation() != null)
3291 * Kludge for magic autoannotation names (see JAL-811)
3293 String[] magicNames = new String[]
3294 { "Consensus", "Quality", "Conservation" };
3295 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
3296 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
3297 for (String nm : magicNames)
3299 visan.put(nm, nullAnnot);
3301 for (JvAnnotRow auan : autoAlan)
3303 visan.put(auan.template.label, auan);
3305 int hSize = al.getAlignmentAnnotation().length;
3306 ArrayList<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
3307 for (int h = 0; h < hSize; h++)
3309 jalview.datamodel.AlignmentAnnotation jalan = al
3310 .getAlignmentAnnotation()[h];
3311 if (jalan.autoCalculated)
3313 JvAnnotRow valan = visan.get(jalan.label);
3316 // delete the auto calculated row from the alignment
3317 al.deleteAnnotation(al.getAlignmentAnnotation()[h], false);
3320 if (valan != nullAnnot)
3322 if (jalan != valan.template)
3324 // newly created autoannotation row instance
3325 // so keep a reference to the visible annotation row
3326 // and copy over all relevant attributes
3327 if (valan.template.graphHeight >= 0)
3330 jalan.graphHeight = valan.template.graphHeight;
3332 jalan.visible = valan.template.visible;
3334 reorder.add(new JvAnnotRow(valan.order, jalan));
3339 int s = 0, srt[] = new int[reorder.size()];
3340 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
3341 for (JvAnnotRow jvar : reorder)
3344 srt[s++] = jvar.order;
3347 jalview.util.QuickSort.sort(srt, rws);
3348 // and re-insert the annotation at its correct position
3349 for (JvAnnotRow jvar : rws)
3351 al.addAnnotation(jvar.template, jvar.order);
3353 af.alignPanel.adjustAnnotationHeight();
3357 Hashtable skipList = null;
3360 * TODO remove this method
3363 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
3364 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
3365 * throw new Error("Implementation Error. No skipList defined for this
3366 * Jalview2XML instance."); } return (AlignFrame)
3367 * skipList.get(view.getSequenceSetId()); }
3371 * Check if the Jalview view contained in object should be skipped or not.
3374 * @return true if view's sequenceSetId is a key in skipList
3376 private boolean skipViewport(JalviewModel object)
3378 if (skipList == null)
3383 if (skipList.containsKey(id = object.getJalviewModelSequence()
3384 .getViewport()[0].getSequenceSetId()))
3386 if (Cache.log != null && Cache.log.isDebugEnabled())
3388 Cache.log.debug("Skipping seuqence set id " + id);
3395 public void AddToSkipList(AlignFrame af)
3397 if (skipList == null)
3399 skipList = new Hashtable();
3401 skipList.put(af.getViewport().getSequenceSetId(), af);
3404 public void clearSkipList()
3406 if (skipList != null)
3413 private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al)
3415 jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId());
3416 Vector dseqs = null;
3419 // create a list of new dataset sequences
3420 dseqs = new Vector();
3422 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
3424 Sequence vamsasSeq = vamsasSet.getSequence(i);
3425 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs);
3427 // create a new dataset
3430 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
3431 dseqs.copyInto(dsseqs);
3432 ds = new jalview.datamodel.Alignment(dsseqs);
3433 debug("Created new dataset " + vamsasSet.getDatasetId()
3434 + " for alignment " + System.identityHashCode(al));
3435 addDatasetRef(vamsasSet.getDatasetId(), ds);
3437 // set the dataset for the newly imported alignment.
3438 if (al.getDataset() == null)
3447 * sequence definition to create/merge dataset sequence for
3451 * vector to add new dataset sequence to
3453 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
3454 AlignmentI ds, Vector dseqs)
3456 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
3458 jalview.datamodel.Sequence sq = (jalview.datamodel.Sequence) seqRefIds
3459 .get(vamsasSeq.getId());
3460 jalview.datamodel.SequenceI dsq = null;
3461 if (sq != null && sq.getDatasetSequence() != null)
3463 dsq = (jalview.datamodel.SequenceI) sq.getDatasetSequence();
3466 String sqid = vamsasSeq.getDsseqid();
3469 // need to create or add a new dataset sequence reference to this sequence
3472 dsq = (jalview.datamodel.SequenceI) seqRefIds.get(sqid);
3477 // make a new dataset sequence
3478 dsq = sq.createDatasetSequence();
3481 // make up a new dataset reference for this sequence
3482 sqid = seqHash(dsq);
3484 dsq.setVamsasId(uniqueSetSuffix + sqid);
3485 seqRefIds.put(sqid, dsq);
3490 dseqs.addElement(dsq);
3495 ds.addSequence(dsq);
3501 { // make this dataset sequence sq's dataset sequence
3502 sq.setDatasetSequence(dsq);
3506 // TODO: refactor this as a merge dataset sequence function
3507 // now check that sq (the dataset sequence) sequence really is the union of
3508 // all references to it
3509 // boolean pre = sq.getStart() < dsq.getStart();
3510 // boolean post = sq.getEnd() > dsq.getEnd();
3514 StringBuffer sb = new StringBuffer();
3515 String newres = jalview.analysis.AlignSeq.extractGaps(
3516 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
3517 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
3518 && newres.length() > dsq.getLength())
3520 // Update with the longer sequence.
3524 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
3525 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
3526 * sb.append(newres.substring(newres.length() - sq.getEnd() -
3527 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
3529 dsq.setSequence(sb.toString());
3531 // TODO: merges will never happen if we 'know' we have the real dataset
3532 // sequence - this should be detected when id==dssid
3533 System.err.println("DEBUG Notice: Merged dataset sequence"); // ("
3534 // + (pre ? "prepended" : "") + " "
3535 // + (post ? "appended" : ""));
3540 java.util.Hashtable datasetIds = null;
3542 java.util.IdentityHashMap dataset2Ids = null;
3544 private Alignment getDatasetFor(String datasetId)
3546 if (datasetIds == null)
3548 datasetIds = new Hashtable();
3551 if (datasetIds.containsKey(datasetId))
3553 return (Alignment) datasetIds.get(datasetId);
3558 private void addDatasetRef(String datasetId, Alignment dataset)
3560 if (datasetIds == null)
3562 datasetIds = new Hashtable();
3564 datasetIds.put(datasetId, dataset);
3568 * make a new dataset ID for this jalview dataset alignment
3573 private String getDatasetIdRef(jalview.datamodel.Alignment dataset)
3575 if (dataset.getDataset() != null)
3577 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
3579 String datasetId = makeHashCode(dataset, null);
3580 if (datasetId == null)
3582 // make a new datasetId and record it
3583 if (dataset2Ids == null)
3585 dataset2Ids = new IdentityHashMap();
3589 datasetId = (String) dataset2Ids.get(dataset);
3591 if (datasetId == null)
3593 datasetId = "ds" + dataset2Ids.size() + 1;
3594 dataset2Ids.put(dataset, datasetId);
3600 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
3602 for (int d = 0; d < sequence.getDBRefCount(); d++)
3604 DBRef dr = sequence.getDBRef(d);
3605 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
3606 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
3607 .getVersion(), sequence.getDBRef(d).getAccessionId());
3608 if (dr.getMapping() != null)
3610 entry.setMap(addMapping(dr.getMapping()));
3612 datasetSequence.addDBRef(entry);
3616 private jalview.datamodel.Mapping addMapping(Mapping m)
3618 SequenceI dsto = null;
3619 // Mapping m = dr.getMapping();
3620 int fr[] = new int[m.getMapListFromCount() * 2];
3621 Enumeration f = m.enumerateMapListFrom();
3622 for (int _i = 0; f.hasMoreElements(); _i += 2)
3624 MapListFrom mf = (MapListFrom) f.nextElement();
3625 fr[_i] = mf.getStart();
3626 fr[_i + 1] = mf.getEnd();
3628 int fto[] = new int[m.getMapListToCount() * 2];
3629 f = m.enumerateMapListTo();
3630 for (int _i = 0; f.hasMoreElements(); _i += 2)
3632 MapListTo mf = (MapListTo) f.nextElement();
3633 fto[_i] = mf.getStart();
3634 fto[_i + 1] = mf.getEnd();
3636 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
3637 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
3638 if (m.getMappingChoice() != null)
3640 MappingChoice mc = m.getMappingChoice();
3641 if (mc.getDseqFor() != null)
3643 String dsfor = "" + mc.getDseqFor();
3644 if (seqRefIds.containsKey(dsfor))
3649 jmap.setTo((SequenceI) seqRefIds.get(dsfor));
3653 frefedSequence.add(new Object[]
3660 * local sequence definition
3662 Sequence ms = mc.getSequence();
3663 jalview.datamodel.Sequence djs = null;
3664 String sqid = ms.getDsseqid();
3665 if (sqid != null && sqid.length() > 0)
3668 * recover dataset sequence
3670 djs = (jalview.datamodel.Sequence) seqRefIds.get(sqid);
3675 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
3676 sqid = ((Object) ms).toString(); // make up a new hascode for
3677 // undefined dataset sequence hash
3678 // (unlikely to happen)
3684 * make a new dataset sequence and add it to refIds hash
3686 djs = new jalview.datamodel.Sequence(ms.getName(),
3688 djs.setStart(jmap.getMap().getToLowest());
3689 djs.setEnd(jmap.getMap().getToHighest());
3690 djs.setVamsasId(uniqueSetSuffix + sqid);
3692 seqRefIds.put(sqid, djs);
3695 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
3704 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
3705 boolean keepSeqRefs)
3708 jalview.schemabinding.version2.JalviewModel jm = SaveState(ap, null,
3714 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
3718 uniqueSetSuffix = "";
3719 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
3724 if (this.frefedSequence == null)
3726 frefedSequence = new Vector();
3729 viewportsAdded = new Hashtable();
3731 AlignFrame af = LoadFromObject(jm, null, false, null);
3732 af.alignPanels.clear();
3733 af.closeMenuItem_actionPerformed(true);
3736 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
3737 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
3738 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
3739 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
3740 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
3743 return af.alignPanel;
3747 * flag indicating if hashtables should be cleared on finalization TODO this
3748 * flag may not be necessary
3750 private boolean _cleartables = true;
3752 private Hashtable jvids2vobj;
3757 * @see java.lang.Object#finalize()
3759 protected void finalize() throws Throwable
3761 // really make sure we have no buried refs left.
3766 this.seqRefIds = null;
3767 this.seqsToIds = null;
3771 private void warn(String msg)
3776 private void warn(String msg, Exception e)
3778 if (Cache.log != null)
3782 Cache.log.warn(msg, e);
3786 Cache.log.warn(msg);
3791 System.err.println("Warning: " + msg);
3794 e.printStackTrace();
3799 private void debug(String string)
3801 debug(string, null);
3804 private void debug(String msg, Exception e)
3806 if (Cache.log != null)
3810 Cache.log.debug(msg, e);
3814 Cache.log.debug(msg);
3819 System.err.println("Warning: " + msg);
3822 e.printStackTrace();
3828 * set the object to ID mapping tables used to write/recover objects and XML
3829 * ID strings for the jalview project. If external tables are provided then
3830 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
3831 * object goes out of scope. - also populates the datasetIds hashtable with
3832 * alignment objects containing dataset sequences
3835 * Map from ID strings to jalview datamodel
3837 * Map from jalview datamodel to ID strings
3841 public void setObjectMappingTables(Hashtable vobj2jv,
3842 IdentityHashMap jv2vobj)
3844 this.jv2vobj = jv2vobj;
3845 this.vobj2jv = vobj2jv;
3846 Iterator ds = jv2vobj.keySet().iterator();
3848 while (ds.hasNext())
3850 Object jvobj = ds.next();
3851 id = jv2vobj.get(jvobj).toString();
3852 if (jvobj instanceof jalview.datamodel.Alignment)
3854 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
3856 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
3859 else if (jvobj instanceof jalview.datamodel.Sequence)
3861 // register sequence object so the XML parser can recover it.
3862 if (seqRefIds == null)
3864 seqRefIds = new Hashtable();
3866 if (seqsToIds == null)
3868 seqsToIds = new IdentityHashMap();
3870 seqRefIds.put(jv2vobj.get(jvobj).toString(), jvobj);
3871 seqsToIds.put(jvobj, id);
3873 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
3875 if (annotationIds == null)
3877 annotationIds = new Hashtable();
3880 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvobj);
3881 jalview.datamodel.AlignmentAnnotation jvann = (jalview.datamodel.AlignmentAnnotation) jvobj;
3882 if (jvann.annotationId == null)
3884 jvann.annotationId = anid;
3886 if (!jvann.annotationId.equals(anid))
3888 // TODO verify that this is the correct behaviour
3889 this.warn("Overriding Annotation ID for " + anid
3890 + " from different id : " + jvann.annotationId);
3891 jvann.annotationId = anid;
3894 else if (jvobj instanceof String)
3896 if (jvids2vobj == null)
3898 jvids2vobj = new Hashtable();
3899 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
3903 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
3908 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
3909 * objects created from the project archive. If string is null (default for
3910 * construction) then suffix will be set automatically.
3914 public void setUniqueSetSuffix(String string)
3916 uniqueSetSuffix = string;
3921 * uses skipList2 as the skipList for skipping views on sequence sets
3922 * associated with keys in the skipList
3926 public void setSkipList(Hashtable skipList2)
3928 skipList = skipList2;