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;
2271 if (!an[i].getScoreOnly())
2273 anot = new jalview.datamodel.Annotation[al.getWidth()];
2274 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
2276 if (ae[aa].getPosition() >= anot.length)
2279 anot[ae[aa].getPosition()] = new jalview.datamodel.Annotation(
2281 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
2282 (ae[aa].getSecondaryStructure() == null || ae[aa]
2283 .getSecondaryStructure().length() == 0) ? ' '
2284 : ae[aa].getSecondaryStructure().charAt(0),
2288 // JBPNote: Consider verifying dataflow for IO of secondary
2289 // structure annotation read from Stockholm files
2290 // this was added to try to ensure that
2291 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
2293 // anot[ae[aa].getPosition()].displayCharacter = "";
2295 anot[ae[aa].getPosition()].colour = new java.awt.Color(
2296 ae[aa].getColour());
2299 jalview.datamodel.AlignmentAnnotation jaa = null;
2301 if (an[i].getGraph())
2303 float llim = 0, hlim = 0;
2304 // if (autoForView || an[i].isAutoCalculated()) {
2307 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2308 an[i].getDescription(), anot, llim, hlim,
2309 an[i].getGraphType());
2311 jaa.graphGroup = an[i].getGraphGroup();
2313 if (an[i].getThresholdLine() != null)
2315 jaa.setThreshold(new jalview.datamodel.GraphLine(an[i]
2316 .getThresholdLine().getValue(), an[i]
2317 .getThresholdLine().getLabel(), new java.awt.Color(
2318 an[i].getThresholdLine().getColour())));
2321 if (autoForView || an[i].isAutoCalculated())
2323 // Hardwire the symbol display line to ensure that labels for
2324 // histograms are displayed
2330 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2331 an[i].getDescription(), anot);
2333 // register new annotation
2334 if (an[i].getId() != null)
2336 annotationIds.put(an[i].getId(), jaa);
2337 jaa.annotationId = an[i].getId();
2339 // recover sequence association
2340 if (an[i].getSequenceRef() != null)
2342 if (al.findName(an[i].getSequenceRef()) != null)
2344 jaa.createSequenceMapping(al.findName(an[i].getSequenceRef()),
2346 al.findName(an[i].getSequenceRef()).addAlignmentAnnotation(jaa);
2349 // and make a note of any group association
2350 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
2352 ArrayList<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
2353 .get(an[i].getGroupRef());
2356 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
2357 groupAnnotRefs.put(an[i].getGroupRef(), aal);
2362 if (an[i].hasScore())
2364 jaa.setScore(an[i].getScore());
2366 if (an[i].hasVisible())
2367 jaa.visible = an[i].getVisible();
2369 if (an[i].hasCentreColLabels())
2370 jaa.centreColLabels = an[i].getCentreColLabels();
2372 if (an[i].hasScaleColLabels())
2374 jaa.scaleColLabel = an[i].getScaleColLabels();
2376 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
2378 // newer files have an 'autoCalculated' flag and store calculation
2379 // state in viewport properties
2380 jaa.autoCalculated = true; // means annotation will be marked for
2381 // update at end of load.
2383 if (an[i].hasGraphHeight())
2385 jaa.graphHeight = an[i].getGraphHeight();
2387 if (an[i].hasBelowAlignment())
2389 jaa.belowAlignment = an[i].isBelowAlignment();
2391 jaa.setCalcId(an[i].getCalcId());
2393 if (jaa.autoCalculated)
2395 autoAlan.add(new JvAnnotRow(i, jaa));
2398 // if (!autoForView)
2400 // add autocalculated group annotation and any user created annotation
2402 al.addAnnotation(jaa);
2407 // ///////////////////////
2409 // Create alignment markup and styles for this view
2410 if (jms.getJGroupCount() > 0)
2412 JGroup[] groups = jms.getJGroup();
2414 for (int i = 0; i < groups.length; i++)
2416 ColourSchemeI cs = null;
2418 if (groups[i].getColour() != null)
2420 if (groups[i].getColour().startsWith("ucs"))
2422 cs = GetUserColourScheme(jms, groups[i].getColour());
2426 cs = ColourSchemeProperty.getColour(al, groups[i].getColour());
2431 cs.setThreshold(groups[i].getPidThreshold(), true);
2435 Vector seqs = new Vector();
2437 for (int s = 0; s < groups[i].getSeqCount(); s++)
2439 String seqId = groups[i].getSeq(s) + "";
2440 jalview.datamodel.SequenceI ts = (jalview.datamodel.SequenceI) seqRefIds
2445 seqs.addElement(ts);
2449 if (seqs.size() < 1)
2454 jalview.datamodel.SequenceGroup sg = new jalview.datamodel.SequenceGroup(
2455 seqs, groups[i].getName(), cs, groups[i].getDisplayBoxes(),
2456 groups[i].getDisplayText(), groups[i].getColourText(),
2457 groups[i].getStart(), groups[i].getEnd());
2459 sg.setOutlineColour(new java.awt.Color(groups[i].getOutlineColour()));
2461 sg.textColour = new java.awt.Color(groups[i].getTextCol1());
2462 sg.textColour2 = new java.awt.Color(groups[i].getTextCol2());
2463 sg.setShowNonconserved(groups[i].hasShowUnconserved() ? groups[i]
2464 .isShowUnconserved() : false);
2465 sg.thresholdTextColour = groups[i].getTextColThreshold();
2466 if (groups[i].hasShowConsensusHistogram())
2468 sg.setShowConsensusHistogram(groups[i].isShowConsensusHistogram());
2471 if (groups[i].hasShowSequenceLogo())
2473 sg.setshowSequenceLogo(groups[i].isShowSequenceLogo());
2475 if (groups[i].hasIgnoreGapsinConsensus())
2477 sg.setIgnoreGapsConsensus(groups[i].getIgnoreGapsinConsensus());
2479 if (groups[i].getConsThreshold() != 0)
2481 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
2482 "All", ResidueProperties.propHash, 3,
2483 sg.getSequences(null), 0, sg.getWidth() - 1);
2485 c.verdict(false, 25);
2486 sg.cs.setConservation(c);
2489 if (groups[i].getId() != null && groupAnnotRefs.size() > 0)
2491 // re-instate unique group/annotation row reference
2492 ArrayList<jalview.datamodel.AlignmentAnnotation> jaal = groupAnnotRefs
2493 .get(groups[i].getId());
2496 for (jalview.datamodel.AlignmentAnnotation jaa : jaal)
2499 if (jaa.autoCalculated)
2501 // match up and try to set group autocalc alignment row for this
2503 if (jaa.label.startsWith("Consensus for "))
2505 sg.setConsensus(jaa);
2507 // match up and try to set group autocalc alignment row for this
2509 if (jaa.label.startsWith("Conservation for "))
2511 sg.setConservationRow(jaa);
2522 // ///////////////////////////////
2525 // If we just load in the same jar file again, the sequenceSetId
2526 // will be the same, and we end up with multiple references
2527 // to the same sequenceSet. We must modify this id on load
2528 // so that each load of the file gives a unique id
2529 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
2530 String viewId = (view.getId() == null ? null : view.getId()
2532 AlignFrame af = null;
2533 AlignViewport av = null;
2534 // now check to see if we really need to create a new viewport.
2535 if (multipleView && viewportsAdded.size() == 0)
2537 // We recovered an alignment for which a viewport already exists.
2538 // TODO: fix up any settings necessary for overlaying stored state onto
2539 // state recovered from another document. (may not be necessary).
2540 // we may need a binding from a viewport in memory to one recovered from
2542 // and then recover its containing af to allow the settings to be applied.
2543 // TODO: fix for vamsas demo
2545 .println("About to recover a viewport for existing alignment: Sequence set ID is "
2547 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
2548 if (seqsetobj != null)
2550 if (seqsetobj instanceof String)
2552 uniqueSeqSetId = (String) seqsetobj;
2554 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
2560 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
2565 AlignmentPanel ap = null;
2566 boolean isnewview = true;
2569 // Check to see if this alignment already has a view id == viewId
2570 jalview.gui.AlignmentPanel views[] = Desktop
2571 .getAlignmentPanels(uniqueSeqSetId);
2572 if (views != null && views.length > 0)
2574 for (int v = 0; v < views.length; v++)
2576 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
2578 // recover the existing alignpanel, alignframe, viewport
2579 af = views[v].alignFrame;
2582 // TODO: could even skip resetting view settings if we don't want to
2583 // change the local settings from other jalview processes
2592 af = loadViewport(file, JSEQ, hiddenSeqs, al, jms, view,
2593 uniqueSeqSetId, viewId, autoAlan);
2598 // /////////////////////////////////////
2599 if (loadTreesAndStructures && jms.getTreeCount() > 0)
2603 for (int t = 0; t < jms.getTreeCount(); t++)
2606 Tree tree = jms.getTree(t);
2608 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
2611 tp = af.ShowNewickTree(
2612 new jalview.io.NewickFile(tree.getNewick()),
2613 tree.getTitle(), tree.getWidth(), tree.getHeight(),
2614 tree.getXpos(), tree.getYpos());
2615 if (tree.getId() != null)
2617 // perhaps bind the tree id to something ?
2622 // update local tree attributes ?
2623 // TODO: should check if tp has been manipulated by user - if so its
2624 // settings shouldn't be modified
2625 tp.setTitle(tree.getTitle());
2626 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
2627 .getWidth(), tree.getHeight()));
2628 tp.av = av; // af.viewport; // TODO: verify 'associate with all
2631 tp.treeCanvas.av = av; // af.viewport;
2632 tp.treeCanvas.ap = ap; // af.alignPanel;
2637 warn("There was a problem recovering stored Newick tree: \n"
2638 + tree.getNewick());
2642 tp.fitToWindow.setState(tree.getFitToWindow());
2643 tp.fitToWindow_actionPerformed(null);
2645 if (tree.getFontName() != null)
2647 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
2648 .getFontStyle(), tree.getFontSize()));
2652 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
2653 .getFontStyle(), tree.getFontSize()));
2656 tp.showPlaceholders(tree.getMarkUnlinked());
2657 tp.showBootstrap(tree.getShowBootstrap());
2658 tp.showDistances(tree.getShowDistances());
2660 tp.treeCanvas.threshold = tree.getThreshold();
2662 if (tree.getCurrentTree())
2664 af.viewport.setCurrentTree(tp.getTree());
2668 } catch (Exception ex)
2670 ex.printStackTrace();
2674 // //LOAD STRUCTURES
2675 if (loadTreesAndStructures)
2677 // run through all PDB ids on the alignment, and collect mappings between
2678 // jmol view ids and all sequences referring to it
2679 Hashtable<String, Object[]> jmolViewIds = new Hashtable();
2681 for (int i = 0; i < JSEQ.length; i++)
2683 if (JSEQ[i].getPdbidsCount() > 0)
2685 Pdbids[] ids = JSEQ[i].getPdbids();
2686 for (int p = 0; p < ids.length; p++)
2688 for (int s = 0; s < ids[p].getStructureStateCount(); s++)
2690 // check to see if we haven't already created this structure view
2691 String sviewid = (ids[p].getStructureState(s).getViewId() == null) ? null
2692 : ids[p].getStructureState(s).getViewId()
2694 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
2695 // Originally : ids[p].getFile()
2696 // : TODO: verify external PDB file recovery still works in normal
2697 // jalview project load
2698 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
2699 jpdb.setId(ids[p].getId());
2701 int x = ids[p].getStructureState(s).getXpos();
2702 int y = ids[p].getStructureState(s).getYpos();
2703 int width = ids[p].getStructureState(s).getWidth();
2704 int height = ids[p].getStructureState(s).getHeight();
2706 // Probably don't need to do this anymore...
2707 // Desktop.desktop.getComponentAt(x, y);
2708 // TODO: NOW: check that this recovers the PDB file correctly.
2709 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
2710 jalview.datamodel.SequenceI seq = (jalview.datamodel.SequenceI) seqRefIds
2711 .get(JSEQ[i].getId() + "");
2712 if (sviewid == null)
2714 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
2717 if (!jmolViewIds.containsKey(sviewid))
2719 jmolViewIds.put(sviewid, new Object[]
2721 { x, y, width, height }, "",
2722 new Hashtable<String, Object[]>(), new boolean[]
2723 { false, false, true } });
2724 // Legacy pre-2.7 conversion JAL-823 :
2725 // do not assume any view has to be linked for colour by
2729 // assemble String[] { pdb files }, String[] { id for each
2730 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
2731 // seqs_file 2}, boolean[] {
2732 // linkAlignPanel,superposeWithAlignpanel}} from hash
2733 Object[] jmoldat = jmolViewIds.get(sviewid);
2734 ((boolean[]) jmoldat[3])[0] |= ids[p].getStructureState(s)
2735 .hasAlignwithAlignPanel() ? ids[p].getStructureState(
2736 s).getAlignwithAlignPanel() : false;
2737 // never colour by linked panel if not specified
2738 ((boolean[]) jmoldat[3])[1] |= ids[p].getStructureState(s)
2739 .hasColourwithAlignPanel() ? ids[p]
2740 .getStructureState(s).getColourwithAlignPanel()
2742 // default for pre-2.7 projects is that Jmol colouring is enabled
2743 ((boolean[]) jmoldat[3])[2] &= ids[p].getStructureState(s)
2744 .hasColourByJmol() ? ids[p].getStructureState(s)
2745 .getColourByJmol() : true;
2747 if (((String) jmoldat[1]).length() < ids[p]
2748 .getStructureState(s).getContent().length())
2751 jmoldat[1] = ids[p].getStructureState(s).getContent();
2754 if (ids[p].getFile() != null)
2756 File mapkey = new File(ids[p].getFile());
2757 Object[] seqstrmaps = (Object[]) ((Hashtable) jmoldat[2])
2759 if (seqstrmaps == null)
2761 ((Hashtable) jmoldat[2]).put(mapkey,
2762 seqstrmaps = new Object[]
2763 { pdbFile, ids[p].getId(), new Vector(),
2766 if (!((Vector) seqstrmaps[2]).contains(seq))
2768 ((Vector) seqstrmaps[2]).addElement(seq);
2769 // ((Vector)seqstrmaps[3]).addElement(n) :
2770 // in principle, chains
2771 // should be stored here : do we need to
2772 // TODO: store and recover seq/pdb_id :
2778 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");
2787 // Instantiate the associated Jmol views
2788 for (Entry<String, Object[]> entry : jmolViewIds.entrySet())
2790 String sviewid = entry.getKey();
2791 Object[] svattrib = entry.getValue();
2792 int[] geom = (int[]) svattrib[0];
2793 String state = (String) svattrib[1];
2794 Hashtable<File, Object[]> oldFiles = (Hashtable<File, Object[]>) svattrib[2];
2795 final boolean useinJmolsuperpos = ((boolean[]) svattrib[3])[0], usetoColourbyseq = ((boolean[]) svattrib[3])[1], jmolColouring = ((boolean[]) svattrib[3])[2];
2796 int x = geom[0], y = geom[1], width = geom[2], height = geom[3];
2797 // collate the pdbfile -> sequence mappings from this view
2798 Vector<String> pdbfilenames = new Vector<String>();
2799 Vector<SequenceI[]> seqmaps = new Vector<SequenceI[]>();
2800 Vector<String> pdbids = new Vector<String>();
2802 // Search to see if we've already created this Jmol view
2803 AppJmol comp = null;
2804 JInternalFrame[] frames = null;
2809 frames = Desktop.desktop.getAllFrames();
2810 } catch (ArrayIndexOutOfBoundsException e)
2812 // occasional No such child exceptions are thrown here...
2817 } catch (Exception f)
2822 } while (frames == null);
2823 // search for any Jmol windows already open from other
2824 // alignment views that exactly match the stored structure state
2825 for (int f = 0; comp == null && f < frames.length; f++)
2827 if (frames[f] instanceof AppJmol)
2830 && ((AppJmol) frames[f]).getViewId().equals(sviewid))
2832 // post jalview 2.4 schema includes structure view id
2833 comp = (AppJmol) frames[f];
2835 else if (frames[f].getX() == x && frames[f].getY() == y
2836 && frames[f].getHeight() == height
2837 && frames[f].getWidth() == width)
2839 comp = (AppJmol) frames[f];
2846 // create a new Jmol window.
2847 // First parse the Jmol state to translate filenames loaded into the
2848 // view, and record the order in which files are shown in the Jmol
2849 // view, so we can add the sequence mappings in same order.
2850 StringBuffer newFileLoc = null;
2851 int cp = 0, ncp, ecp;
2852 while ((ncp = state.indexOf("load ", cp)) > -1)
2854 if (newFileLoc == null)
2856 newFileLoc = new StringBuffer();
2860 // look for next filename in load statement
2861 newFileLoc.append(state.substring(cp,
2862 ncp = (state.indexOf("\"", ncp + 1) + 1)));
2863 String oldfilenam = state.substring(ncp,
2864 ecp = state.indexOf("\"", ncp));
2865 // recover the new mapping data for this old filename
2866 // have to normalize filename - since Jmol and jalview do
2868 // translation differently.
2869 Object[] filedat = oldFiles.get(new File(oldfilenam));
2870 newFileLoc.append(Platform
2871 .escapeString((String) filedat[0]));
2872 pdbfilenames.addElement((String) filedat[0]);
2873 pdbids.addElement((String) filedat[1]);
2874 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
2875 .toArray(new SequenceI[0]));
2876 newFileLoc.append("\"");
2877 cp = ecp + 1; // advance beyond last \" and set cursor so we can
2878 // look for next file statement.
2879 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
2883 // just append rest of state
2884 newFileLoc.append(state.substring(cp));
2889 .print("Ignoring incomplete Jmol state for PDB ids: ");
2890 newFileLoc = new StringBuffer(state);
2891 newFileLoc.append("; load append ");
2892 for (File id : oldFiles.keySet())
2894 // add this and any other pdb files that should be present in
2896 Object[] filedat = oldFiles.get(id);
2898 newFileLoc.append(((String) filedat[0]));
2899 pdbfilenames.addElement((String) filedat[0]);
2900 pdbids.addElement((String) filedat[1]);
2901 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
2902 .toArray(new SequenceI[0]));
2903 newFileLoc.append(" \"");
2904 newFileLoc.append((String) filedat[0]);
2905 newFileLoc.append("\"");
2908 newFileLoc.append(";");
2911 if (newFileLoc != null)
2913 int histbug = newFileLoc.indexOf("history = ");
2915 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";",
2917 String val = (diff == -1) ? null : newFileLoc.substring(
2919 if (val != null && val.length() >= 4)
2921 if (val.contains("e"))
2923 if (val.trim().equals("true"))
2931 newFileLoc.replace(histbug, diff, val);
2934 // TODO: assemble String[] { pdb files }, String[] { id for each
2935 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
2936 // seqs_file 2}} from hash
2937 final String[] pdbf = pdbfilenames
2938 .toArray(new String[pdbfilenames.size()]), id = pdbids
2939 .toArray(new String[pdbids.size()]);
2940 final SequenceI[][] sq = seqmaps
2941 .toArray(new SequenceI[seqmaps.size()][]);
2942 final String fileloc = newFileLoc.toString(), vid = sviewid;
2943 final AlignFrame alf = af;
2944 final java.awt.Rectangle rect = new java.awt.Rectangle(x, y,
2948 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
2953 AppJmol sview = null;
2956 sview = new AppJmol(pdbf, id, sq, alf.alignPanel,
2957 useinJmolsuperpos, usetoColourbyseq,
2958 jmolColouring, fileloc, rect, vid);
2959 } catch (OutOfMemoryError ex)
2961 new OOMWarning("restoring structure view for PDB id "
2962 + id, (OutOfMemoryError) ex.getCause());
2963 if (sview != null && sview.isVisible())
2965 sview.closeViewer();
2966 sview.setVisible(false);
2972 } catch (InvocationTargetException ex)
2974 warn("Unexpected error when opening Jmol view.", ex);
2976 } catch (InterruptedException e)
2978 // e.printStackTrace();
2984 // if (comp != null)
2986 // NOTE: if the jalview project is part of a shared session then
2987 // view synchronization should/could be done here.
2989 // add mapping for sequences in this view to an already open Jmol
2991 for (File id : oldFiles.keySet())
2993 // add this and any other pdb files that should be present in the
2995 Object[] filedat = oldFiles.get(id);
2996 String pdbFile = (String) filedat[0];
2997 SequenceI[] seq = ((Vector<SequenceI>) filedat[2])
2998 .toArray(new SequenceI[0]);
2999 comp.jmb.ssm.setMapping(seq, null, pdbFile,
3000 jalview.io.AppletFormatAdapter.FILE);
3001 comp.jmb.addSequenceForStructFile(pdbFile, seq);
3003 // and add the AlignmentPanel's reference to the Jmol view
3004 comp.addAlignmentPanel(ap);
3005 if (useinJmolsuperpos)
3007 comp.useAlignmentPanelForSuperposition(ap);
3011 comp.excludeAlignmentPanelForSuperposition(ap);
3013 if (usetoColourbyseq)
3015 comp.useAlignmentPanelForColourbyseq(ap, !jmolColouring);
3019 comp.excludeAlignmentPanelForColourbyseq(ap);
3025 // and finally return.
3029 AlignFrame loadViewport(String file, JSeq[] JSEQ, Vector hiddenSeqs,
3030 Alignment al, JalviewModelSequence jms, Viewport view,
3031 String uniqueSeqSetId, String viewId,
3032 ArrayList<JvAnnotRow> autoAlan)
3034 AlignFrame af = null;
3035 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
3036 uniqueSeqSetId, viewId);
3038 af.setFileName(file, "Jalview");
3040 for (int i = 0; i < JSEQ.length; i++)
3042 af.viewport.setSequenceColour(af.viewport.getAlignment()
3043 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
3046 af.viewport.gatherViewsHere = view.getGatheredViews();
3048 if (view.getSequenceSetId() != null)
3050 jalview.gui.AlignViewport av = (jalview.gui.AlignViewport) viewportsAdded
3051 .get(uniqueSeqSetId);
3053 af.viewport.setSequenceSetId(uniqueSeqSetId);
3056 // propagate shared settings to this new view
3057 af.viewport.historyList = av.historyList;
3058 af.viewport.redoList = av.redoList;
3062 viewportsAdded.put(uniqueSeqSetId, af.viewport);
3064 // TODO: check if this method can be called repeatedly without
3065 // side-effects if alignpanel already registered.
3066 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
3068 // apply Hidden regions to view.
3069 if (hiddenSeqs != null)
3071 for (int s = 0; s < JSEQ.length; s++)
3073 jalview.datamodel.SequenceGroup hidden = new jalview.datamodel.SequenceGroup();
3075 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
3078 al.getSequenceAt(JSEQ[s].getHiddenSequences(r)), false);
3080 af.viewport.hideRepSequences(al.getSequenceAt(s), hidden);
3083 jalview.datamodel.SequenceI[] hseqs = new jalview.datamodel.SequenceI[hiddenSeqs
3086 for (int s = 0; s < hiddenSeqs.size(); s++)
3088 hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s);
3091 af.viewport.hideSequence(hseqs);
3094 // recover view properties and display parameters
3095 if (view.getViewName() != null)
3097 af.viewport.viewName = view.getViewName();
3098 af.setInitialTabVisible();
3100 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
3103 af.viewport.setShowAnnotation(view.getShowAnnotation());
3104 af.viewport.setAbovePIDThreshold(view.getPidSelected());
3106 af.viewport.setColourText(view.getShowColourText());
3108 af.viewport.setConservationSelected(view.getConservationSelected());
3109 af.viewport.setShowJVSuffix(view.getShowFullId());
3110 af.viewport.rightAlignIds = view.getRightAlignIds();
3111 af.viewport.setFont(new java.awt.Font(view.getFontName(), view
3112 .getFontStyle(), view.getFontSize()));
3113 af.alignPanel.fontChanged();
3114 af.viewport.setRenderGaps(view.getRenderGaps());
3115 af.viewport.setWrapAlignment(view.getWrapAlignment());
3116 af.alignPanel.setWrapAlignment(view.getWrapAlignment());
3117 af.viewport.setShowAnnotation(view.getShowAnnotation());
3118 af.alignPanel.setAnnotationVisible(view.getShowAnnotation());
3120 af.viewport.setShowBoxes(view.getShowBoxes());
3122 af.viewport.setShowText(view.getShowText());
3124 af.viewport.textColour = new java.awt.Color(view.getTextCol1());
3125 af.viewport.textColour2 = new java.awt.Color(view.getTextCol2());
3126 af.viewport.thresholdTextColour = view.getTextColThreshold();
3127 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
3128 .isShowUnconserved() : false);
3129 af.viewport.setStartRes(view.getStartRes());
3130 af.viewport.setStartSeq(view.getStartSeq());
3132 ColourSchemeI cs = null;
3133 // apply colourschemes
3134 if (view.getBgColour() != null)
3136 if (view.getBgColour().startsWith("ucs"))
3138 cs = GetUserColourScheme(jms, view.getBgColour());
3140 else if (view.getBgColour().startsWith("Annotation"))
3142 // int find annotation
3143 if (af.viewport.getAlignment().getAlignmentAnnotation() != null)
3145 for (int i = 0; i < af.viewport.getAlignment()
3146 .getAlignmentAnnotation().length; i++)
3148 if (af.viewport.getAlignment().getAlignmentAnnotation()[i].label
3149 .equals(view.getAnnotationColours().getAnnotation()))
3151 if (af.viewport.getAlignment().getAlignmentAnnotation()[i]
3152 .getThreshold() == null)
3154 af.viewport.getAlignment().getAlignmentAnnotation()[i]
3155 .setThreshold(new jalview.datamodel.GraphLine(view
3156 .getAnnotationColours().getThreshold(),
3157 "Threshold", java.awt.Color.black)
3162 if (view.getAnnotationColours().getColourScheme()
3165 cs = new AnnotationColourGradient(af.viewport
3166 .getAlignment().getAlignmentAnnotation()[i],
3167 new java.awt.Color(view.getAnnotationColours()
3168 .getMinColour()), new java.awt.Color(view
3169 .getAnnotationColours().getMaxColour()),
3170 view.getAnnotationColours().getAboveThreshold());
3172 else if (view.getAnnotationColours().getColourScheme()
3175 cs = new AnnotationColourGradient(af.viewport
3176 .getAlignment().getAlignmentAnnotation()[i],
3177 GetUserColourScheme(jms, view
3178 .getAnnotationColours().getColourScheme()),
3179 view.getAnnotationColours().getAboveThreshold());
3183 cs = new AnnotationColourGradient(af.viewport
3184 .getAlignment().getAlignmentAnnotation()[i],
3185 ColourSchemeProperty.getColour(al, view
3186 .getAnnotationColours().getColourScheme()),
3187 view.getAnnotationColours().getAboveThreshold());
3190 // Also use these settings for all the groups
3191 if (al.getGroups() != null)
3193 for (int g = 0; g < al.getGroups().size(); g++)
3195 jalview.datamodel.SequenceGroup sg = al.getGroups()
3205 * (view.getAnnotationColours().getColourScheme().equals("None"
3206 * )) { sg.cs = new AnnotationColourGradient(
3207 * af.viewport.getAlignment().getAlignmentAnnotation()[i], new
3208 * java.awt.Color(view.getAnnotationColours().
3209 * getMinColour()), new
3210 * java.awt.Color(view.getAnnotationColours().
3212 * view.getAnnotationColours().getAboveThreshold()); } else
3215 sg.cs = new AnnotationColourGradient(af.viewport
3216 .getAlignment().getAlignmentAnnotation()[i],
3217 sg.cs, view.getAnnotationColours()
3218 .getAboveThreshold());
3232 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
3237 cs.setThreshold(view.getPidThreshold(), true);
3238 cs.setConsensus(af.viewport.getSequenceConsensusHash());
3242 af.viewport.setGlobalColourScheme(cs);
3243 af.viewport.setColourAppliesToAllGroups(false);
3245 if (view.getConservationSelected() && cs != null)
3247 cs.setConservationInc(view.getConsThreshold());
3250 af.changeColour(cs);
3252 af.viewport.setColourAppliesToAllGroups(true);
3254 if (view.getShowSequenceFeatures())
3256 af.viewport.showSequenceFeatures = true;
3258 if (view.hasCentreColumnLabels())
3260 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
3262 if (view.hasIgnoreGapsinConsensus())
3264 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
3267 if (view.hasFollowHighlight())
3269 af.viewport.followHighlight = view.getFollowHighlight();
3271 if (view.hasFollowSelection())
3273 af.viewport.followSelection = view.getFollowSelection();
3275 if (view.hasShowConsensusHistogram())
3277 af.viewport.setShowConsensusHistogram(view
3278 .getShowConsensusHistogram());
3282 af.viewport.setShowConsensusHistogram(true);
3284 if (view.hasShowSequenceLogo())
3286 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
3290 af.viewport.setShowSequenceLogo(false);
3292 if (view.hasShowDbRefTooltip())
3294 af.viewport.setShowDbRefs(view.getShowDbRefTooltip());
3296 if (view.hasShowNPfeatureTooltip())
3298 af.viewport.setShowNpFeats(view.hasShowNPfeatureTooltip());
3300 if (view.hasShowGroupConsensus())
3302 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
3306 af.viewport.setShowGroupConsensus(false);
3308 if (view.hasShowGroupConservation())
3310 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
3314 af.viewport.setShowGroupConservation(false);
3317 // recover featre settings
3318 if (jms.getFeatureSettings() != null)
3320 af.viewport.featuresDisplayed = new Hashtable();
3321 String[] renderOrder = new String[jms.getFeatureSettings()
3322 .getSettingCount()];
3323 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
3325 Setting setting = jms.getFeatureSettings().getSetting(fs);
3326 if (setting.hasMincolour())
3328 GraduatedColor gc = setting.hasMin() ? new GraduatedColor(
3329 new java.awt.Color(setting.getMincolour()),
3330 new java.awt.Color(setting.getColour()),
3331 setting.getMin(), setting.getMax()) : new GraduatedColor(
3332 new java.awt.Color(setting.getMincolour()),
3333 new java.awt.Color(setting.getColour()), 0, 1);
3334 if (setting.hasThreshold())
3336 gc.setThresh(setting.getThreshold());
3337 gc.setThreshType(setting.getThreshstate());
3339 gc.setAutoScaled(true); // default
3340 if (setting.hasAutoScale())
3342 gc.setAutoScaled(setting.getAutoScale());
3344 if (setting.hasColourByLabel())
3346 gc.setColourByLabel(setting.getColourByLabel());
3348 // and put in the feature colour table.
3349 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3350 setting.getType(), gc);
3354 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3356 new java.awt.Color(setting.getColour()));
3358 renderOrder[fs] = setting.getType();
3359 if (setting.hasOrder())
3360 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3361 setting.getType(), setting.getOrder());
3363 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3365 fs / jms.getFeatureSettings().getSettingCount());
3366 if (setting.getDisplay())
3368 af.viewport.featuresDisplayed.put(setting.getType(), new Integer(
3369 setting.getColour()));
3372 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().renderOrder = renderOrder;
3374 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().featureGroups = fgtable = new Hashtable();
3375 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
3377 Group grp = jms.getFeatureSettings().getGroup(gs);
3378 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
3382 if (view.getHiddenColumnsCount() > 0)
3384 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
3386 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
3387 .getHiddenColumns(c).getEnd() // +1
3391 if (view.getCalcIdParam() != null)
3393 for (CalcIdParam calcIdParam : view.getCalcIdParam())
3395 if (calcIdParam != null)
3397 if (recoverCalcIdParam(calcIdParam, af.viewport))
3402 warn("Couldn't recover parameters for "
3403 + calcIdParam.getCalcId());
3408 af.setMenusFromViewport(af.viewport);
3409 // TODO: we don't need to do this if the viewport is aready visible.
3410 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
3412 af.alignPanel.updateAnnotation(false); // recompute any autoannotation
3413 reorderAutoannotation(af, al, autoAlan);
3417 private void reorderAutoannotation(AlignFrame af, Alignment al,
3418 ArrayList<JvAnnotRow> autoAlan)
3420 // copy over visualization settings for autocalculated annotation in the
3422 if (al.getAlignmentAnnotation() != null)
3425 * Kludge for magic autoannotation names (see JAL-811)
3427 String[] magicNames = new String[]
3428 { "Consensus", "Quality", "Conservation" };
3429 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
3430 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
3431 for (String nm : magicNames)
3433 visan.put(nm, nullAnnot);
3435 for (JvAnnotRow auan : autoAlan)
3437 visan.put(auan.template.label
3438 + (auan.template.getCalcId() == null ? "" : "\t"
3439 + auan.template.getCalcId()), auan);
3441 int hSize = al.getAlignmentAnnotation().length;
3442 ArrayList<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
3443 // work through any autoCalculated annotation already on the view
3444 // removing it if it should be placed in a different location on the
3445 // annotation panel.
3446 List<String> remains = new ArrayList(visan.keySet());
3447 for (int h = 0; h < hSize; h++)
3449 jalview.datamodel.AlignmentAnnotation jalan = al
3450 .getAlignmentAnnotation()[h];
3451 if (jalan.autoCalculated)
3454 JvAnnotRow valan = visan.get(k = jalan.label);
3455 if (jalan.getCalcId() != null)
3457 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
3462 // delete the auto calculated row from the alignment
3463 al.deleteAnnotation(jalan, false);
3467 if (valan != nullAnnot)
3469 if (jalan != valan.template)
3471 // newly created autoannotation row instance
3472 // so keep a reference to the visible annotation row
3473 // and copy over all relevant attributes
3474 if (valan.template.graphHeight >= 0)
3477 jalan.graphHeight = valan.template.graphHeight;
3479 jalan.visible = valan.template.visible;
3481 reorder.add(new JvAnnotRow(valan.order, jalan));
3486 // Add any (possibly stale) autocalculated rows that were not appended to
3487 // the view during construction
3488 for (String other : remains)
3490 JvAnnotRow othera = visan.get(other);
3491 if (othera != nullAnnot && othera.template.getCalcId() != null
3492 && othera.template.getCalcId().length() > 0)
3494 reorder.add(othera);
3497 // now put the automatic annotation in its correct place
3498 int s = 0, srt[] = new int[reorder.size()];
3499 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
3500 for (JvAnnotRow jvar : reorder)
3503 srt[s++] = jvar.order;
3506 jalview.util.QuickSort.sort(srt, rws);
3507 // and re-insert the annotation at its correct position
3508 for (JvAnnotRow jvar : rws)
3510 al.addAnnotation(jvar.template, jvar.order);
3512 af.alignPanel.adjustAnnotationHeight();
3516 Hashtable skipList = null;
3519 * TODO remove this method
3522 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
3523 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
3524 * throw new Error("Implementation Error. No skipList defined for this
3525 * Jalview2XML instance."); } return (AlignFrame)
3526 * skipList.get(view.getSequenceSetId()); }
3530 * Check if the Jalview view contained in object should be skipped or not.
3533 * @return true if view's sequenceSetId is a key in skipList
3535 private boolean skipViewport(JalviewModel object)
3537 if (skipList == null)
3542 if (skipList.containsKey(id = object.getJalviewModelSequence()
3543 .getViewport()[0].getSequenceSetId()))
3545 if (Cache.log != null && Cache.log.isDebugEnabled())
3547 Cache.log.debug("Skipping seuqence set id " + id);
3554 public void AddToSkipList(AlignFrame af)
3556 if (skipList == null)
3558 skipList = new Hashtable();
3560 skipList.put(af.getViewport().getSequenceSetId(), af);
3563 public void clearSkipList()
3565 if (skipList != null)
3572 private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al)
3574 jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId());
3575 Vector dseqs = null;
3578 // create a list of new dataset sequences
3579 dseqs = new Vector();
3581 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
3583 Sequence vamsasSeq = vamsasSet.getSequence(i);
3584 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs);
3586 // create a new dataset
3589 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
3590 dseqs.copyInto(dsseqs);
3591 ds = new jalview.datamodel.Alignment(dsseqs);
3592 debug("Created new dataset " + vamsasSet.getDatasetId()
3593 + " for alignment " + System.identityHashCode(al));
3594 addDatasetRef(vamsasSet.getDatasetId(), ds);
3596 // set the dataset for the newly imported alignment.
3597 if (al.getDataset() == null)
3606 * sequence definition to create/merge dataset sequence for
3610 * vector to add new dataset sequence to
3612 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
3613 AlignmentI ds, Vector dseqs)
3615 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
3617 jalview.datamodel.Sequence sq = (jalview.datamodel.Sequence) seqRefIds
3618 .get(vamsasSeq.getId());
3619 jalview.datamodel.SequenceI dsq = null;
3620 if (sq != null && sq.getDatasetSequence() != null)
3622 dsq = sq.getDatasetSequence();
3625 String sqid = vamsasSeq.getDsseqid();
3628 // need to create or add a new dataset sequence reference to this sequence
3631 dsq = (jalview.datamodel.SequenceI) seqRefIds.get(sqid);
3636 // make a new dataset sequence
3637 dsq = sq.createDatasetSequence();
3640 // make up a new dataset reference for this sequence
3641 sqid = seqHash(dsq);
3643 dsq.setVamsasId(uniqueSetSuffix + sqid);
3644 seqRefIds.put(sqid, dsq);
3649 dseqs.addElement(dsq);
3654 ds.addSequence(dsq);
3660 { // make this dataset sequence sq's dataset sequence
3661 sq.setDatasetSequence(dsq);
3665 // TODO: refactor this as a merge dataset sequence function
3666 // now check that sq (the dataset sequence) sequence really is the union of
3667 // all references to it
3668 // boolean pre = sq.getStart() < dsq.getStart();
3669 // boolean post = sq.getEnd() > dsq.getEnd();
3673 StringBuffer sb = new StringBuffer();
3674 String newres = jalview.analysis.AlignSeq.extractGaps(
3675 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
3676 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
3677 && newres.length() > dsq.getLength())
3679 // Update with the longer sequence.
3683 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
3684 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
3685 * sb.append(newres.substring(newres.length() - sq.getEnd() -
3686 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
3688 dsq.setSequence(sb.toString());
3690 // TODO: merges will never happen if we 'know' we have the real dataset
3691 // sequence - this should be detected when id==dssid
3692 System.err.println("DEBUG Notice: Merged dataset sequence"); // ("
3693 // + (pre ? "prepended" : "") + " "
3694 // + (post ? "appended" : ""));
3699 java.util.Hashtable datasetIds = null;
3701 java.util.IdentityHashMap dataset2Ids = null;
3703 private Alignment getDatasetFor(String datasetId)
3705 if (datasetIds == null)
3707 datasetIds = new Hashtable();
3710 if (datasetIds.containsKey(datasetId))
3712 return (Alignment) datasetIds.get(datasetId);
3717 private void addDatasetRef(String datasetId, Alignment dataset)
3719 if (datasetIds == null)
3721 datasetIds = new Hashtable();
3723 datasetIds.put(datasetId, dataset);
3727 * make a new dataset ID for this jalview dataset alignment
3732 private String getDatasetIdRef(jalview.datamodel.Alignment dataset)
3734 if (dataset.getDataset() != null)
3736 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
3738 String datasetId = makeHashCode(dataset, null);
3739 if (datasetId == null)
3741 // make a new datasetId and record it
3742 if (dataset2Ids == null)
3744 dataset2Ids = new IdentityHashMap();
3748 datasetId = (String) dataset2Ids.get(dataset);
3750 if (datasetId == null)
3752 datasetId = "ds" + dataset2Ids.size() + 1;
3753 dataset2Ids.put(dataset, datasetId);
3759 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
3761 for (int d = 0; d < sequence.getDBRefCount(); d++)
3763 DBRef dr = sequence.getDBRef(d);
3764 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
3765 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
3766 .getVersion(), sequence.getDBRef(d).getAccessionId());
3767 if (dr.getMapping() != null)
3769 entry.setMap(addMapping(dr.getMapping()));
3771 datasetSequence.addDBRef(entry);
3775 private jalview.datamodel.Mapping addMapping(Mapping m)
3777 SequenceI dsto = null;
3778 // Mapping m = dr.getMapping();
3779 int fr[] = new int[m.getMapListFromCount() * 2];
3780 Enumeration f = m.enumerateMapListFrom();
3781 for (int _i = 0; f.hasMoreElements(); _i += 2)
3783 MapListFrom mf = (MapListFrom) f.nextElement();
3784 fr[_i] = mf.getStart();
3785 fr[_i + 1] = mf.getEnd();
3787 int fto[] = new int[m.getMapListToCount() * 2];
3788 f = m.enumerateMapListTo();
3789 for (int _i = 0; f.hasMoreElements(); _i += 2)
3791 MapListTo mf = (MapListTo) f.nextElement();
3792 fto[_i] = mf.getStart();
3793 fto[_i + 1] = mf.getEnd();
3795 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
3796 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
3797 if (m.getMappingChoice() != null)
3799 MappingChoice mc = m.getMappingChoice();
3800 if (mc.getDseqFor() != null)
3802 String dsfor = "" + mc.getDseqFor();
3803 if (seqRefIds.containsKey(dsfor))
3808 jmap.setTo((SequenceI) seqRefIds.get(dsfor));
3812 frefedSequence.add(new Object[]
3819 * local sequence definition
3821 Sequence ms = mc.getSequence();
3822 jalview.datamodel.Sequence djs = null;
3823 String sqid = ms.getDsseqid();
3824 if (sqid != null && sqid.length() > 0)
3827 * recover dataset sequence
3829 djs = (jalview.datamodel.Sequence) seqRefIds.get(sqid);
3834 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
3835 sqid = ((Object) ms).toString(); // make up a new hascode for
3836 // undefined dataset sequence hash
3837 // (unlikely to happen)
3843 * make a new dataset sequence and add it to refIds hash
3845 djs = new jalview.datamodel.Sequence(ms.getName(),
3847 djs.setStart(jmap.getMap().getToLowest());
3848 djs.setEnd(jmap.getMap().getToHighest());
3849 djs.setVamsasId(uniqueSetSuffix + sqid);
3851 seqRefIds.put(sqid, djs);
3854 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
3863 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
3864 boolean keepSeqRefs)
3867 jalview.schemabinding.version2.JalviewModel jm = SaveState(ap, null,
3873 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
3877 uniqueSetSuffix = "";
3878 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
3883 if (this.frefedSequence == null)
3885 frefedSequence = new Vector();
3888 viewportsAdded = new Hashtable();
3890 AlignFrame af = LoadFromObject(jm, null, false, null);
3891 af.alignPanels.clear();
3892 af.closeMenuItem_actionPerformed(true);
3895 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
3896 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
3897 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
3898 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
3899 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
3902 return af.alignPanel;
3906 * flag indicating if hashtables should be cleared on finalization TODO this
3907 * flag may not be necessary
3909 private final boolean _cleartables = true;
3911 private Hashtable jvids2vobj;
3916 * @see java.lang.Object#finalize()
3919 protected void finalize() throws Throwable
3921 // really make sure we have no buried refs left.
3926 this.seqRefIds = null;
3927 this.seqsToIds = null;
3931 private void warn(String msg)
3936 private void warn(String msg, Exception e)
3938 if (Cache.log != null)
3942 Cache.log.warn(msg, e);
3946 Cache.log.warn(msg);
3951 System.err.println("Warning: " + msg);
3954 e.printStackTrace();
3959 private void debug(String string)
3961 debug(string, null);
3964 private void debug(String msg, Exception e)
3966 if (Cache.log != null)
3970 Cache.log.debug(msg, e);
3974 Cache.log.debug(msg);
3979 System.err.println("Warning: " + msg);
3982 e.printStackTrace();
3988 * set the object to ID mapping tables used to write/recover objects and XML
3989 * ID strings for the jalview project. If external tables are provided then
3990 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
3991 * object goes out of scope. - also populates the datasetIds hashtable with
3992 * alignment objects containing dataset sequences
3995 * Map from ID strings to jalview datamodel
3997 * Map from jalview datamodel to ID strings
4001 public void setObjectMappingTables(Hashtable vobj2jv,
4002 IdentityHashMap jv2vobj)
4004 this.jv2vobj = jv2vobj;
4005 this.vobj2jv = vobj2jv;
4006 Iterator ds = jv2vobj.keySet().iterator();
4008 while (ds.hasNext())
4010 Object jvobj = ds.next();
4011 id = jv2vobj.get(jvobj).toString();
4012 if (jvobj instanceof jalview.datamodel.Alignment)
4014 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
4016 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
4019 else if (jvobj instanceof jalview.datamodel.Sequence)
4021 // register sequence object so the XML parser can recover it.
4022 if (seqRefIds == null)
4024 seqRefIds = new Hashtable();
4026 if (seqsToIds == null)
4028 seqsToIds = new IdentityHashMap();
4030 seqRefIds.put(jv2vobj.get(jvobj).toString(), jvobj);
4031 seqsToIds.put(jvobj, id);
4033 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
4035 if (annotationIds == null)
4037 annotationIds = new Hashtable();
4040 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvobj);
4041 jalview.datamodel.AlignmentAnnotation jvann = (jalview.datamodel.AlignmentAnnotation) jvobj;
4042 if (jvann.annotationId == null)
4044 jvann.annotationId = anid;
4046 if (!jvann.annotationId.equals(anid))
4048 // TODO verify that this is the correct behaviour
4049 this.warn("Overriding Annotation ID for " + anid
4050 + " from different id : " + jvann.annotationId);
4051 jvann.annotationId = anid;
4054 else if (jvobj instanceof String)
4056 if (jvids2vobj == null)
4058 jvids2vobj = new Hashtable();
4059 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
4063 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
4068 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
4069 * objects created from the project archive. If string is null (default for
4070 * construction) then suffix will be set automatically.
4074 public void setUniqueSetSuffix(String string)
4076 uniqueSetSuffix = string;
4081 * uses skipList2 as the skipList for skipping views on sequence sets
4082 * associated with keys in the skipList
4086 public void setSkipList(Hashtable skipList2)
4088 skipList = skipList2;