2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)
3 * Copyright (C) 2011 J Procter, AM Waterhouse, J Engelhardt, LM Lui, G Barton, M Clamp, S Searle
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
11 * Jalview is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty
13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along with Jalview. If not, see <http://www.gnu.org/licenses/>.
20 import java.awt.Rectangle;
22 import java.lang.reflect.InvocationTargetException;
25 import java.util.Map.Entry;
26 import java.util.jar.*;
30 import org.exolab.castor.xml.*;
32 import jalview.bin.Cache;
33 import jalview.datamodel.Alignment;
34 import jalview.datamodel.AlignmentAnnotation;
35 import jalview.datamodel.AlignmentI;
36 import jalview.datamodel.SequenceI;
37 import jalview.schemabinding.version2.*;
38 import jalview.schemes.*;
39 import jalview.util.Platform;
40 import jalview.util.jarInputStreamProvider;
41 import jalview.ws.jws2.AAConsClient;
42 import jalview.ws.jws2.Jws2Discoverer;
43 import jalview.ws.jws2.dm.AAConsSettings;
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 for (int s = 0; s < sg.getSize(); s++)
1009 jalview.datamodel.Sequence seq = (jalview.datamodel.Sequence) sg
1011 groups[i].addSeq(seqHash(seq));
1015 jms.setJGroup(groups);
1018 // /////////SAVE VIEWPORT
1019 Viewport view = new Viewport();
1020 view.setTitle(ap.alignFrame.getTitle());
1021 view.setSequenceSetId(makeHashCode(av.getSequenceSetId(),
1022 av.getSequenceSetId()));
1023 view.setId(av.getViewId());
1024 view.setViewName(av.viewName);
1025 view.setGatheredViews(av.gatherViewsHere);
1027 if (ap.av.explodedPosition != null)
1029 view.setXpos(av.explodedPosition.x);
1030 view.setYpos(av.explodedPosition.y);
1031 view.setWidth(av.explodedPosition.width);
1032 view.setHeight(av.explodedPosition.height);
1036 view.setXpos(ap.alignFrame.getBounds().x);
1037 view.setYpos(ap.alignFrame.getBounds().y);
1038 view.setWidth(ap.alignFrame.getBounds().width);
1039 view.setHeight(ap.alignFrame.getBounds().height);
1042 view.setStartRes(av.startRes);
1043 view.setStartSeq(av.startSeq);
1045 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1047 view.setBgColour(SetUserColourScheme(av.getGlobalColourScheme(),
1050 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1052 jalview.schemes.AnnotationColourGradient acg = (jalview.schemes.AnnotationColourGradient) av
1053 .getGlobalColourScheme();
1055 AnnotationColours ac = new AnnotationColours();
1056 ac.setAboveThreshold(acg.getAboveThreshold());
1057 ac.setThreshold(acg.getAnnotationThreshold());
1058 ac.setAnnotation(acg.getAnnotation());
1059 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1061 ac.setColourScheme(SetUserColourScheme(acg.getBaseColour(),
1066 ac.setColourScheme(ColourSchemeProperty.getColourName(acg
1070 ac.setMaxColour(acg.getMaxColour().getRGB());
1071 ac.setMinColour(acg.getMinColour().getRGB());
1072 view.setAnnotationColours(ac);
1073 view.setBgColour("AnnotationColourGradient");
1077 view.setBgColour(ColourSchemeProperty.getColourName(av
1078 .getGlobalColourScheme()));
1081 ColourSchemeI cs = av.getGlobalColourScheme();
1085 if (cs.conservationApplied())
1087 view.setConsThreshold(cs.getConservationInc());
1088 if (cs instanceof jalview.schemes.UserColourScheme)
1090 view.setBgColour(SetUserColourScheme(cs, userColours, jms));
1094 if (cs instanceof ResidueColourScheme)
1096 view.setPidThreshold(cs.getThreshold());
1100 view.setConservationSelected(av.getConservationSelected());
1101 view.setPidSelected(av.getAbovePIDThreshold());
1102 view.setFontName(av.font.getName());
1103 view.setFontSize(av.font.getSize());
1104 view.setFontStyle(av.font.getStyle());
1105 view.setRenderGaps(av.renderGaps);
1106 view.setShowAnnotation(av.getShowAnnotation());
1107 view.setShowBoxes(av.getShowBoxes());
1108 view.setShowColourText(av.getColourText());
1109 view.setShowFullId(av.getShowJVSuffix());
1110 view.setRightAlignIds(av.rightAlignIds);
1111 view.setShowSequenceFeatures(av.showSequenceFeatures);
1112 view.setShowText(av.getShowText());
1113 view.setShowUnconserved(av.getShowUnconserved());
1114 view.setWrapAlignment(av.getWrapAlignment());
1115 view.setTextCol1(av.textColour.getRGB());
1116 view.setTextCol2(av.textColour2.getRGB());
1117 view.setTextColThreshold(av.thresholdTextColour);
1118 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1119 view.setShowSequenceLogo(av.isShowSequenceLogo());
1120 view.setShowGroupConsensus(av.isShowGroupConsensus());
1121 view.setShowGroupConservation(av.isShowGroupConservation());
1122 view.setShowNPfeatureTooltip(av.isShowNpFeats());
1123 view.setShowDbRefTooltip(av.isShowDbRefs());
1124 view.setFollowHighlight(av.followHighlight);
1125 view.setFollowSelection(av.followSelection);
1126 view.setIgnoreGapsinConsensus(av.getIgnoreGapsConsensus());
1127 if (av.featuresDisplayed != null)
1129 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1131 String[] renderOrder = ap.seqPanel.seqCanvas.getFeatureRenderer().renderOrder;
1133 Vector settingsAdded = new Vector();
1134 Object gstyle = null;
1135 GraduatedColor gcol = null;
1136 if (renderOrder != null)
1138 for (int ro = 0; ro < renderOrder.length; ro++)
1140 gstyle = ap.seqPanel.seqCanvas.getFeatureRenderer()
1141 .getFeatureStyle(renderOrder[ro]);
1142 Setting setting = new Setting();
1143 setting.setType(renderOrder[ro]);
1144 if (gstyle instanceof GraduatedColor)
1146 gcol = (GraduatedColor) gstyle;
1147 setting.setColour(gcol.getMaxColor().getRGB());
1148 setting.setMincolour(gcol.getMinColor().getRGB());
1149 setting.setMin(gcol.getMin());
1150 setting.setMax(gcol.getMax());
1151 setting.setColourByLabel(gcol.isColourByLabel());
1152 setting.setAutoScale(gcol.isAutoScale());
1153 setting.setThreshold(gcol.getThresh());
1154 setting.setThreshstate(gcol.getThreshType());
1158 setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer()
1159 .getColour(renderOrder[ro]).getRGB());
1162 setting.setDisplay(av.featuresDisplayed
1163 .containsKey(renderOrder[ro]));
1164 float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer()
1165 .getOrder(renderOrder[ro]);
1168 setting.setOrder(rorder);
1170 fs.addSetting(setting);
1171 settingsAdded.addElement(renderOrder[ro]);
1175 // Make sure we save none displayed feature settings
1176 Iterator en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureColours
1177 .keySet().iterator();
1178 while (en.hasNext())
1180 String key = en.next().toString();
1181 if (settingsAdded.contains(key))
1186 Setting setting = new Setting();
1187 setting.setType(key);
1188 setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer()
1189 .getColour(key).getRGB());
1191 setting.setDisplay(false);
1192 float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer().getOrder(
1196 setting.setOrder(rorder);
1198 fs.addSetting(setting);
1199 settingsAdded.addElement(key);
1201 en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups
1202 .keySet().iterator();
1203 Vector groupsAdded = new Vector();
1204 while (en.hasNext())
1206 String grp = en.next().toString();
1207 if (groupsAdded.contains(grp))
1211 Group g = new Group();
1213 g.setDisplay(((Boolean) ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups
1214 .get(grp)).booleanValue());
1216 groupsAdded.addElement(grp);
1218 jms.setFeatureSettings(fs);
1222 if (av.hasHiddenColumns())
1224 if (av.getColumnSelection() == null
1225 || av.getColumnSelection().getHiddenColumns() == null)
1227 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1231 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1234 int[] region = (int[]) av.getColumnSelection().getHiddenColumns()
1236 HiddenColumns hc = new HiddenColumns();
1237 hc.setStart(region[0]);
1238 hc.setEnd(region[1]);
1239 view.addHiddenColumns(hc);
1243 if (calcIdSet.size() > 0)
1245 for (String calcId : calcIdSet)
1247 if (calcId.trim().length() > 0)
1249 CalcIdParam cidp = createCalcIdParam(calcId, av);
1250 // Some calcIds have no parameters.
1253 view.addCalcIdParam(cidp);
1259 jms.addViewport(view);
1261 object.setJalviewModelSequence(jms);
1262 object.getVamsasModel().addSequenceSet(vamsasSet);
1264 if (jout != null && fileName != null)
1266 // We may not want to write the object to disk,
1267 // eg we can copy the alignViewport to a new view object
1268 // using save and then load
1271 JarEntry entry = new JarEntry(fileName);
1272 jout.putNextEntry(entry);
1273 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1275 org.exolab.castor.xml.Marshaller marshaller = new org.exolab.castor.xml.Marshaller(
1277 marshaller.marshal(object);
1280 } catch (Exception ex)
1282 // TODO: raise error in GUI if marshalling failed.
1283 ex.printStackTrace();
1289 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1291 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1292 if (settings != null)
1294 CalcIdParam vCalcIdParam = new CalcIdParam();
1295 vCalcIdParam.setCalcId(calcId);
1296 vCalcIdParam.addServiceURL(settings.getServiceURI());
1297 // generic URI allowing a third party to resolve another instance of the
1298 // service used for this calculation
1299 for (String urls : settings.getServiceURLs())
1301 vCalcIdParam.addServiceURL(urls);
1303 vCalcIdParam.setVersion("1.0");
1304 if (settings.getPreset() != null)
1306 WsParamSetI setting = settings.getPreset();
1307 vCalcIdParam.setName(setting.getName());
1308 vCalcIdParam.setDescription(setting.getDescription());
1312 vCalcIdParam.setName("");
1313 vCalcIdParam.setDescription("Last used parameters");
1315 // need to be able to recover 1) settings 2) user-defined presets or
1316 // recreate settings from preset 3) predefined settings provided by
1317 // service - or settings that can be transferred (or discarded)
1318 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1320 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1321 // todo - decide if updateImmediately is needed for any projects.
1323 return vCalcIdParam;
1328 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1331 if (calcIdParam.getVersion().equals("1.0"))
1333 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1334 .getPreferredServiceFor(calcIdParam.getServiceURL());
1335 if (service != null)
1337 WsParamSetI parmSet = null;
1340 parmSet = service.getParamStore().parseServiceParameterFile(
1341 calcIdParam.getName(), calcIdParam.getDescription(),
1342 calcIdParam.getServiceURL(),
1343 calcIdParam.getParameters().replace("|\\n|", "\n"));
1344 } catch (IOException x)
1346 warn("Couldn't parse parameter data for "
1347 + calcIdParam.getCalcId(), x);
1350 List<ArgumentI> argList = null;
1351 if (calcIdParam.getName().length() > 0)
1353 parmSet = service.getParamStore()
1354 .getPreset(calcIdParam.getName());
1355 if (parmSet != null)
1357 // TODO : check we have a good match with settings in AACons -
1358 // otherwise we'll need to create a new preset
1363 argList = parmSet.getArguments();
1366 AAConsSettings settings = new AAConsSettings(
1367 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1368 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1369 calcIdParam.isNeedsUpdate());
1374 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1378 throw new Error("Unsupported Version for calcIdparam "
1379 + calcIdParam.toString());
1383 * External mapping between jalview objects and objects yielding a valid and
1384 * unique object ID string. This is null for normal Jalview project IO, but
1385 * non-null when a jalview project is being read or written as part of a
1388 IdentityHashMap jv2vobj = null;
1391 * Construct a unique ID for jvobj using either existing bindings or if none
1392 * exist, the result of the hashcode call for the object.
1395 * jalview data object
1396 * @return unique ID for referring to jvobj
1398 private String makeHashCode(Object jvobj, String altCode)
1400 if (jv2vobj != null)
1402 Object id = jv2vobj.get(jvobj);
1405 return id.toString();
1407 // check string ID mappings
1408 if (jvids2vobj != null && jvobj instanceof String)
1410 id = jvids2vobj.get(jvobj);
1414 return id.toString();
1416 // give up and warn that something has gone wrong
1417 warn("Cannot find ID for object in external mapping : " + jvobj);
1423 * return local jalview object mapped to ID, if it exists
1427 * @return null or object bound to idcode
1429 private Object retrieveExistingObj(String idcode)
1431 if (idcode != null && vobj2jv != null)
1433 return vobj2jv.get(idcode);
1439 * binding from ID strings from external mapping table to jalview data model
1442 private Hashtable vobj2jv;
1444 private Sequence createVamsasSequence(String id, SequenceI jds)
1446 return createVamsasSequence(true, id, jds, null);
1449 private Sequence createVamsasSequence(boolean recurse, String id,
1450 SequenceI jds, SequenceI parentseq)
1452 Sequence vamsasSeq = new Sequence();
1453 vamsasSeq.setId(id);
1454 vamsasSeq.setName(jds.getName());
1455 vamsasSeq.setSequence(jds.getSequenceAsString());
1456 vamsasSeq.setDescription(jds.getDescription());
1457 jalview.datamodel.DBRefEntry[] dbrefs = null;
1458 if (jds.getDatasetSequence() != null)
1460 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
1461 if (jds.getDatasetSequence().getDBRef() != null)
1463 dbrefs = jds.getDatasetSequence().getDBRef();
1468 vamsasSeq.setDsseqid(id); // so we can tell which sequences really are
1469 // dataset sequences only
1470 dbrefs = jds.getDBRef();
1474 for (int d = 0; d < dbrefs.length; d++)
1476 DBRef dbref = new DBRef();
1477 dbref.setSource(dbrefs[d].getSource());
1478 dbref.setVersion(dbrefs[d].getVersion());
1479 dbref.setAccessionId(dbrefs[d].getAccessionId());
1480 if (dbrefs[d].hasMap())
1482 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
1484 dbref.setMapping(mp);
1486 vamsasSeq.addDBRef(dbref);
1492 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
1493 SequenceI parentseq, SequenceI jds, boolean recurse)
1496 if (jmp.getMap() != null)
1500 jalview.util.MapList mlst = jmp.getMap();
1501 int r[] = mlst.getFromRanges();
1502 for (int s = 0; s < r.length; s += 2)
1504 MapListFrom mfrom = new MapListFrom();
1505 mfrom.setStart(r[s]);
1506 mfrom.setEnd(r[s + 1]);
1507 mp.addMapListFrom(mfrom);
1509 r = mlst.getToRanges();
1510 for (int s = 0; s < r.length; s += 2)
1512 MapListTo mto = new MapListTo();
1514 mto.setEnd(r[s + 1]);
1515 mp.addMapListTo(mto);
1517 mp.setMapFromUnit(mlst.getFromRatio());
1518 mp.setMapToUnit(mlst.getToRatio());
1519 if (jmp.getTo() != null)
1521 MappingChoice mpc = new MappingChoice();
1523 && (parentseq != jmp.getTo() || parentseq
1524 .getDatasetSequence() != jmp.getTo()))
1526 mpc.setSequence(createVamsasSequence(false, seqHash(jmp.getTo()),
1532 SequenceI ps = null;
1533 if (parentseq != jmp.getTo()
1534 && parentseq.getDatasetSequence() != jmp.getTo())
1536 // chaining dbref rather than a handshaking one
1537 jmpid = seqHash(ps = jmp.getTo());
1541 jmpid = seqHash(ps = parentseq);
1543 mpc.setDseqFor(jmpid);
1544 if (!seqRefIds.containsKey(mpc.getDseqFor()))
1546 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
1547 seqRefIds.put(mpc.getDseqFor(), ps);
1551 jalview.bin.Cache.log.debug("reusing DseqFor ID");
1554 mp.setMappingChoice(mpc);
1560 String SetUserColourScheme(jalview.schemes.ColourSchemeI cs,
1561 Vector userColours, JalviewModelSequence jms)
1564 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
1565 boolean newucs = false;
1566 if (!userColours.contains(ucs))
1568 userColours.add(ucs);
1571 id = "ucs" + userColours.indexOf(ucs);
1574 // actually create the scheme's entry in the XML model
1575 java.awt.Color[] colours = ucs.getColours();
1576 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
1577 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
1579 for (int i = 0; i < colours.length; i++)
1581 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1582 col.setName(ResidueProperties.aa[i]);
1583 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1584 jbucs.addColour(col);
1586 if (ucs.getLowerCaseColours() != null)
1588 colours = ucs.getLowerCaseColours();
1589 for (int i = 0; i < colours.length; i++)
1591 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1592 col.setName(ResidueProperties.aa[i].toLowerCase());
1593 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1594 jbucs.addColour(col);
1599 uc.setUserColourScheme(jbucs);
1600 jms.addUserColours(uc);
1606 jalview.schemes.UserColourScheme GetUserColourScheme(
1607 JalviewModelSequence jms, String id)
1609 UserColours[] uc = jms.getUserColours();
1610 UserColours colours = null;
1612 for (int i = 0; i < uc.length; i++)
1614 if (uc[i].getId().equals(id))
1622 java.awt.Color[] newColours = new java.awt.Color[24];
1624 for (int i = 0; i < 24; i++)
1626 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1627 .getUserColourScheme().getColour(i).getRGB(), 16));
1630 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
1633 if (colours.getUserColourScheme().getColourCount() > 24)
1635 newColours = new java.awt.Color[23];
1636 for (int i = 0; i < 23; i++)
1638 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1639 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
1641 ucs.setLowerCaseColours(newColours);
1648 * contains last error message (if any) encountered by XML loader.
1650 String errorMessage = null;
1653 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
1654 * exceptions are raised during project XML parsing
1656 public boolean attemptversion1parse = true;
1659 * Load a jalview project archive from a jar file
1662 * - HTTP URL or filename
1664 public AlignFrame LoadJalviewAlign(final String file)
1667 jalview.gui.AlignFrame af = null;
1671 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
1672 // Workaround is to make sure caller implements the JarInputStreamProvider
1674 // so we can re-open the jar input stream for each entry.
1676 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
1677 af = LoadJalviewAlign(jprovider);
1678 } catch (MalformedURLException e)
1680 errorMessage = "Invalid URL format for '" + file + "'";
1686 private jarInputStreamProvider createjarInputStreamProvider(
1687 final String file) throws MalformedURLException
1690 errorMessage = null;
1691 uniqueSetSuffix = null;
1693 viewportsAdded = null;
1694 frefedSequence = null;
1696 if (file.startsWith("http://"))
1698 url = new URL(file);
1700 final URL _url = url;
1701 return new jarInputStreamProvider()
1705 public JarInputStream getJarInputStream() throws IOException
1709 return new JarInputStream(_url.openStream());
1713 return new JarInputStream(new FileInputStream(file));
1718 public String getFilename()
1726 * Recover jalview session from a jalview project archive. Caller may
1727 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
1728 * themselves. Any null fields will be initialised with default values,
1729 * non-null fields are left alone.
1734 public AlignFrame LoadJalviewAlign(final jarInputStreamProvider jprovider)
1736 errorMessage = null;
1737 if (uniqueSetSuffix == null)
1739 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
1741 if (seqRefIds == null)
1743 seqRefIds = new Hashtable();
1745 if (viewportsAdded == null)
1747 viewportsAdded = new Hashtable();
1749 if (frefedSequence == null)
1751 frefedSequence = new Vector();
1754 jalview.gui.AlignFrame af = null;
1755 Hashtable gatherToThisFrame = new Hashtable();
1756 final String file = jprovider.getFilename();
1759 JarInputStream jin = null;
1760 JarEntry jarentry = null;
1765 jin = jprovider.getJarInputStream();
1766 for (int i = 0; i < entryCount; i++)
1768 jarentry = jin.getNextJarEntry();
1771 if (jarentry != null && jarentry.getName().endsWith(".xml"))
1773 InputStreamReader in = new InputStreamReader(jin, "UTF-8");
1774 JalviewModel object = new JalviewModel();
1776 Unmarshaller unmar = new Unmarshaller(object);
1777 unmar.setValidation(false);
1778 object = (JalviewModel) unmar.unmarshal(in);
1779 if (true) // !skipViewport(object))
1781 af = LoadFromObject(object, file, true, jprovider);
1782 if (af.viewport.gatherViewsHere)
1784 gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
1789 else if (jarentry != null)
1791 // Some other file here.
1794 } while (jarentry != null);
1795 resolveFrefedSequences();
1796 } catch (java.io.FileNotFoundException ex)
1798 ex.printStackTrace();
1799 errorMessage = "Couldn't locate Jalview XML file : " + file;
1800 System.err.println("Exception whilst loading jalview XML file : "
1802 } catch (java.net.UnknownHostException ex)
1804 ex.printStackTrace();
1805 errorMessage = "Couldn't locate Jalview XML file : " + file;
1806 System.err.println("Exception whilst loading jalview XML file : "
1808 } catch (Exception ex)
1810 System.err.println("Parsing as Jalview Version 2 file failed.");
1811 ex.printStackTrace(System.err);
1812 if (attemptversion1parse)
1814 // Is Version 1 Jar file?
1817 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
1818 } catch (Exception ex2)
1820 System.err.println("Exception whilst loading as jalviewXMLV1:");
1821 ex2.printStackTrace();
1825 if (Desktop.instance != null)
1827 Desktop.instance.stopLoading();
1831 System.out.println("Successfully loaded archive file");
1834 ex.printStackTrace();
1836 System.err.println("Exception whilst loading jalview XML file : "
1838 } catch (OutOfMemoryError e)
1840 // Don't use the OOM Window here
1841 errorMessage = "Out of memory loading jalview XML file";
1842 System.err.println("Out of memory whilst loading jalview XML file");
1843 e.printStackTrace();
1846 if (Desktop.instance != null)
1848 Desktop.instance.stopLoading();
1851 Enumeration en = gatherToThisFrame.elements();
1852 while (en.hasMoreElements())
1854 Desktop.instance.gatherViews((AlignFrame) en.nextElement());
1856 if (errorMessage != null)
1864 * check errorMessage for a valid error message and raise an error box in the
1865 * GUI or write the current errorMessage to stderr and then clear the error
1868 protected void reportErrors()
1870 reportErrors(false);
1873 protected void reportErrors(final boolean saving)
1875 if (errorMessage != null)
1877 final String finalErrorMessage = errorMessage;
1880 javax.swing.SwingUtilities.invokeLater(new Runnable()
1885 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1886 finalErrorMessage, "Error "
1887 + (saving ? "saving" : "loading")
1888 + " Jalview file", JOptionPane.WARNING_MESSAGE);
1894 System.err.println("Problem loading Jalview file: " + errorMessage);
1897 errorMessage = null;
1900 Hashtable alreadyLoadedPDB;
1903 * when set, local views will be updated from view stored in JalviewXML
1904 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
1905 * sync if this is set to true.
1907 private final boolean updateLocalViews = false;
1909 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
1911 if (alreadyLoadedPDB == null)
1912 alreadyLoadedPDB = new Hashtable();
1914 if (alreadyLoadedPDB.containsKey(pdbId))
1915 return alreadyLoadedPDB.get(pdbId).toString();
1919 JarInputStream jin = jprovider.getJarInputStream();
1921 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
1922 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
1923 * FileInputStream(jprovider)); }
1926 JarEntry entry = null;
1929 entry = jin.getNextJarEntry();
1930 } while (entry != null && !entry.getName().equals(pdbId));
1933 BufferedReader in = new BufferedReader(new InputStreamReader(jin));
1934 File outFile = File.createTempFile("jalview_pdb", ".txt");
1935 outFile.deleteOnExit();
1936 PrintWriter out = new PrintWriter(new FileOutputStream(outFile));
1939 while ((data = in.readLine()) != null)
1946 } catch (Exception foo)
1951 String t = outFile.getAbsolutePath();
1952 alreadyLoadedPDB.put(pdbId, t);
1957 warn("Couldn't find PDB file entry in Jalview Jar for " + pdbId);
1959 } catch (Exception ex)
1961 ex.printStackTrace();
1967 private class JvAnnotRow
1969 public JvAnnotRow(int i, AlignmentAnnotation jaa)
1976 * persisted version of annotation row from which to take vis properties
1978 public jalview.datamodel.AlignmentAnnotation template;
1981 * original position of the annotation row in the alignment
1987 * Load alignment frame from jalview XML DOM object
1992 * filename source string
1993 * @param loadTreesAndStructures
1994 * when false only create Viewport
1996 * data source provider
1997 * @return alignment frame created from view stored in DOM
1999 AlignFrame LoadFromObject(JalviewModel object, String file,
2000 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2002 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2003 Sequence[] vamsasSeq = vamsasSet.getSequence();
2005 JalviewModelSequence jms = object.getJalviewModelSequence();
2007 Viewport view = jms.getViewport(0);
2008 // ////////////////////////////////
2011 Vector hiddenSeqs = null;
2012 jalview.datamodel.Sequence jseq;
2014 ArrayList tmpseqs = new ArrayList();
2016 boolean multipleView = false;
2018 JSeq[] JSEQ = object.getJalviewModelSequence().getJSeq();
2019 int vi = 0; // counter in vamsasSeq array
2020 for (int i = 0; i < JSEQ.length; i++)
2022 String seqId = JSEQ[i].getId();
2024 if (seqRefIds.get(seqId) != null)
2026 tmpseqs.add(seqRefIds.get(seqId));
2027 multipleView = true;
2031 jseq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2032 vamsasSeq[vi].getSequence());
2033 jseq.setDescription(vamsasSeq[vi].getDescription());
2034 jseq.setStart(JSEQ[i].getStart());
2035 jseq.setEnd(JSEQ[i].getEnd());
2036 jseq.setVamsasId(uniqueSetSuffix + seqId);
2037 seqRefIds.put(vamsasSeq[vi].getId(), jseq);
2042 if (JSEQ[i].getHidden())
2044 if (hiddenSeqs == null)
2046 hiddenSeqs = new Vector();
2049 hiddenSeqs.addElement(seqRefIds.get(seqId));
2055 // Create the alignment object from the sequence set
2056 // ///////////////////////////////
2057 jalview.datamodel.Sequence[] orderedSeqs = new jalview.datamodel.Sequence[tmpseqs
2060 tmpseqs.toArray(orderedSeqs);
2062 jalview.datamodel.Alignment al = new jalview.datamodel.Alignment(
2065 // / Add the alignment properties
2066 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2068 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2069 al.setProperty(ssp.getKey(), ssp.getValue());
2073 // SequenceFeatures are added to the DatasetSequence,
2074 // so we must create or recover the dataset before loading features
2075 // ///////////////////////////////
2076 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2078 // older jalview projects do not have a dataset id.
2079 al.setDataset(null);
2083 recoverDatasetFor(vamsasSet, al);
2085 // ///////////////////////////////
2087 Hashtable pdbloaded = new Hashtable();
2090 // load sequence features, database references and any associated PDB
2091 // structures for the alignment
2092 for (int i = 0; i < vamsasSeq.length; i++)
2094 if (JSEQ[i].getFeaturesCount() > 0)
2096 Features[] features = JSEQ[i].getFeatures();
2097 for (int f = 0; f < features.length; f++)
2099 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2100 features[f].getType(), features[f].getDescription(),
2101 features[f].getStatus(), features[f].getBegin(),
2102 features[f].getEnd(), features[f].getFeatureGroup());
2104 sf.setScore(features[f].getScore());
2105 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2107 OtherData keyValue = features[f].getOtherData(od);
2108 if (keyValue.getKey().startsWith("LINK"))
2110 sf.addLink(keyValue.getValue());
2114 sf.setValue(keyValue.getKey(), keyValue.getValue());
2119 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
2122 if (vamsasSeq[i].getDBRefCount() > 0)
2124 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2126 if (JSEQ[i].getPdbidsCount() > 0)
2128 Pdbids[] ids = JSEQ[i].getPdbids();
2129 for (int p = 0; p < ids.length; p++)
2131 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2132 entry.setId(ids[p].getId());
2133 entry.setType(ids[p].getType());
2134 if (ids[p].getFile() != null)
2136 if (!pdbloaded.containsKey(ids[p].getFile()))
2138 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2142 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2146 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2150 } // end !multipleview
2152 // ///////////////////////////////
2153 // LOAD SEQUENCE MAPPINGS
2155 if (vamsasSet.getAlcodonFrameCount() > 0)
2157 // TODO Potentially this should only be done once for all views of an
2159 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2160 for (int i = 0; i < alc.length; i++)
2162 jalview.datamodel.AlignedCodonFrame cf = new jalview.datamodel.AlignedCodonFrame(
2163 alc[i].getAlcodonCount());
2164 if (alc[i].getAlcodonCount() > 0)
2166 Alcodon[] alcods = alc[i].getAlcodon();
2167 for (int p = 0; p < cf.codons.length; p++)
2169 if (alcods[p].hasPos1() && alcods[p].hasPos2()
2170 && alcods[p].hasPos3())
2172 // translated codons require three valid positions
2173 cf.codons[p] = new int[3];
2174 cf.codons[p][0] = (int) alcods[p].getPos1();
2175 cf.codons[p][1] = (int) alcods[p].getPos2();
2176 cf.codons[p][2] = (int) alcods[p].getPos3();
2180 cf.codons[p] = null;
2184 if (alc[i].getAlcodMapCount() > 0)
2186 AlcodMap[] maps = alc[i].getAlcodMap();
2187 for (int m = 0; m < maps.length; m++)
2189 SequenceI dnaseq = (SequenceI) seqRefIds
2190 .get(maps[m].getDnasq());
2192 jalview.datamodel.Mapping mapping = null;
2193 // attach to dna sequence reference.
2194 if (maps[m].getMapping() != null)
2196 mapping = addMapping(maps[m].getMapping());
2200 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
2205 frefedSequence.add(new Object[]
2206 { maps[m].getDnasq(), cf, mapping });
2210 al.addCodonFrame(cf);
2215 // ////////////////////////////////
2217 ArrayList<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
2219 * store any annotations which forward reference a group's ID
2221 Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>>();
2223 if (vamsasSet.getAnnotationCount() > 0)
2225 Annotation[] an = vamsasSet.getAnnotation();
2227 for (int i = 0; i < an.length; i++)
2230 * test if annotation is automatically calculated for this view only
2232 boolean autoForView = false;
2233 if (an[i].getLabel().equals("Quality")
2234 || an[i].getLabel().equals("Conservation")
2235 || an[i].getLabel().equals("Consensus"))
2237 // Kludge for pre 2.5 projects which lacked the autocalculated flag
2239 if (!an[i].hasAutoCalculated())
2241 an[i].setAutoCalculated(true);
2245 || (an[i].hasAutoCalculated() && an[i].isAutoCalculated()))
2247 // remove ID - we don't recover annotation from other views for
2248 // view-specific annotation
2252 // set visiblity for other annotation in this view
2253 if (an[i].getId() != null
2254 && annotationIds.containsKey(an[i].getId()))
2256 jalview.datamodel.AlignmentAnnotation jda = (jalview.datamodel.AlignmentAnnotation) annotationIds
2257 .get(an[i].getId());
2258 // in principle Visible should always be true for annotation displayed
2259 // in multiple views
2260 if (an[i].hasVisible())
2261 jda.visible = an[i].getVisible();
2263 al.addAnnotation(jda);
2267 // Construct new annotation from model.
2268 AnnotationElement[] ae = an[i].getAnnotationElement();
2269 jalview.datamodel.Annotation[] anot = null;
2270 java.awt.Color firstColour=null;
2272 if (!an[i].getScoreOnly())
2274 anot = new jalview.datamodel.Annotation[al.getWidth()];
2275 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
2277 anpos = ae[aa].getPosition();
2279 if (anpos >= anot.length)
2282 anot[anpos] = new jalview.datamodel.Annotation(
2284 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
2285 (ae[aa].getSecondaryStructure() == null || ae[aa]
2286 .getSecondaryStructure().length() == 0) ? ' '
2287 : ae[aa].getSecondaryStructure().charAt(0),
2291 // JBPNote: Consider verifying dataflow for IO of secondary
2292 // structure annotation read from Stockholm files
2293 // this was added to try to ensure that
2294 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
2296 // anot[ae[aa].getPosition()].displayCharacter = "";
2298 anot[anpos].colour = new java.awt.Color(
2299 ae[aa].getColour());
2300 if (firstColour==null)
2302 firstColour=anot[anpos].colour;
2306 jalview.datamodel.AlignmentAnnotation jaa = null;
2308 if (an[i].getGraph())
2310 float llim = 0, hlim = 0;
2311 // if (autoForView || an[i].isAutoCalculated()) {
2314 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2315 an[i].getDescription(), anot, llim, hlim,
2316 an[i].getGraphType());
2318 jaa.graphGroup = an[i].getGraphGroup();
2319 jaa._linecolour=firstColour;
2320 if (an[i].getThresholdLine() != null)
2322 jaa.setThreshold(new jalview.datamodel.GraphLine(an[i]
2323 .getThresholdLine().getValue(), an[i]
2324 .getThresholdLine().getLabel(), new java.awt.Color(
2325 an[i].getThresholdLine().getColour())));
2328 if (autoForView || an[i].isAutoCalculated())
2330 // Hardwire the symbol display line to ensure that labels for
2331 // histograms are displayed
2337 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2338 an[i].getDescription(), anot);
2339 jaa._linecolour=firstColour;
2341 // register new annotation
2342 if (an[i].getId() != null)
2344 annotationIds.put(an[i].getId(), jaa);
2345 jaa.annotationId = an[i].getId();
2347 // recover sequence association
2348 if (an[i].getSequenceRef() != null)
2350 if (al.findName(an[i].getSequenceRef()) != null)
2352 jaa.createSequenceMapping(al.findName(an[i].getSequenceRef()),
2354 al.findName(an[i].getSequenceRef()).addAlignmentAnnotation(jaa);
2357 // and make a note of any group association
2358 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
2360 ArrayList<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
2361 .get(an[i].getGroupRef());
2364 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
2365 groupAnnotRefs.put(an[i].getGroupRef(), aal);
2370 if (an[i].hasScore())
2372 jaa.setScore(an[i].getScore());
2374 if (an[i].hasVisible())
2375 jaa.visible = an[i].getVisible();
2377 if (an[i].hasCentreColLabels())
2378 jaa.centreColLabels = an[i].getCentreColLabels();
2380 if (an[i].hasScaleColLabels())
2382 jaa.scaleColLabel = an[i].getScaleColLabels();
2384 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
2386 // newer files have an 'autoCalculated' flag and store calculation
2387 // state in viewport properties
2388 jaa.autoCalculated = true; // means annotation will be marked for
2389 // update at end of load.
2391 if (an[i].hasGraphHeight())
2393 jaa.graphHeight = an[i].getGraphHeight();
2395 if (an[i].hasBelowAlignment())
2397 jaa.belowAlignment = an[i].isBelowAlignment();
2399 jaa.setCalcId(an[i].getCalcId());
2401 if (jaa.autoCalculated)
2403 autoAlan.add(new JvAnnotRow(i, jaa));
2406 // if (!autoForView)
2408 // add autocalculated group annotation and any user created annotation
2410 al.addAnnotation(jaa);
2415 // ///////////////////////
2417 // Create alignment markup and styles for this view
2418 if (jms.getJGroupCount() > 0)
2420 JGroup[] groups = jms.getJGroup();
2422 for (int i = 0; i < groups.length; i++)
2424 ColourSchemeI cs = null;
2426 if (groups[i].getColour() != null)
2428 if (groups[i].getColour().startsWith("ucs"))
2430 cs = GetUserColourScheme(jms, groups[i].getColour());
2434 cs = ColourSchemeProperty.getColour(al, groups[i].getColour());
2439 cs.setThreshold(groups[i].getPidThreshold(), true);
2443 Vector seqs = new Vector();
2445 for (int s = 0; s < groups[i].getSeqCount(); s++)
2447 String seqId = groups[i].getSeq(s) + "";
2448 jalview.datamodel.SequenceI ts = (jalview.datamodel.SequenceI) seqRefIds
2453 seqs.addElement(ts);
2457 if (seqs.size() < 1)
2462 jalview.datamodel.SequenceGroup sg = new jalview.datamodel.SequenceGroup(
2463 seqs, groups[i].getName(), cs, groups[i].getDisplayBoxes(),
2464 groups[i].getDisplayText(), groups[i].getColourText(),
2465 groups[i].getStart(), groups[i].getEnd());
2467 sg.setOutlineColour(new java.awt.Color(groups[i].getOutlineColour()));
2469 sg.textColour = new java.awt.Color(groups[i].getTextCol1());
2470 sg.textColour2 = new java.awt.Color(groups[i].getTextCol2());
2471 sg.setShowNonconserved(groups[i].hasShowUnconserved() ? groups[i]
2472 .isShowUnconserved() : false);
2473 sg.thresholdTextColour = groups[i].getTextColThreshold();
2474 if (groups[i].hasShowConsensusHistogram())
2476 sg.setShowConsensusHistogram(groups[i].isShowConsensusHistogram());
2479 if (groups[i].hasShowSequenceLogo())
2481 sg.setshowSequenceLogo(groups[i].isShowSequenceLogo());
2483 if (groups[i].hasIgnoreGapsinConsensus())
2485 sg.setIgnoreGapsConsensus(groups[i].getIgnoreGapsinConsensus());
2487 if (groups[i].getConsThreshold() != 0)
2489 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
2490 "All", ResidueProperties.propHash, 3,
2491 sg.getSequences(null), 0, sg.getWidth() - 1);
2493 c.verdict(false, 25);
2494 sg.cs.setConservation(c);
2497 if (groups[i].getId() != null && groupAnnotRefs.size() > 0)
2499 // re-instate unique group/annotation row reference
2500 ArrayList<jalview.datamodel.AlignmentAnnotation> jaal = groupAnnotRefs
2501 .get(groups[i].getId());
2504 for (jalview.datamodel.AlignmentAnnotation jaa : jaal)
2507 if (jaa.autoCalculated)
2509 // match up and try to set group autocalc alignment row for this
2511 if (jaa.label.startsWith("Consensus for "))
2513 sg.setConsensus(jaa);
2515 // match up and try to set group autocalc alignment row for this
2517 if (jaa.label.startsWith("Conservation for "))
2519 sg.setConservationRow(jaa);
2530 // ///////////////////////////////
2533 // If we just load in the same jar file again, the sequenceSetId
2534 // will be the same, and we end up with multiple references
2535 // to the same sequenceSet. We must modify this id on load
2536 // so that each load of the file gives a unique id
2537 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
2538 String viewId = (view.getId() == null ? null : view.getId()
2540 AlignFrame af = null;
2541 AlignViewport av = null;
2542 // now check to see if we really need to create a new viewport.
2543 if (multipleView && viewportsAdded.size() == 0)
2545 // We recovered an alignment for which a viewport already exists.
2546 // TODO: fix up any settings necessary for overlaying stored state onto
2547 // state recovered from another document. (may not be necessary).
2548 // we may need a binding from a viewport in memory to one recovered from
2550 // and then recover its containing af to allow the settings to be applied.
2551 // TODO: fix for vamsas demo
2553 .println("About to recover a viewport for existing alignment: Sequence set ID is "
2555 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
2556 if (seqsetobj != null)
2558 if (seqsetobj instanceof String)
2560 uniqueSeqSetId = (String) seqsetobj;
2562 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
2568 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
2573 AlignmentPanel ap = null;
2574 boolean isnewview = true;
2577 // Check to see if this alignment already has a view id == viewId
2578 jalview.gui.AlignmentPanel views[] = Desktop
2579 .getAlignmentPanels(uniqueSeqSetId);
2580 if (views != null && views.length > 0)
2582 for (int v = 0; v < views.length; v++)
2584 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
2586 // recover the existing alignpanel, alignframe, viewport
2587 af = views[v].alignFrame;
2590 // TODO: could even skip resetting view settings if we don't want to
2591 // change the local settings from other jalview processes
2600 af = loadViewport(file, JSEQ, hiddenSeqs, al, jms, view,
2601 uniqueSeqSetId, viewId, autoAlan);
2606 // /////////////////////////////////////
2607 if (loadTreesAndStructures && jms.getTreeCount() > 0)
2611 for (int t = 0; t < jms.getTreeCount(); t++)
2614 Tree tree = jms.getTree(t);
2616 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
2619 tp = af.ShowNewickTree(
2620 new jalview.io.NewickFile(tree.getNewick()),
2621 tree.getTitle(), tree.getWidth(), tree.getHeight(),
2622 tree.getXpos(), tree.getYpos());
2623 if (tree.getId() != null)
2625 // perhaps bind the tree id to something ?
2630 // update local tree attributes ?
2631 // TODO: should check if tp has been manipulated by user - if so its
2632 // settings shouldn't be modified
2633 tp.setTitle(tree.getTitle());
2634 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
2635 .getWidth(), tree.getHeight()));
2636 tp.av = av; // af.viewport; // TODO: verify 'associate with all
2639 tp.treeCanvas.av = av; // af.viewport;
2640 tp.treeCanvas.ap = ap; // af.alignPanel;
2645 warn("There was a problem recovering stored Newick tree: \n"
2646 + tree.getNewick());
2650 tp.fitToWindow.setState(tree.getFitToWindow());
2651 tp.fitToWindow_actionPerformed(null);
2653 if (tree.getFontName() != null)
2655 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
2656 .getFontStyle(), tree.getFontSize()));
2660 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
2661 .getFontStyle(), tree.getFontSize()));
2664 tp.showPlaceholders(tree.getMarkUnlinked());
2665 tp.showBootstrap(tree.getShowBootstrap());
2666 tp.showDistances(tree.getShowDistances());
2668 tp.treeCanvas.threshold = tree.getThreshold();
2670 if (tree.getCurrentTree())
2672 af.viewport.setCurrentTree(tp.getTree());
2676 } catch (Exception ex)
2678 ex.printStackTrace();
2682 // //LOAD STRUCTURES
2683 if (loadTreesAndStructures)
2685 // run through all PDB ids on the alignment, and collect mappings between
2686 // jmol view ids and all sequences referring to it
2687 Hashtable<String, Object[]> jmolViewIds = new Hashtable();
2689 for (int i = 0; i < JSEQ.length; i++)
2691 if (JSEQ[i].getPdbidsCount() > 0)
2693 Pdbids[] ids = JSEQ[i].getPdbids();
2694 for (int p = 0; p < ids.length; p++)
2696 for (int s = 0; s < ids[p].getStructureStateCount(); s++)
2698 // check to see if we haven't already created this structure view
2699 String sviewid = (ids[p].getStructureState(s).getViewId() == null) ? null
2700 : ids[p].getStructureState(s).getViewId()
2702 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
2703 // Originally : ids[p].getFile()
2704 // : TODO: verify external PDB file recovery still works in normal
2705 // jalview project load
2706 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
2707 jpdb.setId(ids[p].getId());
2709 int x = ids[p].getStructureState(s).getXpos();
2710 int y = ids[p].getStructureState(s).getYpos();
2711 int width = ids[p].getStructureState(s).getWidth();
2712 int height = ids[p].getStructureState(s).getHeight();
2714 // Probably don't need to do this anymore...
2715 // Desktop.desktop.getComponentAt(x, y);
2716 // TODO: NOW: check that this recovers the PDB file correctly.
2717 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
2718 jalview.datamodel.SequenceI seq = (jalview.datamodel.SequenceI) seqRefIds
2719 .get(JSEQ[i].getId() + "");
2720 if (sviewid == null)
2722 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
2725 if (!jmolViewIds.containsKey(sviewid))
2727 jmolViewIds.put(sviewid, new Object[]
2729 { x, y, width, height }, "",
2730 new Hashtable<String, Object[]>(), new boolean[]
2731 { false, false, true } });
2732 // Legacy pre-2.7 conversion JAL-823 :
2733 // do not assume any view has to be linked for colour by
2737 // assemble String[] { pdb files }, String[] { id for each
2738 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
2739 // seqs_file 2}, boolean[] {
2740 // linkAlignPanel,superposeWithAlignpanel}} from hash
2741 Object[] jmoldat = jmolViewIds.get(sviewid);
2742 ((boolean[]) jmoldat[3])[0] |= ids[p].getStructureState(s)
2743 .hasAlignwithAlignPanel() ? ids[p].getStructureState(
2744 s).getAlignwithAlignPanel() : false;
2745 // never colour by linked panel if not specified
2746 ((boolean[]) jmoldat[3])[1] |= ids[p].getStructureState(s)
2747 .hasColourwithAlignPanel() ? ids[p]
2748 .getStructureState(s).getColourwithAlignPanel()
2750 // default for pre-2.7 projects is that Jmol colouring is enabled
2751 ((boolean[]) jmoldat[3])[2] &= ids[p].getStructureState(s)
2752 .hasColourByJmol() ? ids[p].getStructureState(s)
2753 .getColourByJmol() : true;
2755 if (((String) jmoldat[1]).length() < ids[p]
2756 .getStructureState(s).getContent().length())
2759 jmoldat[1] = ids[p].getStructureState(s).getContent();
2762 if (ids[p].getFile() != null)
2764 File mapkey = new File(ids[p].getFile());
2765 Object[] seqstrmaps = (Object[]) ((Hashtable) jmoldat[2])
2767 if (seqstrmaps == null)
2769 ((Hashtable) jmoldat[2]).put(mapkey,
2770 seqstrmaps = new Object[]
2771 { pdbFile, ids[p].getId(), new Vector(),
2774 if (!((Vector) seqstrmaps[2]).contains(seq))
2776 ((Vector) seqstrmaps[2]).addElement(seq);
2777 // ((Vector)seqstrmaps[3]).addElement(n) :
2778 // in principle, chains
2779 // should be stored here : do we need to
2780 // TODO: store and recover seq/pdb_id :
2786 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");
2795 // Instantiate the associated Jmol views
2796 for (Entry<String, Object[]> entry : jmolViewIds.entrySet())
2798 String sviewid = entry.getKey();
2799 Object[] svattrib = entry.getValue();
2800 int[] geom = (int[]) svattrib[0];
2801 String state = (String) svattrib[1];
2802 Hashtable<File, Object[]> oldFiles = (Hashtable<File, Object[]>) svattrib[2];
2803 final boolean useinJmolsuperpos = ((boolean[]) svattrib[3])[0], usetoColourbyseq = ((boolean[]) svattrib[3])[1], jmolColouring = ((boolean[]) svattrib[3])[2];
2804 int x = geom[0], y = geom[1], width = geom[2], height = geom[3];
2805 // collate the pdbfile -> sequence mappings from this view
2806 Vector<String> pdbfilenames = new Vector<String>();
2807 Vector<SequenceI[]> seqmaps = new Vector<SequenceI[]>();
2808 Vector<String> pdbids = new Vector<String>();
2810 // Search to see if we've already created this Jmol view
2811 AppJmol comp = null;
2812 JInternalFrame[] frames = null;
2817 frames = Desktop.desktop.getAllFrames();
2818 } catch (ArrayIndexOutOfBoundsException e)
2820 // occasional No such child exceptions are thrown here...
2825 } catch (Exception f)
2830 } while (frames == null);
2831 // search for any Jmol windows already open from other
2832 // alignment views that exactly match the stored structure state
2833 for (int f = 0; comp == null && f < frames.length; f++)
2835 if (frames[f] instanceof AppJmol)
2838 && ((AppJmol) frames[f]).getViewId().equals(sviewid))
2840 // post jalview 2.4 schema includes structure view id
2841 comp = (AppJmol) frames[f];
2843 else if (frames[f].getX() == x && frames[f].getY() == y
2844 && frames[f].getHeight() == height
2845 && frames[f].getWidth() == width)
2847 comp = (AppJmol) frames[f];
2854 // create a new Jmol window.
2855 // First parse the Jmol state to translate filenames loaded into the
2856 // view, and record the order in which files are shown in the Jmol
2857 // view, so we can add the sequence mappings in same order.
2858 StringBuffer newFileLoc = null;
2859 int cp = 0, ncp, ecp;
2860 while ((ncp = state.indexOf("load ", cp)) > -1)
2862 if (newFileLoc == null)
2864 newFileLoc = new StringBuffer();
2868 // look for next filename in load statement
2869 newFileLoc.append(state.substring(cp,
2870 ncp = (state.indexOf("\"", ncp + 1) + 1)));
2871 String oldfilenam = state.substring(ncp,
2872 ecp = state.indexOf("\"", ncp));
2873 // recover the new mapping data for this old filename
2874 // have to normalize filename - since Jmol and jalview do
2876 // translation differently.
2877 Object[] filedat = oldFiles.get(new File(oldfilenam));
2878 newFileLoc.append(Platform
2879 .escapeString((String) filedat[0]));
2880 pdbfilenames.addElement((String) filedat[0]);
2881 pdbids.addElement((String) filedat[1]);
2882 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
2883 .toArray(new SequenceI[0]));
2884 newFileLoc.append("\"");
2885 cp = ecp + 1; // advance beyond last \" and set cursor so we can
2886 // look for next file statement.
2887 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
2891 // just append rest of state
2892 newFileLoc.append(state.substring(cp));
2897 .print("Ignoring incomplete Jmol state for PDB ids: ");
2898 newFileLoc = new StringBuffer(state);
2899 newFileLoc.append("; load append ");
2900 for (File id : oldFiles.keySet())
2902 // add this and any other pdb files that should be present in
2904 Object[] filedat = oldFiles.get(id);
2906 newFileLoc.append(((String) filedat[0]));
2907 pdbfilenames.addElement((String) filedat[0]);
2908 pdbids.addElement((String) filedat[1]);
2909 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
2910 .toArray(new SequenceI[0]));
2911 newFileLoc.append(" \"");
2912 newFileLoc.append((String) filedat[0]);
2913 newFileLoc.append("\"");
2916 newFileLoc.append(";");
2919 if (newFileLoc != null)
2921 int histbug = newFileLoc.indexOf("history = ");
2923 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";",
2925 String val = (diff == -1) ? null : newFileLoc.substring(
2927 if (val != null && val.length() >= 4)
2929 if (val.contains("e"))
2931 if (val.trim().equals("true"))
2939 newFileLoc.replace(histbug, diff, val);
2942 // TODO: assemble String[] { pdb files }, String[] { id for each
2943 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
2944 // seqs_file 2}} from hash
2945 final String[] pdbf = pdbfilenames
2946 .toArray(new String[pdbfilenames.size()]), id = pdbids
2947 .toArray(new String[pdbids.size()]);
2948 final SequenceI[][] sq = seqmaps
2949 .toArray(new SequenceI[seqmaps.size()][]);
2950 final String fileloc = newFileLoc.toString(), vid = sviewid;
2951 final AlignFrame alf = af;
2952 final java.awt.Rectangle rect = new java.awt.Rectangle(x, y,
2956 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
2961 AppJmol sview = null;
2964 sview = new AppJmol(pdbf, id, sq, alf.alignPanel,
2965 useinJmolsuperpos, usetoColourbyseq,
2966 jmolColouring, fileloc, rect, vid);
2967 } catch (OutOfMemoryError ex)
2969 new OOMWarning("restoring structure view for PDB id "
2970 + id, (OutOfMemoryError) ex.getCause());
2971 if (sview != null && sview.isVisible())
2973 sview.closeViewer();
2974 sview.setVisible(false);
2980 } catch (InvocationTargetException ex)
2982 warn("Unexpected error when opening Jmol view.", ex);
2984 } catch (InterruptedException e)
2986 // e.printStackTrace();
2992 // if (comp != null)
2994 // NOTE: if the jalview project is part of a shared session then
2995 // view synchronization should/could be done here.
2997 // add mapping for sequences in this view to an already open Jmol
2999 for (File id : oldFiles.keySet())
3001 // add this and any other pdb files that should be present in the
3003 Object[] filedat = oldFiles.get(id);
3004 String pdbFile = (String) filedat[0];
3005 SequenceI[] seq = ((Vector<SequenceI>) filedat[2])
3006 .toArray(new SequenceI[0]);
3007 comp.jmb.ssm.setMapping(seq, null, pdbFile,
3008 jalview.io.AppletFormatAdapter.FILE);
3009 comp.jmb.addSequenceForStructFile(pdbFile, seq);
3011 // and add the AlignmentPanel's reference to the Jmol view
3012 comp.addAlignmentPanel(ap);
3013 if (useinJmolsuperpos)
3015 comp.useAlignmentPanelForSuperposition(ap);
3019 comp.excludeAlignmentPanelForSuperposition(ap);
3021 if (usetoColourbyseq)
3023 comp.useAlignmentPanelForColourbyseq(ap, !jmolColouring);
3027 comp.excludeAlignmentPanelForColourbyseq(ap);
3033 // and finally return.
3037 AlignFrame loadViewport(String file, JSeq[] JSEQ, Vector hiddenSeqs,
3038 Alignment al, JalviewModelSequence jms, Viewport view,
3039 String uniqueSeqSetId, String viewId,
3040 ArrayList<JvAnnotRow> autoAlan)
3042 AlignFrame af = null;
3043 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
3044 uniqueSeqSetId, viewId);
3046 af.setFileName(file, "Jalview");
3048 for (int i = 0; i < JSEQ.length; i++)
3050 af.viewport.setSequenceColour(af.viewport.getAlignment()
3051 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
3054 af.viewport.gatherViewsHere = view.getGatheredViews();
3056 if (view.getSequenceSetId() != null)
3058 jalview.gui.AlignViewport av = (jalview.gui.AlignViewport) viewportsAdded
3059 .get(uniqueSeqSetId);
3061 af.viewport.setSequenceSetId(uniqueSeqSetId);
3064 // propagate shared settings to this new view
3065 af.viewport.historyList = av.historyList;
3066 af.viewport.redoList = av.redoList;
3070 viewportsAdded.put(uniqueSeqSetId, af.viewport);
3072 // TODO: check if this method can be called repeatedly without
3073 // side-effects if alignpanel already registered.
3074 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
3076 // apply Hidden regions to view.
3077 if (hiddenSeqs != null)
3079 for (int s = 0; s < JSEQ.length; s++)
3081 jalview.datamodel.SequenceGroup hidden = new jalview.datamodel.SequenceGroup();
3083 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
3086 al.getSequenceAt(JSEQ[s].getHiddenSequences(r)), false);
3088 af.viewport.hideRepSequences(al.getSequenceAt(s), hidden);
3091 jalview.datamodel.SequenceI[] hseqs = new jalview.datamodel.SequenceI[hiddenSeqs
3094 for (int s = 0; s < hiddenSeqs.size(); s++)
3096 hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s);
3099 af.viewport.hideSequence(hseqs);
3102 // recover view properties and display parameters
3103 if (view.getViewName() != null)
3105 af.viewport.viewName = view.getViewName();
3106 af.setInitialTabVisible();
3108 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
3111 af.viewport.setShowAnnotation(view.getShowAnnotation());
3112 af.viewport.setAbovePIDThreshold(view.getPidSelected());
3114 af.viewport.setColourText(view.getShowColourText());
3116 af.viewport.setConservationSelected(view.getConservationSelected());
3117 af.viewport.setShowJVSuffix(view.getShowFullId());
3118 af.viewport.rightAlignIds = view.getRightAlignIds();
3119 af.viewport.setFont(new java.awt.Font(view.getFontName(), view
3120 .getFontStyle(), view.getFontSize()));
3121 af.alignPanel.fontChanged();
3122 af.viewport.setRenderGaps(view.getRenderGaps());
3123 af.viewport.setWrapAlignment(view.getWrapAlignment());
3124 af.alignPanel.setWrapAlignment(view.getWrapAlignment());
3125 af.viewport.setShowAnnotation(view.getShowAnnotation());
3126 af.alignPanel.setAnnotationVisible(view.getShowAnnotation());
3128 af.viewport.setShowBoxes(view.getShowBoxes());
3130 af.viewport.setShowText(view.getShowText());
3132 af.viewport.textColour = new java.awt.Color(view.getTextCol1());
3133 af.viewport.textColour2 = new java.awt.Color(view.getTextCol2());
3134 af.viewport.thresholdTextColour = view.getTextColThreshold();
3135 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
3136 .isShowUnconserved() : false);
3137 af.viewport.setStartRes(view.getStartRes());
3138 af.viewport.setStartSeq(view.getStartSeq());
3140 ColourSchemeI cs = null;
3141 // apply colourschemes
3142 if (view.getBgColour() != null)
3144 if (view.getBgColour().startsWith("ucs"))
3146 cs = GetUserColourScheme(jms, view.getBgColour());
3148 else if (view.getBgColour().startsWith("Annotation"))
3150 // int find annotation
3151 if (af.viewport.getAlignment().getAlignmentAnnotation() != null)
3153 for (int i = 0; i < af.viewport.getAlignment()
3154 .getAlignmentAnnotation().length; i++)
3156 if (af.viewport.getAlignment().getAlignmentAnnotation()[i].label
3157 .equals(view.getAnnotationColours().getAnnotation()))
3159 if (af.viewport.getAlignment().getAlignmentAnnotation()[i]
3160 .getThreshold() == null)
3162 af.viewport.getAlignment().getAlignmentAnnotation()[i]
3163 .setThreshold(new jalview.datamodel.GraphLine(view
3164 .getAnnotationColours().getThreshold(),
3165 "Threshold", java.awt.Color.black)
3170 if (view.getAnnotationColours().getColourScheme()
3173 cs = new AnnotationColourGradient(af.viewport
3174 .getAlignment().getAlignmentAnnotation()[i],
3175 new java.awt.Color(view.getAnnotationColours()
3176 .getMinColour()), new java.awt.Color(view
3177 .getAnnotationColours().getMaxColour()),
3178 view.getAnnotationColours().getAboveThreshold());
3180 else if (view.getAnnotationColours().getColourScheme()
3183 cs = new AnnotationColourGradient(af.viewport
3184 .getAlignment().getAlignmentAnnotation()[i],
3185 GetUserColourScheme(jms, view
3186 .getAnnotationColours().getColourScheme()),
3187 view.getAnnotationColours().getAboveThreshold());
3191 cs = new AnnotationColourGradient(af.viewport
3192 .getAlignment().getAlignmentAnnotation()[i],
3193 ColourSchemeProperty.getColour(al, view
3194 .getAnnotationColours().getColourScheme()),
3195 view.getAnnotationColours().getAboveThreshold());
3198 // Also use these settings for all the groups
3199 if (al.getGroups() != null)
3201 for (int g = 0; g < al.getGroups().size(); g++)
3203 jalview.datamodel.SequenceGroup sg = al.getGroups()
3213 * (view.getAnnotationColours().getColourScheme().equals("None"
3214 * )) { sg.cs = new AnnotationColourGradient(
3215 * af.viewport.getAlignment().getAlignmentAnnotation()[i], new
3216 * java.awt.Color(view.getAnnotationColours().
3217 * getMinColour()), new
3218 * java.awt.Color(view.getAnnotationColours().
3220 * view.getAnnotationColours().getAboveThreshold()); } else
3223 sg.cs = new AnnotationColourGradient(af.viewport
3224 .getAlignment().getAlignmentAnnotation()[i],
3225 sg.cs, view.getAnnotationColours()
3226 .getAboveThreshold());
3240 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
3245 cs.setThreshold(view.getPidThreshold(), true);
3246 cs.setConsensus(af.viewport.getSequenceConsensusHash());
3250 af.viewport.setGlobalColourScheme(cs);
3251 af.viewport.setColourAppliesToAllGroups(false);
3253 if (view.getConservationSelected() && cs != null)
3255 cs.setConservationInc(view.getConsThreshold());
3258 af.changeColour(cs);
3260 af.viewport.setColourAppliesToAllGroups(true);
3262 if (view.getShowSequenceFeatures())
3264 af.viewport.showSequenceFeatures = true;
3266 if (view.hasCentreColumnLabels())
3268 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
3270 if (view.hasIgnoreGapsinConsensus())
3272 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
3275 if (view.hasFollowHighlight())
3277 af.viewport.followHighlight = view.getFollowHighlight();
3279 if (view.hasFollowSelection())
3281 af.viewport.followSelection = view.getFollowSelection();
3283 if (view.hasShowConsensusHistogram())
3285 af.viewport.setShowConsensusHistogram(view
3286 .getShowConsensusHistogram());
3290 af.viewport.setShowConsensusHistogram(true);
3292 if (view.hasShowSequenceLogo())
3294 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
3298 af.viewport.setShowSequenceLogo(false);
3300 if (view.hasShowDbRefTooltip())
3302 af.viewport.setShowDbRefs(view.getShowDbRefTooltip());
3304 if (view.hasShowNPfeatureTooltip())
3306 af.viewport.setShowNpFeats(view.hasShowNPfeatureTooltip());
3308 if (view.hasShowGroupConsensus())
3310 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
3314 af.viewport.setShowGroupConsensus(false);
3316 if (view.hasShowGroupConservation())
3318 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
3322 af.viewport.setShowGroupConservation(false);
3325 // recover featre settings
3326 if (jms.getFeatureSettings() != null)
3328 af.viewport.featuresDisplayed = new Hashtable();
3329 String[] renderOrder = new String[jms.getFeatureSettings()
3330 .getSettingCount()];
3331 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
3333 Setting setting = jms.getFeatureSettings().getSetting(fs);
3334 if (setting.hasMincolour())
3336 GraduatedColor gc = setting.hasMin() ? new GraduatedColor(
3337 new java.awt.Color(setting.getMincolour()),
3338 new java.awt.Color(setting.getColour()),
3339 setting.getMin(), setting.getMax()) : new GraduatedColor(
3340 new java.awt.Color(setting.getMincolour()),
3341 new java.awt.Color(setting.getColour()), 0, 1);
3342 if (setting.hasThreshold())
3344 gc.setThresh(setting.getThreshold());
3345 gc.setThreshType(setting.getThreshstate());
3347 gc.setAutoScaled(true); // default
3348 if (setting.hasAutoScale())
3350 gc.setAutoScaled(setting.getAutoScale());
3352 if (setting.hasColourByLabel())
3354 gc.setColourByLabel(setting.getColourByLabel());
3356 // and put in the feature colour table.
3357 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3358 setting.getType(), gc);
3362 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3364 new java.awt.Color(setting.getColour()));
3366 renderOrder[fs] = setting.getType();
3367 if (setting.hasOrder())
3368 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3369 setting.getType(), setting.getOrder());
3371 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3373 fs / jms.getFeatureSettings().getSettingCount());
3374 if (setting.getDisplay())
3376 af.viewport.featuresDisplayed.put(setting.getType(), new Integer(
3377 setting.getColour()));
3380 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().renderOrder = renderOrder;
3382 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().featureGroups = fgtable = new Hashtable();
3383 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
3385 Group grp = jms.getFeatureSettings().getGroup(gs);
3386 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
3390 if (view.getHiddenColumnsCount() > 0)
3392 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
3394 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
3395 .getHiddenColumns(c).getEnd() // +1
3399 if (view.getCalcIdParam() != null)
3401 for (CalcIdParam calcIdParam : view.getCalcIdParam())
3403 if (calcIdParam != null)
3405 if (recoverCalcIdParam(calcIdParam, af.viewport))
3410 warn("Couldn't recover parameters for "
3411 + calcIdParam.getCalcId());
3416 af.setMenusFromViewport(af.viewport);
3417 // TODO: we don't need to do this if the viewport is aready visible.
3418 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
3420 af.alignPanel.updateAnnotation(false); // recompute any autoannotation
3421 reorderAutoannotation(af, al, autoAlan);
3425 private void reorderAutoannotation(AlignFrame af, Alignment al,
3426 ArrayList<JvAnnotRow> autoAlan)
3428 // copy over visualization settings for autocalculated annotation in the
3430 if (al.getAlignmentAnnotation() != null)
3433 * Kludge for magic autoannotation names (see JAL-811)
3435 String[] magicNames = new String[]
3436 { "Consensus", "Quality", "Conservation" };
3437 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
3438 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
3439 for (String nm : magicNames)
3441 visan.put(nm, nullAnnot);
3443 for (JvAnnotRow auan : autoAlan)
3445 visan.put(auan.template.label
3446 + (auan.template.getCalcId() == null ? "" : "\t"
3447 + auan.template.getCalcId()), auan);
3449 int hSize = al.getAlignmentAnnotation().length;
3450 ArrayList<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
3451 // work through any autoCalculated annotation already on the view
3452 // removing it if it should be placed in a different location on the
3453 // annotation panel.
3454 List<String> remains = new ArrayList(visan.keySet());
3455 for (int h = 0; h < hSize; h++)
3457 jalview.datamodel.AlignmentAnnotation jalan = al
3458 .getAlignmentAnnotation()[h];
3459 if (jalan.autoCalculated)
3462 JvAnnotRow valan = visan.get(k = jalan.label);
3463 if (jalan.getCalcId() != null)
3465 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
3470 // delete the auto calculated row from the alignment
3471 al.deleteAnnotation(jalan, false);
3475 if (valan != nullAnnot)
3477 if (jalan != valan.template)
3479 // newly created autoannotation row instance
3480 // so keep a reference to the visible annotation row
3481 // and copy over all relevant attributes
3482 if (valan.template.graphHeight >= 0)
3485 jalan.graphHeight = valan.template.graphHeight;
3487 jalan.visible = valan.template.visible;
3489 reorder.add(new JvAnnotRow(valan.order, jalan));
3494 // Add any (possibly stale) autocalculated rows that were not appended to
3495 // the view during construction
3496 for (String other : remains)
3498 JvAnnotRow othera = visan.get(other);
3499 if (othera != nullAnnot && othera.template.getCalcId() != null
3500 && othera.template.getCalcId().length() > 0)
3502 reorder.add(othera);
3505 // now put the automatic annotation in its correct place
3506 int s = 0, srt[] = new int[reorder.size()];
3507 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
3508 for (JvAnnotRow jvar : reorder)
3511 srt[s++] = jvar.order;
3514 jalview.util.QuickSort.sort(srt, rws);
3515 // and re-insert the annotation at its correct position
3516 for (JvAnnotRow jvar : rws)
3518 al.addAnnotation(jvar.template, jvar.order);
3520 af.alignPanel.adjustAnnotationHeight();
3524 Hashtable skipList = null;
3527 * TODO remove this method
3530 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
3531 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
3532 * throw new Error("Implementation Error. No skipList defined for this
3533 * Jalview2XML instance."); } return (AlignFrame)
3534 * skipList.get(view.getSequenceSetId()); }
3538 * Check if the Jalview view contained in object should be skipped or not.
3541 * @return true if view's sequenceSetId is a key in skipList
3543 private boolean skipViewport(JalviewModel object)
3545 if (skipList == null)
3550 if (skipList.containsKey(id = object.getJalviewModelSequence()
3551 .getViewport()[0].getSequenceSetId()))
3553 if (Cache.log != null && Cache.log.isDebugEnabled())
3555 Cache.log.debug("Skipping seuqence set id " + id);
3562 public void AddToSkipList(AlignFrame af)
3564 if (skipList == null)
3566 skipList = new Hashtable();
3568 skipList.put(af.getViewport().getSequenceSetId(), af);
3571 public void clearSkipList()
3573 if (skipList != null)
3580 private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al)
3582 jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId());
3583 Vector dseqs = null;
3586 // create a list of new dataset sequences
3587 dseqs = new Vector();
3589 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
3591 Sequence vamsasSeq = vamsasSet.getSequence(i);
3592 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs);
3594 // create a new dataset
3597 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
3598 dseqs.copyInto(dsseqs);
3599 ds = new jalview.datamodel.Alignment(dsseqs);
3600 debug("Created new dataset " + vamsasSet.getDatasetId()
3601 + " for alignment " + System.identityHashCode(al));
3602 addDatasetRef(vamsasSet.getDatasetId(), ds);
3604 // set the dataset for the newly imported alignment.
3605 if (al.getDataset() == null)
3614 * sequence definition to create/merge dataset sequence for
3618 * vector to add new dataset sequence to
3620 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
3621 AlignmentI ds, Vector dseqs)
3623 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
3625 jalview.datamodel.Sequence sq = (jalview.datamodel.Sequence) seqRefIds
3626 .get(vamsasSeq.getId());
3627 jalview.datamodel.SequenceI dsq = null;
3628 if (sq != null && sq.getDatasetSequence() != null)
3630 dsq = sq.getDatasetSequence();
3633 String sqid = vamsasSeq.getDsseqid();
3636 // need to create or add a new dataset sequence reference to this sequence
3639 dsq = (jalview.datamodel.SequenceI) seqRefIds.get(sqid);
3644 // make a new dataset sequence
3645 dsq = sq.createDatasetSequence();
3648 // make up a new dataset reference for this sequence
3649 sqid = seqHash(dsq);
3651 dsq.setVamsasId(uniqueSetSuffix + sqid);
3652 seqRefIds.put(sqid, dsq);
3657 dseqs.addElement(dsq);
3662 ds.addSequence(dsq);
3668 { // make this dataset sequence sq's dataset sequence
3669 sq.setDatasetSequence(dsq);
3673 // TODO: refactor this as a merge dataset sequence function
3674 // now check that sq (the dataset sequence) sequence really is the union of
3675 // all references to it
3676 // boolean pre = sq.getStart() < dsq.getStart();
3677 // boolean post = sq.getEnd() > dsq.getEnd();
3681 StringBuffer sb = new StringBuffer();
3682 String newres = jalview.analysis.AlignSeq.extractGaps(
3683 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
3684 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
3685 && newres.length() > dsq.getLength())
3687 // Update with the longer sequence.
3691 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
3692 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
3693 * sb.append(newres.substring(newres.length() - sq.getEnd() -
3694 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
3696 dsq.setSequence(sb.toString());
3698 // TODO: merges will never happen if we 'know' we have the real dataset
3699 // sequence - this should be detected when id==dssid
3700 System.err.println("DEBUG Notice: Merged dataset sequence"); // ("
3701 // + (pre ? "prepended" : "") + " "
3702 // + (post ? "appended" : ""));
3707 java.util.Hashtable datasetIds = null;
3709 java.util.IdentityHashMap dataset2Ids = null;
3711 private Alignment getDatasetFor(String datasetId)
3713 if (datasetIds == null)
3715 datasetIds = new Hashtable();
3718 if (datasetIds.containsKey(datasetId))
3720 return (Alignment) datasetIds.get(datasetId);
3725 private void addDatasetRef(String datasetId, Alignment dataset)
3727 if (datasetIds == null)
3729 datasetIds = new Hashtable();
3731 datasetIds.put(datasetId, dataset);
3735 * make a new dataset ID for this jalview dataset alignment
3740 private String getDatasetIdRef(jalview.datamodel.Alignment dataset)
3742 if (dataset.getDataset() != null)
3744 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
3746 String datasetId = makeHashCode(dataset, null);
3747 if (datasetId == null)
3749 // make a new datasetId and record it
3750 if (dataset2Ids == null)
3752 dataset2Ids = new IdentityHashMap();
3756 datasetId = (String) dataset2Ids.get(dataset);
3758 if (datasetId == null)
3760 datasetId = "ds" + dataset2Ids.size() + 1;
3761 dataset2Ids.put(dataset, datasetId);
3767 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
3769 for (int d = 0; d < sequence.getDBRefCount(); d++)
3771 DBRef dr = sequence.getDBRef(d);
3772 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
3773 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
3774 .getVersion(), sequence.getDBRef(d).getAccessionId());
3775 if (dr.getMapping() != null)
3777 entry.setMap(addMapping(dr.getMapping()));
3779 datasetSequence.addDBRef(entry);
3783 private jalview.datamodel.Mapping addMapping(Mapping m)
3785 SequenceI dsto = null;
3786 // Mapping m = dr.getMapping();
3787 int fr[] = new int[m.getMapListFromCount() * 2];
3788 Enumeration f = m.enumerateMapListFrom();
3789 for (int _i = 0; f.hasMoreElements(); _i += 2)
3791 MapListFrom mf = (MapListFrom) f.nextElement();
3792 fr[_i] = mf.getStart();
3793 fr[_i + 1] = mf.getEnd();
3795 int fto[] = new int[m.getMapListToCount() * 2];
3796 f = m.enumerateMapListTo();
3797 for (int _i = 0; f.hasMoreElements(); _i += 2)
3799 MapListTo mf = (MapListTo) f.nextElement();
3800 fto[_i] = mf.getStart();
3801 fto[_i + 1] = mf.getEnd();
3803 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
3804 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
3805 if (m.getMappingChoice() != null)
3807 MappingChoice mc = m.getMappingChoice();
3808 if (mc.getDseqFor() != null)
3810 String dsfor = "" + mc.getDseqFor();
3811 if (seqRefIds.containsKey(dsfor))
3816 jmap.setTo((SequenceI) seqRefIds.get(dsfor));
3820 frefedSequence.add(new Object[]
3827 * local sequence definition
3829 Sequence ms = mc.getSequence();
3830 jalview.datamodel.Sequence djs = null;
3831 String sqid = ms.getDsseqid();
3832 if (sqid != null && sqid.length() > 0)
3835 * recover dataset sequence
3837 djs = (jalview.datamodel.Sequence) seqRefIds.get(sqid);
3842 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
3843 sqid = ((Object) ms).toString(); // make up a new hascode for
3844 // undefined dataset sequence hash
3845 // (unlikely to happen)
3851 * make a new dataset sequence and add it to refIds hash
3853 djs = new jalview.datamodel.Sequence(ms.getName(),
3855 djs.setStart(jmap.getMap().getToLowest());
3856 djs.setEnd(jmap.getMap().getToHighest());
3857 djs.setVamsasId(uniqueSetSuffix + sqid);
3859 seqRefIds.put(sqid, djs);
3862 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
3871 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
3872 boolean keepSeqRefs)
3875 jalview.schemabinding.version2.JalviewModel jm = SaveState(ap, null,
3881 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
3885 uniqueSetSuffix = "";
3886 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
3891 if (this.frefedSequence == null)
3893 frefedSequence = new Vector();
3896 viewportsAdded = new Hashtable();
3898 AlignFrame af = LoadFromObject(jm, null, false, null);
3899 af.alignPanels.clear();
3900 af.closeMenuItem_actionPerformed(true);
3903 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
3904 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
3905 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
3906 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
3907 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
3910 return af.alignPanel;
3914 * flag indicating if hashtables should be cleared on finalization TODO this
3915 * flag may not be necessary
3917 private final boolean _cleartables = true;
3919 private Hashtable jvids2vobj;
3924 * @see java.lang.Object#finalize()
3927 protected void finalize() throws Throwable
3929 // really make sure we have no buried refs left.
3934 this.seqRefIds = null;
3935 this.seqsToIds = null;
3939 private void warn(String msg)
3944 private void warn(String msg, Exception e)
3946 if (Cache.log != null)
3950 Cache.log.warn(msg, e);
3954 Cache.log.warn(msg);
3959 System.err.println("Warning: " + msg);
3962 e.printStackTrace();
3967 private void debug(String string)
3969 debug(string, null);
3972 private void debug(String msg, Exception e)
3974 if (Cache.log != null)
3978 Cache.log.debug(msg, e);
3982 Cache.log.debug(msg);
3987 System.err.println("Warning: " + msg);
3990 e.printStackTrace();
3996 * set the object to ID mapping tables used to write/recover objects and XML
3997 * ID strings for the jalview project. If external tables are provided then
3998 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
3999 * object goes out of scope. - also populates the datasetIds hashtable with
4000 * alignment objects containing dataset sequences
4003 * Map from ID strings to jalview datamodel
4005 * Map from jalview datamodel to ID strings
4009 public void setObjectMappingTables(Hashtable vobj2jv,
4010 IdentityHashMap jv2vobj)
4012 this.jv2vobj = jv2vobj;
4013 this.vobj2jv = vobj2jv;
4014 Iterator ds = jv2vobj.keySet().iterator();
4016 while (ds.hasNext())
4018 Object jvobj = ds.next();
4019 id = jv2vobj.get(jvobj).toString();
4020 if (jvobj instanceof jalview.datamodel.Alignment)
4022 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
4024 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
4027 else if (jvobj instanceof jalview.datamodel.Sequence)
4029 // register sequence object so the XML parser can recover it.
4030 if (seqRefIds == null)
4032 seqRefIds = new Hashtable();
4034 if (seqsToIds == null)
4036 seqsToIds = new IdentityHashMap();
4038 seqRefIds.put(jv2vobj.get(jvobj).toString(), jvobj);
4039 seqsToIds.put(jvobj, id);
4041 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
4043 if (annotationIds == null)
4045 annotationIds = new Hashtable();
4048 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvobj);
4049 jalview.datamodel.AlignmentAnnotation jvann = (jalview.datamodel.AlignmentAnnotation) jvobj;
4050 if (jvann.annotationId == null)
4052 jvann.annotationId = anid;
4054 if (!jvann.annotationId.equals(anid))
4056 // TODO verify that this is the correct behaviour
4057 this.warn("Overriding Annotation ID for " + anid
4058 + " from different id : " + jvann.annotationId);
4059 jvann.annotationId = anid;
4062 else if (jvobj instanceof String)
4064 if (jvids2vobj == null)
4066 jvids2vobj = new Hashtable();
4067 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
4071 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
4076 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
4077 * objects created from the project archive. If string is null (default for
4078 * construction) then suffix will be set automatically.
4082 public void setUniqueSetSuffix(String string)
4084 uniqueSetSuffix = string;
4089 * uses skipList2 as the skipList for skipping views on sequence sets
4090 * associated with keys in the skipList
4094 public void setSkipList(Hashtable skipList2)
4096 skipList = skipList2;