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(
2301 ae[aa].getColour());
2302 if (firstColour==null)
2304 firstColour=anot[anpos].colour;
2308 jalview.datamodel.AlignmentAnnotation jaa = null;
2310 if (an[i].getGraph())
2312 float llim = 0, hlim = 0;
2313 // if (autoForView || an[i].isAutoCalculated()) {
2316 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2317 an[i].getDescription(), anot, llim, hlim,
2318 an[i].getGraphType());
2320 jaa.graphGroup = an[i].getGraphGroup();
2321 jaa._linecolour=firstColour;
2322 if (an[i].getThresholdLine() != null)
2324 jaa.setThreshold(new jalview.datamodel.GraphLine(an[i]
2325 .getThresholdLine().getValue(), an[i]
2326 .getThresholdLine().getLabel(), new java.awt.Color(
2327 an[i].getThresholdLine().getColour())));
2330 if (autoForView || an[i].isAutoCalculated())
2332 // Hardwire the symbol display line to ensure that labels for
2333 // histograms are displayed
2339 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2340 an[i].getDescription(), anot);
2341 jaa._linecolour=firstColour;
2343 // register new annotation
2344 if (an[i].getId() != null)
2346 annotationIds.put(an[i].getId(), jaa);
2347 jaa.annotationId = an[i].getId();
2349 // recover sequence association
2350 if (an[i].getSequenceRef() != null)
2352 if (al.findName(an[i].getSequenceRef()) != null)
2354 jaa.createSequenceMapping(al.findName(an[i].getSequenceRef()),
2356 al.findName(an[i].getSequenceRef()).addAlignmentAnnotation(jaa);
2359 // and make a note of any group association
2360 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
2362 ArrayList<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
2363 .get(an[i].getGroupRef());
2366 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
2367 groupAnnotRefs.put(an[i].getGroupRef(), aal);
2372 if (an[i].hasScore())
2374 jaa.setScore(an[i].getScore());
2376 if (an[i].hasVisible())
2377 jaa.visible = an[i].getVisible();
2379 if (an[i].hasCentreColLabels())
2380 jaa.centreColLabels = an[i].getCentreColLabels();
2382 if (an[i].hasScaleColLabels())
2384 jaa.scaleColLabel = an[i].getScaleColLabels();
2386 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
2388 // newer files have an 'autoCalculated' flag and store calculation
2389 // state in viewport properties
2390 jaa.autoCalculated = true; // means annotation will be marked for
2391 // update at end of load.
2393 if (an[i].hasGraphHeight())
2395 jaa.graphHeight = an[i].getGraphHeight();
2397 if (an[i].hasBelowAlignment())
2399 jaa.belowAlignment = an[i].isBelowAlignment();
2401 jaa.setCalcId(an[i].getCalcId());
2403 if (jaa.autoCalculated)
2405 autoAlan.add(new JvAnnotRow(i, jaa));
2408 // if (!autoForView)
2410 // add autocalculated group annotation and any user created annotation
2412 al.addAnnotation(jaa);
2417 // ///////////////////////
2419 // Create alignment markup and styles for this view
2420 if (jms.getJGroupCount() > 0)
2422 JGroup[] groups = jms.getJGroup();
2424 for (int i = 0; i < groups.length; i++)
2426 ColourSchemeI cs = null;
2428 if (groups[i].getColour() != null)
2430 if (groups[i].getColour().startsWith("ucs"))
2432 cs = GetUserColourScheme(jms, groups[i].getColour());
2436 cs = ColourSchemeProperty.getColour(al, groups[i].getColour());
2441 cs.setThreshold(groups[i].getPidThreshold(), true);
2445 Vector seqs = new Vector();
2447 for (int s = 0; s < groups[i].getSeqCount(); s++)
2449 String seqId = groups[i].getSeq(s) + "";
2450 jalview.datamodel.SequenceI ts = (jalview.datamodel.SequenceI) seqRefIds
2455 seqs.addElement(ts);
2459 if (seqs.size() < 1)
2464 jalview.datamodel.SequenceGroup sg = new jalview.datamodel.SequenceGroup(
2465 seqs, groups[i].getName(), cs, groups[i].getDisplayBoxes(),
2466 groups[i].getDisplayText(), groups[i].getColourText(),
2467 groups[i].getStart(), groups[i].getEnd());
2469 sg.setOutlineColour(new java.awt.Color(groups[i].getOutlineColour()));
2471 sg.textColour = new java.awt.Color(groups[i].getTextCol1());
2472 sg.textColour2 = new java.awt.Color(groups[i].getTextCol2());
2473 sg.setShowNonconserved(groups[i].hasShowUnconserved() ? groups[i]
2474 .isShowUnconserved() : false);
2475 sg.thresholdTextColour = groups[i].getTextColThreshold();
2476 if (groups[i].hasShowConsensusHistogram())
2478 sg.setShowConsensusHistogram(groups[i].isShowConsensusHistogram());
2481 if (groups[i].hasShowSequenceLogo())
2483 sg.setshowSequenceLogo(groups[i].isShowSequenceLogo());
2485 if (groups[i].hasNormaliseSequenceLogo())
2487 sg.setNormaliseSequenceLogo(groups[i].isNormaliseSequenceLogo());
2489 if (groups[i].hasIgnoreGapsinConsensus())
2491 sg.setIgnoreGapsConsensus(groups[i].getIgnoreGapsinConsensus());
2493 if (groups[i].getConsThreshold() != 0)
2495 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
2496 "All", ResidueProperties.propHash, 3,
2497 sg.getSequences(null), 0, sg.getWidth() - 1);
2499 c.verdict(false, 25);
2500 sg.cs.setConservation(c);
2503 if (groups[i].getId() != null && groupAnnotRefs.size() > 0)
2505 // re-instate unique group/annotation row reference
2506 ArrayList<jalview.datamodel.AlignmentAnnotation> jaal = groupAnnotRefs
2507 .get(groups[i].getId());
2510 for (jalview.datamodel.AlignmentAnnotation jaa : jaal)
2513 if (jaa.autoCalculated)
2515 // match up and try to set group autocalc alignment row for this
2517 if (jaa.label.startsWith("Consensus for "))
2519 sg.setConsensus(jaa);
2521 // match up and try to set group autocalc alignment row for this
2523 if (jaa.label.startsWith("Conservation for "))
2525 sg.setConservationRow(jaa);
2536 // ///////////////////////////////
2539 // If we just load in the same jar file again, the sequenceSetId
2540 // will be the same, and we end up with multiple references
2541 // to the same sequenceSet. We must modify this id on load
2542 // so that each load of the file gives a unique id
2543 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
2544 String viewId = (view.getId() == null ? null : view.getId()
2546 AlignFrame af = null;
2547 AlignViewport av = null;
2548 // now check to see if we really need to create a new viewport.
2549 if (multipleView && viewportsAdded.size() == 0)
2551 // We recovered an alignment for which a viewport already exists.
2552 // TODO: fix up any settings necessary for overlaying stored state onto
2553 // state recovered from another document. (may not be necessary).
2554 // we may need a binding from a viewport in memory to one recovered from
2556 // and then recover its containing af to allow the settings to be applied.
2557 // TODO: fix for vamsas demo
2559 .println("About to recover a viewport for existing alignment: Sequence set ID is "
2561 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
2562 if (seqsetobj != null)
2564 if (seqsetobj instanceof String)
2566 uniqueSeqSetId = (String) seqsetobj;
2568 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
2574 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
2579 AlignmentPanel ap = null;
2580 boolean isnewview = true;
2583 // Check to see if this alignment already has a view id == viewId
2584 jalview.gui.AlignmentPanel views[] = Desktop
2585 .getAlignmentPanels(uniqueSeqSetId);
2586 if (views != null && views.length > 0)
2588 for (int v = 0; v < views.length; v++)
2590 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
2592 // recover the existing alignpanel, alignframe, viewport
2593 af = views[v].alignFrame;
2596 // TODO: could even skip resetting view settings if we don't want to
2597 // change the local settings from other jalview processes
2606 af = loadViewport(file, JSEQ, hiddenSeqs, al, jms, view,
2607 uniqueSeqSetId, viewId, autoAlan);
2612 // /////////////////////////////////////
2613 if (loadTreesAndStructures && jms.getTreeCount() > 0)
2617 for (int t = 0; t < jms.getTreeCount(); t++)
2620 Tree tree = jms.getTree(t);
2622 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
2625 tp = af.ShowNewickTree(
2626 new jalview.io.NewickFile(tree.getNewick()),
2627 tree.getTitle(), tree.getWidth(), tree.getHeight(),
2628 tree.getXpos(), tree.getYpos());
2629 if (tree.getId() != null)
2631 // perhaps bind the tree id to something ?
2636 // update local tree attributes ?
2637 // TODO: should check if tp has been manipulated by user - if so its
2638 // settings shouldn't be modified
2639 tp.setTitle(tree.getTitle());
2640 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
2641 .getWidth(), tree.getHeight()));
2642 tp.av = av; // af.viewport; // TODO: verify 'associate with all
2645 tp.treeCanvas.av = av; // af.viewport;
2646 tp.treeCanvas.ap = ap; // af.alignPanel;
2651 warn("There was a problem recovering stored Newick tree: \n"
2652 + tree.getNewick());
2656 tp.fitToWindow.setState(tree.getFitToWindow());
2657 tp.fitToWindow_actionPerformed(null);
2659 if (tree.getFontName() != null)
2661 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
2662 .getFontStyle(), tree.getFontSize()));
2666 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
2667 .getFontStyle(), tree.getFontSize()));
2670 tp.showPlaceholders(tree.getMarkUnlinked());
2671 tp.showBootstrap(tree.getShowBootstrap());
2672 tp.showDistances(tree.getShowDistances());
2674 tp.treeCanvas.threshold = tree.getThreshold();
2676 if (tree.getCurrentTree())
2678 af.viewport.setCurrentTree(tp.getTree());
2682 } catch (Exception ex)
2684 ex.printStackTrace();
2688 // //LOAD STRUCTURES
2689 if (loadTreesAndStructures)
2691 // run through all PDB ids on the alignment, and collect mappings between
2692 // jmol view ids and all sequences referring to it
2693 Hashtable<String, Object[]> jmolViewIds = new Hashtable();
2695 for (int i = 0; i < JSEQ.length; i++)
2697 if (JSEQ[i].getPdbidsCount() > 0)
2699 Pdbids[] ids = JSEQ[i].getPdbids();
2700 for (int p = 0; p < ids.length; p++)
2702 for (int s = 0; s < ids[p].getStructureStateCount(); s++)
2704 // check to see if we haven't already created this structure view
2705 String sviewid = (ids[p].getStructureState(s).getViewId() == null) ? null
2706 : ids[p].getStructureState(s).getViewId()
2708 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
2709 // Originally : ids[p].getFile()
2710 // : TODO: verify external PDB file recovery still works in normal
2711 // jalview project load
2712 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
2713 jpdb.setId(ids[p].getId());
2715 int x = ids[p].getStructureState(s).getXpos();
2716 int y = ids[p].getStructureState(s).getYpos();
2717 int width = ids[p].getStructureState(s).getWidth();
2718 int height = ids[p].getStructureState(s).getHeight();
2720 // Probably don't need to do this anymore...
2721 // Desktop.desktop.getComponentAt(x, y);
2722 // TODO: NOW: check that this recovers the PDB file correctly.
2723 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
2724 jalview.datamodel.SequenceI seq = (jalview.datamodel.SequenceI) seqRefIds
2725 .get(JSEQ[i].getId() + "");
2726 if (sviewid == null)
2728 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
2731 if (!jmolViewIds.containsKey(sviewid))
2733 jmolViewIds.put(sviewid, new Object[]
2735 { x, y, width, height }, "",
2736 new Hashtable<String, Object[]>(), new boolean[]
2737 { false, false, true } });
2738 // Legacy pre-2.7 conversion JAL-823 :
2739 // do not assume any view has to be linked for colour by
2743 // assemble String[] { pdb files }, String[] { id for each
2744 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
2745 // seqs_file 2}, boolean[] {
2746 // linkAlignPanel,superposeWithAlignpanel}} from hash
2747 Object[] jmoldat = jmolViewIds.get(sviewid);
2748 ((boolean[]) jmoldat[3])[0] |= ids[p].getStructureState(s)
2749 .hasAlignwithAlignPanel() ? ids[p].getStructureState(
2750 s).getAlignwithAlignPanel() : false;
2751 // never colour by linked panel if not specified
2752 ((boolean[]) jmoldat[3])[1] |= ids[p].getStructureState(s)
2753 .hasColourwithAlignPanel() ? ids[p]
2754 .getStructureState(s).getColourwithAlignPanel()
2756 // default for pre-2.7 projects is that Jmol colouring is enabled
2757 ((boolean[]) jmoldat[3])[2] &= ids[p].getStructureState(s)
2758 .hasColourByJmol() ? ids[p].getStructureState(s)
2759 .getColourByJmol() : true;
2761 if (((String) jmoldat[1]).length() < ids[p]
2762 .getStructureState(s).getContent().length())
2765 jmoldat[1] = ids[p].getStructureState(s).getContent();
2768 if (ids[p].getFile() != null)
2770 File mapkey = new File(ids[p].getFile());
2771 Object[] seqstrmaps = (Object[]) ((Hashtable) jmoldat[2])
2773 if (seqstrmaps == null)
2775 ((Hashtable) jmoldat[2]).put(mapkey,
2776 seqstrmaps = new Object[]
2777 { pdbFile, ids[p].getId(), new Vector(),
2780 if (!((Vector) seqstrmaps[2]).contains(seq))
2782 ((Vector) seqstrmaps[2]).addElement(seq);
2783 // ((Vector)seqstrmaps[3]).addElement(n) :
2784 // in principle, chains
2785 // should be stored here : do we need to
2786 // TODO: store and recover seq/pdb_id :
2792 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");
2801 // Instantiate the associated Jmol views
2802 for (Entry<String, Object[]> entry : jmolViewIds.entrySet())
2804 String sviewid = entry.getKey();
2805 Object[] svattrib = entry.getValue();
2806 int[] geom = (int[]) svattrib[0];
2807 String state = (String) svattrib[1];
2808 Hashtable<File, Object[]> oldFiles = (Hashtable<File, Object[]>) svattrib[2];
2809 final boolean useinJmolsuperpos = ((boolean[]) svattrib[3])[0], usetoColourbyseq = ((boolean[]) svattrib[3])[1], jmolColouring = ((boolean[]) svattrib[3])[2];
2810 int x = geom[0], y = geom[1], width = geom[2], height = geom[3];
2811 // collate the pdbfile -> sequence mappings from this view
2812 Vector<String> pdbfilenames = new Vector<String>();
2813 Vector<SequenceI[]> seqmaps = new Vector<SequenceI[]>();
2814 Vector<String> pdbids = new Vector<String>();
2816 // Search to see if we've already created this Jmol view
2817 AppJmol comp = null;
2818 JInternalFrame[] frames = null;
2823 frames = Desktop.desktop.getAllFrames();
2824 } catch (ArrayIndexOutOfBoundsException e)
2826 // occasional No such child exceptions are thrown here...
2831 } catch (Exception f)
2836 } while (frames == null);
2837 // search for any Jmol windows already open from other
2838 // alignment views that exactly match the stored structure state
2839 for (int f = 0; comp == null && f < frames.length; f++)
2841 if (frames[f] instanceof AppJmol)
2844 && ((AppJmol) frames[f]).getViewId().equals(sviewid))
2846 // post jalview 2.4 schema includes structure view id
2847 comp = (AppJmol) frames[f];
2849 else if (frames[f].getX() == x && frames[f].getY() == y
2850 && frames[f].getHeight() == height
2851 && frames[f].getWidth() == width)
2853 comp = (AppJmol) frames[f];
2860 // create a new Jmol window.
2861 // First parse the Jmol state to translate filenames loaded into the
2862 // view, and record the order in which files are shown in the Jmol
2863 // view, so we can add the sequence mappings in same order.
2864 StringBuffer newFileLoc = null;
2865 int cp = 0, ncp, ecp;
2866 while ((ncp = state.indexOf("load ", cp)) > -1)
2868 if (newFileLoc == null)
2870 newFileLoc = new StringBuffer();
2874 // look for next filename in load statement
2875 newFileLoc.append(state.substring(cp,
2876 ncp = (state.indexOf("\"", ncp + 1) + 1)));
2877 String oldfilenam = state.substring(ncp,
2878 ecp = state.indexOf("\"", ncp));
2879 // recover the new mapping data for this old filename
2880 // have to normalize filename - since Jmol and jalview do
2882 // translation differently.
2883 Object[] filedat = oldFiles.get(new File(oldfilenam));
2884 newFileLoc.append(Platform
2885 .escapeString((String) filedat[0]));
2886 pdbfilenames.addElement((String) filedat[0]);
2887 pdbids.addElement((String) filedat[1]);
2888 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
2889 .toArray(new SequenceI[0]));
2890 newFileLoc.append("\"");
2891 cp = ecp + 1; // advance beyond last \" and set cursor so we can
2892 // look for next file statement.
2893 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
2897 // just append rest of state
2898 newFileLoc.append(state.substring(cp));
2903 .print("Ignoring incomplete Jmol state for PDB ids: ");
2904 newFileLoc = new StringBuffer(state);
2905 newFileLoc.append("; load append ");
2906 for (File id : oldFiles.keySet())
2908 // add this and any other pdb files that should be present in
2910 Object[] filedat = oldFiles.get(id);
2912 newFileLoc.append(((String) filedat[0]));
2913 pdbfilenames.addElement((String) filedat[0]);
2914 pdbids.addElement((String) filedat[1]);
2915 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
2916 .toArray(new SequenceI[0]));
2917 newFileLoc.append(" \"");
2918 newFileLoc.append((String) filedat[0]);
2919 newFileLoc.append("\"");
2922 newFileLoc.append(";");
2925 if (newFileLoc != null)
2927 int histbug = newFileLoc.indexOf("history = ");
2929 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";",
2931 String val = (diff == -1) ? null : newFileLoc.substring(
2933 if (val != null && val.length() >= 4)
2935 if (val.contains("e"))
2937 if (val.trim().equals("true"))
2945 newFileLoc.replace(histbug, diff, val);
2948 // TODO: assemble String[] { pdb files }, String[] { id for each
2949 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
2950 // seqs_file 2}} from hash
2951 final String[] pdbf = pdbfilenames
2952 .toArray(new String[pdbfilenames.size()]), id = pdbids
2953 .toArray(new String[pdbids.size()]);
2954 final SequenceI[][] sq = seqmaps
2955 .toArray(new SequenceI[seqmaps.size()][]);
2956 final String fileloc = newFileLoc.toString(), vid = sviewid;
2957 final AlignFrame alf = af;
2958 final java.awt.Rectangle rect = new java.awt.Rectangle(x, y,
2962 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
2967 AppJmol sview = null;
2970 sview = new AppJmol(pdbf, id, sq, alf.alignPanel,
2971 useinJmolsuperpos, usetoColourbyseq,
2972 jmolColouring, fileloc, rect, vid);
2973 } catch (OutOfMemoryError ex)
2975 new OOMWarning("restoring structure view for PDB id "
2976 + id, (OutOfMemoryError) ex.getCause());
2977 if (sview != null && sview.isVisible())
2979 sview.closeViewer();
2980 sview.setVisible(false);
2986 } catch (InvocationTargetException ex)
2988 warn("Unexpected error when opening Jmol view.", ex);
2990 } catch (InterruptedException e)
2992 // e.printStackTrace();
2998 // if (comp != null)
3000 // NOTE: if the jalview project is part of a shared session then
3001 // view synchronization should/could be done here.
3003 // add mapping for sequences in this view to an already open Jmol
3005 for (File id : oldFiles.keySet())
3007 // add this and any other pdb files that should be present in the
3009 Object[] filedat = oldFiles.get(id);
3010 String pdbFile = (String) filedat[0];
3011 SequenceI[] seq = ((Vector<SequenceI>) filedat[2])
3012 .toArray(new SequenceI[0]);
3013 comp.jmb.ssm.setMapping(seq, null, pdbFile,
3014 jalview.io.AppletFormatAdapter.FILE);
3015 comp.jmb.addSequenceForStructFile(pdbFile, seq);
3017 // and add the AlignmentPanel's reference to the Jmol view
3018 comp.addAlignmentPanel(ap);
3019 if (useinJmolsuperpos)
3021 comp.useAlignmentPanelForSuperposition(ap);
3025 comp.excludeAlignmentPanelForSuperposition(ap);
3027 if (usetoColourbyseq)
3029 comp.useAlignmentPanelForColourbyseq(ap, !jmolColouring);
3033 comp.excludeAlignmentPanelForColourbyseq(ap);
3039 // and finally return.
3043 AlignFrame loadViewport(String file, JSeq[] JSEQ, Vector hiddenSeqs,
3044 Alignment al, JalviewModelSequence jms, Viewport view,
3045 String uniqueSeqSetId, String viewId,
3046 ArrayList<JvAnnotRow> autoAlan)
3048 AlignFrame af = null;
3049 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
3050 uniqueSeqSetId, viewId);
3052 af.setFileName(file, "Jalview");
3054 for (int i = 0; i < JSEQ.length; i++)
3056 af.viewport.setSequenceColour(af.viewport.getAlignment()
3057 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
3060 af.viewport.gatherViewsHere = view.getGatheredViews();
3062 if (view.getSequenceSetId() != null)
3064 jalview.gui.AlignViewport av = (jalview.gui.AlignViewport) viewportsAdded
3065 .get(uniqueSeqSetId);
3067 af.viewport.setSequenceSetId(uniqueSeqSetId);
3070 // propagate shared settings to this new view
3071 af.viewport.historyList = av.historyList;
3072 af.viewport.redoList = av.redoList;
3076 viewportsAdded.put(uniqueSeqSetId, af.viewport);
3078 // TODO: check if this method can be called repeatedly without
3079 // side-effects if alignpanel already registered.
3080 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
3082 // apply Hidden regions to view.
3083 if (hiddenSeqs != null)
3085 for (int s = 0; s < JSEQ.length; s++)
3087 jalview.datamodel.SequenceGroup hidden = new jalview.datamodel.SequenceGroup();
3089 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
3092 al.getSequenceAt(JSEQ[s].getHiddenSequences(r)), false);
3094 af.viewport.hideRepSequences(al.getSequenceAt(s), hidden);
3097 jalview.datamodel.SequenceI[] hseqs = new jalview.datamodel.SequenceI[hiddenSeqs
3100 for (int s = 0; s < hiddenSeqs.size(); s++)
3102 hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s);
3105 af.viewport.hideSequence(hseqs);
3108 // recover view properties and display parameters
3109 if (view.getViewName() != null)
3111 af.viewport.viewName = view.getViewName();
3112 af.setInitialTabVisible();
3114 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
3117 af.viewport.setShowAnnotation(view.getShowAnnotation());
3118 af.viewport.setAbovePIDThreshold(view.getPidSelected());
3120 af.viewport.setColourText(view.getShowColourText());
3122 af.viewport.setConservationSelected(view.getConservationSelected());
3123 af.viewport.setShowJVSuffix(view.getShowFullId());
3124 af.viewport.rightAlignIds = view.getRightAlignIds();
3125 af.viewport.setFont(new java.awt.Font(view.getFontName(), view
3126 .getFontStyle(), view.getFontSize()));
3127 af.alignPanel.fontChanged();
3128 af.viewport.setRenderGaps(view.getRenderGaps());
3129 af.viewport.setWrapAlignment(view.getWrapAlignment());
3130 af.alignPanel.setWrapAlignment(view.getWrapAlignment());
3131 af.viewport.setShowAnnotation(view.getShowAnnotation());
3132 af.alignPanel.setAnnotationVisible(view.getShowAnnotation());
3134 af.viewport.setShowBoxes(view.getShowBoxes());
3136 af.viewport.setShowText(view.getShowText());
3138 af.viewport.textColour = new java.awt.Color(view.getTextCol1());
3139 af.viewport.textColour2 = new java.awt.Color(view.getTextCol2());
3140 af.viewport.thresholdTextColour = view.getTextColThreshold();
3141 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
3142 .isShowUnconserved() : false);
3143 af.viewport.setStartRes(view.getStartRes());
3144 af.viewport.setStartSeq(view.getStartSeq());
3146 ColourSchemeI cs = null;
3147 // apply colourschemes
3148 if (view.getBgColour() != null)
3150 if (view.getBgColour().startsWith("ucs"))
3152 cs = GetUserColourScheme(jms, view.getBgColour());
3154 else if (view.getBgColour().startsWith("Annotation"))
3156 // int find annotation
3157 if (af.viewport.getAlignment().getAlignmentAnnotation() != null)
3159 for (int i = 0; i < af.viewport.getAlignment()
3160 .getAlignmentAnnotation().length; i++)
3162 if (af.viewport.getAlignment().getAlignmentAnnotation()[i].label
3163 .equals(view.getAnnotationColours().getAnnotation()))
3165 if (af.viewport.getAlignment().getAlignmentAnnotation()[i]
3166 .getThreshold() == null)
3168 af.viewport.getAlignment().getAlignmentAnnotation()[i]
3169 .setThreshold(new jalview.datamodel.GraphLine(view
3170 .getAnnotationColours().getThreshold(),
3171 "Threshold", java.awt.Color.black)
3176 if (view.getAnnotationColours().getColourScheme()
3179 cs = new AnnotationColourGradient(af.viewport
3180 .getAlignment().getAlignmentAnnotation()[i],
3181 new java.awt.Color(view.getAnnotationColours()
3182 .getMinColour()), new java.awt.Color(view
3183 .getAnnotationColours().getMaxColour()),
3184 view.getAnnotationColours().getAboveThreshold());
3186 else if (view.getAnnotationColours().getColourScheme()
3189 cs = new AnnotationColourGradient(af.viewport
3190 .getAlignment().getAlignmentAnnotation()[i],
3191 GetUserColourScheme(jms, view
3192 .getAnnotationColours().getColourScheme()),
3193 view.getAnnotationColours().getAboveThreshold());
3197 cs = new AnnotationColourGradient(af.viewport
3198 .getAlignment().getAlignmentAnnotation()[i],
3199 ColourSchemeProperty.getColour(al, view
3200 .getAnnotationColours().getColourScheme()),
3201 view.getAnnotationColours().getAboveThreshold());
3204 // Also use these settings for all the groups
3205 if (al.getGroups() != null)
3207 for (int g = 0; g < al.getGroups().size(); g++)
3209 jalview.datamodel.SequenceGroup sg = al.getGroups()
3219 * (view.getAnnotationColours().getColourScheme().equals("None"
3220 * )) { sg.cs = new AnnotationColourGradient(
3221 * af.viewport.getAlignment().getAlignmentAnnotation()[i], new
3222 * java.awt.Color(view.getAnnotationColours().
3223 * getMinColour()), new
3224 * java.awt.Color(view.getAnnotationColours().
3226 * view.getAnnotationColours().getAboveThreshold()); } else
3229 sg.cs = new AnnotationColourGradient(af.viewport
3230 .getAlignment().getAlignmentAnnotation()[i],
3231 sg.cs, view.getAnnotationColours()
3232 .getAboveThreshold());
3246 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
3251 cs.setThreshold(view.getPidThreshold(), true);
3252 cs.setConsensus(af.viewport.getSequenceConsensusHash());
3256 af.viewport.setGlobalColourScheme(cs);
3257 af.viewport.setColourAppliesToAllGroups(false);
3259 if (view.getConservationSelected() && cs != null)
3261 cs.setConservationInc(view.getConsThreshold());
3264 af.changeColour(cs);
3266 af.viewport.setColourAppliesToAllGroups(true);
3268 if (view.getShowSequenceFeatures())
3270 af.viewport.showSequenceFeatures = true;
3272 if (view.hasCentreColumnLabels())
3274 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
3276 if (view.hasIgnoreGapsinConsensus())
3278 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
3281 if (view.hasFollowHighlight())
3283 af.viewport.followHighlight = view.getFollowHighlight();
3285 if (view.hasFollowSelection())
3287 af.viewport.followSelection = view.getFollowSelection();
3289 if (view.hasShowConsensusHistogram())
3291 af.viewport.setShowConsensusHistogram(view
3292 .getShowConsensusHistogram());
3296 af.viewport.setShowConsensusHistogram(true);
3298 if (view.hasShowSequenceLogo())
3300 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
3304 af.viewport.setShowSequenceLogo(false);
3306 if (view.hasNormaliseSequenceLogo())
3308 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
3310 if (view.hasShowDbRefTooltip())
3312 af.viewport.setShowDbRefs(view.getShowDbRefTooltip());
3314 if (view.hasShowNPfeatureTooltip())
3316 af.viewport.setShowNpFeats(view.hasShowNPfeatureTooltip());
3318 if (view.hasShowGroupConsensus())
3320 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
3324 af.viewport.setShowGroupConsensus(false);
3326 if (view.hasShowGroupConservation())
3328 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
3332 af.viewport.setShowGroupConservation(false);
3335 // recover featre settings
3336 if (jms.getFeatureSettings() != null)
3338 af.viewport.featuresDisplayed = new Hashtable();
3339 String[] renderOrder = new String[jms.getFeatureSettings()
3340 .getSettingCount()];
3341 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
3343 Setting setting = jms.getFeatureSettings().getSetting(fs);
3344 if (setting.hasMincolour())
3346 GraduatedColor gc = setting.hasMin() ? new GraduatedColor(
3347 new java.awt.Color(setting.getMincolour()),
3348 new java.awt.Color(setting.getColour()),
3349 setting.getMin(), setting.getMax()) : new GraduatedColor(
3350 new java.awt.Color(setting.getMincolour()),
3351 new java.awt.Color(setting.getColour()), 0, 1);
3352 if (setting.hasThreshold())
3354 gc.setThresh(setting.getThreshold());
3355 gc.setThreshType(setting.getThreshstate());
3357 gc.setAutoScaled(true); // default
3358 if (setting.hasAutoScale())
3360 gc.setAutoScaled(setting.getAutoScale());
3362 if (setting.hasColourByLabel())
3364 gc.setColourByLabel(setting.getColourByLabel());
3366 // and put in the feature colour table.
3367 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3368 setting.getType(), gc);
3372 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3374 new java.awt.Color(setting.getColour()));
3376 renderOrder[fs] = setting.getType();
3377 if (setting.hasOrder())
3378 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3379 setting.getType(), setting.getOrder());
3381 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3383 fs / jms.getFeatureSettings().getSettingCount());
3384 if (setting.getDisplay())
3386 af.viewport.featuresDisplayed.put(setting.getType(), new Integer(
3387 setting.getColour()));
3390 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().renderOrder = renderOrder;
3392 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().featureGroups = fgtable = new Hashtable();
3393 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
3395 Group grp = jms.getFeatureSettings().getGroup(gs);
3396 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
3400 if (view.getHiddenColumnsCount() > 0)
3402 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
3404 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
3405 .getHiddenColumns(c).getEnd() // +1
3409 if (view.getCalcIdParam() != null)
3411 for (CalcIdParam calcIdParam : view.getCalcIdParam())
3413 if (calcIdParam != null)
3415 if (recoverCalcIdParam(calcIdParam, af.viewport))
3420 warn("Couldn't recover parameters for "
3421 + calcIdParam.getCalcId());
3426 af.setMenusFromViewport(af.viewport);
3427 // TODO: we don't need to do this if the viewport is aready visible.
3428 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
3430 af.alignPanel.updateAnnotation(false, true); // recompute any autoannotation
3431 reorderAutoannotation(af, al, autoAlan);
3435 private void reorderAutoannotation(AlignFrame af, Alignment al,
3436 ArrayList<JvAnnotRow> autoAlan)
3438 // copy over visualization settings for autocalculated annotation in the
3440 if (al.getAlignmentAnnotation() != null)
3443 * Kludge for magic autoannotation names (see JAL-811)
3445 String[] magicNames = new String[]
3446 { "Consensus", "Quality", "Conservation" };
3447 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
3448 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
3449 for (String nm : magicNames)
3451 visan.put(nm, nullAnnot);
3453 for (JvAnnotRow auan : autoAlan)
3455 visan.put(auan.template.label
3456 + (auan.template.getCalcId() == null ? "" : "\t"
3457 + auan.template.getCalcId()), auan);
3459 int hSize = al.getAlignmentAnnotation().length;
3460 ArrayList<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
3461 // work through any autoCalculated annotation already on the view
3462 // removing it if it should be placed in a different location on the
3463 // annotation panel.
3464 List<String> remains = new ArrayList(visan.keySet());
3465 for (int h = 0; h < hSize; h++)
3467 jalview.datamodel.AlignmentAnnotation jalan = al
3468 .getAlignmentAnnotation()[h];
3469 if (jalan.autoCalculated)
3472 JvAnnotRow valan = visan.get(k = jalan.label);
3473 if (jalan.getCalcId() != null)
3475 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
3480 // delete the auto calculated row from the alignment
3481 al.deleteAnnotation(jalan, false);
3485 if (valan != nullAnnot)
3487 if (jalan != valan.template)
3489 // newly created autoannotation row instance
3490 // so keep a reference to the visible annotation row
3491 // and copy over all relevant attributes
3492 if (valan.template.graphHeight >= 0)
3495 jalan.graphHeight = valan.template.graphHeight;
3497 jalan.visible = valan.template.visible;
3499 reorder.add(new JvAnnotRow(valan.order, jalan));
3504 // Add any (possibly stale) autocalculated rows that were not appended to
3505 // the view during construction
3506 for (String other : remains)
3508 JvAnnotRow othera = visan.get(other);
3509 if (othera != nullAnnot && othera.template.getCalcId() != null
3510 && othera.template.getCalcId().length() > 0)
3512 reorder.add(othera);
3515 // now put the automatic annotation in its correct place
3516 int s = 0, srt[] = new int[reorder.size()];
3517 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
3518 for (JvAnnotRow jvar : reorder)
3521 srt[s++] = jvar.order;
3524 jalview.util.QuickSort.sort(srt, rws);
3525 // and re-insert the annotation at its correct position
3526 for (JvAnnotRow jvar : rws)
3528 al.addAnnotation(jvar.template, jvar.order);
3530 af.alignPanel.adjustAnnotationHeight();
3534 Hashtable skipList = null;
3537 * TODO remove this method
3540 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
3541 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
3542 * throw new Error("Implementation Error. No skipList defined for this
3543 * Jalview2XML instance."); } return (AlignFrame)
3544 * skipList.get(view.getSequenceSetId()); }
3548 * Check if the Jalview view contained in object should be skipped or not.
3551 * @return true if view's sequenceSetId is a key in skipList
3553 private boolean skipViewport(JalviewModel object)
3555 if (skipList == null)
3560 if (skipList.containsKey(id = object.getJalviewModelSequence()
3561 .getViewport()[0].getSequenceSetId()))
3563 if (Cache.log != null && Cache.log.isDebugEnabled())
3565 Cache.log.debug("Skipping seuqence set id " + id);
3572 public void AddToSkipList(AlignFrame af)
3574 if (skipList == null)
3576 skipList = new Hashtable();
3578 skipList.put(af.getViewport().getSequenceSetId(), af);
3581 public void clearSkipList()
3583 if (skipList != null)
3590 private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al)
3592 jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId());
3593 Vector dseqs = null;
3596 // create a list of new dataset sequences
3597 dseqs = new Vector();
3599 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
3601 Sequence vamsasSeq = vamsasSet.getSequence(i);
3602 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs);
3604 // create a new dataset
3607 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
3608 dseqs.copyInto(dsseqs);
3609 ds = new jalview.datamodel.Alignment(dsseqs);
3610 debug("Created new dataset " + vamsasSet.getDatasetId()
3611 + " for alignment " + System.identityHashCode(al));
3612 addDatasetRef(vamsasSet.getDatasetId(), ds);
3614 // set the dataset for the newly imported alignment.
3615 if (al.getDataset() == null)
3624 * sequence definition to create/merge dataset sequence for
3628 * vector to add new dataset sequence to
3630 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
3631 AlignmentI ds, Vector dseqs)
3633 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
3635 jalview.datamodel.Sequence sq = (jalview.datamodel.Sequence) seqRefIds
3636 .get(vamsasSeq.getId());
3637 jalview.datamodel.SequenceI dsq = null;
3638 if (sq != null && sq.getDatasetSequence() != null)
3640 dsq = sq.getDatasetSequence();
3643 String sqid = vamsasSeq.getDsseqid();
3646 // need to create or add a new dataset sequence reference to this sequence
3649 dsq = (jalview.datamodel.SequenceI) seqRefIds.get(sqid);
3654 // make a new dataset sequence
3655 dsq = sq.createDatasetSequence();
3658 // make up a new dataset reference for this sequence
3659 sqid = seqHash(dsq);
3661 dsq.setVamsasId(uniqueSetSuffix + sqid);
3662 seqRefIds.put(sqid, dsq);
3667 dseqs.addElement(dsq);
3672 ds.addSequence(dsq);
3678 { // make this dataset sequence sq's dataset sequence
3679 sq.setDatasetSequence(dsq);
3683 // TODO: refactor this as a merge dataset sequence function
3684 // now check that sq (the dataset sequence) sequence really is the union of
3685 // all references to it
3686 // boolean pre = sq.getStart() < dsq.getStart();
3687 // boolean post = sq.getEnd() > dsq.getEnd();
3691 StringBuffer sb = new StringBuffer();
3692 String newres = jalview.analysis.AlignSeq.extractGaps(
3693 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
3694 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
3695 && newres.length() > dsq.getLength())
3697 // Update with the longer sequence.
3701 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
3702 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
3703 * sb.append(newres.substring(newres.length() - sq.getEnd() -
3704 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
3706 dsq.setSequence(sb.toString());
3708 // TODO: merges will never happen if we 'know' we have the real dataset
3709 // sequence - this should be detected when id==dssid
3710 System.err.println("DEBUG Notice: Merged dataset sequence"); // ("
3711 // + (pre ? "prepended" : "") + " "
3712 // + (post ? "appended" : ""));
3717 java.util.Hashtable datasetIds = null;
3719 java.util.IdentityHashMap dataset2Ids = null;
3721 private Alignment getDatasetFor(String datasetId)
3723 if (datasetIds == null)
3725 datasetIds = new Hashtable();
3728 if (datasetIds.containsKey(datasetId))
3730 return (Alignment) datasetIds.get(datasetId);
3735 private void addDatasetRef(String datasetId, Alignment dataset)
3737 if (datasetIds == null)
3739 datasetIds = new Hashtable();
3741 datasetIds.put(datasetId, dataset);
3745 * make a new dataset ID for this jalview dataset alignment
3750 private String getDatasetIdRef(jalview.datamodel.Alignment dataset)
3752 if (dataset.getDataset() != null)
3754 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
3756 String datasetId = makeHashCode(dataset, null);
3757 if (datasetId == null)
3759 // make a new datasetId and record it
3760 if (dataset2Ids == null)
3762 dataset2Ids = new IdentityHashMap();
3766 datasetId = (String) dataset2Ids.get(dataset);
3768 if (datasetId == null)
3770 datasetId = "ds" + dataset2Ids.size() + 1;
3771 dataset2Ids.put(dataset, datasetId);
3777 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
3779 for (int d = 0; d < sequence.getDBRefCount(); d++)
3781 DBRef dr = sequence.getDBRef(d);
3782 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
3783 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
3784 .getVersion(), sequence.getDBRef(d).getAccessionId());
3785 if (dr.getMapping() != null)
3787 entry.setMap(addMapping(dr.getMapping()));
3789 datasetSequence.addDBRef(entry);
3793 private jalview.datamodel.Mapping addMapping(Mapping m)
3795 SequenceI dsto = null;
3796 // Mapping m = dr.getMapping();
3797 int fr[] = new int[m.getMapListFromCount() * 2];
3798 Enumeration f = m.enumerateMapListFrom();
3799 for (int _i = 0; f.hasMoreElements(); _i += 2)
3801 MapListFrom mf = (MapListFrom) f.nextElement();
3802 fr[_i] = mf.getStart();
3803 fr[_i + 1] = mf.getEnd();
3805 int fto[] = new int[m.getMapListToCount() * 2];
3806 f = m.enumerateMapListTo();
3807 for (int _i = 0; f.hasMoreElements(); _i += 2)
3809 MapListTo mf = (MapListTo) f.nextElement();
3810 fto[_i] = mf.getStart();
3811 fto[_i + 1] = mf.getEnd();
3813 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
3814 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
3815 if (m.getMappingChoice() != null)
3817 MappingChoice mc = m.getMappingChoice();
3818 if (mc.getDseqFor() != null)
3820 String dsfor = "" + mc.getDseqFor();
3821 if (seqRefIds.containsKey(dsfor))
3826 jmap.setTo((SequenceI) seqRefIds.get(dsfor));
3830 frefedSequence.add(new Object[]
3837 * local sequence definition
3839 Sequence ms = mc.getSequence();
3840 jalview.datamodel.Sequence djs = null;
3841 String sqid = ms.getDsseqid();
3842 if (sqid != null && sqid.length() > 0)
3845 * recover dataset sequence
3847 djs = (jalview.datamodel.Sequence) seqRefIds.get(sqid);
3852 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
3853 sqid = ((Object) ms).toString(); // make up a new hascode for
3854 // undefined dataset sequence hash
3855 // (unlikely to happen)
3861 * make a new dataset sequence and add it to refIds hash
3863 djs = new jalview.datamodel.Sequence(ms.getName(),
3865 djs.setStart(jmap.getMap().getToLowest());
3866 djs.setEnd(jmap.getMap().getToHighest());
3867 djs.setVamsasId(uniqueSetSuffix + sqid);
3869 seqRefIds.put(sqid, djs);
3872 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
3881 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
3882 boolean keepSeqRefs)
3885 jalview.schemabinding.version2.JalviewModel jm = SaveState(ap, null,
3891 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
3895 uniqueSetSuffix = "";
3896 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
3901 if (this.frefedSequence == null)
3903 frefedSequence = new Vector();
3906 viewportsAdded = new Hashtable();
3908 AlignFrame af = LoadFromObject(jm, null, false, null);
3909 af.alignPanels.clear();
3910 af.closeMenuItem_actionPerformed(true);
3913 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
3914 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
3915 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
3916 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
3917 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
3920 return af.alignPanel;
3924 * flag indicating if hashtables should be cleared on finalization TODO this
3925 * flag may not be necessary
3927 private final boolean _cleartables = true;
3929 private Hashtable jvids2vobj;
3934 * @see java.lang.Object#finalize()
3937 protected void finalize() throws Throwable
3939 // really make sure we have no buried refs left.
3944 this.seqRefIds = null;
3945 this.seqsToIds = null;
3949 private void warn(String msg)
3954 private void warn(String msg, Exception e)
3956 if (Cache.log != null)
3960 Cache.log.warn(msg, e);
3964 Cache.log.warn(msg);
3969 System.err.println("Warning: " + msg);
3972 e.printStackTrace();
3977 private void debug(String string)
3979 debug(string, null);
3982 private void debug(String msg, Exception e)
3984 if (Cache.log != null)
3988 Cache.log.debug(msg, e);
3992 Cache.log.debug(msg);
3997 System.err.println("Warning: " + msg);
4000 e.printStackTrace();
4006 * set the object to ID mapping tables used to write/recover objects and XML
4007 * ID strings for the jalview project. If external tables are provided then
4008 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
4009 * object goes out of scope. - also populates the datasetIds hashtable with
4010 * alignment objects containing dataset sequences
4013 * Map from ID strings to jalview datamodel
4015 * Map from jalview datamodel to ID strings
4019 public void setObjectMappingTables(Hashtable vobj2jv,
4020 IdentityHashMap jv2vobj)
4022 this.jv2vobj = jv2vobj;
4023 this.vobj2jv = vobj2jv;
4024 Iterator ds = jv2vobj.keySet().iterator();
4026 while (ds.hasNext())
4028 Object jvobj = ds.next();
4029 id = jv2vobj.get(jvobj).toString();
4030 if (jvobj instanceof jalview.datamodel.Alignment)
4032 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
4034 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
4037 else if (jvobj instanceof jalview.datamodel.Sequence)
4039 // register sequence object so the XML parser can recover it.
4040 if (seqRefIds == null)
4042 seqRefIds = new Hashtable();
4044 if (seqsToIds == null)
4046 seqsToIds = new IdentityHashMap();
4048 seqRefIds.put(jv2vobj.get(jvobj).toString(), jvobj);
4049 seqsToIds.put(jvobj, id);
4051 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
4053 if (annotationIds == null)
4055 annotationIds = new Hashtable();
4058 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvobj);
4059 jalview.datamodel.AlignmentAnnotation jvann = (jalview.datamodel.AlignmentAnnotation) jvobj;
4060 if (jvann.annotationId == null)
4062 jvann.annotationId = anid;
4064 if (!jvann.annotationId.equals(anid))
4066 // TODO verify that this is the correct behaviour
4067 this.warn("Overriding Annotation ID for " + anid
4068 + " from different id : " + jvann.annotationId);
4069 jvann.annotationId = anid;
4072 else if (jvobj instanceof String)
4074 if (jvids2vobj == null)
4076 jvids2vobj = new Hashtable();
4077 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
4081 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
4086 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
4087 * objects created from the project archive. If string is null (default for
4088 * construction) then suffix will be set automatically.
4092 public void setUniqueSetSuffix(String string)
4094 uniqueSetSuffix = string;
4099 * uses skipList2 as the skipList for skipping views on sequence sets
4100 * associated with keys in the skipList
4104 public void setSkipList(Hashtable skipList2)
4106 skipList = skipList2;