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.getDefault("VERSION","Development Build"));
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 ac.setPerSequence(acg.isSeqAssociated());
1074 ac.setPredefinedColours(acg.isPredefinedColours());
1075 view.setAnnotationColours(ac);
1076 view.setBgColour("AnnotationColourGradient");
1080 view.setBgColour(ColourSchemeProperty.getColourName(av
1081 .getGlobalColourScheme()));
1084 ColourSchemeI cs = av.getGlobalColourScheme();
1088 if (cs.conservationApplied())
1090 view.setConsThreshold(cs.getConservationInc());
1091 if (cs instanceof jalview.schemes.UserColourScheme)
1093 view.setBgColour(SetUserColourScheme(cs, userColours, jms));
1097 if (cs instanceof ResidueColourScheme)
1099 view.setPidThreshold(cs.getThreshold());
1103 view.setConservationSelected(av.getConservationSelected());
1104 view.setPidSelected(av.getAbovePIDThreshold());
1105 view.setFontName(av.font.getName());
1106 view.setFontSize(av.font.getSize());
1107 view.setFontStyle(av.font.getStyle());
1108 view.setRenderGaps(av.renderGaps);
1109 view.setShowAnnotation(av.getShowAnnotation());
1110 view.setShowBoxes(av.getShowBoxes());
1111 view.setShowColourText(av.getColourText());
1112 view.setShowFullId(av.getShowJVSuffix());
1113 view.setRightAlignIds(av.rightAlignIds);
1114 view.setShowSequenceFeatures(av.showSequenceFeatures);
1115 view.setShowText(av.getShowText());
1116 view.setShowUnconserved(av.getShowUnconserved());
1117 view.setWrapAlignment(av.getWrapAlignment());
1118 view.setTextCol1(av.textColour.getRGB());
1119 view.setTextCol2(av.textColour2.getRGB());
1120 view.setTextColThreshold(av.thresholdTextColour);
1121 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1122 view.setShowSequenceLogo(av.isShowSequenceLogo());
1123 view.setNormaliseSequenceLogo(av.isNormaliseSequenceLogo());
1124 view.setShowGroupConsensus(av.isShowGroupConsensus());
1125 view.setShowGroupConservation(av.isShowGroupConservation());
1126 view.setShowNPfeatureTooltip(av.isShowNpFeats());
1127 view.setShowDbRefTooltip(av.isShowDbRefs());
1128 view.setFollowHighlight(av.followHighlight);
1129 view.setFollowSelection(av.followSelection);
1130 view.setIgnoreGapsinConsensus(av.getIgnoreGapsConsensus());
1131 if (av.featuresDisplayed != null)
1133 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1135 String[] renderOrder = ap.seqPanel.seqCanvas.getFeatureRenderer().renderOrder;
1137 Vector settingsAdded = new Vector();
1138 Object gstyle = null;
1139 GraduatedColor gcol = null;
1140 if (renderOrder != null)
1142 for (int ro = 0; ro < renderOrder.length; ro++)
1144 gstyle = ap.seqPanel.seqCanvas.getFeatureRenderer()
1145 .getFeatureStyle(renderOrder[ro]);
1146 Setting setting = new Setting();
1147 setting.setType(renderOrder[ro]);
1148 if (gstyle instanceof GraduatedColor)
1150 gcol = (GraduatedColor) gstyle;
1151 setting.setColour(gcol.getMaxColor().getRGB());
1152 setting.setMincolour(gcol.getMinColor().getRGB());
1153 setting.setMin(gcol.getMin());
1154 setting.setMax(gcol.getMax());
1155 setting.setColourByLabel(gcol.isColourByLabel());
1156 setting.setAutoScale(gcol.isAutoScale());
1157 setting.setThreshold(gcol.getThresh());
1158 setting.setThreshstate(gcol.getThreshType());
1162 setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer()
1163 .getColour(renderOrder[ro]).getRGB());
1166 setting.setDisplay(av.featuresDisplayed
1167 .containsKey(renderOrder[ro]));
1168 float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer()
1169 .getOrder(renderOrder[ro]);
1172 setting.setOrder(rorder);
1174 fs.addSetting(setting);
1175 settingsAdded.addElement(renderOrder[ro]);
1179 // Make sure we save none displayed feature settings
1180 Iterator en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureColours
1181 .keySet().iterator();
1182 while (en.hasNext())
1184 String key = en.next().toString();
1185 if (settingsAdded.contains(key))
1190 Setting setting = new Setting();
1191 setting.setType(key);
1192 setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer()
1193 .getColour(key).getRGB());
1195 setting.setDisplay(false);
1196 float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer().getOrder(
1200 setting.setOrder(rorder);
1202 fs.addSetting(setting);
1203 settingsAdded.addElement(key);
1205 en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups
1206 .keySet().iterator();
1207 Vector groupsAdded = new Vector();
1208 while (en.hasNext())
1210 String grp = en.next().toString();
1211 if (groupsAdded.contains(grp))
1215 Group g = new Group();
1217 g.setDisplay(((Boolean) ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups
1218 .get(grp)).booleanValue());
1220 groupsAdded.addElement(grp);
1222 jms.setFeatureSettings(fs);
1226 if (av.hasHiddenColumns())
1228 if (av.getColumnSelection() == null
1229 || av.getColumnSelection().getHiddenColumns() == null)
1231 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1235 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1238 int[] region = (int[]) av.getColumnSelection().getHiddenColumns()
1240 HiddenColumns hc = new HiddenColumns();
1241 hc.setStart(region[0]);
1242 hc.setEnd(region[1]);
1243 view.addHiddenColumns(hc);
1247 if (calcIdSet.size() > 0)
1249 for (String calcId : calcIdSet)
1251 if (calcId.trim().length() > 0)
1253 CalcIdParam cidp = createCalcIdParam(calcId, av);
1254 // Some calcIds have no parameters.
1257 view.addCalcIdParam(cidp);
1263 jms.addViewport(view);
1265 object.setJalviewModelSequence(jms);
1266 object.getVamsasModel().addSequenceSet(vamsasSet);
1268 if (jout != null && fileName != null)
1270 // We may not want to write the object to disk,
1271 // eg we can copy the alignViewport to a new view object
1272 // using save and then load
1275 JarEntry entry = new JarEntry(fileName);
1276 jout.putNextEntry(entry);
1277 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1279 org.exolab.castor.xml.Marshaller marshaller = new org.exolab.castor.xml.Marshaller(
1281 marshaller.marshal(object);
1284 } catch (Exception ex)
1286 // TODO: raise error in GUI if marshalling failed.
1287 ex.printStackTrace();
1293 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1295 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1296 if (settings != null)
1298 CalcIdParam vCalcIdParam = new CalcIdParam();
1299 vCalcIdParam.setCalcId(calcId);
1300 vCalcIdParam.addServiceURL(settings.getServiceURI());
1301 // generic URI allowing a third party to resolve another instance of the
1302 // service used for this calculation
1303 for (String urls : settings.getServiceURLs())
1305 vCalcIdParam.addServiceURL(urls);
1307 vCalcIdParam.setVersion("1.0");
1308 if (settings.getPreset() != null)
1310 WsParamSetI setting = settings.getPreset();
1311 vCalcIdParam.setName(setting.getName());
1312 vCalcIdParam.setDescription(setting.getDescription());
1316 vCalcIdParam.setName("");
1317 vCalcIdParam.setDescription("Last used parameters");
1319 // need to be able to recover 1) settings 2) user-defined presets or
1320 // recreate settings from preset 3) predefined settings provided by
1321 // service - or settings that can be transferred (or discarded)
1322 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1324 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1325 // todo - decide if updateImmediately is needed for any projects.
1327 return vCalcIdParam;
1332 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1335 if (calcIdParam.getVersion().equals("1.0"))
1337 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1338 .getPreferredServiceFor(calcIdParam.getServiceURL());
1339 if (service != null)
1341 WsParamSetI parmSet = null;
1344 parmSet = service.getParamStore().parseServiceParameterFile(
1345 calcIdParam.getName(), calcIdParam.getDescription(),
1346 calcIdParam.getServiceURL(),
1347 calcIdParam.getParameters().replace("|\\n|", "\n"));
1348 } catch (IOException x)
1350 warn("Couldn't parse parameter data for "
1351 + calcIdParam.getCalcId(), x);
1354 List<ArgumentI> argList = null;
1355 if (calcIdParam.getName().length() > 0)
1357 parmSet = service.getParamStore()
1358 .getPreset(calcIdParam.getName());
1359 if (parmSet != null)
1361 // TODO : check we have a good match with settings in AACon -
1362 // otherwise we'll need to create a new preset
1367 argList = parmSet.getArguments();
1370 AAConSettings settings = new AAConSettings(
1371 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1372 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1373 calcIdParam.isNeedsUpdate());
1378 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1382 throw new Error("Unsupported Version for calcIdparam "
1383 + calcIdParam.toString());
1387 * External mapping between jalview objects and objects yielding a valid and
1388 * unique object ID string. This is null for normal Jalview project IO, but
1389 * non-null when a jalview project is being read or written as part of a
1392 IdentityHashMap jv2vobj = null;
1395 * Construct a unique ID for jvobj using either existing bindings or if none
1396 * exist, the result of the hashcode call for the object.
1399 * jalview data object
1400 * @return unique ID for referring to jvobj
1402 private String makeHashCode(Object jvobj, String altCode)
1404 if (jv2vobj != null)
1406 Object id = jv2vobj.get(jvobj);
1409 return id.toString();
1411 // check string ID mappings
1412 if (jvids2vobj != null && jvobj instanceof String)
1414 id = jvids2vobj.get(jvobj);
1418 return id.toString();
1420 // give up and warn that something has gone wrong
1421 warn("Cannot find ID for object in external mapping : " + jvobj);
1427 * return local jalview object mapped to ID, if it exists
1431 * @return null or object bound to idcode
1433 private Object retrieveExistingObj(String idcode)
1435 if (idcode != null && vobj2jv != null)
1437 return vobj2jv.get(idcode);
1443 * binding from ID strings from external mapping table to jalview data model
1446 private Hashtable vobj2jv;
1448 private Sequence createVamsasSequence(String id, SequenceI jds)
1450 return createVamsasSequence(true, id, jds, null);
1453 private Sequence createVamsasSequence(boolean recurse, String id,
1454 SequenceI jds, SequenceI parentseq)
1456 Sequence vamsasSeq = new Sequence();
1457 vamsasSeq.setId(id);
1458 vamsasSeq.setName(jds.getName());
1459 vamsasSeq.setSequence(jds.getSequenceAsString());
1460 vamsasSeq.setDescription(jds.getDescription());
1461 jalview.datamodel.DBRefEntry[] dbrefs = null;
1462 if (jds.getDatasetSequence() != null)
1464 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
1465 if (jds.getDatasetSequence().getDBRef() != null)
1467 dbrefs = jds.getDatasetSequence().getDBRef();
1472 vamsasSeq.setDsseqid(id); // so we can tell which sequences really are
1473 // dataset sequences only
1474 dbrefs = jds.getDBRef();
1478 for (int d = 0; d < dbrefs.length; d++)
1480 DBRef dbref = new DBRef();
1481 dbref.setSource(dbrefs[d].getSource());
1482 dbref.setVersion(dbrefs[d].getVersion());
1483 dbref.setAccessionId(dbrefs[d].getAccessionId());
1484 if (dbrefs[d].hasMap())
1486 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
1488 dbref.setMapping(mp);
1490 vamsasSeq.addDBRef(dbref);
1496 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
1497 SequenceI parentseq, SequenceI jds, boolean recurse)
1500 if (jmp.getMap() != null)
1504 jalview.util.MapList mlst = jmp.getMap();
1505 int r[] = mlst.getFromRanges();
1506 for (int s = 0; s < r.length; s += 2)
1508 MapListFrom mfrom = new MapListFrom();
1509 mfrom.setStart(r[s]);
1510 mfrom.setEnd(r[s + 1]);
1511 mp.addMapListFrom(mfrom);
1513 r = mlst.getToRanges();
1514 for (int s = 0; s < r.length; s += 2)
1516 MapListTo mto = new MapListTo();
1518 mto.setEnd(r[s + 1]);
1519 mp.addMapListTo(mto);
1521 mp.setMapFromUnit(mlst.getFromRatio());
1522 mp.setMapToUnit(mlst.getToRatio());
1523 if (jmp.getTo() != null)
1525 MappingChoice mpc = new MappingChoice();
1527 && (parentseq != jmp.getTo() || parentseq
1528 .getDatasetSequence() != jmp.getTo()))
1530 mpc.setSequence(createVamsasSequence(false, seqHash(jmp.getTo()),
1536 SequenceI ps = null;
1537 if (parentseq != jmp.getTo()
1538 && parentseq.getDatasetSequence() != jmp.getTo())
1540 // chaining dbref rather than a handshaking one
1541 jmpid = seqHash(ps = jmp.getTo());
1545 jmpid = seqHash(ps = parentseq);
1547 mpc.setDseqFor(jmpid);
1548 if (!seqRefIds.containsKey(mpc.getDseqFor()))
1550 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
1551 seqRefIds.put(mpc.getDseqFor(), ps);
1555 jalview.bin.Cache.log.debug("reusing DseqFor ID");
1558 mp.setMappingChoice(mpc);
1564 String SetUserColourScheme(jalview.schemes.ColourSchemeI cs,
1565 Vector userColours, JalviewModelSequence jms)
1568 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
1569 boolean newucs = false;
1570 if (!userColours.contains(ucs))
1572 userColours.add(ucs);
1575 id = "ucs" + userColours.indexOf(ucs);
1578 // actually create the scheme's entry in the XML model
1579 java.awt.Color[] colours = ucs.getColours();
1580 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
1581 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
1583 for (int i = 0; i < colours.length; i++)
1585 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1586 col.setName(ResidueProperties.aa[i]);
1587 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1588 jbucs.addColour(col);
1590 if (ucs.getLowerCaseColours() != null)
1592 colours = ucs.getLowerCaseColours();
1593 for (int i = 0; i < colours.length; i++)
1595 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1596 col.setName(ResidueProperties.aa[i].toLowerCase());
1597 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1598 jbucs.addColour(col);
1603 uc.setUserColourScheme(jbucs);
1604 jms.addUserColours(uc);
1610 jalview.schemes.UserColourScheme GetUserColourScheme(
1611 JalviewModelSequence jms, String id)
1613 UserColours[] uc = jms.getUserColours();
1614 UserColours colours = null;
1616 for (int i = 0; i < uc.length; i++)
1618 if (uc[i].getId().equals(id))
1626 java.awt.Color[] newColours = new java.awt.Color[24];
1628 for (int i = 0; i < 24; i++)
1630 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1631 .getUserColourScheme().getColour(i).getRGB(), 16));
1634 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
1637 if (colours.getUserColourScheme().getColourCount() > 24)
1639 newColours = new java.awt.Color[23];
1640 for (int i = 0; i < 23; i++)
1642 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1643 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
1645 ucs.setLowerCaseColours(newColours);
1652 * contains last error message (if any) encountered by XML loader.
1654 String errorMessage = null;
1657 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
1658 * exceptions are raised during project XML parsing
1660 public boolean attemptversion1parse = true;
1663 * Load a jalview project archive from a jar file
1666 * - HTTP URL or filename
1668 public AlignFrame LoadJalviewAlign(final String file)
1671 jalview.gui.AlignFrame af = null;
1675 // create list to store references for any new Jmol viewers created
1676 newStructureViewers=new Vector<AppJmol>();
1677 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
1678 // Workaround is to make sure caller implements the JarInputStreamProvider
1680 // so we can re-open the jar input stream for each entry.
1682 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
1683 af = LoadJalviewAlign(jprovider);
1685 } catch (MalformedURLException e)
1687 errorMessage = "Invalid URL format for '" + file + "'";
1693 SwingUtilities.invokeAndWait(new Runnable()
1697 setLoadingFinishedForNewStructureViewers();
1700 } catch (Exception x)
1708 private jarInputStreamProvider createjarInputStreamProvider(
1709 final String file) throws MalformedURLException
1712 errorMessage = null;
1713 uniqueSetSuffix = null;
1715 viewportsAdded = null;
1716 frefedSequence = null;
1718 if (file.startsWith("http://"))
1720 url = new URL(file);
1722 final URL _url = url;
1723 return new jarInputStreamProvider()
1727 public JarInputStream getJarInputStream() throws IOException
1731 return new JarInputStream(_url.openStream());
1735 return new JarInputStream(new FileInputStream(file));
1740 public String getFilename()
1748 * Recover jalview session from a jalview project archive. Caller may
1749 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
1750 * themselves. Any null fields will be initialised with default values,
1751 * non-null fields are left alone.
1756 public AlignFrame LoadJalviewAlign(final jarInputStreamProvider jprovider)
1758 errorMessage = null;
1759 if (uniqueSetSuffix == null)
1761 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
1763 if (seqRefIds == null)
1765 seqRefIds = new Hashtable();
1767 if (viewportsAdded == null)
1769 viewportsAdded = new Hashtable();
1771 if (frefedSequence == null)
1773 frefedSequence = new Vector();
1776 jalview.gui.AlignFrame af = null;
1777 Hashtable gatherToThisFrame = new Hashtable();
1778 final String file = jprovider.getFilename();
1781 JarInputStream jin = null;
1782 JarEntry jarentry = null;
1787 jin = jprovider.getJarInputStream();
1788 for (int i = 0; i < entryCount; i++)
1790 jarentry = jin.getNextJarEntry();
1793 if (jarentry != null && jarentry.getName().endsWith(".xml"))
1795 InputStreamReader in = new InputStreamReader(jin, "UTF-8");
1796 JalviewModel object = new JalviewModel();
1798 Unmarshaller unmar = new Unmarshaller(object);
1799 unmar.setValidation(false);
1800 object = (JalviewModel) unmar.unmarshal(in);
1801 if (true) // !skipViewport(object))
1803 af = LoadFromObject(object, file, true, jprovider);
1804 if (af.viewport.gatherViewsHere)
1806 gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
1811 else if (jarentry != null)
1813 // Some other file here.
1816 } while (jarentry != null);
1817 resolveFrefedSequences();
1818 } catch (java.io.FileNotFoundException ex)
1820 ex.printStackTrace();
1821 errorMessage = "Couldn't locate Jalview XML file : " + file;
1822 System.err.println("Exception whilst loading jalview XML file : "
1824 } catch (java.net.UnknownHostException ex)
1826 ex.printStackTrace();
1827 errorMessage = "Couldn't locate Jalview XML file : " + file;
1828 System.err.println("Exception whilst loading jalview XML file : "
1830 } catch (Exception ex)
1832 System.err.println("Parsing as Jalview Version 2 file failed.");
1833 ex.printStackTrace(System.err);
1834 if (attemptversion1parse)
1836 // Is Version 1 Jar file?
1839 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
1840 } catch (Exception ex2)
1842 System.err.println("Exception whilst loading as jalviewXMLV1:");
1843 ex2.printStackTrace();
1847 if (Desktop.instance != null)
1849 Desktop.instance.stopLoading();
1853 System.out.println("Successfully loaded archive file");
1856 ex.printStackTrace();
1858 System.err.println("Exception whilst loading jalview XML file : "
1860 } catch (OutOfMemoryError e)
1862 // Don't use the OOM Window here
1863 errorMessage = "Out of memory loading jalview XML file";
1864 System.err.println("Out of memory whilst loading jalview XML file");
1865 e.printStackTrace();
1868 if (Desktop.instance != null)
1870 Desktop.instance.stopLoading();
1873 Enumeration en = gatherToThisFrame.elements();
1874 while (en.hasMoreElements())
1876 Desktop.instance.gatherViews((AlignFrame) en.nextElement());
1878 if (errorMessage != null)
1886 * check errorMessage for a valid error message and raise an error box in the
1887 * GUI or write the current errorMessage to stderr and then clear the error
1890 protected void reportErrors()
1892 reportErrors(false);
1895 protected void reportErrors(final boolean saving)
1897 if (errorMessage != null)
1899 final String finalErrorMessage = errorMessage;
1902 javax.swing.SwingUtilities.invokeLater(new Runnable()
1907 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1908 finalErrorMessage, "Error "
1909 + (saving ? "saving" : "loading")
1910 + " Jalview file", JOptionPane.WARNING_MESSAGE);
1916 System.err.println("Problem loading Jalview file: " + errorMessage);
1919 errorMessage = null;
1922 Hashtable alreadyLoadedPDB;
1925 * when set, local views will be updated from view stored in JalviewXML
1926 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
1927 * sync if this is set to true.
1929 private final boolean updateLocalViews = false;
1931 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
1933 if (alreadyLoadedPDB == null)
1934 alreadyLoadedPDB = new Hashtable();
1936 if (alreadyLoadedPDB.containsKey(pdbId))
1937 return alreadyLoadedPDB.get(pdbId).toString();
1941 JarInputStream jin = jprovider.getJarInputStream();
1943 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
1944 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
1945 * FileInputStream(jprovider)); }
1948 JarEntry entry = null;
1951 entry = jin.getNextJarEntry();
1952 } while (entry != null && !entry.getName().equals(pdbId));
1955 BufferedReader in = new BufferedReader(new InputStreamReader(jin));
1956 File outFile = File.createTempFile("jalview_pdb", ".txt");
1957 outFile.deleteOnExit();
1958 PrintWriter out = new PrintWriter(new FileOutputStream(outFile));
1961 while ((data = in.readLine()) != null)
1968 } catch (Exception foo)
1973 String t = outFile.getAbsolutePath();
1974 alreadyLoadedPDB.put(pdbId, t);
1979 warn("Couldn't find PDB file entry in Jalview Jar for " + pdbId);
1981 } catch (Exception ex)
1983 ex.printStackTrace();
1989 private class JvAnnotRow
1991 public JvAnnotRow(int i, AlignmentAnnotation jaa)
1998 * persisted version of annotation row from which to take vis properties
2000 public jalview.datamodel.AlignmentAnnotation template;
2003 * original position of the annotation row in the alignment
2009 * Load alignment frame from jalview XML DOM object
2014 * filename source string
2015 * @param loadTreesAndStructures
2016 * when false only create Viewport
2018 * data source provider
2019 * @return alignment frame created from view stored in DOM
2021 AlignFrame LoadFromObject(JalviewModel object, String file,
2022 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2024 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2025 Sequence[] vamsasSeq = vamsasSet.getSequence();
2027 JalviewModelSequence jms = object.getJalviewModelSequence();
2029 Viewport view = jms.getViewport(0);
2030 // ////////////////////////////////
2033 Vector hiddenSeqs = null;
2034 jalview.datamodel.Sequence jseq;
2036 ArrayList tmpseqs = new ArrayList();
2038 boolean multipleView = false;
2040 JSeq[] JSEQ = object.getJalviewModelSequence().getJSeq();
2041 int vi = 0; // counter in vamsasSeq array
2042 for (int i = 0; i < JSEQ.length; i++)
2044 String seqId = JSEQ[i].getId();
2046 if (seqRefIds.get(seqId) != null)
2048 tmpseqs.add(seqRefIds.get(seqId));
2049 multipleView = true;
2053 jseq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2054 vamsasSeq[vi].getSequence());
2055 jseq.setDescription(vamsasSeq[vi].getDescription());
2056 jseq.setStart(JSEQ[i].getStart());
2057 jseq.setEnd(JSEQ[i].getEnd());
2058 jseq.setVamsasId(uniqueSetSuffix + seqId);
2059 seqRefIds.put(vamsasSeq[vi].getId(), jseq);
2064 if (JSEQ[i].getHidden())
2066 if (hiddenSeqs == null)
2068 hiddenSeqs = new Vector();
2071 hiddenSeqs.addElement(seqRefIds.get(seqId));
2077 // Create the alignment object from the sequence set
2078 // ///////////////////////////////
2079 jalview.datamodel.Sequence[] orderedSeqs = new jalview.datamodel.Sequence[tmpseqs
2082 tmpseqs.toArray(orderedSeqs);
2084 jalview.datamodel.Alignment al = new jalview.datamodel.Alignment(
2087 // / Add the alignment properties
2088 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2090 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2091 al.setProperty(ssp.getKey(), ssp.getValue());
2095 // SequenceFeatures are added to the DatasetSequence,
2096 // so we must create or recover the dataset before loading features
2097 // ///////////////////////////////
2098 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2100 // older jalview projects do not have a dataset id.
2101 al.setDataset(null);
2105 recoverDatasetFor(vamsasSet, al);
2107 // ///////////////////////////////
2109 Hashtable pdbloaded = new Hashtable();
2112 // load sequence features, database references and any associated PDB
2113 // structures for the alignment
2114 for (int i = 0; i < vamsasSeq.length; i++)
2116 if (JSEQ[i].getFeaturesCount() > 0)
2118 Features[] features = JSEQ[i].getFeatures();
2119 for (int f = 0; f < features.length; f++)
2121 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2122 features[f].getType(), features[f].getDescription(),
2123 features[f].getStatus(), features[f].getBegin(),
2124 features[f].getEnd(), features[f].getFeatureGroup());
2126 sf.setScore(features[f].getScore());
2127 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2129 OtherData keyValue = features[f].getOtherData(od);
2130 if (keyValue.getKey().startsWith("LINK"))
2132 sf.addLink(keyValue.getValue());
2136 sf.setValue(keyValue.getKey(), keyValue.getValue());
2141 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
2144 if (vamsasSeq[i].getDBRefCount() > 0)
2146 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2148 if (JSEQ[i].getPdbidsCount() > 0)
2150 Pdbids[] ids = JSEQ[i].getPdbids();
2151 for (int p = 0; p < ids.length; p++)
2153 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2154 entry.setId(ids[p].getId());
2155 entry.setType(ids[p].getType());
2156 if (ids[p].getFile() != null)
2158 if (!pdbloaded.containsKey(ids[p].getFile()))
2160 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2164 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2168 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2172 } // end !multipleview
2174 // ///////////////////////////////
2175 // LOAD SEQUENCE MAPPINGS
2177 if (vamsasSet.getAlcodonFrameCount() > 0)
2179 // TODO Potentially this should only be done once for all views of an
2181 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2182 for (int i = 0; i < alc.length; i++)
2184 jalview.datamodel.AlignedCodonFrame cf = new jalview.datamodel.AlignedCodonFrame(
2185 alc[i].getAlcodonCount());
2186 if (alc[i].getAlcodonCount() > 0)
2188 Alcodon[] alcods = alc[i].getAlcodon();
2189 for (int p = 0; p < cf.codons.length; p++)
2191 if (alcods[p].hasPos1() && alcods[p].hasPos2()
2192 && alcods[p].hasPos3())
2194 // translated codons require three valid positions
2195 cf.codons[p] = new int[3];
2196 cf.codons[p][0] = (int) alcods[p].getPos1();
2197 cf.codons[p][1] = (int) alcods[p].getPos2();
2198 cf.codons[p][2] = (int) alcods[p].getPos3();
2202 cf.codons[p] = null;
2206 if (alc[i].getAlcodMapCount() > 0)
2208 AlcodMap[] maps = alc[i].getAlcodMap();
2209 for (int m = 0; m < maps.length; m++)
2211 SequenceI dnaseq = (SequenceI) seqRefIds
2212 .get(maps[m].getDnasq());
2214 jalview.datamodel.Mapping mapping = null;
2215 // attach to dna sequence reference.
2216 if (maps[m].getMapping() != null)
2218 mapping = addMapping(maps[m].getMapping());
2222 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
2227 frefedSequence.add(new Object[]
2228 { maps[m].getDnasq(), cf, mapping });
2232 al.addCodonFrame(cf);
2237 // ////////////////////////////////
2239 ArrayList<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
2241 * store any annotations which forward reference a group's ID
2243 Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>>();
2245 if (vamsasSet.getAnnotationCount() > 0)
2247 Annotation[] an = vamsasSet.getAnnotation();
2249 for (int i = 0; i < an.length; i++)
2252 * test if annotation is automatically calculated for this view only
2254 boolean autoForView = false;
2255 if (an[i].getLabel().equals("Quality")
2256 || an[i].getLabel().equals("Conservation")
2257 || an[i].getLabel().equals("Consensus"))
2259 // Kludge for pre 2.5 projects which lacked the autocalculated flag
2261 if (!an[i].hasAutoCalculated())
2263 an[i].setAutoCalculated(true);
2267 || (an[i].hasAutoCalculated() && an[i].isAutoCalculated()))
2269 // remove ID - we don't recover annotation from other views for
2270 // view-specific annotation
2274 // set visiblity for other annotation in this view
2275 if (an[i].getId() != null
2276 && annotationIds.containsKey(an[i].getId()))
2278 jalview.datamodel.AlignmentAnnotation jda = (jalview.datamodel.AlignmentAnnotation) annotationIds
2279 .get(an[i].getId());
2280 // in principle Visible should always be true for annotation displayed
2281 // in multiple views
2282 if (an[i].hasVisible())
2283 jda.visible = an[i].getVisible();
2285 al.addAnnotation(jda);
2289 // Construct new annotation from model.
2290 AnnotationElement[] ae = an[i].getAnnotationElement();
2291 jalview.datamodel.Annotation[] anot = null;
2292 java.awt.Color firstColour = null;
2294 if (!an[i].getScoreOnly())
2296 anot = new jalview.datamodel.Annotation[al.getWidth()];
2297 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
2299 anpos = ae[aa].getPosition();
2301 if (anpos >= anot.length)
2304 anot[anpos] = new jalview.datamodel.Annotation(
2306 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
2307 (ae[aa].getSecondaryStructure() == null || ae[aa]
2308 .getSecondaryStructure().length() == 0) ? ' '
2309 : ae[aa].getSecondaryStructure().charAt(0),
2313 // JBPNote: Consider verifying dataflow for IO of secondary
2314 // structure annotation read from Stockholm files
2315 // this was added to try to ensure that
2316 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
2318 // anot[ae[aa].getPosition()].displayCharacter = "";
2320 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
2321 if (firstColour == null)
2323 firstColour = anot[anpos].colour;
2327 jalview.datamodel.AlignmentAnnotation jaa = null;
2329 if (an[i].getGraph())
2331 float llim = 0, hlim = 0;
2332 // if (autoForView || an[i].isAutoCalculated()) {
2335 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2336 an[i].getDescription(), anot, llim, hlim,
2337 an[i].getGraphType());
2339 jaa.graphGroup = an[i].getGraphGroup();
2340 jaa._linecolour = firstColour;
2341 if (an[i].getThresholdLine() != null)
2343 jaa.setThreshold(new jalview.datamodel.GraphLine(an[i]
2344 .getThresholdLine().getValue(), an[i]
2345 .getThresholdLine().getLabel(), new java.awt.Color(
2346 an[i].getThresholdLine().getColour())));
2349 if (autoForView || an[i].isAutoCalculated())
2351 // Hardwire the symbol display line to ensure that labels for
2352 // histograms are displayed
2358 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2359 an[i].getDescription(), anot);
2360 jaa._linecolour = firstColour;
2362 // register new annotation
2363 if (an[i].getId() != null)
2365 annotationIds.put(an[i].getId(), jaa);
2366 jaa.annotationId = an[i].getId();
2368 // recover sequence association
2369 if (an[i].getSequenceRef() != null)
2371 if (al.findName(an[i].getSequenceRef()) != null)
2373 jaa.createSequenceMapping(al.findName(an[i].getSequenceRef()),
2375 al.findName(an[i].getSequenceRef()).addAlignmentAnnotation(jaa);
2378 // and make a note of any group association
2379 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
2381 ArrayList<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
2382 .get(an[i].getGroupRef());
2385 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
2386 groupAnnotRefs.put(an[i].getGroupRef(), aal);
2391 if (an[i].hasScore())
2393 jaa.setScore(an[i].getScore());
2395 if (an[i].hasVisible())
2396 jaa.visible = an[i].getVisible();
2398 if (an[i].hasCentreColLabels())
2399 jaa.centreColLabels = an[i].getCentreColLabels();
2401 if (an[i].hasScaleColLabels())
2403 jaa.scaleColLabel = an[i].getScaleColLabels();
2405 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
2407 // newer files have an 'autoCalculated' flag and store calculation
2408 // state in viewport properties
2409 jaa.autoCalculated = true; // means annotation will be marked for
2410 // update at end of load.
2412 if (an[i].hasGraphHeight())
2414 jaa.graphHeight = an[i].getGraphHeight();
2416 if (an[i].hasBelowAlignment())
2418 jaa.belowAlignment = an[i].isBelowAlignment();
2420 jaa.setCalcId(an[i].getCalcId());
2422 if (jaa.autoCalculated)
2424 autoAlan.add(new JvAnnotRow(i, jaa));
2427 // if (!autoForView)
2429 // add autocalculated group annotation and any user created annotation
2431 al.addAnnotation(jaa);
2436 // ///////////////////////
2438 // Create alignment markup and styles for this view
2439 if (jms.getJGroupCount() > 0)
2441 JGroup[] groups = jms.getJGroup();
2443 for (int i = 0; i < groups.length; i++)
2445 ColourSchemeI cs = null;
2447 if (groups[i].getColour() != null)
2449 if (groups[i].getColour().startsWith("ucs"))
2451 cs = GetUserColourScheme(jms, groups[i].getColour());
2455 cs = ColourSchemeProperty.getColour(al, groups[i].getColour());
2460 cs.setThreshold(groups[i].getPidThreshold(), true);
2464 Vector seqs = new Vector();
2466 for (int s = 0; s < groups[i].getSeqCount(); s++)
2468 String seqId = groups[i].getSeq(s) + "";
2469 jalview.datamodel.SequenceI ts = (jalview.datamodel.SequenceI) seqRefIds
2474 seqs.addElement(ts);
2478 if (seqs.size() < 1)
2483 jalview.datamodel.SequenceGroup sg = new jalview.datamodel.SequenceGroup(
2484 seqs, groups[i].getName(), cs, groups[i].getDisplayBoxes(),
2485 groups[i].getDisplayText(), groups[i].getColourText(),
2486 groups[i].getStart(), groups[i].getEnd());
2488 sg.setOutlineColour(new java.awt.Color(groups[i].getOutlineColour()));
2490 sg.textColour = new java.awt.Color(groups[i].getTextCol1());
2491 sg.textColour2 = new java.awt.Color(groups[i].getTextCol2());
2492 sg.setShowNonconserved(groups[i].hasShowUnconserved() ? groups[i]
2493 .isShowUnconserved() : false);
2494 sg.thresholdTextColour = groups[i].getTextColThreshold();
2495 if (groups[i].hasShowConsensusHistogram())
2497 sg.setShowConsensusHistogram(groups[i].isShowConsensusHistogram());
2500 if (groups[i].hasShowSequenceLogo())
2502 sg.setshowSequenceLogo(groups[i].isShowSequenceLogo());
2504 if (groups[i].hasNormaliseSequenceLogo())
2506 sg.setNormaliseSequenceLogo(groups[i].isNormaliseSequenceLogo());
2508 if (groups[i].hasIgnoreGapsinConsensus())
2510 sg.setIgnoreGapsConsensus(groups[i].getIgnoreGapsinConsensus());
2512 if (groups[i].getConsThreshold() != 0)
2514 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
2515 "All", ResidueProperties.propHash, 3,
2516 sg.getSequences(null), 0, sg.getWidth() - 1);
2518 c.verdict(false, 25);
2519 sg.cs.setConservation(c);
2522 if (groups[i].getId() != null && groupAnnotRefs.size() > 0)
2524 // re-instate unique group/annotation row reference
2525 ArrayList<jalview.datamodel.AlignmentAnnotation> jaal = groupAnnotRefs
2526 .get(groups[i].getId());
2529 for (jalview.datamodel.AlignmentAnnotation jaa : jaal)
2532 if (jaa.autoCalculated)
2534 // match up and try to set group autocalc alignment row for this
2536 if (jaa.label.startsWith("Consensus for "))
2538 sg.setConsensus(jaa);
2540 // match up and try to set group autocalc alignment row for this
2542 if (jaa.label.startsWith("Conservation for "))
2544 sg.setConservationRow(jaa);
2555 // ///////////////////////////////
2558 // If we just load in the same jar file again, the sequenceSetId
2559 // will be the same, and we end up with multiple references
2560 // to the same sequenceSet. We must modify this id on load
2561 // so that each load of the file gives a unique id
2562 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
2563 String viewId = (view.getId() == null ? null : view.getId()
2565 AlignFrame af = null;
2566 AlignViewport av = null;
2567 // now check to see if we really need to create a new viewport.
2568 if (multipleView && viewportsAdded.size() == 0)
2570 // We recovered an alignment for which a viewport already exists.
2571 // TODO: fix up any settings necessary for overlaying stored state onto
2572 // state recovered from another document. (may not be necessary).
2573 // we may need a binding from a viewport in memory to one recovered from
2575 // and then recover its containing af to allow the settings to be applied.
2576 // TODO: fix for vamsas demo
2578 .println("About to recover a viewport for existing alignment: Sequence set ID is "
2580 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
2581 if (seqsetobj != null)
2583 if (seqsetobj instanceof String)
2585 uniqueSeqSetId = (String) seqsetobj;
2587 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
2593 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
2598 AlignmentPanel ap = null;
2599 boolean isnewview = true;
2602 // Check to see if this alignment already has a view id == viewId
2603 jalview.gui.AlignmentPanel views[] = Desktop
2604 .getAlignmentPanels(uniqueSeqSetId);
2605 if (views != null && views.length > 0)
2607 for (int v = 0; v < views.length; v++)
2609 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
2611 // recover the existing alignpanel, alignframe, viewport
2612 af = views[v].alignFrame;
2615 // TODO: could even skip resetting view settings if we don't want to
2616 // change the local settings from other jalview processes
2625 af = loadViewport(file, JSEQ, hiddenSeqs, al, jms, view,
2626 uniqueSeqSetId, viewId, autoAlan);
2631 // /////////////////////////////////////
2632 if (loadTreesAndStructures && jms.getTreeCount() > 0)
2636 for (int t = 0; t < jms.getTreeCount(); t++)
2639 Tree tree = jms.getTree(t);
2641 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
2644 tp = af.ShowNewickTree(
2645 new jalview.io.NewickFile(tree.getNewick()),
2646 tree.getTitle(), tree.getWidth(), tree.getHeight(),
2647 tree.getXpos(), tree.getYpos());
2648 if (tree.getId() != null)
2650 // perhaps bind the tree id to something ?
2655 // update local tree attributes ?
2656 // TODO: should check if tp has been manipulated by user - if so its
2657 // settings shouldn't be modified
2658 tp.setTitle(tree.getTitle());
2659 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
2660 .getWidth(), tree.getHeight()));
2661 tp.av = av; // af.viewport; // TODO: verify 'associate with all
2664 tp.treeCanvas.av = av; // af.viewport;
2665 tp.treeCanvas.ap = ap; // af.alignPanel;
2670 warn("There was a problem recovering stored Newick tree: \n"
2671 + tree.getNewick());
2675 tp.fitToWindow.setState(tree.getFitToWindow());
2676 tp.fitToWindow_actionPerformed(null);
2678 if (tree.getFontName() != null)
2680 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
2681 .getFontStyle(), tree.getFontSize()));
2685 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
2686 .getFontStyle(), tree.getFontSize()));
2689 tp.showPlaceholders(tree.getMarkUnlinked());
2690 tp.showBootstrap(tree.getShowBootstrap());
2691 tp.showDistances(tree.getShowDistances());
2693 tp.treeCanvas.threshold = tree.getThreshold();
2695 if (tree.getCurrentTree())
2697 af.viewport.setCurrentTree(tp.getTree());
2701 } catch (Exception ex)
2703 ex.printStackTrace();
2707 // //LOAD STRUCTURES
2708 if (loadTreesAndStructures)
2710 // run through all PDB ids on the alignment, and collect mappings between
2711 // jmol view ids and all sequences referring to it
2712 Hashtable<String, Object[]> jmolViewIds = new Hashtable();
2714 for (int i = 0; i < JSEQ.length; i++)
2716 if (JSEQ[i].getPdbidsCount() > 0)
2718 Pdbids[] ids = JSEQ[i].getPdbids();
2719 for (int p = 0; p < ids.length; p++)
2721 for (int s = 0; s < ids[p].getStructureStateCount(); s++)
2723 // check to see if we haven't already created this structure view
2724 String sviewid = (ids[p].getStructureState(s).getViewId() == null) ? null
2725 : ids[p].getStructureState(s).getViewId()
2727 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
2728 // Originally : ids[p].getFile()
2729 // : TODO: verify external PDB file recovery still works in normal
2730 // jalview project load
2731 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
2732 jpdb.setId(ids[p].getId());
2734 int x = ids[p].getStructureState(s).getXpos();
2735 int y = ids[p].getStructureState(s).getYpos();
2736 int width = ids[p].getStructureState(s).getWidth();
2737 int height = ids[p].getStructureState(s).getHeight();
2739 // Probably don't need to do this anymore...
2740 // Desktop.desktop.getComponentAt(x, y);
2741 // TODO: NOW: check that this recovers the PDB file correctly.
2742 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
2743 jalview.datamodel.SequenceI seq = (jalview.datamodel.SequenceI) seqRefIds
2744 .get(JSEQ[i].getId() + "");
2745 if (sviewid == null)
2747 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
2750 if (!jmolViewIds.containsKey(sviewid))
2752 jmolViewIds.put(sviewid, new Object[]
2754 { x, y, width, height }, "",
2755 new Hashtable<String, Object[]>(), new boolean[]
2756 { false, false, true } });
2757 // Legacy pre-2.7 conversion JAL-823 :
2758 // do not assume any view has to be linked for colour by
2762 // assemble String[] { pdb files }, String[] { id for each
2763 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
2764 // seqs_file 2}, boolean[] {
2765 // linkAlignPanel,superposeWithAlignpanel}} from hash
2766 Object[] jmoldat = jmolViewIds.get(sviewid);
2767 ((boolean[]) jmoldat[3])[0] |= ids[p].getStructureState(s)
2768 .hasAlignwithAlignPanel() ? ids[p].getStructureState(
2769 s).getAlignwithAlignPanel() : false;
2770 // never colour by linked panel if not specified
2771 ((boolean[]) jmoldat[3])[1] |= ids[p].getStructureState(s)
2772 .hasColourwithAlignPanel() ? ids[p]
2773 .getStructureState(s).getColourwithAlignPanel()
2775 // default for pre-2.7 projects is that Jmol colouring is enabled
2776 ((boolean[]) jmoldat[3])[2] &= ids[p].getStructureState(s)
2777 .hasColourByJmol() ? ids[p].getStructureState(s)
2778 .getColourByJmol() : true;
2780 if (((String) jmoldat[1]).length() < ids[p]
2781 .getStructureState(s).getContent().length())
2784 jmoldat[1] = ids[p].getStructureState(s).getContent();
2787 if (ids[p].getFile() != null)
2789 File mapkey = new File(ids[p].getFile());
2790 Object[] seqstrmaps = (Object[]) ((Hashtable) jmoldat[2])
2792 if (seqstrmaps == null)
2794 ((Hashtable) jmoldat[2]).put(mapkey,
2795 seqstrmaps = new Object[]
2796 { pdbFile, ids[p].getId(), new Vector(),
2799 if (!((Vector) seqstrmaps[2]).contains(seq))
2801 ((Vector) seqstrmaps[2]).addElement(seq);
2802 // ((Vector)seqstrmaps[3]).addElement(n) :
2803 // in principle, chains
2804 // should be stored here : do we need to
2805 // TODO: store and recover seq/pdb_id :
2811 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");
2820 // Instantiate the associated Jmol views
2821 for (Entry<String, Object[]> entry : jmolViewIds.entrySet())
2823 String sviewid = entry.getKey();
2824 Object[] svattrib = entry.getValue();
2825 int[] geom = (int[]) svattrib[0];
2826 String state = (String) svattrib[1];
2827 Hashtable<File, Object[]> oldFiles = (Hashtable<File, Object[]>) svattrib[2];
2828 final boolean useinJmolsuperpos = ((boolean[]) svattrib[3])[0], usetoColourbyseq = ((boolean[]) svattrib[3])[1], jmolColouring = ((boolean[]) svattrib[3])[2];
2829 int x = geom[0], y = geom[1], width = geom[2], height = geom[3];
2830 // collate the pdbfile -> sequence mappings from this view
2831 Vector<String> pdbfilenames = new Vector<String>();
2832 Vector<SequenceI[]> seqmaps = new Vector<SequenceI[]>();
2833 Vector<String> pdbids = new Vector<String>();
2835 // Search to see if we've already created this Jmol view
2836 AppJmol comp = null;
2837 JInternalFrame[] frames = null;
2842 frames = Desktop.desktop.getAllFrames();
2843 } catch (ArrayIndexOutOfBoundsException e)
2845 // occasional No such child exceptions are thrown here...
2850 } catch (Exception f)
2855 } while (frames == null);
2856 // search for any Jmol windows already open from other
2857 // alignment views that exactly match the stored structure state
2858 for (int f = 0; comp == null && f < frames.length; f++)
2860 if (frames[f] instanceof AppJmol)
2863 && ((AppJmol) frames[f]).getViewId().equals(sviewid))
2865 // post jalview 2.4 schema includes structure view id
2866 comp = (AppJmol) frames[f];
2868 else if (frames[f].getX() == x && frames[f].getY() == y
2869 && frames[f].getHeight() == height
2870 && frames[f].getWidth() == width)
2872 comp = (AppJmol) frames[f];
2879 // create a new Jmol window.
2880 // First parse the Jmol state to translate filenames loaded into the
2881 // view, and record the order in which files are shown in the Jmol
2882 // view, so we can add the sequence mappings in same order.
2883 StringBuffer newFileLoc = null;
2884 int cp = 0, ncp, ecp;
2885 while ((ncp = state.indexOf("load ", cp)) > -1)
2887 if (newFileLoc == null)
2889 newFileLoc = new StringBuffer();
2893 // look for next filename in load statement
2894 newFileLoc.append(state.substring(cp,
2895 ncp = (state.indexOf("\"", ncp + 1) + 1)));
2896 String oldfilenam = state.substring(ncp,
2897 ecp = state.indexOf("\"", ncp));
2898 // recover the new mapping data for this old filename
2899 // have to normalize filename - since Jmol and jalview do
2901 // translation differently.
2902 Object[] filedat = oldFiles.get(new File(oldfilenam));
2903 newFileLoc.append(Platform
2904 .escapeString((String) filedat[0]));
2905 pdbfilenames.addElement((String) filedat[0]);
2906 pdbids.addElement((String) filedat[1]);
2907 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
2908 .toArray(new SequenceI[0]));
2909 newFileLoc.append("\"");
2910 cp = ecp + 1; // advance beyond last \" and set cursor so we can
2911 // look for next file statement.
2912 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
2916 // just append rest of state
2917 newFileLoc.append(state.substring(cp));
2922 .print("Ignoring incomplete Jmol state for PDB ids: ");
2923 newFileLoc = new StringBuffer(state);
2924 newFileLoc.append("; load append ");
2925 for (File id : oldFiles.keySet())
2927 // add this and any other pdb files that should be present in
2929 Object[] filedat = oldFiles.get(id);
2931 newFileLoc.append(((String) filedat[0]));
2932 pdbfilenames.addElement((String) filedat[0]);
2933 pdbids.addElement((String) filedat[1]);
2934 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
2935 .toArray(new SequenceI[0]));
2936 newFileLoc.append(" \"");
2937 newFileLoc.append((String) filedat[0]);
2938 newFileLoc.append("\"");
2941 newFileLoc.append(";");
2944 if (newFileLoc != null)
2946 int histbug = newFileLoc.indexOf("history = ");
2948 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";",
2950 String val = (diff == -1) ? null : newFileLoc.substring(
2952 if (val != null && val.length() >= 4)
2954 if (val.contains("e"))
2956 if (val.trim().equals("true"))
2964 newFileLoc.replace(histbug, diff, val);
2967 // TODO: assemble String[] { pdb files }, String[] { id for each
2968 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
2969 // seqs_file 2}} from hash
2970 final String[] pdbf = pdbfilenames
2971 .toArray(new String[pdbfilenames.size()]), id = pdbids
2972 .toArray(new String[pdbids.size()]);
2973 final SequenceI[][] sq = seqmaps
2974 .toArray(new SequenceI[seqmaps.size()][]);
2975 final String fileloc = newFileLoc.toString(), vid = sviewid;
2976 final AlignFrame alf = af;
2977 final java.awt.Rectangle rect = new java.awt.Rectangle(x, y,
2981 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
2986 AppJmol sview = null;
2989 sview = new AppJmol(pdbf, id, sq, alf.alignPanel,
2990 useinJmolsuperpos, usetoColourbyseq,
2991 jmolColouring, fileloc, rect, vid);
2992 addNewStructureViewer(sview);
2993 } catch (OutOfMemoryError ex)
2995 new OOMWarning("restoring structure view for PDB id "
2996 + id, (OutOfMemoryError) ex.getCause());
2997 if (sview != null && sview.isVisible())
2999 sview.closeViewer();
3000 sview.setVisible(false);
3006 } catch (InvocationTargetException ex)
3008 warn("Unexpected error when opening Jmol view.", ex);
3010 } catch (InterruptedException e)
3012 // e.printStackTrace();
3018 // if (comp != null)
3020 // NOTE: if the jalview project is part of a shared session then
3021 // view synchronization should/could be done here.
3023 // add mapping for sequences in this view to an already open Jmol
3025 for (File id : oldFiles.keySet())
3027 // add this and any other pdb files that should be present in the
3029 Object[] filedat = oldFiles.get(id);
3030 String pdbFile = (String) filedat[0];
3031 SequenceI[] seq = ((Vector<SequenceI>) filedat[2])
3032 .toArray(new SequenceI[0]);
3033 comp.jmb.ssm.setMapping(seq, null, pdbFile,
3034 jalview.io.AppletFormatAdapter.FILE);
3035 comp.jmb.addSequenceForStructFile(pdbFile, seq);
3037 // and add the AlignmentPanel's reference to the Jmol view
3038 comp.addAlignmentPanel(ap);
3039 if (useinJmolsuperpos)
3041 comp.useAlignmentPanelForSuperposition(ap);
3045 comp.excludeAlignmentPanelForSuperposition(ap);
3047 if (usetoColourbyseq)
3049 comp.useAlignmentPanelForColourbyseq(ap, !jmolColouring);
3053 comp.excludeAlignmentPanelForColourbyseq(ap);
3059 // and finally return.
3062 Vector<AppJmol> newStructureViewers=null;
3063 protected void addNewStructureViewer(AppJmol sview)
3065 if (newStructureViewers!=null)
3067 sview.jmb.setFinishedLoadingFromArchive(false);
3068 newStructureViewers.add(sview);
3071 protected void setLoadingFinishedForNewStructureViewers()
3073 if (newStructureViewers!=null)
3075 for (AppJmol sview:newStructureViewers)
3077 sview.jmb.setFinishedLoadingFromArchive(true);
3079 newStructureViewers.clear();
3080 newStructureViewers=null;
3084 AlignFrame loadViewport(String file, JSeq[] JSEQ, Vector hiddenSeqs,
3085 Alignment al, JalviewModelSequence jms, Viewport view,
3086 String uniqueSeqSetId, String viewId,
3087 ArrayList<JvAnnotRow> autoAlan)
3089 AlignFrame af = null;
3090 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
3091 uniqueSeqSetId, viewId);
3093 af.setFileName(file, "Jalview");
3095 for (int i = 0; i < JSEQ.length; i++)
3097 af.viewport.setSequenceColour(af.viewport.getAlignment()
3098 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
3101 af.viewport.gatherViewsHere = view.getGatheredViews();
3103 if (view.getSequenceSetId() != null)
3105 jalview.gui.AlignViewport av = (jalview.gui.AlignViewport) viewportsAdded
3106 .get(uniqueSeqSetId);
3108 af.viewport.setSequenceSetId(uniqueSeqSetId);
3111 // propagate shared settings to this new view
3112 af.viewport.historyList = av.historyList;
3113 af.viewport.redoList = av.redoList;
3117 viewportsAdded.put(uniqueSeqSetId, af.viewport);
3119 // TODO: check if this method can be called repeatedly without
3120 // side-effects if alignpanel already registered.
3121 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
3123 // apply Hidden regions to view.
3124 if (hiddenSeqs != null)
3126 for (int s = 0; s < JSEQ.length; s++)
3128 jalview.datamodel.SequenceGroup hidden = new jalview.datamodel.SequenceGroup();
3130 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
3133 al.getSequenceAt(JSEQ[s].getHiddenSequences(r)), false);
3135 af.viewport.hideRepSequences(al.getSequenceAt(s), hidden);
3138 jalview.datamodel.SequenceI[] hseqs = new jalview.datamodel.SequenceI[hiddenSeqs
3141 for (int s = 0; s < hiddenSeqs.size(); s++)
3143 hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s);
3146 af.viewport.hideSequence(hseqs);
3149 // recover view properties and display parameters
3150 if (view.getViewName() != null)
3152 af.viewport.viewName = view.getViewName();
3153 af.setInitialTabVisible();
3155 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
3158 af.viewport.setShowAnnotation(view.getShowAnnotation());
3159 af.viewport.setAbovePIDThreshold(view.getPidSelected());
3161 af.viewport.setColourText(view.getShowColourText());
3163 af.viewport.setConservationSelected(view.getConservationSelected());
3164 af.viewport.setShowJVSuffix(view.getShowFullId());
3165 af.viewport.rightAlignIds = view.getRightAlignIds();
3166 af.viewport.setFont(new java.awt.Font(view.getFontName(), view
3167 .getFontStyle(), view.getFontSize()));
3168 af.alignPanel.fontChanged();
3169 af.viewport.setRenderGaps(view.getRenderGaps());
3170 af.viewport.setWrapAlignment(view.getWrapAlignment());
3171 af.alignPanel.setWrapAlignment(view.getWrapAlignment());
3172 af.viewport.setShowAnnotation(view.getShowAnnotation());
3173 af.alignPanel.setAnnotationVisible(view.getShowAnnotation());
3175 af.viewport.setShowBoxes(view.getShowBoxes());
3177 af.viewport.setShowText(view.getShowText());
3179 af.viewport.textColour = new java.awt.Color(view.getTextCol1());
3180 af.viewport.textColour2 = new java.awt.Color(view.getTextCol2());
3181 af.viewport.thresholdTextColour = view.getTextColThreshold();
3182 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
3183 .isShowUnconserved() : false);
3184 af.viewport.setStartRes(view.getStartRes());
3185 af.viewport.setStartSeq(view.getStartSeq());
3187 ColourSchemeI cs = null;
3188 // apply colourschemes
3189 if (view.getBgColour() != null)
3191 if (view.getBgColour().startsWith("ucs"))
3193 cs = GetUserColourScheme(jms, view.getBgColour());
3195 else if (view.getBgColour().startsWith("Annotation"))
3197 // int find annotation
3198 if (af.viewport.getAlignment().getAlignmentAnnotation() != null)
3200 for (int i = 0; i < af.viewport.getAlignment()
3201 .getAlignmentAnnotation().length; i++)
3203 if (af.viewport.getAlignment().getAlignmentAnnotation()[i].label
3204 .equals(view.getAnnotationColours().getAnnotation()))
3206 if (af.viewport.getAlignment().getAlignmentAnnotation()[i]
3207 .getThreshold() == null)
3209 af.viewport.getAlignment().getAlignmentAnnotation()[i]
3210 .setThreshold(new jalview.datamodel.GraphLine(view
3211 .getAnnotationColours().getThreshold(),
3212 "Threshold", java.awt.Color.black)
3217 if (view.getAnnotationColours().getColourScheme()
3220 cs = new AnnotationColourGradient(af.viewport
3221 .getAlignment().getAlignmentAnnotation()[i],
3222 new java.awt.Color(view.getAnnotationColours()
3223 .getMinColour()), new java.awt.Color(view
3224 .getAnnotationColours().getMaxColour()),
3225 view.getAnnotationColours().getAboveThreshold());
3227 else if (view.getAnnotationColours().getColourScheme()
3230 cs = new AnnotationColourGradient(af.viewport
3231 .getAlignment().getAlignmentAnnotation()[i],
3232 GetUserColourScheme(jms, view
3233 .getAnnotationColours().getColourScheme()),
3234 view.getAnnotationColours().getAboveThreshold());
3238 cs = new AnnotationColourGradient(af.viewport
3239 .getAlignment().getAlignmentAnnotation()[i],
3240 ColourSchemeProperty.getColour(al, view
3241 .getAnnotationColours().getColourScheme()),
3242 view.getAnnotationColours().getAboveThreshold());
3244 if (view.getAnnotationColours().hasPerSequence())
3246 ((AnnotationColourGradient)cs).setSeqAssociated(view.getAnnotationColours().isPerSequence());
3248 if (view.getAnnotationColours().hasPredefinedColours())
3250 ((AnnotationColourGradient)cs).setPredefinedColours(view.getAnnotationColours().isPredefinedColours());
3252 // Also use these settings for all the groups
3253 if (al.getGroups() != null)
3255 for (int g = 0; g < al.getGroups().size(); g++)
3257 jalview.datamodel.SequenceGroup sg = al.getGroups()
3267 * (view.getAnnotationColours().getColourScheme().equals("None"
3268 * )) { sg.cs = new AnnotationColourGradient(
3269 * af.viewport.getAlignment().getAlignmentAnnotation()[i], new
3270 * java.awt.Color(view.getAnnotationColours().
3271 * getMinColour()), new
3272 * java.awt.Color(view.getAnnotationColours().
3274 * view.getAnnotationColours().getAboveThreshold()); } else
3277 sg.cs = new AnnotationColourGradient(af.viewport
3278 .getAlignment().getAlignmentAnnotation()[i],
3279 sg.cs, view.getAnnotationColours()
3280 .getAboveThreshold());
3281 if (cs instanceof AnnotationColourGradient)
3283 if (view.getAnnotationColours().hasPerSequence())
3285 ((AnnotationColourGradient)cs).setSeqAssociated(view.getAnnotationColours().isPerSequence());
3287 if (view.getAnnotationColours().hasPredefinedColours())
3289 ((AnnotationColourGradient)cs).setPredefinedColours(view.getAnnotationColours().isPredefinedColours());
3305 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
3310 cs.setThreshold(view.getPidThreshold(), true);
3311 cs.setConsensus(af.viewport.getSequenceConsensusHash());
3315 af.viewport.setGlobalColourScheme(cs);
3316 af.viewport.setColourAppliesToAllGroups(false);
3318 if (view.getConservationSelected() && cs != null)
3320 cs.setConservationInc(view.getConsThreshold());
3323 af.changeColour(cs);
3325 af.viewport.setColourAppliesToAllGroups(true);
3327 if (view.getShowSequenceFeatures())
3329 af.viewport.showSequenceFeatures = true;
3331 if (view.hasCentreColumnLabels())
3333 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
3335 if (view.hasIgnoreGapsinConsensus())
3337 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
3340 if (view.hasFollowHighlight())
3342 af.viewport.followHighlight = view.getFollowHighlight();
3344 if (view.hasFollowSelection())
3346 af.viewport.followSelection = view.getFollowSelection();
3348 if (view.hasShowConsensusHistogram())
3350 af.viewport.setShowConsensusHistogram(view
3351 .getShowConsensusHistogram());
3355 af.viewport.setShowConsensusHistogram(true);
3357 if (view.hasShowSequenceLogo())
3359 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
3363 af.viewport.setShowSequenceLogo(false);
3365 if (view.hasNormaliseSequenceLogo())
3367 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
3369 if (view.hasShowDbRefTooltip())
3371 af.viewport.setShowDbRefs(view.getShowDbRefTooltip());
3373 if (view.hasShowNPfeatureTooltip())
3375 af.viewport.setShowNpFeats(view.hasShowNPfeatureTooltip());
3377 if (view.hasShowGroupConsensus())
3379 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
3383 af.viewport.setShowGroupConsensus(false);
3385 if (view.hasShowGroupConservation())
3387 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
3391 af.viewport.setShowGroupConservation(false);
3394 // recover featre settings
3395 if (jms.getFeatureSettings() != null)
3397 af.viewport.featuresDisplayed = new Hashtable();
3398 String[] renderOrder = new String[jms.getFeatureSettings()
3399 .getSettingCount()];
3400 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
3402 Setting setting = jms.getFeatureSettings().getSetting(fs);
3403 if (setting.hasMincolour())
3405 GraduatedColor gc = setting.hasMin() ? new GraduatedColor(
3406 new java.awt.Color(setting.getMincolour()),
3407 new java.awt.Color(setting.getColour()),
3408 setting.getMin(), setting.getMax()) : new GraduatedColor(
3409 new java.awt.Color(setting.getMincolour()),
3410 new java.awt.Color(setting.getColour()), 0, 1);
3411 if (setting.hasThreshold())
3413 gc.setThresh(setting.getThreshold());
3414 gc.setThreshType(setting.getThreshstate());
3416 gc.setAutoScaled(true); // default
3417 if (setting.hasAutoScale())
3419 gc.setAutoScaled(setting.getAutoScale());
3421 if (setting.hasColourByLabel())
3423 gc.setColourByLabel(setting.getColourByLabel());
3425 // and put in the feature colour table.
3426 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3427 setting.getType(), gc);
3431 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3433 new java.awt.Color(setting.getColour()));
3435 renderOrder[fs] = setting.getType();
3436 if (setting.hasOrder())
3437 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3438 setting.getType(), setting.getOrder());
3440 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3442 fs / jms.getFeatureSettings().getSettingCount());
3443 if (setting.getDisplay())
3445 af.viewport.featuresDisplayed.put(setting.getType(), new Integer(
3446 setting.getColour()));
3449 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().renderOrder = renderOrder;
3451 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().featureGroups = fgtable = new Hashtable();
3452 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
3454 Group grp = jms.getFeatureSettings().getGroup(gs);
3455 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
3459 if (view.getHiddenColumnsCount() > 0)
3461 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
3463 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
3464 .getHiddenColumns(c).getEnd() // +1
3468 if (view.getCalcIdParam() != null)
3470 for (CalcIdParam calcIdParam : view.getCalcIdParam())
3472 if (calcIdParam != null)
3474 if (recoverCalcIdParam(calcIdParam, af.viewport))
3479 warn("Couldn't recover parameters for "
3480 + calcIdParam.getCalcId());
3485 af.setMenusFromViewport(af.viewport);
3486 // TODO: we don't need to do this if the viewport is aready visible.
3487 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
3489 af.alignPanel.updateAnnotation(false, true); // recompute any autoannotation
3490 reorderAutoannotation(af, al, autoAlan);
3491 af.alignPanel.alignmentChanged();
3495 private void reorderAutoannotation(AlignFrame af, Alignment al,
3496 ArrayList<JvAnnotRow> autoAlan)
3498 // copy over visualization settings for autocalculated annotation in the
3500 if (al.getAlignmentAnnotation() != null)
3503 * Kludge for magic autoannotation names (see JAL-811)
3505 String[] magicNames = new String[]
3506 { "Consensus", "Quality", "Conservation" };
3507 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
3508 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
3509 for (String nm : magicNames)
3511 visan.put(nm, nullAnnot);
3513 for (JvAnnotRow auan : autoAlan)
3515 visan.put(auan.template.label
3516 + (auan.template.getCalcId() == null ? "" : "\t"
3517 + auan.template.getCalcId()), auan);
3519 int hSize = al.getAlignmentAnnotation().length;
3520 ArrayList<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
3521 // work through any autoCalculated annotation already on the view
3522 // removing it if it should be placed in a different location on the
3523 // annotation panel.
3524 List<String> remains = new ArrayList(visan.keySet());
3525 for (int h = 0; h < hSize; h++)
3527 jalview.datamodel.AlignmentAnnotation jalan = al
3528 .getAlignmentAnnotation()[h];
3529 if (jalan.autoCalculated)
3532 JvAnnotRow valan = visan.get(k = jalan.label);
3533 if (jalan.getCalcId() != null)
3535 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
3540 // delete the auto calculated row from the alignment
3541 al.deleteAnnotation(jalan, false);
3545 if (valan != nullAnnot)
3547 if (jalan != valan.template)
3549 // newly created autoannotation row instance
3550 // so keep a reference to the visible annotation row
3551 // and copy over all relevant attributes
3552 if (valan.template.graphHeight >= 0)
3555 jalan.graphHeight = valan.template.graphHeight;
3557 jalan.visible = valan.template.visible;
3559 reorder.add(new JvAnnotRow(valan.order, jalan));
3564 // Add any (possibly stale) autocalculated rows that were not appended to
3565 // the view during construction
3566 for (String other : remains)
3568 JvAnnotRow othera = visan.get(other);
3569 if (othera != nullAnnot && othera.template.getCalcId() != null
3570 && othera.template.getCalcId().length() > 0)
3572 reorder.add(othera);
3575 // now put the automatic annotation in its correct place
3576 int s = 0, srt[] = new int[reorder.size()];
3577 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
3578 for (JvAnnotRow jvar : reorder)
3581 srt[s++] = jvar.order;
3584 jalview.util.QuickSort.sort(srt, rws);
3585 // and re-insert the annotation at its correct position
3586 for (JvAnnotRow jvar : rws)
3588 al.addAnnotation(jvar.template, jvar.order);
3590 af.alignPanel.adjustAnnotationHeight();
3594 Hashtable skipList = null;
3597 * TODO remove this method
3600 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
3601 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
3602 * throw new Error("Implementation Error. No skipList defined for this
3603 * Jalview2XML instance."); } return (AlignFrame)
3604 * skipList.get(view.getSequenceSetId()); }
3608 * Check if the Jalview view contained in object should be skipped or not.
3611 * @return true if view's sequenceSetId is a key in skipList
3613 private boolean skipViewport(JalviewModel object)
3615 if (skipList == null)
3620 if (skipList.containsKey(id = object.getJalviewModelSequence()
3621 .getViewport()[0].getSequenceSetId()))
3623 if (Cache.log != null && Cache.log.isDebugEnabled())
3625 Cache.log.debug("Skipping seuqence set id " + id);
3632 public void AddToSkipList(AlignFrame af)
3634 if (skipList == null)
3636 skipList = new Hashtable();
3638 skipList.put(af.getViewport().getSequenceSetId(), af);
3641 public void clearSkipList()
3643 if (skipList != null)
3650 private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al)
3652 jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId());
3653 Vector dseqs = null;
3656 // create a list of new dataset sequences
3657 dseqs = new Vector();
3659 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
3661 Sequence vamsasSeq = vamsasSet.getSequence(i);
3662 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs);
3664 // create a new dataset
3667 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
3668 dseqs.copyInto(dsseqs);
3669 ds = new jalview.datamodel.Alignment(dsseqs);
3670 debug("Created new dataset " + vamsasSet.getDatasetId()
3671 + " for alignment " + System.identityHashCode(al));
3672 addDatasetRef(vamsasSet.getDatasetId(), ds);
3674 // set the dataset for the newly imported alignment.
3675 if (al.getDataset() == null)
3684 * sequence definition to create/merge dataset sequence for
3688 * vector to add new dataset sequence to
3690 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
3691 AlignmentI ds, Vector dseqs)
3693 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
3695 jalview.datamodel.Sequence sq = (jalview.datamodel.Sequence) seqRefIds
3696 .get(vamsasSeq.getId());
3697 jalview.datamodel.SequenceI dsq = null;
3698 if (sq != null && sq.getDatasetSequence() != null)
3700 dsq = sq.getDatasetSequence();
3703 String sqid = vamsasSeq.getDsseqid();
3706 // need to create or add a new dataset sequence reference to this sequence
3709 dsq = (jalview.datamodel.SequenceI) seqRefIds.get(sqid);
3714 // make a new dataset sequence
3715 dsq = sq.createDatasetSequence();
3718 // make up a new dataset reference for this sequence
3719 sqid = seqHash(dsq);
3721 dsq.setVamsasId(uniqueSetSuffix + sqid);
3722 seqRefIds.put(sqid, dsq);
3727 dseqs.addElement(dsq);
3732 ds.addSequence(dsq);
3738 { // make this dataset sequence sq's dataset sequence
3739 sq.setDatasetSequence(dsq);
3740 // and update the current dataset alignment
3743 if (!dseqs.contains(dsq))
3748 if (ds.findIndex(dsq)<0)
3750 ds.addSequence(dsq);
3757 // TODO: refactor this as a merge dataset sequence function
3758 // now check that sq (the dataset sequence) sequence really is the union of
3759 // all references to it
3760 // boolean pre = sq.getStart() < dsq.getStart();
3761 // boolean post = sq.getEnd() > dsq.getEnd();
3765 StringBuffer sb = new StringBuffer();
3766 String newres = jalview.analysis.AlignSeq.extractGaps(
3767 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
3768 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
3769 && newres.length() > dsq.getLength())
3771 // Update with the longer sequence.
3775 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
3776 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
3777 * sb.append(newres.substring(newres.length() - sq.getEnd() -
3778 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
3780 dsq.setSequence(newres);
3782 // TODO: merges will never happen if we 'know' we have the real dataset
3783 // sequence - this should be detected when id==dssid
3784 System.err.println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
3785 // + (pre ? "prepended" : "") + " "
3786 // + (post ? "appended" : ""));
3791 java.util.Hashtable datasetIds = null;
3793 java.util.IdentityHashMap dataset2Ids = null;
3795 private Alignment getDatasetFor(String datasetId)
3797 if (datasetIds == null)
3799 datasetIds = new Hashtable();
3802 if (datasetIds.containsKey(datasetId))
3804 return (Alignment) datasetIds.get(datasetId);
3809 private void addDatasetRef(String datasetId, Alignment dataset)
3811 if (datasetIds == null)
3813 datasetIds = new Hashtable();
3815 datasetIds.put(datasetId, dataset);
3819 * make a new dataset ID for this jalview dataset alignment
3824 private String getDatasetIdRef(jalview.datamodel.Alignment dataset)
3826 if (dataset.getDataset() != null)
3828 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
3830 String datasetId = makeHashCode(dataset, null);
3831 if (datasetId == null)
3833 // make a new datasetId and record it
3834 if (dataset2Ids == null)
3836 dataset2Ids = new IdentityHashMap();
3840 datasetId = (String) dataset2Ids.get(dataset);
3842 if (datasetId == null)
3844 datasetId = "ds" + dataset2Ids.size() + 1;
3845 dataset2Ids.put(dataset, datasetId);
3851 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
3853 for (int d = 0; d < sequence.getDBRefCount(); d++)
3855 DBRef dr = sequence.getDBRef(d);
3856 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
3857 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
3858 .getVersion(), sequence.getDBRef(d).getAccessionId());
3859 if (dr.getMapping() != null)
3861 entry.setMap(addMapping(dr.getMapping()));
3863 datasetSequence.addDBRef(entry);
3867 private jalview.datamodel.Mapping addMapping(Mapping m)
3869 SequenceI dsto = null;
3870 // Mapping m = dr.getMapping();
3871 int fr[] = new int[m.getMapListFromCount() * 2];
3872 Enumeration f = m.enumerateMapListFrom();
3873 for (int _i = 0; f.hasMoreElements(); _i += 2)
3875 MapListFrom mf = (MapListFrom) f.nextElement();
3876 fr[_i] = mf.getStart();
3877 fr[_i + 1] = mf.getEnd();
3879 int fto[] = new int[m.getMapListToCount() * 2];
3880 f = m.enumerateMapListTo();
3881 for (int _i = 0; f.hasMoreElements(); _i += 2)
3883 MapListTo mf = (MapListTo) f.nextElement();
3884 fto[_i] = mf.getStart();
3885 fto[_i + 1] = mf.getEnd();
3887 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
3888 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
3889 if (m.getMappingChoice() != null)
3891 MappingChoice mc = m.getMappingChoice();
3892 if (mc.getDseqFor() != null)
3894 String dsfor = "" + mc.getDseqFor();
3895 if (seqRefIds.containsKey(dsfor))
3900 jmap.setTo((SequenceI) seqRefIds.get(dsfor));
3904 frefedSequence.add(new Object[]
3911 * local sequence definition
3913 Sequence ms = mc.getSequence();
3914 jalview.datamodel.Sequence djs = null;
3915 String sqid = ms.getDsseqid();
3916 if (sqid != null && sqid.length() > 0)
3919 * recover dataset sequence
3921 djs = (jalview.datamodel.Sequence) seqRefIds.get(sqid);
3926 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
3927 sqid = ((Object) ms).toString(); // make up a new hascode for
3928 // undefined dataset sequence hash
3929 // (unlikely to happen)
3935 * make a new dataset sequence and add it to refIds hash
3937 djs = new jalview.datamodel.Sequence(ms.getName(),
3939 djs.setStart(jmap.getMap().getToLowest());
3940 djs.setEnd(jmap.getMap().getToHighest());
3941 djs.setVamsasId(uniqueSetSuffix + sqid);
3943 seqRefIds.put(sqid, djs);
3946 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
3955 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
3956 boolean keepSeqRefs)
3959 jalview.schemabinding.version2.JalviewModel jm = SaveState(ap, null,
3965 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
3969 uniqueSetSuffix = "";
3970 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
3975 if (this.frefedSequence == null)
3977 frefedSequence = new Vector();
3980 viewportsAdded = new Hashtable();
3982 AlignFrame af = LoadFromObject(jm, null, false, null);
3983 af.alignPanels.clear();
3984 af.closeMenuItem_actionPerformed(true);
3987 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
3988 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
3989 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
3990 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
3991 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
3994 return af.alignPanel;
3998 * flag indicating if hashtables should be cleared on finalization TODO this
3999 * flag may not be necessary
4001 private final boolean _cleartables = true;
4003 private Hashtable jvids2vobj;
4008 * @see java.lang.Object#finalize()
4011 protected void finalize() throws Throwable
4013 // really make sure we have no buried refs left.
4018 this.seqRefIds = null;
4019 this.seqsToIds = null;
4023 private void warn(String msg)
4028 private void warn(String msg, Exception e)
4030 if (Cache.log != null)
4034 Cache.log.warn(msg, e);
4038 Cache.log.warn(msg);
4043 System.err.println("Warning: " + msg);
4046 e.printStackTrace();
4051 private void debug(String string)
4053 debug(string, null);
4056 private void debug(String msg, Exception e)
4058 if (Cache.log != null)
4062 Cache.log.debug(msg, e);
4066 Cache.log.debug(msg);
4071 System.err.println("Warning: " + msg);
4074 e.printStackTrace();
4080 * set the object to ID mapping tables used to write/recover objects and XML
4081 * ID strings for the jalview project. If external tables are provided then
4082 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
4083 * object goes out of scope. - also populates the datasetIds hashtable with
4084 * alignment objects containing dataset sequences
4087 * Map from ID strings to jalview datamodel
4089 * Map from jalview datamodel to ID strings
4093 public void setObjectMappingTables(Hashtable vobj2jv,
4094 IdentityHashMap jv2vobj)
4096 this.jv2vobj = jv2vobj;
4097 this.vobj2jv = vobj2jv;
4098 Iterator ds = jv2vobj.keySet().iterator();
4100 while (ds.hasNext())
4102 Object jvobj = ds.next();
4103 id = jv2vobj.get(jvobj).toString();
4104 if (jvobj instanceof jalview.datamodel.Alignment)
4106 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
4108 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
4111 else if (jvobj instanceof jalview.datamodel.Sequence)
4113 // register sequence object so the XML parser can recover it.
4114 if (seqRefIds == null)
4116 seqRefIds = new Hashtable();
4118 if (seqsToIds == null)
4120 seqsToIds = new IdentityHashMap();
4122 seqRefIds.put(jv2vobj.get(jvobj).toString(), jvobj);
4123 seqsToIds.put(jvobj, id);
4125 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
4127 if (annotationIds == null)
4129 annotationIds = new Hashtable();
4132 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvobj);
4133 jalview.datamodel.AlignmentAnnotation jvann = (jalview.datamodel.AlignmentAnnotation) jvobj;
4134 if (jvann.annotationId == null)
4136 jvann.annotationId = anid;
4138 if (!jvann.annotationId.equals(anid))
4140 // TODO verify that this is the correct behaviour
4141 this.warn("Overriding Annotation ID for " + anid
4142 + " from different id : " + jvann.annotationId);
4143 jvann.annotationId = anid;
4146 else if (jvobj instanceof String)
4148 if (jvids2vobj == null)
4150 jvids2vobj = new Hashtable();
4151 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
4155 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
4160 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
4161 * objects created from the project archive. If string is null (default for
4162 * construction) then suffix will be set automatically.
4166 public void setUniqueSetSuffix(String string)
4168 uniqueSetSuffix = string;
4173 * uses skipList2 as the skipList for skipping views on sequence sets
4174 * associated with keys in the skipList
4178 public void setSkipList(Hashtable skipList2)
4180 skipList = skipList2;