2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.0b1)
3 * Copyright (C) 2014 The Jalview Authors
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/>.
17 * The Jalview Authors are detailed in the 'AUTHORS' file.
21 import java.awt.Rectangle;
23 import java.lang.reflect.InvocationTargetException;
26 import java.util.Map.Entry;
27 import java.util.jar.*;
31 import org.exolab.castor.xml.*;
33 import jalview.bin.Cache;
34 import jalview.datamodel.Alignment;
35 import jalview.datamodel.AlignmentAnnotation;
36 import jalview.datamodel.AlignmentI;
37 import jalview.datamodel.SequenceI;
38 import jalview.schemabinding.version2.*;
39 import jalview.schemes.*;
40 import jalview.util.Platform;
41 import jalview.util.jarInputStreamProvider;
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 // create list to store references for any new Jmol viewers created
1674 newStructureViewers=new Vector<AppJmol>();
1675 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
1676 // Workaround is to make sure caller implements the JarInputStreamProvider
1678 // so we can re-open the jar input stream for each entry.
1680 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
1681 af = LoadJalviewAlign(jprovider);
1683 } catch (MalformedURLException e)
1685 errorMessage = "Invalid URL format for '" + file + "'";
1691 SwingUtilities.invokeAndWait(new Runnable()
1695 setLoadingFinishedForNewStructureViewers();
1698 } catch (Exception x)
1706 private jarInputStreamProvider createjarInputStreamProvider(
1707 final String file) throws MalformedURLException
1710 errorMessage = null;
1711 uniqueSetSuffix = null;
1713 viewportsAdded = null;
1714 frefedSequence = null;
1716 if (file.startsWith("http://"))
1718 url = new URL(file);
1720 final URL _url = url;
1721 return new jarInputStreamProvider()
1725 public JarInputStream getJarInputStream() throws IOException
1729 return new JarInputStream(_url.openStream());
1733 return new JarInputStream(new FileInputStream(file));
1738 public String getFilename()
1746 * Recover jalview session from a jalview project archive. Caller may
1747 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
1748 * themselves. Any null fields will be initialised with default values,
1749 * non-null fields are left alone.
1754 public AlignFrame LoadJalviewAlign(final jarInputStreamProvider jprovider)
1756 errorMessage = null;
1757 if (uniqueSetSuffix == null)
1759 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
1761 if (seqRefIds == null)
1763 seqRefIds = new Hashtable();
1765 if (viewportsAdded == null)
1767 viewportsAdded = new Hashtable();
1769 if (frefedSequence == null)
1771 frefedSequence = new Vector();
1774 jalview.gui.AlignFrame af = null;
1775 Hashtable gatherToThisFrame = new Hashtable();
1776 final String file = jprovider.getFilename();
1779 JarInputStream jin = null;
1780 JarEntry jarentry = null;
1785 jin = jprovider.getJarInputStream();
1786 for (int i = 0; i < entryCount; i++)
1788 jarentry = jin.getNextJarEntry();
1791 if (jarentry != null && jarentry.getName().endsWith(".xml"))
1793 InputStreamReader in = new InputStreamReader(jin, "UTF-8");
1794 JalviewModel object = new JalviewModel();
1796 Unmarshaller unmar = new Unmarshaller(object);
1797 unmar.setValidation(false);
1798 object = (JalviewModel) unmar.unmarshal(in);
1799 if (true) // !skipViewport(object))
1801 af = LoadFromObject(object, file, true, jprovider);
1802 if (af.viewport.gatherViewsHere)
1804 gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
1809 else if (jarentry != null)
1811 // Some other file here.
1814 } while (jarentry != null);
1815 resolveFrefedSequences();
1816 } catch (java.io.FileNotFoundException ex)
1818 ex.printStackTrace();
1819 errorMessage = "Couldn't locate Jalview XML file : " + file;
1820 System.err.println("Exception whilst loading jalview XML file : "
1822 } catch (java.net.UnknownHostException ex)
1824 ex.printStackTrace();
1825 errorMessage = "Couldn't locate Jalview XML file : " + file;
1826 System.err.println("Exception whilst loading jalview XML file : "
1828 } catch (Exception ex)
1830 System.err.println("Parsing as Jalview Version 2 file failed.");
1831 ex.printStackTrace(System.err);
1832 if (attemptversion1parse)
1834 // Is Version 1 Jar file?
1837 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
1838 } catch (Exception ex2)
1840 System.err.println("Exception whilst loading as jalviewXMLV1:");
1841 ex2.printStackTrace();
1845 if (Desktop.instance != null)
1847 Desktop.instance.stopLoading();
1851 System.out.println("Successfully loaded archive file");
1854 ex.printStackTrace();
1856 System.err.println("Exception whilst loading jalview XML file : "
1858 } catch (OutOfMemoryError e)
1860 // Don't use the OOM Window here
1861 errorMessage = "Out of memory loading jalview XML file";
1862 System.err.println("Out of memory whilst loading jalview XML file");
1863 e.printStackTrace();
1866 if (Desktop.instance != null)
1868 Desktop.instance.stopLoading();
1871 Enumeration en = gatherToThisFrame.elements();
1872 while (en.hasMoreElements())
1874 Desktop.instance.gatherViews((AlignFrame) en.nextElement());
1876 if (errorMessage != null)
1884 * check errorMessage for a valid error message and raise an error box in the
1885 * GUI or write the current errorMessage to stderr and then clear the error
1888 protected void reportErrors()
1890 reportErrors(false);
1893 protected void reportErrors(final boolean saving)
1895 if (errorMessage != null)
1897 final String finalErrorMessage = errorMessage;
1900 javax.swing.SwingUtilities.invokeLater(new Runnable()
1905 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1906 finalErrorMessage, "Error "
1907 + (saving ? "saving" : "loading")
1908 + " Jalview file", JOptionPane.WARNING_MESSAGE);
1914 System.err.println("Problem loading Jalview file: " + errorMessage);
1917 errorMessage = null;
1920 Hashtable alreadyLoadedPDB;
1923 * when set, local views will be updated from view stored in JalviewXML
1924 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
1925 * sync if this is set to true.
1927 private final boolean updateLocalViews = false;
1929 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
1931 if (alreadyLoadedPDB == null)
1932 alreadyLoadedPDB = new Hashtable();
1934 if (alreadyLoadedPDB.containsKey(pdbId))
1935 return alreadyLoadedPDB.get(pdbId).toString();
1939 JarInputStream jin = jprovider.getJarInputStream();
1941 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
1942 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
1943 * FileInputStream(jprovider)); }
1946 JarEntry entry = null;
1949 entry = jin.getNextJarEntry();
1950 } while (entry != null && !entry.getName().equals(pdbId));
1953 BufferedReader in = new BufferedReader(new InputStreamReader(jin));
1954 File outFile = File.createTempFile("jalview_pdb", ".txt");
1955 outFile.deleteOnExit();
1956 PrintWriter out = new PrintWriter(new FileOutputStream(outFile));
1959 while ((data = in.readLine()) != null)
1966 } catch (Exception foo)
1971 String t = outFile.getAbsolutePath();
1972 alreadyLoadedPDB.put(pdbId, t);
1977 warn("Couldn't find PDB file entry in Jalview Jar for " + pdbId);
1979 } catch (Exception ex)
1981 ex.printStackTrace();
1987 private class JvAnnotRow
1989 public JvAnnotRow(int i, AlignmentAnnotation jaa)
1996 * persisted version of annotation row from which to take vis properties
1998 public jalview.datamodel.AlignmentAnnotation template;
2001 * original position of the annotation row in the alignment
2007 * Load alignment frame from jalview XML DOM object
2012 * filename source string
2013 * @param loadTreesAndStructures
2014 * when false only create Viewport
2016 * data source provider
2017 * @return alignment frame created from view stored in DOM
2019 AlignFrame LoadFromObject(JalviewModel object, String file,
2020 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2022 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2023 Sequence[] vamsasSeq = vamsasSet.getSequence();
2025 JalviewModelSequence jms = object.getJalviewModelSequence();
2027 Viewport view = jms.getViewport(0);
2028 // ////////////////////////////////
2031 Vector hiddenSeqs = null;
2032 jalview.datamodel.Sequence jseq;
2034 ArrayList tmpseqs = new ArrayList();
2036 boolean multipleView = false;
2038 JSeq[] JSEQ = object.getJalviewModelSequence().getJSeq();
2039 int vi = 0; // counter in vamsasSeq array
2040 for (int i = 0; i < JSEQ.length; i++)
2042 String seqId = JSEQ[i].getId();
2044 if (seqRefIds.get(seqId) != null)
2046 tmpseqs.add(seqRefIds.get(seqId));
2047 multipleView = true;
2051 jseq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2052 vamsasSeq[vi].getSequence());
2053 jseq.setDescription(vamsasSeq[vi].getDescription());
2054 jseq.setStart(JSEQ[i].getStart());
2055 jseq.setEnd(JSEQ[i].getEnd());
2056 jseq.setVamsasId(uniqueSetSuffix + seqId);
2057 seqRefIds.put(vamsasSeq[vi].getId(), jseq);
2062 if (JSEQ[i].getHidden())
2064 if (hiddenSeqs == null)
2066 hiddenSeqs = new Vector();
2069 hiddenSeqs.addElement(seqRefIds.get(seqId));
2075 // Create the alignment object from the sequence set
2076 // ///////////////////////////////
2077 jalview.datamodel.Sequence[] orderedSeqs = new jalview.datamodel.Sequence[tmpseqs
2080 tmpseqs.toArray(orderedSeqs);
2082 jalview.datamodel.Alignment al = new jalview.datamodel.Alignment(
2085 // / Add the alignment properties
2086 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2088 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2089 al.setProperty(ssp.getKey(), ssp.getValue());
2093 // SequenceFeatures are added to the DatasetSequence,
2094 // so we must create or recover the dataset before loading features
2095 // ///////////////////////////////
2096 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2098 // older jalview projects do not have a dataset id.
2099 al.setDataset(null);
2103 recoverDatasetFor(vamsasSet, al);
2105 // ///////////////////////////////
2107 Hashtable pdbloaded = new Hashtable();
2110 // load sequence features, database references and any associated PDB
2111 // structures for the alignment
2112 for (int i = 0; i < vamsasSeq.length; i++)
2114 if (JSEQ[i].getFeaturesCount() > 0)
2116 Features[] features = JSEQ[i].getFeatures();
2117 for (int f = 0; f < features.length; f++)
2119 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2120 features[f].getType(), features[f].getDescription(),
2121 features[f].getStatus(), features[f].getBegin(),
2122 features[f].getEnd(), features[f].getFeatureGroup());
2124 sf.setScore(features[f].getScore());
2125 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2127 OtherData keyValue = features[f].getOtherData(od);
2128 if (keyValue.getKey().startsWith("LINK"))
2130 sf.addLink(keyValue.getValue());
2134 sf.setValue(keyValue.getKey(), keyValue.getValue());
2139 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
2142 if (vamsasSeq[i].getDBRefCount() > 0)
2144 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2146 if (JSEQ[i].getPdbidsCount() > 0)
2148 Pdbids[] ids = JSEQ[i].getPdbids();
2149 for (int p = 0; p < ids.length; p++)
2151 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2152 entry.setId(ids[p].getId());
2153 entry.setType(ids[p].getType());
2154 if (ids[p].getFile() != null)
2156 if (!pdbloaded.containsKey(ids[p].getFile()))
2158 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2162 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2166 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2170 } // end !multipleview
2172 // ///////////////////////////////
2173 // LOAD SEQUENCE MAPPINGS
2175 if (vamsasSet.getAlcodonFrameCount() > 0)
2177 // TODO Potentially this should only be done once for all views of an
2179 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2180 for (int i = 0; i < alc.length; i++)
2182 jalview.datamodel.AlignedCodonFrame cf = new jalview.datamodel.AlignedCodonFrame(
2183 alc[i].getAlcodonCount());
2184 if (alc[i].getAlcodonCount() > 0)
2186 Alcodon[] alcods = alc[i].getAlcodon();
2187 for (int p = 0; p < cf.codons.length; p++)
2189 if (alcods[p].hasPos1() && alcods[p].hasPos2()
2190 && alcods[p].hasPos3())
2192 // translated codons require three valid positions
2193 cf.codons[p] = new int[3];
2194 cf.codons[p][0] = (int) alcods[p].getPos1();
2195 cf.codons[p][1] = (int) alcods[p].getPos2();
2196 cf.codons[p][2] = (int) alcods[p].getPos3();
2200 cf.codons[p] = null;
2204 if (alc[i].getAlcodMapCount() > 0)
2206 AlcodMap[] maps = alc[i].getAlcodMap();
2207 for (int m = 0; m < maps.length; m++)
2209 SequenceI dnaseq = (SequenceI) seqRefIds
2210 .get(maps[m].getDnasq());
2212 jalview.datamodel.Mapping mapping = null;
2213 // attach to dna sequence reference.
2214 if (maps[m].getMapping() != null)
2216 mapping = addMapping(maps[m].getMapping());
2220 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
2225 frefedSequence.add(new Object[]
2226 { maps[m].getDnasq(), cf, mapping });
2230 al.addCodonFrame(cf);
2235 // ////////////////////////////////
2237 ArrayList<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
2239 * store any annotations which forward reference a group's ID
2241 Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>>();
2243 if (vamsasSet.getAnnotationCount() > 0)
2245 Annotation[] an = vamsasSet.getAnnotation();
2247 for (int i = 0; i < an.length; i++)
2250 * test if annotation is automatically calculated for this view only
2252 boolean autoForView = false;
2253 if (an[i].getLabel().equals("Quality")
2254 || an[i].getLabel().equals("Conservation")
2255 || an[i].getLabel().equals("Consensus"))
2257 // Kludge for pre 2.5 projects which lacked the autocalculated flag
2259 if (!an[i].hasAutoCalculated())
2261 an[i].setAutoCalculated(true);
2265 || (an[i].hasAutoCalculated() && an[i].isAutoCalculated()))
2267 // remove ID - we don't recover annotation from other views for
2268 // view-specific annotation
2272 // set visiblity for other annotation in this view
2273 if (an[i].getId() != null
2274 && annotationIds.containsKey(an[i].getId()))
2276 jalview.datamodel.AlignmentAnnotation jda = (jalview.datamodel.AlignmentAnnotation) annotationIds
2277 .get(an[i].getId());
2278 // in principle Visible should always be true for annotation displayed
2279 // in multiple views
2280 if (an[i].hasVisible())
2281 jda.visible = an[i].getVisible();
2283 al.addAnnotation(jda);
2287 // Construct new annotation from model.
2288 AnnotationElement[] ae = an[i].getAnnotationElement();
2289 jalview.datamodel.Annotation[] anot = null;
2290 java.awt.Color firstColour = null;
2292 if (!an[i].getScoreOnly())
2294 anot = new jalview.datamodel.Annotation[al.getWidth()];
2295 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
2297 anpos = ae[aa].getPosition();
2299 if (anpos >= anot.length)
2302 anot[anpos] = new jalview.datamodel.Annotation(
2304 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
2305 (ae[aa].getSecondaryStructure() == null || ae[aa]
2306 .getSecondaryStructure().length() == 0) ? ' '
2307 : ae[aa].getSecondaryStructure().charAt(0),
2311 // JBPNote: Consider verifying dataflow for IO of secondary
2312 // structure annotation read from Stockholm files
2313 // this was added to try to ensure that
2314 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
2316 // anot[ae[aa].getPosition()].displayCharacter = "";
2318 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
2319 if (firstColour == null)
2321 firstColour = anot[anpos].colour;
2325 jalview.datamodel.AlignmentAnnotation jaa = null;
2327 if (an[i].getGraph())
2329 float llim = 0, hlim = 0;
2330 // if (autoForView || an[i].isAutoCalculated()) {
2333 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2334 an[i].getDescription(), anot, llim, hlim,
2335 an[i].getGraphType());
2337 jaa.graphGroup = an[i].getGraphGroup();
2338 jaa._linecolour = firstColour;
2339 if (an[i].getThresholdLine() != null)
2341 jaa.setThreshold(new jalview.datamodel.GraphLine(an[i]
2342 .getThresholdLine().getValue(), an[i]
2343 .getThresholdLine().getLabel(), new java.awt.Color(
2344 an[i].getThresholdLine().getColour())));
2347 if (autoForView || an[i].isAutoCalculated())
2349 // Hardwire the symbol display line to ensure that labels for
2350 // histograms are displayed
2356 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2357 an[i].getDescription(), anot);
2358 jaa._linecolour = firstColour;
2360 // register new annotation
2361 if (an[i].getId() != null)
2363 annotationIds.put(an[i].getId(), jaa);
2364 jaa.annotationId = an[i].getId();
2366 // recover sequence association
2367 if (an[i].getSequenceRef() != null)
2369 if (al.findName(an[i].getSequenceRef()) != null)
2371 jaa.createSequenceMapping(al.findName(an[i].getSequenceRef()),
2373 al.findName(an[i].getSequenceRef()).addAlignmentAnnotation(jaa);
2376 // and make a note of any group association
2377 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
2379 ArrayList<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
2380 .get(an[i].getGroupRef());
2383 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
2384 groupAnnotRefs.put(an[i].getGroupRef(), aal);
2389 if (an[i].hasScore())
2391 jaa.setScore(an[i].getScore());
2393 if (an[i].hasVisible())
2394 jaa.visible = an[i].getVisible();
2396 if (an[i].hasCentreColLabels())
2397 jaa.centreColLabels = an[i].getCentreColLabels();
2399 if (an[i].hasScaleColLabels())
2401 jaa.scaleColLabel = an[i].getScaleColLabels();
2403 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
2405 // newer files have an 'autoCalculated' flag and store calculation
2406 // state in viewport properties
2407 jaa.autoCalculated = true; // means annotation will be marked for
2408 // update at end of load.
2410 if (an[i].hasGraphHeight())
2412 jaa.graphHeight = an[i].getGraphHeight();
2414 if (an[i].hasBelowAlignment())
2416 jaa.belowAlignment = an[i].isBelowAlignment();
2418 jaa.setCalcId(an[i].getCalcId());
2420 if (jaa.autoCalculated)
2422 autoAlan.add(new JvAnnotRow(i, jaa));
2425 // if (!autoForView)
2427 // add autocalculated group annotation and any user created annotation
2429 al.addAnnotation(jaa);
2434 // ///////////////////////
2436 // Create alignment markup and styles for this view
2437 if (jms.getJGroupCount() > 0)
2439 JGroup[] groups = jms.getJGroup();
2441 for (int i = 0; i < groups.length; i++)
2443 ColourSchemeI cs = null;
2445 if (groups[i].getColour() != null)
2447 if (groups[i].getColour().startsWith("ucs"))
2449 cs = GetUserColourScheme(jms, groups[i].getColour());
2453 cs = ColourSchemeProperty.getColour(al, groups[i].getColour());
2458 cs.setThreshold(groups[i].getPidThreshold(), true);
2462 Vector seqs = new Vector();
2464 for (int s = 0; s < groups[i].getSeqCount(); s++)
2466 String seqId = groups[i].getSeq(s) + "";
2467 jalview.datamodel.SequenceI ts = (jalview.datamodel.SequenceI) seqRefIds
2472 seqs.addElement(ts);
2476 if (seqs.size() < 1)
2481 jalview.datamodel.SequenceGroup sg = new jalview.datamodel.SequenceGroup(
2482 seqs, groups[i].getName(), cs, groups[i].getDisplayBoxes(),
2483 groups[i].getDisplayText(), groups[i].getColourText(),
2484 groups[i].getStart(), groups[i].getEnd());
2486 sg.setOutlineColour(new java.awt.Color(groups[i].getOutlineColour()));
2488 sg.textColour = new java.awt.Color(groups[i].getTextCol1());
2489 sg.textColour2 = new java.awt.Color(groups[i].getTextCol2());
2490 sg.setShowNonconserved(groups[i].hasShowUnconserved() ? groups[i]
2491 .isShowUnconserved() : false);
2492 sg.thresholdTextColour = groups[i].getTextColThreshold();
2493 if (groups[i].hasShowConsensusHistogram())
2495 sg.setShowConsensusHistogram(groups[i].isShowConsensusHistogram());
2498 if (groups[i].hasShowSequenceLogo())
2500 sg.setshowSequenceLogo(groups[i].isShowSequenceLogo());
2502 if (groups[i].hasNormaliseSequenceLogo())
2504 sg.setNormaliseSequenceLogo(groups[i].isNormaliseSequenceLogo());
2506 if (groups[i].hasIgnoreGapsinConsensus())
2508 sg.setIgnoreGapsConsensus(groups[i].getIgnoreGapsinConsensus());
2510 if (groups[i].getConsThreshold() != 0)
2512 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
2513 "All", ResidueProperties.propHash, 3,
2514 sg.getSequences(null), 0, sg.getWidth() - 1);
2516 c.verdict(false, 25);
2517 sg.cs.setConservation(c);
2520 if (groups[i].getId() != null && groupAnnotRefs.size() > 0)
2522 // re-instate unique group/annotation row reference
2523 ArrayList<jalview.datamodel.AlignmentAnnotation> jaal = groupAnnotRefs
2524 .get(groups[i].getId());
2527 for (jalview.datamodel.AlignmentAnnotation jaa : jaal)
2530 if (jaa.autoCalculated)
2532 // match up and try to set group autocalc alignment row for this
2534 if (jaa.label.startsWith("Consensus for "))
2536 sg.setConsensus(jaa);
2538 // match up and try to set group autocalc alignment row for this
2540 if (jaa.label.startsWith("Conservation for "))
2542 sg.setConservationRow(jaa);
2553 // ///////////////////////////////
2556 // If we just load in the same jar file again, the sequenceSetId
2557 // will be the same, and we end up with multiple references
2558 // to the same sequenceSet. We must modify this id on load
2559 // so that each load of the file gives a unique id
2560 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
2561 String viewId = (view.getId() == null ? null : view.getId()
2563 AlignFrame af = null;
2564 AlignViewport av = null;
2565 // now check to see if we really need to create a new viewport.
2566 if (multipleView && viewportsAdded.size() == 0)
2568 // We recovered an alignment for which a viewport already exists.
2569 // TODO: fix up any settings necessary for overlaying stored state onto
2570 // state recovered from another document. (may not be necessary).
2571 // we may need a binding from a viewport in memory to one recovered from
2573 // and then recover its containing af to allow the settings to be applied.
2574 // TODO: fix for vamsas demo
2576 .println("About to recover a viewport for existing alignment: Sequence set ID is "
2578 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
2579 if (seqsetobj != null)
2581 if (seqsetobj instanceof String)
2583 uniqueSeqSetId = (String) seqsetobj;
2585 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
2591 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
2596 AlignmentPanel ap = null;
2597 boolean isnewview = true;
2600 // Check to see if this alignment already has a view id == viewId
2601 jalview.gui.AlignmentPanel views[] = Desktop
2602 .getAlignmentPanels(uniqueSeqSetId);
2603 if (views != null && views.length > 0)
2605 for (int v = 0; v < views.length; v++)
2607 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
2609 // recover the existing alignpanel, alignframe, viewport
2610 af = views[v].alignFrame;
2613 // TODO: could even skip resetting view settings if we don't want to
2614 // change the local settings from other jalview processes
2623 af = loadViewport(file, JSEQ, hiddenSeqs, al, jms, view,
2624 uniqueSeqSetId, viewId, autoAlan);
2629 // /////////////////////////////////////
2630 if (loadTreesAndStructures && jms.getTreeCount() > 0)
2634 for (int t = 0; t < jms.getTreeCount(); t++)
2637 Tree tree = jms.getTree(t);
2639 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
2642 tp = af.ShowNewickTree(
2643 new jalview.io.NewickFile(tree.getNewick()),
2644 tree.getTitle(), tree.getWidth(), tree.getHeight(),
2645 tree.getXpos(), tree.getYpos());
2646 if (tree.getId() != null)
2648 // perhaps bind the tree id to something ?
2653 // update local tree attributes ?
2654 // TODO: should check if tp has been manipulated by user - if so its
2655 // settings shouldn't be modified
2656 tp.setTitle(tree.getTitle());
2657 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
2658 .getWidth(), tree.getHeight()));
2659 tp.av = av; // af.viewport; // TODO: verify 'associate with all
2662 tp.treeCanvas.av = av; // af.viewport;
2663 tp.treeCanvas.ap = ap; // af.alignPanel;
2668 warn("There was a problem recovering stored Newick tree: \n"
2669 + tree.getNewick());
2673 tp.fitToWindow.setState(tree.getFitToWindow());
2674 tp.fitToWindow_actionPerformed(null);
2676 if (tree.getFontName() != null)
2678 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
2679 .getFontStyle(), tree.getFontSize()));
2683 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
2684 .getFontStyle(), tree.getFontSize()));
2687 tp.showPlaceholders(tree.getMarkUnlinked());
2688 tp.showBootstrap(tree.getShowBootstrap());
2689 tp.showDistances(tree.getShowDistances());
2691 tp.treeCanvas.threshold = tree.getThreshold();
2693 if (tree.getCurrentTree())
2695 af.viewport.setCurrentTree(tp.getTree());
2699 } catch (Exception ex)
2701 ex.printStackTrace();
2705 // //LOAD STRUCTURES
2706 if (loadTreesAndStructures)
2708 // run through all PDB ids on the alignment, and collect mappings between
2709 // jmol view ids and all sequences referring to it
2710 Hashtable<String, Object[]> jmolViewIds = new Hashtable();
2712 for (int i = 0; i < JSEQ.length; i++)
2714 if (JSEQ[i].getPdbidsCount() > 0)
2716 Pdbids[] ids = JSEQ[i].getPdbids();
2717 for (int p = 0; p < ids.length; p++)
2719 for (int s = 0; s < ids[p].getStructureStateCount(); s++)
2721 // check to see if we haven't already created this structure view
2722 String sviewid = (ids[p].getStructureState(s).getViewId() == null) ? null
2723 : ids[p].getStructureState(s).getViewId()
2725 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
2726 // Originally : ids[p].getFile()
2727 // : TODO: verify external PDB file recovery still works in normal
2728 // jalview project load
2729 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
2730 jpdb.setId(ids[p].getId());
2732 int x = ids[p].getStructureState(s).getXpos();
2733 int y = ids[p].getStructureState(s).getYpos();
2734 int width = ids[p].getStructureState(s).getWidth();
2735 int height = ids[p].getStructureState(s).getHeight();
2737 // Probably don't need to do this anymore...
2738 // Desktop.desktop.getComponentAt(x, y);
2739 // TODO: NOW: check that this recovers the PDB file correctly.
2740 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
2741 jalview.datamodel.SequenceI seq = (jalview.datamodel.SequenceI) seqRefIds
2742 .get(JSEQ[i].getId() + "");
2743 if (sviewid == null)
2745 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
2748 if (!jmolViewIds.containsKey(sviewid))
2750 jmolViewIds.put(sviewid, new Object[]
2752 { x, y, width, height }, "",
2753 new Hashtable<String, Object[]>(), new boolean[]
2754 { false, false, true } });
2755 // Legacy pre-2.7 conversion JAL-823 :
2756 // do not assume any view has to be linked for colour by
2760 // assemble String[] { pdb files }, String[] { id for each
2761 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
2762 // seqs_file 2}, boolean[] {
2763 // linkAlignPanel,superposeWithAlignpanel}} from hash
2764 Object[] jmoldat = jmolViewIds.get(sviewid);
2765 ((boolean[]) jmoldat[3])[0] |= ids[p].getStructureState(s)
2766 .hasAlignwithAlignPanel() ? ids[p].getStructureState(
2767 s).getAlignwithAlignPanel() : false;
2768 // never colour by linked panel if not specified
2769 ((boolean[]) jmoldat[3])[1] |= ids[p].getStructureState(s)
2770 .hasColourwithAlignPanel() ? ids[p]
2771 .getStructureState(s).getColourwithAlignPanel()
2773 // default for pre-2.7 projects is that Jmol colouring is enabled
2774 ((boolean[]) jmoldat[3])[2] &= ids[p].getStructureState(s)
2775 .hasColourByJmol() ? ids[p].getStructureState(s)
2776 .getColourByJmol() : true;
2778 if (((String) jmoldat[1]).length() < ids[p]
2779 .getStructureState(s).getContent().length())
2782 jmoldat[1] = ids[p].getStructureState(s).getContent();
2785 if (ids[p].getFile() != null)
2787 File mapkey = new File(ids[p].getFile());
2788 Object[] seqstrmaps = (Object[]) ((Hashtable) jmoldat[2])
2790 if (seqstrmaps == null)
2792 ((Hashtable) jmoldat[2]).put(mapkey,
2793 seqstrmaps = new Object[]
2794 { pdbFile, ids[p].getId(), new Vector(),
2797 if (!((Vector) seqstrmaps[2]).contains(seq))
2799 ((Vector) seqstrmaps[2]).addElement(seq);
2800 // ((Vector)seqstrmaps[3]).addElement(n) :
2801 // in principle, chains
2802 // should be stored here : do we need to
2803 // TODO: store and recover seq/pdb_id :
2809 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");
2818 // Instantiate the associated Jmol views
2819 for (Entry<String, Object[]> entry : jmolViewIds.entrySet())
2821 String sviewid = entry.getKey();
2822 Object[] svattrib = entry.getValue();
2823 int[] geom = (int[]) svattrib[0];
2824 String state = (String) svattrib[1];
2825 Hashtable<File, Object[]> oldFiles = (Hashtable<File, Object[]>) svattrib[2];
2826 final boolean useinJmolsuperpos = ((boolean[]) svattrib[3])[0], usetoColourbyseq = ((boolean[]) svattrib[3])[1], jmolColouring = ((boolean[]) svattrib[3])[2];
2827 int x = geom[0], y = geom[1], width = geom[2], height = geom[3];
2828 // collate the pdbfile -> sequence mappings from this view
2829 Vector<String> pdbfilenames = new Vector<String>();
2830 Vector<SequenceI[]> seqmaps = new Vector<SequenceI[]>();
2831 Vector<String> pdbids = new Vector<String>();
2833 // Search to see if we've already created this Jmol view
2834 AppJmol comp = null;
2835 JInternalFrame[] frames = null;
2840 frames = Desktop.desktop.getAllFrames();
2841 } catch (ArrayIndexOutOfBoundsException e)
2843 // occasional No such child exceptions are thrown here...
2848 } catch (Exception f)
2853 } while (frames == null);
2854 // search for any Jmol windows already open from other
2855 // alignment views that exactly match the stored structure state
2856 for (int f = 0; comp == null && f < frames.length; f++)
2858 if (frames[f] instanceof AppJmol)
2861 && ((AppJmol) frames[f]).getViewId().equals(sviewid))
2863 // post jalview 2.4 schema includes structure view id
2864 comp = (AppJmol) frames[f];
2866 else if (frames[f].getX() == x && frames[f].getY() == y
2867 && frames[f].getHeight() == height
2868 && frames[f].getWidth() == width)
2870 comp = (AppJmol) frames[f];
2877 // create a new Jmol window.
2878 // First parse the Jmol state to translate filenames loaded into the
2879 // view, and record the order in which files are shown in the Jmol
2880 // view, so we can add the sequence mappings in same order.
2881 StringBuffer newFileLoc = null;
2882 int cp = 0, ncp, ecp;
2883 while ((ncp = state.indexOf("load ", cp)) > -1)
2885 if (newFileLoc == null)
2887 newFileLoc = new StringBuffer();
2891 // look for next filename in load statement
2892 newFileLoc.append(state.substring(cp,
2893 ncp = (state.indexOf("\"", ncp + 1) + 1)));
2894 String oldfilenam = state.substring(ncp,
2895 ecp = state.indexOf("\"", ncp));
2896 // recover the new mapping data for this old filename
2897 // have to normalize filename - since Jmol and jalview do
2899 // translation differently.
2900 Object[] filedat = oldFiles.get(new File(oldfilenam));
2901 newFileLoc.append(Platform
2902 .escapeString((String) filedat[0]));
2903 pdbfilenames.addElement((String) filedat[0]);
2904 pdbids.addElement((String) filedat[1]);
2905 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
2906 .toArray(new SequenceI[0]));
2907 newFileLoc.append("\"");
2908 cp = ecp + 1; // advance beyond last \" and set cursor so we can
2909 // look for next file statement.
2910 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
2914 // just append rest of state
2915 newFileLoc.append(state.substring(cp));
2920 .print("Ignoring incomplete Jmol state for PDB ids: ");
2921 newFileLoc = new StringBuffer(state);
2922 newFileLoc.append("; load append ");
2923 for (File id : oldFiles.keySet())
2925 // add this and any other pdb files that should be present in
2927 Object[] filedat = oldFiles.get(id);
2929 newFileLoc.append(((String) filedat[0]));
2930 pdbfilenames.addElement((String) filedat[0]);
2931 pdbids.addElement((String) filedat[1]);
2932 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
2933 .toArray(new SequenceI[0]));
2934 newFileLoc.append(" \"");
2935 newFileLoc.append((String) filedat[0]);
2936 newFileLoc.append("\"");
2939 newFileLoc.append(";");
2942 if (newFileLoc != null)
2944 int histbug = newFileLoc.indexOf("history = ");
2946 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";",
2948 String val = (diff == -1) ? null : newFileLoc.substring(
2950 if (val != null && val.length() >= 4)
2952 if (val.contains("e"))
2954 if (val.trim().equals("true"))
2962 newFileLoc.replace(histbug, diff, val);
2965 // TODO: assemble String[] { pdb files }, String[] { id for each
2966 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
2967 // seqs_file 2}} from hash
2968 final String[] pdbf = pdbfilenames
2969 .toArray(new String[pdbfilenames.size()]), id = pdbids
2970 .toArray(new String[pdbids.size()]);
2971 final SequenceI[][] sq = seqmaps
2972 .toArray(new SequenceI[seqmaps.size()][]);
2973 final String fileloc = newFileLoc.toString(), vid = sviewid;
2974 final AlignFrame alf = af;
2975 final java.awt.Rectangle rect = new java.awt.Rectangle(x, y,
2979 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
2984 AppJmol sview = null;
2987 sview = new AppJmol(pdbf, id, sq, alf.alignPanel,
2988 useinJmolsuperpos, usetoColourbyseq,
2989 jmolColouring, fileloc, rect, vid);
2990 addNewStructureViewer(sview);
2991 } catch (OutOfMemoryError ex)
2993 new OOMWarning("restoring structure view for PDB id "
2994 + id, (OutOfMemoryError) ex.getCause());
2995 if (sview != null && sview.isVisible())
2997 sview.closeViewer();
2998 sview.setVisible(false);
3004 } catch (InvocationTargetException ex)
3006 warn("Unexpected error when opening Jmol view.", ex);
3008 } catch (InterruptedException e)
3010 // e.printStackTrace();
3016 // if (comp != null)
3018 // NOTE: if the jalview project is part of a shared session then
3019 // view synchronization should/could be done here.
3021 // add mapping for sequences in this view to an already open Jmol
3023 for (File id : oldFiles.keySet())
3025 // add this and any other pdb files that should be present in the
3027 Object[] filedat = oldFiles.get(id);
3028 String pdbFile = (String) filedat[0];
3029 SequenceI[] seq = ((Vector<SequenceI>) filedat[2])
3030 .toArray(new SequenceI[0]);
3031 comp.jmb.ssm.setMapping(seq, null, pdbFile,
3032 jalview.io.AppletFormatAdapter.FILE);
3033 comp.jmb.addSequenceForStructFile(pdbFile, seq);
3035 // and add the AlignmentPanel's reference to the Jmol view
3036 comp.addAlignmentPanel(ap);
3037 if (useinJmolsuperpos)
3039 comp.useAlignmentPanelForSuperposition(ap);
3043 comp.excludeAlignmentPanelForSuperposition(ap);
3045 if (usetoColourbyseq)
3047 comp.useAlignmentPanelForColourbyseq(ap, !jmolColouring);
3051 comp.excludeAlignmentPanelForColourbyseq(ap);
3057 // and finally return.
3060 Vector<AppJmol> newStructureViewers=null;
3061 protected void addNewStructureViewer(AppJmol sview)
3063 if (newStructureViewers!=null)
3065 sview.jmb.setFinishedLoadingFromArchive(false);
3066 newStructureViewers.add(sview);
3069 protected void setLoadingFinishedForNewStructureViewers()
3071 if (newStructureViewers!=null)
3073 for (AppJmol sview:newStructureViewers)
3075 sview.jmb.setFinishedLoadingFromArchive(true);
3077 newStructureViewers.clear();
3078 newStructureViewers=null;
3082 AlignFrame loadViewport(String file, JSeq[] JSEQ, Vector hiddenSeqs,
3083 Alignment al, JalviewModelSequence jms, Viewport view,
3084 String uniqueSeqSetId, String viewId,
3085 ArrayList<JvAnnotRow> autoAlan)
3087 AlignFrame af = null;
3088 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
3089 uniqueSeqSetId, viewId);
3091 af.setFileName(file, "Jalview");
3093 for (int i = 0; i < JSEQ.length; i++)
3095 af.viewport.setSequenceColour(af.viewport.getAlignment()
3096 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
3099 af.viewport.gatherViewsHere = view.getGatheredViews();
3101 if (view.getSequenceSetId() != null)
3103 jalview.gui.AlignViewport av = (jalview.gui.AlignViewport) viewportsAdded
3104 .get(uniqueSeqSetId);
3106 af.viewport.setSequenceSetId(uniqueSeqSetId);
3109 // propagate shared settings to this new view
3110 af.viewport.historyList = av.historyList;
3111 af.viewport.redoList = av.redoList;
3115 viewportsAdded.put(uniqueSeqSetId, af.viewport);
3117 // TODO: check if this method can be called repeatedly without
3118 // side-effects if alignpanel already registered.
3119 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
3121 // apply Hidden regions to view.
3122 if (hiddenSeqs != null)
3124 for (int s = 0; s < JSEQ.length; s++)
3126 jalview.datamodel.SequenceGroup hidden = new jalview.datamodel.SequenceGroup();
3128 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
3131 al.getSequenceAt(JSEQ[s].getHiddenSequences(r)), false);
3133 af.viewport.hideRepSequences(al.getSequenceAt(s), hidden);
3136 jalview.datamodel.SequenceI[] hseqs = new jalview.datamodel.SequenceI[hiddenSeqs
3139 for (int s = 0; s < hiddenSeqs.size(); s++)
3141 hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s);
3144 af.viewport.hideSequence(hseqs);
3147 // recover view properties and display parameters
3148 if (view.getViewName() != null)
3150 af.viewport.viewName = view.getViewName();
3151 af.setInitialTabVisible();
3153 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
3156 af.viewport.setShowAnnotation(view.getShowAnnotation());
3157 af.viewport.setAbovePIDThreshold(view.getPidSelected());
3159 af.viewport.setColourText(view.getShowColourText());
3161 af.viewport.setConservationSelected(view.getConservationSelected());
3162 af.viewport.setShowJVSuffix(view.getShowFullId());
3163 af.viewport.rightAlignIds = view.getRightAlignIds();
3164 af.viewport.setFont(new java.awt.Font(view.getFontName(), view
3165 .getFontStyle(), view.getFontSize()));
3166 af.alignPanel.fontChanged();
3167 af.viewport.setRenderGaps(view.getRenderGaps());
3168 af.viewport.setWrapAlignment(view.getWrapAlignment());
3169 af.alignPanel.setWrapAlignment(view.getWrapAlignment());
3170 af.viewport.setShowAnnotation(view.getShowAnnotation());
3171 af.alignPanel.setAnnotationVisible(view.getShowAnnotation());
3173 af.viewport.setShowBoxes(view.getShowBoxes());
3175 af.viewport.setShowText(view.getShowText());
3177 af.viewport.textColour = new java.awt.Color(view.getTextCol1());
3178 af.viewport.textColour2 = new java.awt.Color(view.getTextCol2());
3179 af.viewport.thresholdTextColour = view.getTextColThreshold();
3180 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
3181 .isShowUnconserved() : false);
3182 af.viewport.setStartRes(view.getStartRes());
3183 af.viewport.setStartSeq(view.getStartSeq());
3185 ColourSchemeI cs = null;
3186 // apply colourschemes
3187 if (view.getBgColour() != null)
3189 if (view.getBgColour().startsWith("ucs"))
3191 cs = GetUserColourScheme(jms, view.getBgColour());
3193 else if (view.getBgColour().startsWith("Annotation"))
3195 // int find annotation
3196 if (af.viewport.getAlignment().getAlignmentAnnotation() != null)
3198 for (int i = 0; i < af.viewport.getAlignment()
3199 .getAlignmentAnnotation().length; i++)
3201 if (af.viewport.getAlignment().getAlignmentAnnotation()[i].label
3202 .equals(view.getAnnotationColours().getAnnotation()))
3204 if (af.viewport.getAlignment().getAlignmentAnnotation()[i]
3205 .getThreshold() == null)
3207 af.viewport.getAlignment().getAlignmentAnnotation()[i]
3208 .setThreshold(new jalview.datamodel.GraphLine(view
3209 .getAnnotationColours().getThreshold(),
3210 "Threshold", java.awt.Color.black)
3215 if (view.getAnnotationColours().getColourScheme()
3218 cs = new AnnotationColourGradient(af.viewport
3219 .getAlignment().getAlignmentAnnotation()[i],
3220 new java.awt.Color(view.getAnnotationColours()
3221 .getMinColour()), new java.awt.Color(view
3222 .getAnnotationColours().getMaxColour()),
3223 view.getAnnotationColours().getAboveThreshold());
3225 else if (view.getAnnotationColours().getColourScheme()
3228 cs = new AnnotationColourGradient(af.viewport
3229 .getAlignment().getAlignmentAnnotation()[i],
3230 GetUserColourScheme(jms, view
3231 .getAnnotationColours().getColourScheme()),
3232 view.getAnnotationColours().getAboveThreshold());
3236 cs = new AnnotationColourGradient(af.viewport
3237 .getAlignment().getAlignmentAnnotation()[i],
3238 ColourSchemeProperty.getColour(al, view
3239 .getAnnotationColours().getColourScheme()),
3240 view.getAnnotationColours().getAboveThreshold());
3243 // Also use these settings for all the groups
3244 if (al.getGroups() != null)
3246 for (int g = 0; g < al.getGroups().size(); g++)
3248 jalview.datamodel.SequenceGroup sg = al.getGroups()
3258 * (view.getAnnotationColours().getColourScheme().equals("None"
3259 * )) { sg.cs = new AnnotationColourGradient(
3260 * af.viewport.getAlignment().getAlignmentAnnotation()[i], new
3261 * java.awt.Color(view.getAnnotationColours().
3262 * getMinColour()), new
3263 * java.awt.Color(view.getAnnotationColours().
3265 * view.getAnnotationColours().getAboveThreshold()); } else
3268 sg.cs = new AnnotationColourGradient(af.viewport
3269 .getAlignment().getAlignmentAnnotation()[i],
3270 sg.cs, view.getAnnotationColours()
3271 .getAboveThreshold());
3285 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
3290 cs.setThreshold(view.getPidThreshold(), true);
3291 cs.setConsensus(af.viewport.getSequenceConsensusHash());
3295 af.viewport.setGlobalColourScheme(cs);
3296 af.viewport.setColourAppliesToAllGroups(false);
3298 if (view.getConservationSelected() && cs != null)
3300 cs.setConservationInc(view.getConsThreshold());
3303 af.changeColour(cs);
3305 af.viewport.setColourAppliesToAllGroups(true);
3307 if (view.getShowSequenceFeatures())
3309 af.viewport.showSequenceFeatures = true;
3311 if (view.hasCentreColumnLabels())
3313 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
3315 if (view.hasIgnoreGapsinConsensus())
3317 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
3320 if (view.hasFollowHighlight())
3322 af.viewport.followHighlight = view.getFollowHighlight();
3324 if (view.hasFollowSelection())
3326 af.viewport.followSelection = view.getFollowSelection();
3328 if (view.hasShowConsensusHistogram())
3330 af.viewport.setShowConsensusHistogram(view
3331 .getShowConsensusHistogram());
3335 af.viewport.setShowConsensusHistogram(true);
3337 if (view.hasShowSequenceLogo())
3339 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
3343 af.viewport.setShowSequenceLogo(false);
3345 if (view.hasNormaliseSequenceLogo())
3347 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
3349 if (view.hasShowDbRefTooltip())
3351 af.viewport.setShowDbRefs(view.getShowDbRefTooltip());
3353 if (view.hasShowNPfeatureTooltip())
3355 af.viewport.setShowNpFeats(view.hasShowNPfeatureTooltip());
3357 if (view.hasShowGroupConsensus())
3359 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
3363 af.viewport.setShowGroupConsensus(false);
3365 if (view.hasShowGroupConservation())
3367 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
3371 af.viewport.setShowGroupConservation(false);
3374 // recover featre settings
3375 if (jms.getFeatureSettings() != null)
3377 af.viewport.featuresDisplayed = new Hashtable();
3378 String[] renderOrder = new String[jms.getFeatureSettings()
3379 .getSettingCount()];
3380 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
3382 Setting setting = jms.getFeatureSettings().getSetting(fs);
3383 if (setting.hasMincolour())
3385 GraduatedColor gc = setting.hasMin() ? new GraduatedColor(
3386 new java.awt.Color(setting.getMincolour()),
3387 new java.awt.Color(setting.getColour()),
3388 setting.getMin(), setting.getMax()) : new GraduatedColor(
3389 new java.awt.Color(setting.getMincolour()),
3390 new java.awt.Color(setting.getColour()), 0, 1);
3391 if (setting.hasThreshold())
3393 gc.setThresh(setting.getThreshold());
3394 gc.setThreshType(setting.getThreshstate());
3396 gc.setAutoScaled(true); // default
3397 if (setting.hasAutoScale())
3399 gc.setAutoScaled(setting.getAutoScale());
3401 if (setting.hasColourByLabel())
3403 gc.setColourByLabel(setting.getColourByLabel());
3405 // and put in the feature colour table.
3406 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3407 setting.getType(), gc);
3411 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3413 new java.awt.Color(setting.getColour()));
3415 renderOrder[fs] = setting.getType();
3416 if (setting.hasOrder())
3417 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3418 setting.getType(), setting.getOrder());
3420 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3422 fs / jms.getFeatureSettings().getSettingCount());
3423 if (setting.getDisplay())
3425 af.viewport.featuresDisplayed.put(setting.getType(), new Integer(
3426 setting.getColour()));
3429 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().renderOrder = renderOrder;
3431 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().featureGroups = fgtable = new Hashtable();
3432 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
3434 Group grp = jms.getFeatureSettings().getGroup(gs);
3435 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
3439 if (view.getHiddenColumnsCount() > 0)
3441 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
3443 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
3444 .getHiddenColumns(c).getEnd() // +1
3448 if (view.getCalcIdParam() != null)
3450 for (CalcIdParam calcIdParam : view.getCalcIdParam())
3452 if (calcIdParam != null)
3454 if (recoverCalcIdParam(calcIdParam, af.viewport))
3459 warn("Couldn't recover parameters for "
3460 + calcIdParam.getCalcId());
3465 af.setMenusFromViewport(af.viewport);
3466 // TODO: we don't need to do this if the viewport is aready visible.
3467 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
3469 af.alignPanel.updateAnnotation(false, true); // recompute any autoannotation
3470 reorderAutoannotation(af, al, autoAlan);
3474 private void reorderAutoannotation(AlignFrame af, Alignment al,
3475 ArrayList<JvAnnotRow> autoAlan)
3477 // copy over visualization settings for autocalculated annotation in the
3479 if (al.getAlignmentAnnotation() != null)
3482 * Kludge for magic autoannotation names (see JAL-811)
3484 String[] magicNames = new String[]
3485 { "Consensus", "Quality", "Conservation" };
3486 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
3487 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
3488 for (String nm : magicNames)
3490 visan.put(nm, nullAnnot);
3492 for (JvAnnotRow auan : autoAlan)
3494 visan.put(auan.template.label
3495 + (auan.template.getCalcId() == null ? "" : "\t"
3496 + auan.template.getCalcId()), auan);
3498 int hSize = al.getAlignmentAnnotation().length;
3499 ArrayList<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
3500 // work through any autoCalculated annotation already on the view
3501 // removing it if it should be placed in a different location on the
3502 // annotation panel.
3503 List<String> remains = new ArrayList(visan.keySet());
3504 for (int h = 0; h < hSize; h++)
3506 jalview.datamodel.AlignmentAnnotation jalan = al
3507 .getAlignmentAnnotation()[h];
3508 if (jalan.autoCalculated)
3511 JvAnnotRow valan = visan.get(k = jalan.label);
3512 if (jalan.getCalcId() != null)
3514 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
3519 // delete the auto calculated row from the alignment
3520 al.deleteAnnotation(jalan, false);
3524 if (valan != nullAnnot)
3526 if (jalan != valan.template)
3528 // newly created autoannotation row instance
3529 // so keep a reference to the visible annotation row
3530 // and copy over all relevant attributes
3531 if (valan.template.graphHeight >= 0)
3534 jalan.graphHeight = valan.template.graphHeight;
3536 jalan.visible = valan.template.visible;
3538 reorder.add(new JvAnnotRow(valan.order, jalan));
3543 // Add any (possibly stale) autocalculated rows that were not appended to
3544 // the view during construction
3545 for (String other : remains)
3547 JvAnnotRow othera = visan.get(other);
3548 if (othera != nullAnnot && othera.template.getCalcId() != null
3549 && othera.template.getCalcId().length() > 0)
3551 reorder.add(othera);
3554 // now put the automatic annotation in its correct place
3555 int s = 0, srt[] = new int[reorder.size()];
3556 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
3557 for (JvAnnotRow jvar : reorder)
3560 srt[s++] = jvar.order;
3563 jalview.util.QuickSort.sort(srt, rws);
3564 // and re-insert the annotation at its correct position
3565 for (JvAnnotRow jvar : rws)
3567 al.addAnnotation(jvar.template, jvar.order);
3569 af.alignPanel.adjustAnnotationHeight();
3573 Hashtable skipList = null;
3576 * TODO remove this method
3579 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
3580 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
3581 * throw new Error("Implementation Error. No skipList defined for this
3582 * Jalview2XML instance."); } return (AlignFrame)
3583 * skipList.get(view.getSequenceSetId()); }
3587 * Check if the Jalview view contained in object should be skipped or not.
3590 * @return true if view's sequenceSetId is a key in skipList
3592 private boolean skipViewport(JalviewModel object)
3594 if (skipList == null)
3599 if (skipList.containsKey(id = object.getJalviewModelSequence()
3600 .getViewport()[0].getSequenceSetId()))
3602 if (Cache.log != null && Cache.log.isDebugEnabled())
3604 Cache.log.debug("Skipping seuqence set id " + id);
3611 public void AddToSkipList(AlignFrame af)
3613 if (skipList == null)
3615 skipList = new Hashtable();
3617 skipList.put(af.getViewport().getSequenceSetId(), af);
3620 public void clearSkipList()
3622 if (skipList != null)
3629 private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al)
3631 jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId());
3632 Vector dseqs = null;
3635 // create a list of new dataset sequences
3636 dseqs = new Vector();
3638 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
3640 Sequence vamsasSeq = vamsasSet.getSequence(i);
3641 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs);
3643 // create a new dataset
3646 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
3647 dseqs.copyInto(dsseqs);
3648 ds = new jalview.datamodel.Alignment(dsseqs);
3649 debug("Created new dataset " + vamsasSet.getDatasetId()
3650 + " for alignment " + System.identityHashCode(al));
3651 addDatasetRef(vamsasSet.getDatasetId(), ds);
3653 // set the dataset for the newly imported alignment.
3654 if (al.getDataset() == null)
3663 * sequence definition to create/merge dataset sequence for
3667 * vector to add new dataset sequence to
3669 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
3670 AlignmentI ds, Vector dseqs)
3672 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
3674 jalview.datamodel.Sequence sq = (jalview.datamodel.Sequence) seqRefIds
3675 .get(vamsasSeq.getId());
3676 jalview.datamodel.SequenceI dsq = null;
3677 if (sq != null && sq.getDatasetSequence() != null)
3679 dsq = sq.getDatasetSequence();
3682 String sqid = vamsasSeq.getDsseqid();
3685 // need to create or add a new dataset sequence reference to this sequence
3688 dsq = (jalview.datamodel.SequenceI) seqRefIds.get(sqid);
3693 // make a new dataset sequence
3694 dsq = sq.createDatasetSequence();
3697 // make up a new dataset reference for this sequence
3698 sqid = seqHash(dsq);
3700 dsq.setVamsasId(uniqueSetSuffix + sqid);
3701 seqRefIds.put(sqid, dsq);
3706 dseqs.addElement(dsq);
3711 ds.addSequence(dsq);
3717 { // make this dataset sequence sq's dataset sequence
3718 sq.setDatasetSequence(dsq);
3722 // TODO: refactor this as a merge dataset sequence function
3723 // now check that sq (the dataset sequence) sequence really is the union of
3724 // all references to it
3725 // boolean pre = sq.getStart() < dsq.getStart();
3726 // boolean post = sq.getEnd() > dsq.getEnd();
3730 StringBuffer sb = new StringBuffer();
3731 String newres = jalview.analysis.AlignSeq.extractGaps(
3732 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
3733 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
3734 && newres.length() > dsq.getLength())
3736 // Update with the longer sequence.
3740 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
3741 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
3742 * sb.append(newres.substring(newres.length() - sq.getEnd() -
3743 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
3745 dsq.setSequence(sb.toString());
3747 // TODO: merges will never happen if we 'know' we have the real dataset
3748 // sequence - this should be detected when id==dssid
3749 System.err.println("DEBUG Notice: Merged dataset sequence"); // ("
3750 // + (pre ? "prepended" : "") + " "
3751 // + (post ? "appended" : ""));
3756 java.util.Hashtable datasetIds = null;
3758 java.util.IdentityHashMap dataset2Ids = null;
3760 private Alignment getDatasetFor(String datasetId)
3762 if (datasetIds == null)
3764 datasetIds = new Hashtable();
3767 if (datasetIds.containsKey(datasetId))
3769 return (Alignment) datasetIds.get(datasetId);
3774 private void addDatasetRef(String datasetId, Alignment dataset)
3776 if (datasetIds == null)
3778 datasetIds = new Hashtable();
3780 datasetIds.put(datasetId, dataset);
3784 * make a new dataset ID for this jalview dataset alignment
3789 private String getDatasetIdRef(jalview.datamodel.Alignment dataset)
3791 if (dataset.getDataset() != null)
3793 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
3795 String datasetId = makeHashCode(dataset, null);
3796 if (datasetId == null)
3798 // make a new datasetId and record it
3799 if (dataset2Ids == null)
3801 dataset2Ids = new IdentityHashMap();
3805 datasetId = (String) dataset2Ids.get(dataset);
3807 if (datasetId == null)
3809 datasetId = "ds" + dataset2Ids.size() + 1;
3810 dataset2Ids.put(dataset, datasetId);
3816 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
3818 for (int d = 0; d < sequence.getDBRefCount(); d++)
3820 DBRef dr = sequence.getDBRef(d);
3821 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
3822 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
3823 .getVersion(), sequence.getDBRef(d).getAccessionId());
3824 if (dr.getMapping() != null)
3826 entry.setMap(addMapping(dr.getMapping()));
3828 datasetSequence.addDBRef(entry);
3832 private jalview.datamodel.Mapping addMapping(Mapping m)
3834 SequenceI dsto = null;
3835 // Mapping m = dr.getMapping();
3836 int fr[] = new int[m.getMapListFromCount() * 2];
3837 Enumeration f = m.enumerateMapListFrom();
3838 for (int _i = 0; f.hasMoreElements(); _i += 2)
3840 MapListFrom mf = (MapListFrom) f.nextElement();
3841 fr[_i] = mf.getStart();
3842 fr[_i + 1] = mf.getEnd();
3844 int fto[] = new int[m.getMapListToCount() * 2];
3845 f = m.enumerateMapListTo();
3846 for (int _i = 0; f.hasMoreElements(); _i += 2)
3848 MapListTo mf = (MapListTo) f.nextElement();
3849 fto[_i] = mf.getStart();
3850 fto[_i + 1] = mf.getEnd();
3852 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
3853 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
3854 if (m.getMappingChoice() != null)
3856 MappingChoice mc = m.getMappingChoice();
3857 if (mc.getDseqFor() != null)
3859 String dsfor = "" + mc.getDseqFor();
3860 if (seqRefIds.containsKey(dsfor))
3865 jmap.setTo((SequenceI) seqRefIds.get(dsfor));
3869 frefedSequence.add(new Object[]
3876 * local sequence definition
3878 Sequence ms = mc.getSequence();
3879 jalview.datamodel.Sequence djs = null;
3880 String sqid = ms.getDsseqid();
3881 if (sqid != null && sqid.length() > 0)
3884 * recover dataset sequence
3886 djs = (jalview.datamodel.Sequence) seqRefIds.get(sqid);
3891 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
3892 sqid = ((Object) ms).toString(); // make up a new hascode for
3893 // undefined dataset sequence hash
3894 // (unlikely to happen)
3900 * make a new dataset sequence and add it to refIds hash
3902 djs = new jalview.datamodel.Sequence(ms.getName(),
3904 djs.setStart(jmap.getMap().getToLowest());
3905 djs.setEnd(jmap.getMap().getToHighest());
3906 djs.setVamsasId(uniqueSetSuffix + sqid);
3908 seqRefIds.put(sqid, djs);
3911 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
3920 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
3921 boolean keepSeqRefs)
3924 jalview.schemabinding.version2.JalviewModel jm = SaveState(ap, null,
3930 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
3934 uniqueSetSuffix = "";
3935 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
3940 if (this.frefedSequence == null)
3942 frefedSequence = new Vector();
3945 viewportsAdded = new Hashtable();
3947 AlignFrame af = LoadFromObject(jm, null, false, null);
3948 af.alignPanels.clear();
3949 af.closeMenuItem_actionPerformed(true);
3952 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
3953 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
3954 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
3955 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
3956 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
3959 return af.alignPanel;
3963 * flag indicating if hashtables should be cleared on finalization TODO this
3964 * flag may not be necessary
3966 private final boolean _cleartables = true;
3968 private Hashtable jvids2vobj;
3973 * @see java.lang.Object#finalize()
3976 protected void finalize() throws Throwable
3978 // really make sure we have no buried refs left.
3983 this.seqRefIds = null;
3984 this.seqsToIds = null;
3988 private void warn(String msg)
3993 private void warn(String msg, Exception e)
3995 if (Cache.log != null)
3999 Cache.log.warn(msg, e);
4003 Cache.log.warn(msg);
4008 System.err.println("Warning: " + msg);
4011 e.printStackTrace();
4016 private void debug(String string)
4018 debug(string, null);
4021 private void debug(String msg, Exception e)
4023 if (Cache.log != null)
4027 Cache.log.debug(msg, e);
4031 Cache.log.debug(msg);
4036 System.err.println("Warning: " + msg);
4039 e.printStackTrace();
4045 * set the object to ID mapping tables used to write/recover objects and XML
4046 * ID strings for the jalview project. If external tables are provided then
4047 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
4048 * object goes out of scope. - also populates the datasetIds hashtable with
4049 * alignment objects containing dataset sequences
4052 * Map from ID strings to jalview datamodel
4054 * Map from jalview datamodel to ID strings
4058 public void setObjectMappingTables(Hashtable vobj2jv,
4059 IdentityHashMap jv2vobj)
4061 this.jv2vobj = jv2vobj;
4062 this.vobj2jv = vobj2jv;
4063 Iterator ds = jv2vobj.keySet().iterator();
4065 while (ds.hasNext())
4067 Object jvobj = ds.next();
4068 id = jv2vobj.get(jvobj).toString();
4069 if (jvobj instanceof jalview.datamodel.Alignment)
4071 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
4073 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
4076 else if (jvobj instanceof jalview.datamodel.Sequence)
4078 // register sequence object so the XML parser can recover it.
4079 if (seqRefIds == null)
4081 seqRefIds = new Hashtable();
4083 if (seqsToIds == null)
4085 seqsToIds = new IdentityHashMap();
4087 seqRefIds.put(jv2vobj.get(jvobj).toString(), jvobj);
4088 seqsToIds.put(jvobj, id);
4090 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
4092 if (annotationIds == null)
4094 annotationIds = new Hashtable();
4097 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvobj);
4098 jalview.datamodel.AlignmentAnnotation jvann = (jalview.datamodel.AlignmentAnnotation) jvobj;
4099 if (jvann.annotationId == null)
4101 jvann.annotationId = anid;
4103 if (!jvann.annotationId.equals(anid))
4105 // TODO verify that this is the correct behaviour
4106 this.warn("Overriding Annotation ID for " + anid
4107 + " from different id : " + jvann.annotationId);
4108 jvann.annotationId = anid;
4111 else if (jvobj instanceof String)
4113 if (jvids2vobj == null)
4115 jvids2vobj = new Hashtable();
4116 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
4120 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
4125 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
4126 * objects created from the project archive. If string is null (default for
4127 * construction) then suffix will be set automatically.
4131 public void setUniqueSetSuffix(String string)
4133 uniqueSetSuffix = string;
4138 * uses skipList2 as the skipList for skipping views on sequence sets
4139 * associated with keys in the skipList
4143 public void setSkipList(Hashtable skipList2)
4145 skipList = skipList2;