2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)
3 * Copyright (C) 2011 J Procter, AM Waterhouse, J Engelhardt, LM Lui, G Barton, M Clamp, S Searle
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
11 * Jalview is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty
13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along with Jalview. If not, see <http://www.gnu.org/licenses/>.
20 import java.awt.Rectangle;
22 import java.lang.reflect.InvocationTargetException;
25 import java.util.Map.Entry;
26 import java.util.jar.*;
30 import org.exolab.castor.xml.*;
32 import jalview.bin.Cache;
33 import jalview.datamodel.Alignment;
34 import jalview.datamodel.AlignmentAnnotation;
35 import jalview.datamodel.AlignmentI;
36 import jalview.datamodel.SequenceI;
37 import jalview.schemabinding.version2.*;
38 import jalview.schemes.*;
39 import jalview.util.Platform;
40 import jalview.util.jarInputStreamProvider;
41 import jalview.ws.jws2.AAConClient;
42 import jalview.ws.jws2.Jws2Discoverer;
43 import jalview.ws.jws2.dm.AAConSettings;
44 import jalview.ws.jws2.jabaws2.Jws2Instance;
45 import jalview.ws.params.ArgumentI;
46 import jalview.ws.params.AutoCalcSetting;
47 import jalview.ws.params.WsParamSetI;
50 * Write out the current jalview desktop state as a Jalview XML stream.
52 * Note: the vamsas objects referred to here are primitive versions of the
53 * VAMSAS project schema elements - they are not the same and most likely never
57 * @version $Revision: 1.134 $
59 public class Jalview2XML
62 * create/return unique hash string for sq
65 * @return new or existing unique string for sq
67 String seqHash(SequenceI sq)
69 if (seqsToIds == null)
73 if (seqsToIds.containsKey(sq))
75 return (String) seqsToIds.get(sq);
79 // create sequential key
80 String key = "sq" + (seqsToIds.size() + 1);
81 key = makeHashCode(sq, key); // check we don't have an external reference
83 seqsToIds.put(sq, key);
92 if (seqRefIds != null)
96 if (seqsToIds != null)
106 warn("clearSeqRefs called when _cleartables was not set. Doing nothing.");
107 // seqRefIds = new Hashtable();
108 // seqsToIds = new IdentityHashMap();
114 if (seqsToIds == null)
116 seqsToIds = new IdentityHashMap();
118 if (seqRefIds == null)
120 seqRefIds = new Hashtable();
125 * SequenceI reference -> XML ID string in jalview XML. Populated as XML reps
126 * of sequence objects are created.
128 java.util.IdentityHashMap seqsToIds = null;
131 * jalview XML Sequence ID to jalview sequence object reference (both dataset
132 * and alignment sequences. Populated as XML reps of sequence objects are
135 java.util.Hashtable seqRefIds = null; // key->SequenceI resolution
137 Vector frefedSequence = null;
139 boolean raiseGUI = true; // whether errors are raised in dialog boxes or not
145 public Jalview2XML(boolean raiseGUI)
147 this.raiseGUI = raiseGUI;
150 public void resolveFrefedSequences()
152 if (frefedSequence.size() > 0)
154 int r = 0, rSize = frefedSequence.size();
157 Object[] ref = (Object[]) frefedSequence.elementAt(r);
160 String sref = (String) ref[0];
161 if (seqRefIds.containsKey(sref))
163 if (ref[1] instanceof jalview.datamodel.Mapping)
165 SequenceI seq = (SequenceI) seqRefIds.get(sref);
166 while (seq.getDatasetSequence() != null)
168 seq = seq.getDatasetSequence();
170 ((jalview.datamodel.Mapping) ref[1]).setTo(seq);
174 if (ref[1] instanceof jalview.datamodel.AlignedCodonFrame)
176 SequenceI seq = (SequenceI) seqRefIds.get(sref);
177 while (seq.getDatasetSequence() != null)
179 seq = seq.getDatasetSequence();
182 && ref[2] instanceof jalview.datamodel.Mapping)
184 jalview.datamodel.Mapping mp = (jalview.datamodel.Mapping) ref[2];
185 ((jalview.datamodel.AlignedCodonFrame) ref[1]).addMap(
186 seq, mp.getTo(), mp.getMap());
191 .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for AlcodonFrames involving "
192 + ref[2].getClass() + " type objects.");
198 .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for "
199 + ref[1].getClass() + " type objects.");
202 frefedSequence.remove(r);
208 .println("IMPLEMENTATION WARNING: Unresolved forward reference for hash string "
210 + " with objecttype "
211 + ref[1].getClass());
218 frefedSequence.remove(r);
226 * This maintains a list of viewports, the key being the seqSetId. Important
227 * to set historyItem and redoList for multiple views
229 Hashtable viewportsAdded;
231 Hashtable annotationIds = new Hashtable();
233 String uniqueSetSuffix = "";
236 * List of pdbfiles added to Jar
238 Vector pdbfiles = null;
240 // SAVES SEVERAL ALIGNMENT WINDOWS TO SAME JARFILE
241 public void SaveState(File statefile)
245 FileOutputStream fos = new FileOutputStream(statefile);
246 JarOutputStream jout = new JarOutputStream(fos);
249 } catch (Exception e)
251 // TODO: inform user of the problem - they need to know if their data was
253 if (errorMessage == null)
255 errorMessage = "Couldn't write Jalview Archive to output file '"
256 + statefile + "' - See console error log for details";
260 errorMessage += "(output file was '" + statefile + "')";
268 * Writes a jalview project archive to the given Jar output stream.
272 public void SaveState(JarOutputStream jout)
274 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
284 // NOTE UTF-8 MUST BE USED FOR WRITING UNICODE CHARS
285 // //////////////////////////////////////////////////
286 // NOTE ALSO new PrintWriter must be used for each new JarEntry
287 PrintWriter out = null;
289 Vector shortNames = new Vector();
292 for (int i = frames.length - 1; i > -1; i--)
294 if (frames[i] instanceof AlignFrame)
296 AlignFrame af = (AlignFrame) frames[i];
299 && skipList.containsKey(af.getViewport()
300 .getSequenceSetId()))
305 String shortName = af.getTitle();
307 if (shortName.indexOf(File.separatorChar) > -1)
309 shortName = shortName.substring(shortName
310 .lastIndexOf(File.separatorChar) + 1);
315 while (shortNames.contains(shortName))
317 if (shortName.endsWith("_" + (count - 1)))
319 shortName = shortName
320 .substring(0, shortName.lastIndexOf("_"));
323 shortName = shortName.concat("_" + count);
327 shortNames.addElement(shortName);
329 if (!shortName.endsWith(".xml"))
331 shortName = shortName + ".xml";
334 int ap, apSize = af.alignPanels.size();
335 for (ap = 0; ap < apSize; ap++)
337 AlignmentPanel apanel = (AlignmentPanel) af.alignPanels
339 String fileName = apSize == 1 ? shortName : ap + shortName;
340 if (!fileName.endsWith(".xml"))
342 fileName = fileName + ".xml";
345 SaveState(apanel, fileName, jout);
352 } catch (Exception foo)
357 } catch (Exception ex)
359 // TODO: inform user of the problem - they need to know if their data was
361 if (errorMessage == null)
363 errorMessage = "Couldn't write Jalview Archive - see error output for details";
365 ex.printStackTrace();
369 // USE THIS METHOD TO SAVE A SINGLE ALIGNMENT WINDOW
370 public boolean SaveAlignment(AlignFrame af, String jarFile,
375 int ap, apSize = af.alignPanels.size();
376 FileOutputStream fos = new FileOutputStream(jarFile);
377 JarOutputStream jout = new JarOutputStream(fos);
378 for (ap = 0; ap < apSize; ap++)
380 AlignmentPanel apanel = (AlignmentPanel) af.alignPanels
382 String jfileName = apSize == 1 ? fileName : fileName + ap;
383 if (!jfileName.endsWith(".xml"))
385 jfileName = jfileName + ".xml";
387 SaveState(apanel, jfileName, jout);
393 } catch (Exception foo)
399 } catch (Exception ex)
401 errorMessage = "Couldn't Write alignment view to Jalview Archive - see error output for details";
402 ex.printStackTrace();
408 * create a JalviewModel from an algnment view and marshall it to a
412 * panel to create jalview model for
414 * name of alignment panel written to output stream
420 public JalviewModel SaveState(AlignmentPanel ap, String fileName,
421 JarOutputStream jout)
424 Vector jmolViewIds = new Vector(); //
425 Vector userColours = new Vector();
427 AlignViewport av = ap.av;
429 JalviewModel object = new JalviewModel();
430 object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel());
432 object.setCreationDate(new java.util.Date(System.currentTimeMillis()));
433 object.setVersion(jalview.bin.Cache.getProperty("VERSION"));
435 jalview.datamodel.AlignmentI jal = av.getAlignment();
437 if (av.hasHiddenRows())
439 jal = jal.getHiddenSequences().getFullAlignment();
442 SequenceSet vamsasSet = new SequenceSet();
444 JalviewModelSequence jms = new JalviewModelSequence();
446 vamsasSet.setGapChar(jal.getGapCharacter() + "");
448 if (jal.getDataset() != null)
450 // dataset id is the dataset's hashcode
451 vamsasSet.setDatasetId(getDatasetIdRef(jal.getDataset()));
453 if (jal.getProperties() != null)
455 Enumeration en = jal.getProperties().keys();
456 while (en.hasMoreElements())
458 String key = en.nextElement().toString();
459 SequenceSetProperties ssp = new SequenceSetProperties();
461 ssp.setValue(jal.getProperties().get(key).toString());
462 vamsasSet.addSequenceSetProperties(ssp);
467 Set<String> calcIdSet = new HashSet<String>();
471 jalview.datamodel.SequenceI jds;
472 for (int i = 0; i < jal.getHeight(); i++)
474 jds = jal.getSequenceAt(i);
477 if (seqRefIds.get(id) != null)
479 // This happens for two reasons: 1. multiple views are being serialised.
480 // 2. the hashCode has collided with another sequence's code. This DOES
481 // HAPPEN! (PF00072.15.stk does this)
482 // JBPNote: Uncomment to debug writing out of files that do not read
483 // back in due to ArrayOutOfBoundExceptions.
484 // System.err.println("vamsasSeq backref: "+id+"");
485 // System.err.println(jds.getName()+"
486 // "+jds.getStart()+"-"+jds.getEnd()+" "+jds.getSequenceAsString());
487 // System.err.println("Hashcode: "+seqHash(jds));
488 // SequenceI rsq = (SequenceI) seqRefIds.get(id + "");
489 // System.err.println(rsq.getName()+"
490 // "+rsq.getStart()+"-"+rsq.getEnd()+" "+rsq.getSequenceAsString());
491 // System.err.println("Hashcode: "+seqHash(rsq));
495 vamsasSeq = createVamsasSequence(id, jds);
496 vamsasSet.addSequence(vamsasSeq);
497 seqRefIds.put(id, jds);
501 jseq.setStart(jds.getStart());
502 jseq.setEnd(jds.getEnd());
503 jseq.setColour(av.getSequenceColour(jds).getRGB());
505 jseq.setId(id); // jseq id should be a string not a number
507 if (av.hasHiddenRows())
509 jseq.setHidden(av.getAlignment().getHiddenSequences().isHidden(jds));
511 if (av.isHiddenRepSequence(jal.getSequenceAt(i)))
513 jalview.datamodel.SequenceI[] reps = av.getRepresentedSequences(
514 jal.getSequenceAt(i)).getSequencesInOrder(jal);
516 for (int h = 0; h < reps.length; h++)
518 if (reps[h] != jal.getSequenceAt(i))
520 jseq.addHiddenSequences(jal.findIndex(reps[h]));
526 if (jds.getDatasetSequence().getSequenceFeatures() != null)
528 jalview.datamodel.SequenceFeature[] sf = jds.getDatasetSequence()
529 .getSequenceFeatures();
531 while (index < sf.length)
533 Features features = new Features();
535 features.setBegin(sf[index].getBegin());
536 features.setEnd(sf[index].getEnd());
537 features.setDescription(sf[index].getDescription());
538 features.setType(sf[index].getType());
539 features.setFeatureGroup(sf[index].getFeatureGroup());
540 features.setScore(sf[index].getScore());
541 if (sf[index].links != null)
543 for (int l = 0; l < sf[index].links.size(); l++)
545 OtherData keyValue = new OtherData();
546 keyValue.setKey("LINK_" + l);
547 keyValue.setValue(sf[index].links.elementAt(l).toString());
548 features.addOtherData(keyValue);
551 if (sf[index].otherDetails != null)
554 Enumeration keys = sf[index].otherDetails.keys();
555 while (keys.hasMoreElements())
557 key = keys.nextElement().toString();
558 OtherData keyValue = new OtherData();
559 keyValue.setKey(key);
560 keyValue.setValue(sf[index].otherDetails.get(key).toString());
561 features.addOtherData(keyValue);
565 jseq.addFeatures(features);
570 if (jds.getDatasetSequence().getPDBId() != null)
572 Enumeration en = jds.getDatasetSequence().getPDBId().elements();
573 while (en.hasMoreElements())
575 Pdbids pdb = new Pdbids();
576 jalview.datamodel.PDBEntry entry = (jalview.datamodel.PDBEntry) en
579 pdb.setId(entry.getId());
580 pdb.setType(entry.getType());
583 // This must have been loaded, is it still visible?
584 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
585 String matchedFile = null;
586 for (int f = frames.length - 1; f > -1; f--)
588 if (frames[f] instanceof AppJmol)
590 jmol = (AppJmol) frames[f];
591 for (int peid = 0; peid < jmol.jmb.pdbentry.length; peid++)
593 if (!jmol.jmb.pdbentry[peid].getId().equals(entry.getId())
594 && !(entry.getId().length() > 4 && entry
598 jmol.jmb.pdbentry[peid].getId()
601 if (matchedFile == null)
603 matchedFile = jmol.jmb.pdbentry[peid].getFile();
605 else if (!matchedFile.equals(jmol.jmb.pdbentry[peid]
609 .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
610 + jmol.jmb.pdbentry[peid].getFile());
614 // can get at it if the ID
615 // match is ambiguous (e.g.
617 String statestring = jmol.jmb.viewer.getStateInfo();
619 for (int smap = 0; smap < jmol.jmb.sequence[peid].length; smap++)
621 // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
622 if (jds == jmol.jmb.sequence[peid][smap])
624 StructureState state = new StructureState();
625 state.setVisible(true);
626 state.setXpos(jmol.getX());
627 state.setYpos(jmol.getY());
628 state.setWidth(jmol.getWidth());
629 state.setHeight(jmol.getHeight());
630 state.setViewId(jmol.getViewId());
631 state.setAlignwithAlignPanel(jmol.isUsedforaligment(ap));
632 state.setColourwithAlignPanel(jmol
633 .isUsedforcolourby(ap));
634 state.setColourByJmol(jmol.isColouredByJmol());
635 if (!jmolViewIds.contains(state.getViewId()))
637 // Make sure we only store a Jmol state once in each XML
639 jmolViewIds.addElement(state.getViewId());
640 state.setContent(statestring.replaceAll("\n", ""));
644 state.setContent("# duplicate state");
646 pdb.addStructureState(state);
653 if (matchedFile != null || entry.getFile() != null)
655 if (entry.getFile() != null)
658 matchedFile = entry.getFile();
660 pdb.setFile(matchedFile); // entry.getFile());
661 if (pdbfiles == null)
663 pdbfiles = new Vector();
666 if (!pdbfiles.contains(entry.getId()))
668 pdbfiles.addElement(entry.getId());
671 File file = new File(matchedFile);
672 if (file.exists() && jout != null)
674 byte[] data = new byte[(int) file.length()];
675 jout.putNextEntry(new JarEntry(entry.getId()));
676 DataInputStream dis = new DataInputStream(
677 new FileInputStream(file));
680 DataOutputStream dout = new DataOutputStream(jout);
681 dout.write(data, 0, data.length);
685 } catch (Exception ex)
687 ex.printStackTrace();
693 if (entry.getProperty() != null)
695 PdbentryItem item = new PdbentryItem();
696 Hashtable properties = entry.getProperty();
697 Enumeration en2 = properties.keys();
698 while (en2.hasMoreElements())
700 Property prop = new Property();
701 String key = en2.nextElement().toString();
703 prop.setValue(properties.get(key).toString());
704 item.addProperty(prop);
706 pdb.addPdbentryItem(item);
716 if (av.hasHiddenRows())
718 jal = av.getAlignment();
721 if (jal.getCodonFrames() != null && jal.getCodonFrames().length > 0)
723 jalview.datamodel.AlignedCodonFrame[] jac = jal.getCodonFrames();
724 for (int i = 0; i < jac.length; i++)
726 AlcodonFrame alc = new AlcodonFrame();
727 vamsasSet.addAlcodonFrame(alc);
728 for (int p = 0; p < jac[i].aaWidth; p++)
730 Alcodon cmap = new Alcodon();
731 if (jac[i].codons[p] != null)
733 // Null codons indicate a gapped column in the translated peptide
735 cmap.setPos1(jac[i].codons[p][0]);
736 cmap.setPos2(jac[i].codons[p][1]);
737 cmap.setPos3(jac[i].codons[p][2]);
739 alc.addAlcodon(cmap);
741 if (jac[i].getProtMappings() != null
742 && jac[i].getProtMappings().length > 0)
744 SequenceI[] dnas = jac[i].getdnaSeqs();
745 jalview.datamodel.Mapping[] pmaps = jac[i].getProtMappings();
746 for (int m = 0; m < pmaps.length; m++)
748 AlcodMap alcmap = new AlcodMap();
749 alcmap.setDnasq(seqHash(dnas[m]));
750 alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
752 alc.addAlcodMap(alcmap);
759 // /////////////////////////////////
760 if (av.currentTree != null)
762 // FIND ANY ASSOCIATED TREES
763 // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
764 if (Desktop.desktop != null)
766 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
768 for (int t = 0; t < frames.length; t++)
770 if (frames[t] instanceof TreePanel)
772 TreePanel tp = (TreePanel) frames[t];
774 if (tp.treeCanvas.av.getAlignment() == jal)
776 Tree tree = new Tree();
777 tree.setTitle(tp.getTitle());
778 tree.setCurrentTree((av.currentTree == tp.getTree()));
779 tree.setNewick(tp.getTree().toString());
780 tree.setThreshold(tp.treeCanvas.threshold);
782 tree.setFitToWindow(tp.fitToWindow.getState());
783 tree.setFontName(tp.getTreeFont().getName());
784 tree.setFontSize(tp.getTreeFont().getSize());
785 tree.setFontStyle(tp.getTreeFont().getStyle());
786 tree.setMarkUnlinked(tp.placeholdersMenu.getState());
788 tree.setShowBootstrap(tp.bootstrapMenu.getState());
789 tree.setShowDistances(tp.distanceMenu.getState());
791 tree.setHeight(tp.getHeight());
792 tree.setWidth(tp.getWidth());
793 tree.setXpos(tp.getX());
794 tree.setYpos(tp.getY());
795 tree.setId(makeHashCode(tp, null));
804 * store forward refs from an annotationRow to any groups
806 IdentityHashMap groupRefs = new IdentityHashMap();
807 if (jal.getAlignmentAnnotation() != null)
809 jalview.datamodel.AlignmentAnnotation[] aa = jal
810 .getAlignmentAnnotation();
812 for (int i = 0; i < aa.length; i++)
814 Annotation an = new Annotation();
816 if (aa[i].annotationId != null)
818 annotationIds.put(aa[i].annotationId, aa[i]);
821 an.setId(aa[i].annotationId);
823 an.setVisible(aa[i].visible);
825 an.setDescription(aa[i].description);
827 if (aa[i].sequenceRef != null)
829 // TODO later annotation sequenceRef should be the XML ID of the
830 // sequence rather than its display name
831 an.setSequenceRef(aa[i].sequenceRef.getName());
833 if (aa[i].groupRef != null)
835 Object groupIdr = groupRefs.get(aa[i].groupRef);
836 if (groupIdr == null)
838 // make a locally unique String
839 groupRefs.put(aa[i].groupRef,
840 groupIdr = ("" + System.currentTimeMillis()
841 + aa[i].groupRef.getName() + groupRefs.size()));
843 an.setGroupRef(groupIdr.toString());
846 // store all visualization attributes for annotation
847 an.setGraphHeight(aa[i].graphHeight);
848 an.setCentreColLabels(aa[i].centreColLabels);
849 an.setScaleColLabels(aa[i].scaleColLabel);
850 an.setShowAllColLabels(aa[i].showAllColLabels);
851 an.setBelowAlignment(aa[i].belowAlignment);
856 an.setGraphType(aa[i].graph);
857 an.setGraphGroup(aa[i].graphGroup);
858 if (aa[i].getThreshold() != null)
860 ThresholdLine line = new ThresholdLine();
861 line.setLabel(aa[i].getThreshold().label);
862 line.setValue(aa[i].getThreshold().value);
863 line.setColour(aa[i].getThreshold().colour.getRGB());
864 an.setThresholdLine(line);
872 an.setLabel(aa[i].label);
874 if (aa[i] == av.getAlignmentQualityAnnot()
875 || aa[i] == av.getAlignmentConservationAnnotation()
876 || aa[i] == av.getAlignmentConsensusAnnotation()
877 || aa[i].autoCalculated)
879 // new way of indicating autocalculated annotation -
880 an.setAutoCalculated(aa[i].autoCalculated);
882 if (aa[i].hasScore())
884 an.setScore(aa[i].getScore());
887 if (aa[i].getCalcId() != null)
889 calcIdSet.add(aa[i].getCalcId());
890 an.setCalcId(aa[i].getCalcId());
893 AnnotationElement ae;
894 if (aa[i].annotations != null)
896 an.setScoreOnly(false);
897 for (int a = 0; a < aa[i].annotations.length; a++)
899 if ((aa[i] == null) || (aa[i].annotations[a] == null))
904 ae = new AnnotationElement();
905 if (aa[i].annotations[a].description != null)
906 ae.setDescription(aa[i].annotations[a].description);
907 if (aa[i].annotations[a].displayCharacter != null)
908 ae.setDisplayCharacter(aa[i].annotations[a].displayCharacter);
910 if (!Float.isNaN(aa[i].annotations[a].value))
911 ae.setValue(aa[i].annotations[a].value);
914 if (aa[i].annotations[a].secondaryStructure != ' '
915 && aa[i].annotations[a].secondaryStructure != '\0')
916 ae.setSecondaryStructure(aa[i].annotations[a].secondaryStructure
919 if (aa[i].annotations[a].colour != null
920 && aa[i].annotations[a].colour != java.awt.Color.black)
922 ae.setColour(aa[i].annotations[a].colour.getRGB());
925 an.addAnnotationElement(ae);
926 if (aa[i].autoCalculated)
928 // only write one non-null entry into the annotation row -
929 // sufficient to get the visualization attributes necessary to
937 an.setScoreOnly(true);
939 vamsasSet.addAnnotation(an);
943 if (jal.getGroups() != null)
945 JGroup[] groups = new JGroup[jal.getGroups().size()];
947 for (jalview.datamodel.SequenceGroup sg : jal.getGroups())
949 groups[++i] = new JGroup();
951 groups[i].setStart(sg.getStartRes());
952 groups[i].setEnd(sg.getEndRes());
953 groups[i].setName(sg.getName());
954 if (groupRefs.containsKey(sg))
956 // group has references so set it's ID field
957 groups[i].setId(groupRefs.get(sg).toString());
961 if (sg.cs.conservationApplied())
963 groups[i].setConsThreshold(sg.cs.getConservationInc());
965 if (sg.cs instanceof jalview.schemes.UserColourScheme)
967 groups[i].setColour(SetUserColourScheme(sg.cs, userColours,
973 .setColour(ColourSchemeProperty.getColourName(sg.cs));
976 else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient)
979 .setColour(ColourSchemeProperty
980 .getColourName(((jalview.schemes.AnnotationColourGradient) sg.cs)
983 else if (sg.cs instanceof jalview.schemes.UserColourScheme)
986 .setColour(SetUserColourScheme(sg.cs, userColours, jms));
990 groups[i].setColour(ColourSchemeProperty.getColourName(sg.cs));
993 groups[i].setPidThreshold(sg.cs.getThreshold());
996 groups[i].setOutlineColour(sg.getOutlineColour().getRGB());
997 groups[i].setDisplayBoxes(sg.getDisplayBoxes());
998 groups[i].setDisplayText(sg.getDisplayText());
999 groups[i].setColourText(sg.getColourText());
1000 groups[i].setTextCol1(sg.textColour.getRGB());
1001 groups[i].setTextCol2(sg.textColour2.getRGB());
1002 groups[i].setTextColThreshold(sg.thresholdTextColour);
1003 groups[i].setShowUnconserved(sg.getShowNonconserved());
1004 groups[i].setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
1005 groups[i].setShowConsensusHistogram(sg.isShowConsensusHistogram());
1006 groups[i].setShowSequenceLogo(sg.isShowSequenceLogo());
1007 groups[i].setNormaliseSequenceLogo(sg.isNormaliseSequenceLogo());
1008 for (int s = 0; s < sg.getSize(); s++)
1010 jalview.datamodel.Sequence seq = (jalview.datamodel.Sequence) sg
1012 groups[i].addSeq(seqHash(seq));
1016 jms.setJGroup(groups);
1019 // /////////SAVE VIEWPORT
1020 Viewport view = new Viewport();
1021 view.setTitle(ap.alignFrame.getTitle());
1022 view.setSequenceSetId(makeHashCode(av.getSequenceSetId(),
1023 av.getSequenceSetId()));
1024 view.setId(av.getViewId());
1025 view.setViewName(av.viewName);
1026 view.setGatheredViews(av.gatherViewsHere);
1028 if (ap.av.explodedPosition != null)
1030 view.setXpos(av.explodedPosition.x);
1031 view.setYpos(av.explodedPosition.y);
1032 view.setWidth(av.explodedPosition.width);
1033 view.setHeight(av.explodedPosition.height);
1037 view.setXpos(ap.alignFrame.getBounds().x);
1038 view.setYpos(ap.alignFrame.getBounds().y);
1039 view.setWidth(ap.alignFrame.getBounds().width);
1040 view.setHeight(ap.alignFrame.getBounds().height);
1043 view.setStartRes(av.startRes);
1044 view.setStartSeq(av.startSeq);
1046 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1048 view.setBgColour(SetUserColourScheme(av.getGlobalColourScheme(),
1051 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1053 jalview.schemes.AnnotationColourGradient acg = (jalview.schemes.AnnotationColourGradient) av
1054 .getGlobalColourScheme();
1056 AnnotationColours ac = new AnnotationColours();
1057 ac.setAboveThreshold(acg.getAboveThreshold());
1058 ac.setThreshold(acg.getAnnotationThreshold());
1059 ac.setAnnotation(acg.getAnnotation());
1060 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1062 ac.setColourScheme(SetUserColourScheme(acg.getBaseColour(),
1067 ac.setColourScheme(ColourSchemeProperty.getColourName(acg
1071 ac.setMaxColour(acg.getMaxColour().getRGB());
1072 ac.setMinColour(acg.getMinColour().getRGB());
1073 view.setAnnotationColours(ac);
1074 view.setBgColour("AnnotationColourGradient");
1078 view.setBgColour(ColourSchemeProperty.getColourName(av
1079 .getGlobalColourScheme()));
1082 ColourSchemeI cs = av.getGlobalColourScheme();
1086 if (cs.conservationApplied())
1088 view.setConsThreshold(cs.getConservationInc());
1089 if (cs instanceof jalview.schemes.UserColourScheme)
1091 view.setBgColour(SetUserColourScheme(cs, userColours, jms));
1095 if (cs instanceof ResidueColourScheme)
1097 view.setPidThreshold(cs.getThreshold());
1101 view.setConservationSelected(av.getConservationSelected());
1102 view.setPidSelected(av.getAbovePIDThreshold());
1103 view.setFontName(av.font.getName());
1104 view.setFontSize(av.font.getSize());
1105 view.setFontStyle(av.font.getStyle());
1106 view.setRenderGaps(av.renderGaps);
1107 view.setShowAnnotation(av.getShowAnnotation());
1108 view.setShowBoxes(av.getShowBoxes());
1109 view.setShowColourText(av.getColourText());
1110 view.setShowFullId(av.getShowJVSuffix());
1111 view.setRightAlignIds(av.rightAlignIds);
1112 view.setShowSequenceFeatures(av.showSequenceFeatures);
1113 view.setShowText(av.getShowText());
1114 view.setShowUnconserved(av.getShowUnconserved());
1115 view.setWrapAlignment(av.getWrapAlignment());
1116 view.setTextCol1(av.textColour.getRGB());
1117 view.setTextCol2(av.textColour2.getRGB());
1118 view.setTextColThreshold(av.thresholdTextColour);
1119 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1120 view.setShowSequenceLogo(av.isShowSequenceLogo());
1121 view.setNormaliseSequenceLogo(av.isNormaliseSequenceLogo());
1122 view.setShowGroupConsensus(av.isShowGroupConsensus());
1123 view.setShowGroupConservation(av.isShowGroupConservation());
1124 view.setShowNPfeatureTooltip(av.isShowNpFeats());
1125 view.setShowDbRefTooltip(av.isShowDbRefs());
1126 view.setFollowHighlight(av.followHighlight);
1127 view.setFollowSelection(av.followSelection);
1128 view.setIgnoreGapsinConsensus(av.getIgnoreGapsConsensus());
1129 if (av.featuresDisplayed != null)
1131 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1133 String[] renderOrder = ap.seqPanel.seqCanvas.getFeatureRenderer().renderOrder;
1135 Vector settingsAdded = new Vector();
1136 Object gstyle = null;
1137 GraduatedColor gcol = null;
1138 if (renderOrder != null)
1140 for (int ro = 0; ro < renderOrder.length; ro++)
1142 gstyle = ap.seqPanel.seqCanvas.getFeatureRenderer()
1143 .getFeatureStyle(renderOrder[ro]);
1144 Setting setting = new Setting();
1145 setting.setType(renderOrder[ro]);
1146 if (gstyle instanceof GraduatedColor)
1148 gcol = (GraduatedColor) gstyle;
1149 setting.setColour(gcol.getMaxColor().getRGB());
1150 setting.setMincolour(gcol.getMinColor().getRGB());
1151 setting.setMin(gcol.getMin());
1152 setting.setMax(gcol.getMax());
1153 setting.setColourByLabel(gcol.isColourByLabel());
1154 setting.setAutoScale(gcol.isAutoScale());
1155 setting.setThreshold(gcol.getThresh());
1156 setting.setThreshstate(gcol.getThreshType());
1160 setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer()
1161 .getColour(renderOrder[ro]).getRGB());
1164 setting.setDisplay(av.featuresDisplayed
1165 .containsKey(renderOrder[ro]));
1166 float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer()
1167 .getOrder(renderOrder[ro]);
1170 setting.setOrder(rorder);
1172 fs.addSetting(setting);
1173 settingsAdded.addElement(renderOrder[ro]);
1177 // Make sure we save none displayed feature settings
1178 Iterator en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureColours
1179 .keySet().iterator();
1180 while (en.hasNext())
1182 String key = en.next().toString();
1183 if (settingsAdded.contains(key))
1188 Setting setting = new Setting();
1189 setting.setType(key);
1190 setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer()
1191 .getColour(key).getRGB());
1193 setting.setDisplay(false);
1194 float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer().getOrder(
1198 setting.setOrder(rorder);
1200 fs.addSetting(setting);
1201 settingsAdded.addElement(key);
1203 en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups
1204 .keySet().iterator();
1205 Vector groupsAdded = new Vector();
1206 while (en.hasNext())
1208 String grp = en.next().toString();
1209 if (groupsAdded.contains(grp))
1213 Group g = new Group();
1215 g.setDisplay(((Boolean) ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups
1216 .get(grp)).booleanValue());
1218 groupsAdded.addElement(grp);
1220 jms.setFeatureSettings(fs);
1224 if (av.hasHiddenColumns())
1226 if (av.getColumnSelection() == null
1227 || av.getColumnSelection().getHiddenColumns() == null)
1229 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1233 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1236 int[] region = (int[]) av.getColumnSelection().getHiddenColumns()
1238 HiddenColumns hc = new HiddenColumns();
1239 hc.setStart(region[0]);
1240 hc.setEnd(region[1]);
1241 view.addHiddenColumns(hc);
1245 if (calcIdSet.size() > 0)
1247 for (String calcId : calcIdSet)
1249 if (calcId.trim().length() > 0)
1251 CalcIdParam cidp = createCalcIdParam(calcId, av);
1252 // Some calcIds have no parameters.
1255 view.addCalcIdParam(cidp);
1261 jms.addViewport(view);
1263 object.setJalviewModelSequence(jms);
1264 object.getVamsasModel().addSequenceSet(vamsasSet);
1266 if (jout != null && fileName != null)
1268 // We may not want to write the object to disk,
1269 // eg we can copy the alignViewport to a new view object
1270 // using save and then load
1273 JarEntry entry = new JarEntry(fileName);
1274 jout.putNextEntry(entry);
1275 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1277 org.exolab.castor.xml.Marshaller marshaller = new org.exolab.castor.xml.Marshaller(
1279 marshaller.marshal(object);
1282 } catch (Exception ex)
1284 // TODO: raise error in GUI if marshalling failed.
1285 ex.printStackTrace();
1291 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1293 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1294 if (settings != null)
1296 CalcIdParam vCalcIdParam = new CalcIdParam();
1297 vCalcIdParam.setCalcId(calcId);
1298 vCalcIdParam.addServiceURL(settings.getServiceURI());
1299 // generic URI allowing a third party to resolve another instance of the
1300 // service used for this calculation
1301 for (String urls : settings.getServiceURLs())
1303 vCalcIdParam.addServiceURL(urls);
1305 vCalcIdParam.setVersion("1.0");
1306 if (settings.getPreset() != null)
1308 WsParamSetI setting = settings.getPreset();
1309 vCalcIdParam.setName(setting.getName());
1310 vCalcIdParam.setDescription(setting.getDescription());
1314 vCalcIdParam.setName("");
1315 vCalcIdParam.setDescription("Last used parameters");
1317 // need to be able to recover 1) settings 2) user-defined presets or
1318 // recreate settings from preset 3) predefined settings provided by
1319 // service - or settings that can be transferred (or discarded)
1320 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1322 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1323 // todo - decide if updateImmediately is needed for any projects.
1325 return vCalcIdParam;
1330 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1333 if (calcIdParam.getVersion().equals("1.0"))
1335 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1336 .getPreferredServiceFor(calcIdParam.getServiceURL());
1337 if (service != null)
1339 WsParamSetI parmSet = null;
1342 parmSet = service.getParamStore().parseServiceParameterFile(
1343 calcIdParam.getName(), calcIdParam.getDescription(),
1344 calcIdParam.getServiceURL(),
1345 calcIdParam.getParameters().replace("|\\n|", "\n"));
1346 } catch (IOException x)
1348 warn("Couldn't parse parameter data for "
1349 + calcIdParam.getCalcId(), x);
1352 List<ArgumentI> argList = null;
1353 if (calcIdParam.getName().length() > 0)
1355 parmSet = service.getParamStore()
1356 .getPreset(calcIdParam.getName());
1357 if (parmSet != null)
1359 // TODO : check we have a good match with settings in AACon -
1360 // otherwise we'll need to create a new preset
1365 argList = parmSet.getArguments();
1368 AAConSettings settings = new AAConSettings(
1369 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1370 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1371 calcIdParam.isNeedsUpdate());
1376 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1380 throw new Error("Unsupported Version for calcIdparam "
1381 + calcIdParam.toString());
1385 * External mapping between jalview objects and objects yielding a valid and
1386 * unique object ID string. This is null for normal Jalview project IO, but
1387 * non-null when a jalview project is being read or written as part of a
1390 IdentityHashMap jv2vobj = null;
1393 * Construct a unique ID for jvobj using either existing bindings or if none
1394 * exist, the result of the hashcode call for the object.
1397 * jalview data object
1398 * @return unique ID for referring to jvobj
1400 private String makeHashCode(Object jvobj, String altCode)
1402 if (jv2vobj != null)
1404 Object id = jv2vobj.get(jvobj);
1407 return id.toString();
1409 // check string ID mappings
1410 if (jvids2vobj != null && jvobj instanceof String)
1412 id = jvids2vobj.get(jvobj);
1416 return id.toString();
1418 // give up and warn that something has gone wrong
1419 warn("Cannot find ID for object in external mapping : " + jvobj);
1425 * return local jalview object mapped to ID, if it exists
1429 * @return null or object bound to idcode
1431 private Object retrieveExistingObj(String idcode)
1433 if (idcode != null && vobj2jv != null)
1435 return vobj2jv.get(idcode);
1441 * binding from ID strings from external mapping table to jalview data model
1444 private Hashtable vobj2jv;
1446 private Sequence createVamsasSequence(String id, SequenceI jds)
1448 return createVamsasSequence(true, id, jds, null);
1451 private Sequence createVamsasSequence(boolean recurse, String id,
1452 SequenceI jds, SequenceI parentseq)
1454 Sequence vamsasSeq = new Sequence();
1455 vamsasSeq.setId(id);
1456 vamsasSeq.setName(jds.getName());
1457 vamsasSeq.setSequence(jds.getSequenceAsString());
1458 vamsasSeq.setDescription(jds.getDescription());
1459 jalview.datamodel.DBRefEntry[] dbrefs = null;
1460 if (jds.getDatasetSequence() != null)
1462 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
1463 if (jds.getDatasetSequence().getDBRef() != null)
1465 dbrefs = jds.getDatasetSequence().getDBRef();
1470 vamsasSeq.setDsseqid(id); // so we can tell which sequences really are
1471 // dataset sequences only
1472 dbrefs = jds.getDBRef();
1476 for (int d = 0; d < dbrefs.length; d++)
1478 DBRef dbref = new DBRef();
1479 dbref.setSource(dbrefs[d].getSource());
1480 dbref.setVersion(dbrefs[d].getVersion());
1481 dbref.setAccessionId(dbrefs[d].getAccessionId());
1482 if (dbrefs[d].hasMap())
1484 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
1486 dbref.setMapping(mp);
1488 vamsasSeq.addDBRef(dbref);
1494 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
1495 SequenceI parentseq, SequenceI jds, boolean recurse)
1498 if (jmp.getMap() != null)
1502 jalview.util.MapList mlst = jmp.getMap();
1503 int r[] = mlst.getFromRanges();
1504 for (int s = 0; s < r.length; s += 2)
1506 MapListFrom mfrom = new MapListFrom();
1507 mfrom.setStart(r[s]);
1508 mfrom.setEnd(r[s + 1]);
1509 mp.addMapListFrom(mfrom);
1511 r = mlst.getToRanges();
1512 for (int s = 0; s < r.length; s += 2)
1514 MapListTo mto = new MapListTo();
1516 mto.setEnd(r[s + 1]);
1517 mp.addMapListTo(mto);
1519 mp.setMapFromUnit(mlst.getFromRatio());
1520 mp.setMapToUnit(mlst.getToRatio());
1521 if (jmp.getTo() != null)
1523 MappingChoice mpc = new MappingChoice();
1525 && (parentseq != jmp.getTo() || parentseq
1526 .getDatasetSequence() != jmp.getTo()))
1528 mpc.setSequence(createVamsasSequence(false, seqHash(jmp.getTo()),
1534 SequenceI ps = null;
1535 if (parentseq != jmp.getTo()
1536 && parentseq.getDatasetSequence() != jmp.getTo())
1538 // chaining dbref rather than a handshaking one
1539 jmpid = seqHash(ps = jmp.getTo());
1543 jmpid = seqHash(ps = parentseq);
1545 mpc.setDseqFor(jmpid);
1546 if (!seqRefIds.containsKey(mpc.getDseqFor()))
1548 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
1549 seqRefIds.put(mpc.getDseqFor(), ps);
1553 jalview.bin.Cache.log.debug("reusing DseqFor ID");
1556 mp.setMappingChoice(mpc);
1562 String SetUserColourScheme(jalview.schemes.ColourSchemeI cs,
1563 Vector userColours, JalviewModelSequence jms)
1566 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
1567 boolean newucs = false;
1568 if (!userColours.contains(ucs))
1570 userColours.add(ucs);
1573 id = "ucs" + userColours.indexOf(ucs);
1576 // actually create the scheme's entry in the XML model
1577 java.awt.Color[] colours = ucs.getColours();
1578 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
1579 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
1581 for (int i = 0; i < colours.length; i++)
1583 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1584 col.setName(ResidueProperties.aa[i]);
1585 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1586 jbucs.addColour(col);
1588 if (ucs.getLowerCaseColours() != null)
1590 colours = ucs.getLowerCaseColours();
1591 for (int i = 0; i < colours.length; i++)
1593 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1594 col.setName(ResidueProperties.aa[i].toLowerCase());
1595 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1596 jbucs.addColour(col);
1601 uc.setUserColourScheme(jbucs);
1602 jms.addUserColours(uc);
1608 jalview.schemes.UserColourScheme GetUserColourScheme(
1609 JalviewModelSequence jms, String id)
1611 UserColours[] uc = jms.getUserColours();
1612 UserColours colours = null;
1614 for (int i = 0; i < uc.length; i++)
1616 if (uc[i].getId().equals(id))
1624 java.awt.Color[] newColours = new java.awt.Color[24];
1626 for (int i = 0; i < 24; i++)
1628 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1629 .getUserColourScheme().getColour(i).getRGB(), 16));
1632 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
1635 if (colours.getUserColourScheme().getColourCount() > 24)
1637 newColours = new java.awt.Color[23];
1638 for (int i = 0; i < 23; i++)
1640 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1641 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
1643 ucs.setLowerCaseColours(newColours);
1650 * contains last error message (if any) encountered by XML loader.
1652 String errorMessage = null;
1655 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
1656 * exceptions are raised during project XML parsing
1658 public boolean attemptversion1parse = true;
1661 * Load a jalview project archive from a jar file
1664 * - HTTP URL or filename
1666 public AlignFrame LoadJalviewAlign(final String file)
1669 jalview.gui.AlignFrame af = null;
1673 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
1674 // Workaround is to make sure caller implements the JarInputStreamProvider
1676 // so we can re-open the jar input stream for each entry.
1678 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
1679 af = LoadJalviewAlign(jprovider);
1680 } catch (MalformedURLException e)
1682 errorMessage = "Invalid URL format for '" + file + "'";
1688 private jarInputStreamProvider createjarInputStreamProvider(
1689 final String file) throws MalformedURLException
1692 errorMessage = null;
1693 uniqueSetSuffix = null;
1695 viewportsAdded = null;
1696 frefedSequence = null;
1698 if (file.startsWith("http://"))
1700 url = new URL(file);
1702 final URL _url = url;
1703 return new jarInputStreamProvider()
1707 public JarInputStream getJarInputStream() throws IOException
1711 return new JarInputStream(_url.openStream());
1715 return new JarInputStream(new FileInputStream(file));
1720 public String getFilename()
1728 * Recover jalview session from a jalview project archive. Caller may
1729 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
1730 * themselves. Any null fields will be initialised with default values,
1731 * non-null fields are left alone.
1736 public AlignFrame LoadJalviewAlign(final jarInputStreamProvider jprovider)
1738 errorMessage = null;
1739 if (uniqueSetSuffix == null)
1741 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
1743 if (seqRefIds == null)
1745 seqRefIds = new Hashtable();
1747 if (viewportsAdded == null)
1749 viewportsAdded = new Hashtable();
1751 if (frefedSequence == null)
1753 frefedSequence = new Vector();
1756 jalview.gui.AlignFrame af = null;
1757 Hashtable gatherToThisFrame = new Hashtable();
1758 final String file = jprovider.getFilename();
1761 JarInputStream jin = null;
1762 JarEntry jarentry = null;
1767 jin = jprovider.getJarInputStream();
1768 for (int i = 0; i < entryCount; i++)
1770 jarentry = jin.getNextJarEntry();
1773 if (jarentry != null && jarentry.getName().endsWith(".xml"))
1775 InputStreamReader in = new InputStreamReader(jin, "UTF-8");
1776 JalviewModel object = new JalviewModel();
1778 Unmarshaller unmar = new Unmarshaller(object);
1779 unmar.setValidation(false);
1780 object = (JalviewModel) unmar.unmarshal(in);
1781 if (true) // !skipViewport(object))
1783 af = LoadFromObject(object, file, true, jprovider);
1784 if (af.viewport.gatherViewsHere)
1786 gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
1791 else if (jarentry != null)
1793 // Some other file here.
1796 } while (jarentry != null);
1797 resolveFrefedSequences();
1798 } catch (java.io.FileNotFoundException ex)
1800 ex.printStackTrace();
1801 errorMessage = "Couldn't locate Jalview XML file : " + file;
1802 System.err.println("Exception whilst loading jalview XML file : "
1804 } catch (java.net.UnknownHostException ex)
1806 ex.printStackTrace();
1807 errorMessage = "Couldn't locate Jalview XML file : " + file;
1808 System.err.println("Exception whilst loading jalview XML file : "
1810 } catch (Exception ex)
1812 System.err.println("Parsing as Jalview Version 2 file failed.");
1813 ex.printStackTrace(System.err);
1814 if (attemptversion1parse)
1816 // Is Version 1 Jar file?
1819 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
1820 } catch (Exception ex2)
1822 System.err.println("Exception whilst loading as jalviewXMLV1:");
1823 ex2.printStackTrace();
1827 if (Desktop.instance != null)
1829 Desktop.instance.stopLoading();
1833 System.out.println("Successfully loaded archive file");
1836 ex.printStackTrace();
1838 System.err.println("Exception whilst loading jalview XML file : "
1840 } catch (OutOfMemoryError e)
1842 // Don't use the OOM Window here
1843 errorMessage = "Out of memory loading jalview XML file";
1844 System.err.println("Out of memory whilst loading jalview XML file");
1845 e.printStackTrace();
1848 if (Desktop.instance != null)
1850 Desktop.instance.stopLoading();
1853 Enumeration en = gatherToThisFrame.elements();
1854 while (en.hasMoreElements())
1856 Desktop.instance.gatherViews((AlignFrame) en.nextElement());
1858 if (errorMessage != null)
1866 * check errorMessage for a valid error message and raise an error box in the
1867 * GUI or write the current errorMessage to stderr and then clear the error
1870 protected void reportErrors()
1872 reportErrors(false);
1875 protected void reportErrors(final boolean saving)
1877 if (errorMessage != null)
1879 final String finalErrorMessage = errorMessage;
1882 javax.swing.SwingUtilities.invokeLater(new Runnable()
1887 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1888 finalErrorMessage, "Error "
1889 + (saving ? "saving" : "loading")
1890 + " Jalview file", JOptionPane.WARNING_MESSAGE);
1896 System.err.println("Problem loading Jalview file: " + errorMessage);
1899 errorMessage = null;
1902 Hashtable alreadyLoadedPDB;
1905 * when set, local views will be updated from view stored in JalviewXML
1906 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
1907 * sync if this is set to true.
1909 private final boolean updateLocalViews = false;
1911 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
1913 if (alreadyLoadedPDB == null)
1914 alreadyLoadedPDB = new Hashtable();
1916 if (alreadyLoadedPDB.containsKey(pdbId))
1917 return alreadyLoadedPDB.get(pdbId).toString();
1921 JarInputStream jin = jprovider.getJarInputStream();
1923 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
1924 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
1925 * FileInputStream(jprovider)); }
1928 JarEntry entry = null;
1931 entry = jin.getNextJarEntry();
1932 } while (entry != null && !entry.getName().equals(pdbId));
1935 BufferedReader in = new BufferedReader(new InputStreamReader(jin));
1936 File outFile = File.createTempFile("jalview_pdb", ".txt");
1937 outFile.deleteOnExit();
1938 PrintWriter out = new PrintWriter(new FileOutputStream(outFile));
1941 while ((data = in.readLine()) != null)
1948 } catch (Exception foo)
1953 String t = outFile.getAbsolutePath();
1954 alreadyLoadedPDB.put(pdbId, t);
1959 warn("Couldn't find PDB file entry in Jalview Jar for " + pdbId);
1961 } catch (Exception ex)
1963 ex.printStackTrace();
1969 private class JvAnnotRow
1971 public JvAnnotRow(int i, AlignmentAnnotation jaa)
1978 * persisted version of annotation row from which to take vis properties
1980 public jalview.datamodel.AlignmentAnnotation template;
1983 * original position of the annotation row in the alignment
1989 * Load alignment frame from jalview XML DOM object
1994 * filename source string
1995 * @param loadTreesAndStructures
1996 * when false only create Viewport
1998 * data source provider
1999 * @return alignment frame created from view stored in DOM
2001 AlignFrame LoadFromObject(JalviewModel object, String file,
2002 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2004 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2005 Sequence[] vamsasSeq = vamsasSet.getSequence();
2007 JalviewModelSequence jms = object.getJalviewModelSequence();
2009 Viewport view = jms.getViewport(0);
2010 // ////////////////////////////////
2013 Vector hiddenSeqs = null;
2014 jalview.datamodel.Sequence jseq;
2016 ArrayList tmpseqs = new ArrayList();
2018 boolean multipleView = false;
2020 JSeq[] JSEQ = object.getJalviewModelSequence().getJSeq();
2021 int vi = 0; // counter in vamsasSeq array
2022 for (int i = 0; i < JSEQ.length; i++)
2024 String seqId = JSEQ[i].getId();
2026 if (seqRefIds.get(seqId) != null)
2028 tmpseqs.add(seqRefIds.get(seqId));
2029 multipleView = true;
2033 jseq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2034 vamsasSeq[vi].getSequence());
2035 jseq.setDescription(vamsasSeq[vi].getDescription());
2036 jseq.setStart(JSEQ[i].getStart());
2037 jseq.setEnd(JSEQ[i].getEnd());
2038 jseq.setVamsasId(uniqueSetSuffix + seqId);
2039 seqRefIds.put(vamsasSeq[vi].getId(), jseq);
2044 if (JSEQ[i].getHidden())
2046 if (hiddenSeqs == null)
2048 hiddenSeqs = new Vector();
2051 hiddenSeqs.addElement(seqRefIds.get(seqId));
2057 // Create the alignment object from the sequence set
2058 // ///////////////////////////////
2059 jalview.datamodel.Sequence[] orderedSeqs = new jalview.datamodel.Sequence[tmpseqs
2062 tmpseqs.toArray(orderedSeqs);
2064 jalview.datamodel.Alignment al = new jalview.datamodel.Alignment(
2067 // / Add the alignment properties
2068 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2070 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2071 al.setProperty(ssp.getKey(), ssp.getValue());
2075 // SequenceFeatures are added to the DatasetSequence,
2076 // so we must create or recover the dataset before loading features
2077 // ///////////////////////////////
2078 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2080 // older jalview projects do not have a dataset id.
2081 al.setDataset(null);
2085 recoverDatasetFor(vamsasSet, al);
2087 // ///////////////////////////////
2089 Hashtable pdbloaded = new Hashtable();
2092 // load sequence features, database references and any associated PDB
2093 // structures for the alignment
2094 for (int i = 0; i < vamsasSeq.length; i++)
2096 if (JSEQ[i].getFeaturesCount() > 0)
2098 Features[] features = JSEQ[i].getFeatures();
2099 for (int f = 0; f < features.length; f++)
2101 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2102 features[f].getType(), features[f].getDescription(),
2103 features[f].getStatus(), features[f].getBegin(),
2104 features[f].getEnd(), features[f].getFeatureGroup());
2106 sf.setScore(features[f].getScore());
2107 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2109 OtherData keyValue = features[f].getOtherData(od);
2110 if (keyValue.getKey().startsWith("LINK"))
2112 sf.addLink(keyValue.getValue());
2116 sf.setValue(keyValue.getKey(), keyValue.getValue());
2121 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
2124 if (vamsasSeq[i].getDBRefCount() > 0)
2126 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2128 if (JSEQ[i].getPdbidsCount() > 0)
2130 Pdbids[] ids = JSEQ[i].getPdbids();
2131 for (int p = 0; p < ids.length; p++)
2133 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2134 entry.setId(ids[p].getId());
2135 entry.setType(ids[p].getType());
2136 if (ids[p].getFile() != null)
2138 if (!pdbloaded.containsKey(ids[p].getFile()))
2140 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2144 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2148 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2152 } // end !multipleview
2154 // ///////////////////////////////
2155 // LOAD SEQUENCE MAPPINGS
2157 if (vamsasSet.getAlcodonFrameCount() > 0)
2159 // TODO Potentially this should only be done once for all views of an
2161 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2162 for (int i = 0; i < alc.length; i++)
2164 jalview.datamodel.AlignedCodonFrame cf = new jalview.datamodel.AlignedCodonFrame(
2165 alc[i].getAlcodonCount());
2166 if (alc[i].getAlcodonCount() > 0)
2168 Alcodon[] alcods = alc[i].getAlcodon();
2169 for (int p = 0; p < cf.codons.length; p++)
2171 if (alcods[p].hasPos1() && alcods[p].hasPos2()
2172 && alcods[p].hasPos3())
2174 // translated codons require three valid positions
2175 cf.codons[p] = new int[3];
2176 cf.codons[p][0] = (int) alcods[p].getPos1();
2177 cf.codons[p][1] = (int) alcods[p].getPos2();
2178 cf.codons[p][2] = (int) alcods[p].getPos3();
2182 cf.codons[p] = null;
2186 if (alc[i].getAlcodMapCount() > 0)
2188 AlcodMap[] maps = alc[i].getAlcodMap();
2189 for (int m = 0; m < maps.length; m++)
2191 SequenceI dnaseq = (SequenceI) seqRefIds
2192 .get(maps[m].getDnasq());
2194 jalview.datamodel.Mapping mapping = null;
2195 // attach to dna sequence reference.
2196 if (maps[m].getMapping() != null)
2198 mapping = addMapping(maps[m].getMapping());
2202 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
2207 frefedSequence.add(new Object[]
2208 { maps[m].getDnasq(), cf, mapping });
2212 al.addCodonFrame(cf);
2217 // ////////////////////////////////
2219 ArrayList<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
2221 * store any annotations which forward reference a group's ID
2223 Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>>();
2225 if (vamsasSet.getAnnotationCount() > 0)
2227 Annotation[] an = vamsasSet.getAnnotation();
2229 for (int i = 0; i < an.length; i++)
2232 * test if annotation is automatically calculated for this view only
2234 boolean autoForView = false;
2235 if (an[i].getLabel().equals("Quality")
2236 || an[i].getLabel().equals("Conservation")
2237 || an[i].getLabel().equals("Consensus"))
2239 // Kludge for pre 2.5 projects which lacked the autocalculated flag
2241 if (!an[i].hasAutoCalculated())
2243 an[i].setAutoCalculated(true);
2247 || (an[i].hasAutoCalculated() && an[i].isAutoCalculated()))
2249 // remove ID - we don't recover annotation from other views for
2250 // view-specific annotation
2254 // set visiblity for other annotation in this view
2255 if (an[i].getId() != null
2256 && annotationIds.containsKey(an[i].getId()))
2258 jalview.datamodel.AlignmentAnnotation jda = (jalview.datamodel.AlignmentAnnotation) annotationIds
2259 .get(an[i].getId());
2260 // in principle Visible should always be true for annotation displayed
2261 // in multiple views
2262 if (an[i].hasVisible())
2263 jda.visible = an[i].getVisible();
2265 al.addAnnotation(jda);
2269 // Construct new annotation from model.
2270 AnnotationElement[] ae = an[i].getAnnotationElement();
2271 jalview.datamodel.Annotation[] anot = null;
2272 java.awt.Color firstColour = null;
2274 if (!an[i].getScoreOnly())
2276 anot = new jalview.datamodel.Annotation[al.getWidth()];
2277 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
2279 anpos = ae[aa].getPosition();
2281 if (anpos >= anot.length)
2284 anot[anpos] = new jalview.datamodel.Annotation(
2286 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
2287 (ae[aa].getSecondaryStructure() == null || ae[aa]
2288 .getSecondaryStructure().length() == 0) ? ' '
2289 : ae[aa].getSecondaryStructure().charAt(0),
2293 // JBPNote: Consider verifying dataflow for IO of secondary
2294 // structure annotation read from Stockholm files
2295 // this was added to try to ensure that
2296 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
2298 // anot[ae[aa].getPosition()].displayCharacter = "";
2300 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
2301 if (firstColour == null)
2303 firstColour = anot[anpos].colour;
2307 jalview.datamodel.AlignmentAnnotation jaa = null;
2309 if (an[i].getGraph())
2311 float llim = 0, hlim = 0;
2312 // if (autoForView || an[i].isAutoCalculated()) {
2315 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2316 an[i].getDescription(), anot, llim, hlim,
2317 an[i].getGraphType());
2319 jaa.graphGroup = an[i].getGraphGroup();
2320 jaa._linecolour = firstColour;
2321 if (an[i].getThresholdLine() != null)
2323 jaa.setThreshold(new jalview.datamodel.GraphLine(an[i]
2324 .getThresholdLine().getValue(), an[i]
2325 .getThresholdLine().getLabel(), new java.awt.Color(
2326 an[i].getThresholdLine().getColour())));
2329 if (autoForView || an[i].isAutoCalculated())
2331 // Hardwire the symbol display line to ensure that labels for
2332 // histograms are displayed
2338 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2339 an[i].getDescription(), anot);
2340 jaa._linecolour = firstColour;
2342 // register new annotation
2343 if (an[i].getId() != null)
2345 annotationIds.put(an[i].getId(), jaa);
2346 jaa.annotationId = an[i].getId();
2348 // recover sequence association
2349 if (an[i].getSequenceRef() != null)
2351 if (al.findName(an[i].getSequenceRef()) != null)
2353 jaa.createSequenceMapping(al.findName(an[i].getSequenceRef()),
2355 al.findName(an[i].getSequenceRef()).addAlignmentAnnotation(jaa);
2358 // and make a note of any group association
2359 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
2361 ArrayList<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
2362 .get(an[i].getGroupRef());
2365 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
2366 groupAnnotRefs.put(an[i].getGroupRef(), aal);
2371 if (an[i].hasScore())
2373 jaa.setScore(an[i].getScore());
2375 if (an[i].hasVisible())
2376 jaa.visible = an[i].getVisible();
2378 if (an[i].hasCentreColLabels())
2379 jaa.centreColLabels = an[i].getCentreColLabels();
2381 if (an[i].hasScaleColLabels())
2383 jaa.scaleColLabel = an[i].getScaleColLabels();
2385 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
2387 // newer files have an 'autoCalculated' flag and store calculation
2388 // state in viewport properties
2389 jaa.autoCalculated = true; // means annotation will be marked for
2390 // update at end of load.
2392 if (an[i].hasGraphHeight())
2394 jaa.graphHeight = an[i].getGraphHeight();
2396 if (an[i].hasBelowAlignment())
2398 jaa.belowAlignment = an[i].isBelowAlignment();
2400 jaa.setCalcId(an[i].getCalcId());
2402 if (jaa.autoCalculated)
2404 autoAlan.add(new JvAnnotRow(i, jaa));
2407 // if (!autoForView)
2409 // add autocalculated group annotation and any user created annotation
2411 al.addAnnotation(jaa);
2416 // ///////////////////////
2418 // Create alignment markup and styles for this view
2419 if (jms.getJGroupCount() > 0)
2421 JGroup[] groups = jms.getJGroup();
2423 for (int i = 0; i < groups.length; i++)
2425 ColourSchemeI cs = null;
2427 if (groups[i].getColour() != null)
2429 if (groups[i].getColour().startsWith("ucs"))
2431 cs = GetUserColourScheme(jms, groups[i].getColour());
2435 cs = ColourSchemeProperty.getColour(al, groups[i].getColour());
2440 cs.setThreshold(groups[i].getPidThreshold(), true);
2444 Vector seqs = new Vector();
2446 for (int s = 0; s < groups[i].getSeqCount(); s++)
2448 String seqId = groups[i].getSeq(s) + "";
2449 jalview.datamodel.SequenceI ts = (jalview.datamodel.SequenceI) seqRefIds
2454 seqs.addElement(ts);
2458 if (seqs.size() < 1)
2463 jalview.datamodel.SequenceGroup sg = new jalview.datamodel.SequenceGroup(
2464 seqs, groups[i].getName(), cs, groups[i].getDisplayBoxes(),
2465 groups[i].getDisplayText(), groups[i].getColourText(),
2466 groups[i].getStart(), groups[i].getEnd());
2468 sg.setOutlineColour(new java.awt.Color(groups[i].getOutlineColour()));
2470 sg.textColour = new java.awt.Color(groups[i].getTextCol1());
2471 sg.textColour2 = new java.awt.Color(groups[i].getTextCol2());
2472 sg.setShowNonconserved(groups[i].hasShowUnconserved() ? groups[i]
2473 .isShowUnconserved() : false);
2474 sg.thresholdTextColour = groups[i].getTextColThreshold();
2475 if (groups[i].hasShowConsensusHistogram())
2477 sg.setShowConsensusHistogram(groups[i].isShowConsensusHistogram());
2480 if (groups[i].hasShowSequenceLogo())
2482 sg.setshowSequenceLogo(groups[i].isShowSequenceLogo());
2484 if (groups[i].hasNormaliseSequenceLogo())
2486 sg.setNormaliseSequenceLogo(groups[i].isNormaliseSequenceLogo());
2488 if (groups[i].hasIgnoreGapsinConsensus())
2490 sg.setIgnoreGapsConsensus(groups[i].getIgnoreGapsinConsensus());
2492 if (groups[i].getConsThreshold() != 0)
2494 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
2495 "All", ResidueProperties.propHash, 3,
2496 sg.getSequences(null), 0, sg.getWidth() - 1);
2498 c.verdict(false, 25);
2499 sg.cs.setConservation(c);
2502 if (groups[i].getId() != null && groupAnnotRefs.size() > 0)
2504 // re-instate unique group/annotation row reference
2505 ArrayList<jalview.datamodel.AlignmentAnnotation> jaal = groupAnnotRefs
2506 .get(groups[i].getId());
2509 for (jalview.datamodel.AlignmentAnnotation jaa : jaal)
2512 if (jaa.autoCalculated)
2514 // match up and try to set group autocalc alignment row for this
2516 if (jaa.label.startsWith("Consensus for "))
2518 sg.setConsensus(jaa);
2520 // match up and try to set group autocalc alignment row for this
2522 if (jaa.label.startsWith("Conservation for "))
2524 sg.setConservationRow(jaa);
2535 // ///////////////////////////////
2538 // If we just load in the same jar file again, the sequenceSetId
2539 // will be the same, and we end up with multiple references
2540 // to the same sequenceSet. We must modify this id on load
2541 // so that each load of the file gives a unique id
2542 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
2543 String viewId = (view.getId() == null ? null : view.getId()
2545 AlignFrame af = null;
2546 AlignViewport av = null;
2547 // now check to see if we really need to create a new viewport.
2548 if (multipleView && viewportsAdded.size() == 0)
2550 // We recovered an alignment for which a viewport already exists.
2551 // TODO: fix up any settings necessary for overlaying stored state onto
2552 // state recovered from another document. (may not be necessary).
2553 // we may need a binding from a viewport in memory to one recovered from
2555 // and then recover its containing af to allow the settings to be applied.
2556 // TODO: fix for vamsas demo
2558 .println("About to recover a viewport for existing alignment: Sequence set ID is "
2560 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
2561 if (seqsetobj != null)
2563 if (seqsetobj instanceof String)
2565 uniqueSeqSetId = (String) seqsetobj;
2567 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
2573 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
2578 AlignmentPanel ap = null;
2579 boolean isnewview = true;
2582 // Check to see if this alignment already has a view id == viewId
2583 jalview.gui.AlignmentPanel views[] = Desktop
2584 .getAlignmentPanels(uniqueSeqSetId);
2585 if (views != null && views.length > 0)
2587 for (int v = 0; v < views.length; v++)
2589 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
2591 // recover the existing alignpanel, alignframe, viewport
2592 af = views[v].alignFrame;
2595 // TODO: could even skip resetting view settings if we don't want to
2596 // change the local settings from other jalview processes
2605 af = loadViewport(file, JSEQ, hiddenSeqs, al, jms, view,
2606 uniqueSeqSetId, viewId, autoAlan);
2611 // /////////////////////////////////////
2612 if (loadTreesAndStructures && jms.getTreeCount() > 0)
2616 for (int t = 0; t < jms.getTreeCount(); t++)
2619 Tree tree = jms.getTree(t);
2621 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
2624 tp = af.ShowNewickTree(
2625 new jalview.io.NewickFile(tree.getNewick()),
2626 tree.getTitle(), tree.getWidth(), tree.getHeight(),
2627 tree.getXpos(), tree.getYpos());
2628 if (tree.getId() != null)
2630 // perhaps bind the tree id to something ?
2635 // update local tree attributes ?
2636 // TODO: should check if tp has been manipulated by user - if so its
2637 // settings shouldn't be modified
2638 tp.setTitle(tree.getTitle());
2639 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
2640 .getWidth(), tree.getHeight()));
2641 tp.av = av; // af.viewport; // TODO: verify 'associate with all
2644 tp.treeCanvas.av = av; // af.viewport;
2645 tp.treeCanvas.ap = ap; // af.alignPanel;
2650 warn("There was a problem recovering stored Newick tree: \n"
2651 + tree.getNewick());
2655 tp.fitToWindow.setState(tree.getFitToWindow());
2656 tp.fitToWindow_actionPerformed(null);
2658 if (tree.getFontName() != null)
2660 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
2661 .getFontStyle(), tree.getFontSize()));
2665 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
2666 .getFontStyle(), tree.getFontSize()));
2669 tp.showPlaceholders(tree.getMarkUnlinked());
2670 tp.showBootstrap(tree.getShowBootstrap());
2671 tp.showDistances(tree.getShowDistances());
2673 tp.treeCanvas.threshold = tree.getThreshold();
2675 if (tree.getCurrentTree())
2677 af.viewport.setCurrentTree(tp.getTree());
2681 } catch (Exception ex)
2683 ex.printStackTrace();
2687 // //LOAD STRUCTURES
2688 if (loadTreesAndStructures)
2690 // run through all PDB ids on the alignment, and collect mappings between
2691 // jmol view ids and all sequences referring to it
2692 Hashtable<String, Object[]> jmolViewIds = new Hashtable();
2694 for (int i = 0; i < JSEQ.length; i++)
2696 if (JSEQ[i].getPdbidsCount() > 0)
2698 Pdbids[] ids = JSEQ[i].getPdbids();
2699 for (int p = 0; p < ids.length; p++)
2701 for (int s = 0; s < ids[p].getStructureStateCount(); s++)
2703 // check to see if we haven't already created this structure view
2704 String sviewid = (ids[p].getStructureState(s).getViewId() == null) ? null
2705 : ids[p].getStructureState(s).getViewId()
2707 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
2708 // Originally : ids[p].getFile()
2709 // : TODO: verify external PDB file recovery still works in normal
2710 // jalview project load
2711 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
2712 jpdb.setId(ids[p].getId());
2714 int x = ids[p].getStructureState(s).getXpos();
2715 int y = ids[p].getStructureState(s).getYpos();
2716 int width = ids[p].getStructureState(s).getWidth();
2717 int height = ids[p].getStructureState(s).getHeight();
2719 // Probably don't need to do this anymore...
2720 // Desktop.desktop.getComponentAt(x, y);
2721 // TODO: NOW: check that this recovers the PDB file correctly.
2722 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
2723 jalview.datamodel.SequenceI seq = (jalview.datamodel.SequenceI) seqRefIds
2724 .get(JSEQ[i].getId() + "");
2725 if (sviewid == null)
2727 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
2730 if (!jmolViewIds.containsKey(sviewid))
2732 jmolViewIds.put(sviewid, new Object[]
2734 { x, y, width, height }, "",
2735 new Hashtable<String, Object[]>(), new boolean[]
2736 { false, false, true } });
2737 // Legacy pre-2.7 conversion JAL-823 :
2738 // do not assume any view has to be linked for colour by
2742 // assemble String[] { pdb files }, String[] { id for each
2743 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
2744 // seqs_file 2}, boolean[] {
2745 // linkAlignPanel,superposeWithAlignpanel}} from hash
2746 Object[] jmoldat = jmolViewIds.get(sviewid);
2747 ((boolean[]) jmoldat[3])[0] |= ids[p].getStructureState(s)
2748 .hasAlignwithAlignPanel() ? ids[p].getStructureState(
2749 s).getAlignwithAlignPanel() : false;
2750 // never colour by linked panel if not specified
2751 ((boolean[]) jmoldat[3])[1] |= ids[p].getStructureState(s)
2752 .hasColourwithAlignPanel() ? ids[p]
2753 .getStructureState(s).getColourwithAlignPanel()
2755 // default for pre-2.7 projects is that Jmol colouring is enabled
2756 ((boolean[]) jmoldat[3])[2] &= ids[p].getStructureState(s)
2757 .hasColourByJmol() ? ids[p].getStructureState(s)
2758 .getColourByJmol() : true;
2760 if (((String) jmoldat[1]).length() < ids[p]
2761 .getStructureState(s).getContent().length())
2764 jmoldat[1] = ids[p].getStructureState(s).getContent();
2767 if (ids[p].getFile() != null)
2769 File mapkey = new File(ids[p].getFile());
2770 Object[] seqstrmaps = (Object[]) ((Hashtable) jmoldat[2])
2772 if (seqstrmaps == null)
2774 ((Hashtable) jmoldat[2]).put(mapkey,
2775 seqstrmaps = new Object[]
2776 { pdbFile, ids[p].getId(), new Vector(),
2779 if (!((Vector) seqstrmaps[2]).contains(seq))
2781 ((Vector) seqstrmaps[2]).addElement(seq);
2782 // ((Vector)seqstrmaps[3]).addElement(n) :
2783 // in principle, chains
2784 // should be stored here : do we need to
2785 // TODO: store and recover seq/pdb_id :
2791 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");
2800 // Instantiate the associated Jmol views
2801 for (Entry<String, Object[]> entry : jmolViewIds.entrySet())
2803 String sviewid = entry.getKey();
2804 Object[] svattrib = entry.getValue();
2805 int[] geom = (int[]) svattrib[0];
2806 String state = (String) svattrib[1];
2807 Hashtable<File, Object[]> oldFiles = (Hashtable<File, Object[]>) svattrib[2];
2808 final boolean useinJmolsuperpos = ((boolean[]) svattrib[3])[0], usetoColourbyseq = ((boolean[]) svattrib[3])[1], jmolColouring = ((boolean[]) svattrib[3])[2];
2809 int x = geom[0], y = geom[1], width = geom[2], height = geom[3];
2810 // collate the pdbfile -> sequence mappings from this view
2811 Vector<String> pdbfilenames = new Vector<String>();
2812 Vector<SequenceI[]> seqmaps = new Vector<SequenceI[]>();
2813 Vector<String> pdbids = new Vector<String>();
2815 // Search to see if we've already created this Jmol view
2816 AppJmol comp = null;
2817 JInternalFrame[] frames = null;
2822 frames = Desktop.desktop.getAllFrames();
2823 } catch (ArrayIndexOutOfBoundsException e)
2825 // occasional No such child exceptions are thrown here...
2830 } catch (Exception f)
2835 } while (frames == null);
2836 // search for any Jmol windows already open from other
2837 // alignment views that exactly match the stored structure state
2838 for (int f = 0; comp == null && f < frames.length; f++)
2840 if (frames[f] instanceof AppJmol)
2843 && ((AppJmol) frames[f]).getViewId().equals(sviewid))
2845 // post jalview 2.4 schema includes structure view id
2846 comp = (AppJmol) frames[f];
2848 else if (frames[f].getX() == x && frames[f].getY() == y
2849 && frames[f].getHeight() == height
2850 && frames[f].getWidth() == width)
2852 comp = (AppJmol) frames[f];
2859 // create a new Jmol window.
2860 // First parse the Jmol state to translate filenames loaded into the
2861 // view, and record the order in which files are shown in the Jmol
2862 // view, so we can add the sequence mappings in same order.
2863 StringBuffer newFileLoc = null;
2864 int cp = 0, ncp, ecp;
2865 while ((ncp = state.indexOf("load ", cp)) > -1)
2867 if (newFileLoc == null)
2869 newFileLoc = new StringBuffer();
2873 // look for next filename in load statement
2874 newFileLoc.append(state.substring(cp,
2875 ncp = (state.indexOf("\"", ncp + 1) + 1)));
2876 String oldfilenam = state.substring(ncp,
2877 ecp = state.indexOf("\"", ncp));
2878 // recover the new mapping data for this old filename
2879 // have to normalize filename - since Jmol and jalview do
2881 // translation differently.
2882 Object[] filedat = oldFiles.get(new File(oldfilenam));
2883 newFileLoc.append(Platform
2884 .escapeString((String) filedat[0]));
2885 pdbfilenames.addElement((String) filedat[0]);
2886 pdbids.addElement((String) filedat[1]);
2887 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
2888 .toArray(new SequenceI[0]));
2889 newFileLoc.append("\"");
2890 cp = ecp + 1; // advance beyond last \" and set cursor so we can
2891 // look for next file statement.
2892 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
2896 // just append rest of state
2897 newFileLoc.append(state.substring(cp));
2902 .print("Ignoring incomplete Jmol state for PDB ids: ");
2903 newFileLoc = new StringBuffer(state);
2904 newFileLoc.append("; load append ");
2905 for (File id : oldFiles.keySet())
2907 // add this and any other pdb files that should be present in
2909 Object[] filedat = oldFiles.get(id);
2911 newFileLoc.append(((String) filedat[0]));
2912 pdbfilenames.addElement((String) filedat[0]);
2913 pdbids.addElement((String) filedat[1]);
2914 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
2915 .toArray(new SequenceI[0]));
2916 newFileLoc.append(" \"");
2917 newFileLoc.append((String) filedat[0]);
2918 newFileLoc.append("\"");
2921 newFileLoc.append(";");
2924 if (newFileLoc != null)
2926 int histbug = newFileLoc.indexOf("history = ");
2928 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";",
2930 String val = (diff == -1) ? null : newFileLoc.substring(
2932 if (val != null && val.length() >= 4)
2934 if (val.contains("e"))
2936 if (val.trim().equals("true"))
2944 newFileLoc.replace(histbug, diff, val);
2947 // TODO: assemble String[] { pdb files }, String[] { id for each
2948 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
2949 // seqs_file 2}} from hash
2950 final String[] pdbf = pdbfilenames
2951 .toArray(new String[pdbfilenames.size()]), id = pdbids
2952 .toArray(new String[pdbids.size()]);
2953 final SequenceI[][] sq = seqmaps
2954 .toArray(new SequenceI[seqmaps.size()][]);
2955 final String fileloc = newFileLoc.toString(), vid = sviewid;
2956 final AlignFrame alf = af;
2957 final java.awt.Rectangle rect = new java.awt.Rectangle(x, y,
2961 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
2966 AppJmol sview = null;
2969 sview = new AppJmol(pdbf, id, sq, alf.alignPanel,
2970 useinJmolsuperpos, usetoColourbyseq,
2971 jmolColouring, fileloc, rect, vid);
2972 } catch (OutOfMemoryError ex)
2974 new OOMWarning("restoring structure view for PDB id "
2975 + id, (OutOfMemoryError) ex.getCause());
2976 if (sview != null && sview.isVisible())
2978 sview.closeViewer();
2979 sview.setVisible(false);
2985 } catch (InvocationTargetException ex)
2987 warn("Unexpected error when opening Jmol view.", ex);
2989 } catch (InterruptedException e)
2991 // e.printStackTrace();
2997 // if (comp != null)
2999 // NOTE: if the jalview project is part of a shared session then
3000 // view synchronization should/could be done here.
3002 // add mapping for sequences in this view to an already open Jmol
3004 for (File id : oldFiles.keySet())
3006 // add this and any other pdb files that should be present in the
3008 Object[] filedat = oldFiles.get(id);
3009 String pdbFile = (String) filedat[0];
3010 SequenceI[] seq = ((Vector<SequenceI>) filedat[2])
3011 .toArray(new SequenceI[0]);
3012 comp.jmb.ssm.setMapping(seq, null, pdbFile,
3013 jalview.io.AppletFormatAdapter.FILE);
3014 comp.jmb.addSequenceForStructFile(pdbFile, seq);
3016 // and add the AlignmentPanel's reference to the Jmol view
3017 comp.addAlignmentPanel(ap);
3018 if (useinJmolsuperpos)
3020 comp.useAlignmentPanelForSuperposition(ap);
3024 comp.excludeAlignmentPanelForSuperposition(ap);
3026 if (usetoColourbyseq)
3028 comp.useAlignmentPanelForColourbyseq(ap, !jmolColouring);
3032 comp.excludeAlignmentPanelForColourbyseq(ap);
3038 // and finally return.
3042 AlignFrame loadViewport(String file, JSeq[] JSEQ, Vector hiddenSeqs,
3043 Alignment al, JalviewModelSequence jms, Viewport view,
3044 String uniqueSeqSetId, String viewId,
3045 ArrayList<JvAnnotRow> autoAlan)
3047 AlignFrame af = null;
3048 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
3049 uniqueSeqSetId, viewId);
3051 af.setFileName(file, "Jalview");
3053 for (int i = 0; i < JSEQ.length; i++)
3055 af.viewport.setSequenceColour(af.viewport.getAlignment()
3056 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
3059 af.viewport.gatherViewsHere = view.getGatheredViews();
3061 if (view.getSequenceSetId() != null)
3063 jalview.gui.AlignViewport av = (jalview.gui.AlignViewport) viewportsAdded
3064 .get(uniqueSeqSetId);
3066 af.viewport.setSequenceSetId(uniqueSeqSetId);
3069 // propagate shared settings to this new view
3070 af.viewport.historyList = av.historyList;
3071 af.viewport.redoList = av.redoList;
3075 viewportsAdded.put(uniqueSeqSetId, af.viewport);
3077 // TODO: check if this method can be called repeatedly without
3078 // side-effects if alignpanel already registered.
3079 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
3081 // apply Hidden regions to view.
3082 if (hiddenSeqs != null)
3084 for (int s = 0; s < JSEQ.length; s++)
3086 jalview.datamodel.SequenceGroup hidden = new jalview.datamodel.SequenceGroup();
3088 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
3091 al.getSequenceAt(JSEQ[s].getHiddenSequences(r)), false);
3093 af.viewport.hideRepSequences(al.getSequenceAt(s), hidden);
3096 jalview.datamodel.SequenceI[] hseqs = new jalview.datamodel.SequenceI[hiddenSeqs
3099 for (int s = 0; s < hiddenSeqs.size(); s++)
3101 hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s);
3104 af.viewport.hideSequence(hseqs);
3107 // recover view properties and display parameters
3108 if (view.getViewName() != null)
3110 af.viewport.viewName = view.getViewName();
3111 af.setInitialTabVisible();
3113 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
3116 af.viewport.setShowAnnotation(view.getShowAnnotation());
3117 af.viewport.setAbovePIDThreshold(view.getPidSelected());
3119 af.viewport.setColourText(view.getShowColourText());
3121 af.viewport.setConservationSelected(view.getConservationSelected());
3122 af.viewport.setShowJVSuffix(view.getShowFullId());
3123 af.viewport.rightAlignIds = view.getRightAlignIds();
3124 af.viewport.setFont(new java.awt.Font(view.getFontName(), view
3125 .getFontStyle(), view.getFontSize()));
3126 af.alignPanel.fontChanged();
3127 af.viewport.setRenderGaps(view.getRenderGaps());
3128 af.viewport.setWrapAlignment(view.getWrapAlignment());
3129 af.alignPanel.setWrapAlignment(view.getWrapAlignment());
3130 af.viewport.setShowAnnotation(view.getShowAnnotation());
3131 af.alignPanel.setAnnotationVisible(view.getShowAnnotation());
3133 af.viewport.setShowBoxes(view.getShowBoxes());
3135 af.viewport.setShowText(view.getShowText());
3137 af.viewport.textColour = new java.awt.Color(view.getTextCol1());
3138 af.viewport.textColour2 = new java.awt.Color(view.getTextCol2());
3139 af.viewport.thresholdTextColour = view.getTextColThreshold();
3140 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
3141 .isShowUnconserved() : false);
3142 af.viewport.setStartRes(view.getStartRes());
3143 af.viewport.setStartSeq(view.getStartSeq());
3145 ColourSchemeI cs = null;
3146 // apply colourschemes
3147 if (view.getBgColour() != null)
3149 if (view.getBgColour().startsWith("ucs"))
3151 cs = GetUserColourScheme(jms, view.getBgColour());
3153 else if (view.getBgColour().startsWith("Annotation"))
3155 // int find annotation
3156 if (af.viewport.getAlignment().getAlignmentAnnotation() != null)
3158 for (int i = 0; i < af.viewport.getAlignment()
3159 .getAlignmentAnnotation().length; i++)
3161 if (af.viewport.getAlignment().getAlignmentAnnotation()[i].label
3162 .equals(view.getAnnotationColours().getAnnotation()))
3164 if (af.viewport.getAlignment().getAlignmentAnnotation()[i]
3165 .getThreshold() == null)
3167 af.viewport.getAlignment().getAlignmentAnnotation()[i]
3168 .setThreshold(new jalview.datamodel.GraphLine(view
3169 .getAnnotationColours().getThreshold(),
3170 "Threshold", java.awt.Color.black)
3175 if (view.getAnnotationColours().getColourScheme()
3178 cs = new AnnotationColourGradient(af.viewport
3179 .getAlignment().getAlignmentAnnotation()[i],
3180 new java.awt.Color(view.getAnnotationColours()
3181 .getMinColour()), new java.awt.Color(view
3182 .getAnnotationColours().getMaxColour()),
3183 view.getAnnotationColours().getAboveThreshold());
3185 else if (view.getAnnotationColours().getColourScheme()
3188 cs = new AnnotationColourGradient(af.viewport
3189 .getAlignment().getAlignmentAnnotation()[i],
3190 GetUserColourScheme(jms, view
3191 .getAnnotationColours().getColourScheme()),
3192 view.getAnnotationColours().getAboveThreshold());
3196 cs = new AnnotationColourGradient(af.viewport
3197 .getAlignment().getAlignmentAnnotation()[i],
3198 ColourSchemeProperty.getColour(al, view
3199 .getAnnotationColours().getColourScheme()),
3200 view.getAnnotationColours().getAboveThreshold());
3203 // Also use these settings for all the groups
3204 if (al.getGroups() != null)
3206 for (int g = 0; g < al.getGroups().size(); g++)
3208 jalview.datamodel.SequenceGroup sg = al.getGroups()
3218 * (view.getAnnotationColours().getColourScheme().equals("None"
3219 * )) { sg.cs = new AnnotationColourGradient(
3220 * af.viewport.getAlignment().getAlignmentAnnotation()[i], new
3221 * java.awt.Color(view.getAnnotationColours().
3222 * getMinColour()), new
3223 * java.awt.Color(view.getAnnotationColours().
3225 * view.getAnnotationColours().getAboveThreshold()); } else
3228 sg.cs = new AnnotationColourGradient(af.viewport
3229 .getAlignment().getAlignmentAnnotation()[i],
3230 sg.cs, view.getAnnotationColours()
3231 .getAboveThreshold());
3245 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
3250 cs.setThreshold(view.getPidThreshold(), true);
3251 cs.setConsensus(af.viewport.getSequenceConsensusHash());
3255 af.viewport.setGlobalColourScheme(cs);
3256 af.viewport.setColourAppliesToAllGroups(false);
3258 if (view.getConservationSelected() && cs != null)
3260 cs.setConservationInc(view.getConsThreshold());
3263 af.changeColour(cs);
3265 af.viewport.setColourAppliesToAllGroups(true);
3267 if (view.getShowSequenceFeatures())
3269 af.viewport.showSequenceFeatures = true;
3271 if (view.hasCentreColumnLabels())
3273 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
3275 if (view.hasIgnoreGapsinConsensus())
3277 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
3280 if (view.hasFollowHighlight())
3282 af.viewport.followHighlight = view.getFollowHighlight();
3284 if (view.hasFollowSelection())
3286 af.viewport.followSelection = view.getFollowSelection();
3288 if (view.hasShowConsensusHistogram())
3290 af.viewport.setShowConsensusHistogram(view
3291 .getShowConsensusHistogram());
3295 af.viewport.setShowConsensusHistogram(true);
3297 if (view.hasShowSequenceLogo())
3299 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
3303 af.viewport.setShowSequenceLogo(false);
3305 if (view.hasNormaliseSequenceLogo())
3307 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
3309 if (view.hasShowDbRefTooltip())
3311 af.viewport.setShowDbRefs(view.getShowDbRefTooltip());
3313 if (view.hasShowNPfeatureTooltip())
3315 af.viewport.setShowNpFeats(view.hasShowNPfeatureTooltip());
3317 if (view.hasShowGroupConsensus())
3319 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
3323 af.viewport.setShowGroupConsensus(false);
3325 if (view.hasShowGroupConservation())
3327 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
3331 af.viewport.setShowGroupConservation(false);
3334 // recover featre settings
3335 if (jms.getFeatureSettings() != null)
3337 af.viewport.featuresDisplayed = new Hashtable();
3338 String[] renderOrder = new String[jms.getFeatureSettings()
3339 .getSettingCount()];
3340 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
3342 Setting setting = jms.getFeatureSettings().getSetting(fs);
3343 if (setting.hasMincolour())
3345 GraduatedColor gc = setting.hasMin() ? new GraduatedColor(
3346 new java.awt.Color(setting.getMincolour()),
3347 new java.awt.Color(setting.getColour()),
3348 setting.getMin(), setting.getMax()) : new GraduatedColor(
3349 new java.awt.Color(setting.getMincolour()),
3350 new java.awt.Color(setting.getColour()), 0, 1);
3351 if (setting.hasThreshold())
3353 gc.setThresh(setting.getThreshold());
3354 gc.setThreshType(setting.getThreshstate());
3356 gc.setAutoScaled(true); // default
3357 if (setting.hasAutoScale())
3359 gc.setAutoScaled(setting.getAutoScale());
3361 if (setting.hasColourByLabel())
3363 gc.setColourByLabel(setting.getColourByLabel());
3365 // and put in the feature colour table.
3366 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3367 setting.getType(), gc);
3371 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3373 new java.awt.Color(setting.getColour()));
3375 renderOrder[fs] = setting.getType();
3376 if (setting.hasOrder())
3377 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3378 setting.getType(), setting.getOrder());
3380 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3382 fs / jms.getFeatureSettings().getSettingCount());
3383 if (setting.getDisplay())
3385 af.viewport.featuresDisplayed.put(setting.getType(), new Integer(
3386 setting.getColour()));
3389 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().renderOrder = renderOrder;
3391 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().featureGroups = fgtable = new Hashtable();
3392 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
3394 Group grp = jms.getFeatureSettings().getGroup(gs);
3395 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
3399 if (view.getHiddenColumnsCount() > 0)
3401 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
3403 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
3404 .getHiddenColumns(c).getEnd() // +1
3408 if (view.getCalcIdParam() != null)
3410 for (CalcIdParam calcIdParam : view.getCalcIdParam())
3412 if (calcIdParam != null)
3414 if (recoverCalcIdParam(calcIdParam, af.viewport))
3419 warn("Couldn't recover parameters for "
3420 + calcIdParam.getCalcId());
3425 af.setMenusFromViewport(af.viewport);
3426 // TODO: we don't need to do this if the viewport is aready visible.
3427 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
3429 af.alignPanel.updateAnnotation(false, true); // recompute any autoannotation
3430 reorderAutoannotation(af, al, autoAlan);
3434 private void reorderAutoannotation(AlignFrame af, Alignment al,
3435 ArrayList<JvAnnotRow> autoAlan)
3437 // copy over visualization settings for autocalculated annotation in the
3439 if (al.getAlignmentAnnotation() != null)
3442 * Kludge for magic autoannotation names (see JAL-811)
3444 String[] magicNames = new String[]
3445 { "Consensus", "Quality", "Conservation" };
3446 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
3447 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
3448 for (String nm : magicNames)
3450 visan.put(nm, nullAnnot);
3452 for (JvAnnotRow auan : autoAlan)
3454 visan.put(auan.template.label
3455 + (auan.template.getCalcId() == null ? "" : "\t"
3456 + auan.template.getCalcId()), auan);
3458 int hSize = al.getAlignmentAnnotation().length;
3459 ArrayList<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
3460 // work through any autoCalculated annotation already on the view
3461 // removing it if it should be placed in a different location on the
3462 // annotation panel.
3463 List<String> remains = new ArrayList(visan.keySet());
3464 for (int h = 0; h < hSize; h++)
3466 jalview.datamodel.AlignmentAnnotation jalan = al
3467 .getAlignmentAnnotation()[h];
3468 if (jalan.autoCalculated)
3471 JvAnnotRow valan = visan.get(k = jalan.label);
3472 if (jalan.getCalcId() != null)
3474 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
3479 // delete the auto calculated row from the alignment
3480 al.deleteAnnotation(jalan, false);
3484 if (valan != nullAnnot)
3486 if (jalan != valan.template)
3488 // newly created autoannotation row instance
3489 // so keep a reference to the visible annotation row
3490 // and copy over all relevant attributes
3491 if (valan.template.graphHeight >= 0)
3494 jalan.graphHeight = valan.template.graphHeight;
3496 jalan.visible = valan.template.visible;
3498 reorder.add(new JvAnnotRow(valan.order, jalan));
3503 // Add any (possibly stale) autocalculated rows that were not appended to
3504 // the view during construction
3505 for (String other : remains)
3507 JvAnnotRow othera = visan.get(other);
3508 if (othera != nullAnnot && othera.template.getCalcId() != null
3509 && othera.template.getCalcId().length() > 0)
3511 reorder.add(othera);
3514 // now put the automatic annotation in its correct place
3515 int s = 0, srt[] = new int[reorder.size()];
3516 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
3517 for (JvAnnotRow jvar : reorder)
3520 srt[s++] = jvar.order;
3523 jalview.util.QuickSort.sort(srt, rws);
3524 // and re-insert the annotation at its correct position
3525 for (JvAnnotRow jvar : rws)
3527 al.addAnnotation(jvar.template, jvar.order);
3529 af.alignPanel.adjustAnnotationHeight();
3533 Hashtable skipList = null;
3536 * TODO remove this method
3539 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
3540 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
3541 * throw new Error("Implementation Error. No skipList defined for this
3542 * Jalview2XML instance."); } return (AlignFrame)
3543 * skipList.get(view.getSequenceSetId()); }
3547 * Check if the Jalview view contained in object should be skipped or not.
3550 * @return true if view's sequenceSetId is a key in skipList
3552 private boolean skipViewport(JalviewModel object)
3554 if (skipList == null)
3559 if (skipList.containsKey(id = object.getJalviewModelSequence()
3560 .getViewport()[0].getSequenceSetId()))
3562 if (Cache.log != null && Cache.log.isDebugEnabled())
3564 Cache.log.debug("Skipping seuqence set id " + id);
3571 public void AddToSkipList(AlignFrame af)
3573 if (skipList == null)
3575 skipList = new Hashtable();
3577 skipList.put(af.getViewport().getSequenceSetId(), af);
3580 public void clearSkipList()
3582 if (skipList != null)
3589 private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al)
3591 jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId());
3592 Vector dseqs = null;
3595 // create a list of new dataset sequences
3596 dseqs = new Vector();
3598 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
3600 Sequence vamsasSeq = vamsasSet.getSequence(i);
3601 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs);
3603 // create a new dataset
3606 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
3607 dseqs.copyInto(dsseqs);
3608 ds = new jalview.datamodel.Alignment(dsseqs);
3609 debug("Created new dataset " + vamsasSet.getDatasetId()
3610 + " for alignment " + System.identityHashCode(al));
3611 addDatasetRef(vamsasSet.getDatasetId(), ds);
3613 // set the dataset for the newly imported alignment.
3614 if (al.getDataset() == null)
3623 * sequence definition to create/merge dataset sequence for
3627 * vector to add new dataset sequence to
3629 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
3630 AlignmentI ds, Vector dseqs)
3632 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
3634 jalview.datamodel.Sequence sq = (jalview.datamodel.Sequence) seqRefIds
3635 .get(vamsasSeq.getId());
3636 jalview.datamodel.SequenceI dsq = null;
3637 if (sq != null && sq.getDatasetSequence() != null)
3639 dsq = sq.getDatasetSequence();
3642 String sqid = vamsasSeq.getDsseqid();
3645 // need to create or add a new dataset sequence reference to this sequence
3648 dsq = (jalview.datamodel.SequenceI) seqRefIds.get(sqid);
3653 // make a new dataset sequence
3654 dsq = sq.createDatasetSequence();
3657 // make up a new dataset reference for this sequence
3658 sqid = seqHash(dsq);
3660 dsq.setVamsasId(uniqueSetSuffix + sqid);
3661 seqRefIds.put(sqid, dsq);
3666 dseqs.addElement(dsq);
3671 ds.addSequence(dsq);
3677 { // make this dataset sequence sq's dataset sequence
3678 sq.setDatasetSequence(dsq);
3682 // TODO: refactor this as a merge dataset sequence function
3683 // now check that sq (the dataset sequence) sequence really is the union of
3684 // all references to it
3685 // boolean pre = sq.getStart() < dsq.getStart();
3686 // boolean post = sq.getEnd() > dsq.getEnd();
3690 StringBuffer sb = new StringBuffer();
3691 String newres = jalview.analysis.AlignSeq.extractGaps(
3692 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
3693 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
3694 && newres.length() > dsq.getLength())
3696 // Update with the longer sequence.
3700 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
3701 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
3702 * sb.append(newres.substring(newres.length() - sq.getEnd() -
3703 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
3705 dsq.setSequence(sb.toString());
3707 // TODO: merges will never happen if we 'know' we have the real dataset
3708 // sequence - this should be detected when id==dssid
3709 System.err.println("DEBUG Notice: Merged dataset sequence"); // ("
3710 // + (pre ? "prepended" : "") + " "
3711 // + (post ? "appended" : ""));
3716 java.util.Hashtable datasetIds = null;
3718 java.util.IdentityHashMap dataset2Ids = null;
3720 private Alignment getDatasetFor(String datasetId)
3722 if (datasetIds == null)
3724 datasetIds = new Hashtable();
3727 if (datasetIds.containsKey(datasetId))
3729 return (Alignment) datasetIds.get(datasetId);
3734 private void addDatasetRef(String datasetId, Alignment dataset)
3736 if (datasetIds == null)
3738 datasetIds = new Hashtable();
3740 datasetIds.put(datasetId, dataset);
3744 * make a new dataset ID for this jalview dataset alignment
3749 private String getDatasetIdRef(jalview.datamodel.Alignment dataset)
3751 if (dataset.getDataset() != null)
3753 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
3755 String datasetId = makeHashCode(dataset, null);
3756 if (datasetId == null)
3758 // make a new datasetId and record it
3759 if (dataset2Ids == null)
3761 dataset2Ids = new IdentityHashMap();
3765 datasetId = (String) dataset2Ids.get(dataset);
3767 if (datasetId == null)
3769 datasetId = "ds" + dataset2Ids.size() + 1;
3770 dataset2Ids.put(dataset, datasetId);
3776 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
3778 for (int d = 0; d < sequence.getDBRefCount(); d++)
3780 DBRef dr = sequence.getDBRef(d);
3781 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
3782 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
3783 .getVersion(), sequence.getDBRef(d).getAccessionId());
3784 if (dr.getMapping() != null)
3786 entry.setMap(addMapping(dr.getMapping()));
3788 datasetSequence.addDBRef(entry);
3792 private jalview.datamodel.Mapping addMapping(Mapping m)
3794 SequenceI dsto = null;
3795 // Mapping m = dr.getMapping();
3796 int fr[] = new int[m.getMapListFromCount() * 2];
3797 Enumeration f = m.enumerateMapListFrom();
3798 for (int _i = 0; f.hasMoreElements(); _i += 2)
3800 MapListFrom mf = (MapListFrom) f.nextElement();
3801 fr[_i] = mf.getStart();
3802 fr[_i + 1] = mf.getEnd();
3804 int fto[] = new int[m.getMapListToCount() * 2];
3805 f = m.enumerateMapListTo();
3806 for (int _i = 0; f.hasMoreElements(); _i += 2)
3808 MapListTo mf = (MapListTo) f.nextElement();
3809 fto[_i] = mf.getStart();
3810 fto[_i + 1] = mf.getEnd();
3812 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
3813 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
3814 if (m.getMappingChoice() != null)
3816 MappingChoice mc = m.getMappingChoice();
3817 if (mc.getDseqFor() != null)
3819 String dsfor = "" + mc.getDseqFor();
3820 if (seqRefIds.containsKey(dsfor))
3825 jmap.setTo((SequenceI) seqRefIds.get(dsfor));
3829 frefedSequence.add(new Object[]
3836 * local sequence definition
3838 Sequence ms = mc.getSequence();
3839 jalview.datamodel.Sequence djs = null;
3840 String sqid = ms.getDsseqid();
3841 if (sqid != null && sqid.length() > 0)
3844 * recover dataset sequence
3846 djs = (jalview.datamodel.Sequence) seqRefIds.get(sqid);
3851 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
3852 sqid = ((Object) ms).toString(); // make up a new hascode for
3853 // undefined dataset sequence hash
3854 // (unlikely to happen)
3860 * make a new dataset sequence and add it to refIds hash
3862 djs = new jalview.datamodel.Sequence(ms.getName(),
3864 djs.setStart(jmap.getMap().getToLowest());
3865 djs.setEnd(jmap.getMap().getToHighest());
3866 djs.setVamsasId(uniqueSetSuffix + sqid);
3868 seqRefIds.put(sqid, djs);
3871 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
3880 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
3881 boolean keepSeqRefs)
3884 jalview.schemabinding.version2.JalviewModel jm = SaveState(ap, null,
3890 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
3894 uniqueSetSuffix = "";
3895 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
3900 if (this.frefedSequence == null)
3902 frefedSequence = new Vector();
3905 viewportsAdded = new Hashtable();
3907 AlignFrame af = LoadFromObject(jm, null, false, null);
3908 af.alignPanels.clear();
3909 af.closeMenuItem_actionPerformed(true);
3912 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
3913 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
3914 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
3915 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
3916 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
3919 return af.alignPanel;
3923 * flag indicating if hashtables should be cleared on finalization TODO this
3924 * flag may not be necessary
3926 private final boolean _cleartables = true;
3928 private Hashtable jvids2vobj;
3933 * @see java.lang.Object#finalize()
3936 protected void finalize() throws Throwable
3938 // really make sure we have no buried refs left.
3943 this.seqRefIds = null;
3944 this.seqsToIds = null;
3948 private void warn(String msg)
3953 private void warn(String msg, Exception e)
3955 if (Cache.log != null)
3959 Cache.log.warn(msg, e);
3963 Cache.log.warn(msg);
3968 System.err.println("Warning: " + msg);
3971 e.printStackTrace();
3976 private void debug(String string)
3978 debug(string, null);
3981 private void debug(String msg, Exception e)
3983 if (Cache.log != null)
3987 Cache.log.debug(msg, e);
3991 Cache.log.debug(msg);
3996 System.err.println("Warning: " + msg);
3999 e.printStackTrace();
4005 * set the object to ID mapping tables used to write/recover objects and XML
4006 * ID strings for the jalview project. If external tables are provided then
4007 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
4008 * object goes out of scope. - also populates the datasetIds hashtable with
4009 * alignment objects containing dataset sequences
4012 * Map from ID strings to jalview datamodel
4014 * Map from jalview datamodel to ID strings
4018 public void setObjectMappingTables(Hashtable vobj2jv,
4019 IdentityHashMap jv2vobj)
4021 this.jv2vobj = jv2vobj;
4022 this.vobj2jv = vobj2jv;
4023 Iterator ds = jv2vobj.keySet().iterator();
4025 while (ds.hasNext())
4027 Object jvobj = ds.next();
4028 id = jv2vobj.get(jvobj).toString();
4029 if (jvobj instanceof jalview.datamodel.Alignment)
4031 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
4033 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
4036 else if (jvobj instanceof jalview.datamodel.Sequence)
4038 // register sequence object so the XML parser can recover it.
4039 if (seqRefIds == null)
4041 seqRefIds = new Hashtable();
4043 if (seqsToIds == null)
4045 seqsToIds = new IdentityHashMap();
4047 seqRefIds.put(jv2vobj.get(jvobj).toString(), jvobj);
4048 seqsToIds.put(jvobj, id);
4050 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
4052 if (annotationIds == null)
4054 annotationIds = new Hashtable();
4057 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvobj);
4058 jalview.datamodel.AlignmentAnnotation jvann = (jalview.datamodel.AlignmentAnnotation) jvobj;
4059 if (jvann.annotationId == null)
4061 jvann.annotationId = anid;
4063 if (!jvann.annotationId.equals(anid))
4065 // TODO verify that this is the correct behaviour
4066 this.warn("Overriding Annotation ID for " + anid
4067 + " from different id : " + jvann.annotationId);
4068 jvann.annotationId = anid;
4071 else if (jvobj instanceof String)
4073 if (jvids2vobj == null)
4075 jvids2vobj = new Hashtable();
4076 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
4080 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
4085 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
4086 * objects created from the project archive. If string is null (default for
4087 * construction) then suffix will be set automatically.
4091 public void setUniqueSetSuffix(String string)
4093 uniqueSetSuffix = string;
4098 * uses skipList2 as the skipList for skipping views on sequence sets
4099 * associated with keys in the skipList
4103 public void setSkipList(Hashtable skipList2)
4105 skipList = skipList2;