2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8)
3 * Copyright (C) 2012 J Procter, AM Waterhouse, LM Lui, J Engelhardt, G Barton, M Clamp, S Searle
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
11 * Jalview is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty
13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along with Jalview. If not, see <http://www.gnu.org/licenses/>.
20 import java.awt.Rectangle;
22 import java.lang.reflect.InvocationTargetException;
25 import java.util.Map.Entry;
26 import java.util.jar.*;
30 import org.exolab.castor.xml.*;
32 import jalview.bin.Cache;
33 import jalview.datamodel.Alignment;
34 import jalview.datamodel.AlignmentAnnotation;
35 import jalview.datamodel.AlignmentI;
36 import jalview.datamodel.SequenceI;
37 import jalview.schemabinding.version2.*;
38 import jalview.schemes.*;
39 import jalview.util.Platform;
40 import jalview.util.jarInputStreamProvider;
41 import jalview.ws.jws2.AAConClient;
42 import jalview.ws.jws2.Jws2Discoverer;
43 import jalview.ws.jws2.dm.AAConSettings;
44 import jalview.ws.jws2.jabaws2.Jws2Instance;
45 import jalview.ws.params.ArgumentI;
46 import jalview.ws.params.AutoCalcSetting;
47 import jalview.ws.params.WsParamSetI;
50 * Write out the current jalview desktop state as a Jalview XML stream.
52 * Note: the vamsas objects referred to here are primitive versions of the
53 * VAMSAS project schema elements - they are not the same and most likely never
57 * @version $Revision: 1.134 $
59 public class Jalview2XML
62 * create/return unique hash string for sq
65 * @return new or existing unique string for sq
67 String seqHash(SequenceI sq)
69 if (seqsToIds == null)
73 if (seqsToIds.containsKey(sq))
75 return (String) seqsToIds.get(sq);
79 // create sequential key
80 String key = "sq" + (seqsToIds.size() + 1);
81 key = makeHashCode(sq, key); // check we don't have an external reference
83 seqsToIds.put(sq, key);
92 if (seqRefIds != null)
96 if (seqsToIds != null)
106 warn("clearSeqRefs called when _cleartables was not set. Doing nothing.");
107 // seqRefIds = new Hashtable();
108 // seqsToIds = new IdentityHashMap();
114 if (seqsToIds == null)
116 seqsToIds = new IdentityHashMap();
118 if (seqRefIds == null)
120 seqRefIds = new Hashtable();
125 * SequenceI reference -> XML ID string in jalview XML. Populated as XML reps
126 * of sequence objects are created.
128 java.util.IdentityHashMap seqsToIds = null;
131 * jalview XML Sequence ID to jalview sequence object reference (both dataset
132 * and alignment sequences. Populated as XML reps of sequence objects are
135 java.util.Hashtable seqRefIds = null; // key->SequenceI resolution
137 Vector frefedSequence = null;
139 boolean raiseGUI = true; // whether errors are raised in dialog boxes or not
145 public Jalview2XML(boolean raiseGUI)
147 this.raiseGUI = raiseGUI;
150 public void resolveFrefedSequences()
152 if (frefedSequence.size() > 0)
154 int r = 0, rSize = frefedSequence.size();
157 Object[] ref = (Object[]) frefedSequence.elementAt(r);
160 String sref = (String) ref[0];
161 if (seqRefIds.containsKey(sref))
163 if (ref[1] instanceof jalview.datamodel.Mapping)
165 SequenceI seq = (SequenceI) seqRefIds.get(sref);
166 while (seq.getDatasetSequence() != null)
168 seq = seq.getDatasetSequence();
170 ((jalview.datamodel.Mapping) ref[1]).setTo(seq);
174 if (ref[1] instanceof jalview.datamodel.AlignedCodonFrame)
176 SequenceI seq = (SequenceI) seqRefIds.get(sref);
177 while (seq.getDatasetSequence() != null)
179 seq = seq.getDatasetSequence();
182 && ref[2] instanceof jalview.datamodel.Mapping)
184 jalview.datamodel.Mapping mp = (jalview.datamodel.Mapping) ref[2];
185 ((jalview.datamodel.AlignedCodonFrame) ref[1]).addMap(
186 seq, mp.getTo(), mp.getMap());
191 .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for AlcodonFrames involving "
192 + ref[2].getClass() + " type objects.");
198 .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for "
199 + ref[1].getClass() + " type objects.");
202 frefedSequence.remove(r);
208 .println("IMPLEMENTATION WARNING: Unresolved forward reference for hash string "
210 + " with objecttype "
211 + ref[1].getClass());
218 frefedSequence.remove(r);
226 * This maintains a list of viewports, the key being the seqSetId. Important
227 * to set historyItem and redoList for multiple views
229 Hashtable viewportsAdded;
231 Hashtable annotationIds = new Hashtable();
233 String uniqueSetSuffix = "";
236 * List of pdbfiles added to Jar
238 Vector pdbfiles = null;
240 // SAVES SEVERAL ALIGNMENT WINDOWS TO SAME JARFILE
241 public void SaveState(File statefile)
245 FileOutputStream fos = new FileOutputStream(statefile);
246 JarOutputStream jout = new JarOutputStream(fos);
249 } catch (Exception e)
251 // TODO: inform user of the problem - they need to know if their data was
253 if (errorMessage == null)
255 errorMessage = "Couldn't write Jalview Archive to output file '"
256 + statefile + "' - See console error log for details";
260 errorMessage += "(output file was '" + statefile + "')";
268 * Writes a jalview project archive to the given Jar output stream.
272 public void SaveState(JarOutputStream jout)
274 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
284 // NOTE UTF-8 MUST BE USED FOR WRITING UNICODE CHARS
285 // //////////////////////////////////////////////////
286 // NOTE ALSO new PrintWriter must be used for each new JarEntry
287 PrintWriter out = null;
289 Vector shortNames = new Vector();
292 for (int i = frames.length - 1; i > -1; i--)
294 if (frames[i] instanceof AlignFrame)
296 AlignFrame af = (AlignFrame) frames[i];
299 && skipList.containsKey(af.getViewport()
300 .getSequenceSetId()))
305 String shortName = af.getTitle();
307 if (shortName.indexOf(File.separatorChar) > -1)
309 shortName = shortName.substring(shortName
310 .lastIndexOf(File.separatorChar) + 1);
315 while (shortNames.contains(shortName))
317 if (shortName.endsWith("_" + (count - 1)))
319 shortName = shortName
320 .substring(0, shortName.lastIndexOf("_"));
323 shortName = shortName.concat("_" + count);
327 shortNames.addElement(shortName);
329 if (!shortName.endsWith(".xml"))
331 shortName = shortName + ".xml";
334 int ap, apSize = af.alignPanels.size();
335 for (ap = 0; ap < apSize; ap++)
337 AlignmentPanel apanel = (AlignmentPanel) af.alignPanels
339 String fileName = apSize == 1 ? shortName : ap + shortName;
340 if (!fileName.endsWith(".xml"))
342 fileName = fileName + ".xml";
345 SaveState(apanel, fileName, jout);
352 } catch (Exception foo)
357 } catch (Exception ex)
359 // TODO: inform user of the problem - they need to know if their data was
361 if (errorMessage == null)
363 errorMessage = "Couldn't write Jalview Archive - see error output for details";
365 ex.printStackTrace();
369 // USE THIS METHOD TO SAVE A SINGLE ALIGNMENT WINDOW
370 public boolean SaveAlignment(AlignFrame af, String jarFile,
375 int ap, apSize = af.alignPanels.size();
376 FileOutputStream fos = new FileOutputStream(jarFile);
377 JarOutputStream jout = new JarOutputStream(fos);
378 for (ap = 0; ap < apSize; ap++)
380 AlignmentPanel apanel = (AlignmentPanel) af.alignPanels
382 String jfileName = apSize == 1 ? fileName : fileName + ap;
383 if (!jfileName.endsWith(".xml"))
385 jfileName = jfileName + ".xml";
387 SaveState(apanel, jfileName, jout);
393 } catch (Exception foo)
399 } catch (Exception ex)
401 errorMessage = "Couldn't Write alignment view to Jalview Archive - see error output for details";
402 ex.printStackTrace();
408 * create a JalviewModel from an algnment view and marshall it to a
412 * panel to create jalview model for
414 * name of alignment panel written to output stream
420 public JalviewModel SaveState(AlignmentPanel ap, String fileName,
421 JarOutputStream jout)
424 Vector jmolViewIds = new Vector(); //
425 Vector userColours = new Vector();
427 AlignViewport av = ap.av;
429 JalviewModel object = new JalviewModel();
430 object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel());
432 object.setCreationDate(new java.util.Date(System.currentTimeMillis()));
433 object.setVersion(jalview.bin.Cache.getProperty("VERSION"));
435 jalview.datamodel.AlignmentI jal = av.getAlignment();
437 if (av.hasHiddenRows())
439 jal = jal.getHiddenSequences().getFullAlignment();
442 SequenceSet vamsasSet = new SequenceSet();
444 JalviewModelSequence jms = new JalviewModelSequence();
446 vamsasSet.setGapChar(jal.getGapCharacter() + "");
448 if (jal.getDataset() != null)
450 // dataset id is the dataset's hashcode
451 vamsasSet.setDatasetId(getDatasetIdRef(jal.getDataset()));
453 if (jal.getProperties() != null)
455 Enumeration en = jal.getProperties().keys();
456 while (en.hasMoreElements())
458 String key = en.nextElement().toString();
459 SequenceSetProperties ssp = new SequenceSetProperties();
461 ssp.setValue(jal.getProperties().get(key).toString());
462 vamsasSet.addSequenceSetProperties(ssp);
467 Set<String> calcIdSet = new HashSet<String>();
471 jalview.datamodel.SequenceI jds;
472 for (int i = 0; i < jal.getHeight(); i++)
474 jds = jal.getSequenceAt(i);
477 if (seqRefIds.get(id) != null)
479 // This happens for two reasons: 1. multiple views are being serialised.
480 // 2. the hashCode has collided with another sequence's code. This DOES
481 // HAPPEN! (PF00072.15.stk does this)
482 // JBPNote: Uncomment to debug writing out of files that do not read
483 // back in due to ArrayOutOfBoundExceptions.
484 // System.err.println("vamsasSeq backref: "+id+"");
485 // System.err.println(jds.getName()+"
486 // "+jds.getStart()+"-"+jds.getEnd()+" "+jds.getSequenceAsString());
487 // System.err.println("Hashcode: "+seqHash(jds));
488 // SequenceI rsq = (SequenceI) seqRefIds.get(id + "");
489 // System.err.println(rsq.getName()+"
490 // "+rsq.getStart()+"-"+rsq.getEnd()+" "+rsq.getSequenceAsString());
491 // System.err.println("Hashcode: "+seqHash(rsq));
495 vamsasSeq = createVamsasSequence(id, jds);
496 vamsasSet.addSequence(vamsasSeq);
497 seqRefIds.put(id, jds);
501 jseq.setStart(jds.getStart());
502 jseq.setEnd(jds.getEnd());
503 jseq.setColour(av.getSequenceColour(jds).getRGB());
505 jseq.setId(id); // jseq id should be a string not a number
507 if (av.hasHiddenRows())
509 jseq.setHidden(av.getAlignment().getHiddenSequences().isHidden(jds));
511 if (av.isHiddenRepSequence(jal.getSequenceAt(i)))
513 jalview.datamodel.SequenceI[] reps = av.getRepresentedSequences(
514 jal.getSequenceAt(i)).getSequencesInOrder(jal);
516 for (int h = 0; h < reps.length; h++)
518 if (reps[h] != jal.getSequenceAt(i))
520 jseq.addHiddenSequences(jal.findIndex(reps[h]));
526 if (jds.getDatasetSequence().getSequenceFeatures() != null)
528 jalview.datamodel.SequenceFeature[] sf = jds.getDatasetSequence()
529 .getSequenceFeatures();
531 while (index < sf.length)
533 Features features = new Features();
535 features.setBegin(sf[index].getBegin());
536 features.setEnd(sf[index].getEnd());
537 features.setDescription(sf[index].getDescription());
538 features.setType(sf[index].getType());
539 features.setFeatureGroup(sf[index].getFeatureGroup());
540 features.setScore(sf[index].getScore());
541 if (sf[index].links != null)
543 for (int l = 0; l < sf[index].links.size(); l++)
545 OtherData keyValue = new OtherData();
546 keyValue.setKey("LINK_" + l);
547 keyValue.setValue(sf[index].links.elementAt(l).toString());
548 features.addOtherData(keyValue);
551 if (sf[index].otherDetails != null)
554 Enumeration keys = sf[index].otherDetails.keys();
555 while (keys.hasMoreElements())
557 key = keys.nextElement().toString();
558 OtherData keyValue = new OtherData();
559 keyValue.setKey(key);
560 keyValue.setValue(sf[index].otherDetails.get(key).toString());
561 features.addOtherData(keyValue);
565 jseq.addFeatures(features);
570 if (jds.getDatasetSequence().getPDBId() != null)
572 Enumeration en = jds.getDatasetSequence().getPDBId().elements();
573 while (en.hasMoreElements())
575 Pdbids pdb = new Pdbids();
576 jalview.datamodel.PDBEntry entry = (jalview.datamodel.PDBEntry) en
579 pdb.setId(entry.getId());
580 pdb.setType(entry.getType());
583 // This must have been loaded, is it still visible?
584 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
585 String matchedFile = null;
586 for (int f = frames.length - 1; f > -1; f--)
588 if (frames[f] instanceof AppJmol)
590 jmol = (AppJmol) frames[f];
591 for (int peid = 0; peid < jmol.jmb.pdbentry.length; peid++)
593 if (!jmol.jmb.pdbentry[peid].getId().equals(entry.getId())
594 && !(entry.getId().length() > 4 && entry
598 jmol.jmb.pdbentry[peid].getId()
601 if (matchedFile == null)
603 matchedFile = jmol.jmb.pdbentry[peid].getFile();
605 else if (!matchedFile.equals(jmol.jmb.pdbentry[peid]
609 .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
610 + jmol.jmb.pdbentry[peid].getFile());
614 // can get at it if the ID
615 // match is ambiguous (e.g.
617 String statestring = jmol.jmb.viewer.getStateInfo();
619 for (int smap = 0; smap < jmol.jmb.sequence[peid].length; smap++)
621 // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
622 if (jds == jmol.jmb.sequence[peid][smap])
624 StructureState state = new StructureState();
625 state.setVisible(true);
626 state.setXpos(jmol.getX());
627 state.setYpos(jmol.getY());
628 state.setWidth(jmol.getWidth());
629 state.setHeight(jmol.getHeight());
630 state.setViewId(jmol.getViewId());
631 state.setAlignwithAlignPanel(jmol.isUsedforaligment(ap));
632 state.setColourwithAlignPanel(jmol
633 .isUsedforcolourby(ap));
634 state.setColourByJmol(jmol.isColouredByJmol());
635 if (!jmolViewIds.contains(state.getViewId()))
637 // Make sure we only store a Jmol state once in each XML
639 jmolViewIds.addElement(state.getViewId());
640 state.setContent(statestring.replaceAll("\n", ""));
644 state.setContent("# duplicate state");
646 pdb.addStructureState(state);
653 if (matchedFile != null || entry.getFile() != null)
655 if (entry.getFile() != null)
658 matchedFile = entry.getFile();
660 pdb.setFile(matchedFile); // entry.getFile());
661 if (pdbfiles == null)
663 pdbfiles = new Vector();
666 if (!pdbfiles.contains(entry.getId()))
668 pdbfiles.addElement(entry.getId());
671 File file = new File(matchedFile);
672 if (file.exists() && jout != null)
674 byte[] data = new byte[(int) file.length()];
675 jout.putNextEntry(new JarEntry(entry.getId()));
676 DataInputStream dis = new DataInputStream(
677 new FileInputStream(file));
680 DataOutputStream dout = new DataOutputStream(jout);
681 dout.write(data, 0, data.length);
685 } catch (Exception ex)
687 ex.printStackTrace();
693 if (entry.getProperty() != null)
695 PdbentryItem item = new PdbentryItem();
696 Hashtable properties = entry.getProperty();
697 Enumeration en2 = properties.keys();
698 while (en2.hasMoreElements())
700 Property prop = new Property();
701 String key = en2.nextElement().toString();
703 prop.setValue(properties.get(key).toString());
704 item.addProperty(prop);
706 pdb.addPdbentryItem(item);
716 if (av.hasHiddenRows())
718 jal = av.getAlignment();
721 if (jal.getCodonFrames() != null && jal.getCodonFrames().length > 0)
723 jalview.datamodel.AlignedCodonFrame[] jac = jal.getCodonFrames();
724 for (int i = 0; i < jac.length; i++)
726 AlcodonFrame alc = new AlcodonFrame();
727 vamsasSet.addAlcodonFrame(alc);
728 for (int p = 0; p < jac[i].aaWidth; p++)
730 Alcodon cmap = new Alcodon();
731 if (jac[i].codons[p] != null)
733 // Null codons indicate a gapped column in the translated peptide
735 cmap.setPos1(jac[i].codons[p][0]);
736 cmap.setPos2(jac[i].codons[p][1]);
737 cmap.setPos3(jac[i].codons[p][2]);
739 alc.addAlcodon(cmap);
741 if (jac[i].getProtMappings() != null
742 && jac[i].getProtMappings().length > 0)
744 SequenceI[] dnas = jac[i].getdnaSeqs();
745 jalview.datamodel.Mapping[] pmaps = jac[i].getProtMappings();
746 for (int m = 0; m < pmaps.length; m++)
748 AlcodMap alcmap = new AlcodMap();
749 alcmap.setDnasq(seqHash(dnas[m]));
750 alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
752 alc.addAlcodMap(alcmap);
759 // /////////////////////////////////
760 if (av.currentTree != null)
762 // FIND ANY ASSOCIATED TREES
763 // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
764 if (Desktop.desktop != null)
766 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
768 for (int t = 0; t < frames.length; t++)
770 if (frames[t] instanceof TreePanel)
772 TreePanel tp = (TreePanel) frames[t];
774 if (tp.treeCanvas.av.getAlignment() == jal)
776 Tree tree = new Tree();
777 tree.setTitle(tp.getTitle());
778 tree.setCurrentTree((av.currentTree == tp.getTree()));
779 tree.setNewick(tp.getTree().toString());
780 tree.setThreshold(tp.treeCanvas.threshold);
782 tree.setFitToWindow(tp.fitToWindow.getState());
783 tree.setFontName(tp.getTreeFont().getName());
784 tree.setFontSize(tp.getTreeFont().getSize());
785 tree.setFontStyle(tp.getTreeFont().getStyle());
786 tree.setMarkUnlinked(tp.placeholdersMenu.getState());
788 tree.setShowBootstrap(tp.bootstrapMenu.getState());
789 tree.setShowDistances(tp.distanceMenu.getState());
791 tree.setHeight(tp.getHeight());
792 tree.setWidth(tp.getWidth());
793 tree.setXpos(tp.getX());
794 tree.setYpos(tp.getY());
795 tree.setId(makeHashCode(tp, null));
804 * store forward refs from an annotationRow to any groups
806 IdentityHashMap groupRefs = new IdentityHashMap();
807 if (jal.getAlignmentAnnotation() != null)
809 jalview.datamodel.AlignmentAnnotation[] aa = jal
810 .getAlignmentAnnotation();
812 for (int i = 0; i < aa.length; i++)
814 Annotation an = new Annotation();
816 if (aa[i].annotationId != null)
818 annotationIds.put(aa[i].annotationId, aa[i]);
821 an.setId(aa[i].annotationId);
823 an.setVisible(aa[i].visible);
825 an.setDescription(aa[i].description);
827 if (aa[i].sequenceRef != null)
829 // TODO later annotation sequenceRef should be the XML ID of the
830 // sequence rather than its display name
831 an.setSequenceRef(aa[i].sequenceRef.getName());
833 if (aa[i].groupRef != null)
835 Object groupIdr = groupRefs.get(aa[i].groupRef);
836 if (groupIdr == null)
838 // make a locally unique String
839 groupRefs.put(aa[i].groupRef,
840 groupIdr = ("" + System.currentTimeMillis()
841 + aa[i].groupRef.getName() + groupRefs.size()));
843 an.setGroupRef(groupIdr.toString());
846 // store all visualization attributes for annotation
847 an.setGraphHeight(aa[i].graphHeight);
848 an.setCentreColLabels(aa[i].centreColLabels);
849 an.setScaleColLabels(aa[i].scaleColLabel);
850 an.setShowAllColLabels(aa[i].showAllColLabels);
851 an.setBelowAlignment(aa[i].belowAlignment);
856 an.setGraphType(aa[i].graph);
857 an.setGraphGroup(aa[i].graphGroup);
858 if (aa[i].getThreshold() != null)
860 ThresholdLine line = new ThresholdLine();
861 line.setLabel(aa[i].getThreshold().label);
862 line.setValue(aa[i].getThreshold().value);
863 line.setColour(aa[i].getThreshold().colour.getRGB());
864 an.setThresholdLine(line);
872 an.setLabel(aa[i].label);
874 if (aa[i] == av.getAlignmentQualityAnnot()
875 || aa[i] == av.getAlignmentConservationAnnotation()
876 || aa[i] == av.getAlignmentConsensusAnnotation()
877 || aa[i].autoCalculated)
879 // new way of indicating autocalculated annotation -
880 an.setAutoCalculated(aa[i].autoCalculated);
882 if (aa[i].hasScore())
884 an.setScore(aa[i].getScore());
887 if (aa[i].getCalcId() != null)
889 calcIdSet.add(aa[i].getCalcId());
890 an.setCalcId(aa[i].getCalcId());
893 AnnotationElement ae;
894 if (aa[i].annotations != null)
896 an.setScoreOnly(false);
897 for (int a = 0; a < aa[i].annotations.length; a++)
899 if ((aa[i] == null) || (aa[i].annotations[a] == null))
904 ae = new AnnotationElement();
905 if (aa[i].annotations[a].description != null)
906 ae.setDescription(aa[i].annotations[a].description);
907 if (aa[i].annotations[a].displayCharacter != null)
908 ae.setDisplayCharacter(aa[i].annotations[a].displayCharacter);
910 if (!Float.isNaN(aa[i].annotations[a].value))
911 ae.setValue(aa[i].annotations[a].value);
914 if (aa[i].annotations[a].secondaryStructure != ' '
915 && aa[i].annotations[a].secondaryStructure != '\0')
916 ae.setSecondaryStructure(aa[i].annotations[a].secondaryStructure
919 if (aa[i].annotations[a].colour != null
920 && aa[i].annotations[a].colour != java.awt.Color.black)
922 ae.setColour(aa[i].annotations[a].colour.getRGB());
925 an.addAnnotationElement(ae);
926 if (aa[i].autoCalculated)
928 // only write one non-null entry into the annotation row -
929 // sufficient to get the visualization attributes necessary to
937 an.setScoreOnly(true);
939 vamsasSet.addAnnotation(an);
943 if (jal.getGroups() != null)
945 JGroup[] groups = new JGroup[jal.getGroups().size()];
947 for (jalview.datamodel.SequenceGroup sg : jal.getGroups())
949 groups[++i] = new JGroup();
951 groups[i].setStart(sg.getStartRes());
952 groups[i].setEnd(sg.getEndRes());
953 groups[i].setName(sg.getName());
954 if (groupRefs.containsKey(sg))
956 // group has references so set it's ID field
957 groups[i].setId(groupRefs.get(sg).toString());
961 if (sg.cs.conservationApplied())
963 groups[i].setConsThreshold(sg.cs.getConservationInc());
965 if (sg.cs instanceof jalview.schemes.UserColourScheme)
967 groups[i].setColour(SetUserColourScheme(sg.cs, userColours,
973 .setColour(ColourSchemeProperty.getColourName(sg.cs));
976 else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient)
979 .setColour(ColourSchemeProperty
980 .getColourName(((jalview.schemes.AnnotationColourGradient) sg.cs)
983 else if (sg.cs instanceof jalview.schemes.UserColourScheme)
986 .setColour(SetUserColourScheme(sg.cs, userColours, jms));
990 groups[i].setColour(ColourSchemeProperty.getColourName(sg.cs));
993 groups[i].setPidThreshold(sg.cs.getThreshold());
996 groups[i].setOutlineColour(sg.getOutlineColour().getRGB());
997 groups[i].setDisplayBoxes(sg.getDisplayBoxes());
998 groups[i].setDisplayText(sg.getDisplayText());
999 groups[i].setColourText(sg.getColourText());
1000 groups[i].setTextCol1(sg.textColour.getRGB());
1001 groups[i].setTextCol2(sg.textColour2.getRGB());
1002 groups[i].setTextColThreshold(sg.thresholdTextColour);
1003 groups[i].setShowUnconserved(sg.getShowNonconserved());
1004 groups[i].setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
1005 groups[i].setShowConsensusHistogram(sg.isShowConsensusHistogram());
1006 groups[i].setShowSequenceLogo(sg.isShowSequenceLogo());
1007 groups[i].setNormaliseSequenceLogo(sg.isNormaliseSequenceLogo());
1008 for (int s = 0; s < sg.getSize(); s++)
1010 jalview.datamodel.Sequence seq = (jalview.datamodel.Sequence) sg
1012 groups[i].addSeq(seqHash(seq));
1016 jms.setJGroup(groups);
1019 // /////////SAVE VIEWPORT
1020 Viewport view = new Viewport();
1021 view.setTitle(ap.alignFrame.getTitle());
1022 view.setSequenceSetId(makeHashCode(av.getSequenceSetId(),
1023 av.getSequenceSetId()));
1024 view.setId(av.getViewId());
1025 view.setViewName(av.viewName);
1026 view.setGatheredViews(av.gatherViewsHere);
1028 if (ap.av.explodedPosition != null)
1030 view.setXpos(av.explodedPosition.x);
1031 view.setYpos(av.explodedPosition.y);
1032 view.setWidth(av.explodedPosition.width);
1033 view.setHeight(av.explodedPosition.height);
1037 view.setXpos(ap.alignFrame.getBounds().x);
1038 view.setYpos(ap.alignFrame.getBounds().y);
1039 view.setWidth(ap.alignFrame.getBounds().width);
1040 view.setHeight(ap.alignFrame.getBounds().height);
1043 view.setStartRes(av.startRes);
1044 view.setStartSeq(av.startSeq);
1046 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1048 view.setBgColour(SetUserColourScheme(av.getGlobalColourScheme(),
1051 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1053 jalview.schemes.AnnotationColourGradient acg = (jalview.schemes.AnnotationColourGradient) av
1054 .getGlobalColourScheme();
1056 AnnotationColours ac = new AnnotationColours();
1057 ac.setAboveThreshold(acg.getAboveThreshold());
1058 ac.setThreshold(acg.getAnnotationThreshold());
1059 ac.setAnnotation(acg.getAnnotation());
1060 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1062 ac.setColourScheme(SetUserColourScheme(acg.getBaseColour(),
1067 ac.setColourScheme(ColourSchemeProperty.getColourName(acg
1071 ac.setMaxColour(acg.getMaxColour().getRGB());
1072 ac.setMinColour(acg.getMinColour().getRGB());
1073 view.setAnnotationColours(ac);
1074 view.setBgColour("AnnotationColourGradient");
1078 view.setBgColour(ColourSchemeProperty.getColourName(av
1079 .getGlobalColourScheme()));
1082 ColourSchemeI cs = av.getGlobalColourScheme();
1086 if (cs.conservationApplied())
1088 view.setConsThreshold(cs.getConservationInc());
1089 if (cs instanceof jalview.schemes.UserColourScheme)
1091 view.setBgColour(SetUserColourScheme(cs, userColours, jms));
1095 if (cs instanceof ResidueColourScheme)
1097 view.setPidThreshold(cs.getThreshold());
1101 view.setConservationSelected(av.getConservationSelected());
1102 view.setPidSelected(av.getAbovePIDThreshold());
1103 view.setFontName(av.font.getName());
1104 view.setFontSize(av.font.getSize());
1105 view.setFontStyle(av.font.getStyle());
1106 view.setRenderGaps(av.renderGaps);
1107 view.setShowAnnotation(av.getShowAnnotation());
1108 view.setShowBoxes(av.getShowBoxes());
1109 view.setShowColourText(av.getColourText());
1110 view.setShowFullId(av.getShowJVSuffix());
1111 view.setRightAlignIds(av.rightAlignIds);
1112 view.setShowSequenceFeatures(av.showSequenceFeatures);
1113 view.setShowText(av.getShowText());
1114 view.setShowUnconserved(av.getShowUnconserved());
1115 view.setWrapAlignment(av.getWrapAlignment());
1116 view.setTextCol1(av.textColour.getRGB());
1117 view.setTextCol2(av.textColour2.getRGB());
1118 view.setTextColThreshold(av.thresholdTextColour);
1119 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1120 view.setShowSequenceLogo(av.isShowSequenceLogo());
1121 view.setNormaliseSequenceLogo(av.isNormaliseSequenceLogo());
1122 view.setShowGroupConsensus(av.isShowGroupConsensus());
1123 view.setShowGroupConservation(av.isShowGroupConservation());
1124 view.setShowNPfeatureTooltip(av.isShowNpFeats());
1125 view.setShowDbRefTooltip(av.isShowDbRefs());
1126 view.setFollowHighlight(av.followHighlight);
1127 view.setFollowSelection(av.followSelection);
1128 view.setIgnoreGapsinConsensus(av.getIgnoreGapsConsensus());
1129 if (av.featuresDisplayed != null)
1131 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1133 String[] renderOrder = ap.seqPanel.seqCanvas.getFeatureRenderer().renderOrder;
1135 Vector settingsAdded = new Vector();
1136 Object gstyle = null;
1137 GraduatedColor gcol = null;
1138 if (renderOrder != null)
1140 for (int ro = 0; ro < renderOrder.length; ro++)
1142 gstyle = ap.seqPanel.seqCanvas.getFeatureRenderer()
1143 .getFeatureStyle(renderOrder[ro]);
1144 Setting setting = new Setting();
1145 setting.setType(renderOrder[ro]);
1146 if (gstyle instanceof GraduatedColor)
1148 gcol = (GraduatedColor) gstyle;
1149 setting.setColour(gcol.getMaxColor().getRGB());
1150 setting.setMincolour(gcol.getMinColor().getRGB());
1151 setting.setMin(gcol.getMin());
1152 setting.setMax(gcol.getMax());
1153 setting.setColourByLabel(gcol.isColourByLabel());
1154 setting.setAutoScale(gcol.isAutoScale());
1155 setting.setThreshold(gcol.getThresh());
1156 setting.setThreshstate(gcol.getThreshType());
1160 setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer()
1161 .getColour(renderOrder[ro]).getRGB());
1164 setting.setDisplay(av.featuresDisplayed
1165 .containsKey(renderOrder[ro]));
1166 float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer()
1167 .getOrder(renderOrder[ro]);
1170 setting.setOrder(rorder);
1172 fs.addSetting(setting);
1173 settingsAdded.addElement(renderOrder[ro]);
1177 // Make sure we save none displayed feature settings
1178 Iterator en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureColours
1179 .keySet().iterator();
1180 while (en.hasNext())
1182 String key = en.next().toString();
1183 if (settingsAdded.contains(key))
1188 Setting setting = new Setting();
1189 setting.setType(key);
1190 setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer()
1191 .getColour(key).getRGB());
1193 setting.setDisplay(false);
1194 float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer().getOrder(
1198 setting.setOrder(rorder);
1200 fs.addSetting(setting);
1201 settingsAdded.addElement(key);
1203 en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups
1204 .keySet().iterator();
1205 Vector groupsAdded = new Vector();
1206 while (en.hasNext())
1208 String grp = en.next().toString();
1209 if (groupsAdded.contains(grp))
1213 Group g = new Group();
1215 g.setDisplay(((Boolean) ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups
1216 .get(grp)).booleanValue());
1218 groupsAdded.addElement(grp);
1220 jms.setFeatureSettings(fs);
1224 if (av.hasHiddenColumns())
1226 if (av.getColumnSelection() == null
1227 || av.getColumnSelection().getHiddenColumns() == null)
1229 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1233 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1236 int[] region = (int[]) av.getColumnSelection().getHiddenColumns()
1238 HiddenColumns hc = new HiddenColumns();
1239 hc.setStart(region[0]);
1240 hc.setEnd(region[1]);
1241 view.addHiddenColumns(hc);
1245 if (calcIdSet.size() > 0)
1247 for (String calcId : calcIdSet)
1249 if (calcId.trim().length() > 0)
1251 CalcIdParam cidp = createCalcIdParam(calcId, av);
1252 // Some calcIds have no parameters.
1255 view.addCalcIdParam(cidp);
1261 jms.addViewport(view);
1263 object.setJalviewModelSequence(jms);
1264 object.getVamsasModel().addSequenceSet(vamsasSet);
1266 if (jout != null && fileName != null)
1268 // We may not want to write the object to disk,
1269 // eg we can copy the alignViewport to a new view object
1270 // using save and then load
1273 JarEntry entry = new JarEntry(fileName);
1274 jout.putNextEntry(entry);
1275 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1277 org.exolab.castor.xml.Marshaller marshaller = new org.exolab.castor.xml.Marshaller(
1279 marshaller.marshal(object);
1282 } catch (Exception ex)
1284 // TODO: raise error in GUI if marshalling failed.
1285 ex.printStackTrace();
1291 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1293 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1294 if (settings != null)
1296 CalcIdParam vCalcIdParam = new CalcIdParam();
1297 vCalcIdParam.setCalcId(calcId);
1298 vCalcIdParam.addServiceURL(settings.getServiceURI());
1299 // generic URI allowing a third party to resolve another instance of the
1300 // service used for this calculation
1301 for (String urls : settings.getServiceURLs())
1303 vCalcIdParam.addServiceURL(urls);
1305 vCalcIdParam.setVersion("1.0");
1306 if (settings.getPreset() != null)
1308 WsParamSetI setting = settings.getPreset();
1309 vCalcIdParam.setName(setting.getName());
1310 vCalcIdParam.setDescription(setting.getDescription());
1314 vCalcIdParam.setName("");
1315 vCalcIdParam.setDescription("Last used parameters");
1317 // need to be able to recover 1) settings 2) user-defined presets or
1318 // recreate settings from preset 3) predefined settings provided by
1319 // service - or settings that can be transferred (or discarded)
1320 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1322 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1323 // todo - decide if updateImmediately is needed for any projects.
1325 return vCalcIdParam;
1330 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1333 if (calcIdParam.getVersion().equals("1.0"))
1335 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1336 .getPreferredServiceFor(calcIdParam.getServiceURL());
1337 if (service != null)
1339 WsParamSetI parmSet = null;
1342 parmSet = service.getParamStore().parseServiceParameterFile(
1343 calcIdParam.getName(), calcIdParam.getDescription(),
1344 calcIdParam.getServiceURL(),
1345 calcIdParam.getParameters().replace("|\\n|", "\n"));
1346 } catch (IOException x)
1348 warn("Couldn't parse parameter data for "
1349 + calcIdParam.getCalcId(), x);
1352 List<ArgumentI> argList = null;
1353 if (calcIdParam.getName().length() > 0)
1355 parmSet = service.getParamStore()
1356 .getPreset(calcIdParam.getName());
1357 if (parmSet != null)
1359 // TODO : check we have a good match with settings in AACon -
1360 // otherwise we'll need to create a new preset
1365 argList = parmSet.getArguments();
1368 AAConSettings settings = new AAConSettings(
1369 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1370 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1371 calcIdParam.isNeedsUpdate());
1376 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1380 throw new Error("Unsupported Version for calcIdparam "
1381 + calcIdParam.toString());
1385 * External mapping between jalview objects and objects yielding a valid and
1386 * unique object ID string. This is null for normal Jalview project IO, but
1387 * non-null when a jalview project is being read or written as part of a
1390 IdentityHashMap jv2vobj = null;
1393 * Construct a unique ID for jvobj using either existing bindings or if none
1394 * exist, the result of the hashcode call for the object.
1397 * jalview data object
1398 * @return unique ID for referring to jvobj
1400 private String makeHashCode(Object jvobj, String altCode)
1402 if (jv2vobj != null)
1404 Object id = jv2vobj.get(jvobj);
1407 return id.toString();
1409 // check string ID mappings
1410 if (jvids2vobj != null && jvobj instanceof String)
1412 id = jvids2vobj.get(jvobj);
1416 return id.toString();
1418 // give up and warn that something has gone wrong
1419 warn("Cannot find ID for object in external mapping : " + jvobj);
1425 * return local jalview object mapped to ID, if it exists
1429 * @return null or object bound to idcode
1431 private Object retrieveExistingObj(String idcode)
1433 if (idcode != null && vobj2jv != null)
1435 return vobj2jv.get(idcode);
1441 * binding from ID strings from external mapping table to jalview data model
1444 private Hashtable vobj2jv;
1446 private Sequence createVamsasSequence(String id, SequenceI jds)
1448 return createVamsasSequence(true, id, jds, null);
1451 private Sequence createVamsasSequence(boolean recurse, String id,
1452 SequenceI jds, SequenceI parentseq)
1454 Sequence vamsasSeq = new Sequence();
1455 vamsasSeq.setId(id);
1456 vamsasSeq.setName(jds.getName());
1457 vamsasSeq.setSequence(jds.getSequenceAsString());
1458 vamsasSeq.setDescription(jds.getDescription());
1459 jalview.datamodel.DBRefEntry[] dbrefs = null;
1460 if (jds.getDatasetSequence() != null)
1462 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
1463 if (jds.getDatasetSequence().getDBRef() != null)
1465 dbrefs = jds.getDatasetSequence().getDBRef();
1470 vamsasSeq.setDsseqid(id); // so we can tell which sequences really are
1471 // dataset sequences only
1472 dbrefs = jds.getDBRef();
1476 for (int d = 0; d < dbrefs.length; d++)
1478 DBRef dbref = new DBRef();
1479 dbref.setSource(dbrefs[d].getSource());
1480 dbref.setVersion(dbrefs[d].getVersion());
1481 dbref.setAccessionId(dbrefs[d].getAccessionId());
1482 if (dbrefs[d].hasMap())
1484 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
1486 dbref.setMapping(mp);
1488 vamsasSeq.addDBRef(dbref);
1494 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
1495 SequenceI parentseq, SequenceI jds, boolean recurse)
1498 if (jmp.getMap() != null)
1502 jalview.util.MapList mlst = jmp.getMap();
1503 int r[] = mlst.getFromRanges();
1504 for (int s = 0; s < r.length; s += 2)
1506 MapListFrom mfrom = new MapListFrom();
1507 mfrom.setStart(r[s]);
1508 mfrom.setEnd(r[s + 1]);
1509 mp.addMapListFrom(mfrom);
1511 r = mlst.getToRanges();
1512 for (int s = 0; s < r.length; s += 2)
1514 MapListTo mto = new MapListTo();
1516 mto.setEnd(r[s + 1]);
1517 mp.addMapListTo(mto);
1519 mp.setMapFromUnit(mlst.getFromRatio());
1520 mp.setMapToUnit(mlst.getToRatio());
1521 if (jmp.getTo() != null)
1523 MappingChoice mpc = new MappingChoice();
1525 && (parentseq != jmp.getTo() || parentseq
1526 .getDatasetSequence() != jmp.getTo()))
1528 mpc.setSequence(createVamsasSequence(false, seqHash(jmp.getTo()),
1534 SequenceI ps = null;
1535 if (parentseq != jmp.getTo()
1536 && parentseq.getDatasetSequence() != jmp.getTo())
1538 // chaining dbref rather than a handshaking one
1539 jmpid = seqHash(ps = jmp.getTo());
1543 jmpid = seqHash(ps = parentseq);
1545 mpc.setDseqFor(jmpid);
1546 if (!seqRefIds.containsKey(mpc.getDseqFor()))
1548 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
1549 seqRefIds.put(mpc.getDseqFor(), ps);
1553 jalview.bin.Cache.log.debug("reusing DseqFor ID");
1556 mp.setMappingChoice(mpc);
1562 String SetUserColourScheme(jalview.schemes.ColourSchemeI cs,
1563 Vector userColours, JalviewModelSequence jms)
1566 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
1567 boolean newucs = false;
1568 if (!userColours.contains(ucs))
1570 userColours.add(ucs);
1573 id = "ucs" + userColours.indexOf(ucs);
1576 // actually create the scheme's entry in the XML model
1577 java.awt.Color[] colours = ucs.getColours();
1578 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
1579 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
1581 for (int i = 0; i < colours.length; i++)
1583 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1584 col.setName(ResidueProperties.aa[i]);
1585 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1586 jbucs.addColour(col);
1588 if (ucs.getLowerCaseColours() != null)
1590 colours = ucs.getLowerCaseColours();
1591 for (int i = 0; i < colours.length; i++)
1593 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1594 col.setName(ResidueProperties.aa[i].toLowerCase());
1595 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1596 jbucs.addColour(col);
1601 uc.setUserColourScheme(jbucs);
1602 jms.addUserColours(uc);
1608 jalview.schemes.UserColourScheme GetUserColourScheme(
1609 JalviewModelSequence jms, String id)
1611 UserColours[] uc = jms.getUserColours();
1612 UserColours colours = null;
1614 for (int i = 0; i < uc.length; i++)
1616 if (uc[i].getId().equals(id))
1624 java.awt.Color[] newColours = new java.awt.Color[24];
1626 for (int i = 0; i < 24; i++)
1628 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1629 .getUserColourScheme().getColour(i).getRGB(), 16));
1632 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
1635 if (colours.getUserColourScheme().getColourCount() > 24)
1637 newColours = new java.awt.Color[23];
1638 for (int i = 0; i < 23; i++)
1640 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1641 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
1643 ucs.setLowerCaseColours(newColours);
1650 * contains last error message (if any) encountered by XML loader.
1652 String errorMessage = null;
1655 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
1656 * exceptions are raised during project XML parsing
1658 public boolean attemptversion1parse = true;
1661 * Load a jalview project archive from a jar file
1664 * - HTTP URL or filename
1666 public AlignFrame LoadJalviewAlign(final String file)
1669 jalview.gui.AlignFrame af = null;
1673 // create list to store references for any new Jmol viewers created
1674 newStructureViewers=new Vector<AppJmol>();
1675 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
1676 // Workaround is to make sure caller implements the JarInputStreamProvider
1678 // so we can re-open the jar input stream for each entry.
1680 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
1681 af = LoadJalviewAlign(jprovider);
1682 setLoadingFinishedForNewStructureViewers();
1683 } catch (MalformedURLException e)
1685 errorMessage = "Invalid URL format for '" + file + "'";
1691 private jarInputStreamProvider createjarInputStreamProvider(
1692 final String file) throws MalformedURLException
1695 errorMessage = null;
1696 uniqueSetSuffix = null;
1698 viewportsAdded = null;
1699 frefedSequence = null;
1701 if (file.startsWith("http://"))
1703 url = new URL(file);
1705 final URL _url = url;
1706 return new jarInputStreamProvider()
1710 public JarInputStream getJarInputStream() throws IOException
1714 return new JarInputStream(_url.openStream());
1718 return new JarInputStream(new FileInputStream(file));
1723 public String getFilename()
1731 * Recover jalview session from a jalview project archive. Caller may
1732 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
1733 * themselves. Any null fields will be initialised with default values,
1734 * non-null fields are left alone.
1739 public AlignFrame LoadJalviewAlign(final jarInputStreamProvider jprovider)
1741 errorMessage = null;
1742 if (uniqueSetSuffix == null)
1744 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
1746 if (seqRefIds == null)
1748 seqRefIds = new Hashtable();
1750 if (viewportsAdded == null)
1752 viewportsAdded = new Hashtable();
1754 if (frefedSequence == null)
1756 frefedSequence = new Vector();
1759 jalview.gui.AlignFrame af = null;
1760 Hashtable gatherToThisFrame = new Hashtable();
1761 final String file = jprovider.getFilename();
1764 JarInputStream jin = null;
1765 JarEntry jarentry = null;
1770 jin = jprovider.getJarInputStream();
1771 for (int i = 0; i < entryCount; i++)
1773 jarentry = jin.getNextJarEntry();
1776 if (jarentry != null && jarentry.getName().endsWith(".xml"))
1778 InputStreamReader in = new InputStreamReader(jin, "UTF-8");
1779 JalviewModel object = new JalviewModel();
1781 Unmarshaller unmar = new Unmarshaller(object);
1782 unmar.setValidation(false);
1783 object = (JalviewModel) unmar.unmarshal(in);
1784 if (true) // !skipViewport(object))
1786 af = LoadFromObject(object, file, true, jprovider);
1787 if (af.viewport.gatherViewsHere)
1789 gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
1794 else if (jarentry != null)
1796 // Some other file here.
1799 } while (jarentry != null);
1800 resolveFrefedSequences();
1801 } catch (java.io.FileNotFoundException ex)
1803 ex.printStackTrace();
1804 errorMessage = "Couldn't locate Jalview XML file : " + file;
1805 System.err.println("Exception whilst loading jalview XML file : "
1807 } catch (java.net.UnknownHostException ex)
1809 ex.printStackTrace();
1810 errorMessage = "Couldn't locate Jalview XML file : " + file;
1811 System.err.println("Exception whilst loading jalview XML file : "
1813 } catch (Exception ex)
1815 System.err.println("Parsing as Jalview Version 2 file failed.");
1816 ex.printStackTrace(System.err);
1817 if (attemptversion1parse)
1819 // Is Version 1 Jar file?
1822 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
1823 } catch (Exception ex2)
1825 System.err.println("Exception whilst loading as jalviewXMLV1:");
1826 ex2.printStackTrace();
1830 if (Desktop.instance != null)
1832 Desktop.instance.stopLoading();
1836 System.out.println("Successfully loaded archive file");
1839 ex.printStackTrace();
1841 System.err.println("Exception whilst loading jalview XML file : "
1843 } catch (OutOfMemoryError e)
1845 // Don't use the OOM Window here
1846 errorMessage = "Out of memory loading jalview XML file";
1847 System.err.println("Out of memory whilst loading jalview XML file");
1848 e.printStackTrace();
1851 if (Desktop.instance != null)
1853 Desktop.instance.stopLoading();
1856 Enumeration en = gatherToThisFrame.elements();
1857 while (en.hasMoreElements())
1859 Desktop.instance.gatherViews((AlignFrame) en.nextElement());
1861 if (errorMessage != null)
1869 * check errorMessage for a valid error message and raise an error box in the
1870 * GUI or write the current errorMessage to stderr and then clear the error
1873 protected void reportErrors()
1875 reportErrors(false);
1878 protected void reportErrors(final boolean saving)
1880 if (errorMessage != null)
1882 final String finalErrorMessage = errorMessage;
1885 javax.swing.SwingUtilities.invokeLater(new Runnable()
1890 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1891 finalErrorMessage, "Error "
1892 + (saving ? "saving" : "loading")
1893 + " Jalview file", JOptionPane.WARNING_MESSAGE);
1899 System.err.println("Problem loading Jalview file: " + errorMessage);
1902 errorMessage = null;
1905 Hashtable alreadyLoadedPDB;
1908 * when set, local views will be updated from view stored in JalviewXML
1909 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
1910 * sync if this is set to true.
1912 private final boolean updateLocalViews = false;
1914 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
1916 if (alreadyLoadedPDB == null)
1917 alreadyLoadedPDB = new Hashtable();
1919 if (alreadyLoadedPDB.containsKey(pdbId))
1920 return alreadyLoadedPDB.get(pdbId).toString();
1924 JarInputStream jin = jprovider.getJarInputStream();
1926 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
1927 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
1928 * FileInputStream(jprovider)); }
1931 JarEntry entry = null;
1934 entry = jin.getNextJarEntry();
1935 } while (entry != null && !entry.getName().equals(pdbId));
1938 BufferedReader in = new BufferedReader(new InputStreamReader(jin));
1939 File outFile = File.createTempFile("jalview_pdb", ".txt");
1940 outFile.deleteOnExit();
1941 PrintWriter out = new PrintWriter(new FileOutputStream(outFile));
1944 while ((data = in.readLine()) != null)
1951 } catch (Exception foo)
1956 String t = outFile.getAbsolutePath();
1957 alreadyLoadedPDB.put(pdbId, t);
1962 warn("Couldn't find PDB file entry in Jalview Jar for " + pdbId);
1964 } catch (Exception ex)
1966 ex.printStackTrace();
1972 private class JvAnnotRow
1974 public JvAnnotRow(int i, AlignmentAnnotation jaa)
1981 * persisted version of annotation row from which to take vis properties
1983 public jalview.datamodel.AlignmentAnnotation template;
1986 * original position of the annotation row in the alignment
1992 * Load alignment frame from jalview XML DOM object
1997 * filename source string
1998 * @param loadTreesAndStructures
1999 * when false only create Viewport
2001 * data source provider
2002 * @return alignment frame created from view stored in DOM
2004 AlignFrame LoadFromObject(JalviewModel object, String file,
2005 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2007 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2008 Sequence[] vamsasSeq = vamsasSet.getSequence();
2010 JalviewModelSequence jms = object.getJalviewModelSequence();
2012 Viewport view = jms.getViewport(0);
2013 // ////////////////////////////////
2016 Vector hiddenSeqs = null;
2017 jalview.datamodel.Sequence jseq;
2019 ArrayList tmpseqs = new ArrayList();
2021 boolean multipleView = false;
2023 JSeq[] JSEQ = object.getJalviewModelSequence().getJSeq();
2024 int vi = 0; // counter in vamsasSeq array
2025 for (int i = 0; i < JSEQ.length; i++)
2027 String seqId = JSEQ[i].getId();
2029 if (seqRefIds.get(seqId) != null)
2031 tmpseqs.add(seqRefIds.get(seqId));
2032 multipleView = true;
2036 jseq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2037 vamsasSeq[vi].getSequence());
2038 jseq.setDescription(vamsasSeq[vi].getDescription());
2039 jseq.setStart(JSEQ[i].getStart());
2040 jseq.setEnd(JSEQ[i].getEnd());
2041 jseq.setVamsasId(uniqueSetSuffix + seqId);
2042 seqRefIds.put(vamsasSeq[vi].getId(), jseq);
2047 if (JSEQ[i].getHidden())
2049 if (hiddenSeqs == null)
2051 hiddenSeqs = new Vector();
2054 hiddenSeqs.addElement(seqRefIds.get(seqId));
2060 // Create the alignment object from the sequence set
2061 // ///////////////////////////////
2062 jalview.datamodel.Sequence[] orderedSeqs = new jalview.datamodel.Sequence[tmpseqs
2065 tmpseqs.toArray(orderedSeqs);
2067 jalview.datamodel.Alignment al = new jalview.datamodel.Alignment(
2070 // / Add the alignment properties
2071 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2073 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2074 al.setProperty(ssp.getKey(), ssp.getValue());
2078 // SequenceFeatures are added to the DatasetSequence,
2079 // so we must create or recover the dataset before loading features
2080 // ///////////////////////////////
2081 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2083 // older jalview projects do not have a dataset id.
2084 al.setDataset(null);
2088 recoverDatasetFor(vamsasSet, al);
2090 // ///////////////////////////////
2092 Hashtable pdbloaded = new Hashtable();
2095 // load sequence features, database references and any associated PDB
2096 // structures for the alignment
2097 for (int i = 0; i < vamsasSeq.length; i++)
2099 if (JSEQ[i].getFeaturesCount() > 0)
2101 Features[] features = JSEQ[i].getFeatures();
2102 for (int f = 0; f < features.length; f++)
2104 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2105 features[f].getType(), features[f].getDescription(),
2106 features[f].getStatus(), features[f].getBegin(),
2107 features[f].getEnd(), features[f].getFeatureGroup());
2109 sf.setScore(features[f].getScore());
2110 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2112 OtherData keyValue = features[f].getOtherData(od);
2113 if (keyValue.getKey().startsWith("LINK"))
2115 sf.addLink(keyValue.getValue());
2119 sf.setValue(keyValue.getKey(), keyValue.getValue());
2124 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
2127 if (vamsasSeq[i].getDBRefCount() > 0)
2129 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2131 if (JSEQ[i].getPdbidsCount() > 0)
2133 Pdbids[] ids = JSEQ[i].getPdbids();
2134 for (int p = 0; p < ids.length; p++)
2136 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2137 entry.setId(ids[p].getId());
2138 entry.setType(ids[p].getType());
2139 if (ids[p].getFile() != null)
2141 if (!pdbloaded.containsKey(ids[p].getFile()))
2143 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2147 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2151 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2155 } // end !multipleview
2157 // ///////////////////////////////
2158 // LOAD SEQUENCE MAPPINGS
2160 if (vamsasSet.getAlcodonFrameCount() > 0)
2162 // TODO Potentially this should only be done once for all views of an
2164 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2165 for (int i = 0; i < alc.length; i++)
2167 jalview.datamodel.AlignedCodonFrame cf = new jalview.datamodel.AlignedCodonFrame(
2168 alc[i].getAlcodonCount());
2169 if (alc[i].getAlcodonCount() > 0)
2171 Alcodon[] alcods = alc[i].getAlcodon();
2172 for (int p = 0; p < cf.codons.length; p++)
2174 if (alcods[p].hasPos1() && alcods[p].hasPos2()
2175 && alcods[p].hasPos3())
2177 // translated codons require three valid positions
2178 cf.codons[p] = new int[3];
2179 cf.codons[p][0] = (int) alcods[p].getPos1();
2180 cf.codons[p][1] = (int) alcods[p].getPos2();
2181 cf.codons[p][2] = (int) alcods[p].getPos3();
2185 cf.codons[p] = null;
2189 if (alc[i].getAlcodMapCount() > 0)
2191 AlcodMap[] maps = alc[i].getAlcodMap();
2192 for (int m = 0; m < maps.length; m++)
2194 SequenceI dnaseq = (SequenceI) seqRefIds
2195 .get(maps[m].getDnasq());
2197 jalview.datamodel.Mapping mapping = null;
2198 // attach to dna sequence reference.
2199 if (maps[m].getMapping() != null)
2201 mapping = addMapping(maps[m].getMapping());
2205 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
2210 frefedSequence.add(new Object[]
2211 { maps[m].getDnasq(), cf, mapping });
2215 al.addCodonFrame(cf);
2220 // ////////////////////////////////
2222 ArrayList<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
2224 * store any annotations which forward reference a group's ID
2226 Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>>();
2228 if (vamsasSet.getAnnotationCount() > 0)
2230 Annotation[] an = vamsasSet.getAnnotation();
2232 for (int i = 0; i < an.length; i++)
2235 * test if annotation is automatically calculated for this view only
2237 boolean autoForView = false;
2238 if (an[i].getLabel().equals("Quality")
2239 || an[i].getLabel().equals("Conservation")
2240 || an[i].getLabel().equals("Consensus"))
2242 // Kludge for pre 2.5 projects which lacked the autocalculated flag
2244 if (!an[i].hasAutoCalculated())
2246 an[i].setAutoCalculated(true);
2250 || (an[i].hasAutoCalculated() && an[i].isAutoCalculated()))
2252 // remove ID - we don't recover annotation from other views for
2253 // view-specific annotation
2257 // set visiblity for other annotation in this view
2258 if (an[i].getId() != null
2259 && annotationIds.containsKey(an[i].getId()))
2261 jalview.datamodel.AlignmentAnnotation jda = (jalview.datamodel.AlignmentAnnotation) annotationIds
2262 .get(an[i].getId());
2263 // in principle Visible should always be true for annotation displayed
2264 // in multiple views
2265 if (an[i].hasVisible())
2266 jda.visible = an[i].getVisible();
2268 al.addAnnotation(jda);
2272 // Construct new annotation from model.
2273 AnnotationElement[] ae = an[i].getAnnotationElement();
2274 jalview.datamodel.Annotation[] anot = null;
2275 java.awt.Color firstColour = null;
2277 if (!an[i].getScoreOnly())
2279 anot = new jalview.datamodel.Annotation[al.getWidth()];
2280 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
2282 anpos = ae[aa].getPosition();
2284 if (anpos >= anot.length)
2287 anot[anpos] = new jalview.datamodel.Annotation(
2289 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
2290 (ae[aa].getSecondaryStructure() == null || ae[aa]
2291 .getSecondaryStructure().length() == 0) ? ' '
2292 : ae[aa].getSecondaryStructure().charAt(0),
2296 // JBPNote: Consider verifying dataflow for IO of secondary
2297 // structure annotation read from Stockholm files
2298 // this was added to try to ensure that
2299 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
2301 // anot[ae[aa].getPosition()].displayCharacter = "";
2303 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
2304 if (firstColour == null)
2306 firstColour = anot[anpos].colour;
2310 jalview.datamodel.AlignmentAnnotation jaa = null;
2312 if (an[i].getGraph())
2314 float llim = 0, hlim = 0;
2315 // if (autoForView || an[i].isAutoCalculated()) {
2318 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2319 an[i].getDescription(), anot, llim, hlim,
2320 an[i].getGraphType());
2322 jaa.graphGroup = an[i].getGraphGroup();
2323 jaa._linecolour = firstColour;
2324 if (an[i].getThresholdLine() != null)
2326 jaa.setThreshold(new jalview.datamodel.GraphLine(an[i]
2327 .getThresholdLine().getValue(), an[i]
2328 .getThresholdLine().getLabel(), new java.awt.Color(
2329 an[i].getThresholdLine().getColour())));
2332 if (autoForView || an[i].isAutoCalculated())
2334 // Hardwire the symbol display line to ensure that labels for
2335 // histograms are displayed
2341 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2342 an[i].getDescription(), anot);
2343 jaa._linecolour = firstColour;
2345 // register new annotation
2346 if (an[i].getId() != null)
2348 annotationIds.put(an[i].getId(), jaa);
2349 jaa.annotationId = an[i].getId();
2351 // recover sequence association
2352 if (an[i].getSequenceRef() != null)
2354 if (al.findName(an[i].getSequenceRef()) != null)
2356 jaa.createSequenceMapping(al.findName(an[i].getSequenceRef()),
2358 al.findName(an[i].getSequenceRef()).addAlignmentAnnotation(jaa);
2361 // and make a note of any group association
2362 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
2364 ArrayList<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
2365 .get(an[i].getGroupRef());
2368 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
2369 groupAnnotRefs.put(an[i].getGroupRef(), aal);
2374 if (an[i].hasScore())
2376 jaa.setScore(an[i].getScore());
2378 if (an[i].hasVisible())
2379 jaa.visible = an[i].getVisible();
2381 if (an[i].hasCentreColLabels())
2382 jaa.centreColLabels = an[i].getCentreColLabels();
2384 if (an[i].hasScaleColLabels())
2386 jaa.scaleColLabel = an[i].getScaleColLabels();
2388 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
2390 // newer files have an 'autoCalculated' flag and store calculation
2391 // state in viewport properties
2392 jaa.autoCalculated = true; // means annotation will be marked for
2393 // update at end of load.
2395 if (an[i].hasGraphHeight())
2397 jaa.graphHeight = an[i].getGraphHeight();
2399 if (an[i].hasBelowAlignment())
2401 jaa.belowAlignment = an[i].isBelowAlignment();
2403 jaa.setCalcId(an[i].getCalcId());
2405 if (jaa.autoCalculated)
2407 autoAlan.add(new JvAnnotRow(i, jaa));
2410 // if (!autoForView)
2412 // add autocalculated group annotation and any user created annotation
2414 al.addAnnotation(jaa);
2419 // ///////////////////////
2421 // Create alignment markup and styles for this view
2422 if (jms.getJGroupCount() > 0)
2424 JGroup[] groups = jms.getJGroup();
2426 for (int i = 0; i < groups.length; i++)
2428 ColourSchemeI cs = null;
2430 if (groups[i].getColour() != null)
2432 if (groups[i].getColour().startsWith("ucs"))
2434 cs = GetUserColourScheme(jms, groups[i].getColour());
2438 cs = ColourSchemeProperty.getColour(al, groups[i].getColour());
2443 cs.setThreshold(groups[i].getPidThreshold(), true);
2447 Vector seqs = new Vector();
2449 for (int s = 0; s < groups[i].getSeqCount(); s++)
2451 String seqId = groups[i].getSeq(s) + "";
2452 jalview.datamodel.SequenceI ts = (jalview.datamodel.SequenceI) seqRefIds
2457 seqs.addElement(ts);
2461 if (seqs.size() < 1)
2466 jalview.datamodel.SequenceGroup sg = new jalview.datamodel.SequenceGroup(
2467 seqs, groups[i].getName(), cs, groups[i].getDisplayBoxes(),
2468 groups[i].getDisplayText(), groups[i].getColourText(),
2469 groups[i].getStart(), groups[i].getEnd());
2471 sg.setOutlineColour(new java.awt.Color(groups[i].getOutlineColour()));
2473 sg.textColour = new java.awt.Color(groups[i].getTextCol1());
2474 sg.textColour2 = new java.awt.Color(groups[i].getTextCol2());
2475 sg.setShowNonconserved(groups[i].hasShowUnconserved() ? groups[i]
2476 .isShowUnconserved() : false);
2477 sg.thresholdTextColour = groups[i].getTextColThreshold();
2478 if (groups[i].hasShowConsensusHistogram())
2480 sg.setShowConsensusHistogram(groups[i].isShowConsensusHistogram());
2483 if (groups[i].hasShowSequenceLogo())
2485 sg.setshowSequenceLogo(groups[i].isShowSequenceLogo());
2487 if (groups[i].hasNormaliseSequenceLogo())
2489 sg.setNormaliseSequenceLogo(groups[i].isNormaliseSequenceLogo());
2491 if (groups[i].hasIgnoreGapsinConsensus())
2493 sg.setIgnoreGapsConsensus(groups[i].getIgnoreGapsinConsensus());
2495 if (groups[i].getConsThreshold() != 0)
2497 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
2498 "All", ResidueProperties.propHash, 3,
2499 sg.getSequences(null), 0, sg.getWidth() - 1);
2501 c.verdict(false, 25);
2502 sg.cs.setConservation(c);
2505 if (groups[i].getId() != null && groupAnnotRefs.size() > 0)
2507 // re-instate unique group/annotation row reference
2508 ArrayList<jalview.datamodel.AlignmentAnnotation> jaal = groupAnnotRefs
2509 .get(groups[i].getId());
2512 for (jalview.datamodel.AlignmentAnnotation jaa : jaal)
2515 if (jaa.autoCalculated)
2517 // match up and try to set group autocalc alignment row for this
2519 if (jaa.label.startsWith("Consensus for "))
2521 sg.setConsensus(jaa);
2523 // match up and try to set group autocalc alignment row for this
2525 if (jaa.label.startsWith("Conservation for "))
2527 sg.setConservationRow(jaa);
2538 // ///////////////////////////////
2541 // If we just load in the same jar file again, the sequenceSetId
2542 // will be the same, and we end up with multiple references
2543 // to the same sequenceSet. We must modify this id on load
2544 // so that each load of the file gives a unique id
2545 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
2546 String viewId = (view.getId() == null ? null : view.getId()
2548 AlignFrame af = null;
2549 AlignViewport av = null;
2550 // now check to see if we really need to create a new viewport.
2551 if (multipleView && viewportsAdded.size() == 0)
2553 // We recovered an alignment for which a viewport already exists.
2554 // TODO: fix up any settings necessary for overlaying stored state onto
2555 // state recovered from another document. (may not be necessary).
2556 // we may need a binding from a viewport in memory to one recovered from
2558 // and then recover its containing af to allow the settings to be applied.
2559 // TODO: fix for vamsas demo
2561 .println("About to recover a viewport for existing alignment: Sequence set ID is "
2563 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
2564 if (seqsetobj != null)
2566 if (seqsetobj instanceof String)
2568 uniqueSeqSetId = (String) seqsetobj;
2570 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
2576 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
2581 AlignmentPanel ap = null;
2582 boolean isnewview = true;
2585 // Check to see if this alignment already has a view id == viewId
2586 jalview.gui.AlignmentPanel views[] = Desktop
2587 .getAlignmentPanels(uniqueSeqSetId);
2588 if (views != null && views.length > 0)
2590 for (int v = 0; v < views.length; v++)
2592 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
2594 // recover the existing alignpanel, alignframe, viewport
2595 af = views[v].alignFrame;
2598 // TODO: could even skip resetting view settings if we don't want to
2599 // change the local settings from other jalview processes
2608 af = loadViewport(file, JSEQ, hiddenSeqs, al, jms, view,
2609 uniqueSeqSetId, viewId, autoAlan);
2614 // /////////////////////////////////////
2615 if (loadTreesAndStructures && jms.getTreeCount() > 0)
2619 for (int t = 0; t < jms.getTreeCount(); t++)
2622 Tree tree = jms.getTree(t);
2624 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
2627 tp = af.ShowNewickTree(
2628 new jalview.io.NewickFile(tree.getNewick()),
2629 tree.getTitle(), tree.getWidth(), tree.getHeight(),
2630 tree.getXpos(), tree.getYpos());
2631 if (tree.getId() != null)
2633 // perhaps bind the tree id to something ?
2638 // update local tree attributes ?
2639 // TODO: should check if tp has been manipulated by user - if so its
2640 // settings shouldn't be modified
2641 tp.setTitle(tree.getTitle());
2642 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
2643 .getWidth(), tree.getHeight()));
2644 tp.av = av; // af.viewport; // TODO: verify 'associate with all
2647 tp.treeCanvas.av = av; // af.viewport;
2648 tp.treeCanvas.ap = ap; // af.alignPanel;
2653 warn("There was a problem recovering stored Newick tree: \n"
2654 + tree.getNewick());
2658 tp.fitToWindow.setState(tree.getFitToWindow());
2659 tp.fitToWindow_actionPerformed(null);
2661 if (tree.getFontName() != null)
2663 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
2664 .getFontStyle(), tree.getFontSize()));
2668 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
2669 .getFontStyle(), tree.getFontSize()));
2672 tp.showPlaceholders(tree.getMarkUnlinked());
2673 tp.showBootstrap(tree.getShowBootstrap());
2674 tp.showDistances(tree.getShowDistances());
2676 tp.treeCanvas.threshold = tree.getThreshold();
2678 if (tree.getCurrentTree())
2680 af.viewport.setCurrentTree(tp.getTree());
2684 } catch (Exception ex)
2686 ex.printStackTrace();
2690 // //LOAD STRUCTURES
2691 if (loadTreesAndStructures)
2693 // run through all PDB ids on the alignment, and collect mappings between
2694 // jmol view ids and all sequences referring to it
2695 Hashtable<String, Object[]> jmolViewIds = new Hashtable();
2697 for (int i = 0; i < JSEQ.length; i++)
2699 if (JSEQ[i].getPdbidsCount() > 0)
2701 Pdbids[] ids = JSEQ[i].getPdbids();
2702 for (int p = 0; p < ids.length; p++)
2704 for (int s = 0; s < ids[p].getStructureStateCount(); s++)
2706 // check to see if we haven't already created this structure view
2707 String sviewid = (ids[p].getStructureState(s).getViewId() == null) ? null
2708 : ids[p].getStructureState(s).getViewId()
2710 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
2711 // Originally : ids[p].getFile()
2712 // : TODO: verify external PDB file recovery still works in normal
2713 // jalview project load
2714 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
2715 jpdb.setId(ids[p].getId());
2717 int x = ids[p].getStructureState(s).getXpos();
2718 int y = ids[p].getStructureState(s).getYpos();
2719 int width = ids[p].getStructureState(s).getWidth();
2720 int height = ids[p].getStructureState(s).getHeight();
2722 // Probably don't need to do this anymore...
2723 // Desktop.desktop.getComponentAt(x, y);
2724 // TODO: NOW: check that this recovers the PDB file correctly.
2725 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
2726 jalview.datamodel.SequenceI seq = (jalview.datamodel.SequenceI) seqRefIds
2727 .get(JSEQ[i].getId() + "");
2728 if (sviewid == null)
2730 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
2733 if (!jmolViewIds.containsKey(sviewid))
2735 jmolViewIds.put(sviewid, new Object[]
2737 { x, y, width, height }, "",
2738 new Hashtable<String, Object[]>(), new boolean[]
2739 { false, false, true } });
2740 // Legacy pre-2.7 conversion JAL-823 :
2741 // do not assume any view has to be linked for colour by
2745 // assemble String[] { pdb files }, String[] { id for each
2746 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
2747 // seqs_file 2}, boolean[] {
2748 // linkAlignPanel,superposeWithAlignpanel}} from hash
2749 Object[] jmoldat = jmolViewIds.get(sviewid);
2750 ((boolean[]) jmoldat[3])[0] |= ids[p].getStructureState(s)
2751 .hasAlignwithAlignPanel() ? ids[p].getStructureState(
2752 s).getAlignwithAlignPanel() : false;
2753 // never colour by linked panel if not specified
2754 ((boolean[]) jmoldat[3])[1] |= ids[p].getStructureState(s)
2755 .hasColourwithAlignPanel() ? ids[p]
2756 .getStructureState(s).getColourwithAlignPanel()
2758 // default for pre-2.7 projects is that Jmol colouring is enabled
2759 ((boolean[]) jmoldat[3])[2] &= ids[p].getStructureState(s)
2760 .hasColourByJmol() ? ids[p].getStructureState(s)
2761 .getColourByJmol() : true;
2763 if (((String) jmoldat[1]).length() < ids[p]
2764 .getStructureState(s).getContent().length())
2767 jmoldat[1] = ids[p].getStructureState(s).getContent();
2770 if (ids[p].getFile() != null)
2772 File mapkey = new File(ids[p].getFile());
2773 Object[] seqstrmaps = (Object[]) ((Hashtable) jmoldat[2])
2775 if (seqstrmaps == null)
2777 ((Hashtable) jmoldat[2]).put(mapkey,
2778 seqstrmaps = new Object[]
2779 { pdbFile, ids[p].getId(), new Vector(),
2782 if (!((Vector) seqstrmaps[2]).contains(seq))
2784 ((Vector) seqstrmaps[2]).addElement(seq);
2785 // ((Vector)seqstrmaps[3]).addElement(n) :
2786 // in principle, chains
2787 // should be stored here : do we need to
2788 // TODO: store and recover seq/pdb_id :
2794 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");
2803 // Instantiate the associated Jmol views
2804 for (Entry<String, Object[]> entry : jmolViewIds.entrySet())
2806 String sviewid = entry.getKey();
2807 Object[] svattrib = entry.getValue();
2808 int[] geom = (int[]) svattrib[0];
2809 String state = (String) svattrib[1];
2810 Hashtable<File, Object[]> oldFiles = (Hashtable<File, Object[]>) svattrib[2];
2811 final boolean useinJmolsuperpos = ((boolean[]) svattrib[3])[0], usetoColourbyseq = ((boolean[]) svattrib[3])[1], jmolColouring = ((boolean[]) svattrib[3])[2];
2812 int x = geom[0], y = geom[1], width = geom[2], height = geom[3];
2813 // collate the pdbfile -> sequence mappings from this view
2814 Vector<String> pdbfilenames = new Vector<String>();
2815 Vector<SequenceI[]> seqmaps = new Vector<SequenceI[]>();
2816 Vector<String> pdbids = new Vector<String>();
2818 // Search to see if we've already created this Jmol view
2819 AppJmol comp = null;
2820 JInternalFrame[] frames = null;
2825 frames = Desktop.desktop.getAllFrames();
2826 } catch (ArrayIndexOutOfBoundsException e)
2828 // occasional No such child exceptions are thrown here...
2833 } catch (Exception f)
2838 } while (frames == null);
2839 // search for any Jmol windows already open from other
2840 // alignment views that exactly match the stored structure state
2841 for (int f = 0; comp == null && f < frames.length; f++)
2843 if (frames[f] instanceof AppJmol)
2846 && ((AppJmol) frames[f]).getViewId().equals(sviewid))
2848 // post jalview 2.4 schema includes structure view id
2849 comp = (AppJmol) frames[f];
2851 else if (frames[f].getX() == x && frames[f].getY() == y
2852 && frames[f].getHeight() == height
2853 && frames[f].getWidth() == width)
2855 comp = (AppJmol) frames[f];
2862 // create a new Jmol window.
2863 // First parse the Jmol state to translate filenames loaded into the
2864 // view, and record the order in which files are shown in the Jmol
2865 // view, so we can add the sequence mappings in same order.
2866 StringBuffer newFileLoc = null;
2867 int cp = 0, ncp, ecp;
2868 while ((ncp = state.indexOf("load ", cp)) > -1)
2870 if (newFileLoc == null)
2872 newFileLoc = new StringBuffer();
2876 // look for next filename in load statement
2877 newFileLoc.append(state.substring(cp,
2878 ncp = (state.indexOf("\"", ncp + 1) + 1)));
2879 String oldfilenam = state.substring(ncp,
2880 ecp = state.indexOf("\"", ncp));
2881 // recover the new mapping data for this old filename
2882 // have to normalize filename - since Jmol and jalview do
2884 // translation differently.
2885 Object[] filedat = oldFiles.get(new File(oldfilenam));
2886 newFileLoc.append(Platform
2887 .escapeString((String) filedat[0]));
2888 pdbfilenames.addElement((String) filedat[0]);
2889 pdbids.addElement((String) filedat[1]);
2890 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
2891 .toArray(new SequenceI[0]));
2892 newFileLoc.append("\"");
2893 cp = ecp + 1; // advance beyond last \" and set cursor so we can
2894 // look for next file statement.
2895 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
2899 // just append rest of state
2900 newFileLoc.append(state.substring(cp));
2905 .print("Ignoring incomplete Jmol state for PDB ids: ");
2906 newFileLoc = new StringBuffer(state);
2907 newFileLoc.append("; load append ");
2908 for (File id : oldFiles.keySet())
2910 // add this and any other pdb files that should be present in
2912 Object[] filedat = oldFiles.get(id);
2914 newFileLoc.append(((String) filedat[0]));
2915 pdbfilenames.addElement((String) filedat[0]);
2916 pdbids.addElement((String) filedat[1]);
2917 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
2918 .toArray(new SequenceI[0]));
2919 newFileLoc.append(" \"");
2920 newFileLoc.append((String) filedat[0]);
2921 newFileLoc.append("\"");
2924 newFileLoc.append(";");
2927 if (newFileLoc != null)
2929 int histbug = newFileLoc.indexOf("history = ");
2931 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";",
2933 String val = (diff == -1) ? null : newFileLoc.substring(
2935 if (val != null && val.length() >= 4)
2937 if (val.contains("e"))
2939 if (val.trim().equals("true"))
2947 newFileLoc.replace(histbug, diff, val);
2950 // TODO: assemble String[] { pdb files }, String[] { id for each
2951 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
2952 // seqs_file 2}} from hash
2953 final String[] pdbf = pdbfilenames
2954 .toArray(new String[pdbfilenames.size()]), id = pdbids
2955 .toArray(new String[pdbids.size()]);
2956 final SequenceI[][] sq = seqmaps
2957 .toArray(new SequenceI[seqmaps.size()][]);
2958 final String fileloc = newFileLoc.toString(), vid = sviewid;
2959 final AlignFrame alf = af;
2960 final java.awt.Rectangle rect = new java.awt.Rectangle(x, y,
2964 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
2969 AppJmol sview = null;
2972 sview = new AppJmol(pdbf, id, sq, alf.alignPanel,
2973 useinJmolsuperpos, usetoColourbyseq,
2974 jmolColouring, fileloc, rect, vid);
2975 addNewStructureViewer(sview);
2976 } catch (OutOfMemoryError ex)
2978 new OOMWarning("restoring structure view for PDB id "
2979 + id, (OutOfMemoryError) ex.getCause());
2980 if (sview != null && sview.isVisible())
2982 sview.closeViewer();
2983 sview.setVisible(false);
2989 } catch (InvocationTargetException ex)
2991 warn("Unexpected error when opening Jmol view.", ex);
2993 } catch (InterruptedException e)
2995 // e.printStackTrace();
3001 // if (comp != null)
3003 // NOTE: if the jalview project is part of a shared session then
3004 // view synchronization should/could be done here.
3006 // add mapping for sequences in this view to an already open Jmol
3008 for (File id : oldFiles.keySet())
3010 // add this and any other pdb files that should be present in the
3012 Object[] filedat = oldFiles.get(id);
3013 String pdbFile = (String) filedat[0];
3014 SequenceI[] seq = ((Vector<SequenceI>) filedat[2])
3015 .toArray(new SequenceI[0]);
3016 comp.jmb.ssm.setMapping(seq, null, pdbFile,
3017 jalview.io.AppletFormatAdapter.FILE);
3018 comp.jmb.addSequenceForStructFile(pdbFile, seq);
3020 // and add the AlignmentPanel's reference to the Jmol view
3021 comp.addAlignmentPanel(ap);
3022 if (useinJmolsuperpos)
3024 comp.useAlignmentPanelForSuperposition(ap);
3028 comp.excludeAlignmentPanelForSuperposition(ap);
3030 if (usetoColourbyseq)
3032 comp.useAlignmentPanelForColourbyseq(ap, !jmolColouring);
3036 comp.excludeAlignmentPanelForColourbyseq(ap);
3042 // and finally return.
3045 Vector<AppJmol> newStructureViewers=null;
3046 protected void addNewStructureViewer(AppJmol sview)
3048 if (newStructureViewers!=null)
3050 sview.jmb.setFinishedLoadingFromArchive(false);
3051 newStructureViewers.add(sview);
3054 protected void setLoadingFinishedForNewStructureViewers()
3056 if (newStructureViewers!=null)
3058 for (AppJmol sview:newStructureViewers)
3060 sview.jmb.setFinishedLoadingFromArchive(true);
3062 newStructureViewers.clear();
3063 newStructureViewers=null;
3067 AlignFrame loadViewport(String file, JSeq[] JSEQ, Vector hiddenSeqs,
3068 Alignment al, JalviewModelSequence jms, Viewport view,
3069 String uniqueSeqSetId, String viewId,
3070 ArrayList<JvAnnotRow> autoAlan)
3072 AlignFrame af = null;
3073 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
3074 uniqueSeqSetId, viewId);
3076 af.setFileName(file, "Jalview");
3078 for (int i = 0; i < JSEQ.length; i++)
3080 af.viewport.setSequenceColour(af.viewport.getAlignment()
3081 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
3084 af.viewport.gatherViewsHere = view.getGatheredViews();
3086 if (view.getSequenceSetId() != null)
3088 jalview.gui.AlignViewport av = (jalview.gui.AlignViewport) viewportsAdded
3089 .get(uniqueSeqSetId);
3091 af.viewport.setSequenceSetId(uniqueSeqSetId);
3094 // propagate shared settings to this new view
3095 af.viewport.historyList = av.historyList;
3096 af.viewport.redoList = av.redoList;
3100 viewportsAdded.put(uniqueSeqSetId, af.viewport);
3102 // TODO: check if this method can be called repeatedly without
3103 // side-effects if alignpanel already registered.
3104 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
3106 // apply Hidden regions to view.
3107 if (hiddenSeqs != null)
3109 for (int s = 0; s < JSEQ.length; s++)
3111 jalview.datamodel.SequenceGroup hidden = new jalview.datamodel.SequenceGroup();
3113 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
3116 al.getSequenceAt(JSEQ[s].getHiddenSequences(r)), false);
3118 af.viewport.hideRepSequences(al.getSequenceAt(s), hidden);
3121 jalview.datamodel.SequenceI[] hseqs = new jalview.datamodel.SequenceI[hiddenSeqs
3124 for (int s = 0; s < hiddenSeqs.size(); s++)
3126 hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s);
3129 af.viewport.hideSequence(hseqs);
3132 // recover view properties and display parameters
3133 if (view.getViewName() != null)
3135 af.viewport.viewName = view.getViewName();
3136 af.setInitialTabVisible();
3138 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
3141 af.viewport.setShowAnnotation(view.getShowAnnotation());
3142 af.viewport.setAbovePIDThreshold(view.getPidSelected());
3144 af.viewport.setColourText(view.getShowColourText());
3146 af.viewport.setConservationSelected(view.getConservationSelected());
3147 af.viewport.setShowJVSuffix(view.getShowFullId());
3148 af.viewport.rightAlignIds = view.getRightAlignIds();
3149 af.viewport.setFont(new java.awt.Font(view.getFontName(), view
3150 .getFontStyle(), view.getFontSize()));
3151 af.alignPanel.fontChanged();
3152 af.viewport.setRenderGaps(view.getRenderGaps());
3153 af.viewport.setWrapAlignment(view.getWrapAlignment());
3154 af.alignPanel.setWrapAlignment(view.getWrapAlignment());
3155 af.viewport.setShowAnnotation(view.getShowAnnotation());
3156 af.alignPanel.setAnnotationVisible(view.getShowAnnotation());
3158 af.viewport.setShowBoxes(view.getShowBoxes());
3160 af.viewport.setShowText(view.getShowText());
3162 af.viewport.textColour = new java.awt.Color(view.getTextCol1());
3163 af.viewport.textColour2 = new java.awt.Color(view.getTextCol2());
3164 af.viewport.thresholdTextColour = view.getTextColThreshold();
3165 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
3166 .isShowUnconserved() : false);
3167 af.viewport.setStartRes(view.getStartRes());
3168 af.viewport.setStartSeq(view.getStartSeq());
3170 ColourSchemeI cs = null;
3171 // apply colourschemes
3172 if (view.getBgColour() != null)
3174 if (view.getBgColour().startsWith("ucs"))
3176 cs = GetUserColourScheme(jms, view.getBgColour());
3178 else if (view.getBgColour().startsWith("Annotation"))
3180 // int find annotation
3181 if (af.viewport.getAlignment().getAlignmentAnnotation() != null)
3183 for (int i = 0; i < af.viewport.getAlignment()
3184 .getAlignmentAnnotation().length; i++)
3186 if (af.viewport.getAlignment().getAlignmentAnnotation()[i].label
3187 .equals(view.getAnnotationColours().getAnnotation()))
3189 if (af.viewport.getAlignment().getAlignmentAnnotation()[i]
3190 .getThreshold() == null)
3192 af.viewport.getAlignment().getAlignmentAnnotation()[i]
3193 .setThreshold(new jalview.datamodel.GraphLine(view
3194 .getAnnotationColours().getThreshold(),
3195 "Threshold", java.awt.Color.black)
3200 if (view.getAnnotationColours().getColourScheme()
3203 cs = new AnnotationColourGradient(af.viewport
3204 .getAlignment().getAlignmentAnnotation()[i],
3205 new java.awt.Color(view.getAnnotationColours()
3206 .getMinColour()), new java.awt.Color(view
3207 .getAnnotationColours().getMaxColour()),
3208 view.getAnnotationColours().getAboveThreshold());
3210 else if (view.getAnnotationColours().getColourScheme()
3213 cs = new AnnotationColourGradient(af.viewport
3214 .getAlignment().getAlignmentAnnotation()[i],
3215 GetUserColourScheme(jms, view
3216 .getAnnotationColours().getColourScheme()),
3217 view.getAnnotationColours().getAboveThreshold());
3221 cs = new AnnotationColourGradient(af.viewport
3222 .getAlignment().getAlignmentAnnotation()[i],
3223 ColourSchemeProperty.getColour(al, view
3224 .getAnnotationColours().getColourScheme()),
3225 view.getAnnotationColours().getAboveThreshold());
3228 // Also use these settings for all the groups
3229 if (al.getGroups() != null)
3231 for (int g = 0; g < al.getGroups().size(); g++)
3233 jalview.datamodel.SequenceGroup sg = al.getGroups()
3243 * (view.getAnnotationColours().getColourScheme().equals("None"
3244 * )) { sg.cs = new AnnotationColourGradient(
3245 * af.viewport.getAlignment().getAlignmentAnnotation()[i], new
3246 * java.awt.Color(view.getAnnotationColours().
3247 * getMinColour()), new
3248 * java.awt.Color(view.getAnnotationColours().
3250 * view.getAnnotationColours().getAboveThreshold()); } else
3253 sg.cs = new AnnotationColourGradient(af.viewport
3254 .getAlignment().getAlignmentAnnotation()[i],
3255 sg.cs, view.getAnnotationColours()
3256 .getAboveThreshold());
3270 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
3275 cs.setThreshold(view.getPidThreshold(), true);
3276 cs.setConsensus(af.viewport.getSequenceConsensusHash());
3280 af.viewport.setGlobalColourScheme(cs);
3281 af.viewport.setColourAppliesToAllGroups(false);
3283 if (view.getConservationSelected() && cs != null)
3285 cs.setConservationInc(view.getConsThreshold());
3288 af.changeColour(cs);
3290 af.viewport.setColourAppliesToAllGroups(true);
3292 if (view.getShowSequenceFeatures())
3294 af.viewport.showSequenceFeatures = true;
3296 if (view.hasCentreColumnLabels())
3298 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
3300 if (view.hasIgnoreGapsinConsensus())
3302 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
3305 if (view.hasFollowHighlight())
3307 af.viewport.followHighlight = view.getFollowHighlight();
3309 if (view.hasFollowSelection())
3311 af.viewport.followSelection = view.getFollowSelection();
3313 if (view.hasShowConsensusHistogram())
3315 af.viewport.setShowConsensusHistogram(view
3316 .getShowConsensusHistogram());
3320 af.viewport.setShowConsensusHistogram(true);
3322 if (view.hasShowSequenceLogo())
3324 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
3328 af.viewport.setShowSequenceLogo(false);
3330 if (view.hasNormaliseSequenceLogo())
3332 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
3334 if (view.hasShowDbRefTooltip())
3336 af.viewport.setShowDbRefs(view.getShowDbRefTooltip());
3338 if (view.hasShowNPfeatureTooltip())
3340 af.viewport.setShowNpFeats(view.hasShowNPfeatureTooltip());
3342 if (view.hasShowGroupConsensus())
3344 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
3348 af.viewport.setShowGroupConsensus(false);
3350 if (view.hasShowGroupConservation())
3352 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
3356 af.viewport.setShowGroupConservation(false);
3359 // recover featre settings
3360 if (jms.getFeatureSettings() != null)
3362 af.viewport.featuresDisplayed = new Hashtable();
3363 String[] renderOrder = new String[jms.getFeatureSettings()
3364 .getSettingCount()];
3365 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
3367 Setting setting = jms.getFeatureSettings().getSetting(fs);
3368 if (setting.hasMincolour())
3370 GraduatedColor gc = setting.hasMin() ? new GraduatedColor(
3371 new java.awt.Color(setting.getMincolour()),
3372 new java.awt.Color(setting.getColour()),
3373 setting.getMin(), setting.getMax()) : new GraduatedColor(
3374 new java.awt.Color(setting.getMincolour()),
3375 new java.awt.Color(setting.getColour()), 0, 1);
3376 if (setting.hasThreshold())
3378 gc.setThresh(setting.getThreshold());
3379 gc.setThreshType(setting.getThreshstate());
3381 gc.setAutoScaled(true); // default
3382 if (setting.hasAutoScale())
3384 gc.setAutoScaled(setting.getAutoScale());
3386 if (setting.hasColourByLabel())
3388 gc.setColourByLabel(setting.getColourByLabel());
3390 // and put in the feature colour table.
3391 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3392 setting.getType(), gc);
3396 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3398 new java.awt.Color(setting.getColour()));
3400 renderOrder[fs] = setting.getType();
3401 if (setting.hasOrder())
3402 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3403 setting.getType(), setting.getOrder());
3405 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3407 fs / jms.getFeatureSettings().getSettingCount());
3408 if (setting.getDisplay())
3410 af.viewport.featuresDisplayed.put(setting.getType(), new Integer(
3411 setting.getColour()));
3414 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().renderOrder = renderOrder;
3416 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().featureGroups = fgtable = new Hashtable();
3417 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
3419 Group grp = jms.getFeatureSettings().getGroup(gs);
3420 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
3424 if (view.getHiddenColumnsCount() > 0)
3426 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
3428 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
3429 .getHiddenColumns(c).getEnd() // +1
3433 if (view.getCalcIdParam() != null)
3435 for (CalcIdParam calcIdParam : view.getCalcIdParam())
3437 if (calcIdParam != null)
3439 if (recoverCalcIdParam(calcIdParam, af.viewport))
3444 warn("Couldn't recover parameters for "
3445 + calcIdParam.getCalcId());
3450 af.setMenusFromViewport(af.viewport);
3451 // TODO: we don't need to do this if the viewport is aready visible.
3452 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
3454 af.alignPanel.updateAnnotation(false, true); // recompute any autoannotation
3455 reorderAutoannotation(af, al, autoAlan);
3459 private void reorderAutoannotation(AlignFrame af, Alignment al,
3460 ArrayList<JvAnnotRow> autoAlan)
3462 // copy over visualization settings for autocalculated annotation in the
3464 if (al.getAlignmentAnnotation() != null)
3467 * Kludge for magic autoannotation names (see JAL-811)
3469 String[] magicNames = new String[]
3470 { "Consensus", "Quality", "Conservation" };
3471 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
3472 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
3473 for (String nm : magicNames)
3475 visan.put(nm, nullAnnot);
3477 for (JvAnnotRow auan : autoAlan)
3479 visan.put(auan.template.label
3480 + (auan.template.getCalcId() == null ? "" : "\t"
3481 + auan.template.getCalcId()), auan);
3483 int hSize = al.getAlignmentAnnotation().length;
3484 ArrayList<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
3485 // work through any autoCalculated annotation already on the view
3486 // removing it if it should be placed in a different location on the
3487 // annotation panel.
3488 List<String> remains = new ArrayList(visan.keySet());
3489 for (int h = 0; h < hSize; h++)
3491 jalview.datamodel.AlignmentAnnotation jalan = al
3492 .getAlignmentAnnotation()[h];
3493 if (jalan.autoCalculated)
3496 JvAnnotRow valan = visan.get(k = jalan.label);
3497 if (jalan.getCalcId() != null)
3499 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
3504 // delete the auto calculated row from the alignment
3505 al.deleteAnnotation(jalan, false);
3509 if (valan != nullAnnot)
3511 if (jalan != valan.template)
3513 // newly created autoannotation row instance
3514 // so keep a reference to the visible annotation row
3515 // and copy over all relevant attributes
3516 if (valan.template.graphHeight >= 0)
3519 jalan.graphHeight = valan.template.graphHeight;
3521 jalan.visible = valan.template.visible;
3523 reorder.add(new JvAnnotRow(valan.order, jalan));
3528 // Add any (possibly stale) autocalculated rows that were not appended to
3529 // the view during construction
3530 for (String other : remains)
3532 JvAnnotRow othera = visan.get(other);
3533 if (othera != nullAnnot && othera.template.getCalcId() != null
3534 && othera.template.getCalcId().length() > 0)
3536 reorder.add(othera);
3539 // now put the automatic annotation in its correct place
3540 int s = 0, srt[] = new int[reorder.size()];
3541 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
3542 for (JvAnnotRow jvar : reorder)
3545 srt[s++] = jvar.order;
3548 jalview.util.QuickSort.sort(srt, rws);
3549 // and re-insert the annotation at its correct position
3550 for (JvAnnotRow jvar : rws)
3552 al.addAnnotation(jvar.template, jvar.order);
3554 af.alignPanel.adjustAnnotationHeight();
3558 Hashtable skipList = null;
3561 * TODO remove this method
3564 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
3565 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
3566 * throw new Error("Implementation Error. No skipList defined for this
3567 * Jalview2XML instance."); } return (AlignFrame)
3568 * skipList.get(view.getSequenceSetId()); }
3572 * Check if the Jalview view contained in object should be skipped or not.
3575 * @return true if view's sequenceSetId is a key in skipList
3577 private boolean skipViewport(JalviewModel object)
3579 if (skipList == null)
3584 if (skipList.containsKey(id = object.getJalviewModelSequence()
3585 .getViewport()[0].getSequenceSetId()))
3587 if (Cache.log != null && Cache.log.isDebugEnabled())
3589 Cache.log.debug("Skipping seuqence set id " + id);
3596 public void AddToSkipList(AlignFrame af)
3598 if (skipList == null)
3600 skipList = new Hashtable();
3602 skipList.put(af.getViewport().getSequenceSetId(), af);
3605 public void clearSkipList()
3607 if (skipList != null)
3614 private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al)
3616 jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId());
3617 Vector dseqs = null;
3620 // create a list of new dataset sequences
3621 dseqs = new Vector();
3623 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
3625 Sequence vamsasSeq = vamsasSet.getSequence(i);
3626 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs);
3628 // create a new dataset
3631 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
3632 dseqs.copyInto(dsseqs);
3633 ds = new jalview.datamodel.Alignment(dsseqs);
3634 debug("Created new dataset " + vamsasSet.getDatasetId()
3635 + " for alignment " + System.identityHashCode(al));
3636 addDatasetRef(vamsasSet.getDatasetId(), ds);
3638 // set the dataset for the newly imported alignment.
3639 if (al.getDataset() == null)
3648 * sequence definition to create/merge dataset sequence for
3652 * vector to add new dataset sequence to
3654 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
3655 AlignmentI ds, Vector dseqs)
3657 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
3659 jalview.datamodel.Sequence sq = (jalview.datamodel.Sequence) seqRefIds
3660 .get(vamsasSeq.getId());
3661 jalview.datamodel.SequenceI dsq = null;
3662 if (sq != null && sq.getDatasetSequence() != null)
3664 dsq = sq.getDatasetSequence();
3667 String sqid = vamsasSeq.getDsseqid();
3670 // need to create or add a new dataset sequence reference to this sequence
3673 dsq = (jalview.datamodel.SequenceI) seqRefIds.get(sqid);
3678 // make a new dataset sequence
3679 dsq = sq.createDatasetSequence();
3682 // make up a new dataset reference for this sequence
3683 sqid = seqHash(dsq);
3685 dsq.setVamsasId(uniqueSetSuffix + sqid);
3686 seqRefIds.put(sqid, dsq);
3691 dseqs.addElement(dsq);
3696 ds.addSequence(dsq);
3702 { // make this dataset sequence sq's dataset sequence
3703 sq.setDatasetSequence(dsq);
3707 // TODO: refactor this as a merge dataset sequence function
3708 // now check that sq (the dataset sequence) sequence really is the union of
3709 // all references to it
3710 // boolean pre = sq.getStart() < dsq.getStart();
3711 // boolean post = sq.getEnd() > dsq.getEnd();
3715 StringBuffer sb = new StringBuffer();
3716 String newres = jalview.analysis.AlignSeq.extractGaps(
3717 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
3718 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
3719 && newres.length() > dsq.getLength())
3721 // Update with the longer sequence.
3725 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
3726 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
3727 * sb.append(newres.substring(newres.length() - sq.getEnd() -
3728 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
3730 dsq.setSequence(sb.toString());
3732 // TODO: merges will never happen if we 'know' we have the real dataset
3733 // sequence - this should be detected when id==dssid
3734 System.err.println("DEBUG Notice: Merged dataset sequence"); // ("
3735 // + (pre ? "prepended" : "") + " "
3736 // + (post ? "appended" : ""));
3741 java.util.Hashtable datasetIds = null;
3743 java.util.IdentityHashMap dataset2Ids = null;
3745 private Alignment getDatasetFor(String datasetId)
3747 if (datasetIds == null)
3749 datasetIds = new Hashtable();
3752 if (datasetIds.containsKey(datasetId))
3754 return (Alignment) datasetIds.get(datasetId);
3759 private void addDatasetRef(String datasetId, Alignment dataset)
3761 if (datasetIds == null)
3763 datasetIds = new Hashtable();
3765 datasetIds.put(datasetId, dataset);
3769 * make a new dataset ID for this jalview dataset alignment
3774 private String getDatasetIdRef(jalview.datamodel.Alignment dataset)
3776 if (dataset.getDataset() != null)
3778 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
3780 String datasetId = makeHashCode(dataset, null);
3781 if (datasetId == null)
3783 // make a new datasetId and record it
3784 if (dataset2Ids == null)
3786 dataset2Ids = new IdentityHashMap();
3790 datasetId = (String) dataset2Ids.get(dataset);
3792 if (datasetId == null)
3794 datasetId = "ds" + dataset2Ids.size() + 1;
3795 dataset2Ids.put(dataset, datasetId);
3801 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
3803 for (int d = 0; d < sequence.getDBRefCount(); d++)
3805 DBRef dr = sequence.getDBRef(d);
3806 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
3807 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
3808 .getVersion(), sequence.getDBRef(d).getAccessionId());
3809 if (dr.getMapping() != null)
3811 entry.setMap(addMapping(dr.getMapping()));
3813 datasetSequence.addDBRef(entry);
3817 private jalview.datamodel.Mapping addMapping(Mapping m)
3819 SequenceI dsto = null;
3820 // Mapping m = dr.getMapping();
3821 int fr[] = new int[m.getMapListFromCount() * 2];
3822 Enumeration f = m.enumerateMapListFrom();
3823 for (int _i = 0; f.hasMoreElements(); _i += 2)
3825 MapListFrom mf = (MapListFrom) f.nextElement();
3826 fr[_i] = mf.getStart();
3827 fr[_i + 1] = mf.getEnd();
3829 int fto[] = new int[m.getMapListToCount() * 2];
3830 f = m.enumerateMapListTo();
3831 for (int _i = 0; f.hasMoreElements(); _i += 2)
3833 MapListTo mf = (MapListTo) f.nextElement();
3834 fto[_i] = mf.getStart();
3835 fto[_i + 1] = mf.getEnd();
3837 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
3838 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
3839 if (m.getMappingChoice() != null)
3841 MappingChoice mc = m.getMappingChoice();
3842 if (mc.getDseqFor() != null)
3844 String dsfor = "" + mc.getDseqFor();
3845 if (seqRefIds.containsKey(dsfor))
3850 jmap.setTo((SequenceI) seqRefIds.get(dsfor));
3854 frefedSequence.add(new Object[]
3861 * local sequence definition
3863 Sequence ms = mc.getSequence();
3864 jalview.datamodel.Sequence djs = null;
3865 String sqid = ms.getDsseqid();
3866 if (sqid != null && sqid.length() > 0)
3869 * recover dataset sequence
3871 djs = (jalview.datamodel.Sequence) seqRefIds.get(sqid);
3876 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
3877 sqid = ((Object) ms).toString(); // make up a new hascode for
3878 // undefined dataset sequence hash
3879 // (unlikely to happen)
3885 * make a new dataset sequence and add it to refIds hash
3887 djs = new jalview.datamodel.Sequence(ms.getName(),
3889 djs.setStart(jmap.getMap().getToLowest());
3890 djs.setEnd(jmap.getMap().getToHighest());
3891 djs.setVamsasId(uniqueSetSuffix + sqid);
3893 seqRefIds.put(sqid, djs);
3896 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
3905 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
3906 boolean keepSeqRefs)
3909 jalview.schemabinding.version2.JalviewModel jm = SaveState(ap, null,
3915 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
3919 uniqueSetSuffix = "";
3920 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
3925 if (this.frefedSequence == null)
3927 frefedSequence = new Vector();
3930 viewportsAdded = new Hashtable();
3932 AlignFrame af = LoadFromObject(jm, null, false, null);
3933 af.alignPanels.clear();
3934 af.closeMenuItem_actionPerformed(true);
3937 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
3938 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
3939 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
3940 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
3941 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
3944 return af.alignPanel;
3948 * flag indicating if hashtables should be cleared on finalization TODO this
3949 * flag may not be necessary
3951 private final boolean _cleartables = true;
3953 private Hashtable jvids2vobj;
3958 * @see java.lang.Object#finalize()
3961 protected void finalize() throws Throwable
3963 // really make sure we have no buried refs left.
3968 this.seqRefIds = null;
3969 this.seqsToIds = null;
3973 private void warn(String msg)
3978 private void warn(String msg, Exception e)
3980 if (Cache.log != null)
3984 Cache.log.warn(msg, e);
3988 Cache.log.warn(msg);
3993 System.err.println("Warning: " + msg);
3996 e.printStackTrace();
4001 private void debug(String string)
4003 debug(string, null);
4006 private void debug(String msg, Exception e)
4008 if (Cache.log != null)
4012 Cache.log.debug(msg, e);
4016 Cache.log.debug(msg);
4021 System.err.println("Warning: " + msg);
4024 e.printStackTrace();
4030 * set the object to ID mapping tables used to write/recover objects and XML
4031 * ID strings for the jalview project. If external tables are provided then
4032 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
4033 * object goes out of scope. - also populates the datasetIds hashtable with
4034 * alignment objects containing dataset sequences
4037 * Map from ID strings to jalview datamodel
4039 * Map from jalview datamodel to ID strings
4043 public void setObjectMappingTables(Hashtable vobj2jv,
4044 IdentityHashMap jv2vobj)
4046 this.jv2vobj = jv2vobj;
4047 this.vobj2jv = vobj2jv;
4048 Iterator ds = jv2vobj.keySet().iterator();
4050 while (ds.hasNext())
4052 Object jvobj = ds.next();
4053 id = jv2vobj.get(jvobj).toString();
4054 if (jvobj instanceof jalview.datamodel.Alignment)
4056 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
4058 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
4061 else if (jvobj instanceof jalview.datamodel.Sequence)
4063 // register sequence object so the XML parser can recover it.
4064 if (seqRefIds == null)
4066 seqRefIds = new Hashtable();
4068 if (seqsToIds == null)
4070 seqsToIds = new IdentityHashMap();
4072 seqRefIds.put(jv2vobj.get(jvobj).toString(), jvobj);
4073 seqsToIds.put(jvobj, id);
4075 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
4077 if (annotationIds == null)
4079 annotationIds = new Hashtable();
4082 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvobj);
4083 jalview.datamodel.AlignmentAnnotation jvann = (jalview.datamodel.AlignmentAnnotation) jvobj;
4084 if (jvann.annotationId == null)
4086 jvann.annotationId = anid;
4088 if (!jvann.annotationId.equals(anid))
4090 // TODO verify that this is the correct behaviour
4091 this.warn("Overriding Annotation ID for " + anid
4092 + " from different id : " + jvann.annotationId);
4093 jvann.annotationId = anid;
4096 else if (jvobj instanceof String)
4098 if (jvids2vobj == null)
4100 jvids2vobj = new Hashtable();
4101 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
4105 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
4110 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
4111 * objects created from the project archive. If string is null (default for
4112 * construction) then suffix will be set automatically.
4116 public void setUniqueSetSuffix(String string)
4118 uniqueSetSuffix = string;
4123 * uses skipList2 as the skipList for skipping views on sequence sets
4124 * associated with keys in the skipList
4128 public void setSkipList(Hashtable skipList2)
4130 skipList = skipList2;