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(jal.getSequenceAt(i)).getSequencesInOrder(jal);
515 for (int h = 0; h < reps.length; h++)
517 if (reps[h] != jal.getSequenceAt(i))
519 jseq.addHiddenSequences(jal.findIndex(reps[h]));
525 if (jds.getDatasetSequence().getSequenceFeatures() != null)
527 jalview.datamodel.SequenceFeature[] sf = jds.getDatasetSequence()
528 .getSequenceFeatures();
530 while (index < sf.length)
532 Features features = new Features();
534 features.setBegin(sf[index].getBegin());
535 features.setEnd(sf[index].getEnd());
536 features.setDescription(sf[index].getDescription());
537 features.setType(sf[index].getType());
538 features.setFeatureGroup(sf[index].getFeatureGroup());
539 features.setScore(sf[index].getScore());
540 if (sf[index].links != null)
542 for (int l = 0; l < sf[index].links.size(); l++)
544 OtherData keyValue = new OtherData();
545 keyValue.setKey("LINK_" + l);
546 keyValue.setValue(sf[index].links.elementAt(l).toString());
547 features.addOtherData(keyValue);
550 if (sf[index].otherDetails != null)
553 Enumeration keys = sf[index].otherDetails.keys();
554 while (keys.hasMoreElements())
556 key = keys.nextElement().toString();
557 OtherData keyValue = new OtherData();
558 keyValue.setKey(key);
559 keyValue.setValue(sf[index].otherDetails.get(key).toString());
560 features.addOtherData(keyValue);
564 jseq.addFeatures(features);
569 if (jds.getDatasetSequence().getPDBId() != null)
571 Enumeration en = jds.getDatasetSequence().getPDBId().elements();
572 while (en.hasMoreElements())
574 Pdbids pdb = new Pdbids();
575 jalview.datamodel.PDBEntry entry = (jalview.datamodel.PDBEntry) en
578 pdb.setId(entry.getId());
579 pdb.setType(entry.getType());
582 // This must have been loaded, is it still visible?
583 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
584 String matchedFile = null;
585 for (int f = frames.length - 1; f > -1; f--)
587 if (frames[f] instanceof AppJmol)
589 jmol = (AppJmol) frames[f];
590 for (int peid = 0; peid < jmol.jmb.pdbentry.length; peid++)
592 if (!jmol.jmb.pdbentry[peid].getId().equals(entry.getId())
593 && !(entry.getId().length() > 4 && entry
597 jmol.jmb.pdbentry[peid].getId()
600 if (matchedFile == null)
602 matchedFile = jmol.jmb.pdbentry[peid].getFile();
604 else if (!matchedFile.equals(jmol.jmb.pdbentry[peid]
608 .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
609 + jmol.jmb.pdbentry[peid].getFile());
613 // can get at it if the ID
614 // match is ambiguous (e.g.
616 String statestring = jmol.jmb.viewer.getStateInfo();
618 for (int smap = 0; smap < jmol.jmb.sequence[peid].length; smap++)
620 // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
621 if (jds==jmol.jmb.sequence[peid][smap])
623 StructureState state = new StructureState();
624 state.setVisible(true);
625 state.setXpos(jmol.getX());
626 state.setYpos(jmol.getY());
627 state.setWidth(jmol.getWidth());
628 state.setHeight(jmol.getHeight());
629 state.setViewId(jmol.getViewId());
630 state.setAlignwithAlignPanel(jmol.isUsedforaligment(ap));
631 state.setColourwithAlignPanel(jmol
632 .isUsedforcolourby(ap));
633 state.setColourByJmol(jmol.isColouredByJmol());
634 if (!jmolViewIds.contains(state.getViewId()))
636 // Make sure we only store a Jmol state once in each XML
638 jmolViewIds.addElement(state.getViewId());
639 state.setContent(statestring.replaceAll("\n", ""));
643 state.setContent("# duplicate state");
645 pdb.addStructureState(state);
652 if (matchedFile != null || entry.getFile() != null)
654 if (entry.getFile() != null)
657 matchedFile = entry.getFile();
659 pdb.setFile(matchedFile); // entry.getFile());
660 if (pdbfiles == null)
662 pdbfiles = new Vector();
665 if (!pdbfiles.contains(entry.getId()))
667 pdbfiles.addElement(entry.getId());
670 File file = new File(matchedFile);
671 if (file.exists() && jout != null)
673 byte[] data = new byte[(int) file.length()];
674 jout.putNextEntry(new JarEntry(entry.getId()));
675 DataInputStream dis = new DataInputStream(
676 new FileInputStream(file));
679 DataOutputStream dout = new DataOutputStream(jout);
680 dout.write(data, 0, data.length);
684 } catch (Exception ex)
686 ex.printStackTrace();
692 if (entry.getProperty() != null)
694 PdbentryItem item = new PdbentryItem();
695 Hashtable properties = entry.getProperty();
696 Enumeration en2 = properties.keys();
697 while (en2.hasMoreElements())
699 Property prop = new Property();
700 String key = en2.nextElement().toString();
702 prop.setValue(properties.get(key).toString());
703 item.addProperty(prop);
705 pdb.addPdbentryItem(item);
715 if (av.hasHiddenRows())
717 jal = av.getAlignment();
720 if (jal.getCodonFrames() != null && jal.getCodonFrames().length > 0)
722 jalview.datamodel.AlignedCodonFrame[] jac = jal.getCodonFrames();
723 for (int i = 0; i < jac.length; i++)
725 AlcodonFrame alc = new AlcodonFrame();
726 vamsasSet.addAlcodonFrame(alc);
727 for (int p = 0; p < jac[i].aaWidth; p++)
729 Alcodon cmap = new Alcodon();
730 if (jac[i].codons[p] != null)
732 // Null codons indicate a gapped column in the translated peptide
734 cmap.setPos1(jac[i].codons[p][0]);
735 cmap.setPos2(jac[i].codons[p][1]);
736 cmap.setPos3(jac[i].codons[p][2]);
738 alc.addAlcodon(cmap);
740 if (jac[i].getProtMappings() != null
741 && jac[i].getProtMappings().length > 0)
743 SequenceI[] dnas = jac[i].getdnaSeqs();
744 jalview.datamodel.Mapping[] pmaps = jac[i].getProtMappings();
745 for (int m = 0; m < pmaps.length; m++)
747 AlcodMap alcmap = new AlcodMap();
748 alcmap.setDnasq(seqHash(dnas[m]));
749 alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
751 alc.addAlcodMap(alcmap);
758 // /////////////////////////////////
759 if (av.currentTree != null)
761 // FIND ANY ASSOCIATED TREES
762 // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
763 if (Desktop.desktop != null)
765 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
767 for (int t = 0; t < frames.length; t++)
769 if (frames[t] instanceof TreePanel)
771 TreePanel tp = (TreePanel) frames[t];
773 if (tp.treeCanvas.av.getAlignment() == jal)
775 Tree tree = new Tree();
776 tree.setTitle(tp.getTitle());
777 tree.setCurrentTree((av.currentTree == tp.getTree()));
778 tree.setNewick(tp.getTree().toString());
779 tree.setThreshold(tp.treeCanvas.threshold);
781 tree.setFitToWindow(tp.fitToWindow.getState());
782 tree.setFontName(tp.getTreeFont().getName());
783 tree.setFontSize(tp.getTreeFont().getSize());
784 tree.setFontStyle(tp.getTreeFont().getStyle());
785 tree.setMarkUnlinked(tp.placeholdersMenu.getState());
787 tree.setShowBootstrap(tp.bootstrapMenu.getState());
788 tree.setShowDistances(tp.distanceMenu.getState());
790 tree.setHeight(tp.getHeight());
791 tree.setWidth(tp.getWidth());
792 tree.setXpos(tp.getX());
793 tree.setYpos(tp.getY());
794 tree.setId(makeHashCode(tp, null));
803 * store forward refs from an annotationRow to any groups
805 IdentityHashMap groupRefs = new IdentityHashMap();
806 if (jal.getAlignmentAnnotation() != null)
808 jalview.datamodel.AlignmentAnnotation[] aa = jal
809 .getAlignmentAnnotation();
811 for (int i = 0; i < aa.length; i++)
813 Annotation an = new Annotation();
815 if (aa[i].annotationId != null)
817 annotationIds.put(aa[i].annotationId, aa[i]);
820 an.setId(aa[i].annotationId);
822 an.setVisible(aa[i].visible);
824 an.setDescription(aa[i].description);
826 if (aa[i].sequenceRef != null)
828 // TODO later annotation sequenceRef should be the XML ID of the
829 // sequence rather than its display name
830 an.setSequenceRef(aa[i].sequenceRef.getName());
832 if (aa[i].groupRef != null)
834 Object groupIdr = groupRefs.get(aa[i].groupRef);
835 if (groupIdr == null)
837 // make a locally unique String
838 groupRefs.put(aa[i].groupRef,
839 groupIdr = ("" + System.currentTimeMillis()
840 + aa[i].groupRef.getName() + groupRefs.size()));
842 an.setGroupRef(groupIdr.toString());
845 // store all visualization attributes for annotation
846 an.setGraphHeight(aa[i].graphHeight);
847 an.setCentreColLabels(aa[i].centreColLabels);
848 an.setScaleColLabels(aa[i].scaleColLabel);
849 an.setShowAllColLabels(aa[i].showAllColLabels);
850 an.setBelowAlignment(aa[i].belowAlignment);
855 an.setGraphType(aa[i].graph);
856 an.setGraphGroup(aa[i].graphGroup);
857 if (aa[i].getThreshold() != null)
859 ThresholdLine line = new ThresholdLine();
860 line.setLabel(aa[i].getThreshold().label);
861 line.setValue(aa[i].getThreshold().value);
862 line.setColour(aa[i].getThreshold().colour.getRGB());
863 an.setThresholdLine(line);
871 an.setLabel(aa[i].label);
873 if (aa[i] == av.getAlignmentQualityAnnot() || aa[i] == av.getAlignmentConservationAnnotation()
874 || aa[i] == av.getAlignmentConsensusAnnotation() || aa[i].autoCalculated)
876 // new way of indicating autocalculated annotation -
877 an.setAutoCalculated(aa[i].autoCalculated);
879 if (aa[i].hasScore())
881 an.setScore(aa[i].getScore());
884 if (aa[i].getCalcId()!=null)
886 calcIdSet.add(aa[i].getCalcId());
887 an.setCalcId(aa[i].getCalcId());
890 AnnotationElement ae;
891 if (aa[i].annotations != null)
893 an.setScoreOnly(false);
894 for (int a = 0; a < aa[i].annotations.length; a++)
896 if ((aa[i] == null) || (aa[i].annotations[a] == null))
901 ae = new AnnotationElement();
902 if (aa[i].annotations[a].description != null)
903 ae.setDescription(aa[i].annotations[a].description);
904 if (aa[i].annotations[a].displayCharacter != null)
905 ae.setDisplayCharacter(aa[i].annotations[a].displayCharacter);
907 if (!Float.isNaN(aa[i].annotations[a].value))
908 ae.setValue(aa[i].annotations[a].value);
911 if (aa[i].annotations[a].secondaryStructure != ' '
912 && aa[i].annotations[a].secondaryStructure != '\0')
913 ae.setSecondaryStructure(aa[i].annotations[a].secondaryStructure
916 if (aa[i].annotations[a].colour != null
917 && aa[i].annotations[a].colour != java.awt.Color.black)
919 ae.setColour(aa[i].annotations[a].colour.getRGB());
922 an.addAnnotationElement(ae);
923 if (aa[i].autoCalculated)
925 // only write one non-null entry into the annotation row -
926 // sufficient to get the visualization attributes necessary to
934 an.setScoreOnly(true);
936 vamsasSet.addAnnotation(an);
940 if (jal.getGroups() != null)
942 JGroup[] groups = new JGroup[jal.getGroups().size()];
944 for (jalview.datamodel.SequenceGroup sg:jal.getGroups())
946 groups[++i] = new JGroup();
948 groups[i].setStart(sg.getStartRes());
949 groups[i].setEnd(sg.getEndRes());
950 groups[i].setName(sg.getName());
951 if (groupRefs.containsKey(sg))
953 // group has references so set it's ID field
954 groups[i].setId(groupRefs.get(sg).toString());
958 if (sg.cs.conservationApplied())
960 groups[i].setConsThreshold(sg.cs.getConservationInc());
962 if (sg.cs instanceof jalview.schemes.UserColourScheme)
964 groups[i].setColour(SetUserColourScheme(sg.cs, userColours,
970 .setColour(ColourSchemeProperty.getColourName(sg.cs));
973 else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient)
976 .setColour(ColourSchemeProperty
977 .getColourName(((jalview.schemes.AnnotationColourGradient) sg.cs)
980 else if (sg.cs instanceof jalview.schemes.UserColourScheme)
983 .setColour(SetUserColourScheme(sg.cs, userColours, jms));
987 groups[i].setColour(ColourSchemeProperty.getColourName(sg.cs));
990 groups[i].setPidThreshold(sg.cs.getThreshold());
993 groups[i].setOutlineColour(sg.getOutlineColour().getRGB());
994 groups[i].setDisplayBoxes(sg.getDisplayBoxes());
995 groups[i].setDisplayText(sg.getDisplayText());
996 groups[i].setColourText(sg.getColourText());
997 groups[i].setTextCol1(sg.textColour.getRGB());
998 groups[i].setTextCol2(sg.textColour2.getRGB());
999 groups[i].setTextColThreshold(sg.thresholdTextColour);
1000 groups[i].setShowUnconserved(sg.getShowNonconserved());
1001 groups[i].setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
1002 groups[i].setShowConsensusHistogram(sg.isShowConsensusHistogram());
1003 groups[i].setShowSequenceLogo(sg.isShowSequenceLogo());
1004 for (int s = 0; s < sg.getSize(); s++)
1006 jalview.datamodel.Sequence seq = (jalview.datamodel.Sequence) sg
1008 groups[i].addSeq(seqHash(seq));
1012 jms.setJGroup(groups);
1015 // /////////SAVE VIEWPORT
1016 Viewport view = new Viewport();
1017 view.setTitle(ap.alignFrame.getTitle());
1018 view.setSequenceSetId(makeHashCode(av.getSequenceSetId(),
1019 av.getSequenceSetId()));
1020 view.setId(av.getViewId());
1021 view.setViewName(av.viewName);
1022 view.setGatheredViews(av.gatherViewsHere);
1024 if (ap.av.explodedPosition != null)
1026 view.setXpos(av.explodedPosition.x);
1027 view.setYpos(av.explodedPosition.y);
1028 view.setWidth(av.explodedPosition.width);
1029 view.setHeight(av.explodedPosition.height);
1033 view.setXpos(ap.alignFrame.getBounds().x);
1034 view.setYpos(ap.alignFrame.getBounds().y);
1035 view.setWidth(ap.alignFrame.getBounds().width);
1036 view.setHeight(ap.alignFrame.getBounds().height);
1039 view.setStartRes(av.startRes);
1040 view.setStartSeq(av.startSeq);
1042 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1044 view.setBgColour(SetUserColourScheme(av.getGlobalColourScheme(),
1047 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1049 jalview.schemes.AnnotationColourGradient acg = (jalview.schemes.AnnotationColourGradient) av
1050 .getGlobalColourScheme();
1052 AnnotationColours ac = new AnnotationColours();
1053 ac.setAboveThreshold(acg.getAboveThreshold());
1054 ac.setThreshold(acg.getAnnotationThreshold());
1055 ac.setAnnotation(acg.getAnnotation());
1056 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1058 ac.setColourScheme(SetUserColourScheme(acg.getBaseColour(),
1063 ac.setColourScheme(ColourSchemeProperty.getColourName(acg
1067 ac.setMaxColour(acg.getMaxColour().getRGB());
1068 ac.setMinColour(acg.getMinColour().getRGB());
1069 view.setAnnotationColours(ac);
1070 view.setBgColour("AnnotationColourGradient");
1074 view.setBgColour(ColourSchemeProperty.getColourName(av
1075 .getGlobalColourScheme()));
1078 ColourSchemeI cs = av.getGlobalColourScheme();
1082 if (cs.conservationApplied())
1084 view.setConsThreshold(cs.getConservationInc());
1085 if (cs instanceof jalview.schemes.UserColourScheme)
1087 view.setBgColour(SetUserColourScheme(cs, userColours, jms));
1091 if (cs instanceof ResidueColourScheme)
1093 view.setPidThreshold(cs.getThreshold());
1097 view.setConservationSelected(av.getConservationSelected());
1098 view.setPidSelected(av.getAbovePIDThreshold());
1099 view.setFontName(av.font.getName());
1100 view.setFontSize(av.font.getSize());
1101 view.setFontStyle(av.font.getStyle());
1102 view.setRenderGaps(av.renderGaps);
1103 view.setShowAnnotation(av.getShowAnnotation());
1104 view.setShowBoxes(av.getShowBoxes());
1105 view.setShowColourText(av.getColourText());
1106 view.setShowFullId(av.getShowJVSuffix());
1107 view.setRightAlignIds(av.rightAlignIds);
1108 view.setShowSequenceFeatures(av.showSequenceFeatures);
1109 view.setShowText(av.getShowText());
1110 view.setShowUnconserved(av.getShowUnconserved());
1111 view.setWrapAlignment(av.getWrapAlignment());
1112 view.setTextCol1(av.textColour.getRGB());
1113 view.setTextCol2(av.textColour2.getRGB());
1114 view.setTextColThreshold(av.thresholdTextColour);
1115 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1116 view.setShowSequenceLogo(av.isShowSequenceLogo());
1117 view.setShowGroupConsensus(av.isShowGroupConsensus());
1118 view.setShowGroupConservation(av.isShowGroupConservation());
1119 view.setShowNPfeatureTooltip(av.isShowNpFeats());
1120 view.setShowDbRefTooltip(av.isShowDbRefs());
1121 view.setFollowHighlight(av.followHighlight);
1122 view.setFollowSelection(av.followSelection);
1123 view.setIgnoreGapsinConsensus(av.getIgnoreGapsConsensus());
1124 if (av.featuresDisplayed != null)
1126 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1128 String[] renderOrder = ap.seqPanel.seqCanvas.getFeatureRenderer().renderOrder;
1130 Vector settingsAdded = new Vector();
1131 Object gstyle = null;
1132 GraduatedColor gcol = null;
1133 if (renderOrder != null)
1135 for (int ro = 0; ro < renderOrder.length; ro++)
1137 gstyle = ap.seqPanel.seqCanvas.getFeatureRenderer()
1138 .getFeatureStyle(renderOrder[ro]);
1139 Setting setting = new Setting();
1140 setting.setType(renderOrder[ro]);
1141 if (gstyle instanceof GraduatedColor)
1143 gcol = (GraduatedColor) gstyle;
1144 setting.setColour(gcol.getMaxColor().getRGB());
1145 setting.setMincolour(gcol.getMinColor().getRGB());
1146 setting.setMin(gcol.getMin());
1147 setting.setMax(gcol.getMax());
1148 setting.setColourByLabel(gcol.isColourByLabel());
1149 setting.setAutoScale(gcol.isAutoScale());
1150 setting.setThreshold(gcol.getThresh());
1151 setting.setThreshstate(gcol.getThreshType());
1155 setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer()
1156 .getColour(renderOrder[ro]).getRGB());
1159 setting.setDisplay(av.featuresDisplayed
1160 .containsKey(renderOrder[ro]));
1161 float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer()
1162 .getOrder(renderOrder[ro]);
1165 setting.setOrder(rorder);
1167 fs.addSetting(setting);
1168 settingsAdded.addElement(renderOrder[ro]);
1172 // Make sure we save none displayed feature settings
1173 Iterator en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureColours
1174 .keySet().iterator();
1175 while (en.hasNext())
1177 String key = en.next().toString();
1178 if (settingsAdded.contains(key))
1183 Setting setting = new Setting();
1184 setting.setType(key);
1185 setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer()
1186 .getColour(key).getRGB());
1188 setting.setDisplay(false);
1189 float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer().getOrder(
1193 setting.setOrder(rorder);
1195 fs.addSetting(setting);
1196 settingsAdded.addElement(key);
1198 en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups.keySet().iterator();
1199 Vector groupsAdded = new Vector();
1200 while (en.hasNext())
1202 String grp = en.next().toString();
1203 if (groupsAdded.contains(grp))
1207 Group g = new Group();
1209 g.setDisplay(((Boolean) ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups
1210 .get(grp)).booleanValue());
1212 groupsAdded.addElement(grp);
1214 jms.setFeatureSettings(fs);
1218 if (av.hasHiddenColumns())
1220 if (av.getColumnSelection() == null
1221 || av.getColumnSelection().getHiddenColumns() == null)
1223 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1227 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1230 int[] region = (int[]) av.getColumnSelection().getHiddenColumns()
1232 HiddenColumns hc = new HiddenColumns();
1233 hc.setStart(region[0]);
1234 hc.setEnd(region[1]);
1235 view.addHiddenColumns(hc);
1239 if (calcIdSet.size() > 0)
1241 for (String calcId : calcIdSet)
1243 if (calcId.trim().length() > 0)
1245 CalcIdParam cidp = createCalcIdParam(calcId, av);
1246 // Some calcIds have no parameters.
1249 view.addCalcIdParam(cidp);
1255 jms.addViewport(view);
1257 object.setJalviewModelSequence(jms);
1258 object.getVamsasModel().addSequenceSet(vamsasSet);
1260 if (jout != null && fileName != null)
1262 // We may not want to write the object to disk,
1263 // eg we can copy the alignViewport to a new view object
1264 // using save and then load
1267 JarEntry entry = new JarEntry(fileName);
1268 jout.putNextEntry(entry);
1269 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1271 org.exolab.castor.xml.Marshaller marshaller = new org.exolab.castor.xml.Marshaller(
1273 marshaller.marshal(object);
1276 } catch (Exception ex)
1278 // TODO: raise error in GUI if marshalling failed.
1279 ex.printStackTrace();
1285 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1287 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1288 if (settings != null)
1290 CalcIdParam vCalcIdParam = new CalcIdParam();
1291 vCalcIdParam.setCalcId(calcId);
1292 vCalcIdParam.addServiceURL(settings.getServiceURI());
1293 // generic URI allowing a third party to resolve another instance of the
1294 // service used for this calculation
1295 for (String urls:settings.getServiceURLs())
1297 vCalcIdParam.addServiceURL(urls);
1299 vCalcIdParam.setVersion("1.0");
1300 if (settings.getPreset() != null)
1302 WsParamSetI setting = settings.getPreset();
1303 vCalcIdParam.setName(setting.getName());
1304 vCalcIdParam.setDescription(setting.getDescription());
1308 vCalcIdParam.setName("");
1309 vCalcIdParam.setDescription("Last used parameters");
1311 // need to be able to recover 1) settings 2) user-defined presets or
1312 // recreate settings from preset 3) predefined settings provided by
1313 // service - or settings that can be transferred (or discarded)
1314 vCalcIdParam.setParameters(settings
1315 .getWsParamFile().replace("\n", "|\\n|"));
1316 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1317 // todo - decide if updateImmediately is needed for any projects.
1319 return vCalcIdParam;
1324 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1327 if (calcIdParam.getVersion().equals("1.0"))
1329 Jws2Instance service=Jws2Discoverer.getDiscoverer().getPreferredServiceFor(calcIdParam.getServiceURL());
1332 WsParamSetI parmSet=null;
1334 parmSet = service.getParamStore().parseServiceParameterFile(calcIdParam.getName(), calcIdParam.getDescription(), calcIdParam.getServiceURL(), calcIdParam.getParameters().replace("|\\n|", "\n"));
1335 } catch (IOException x)
1337 warn("Couldn't parse parameter data for "+calcIdParam.getCalcId(), x);
1340 List<ArgumentI> argList=null;
1341 if (calcIdParam.getName().length()>0) {
1342 parmSet = service.getParamStore().getPreset(calcIdParam.getName());
1345 // TODO : check we have a good match with settings in AACons - otherwise we'll need to create a new preset
1349 argList = parmSet.getArguments();
1352 AAConsSettings settings = new AAConsSettings(calcIdParam.isAutoUpdate(), service, parmSet, argList);
1353 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings, calcIdParam.isNeedsUpdate());
1356 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1360 throw new Error("Unsupported Version for calcIdparam "
1361 + calcIdParam.toString());
1364 * External mapping between jalview objects and objects yielding a valid and
1365 * unique object ID string. This is null for normal Jalview project IO, but
1366 * non-null when a jalview project is being read or written as part of a
1369 IdentityHashMap jv2vobj = null;
1372 * Construct a unique ID for jvobj using either existing bindings or if none
1373 * exist, the result of the hashcode call for the object.
1376 * jalview data object
1377 * @return unique ID for referring to jvobj
1379 private String makeHashCode(Object jvobj, String altCode)
1381 if (jv2vobj != null)
1383 Object id = jv2vobj.get(jvobj);
1386 return id.toString();
1388 // check string ID mappings
1389 if (jvids2vobj != null && jvobj instanceof String)
1391 id = jvids2vobj.get(jvobj);
1395 return id.toString();
1397 // give up and warn that something has gone wrong
1398 warn("Cannot find ID for object in external mapping : " + jvobj);
1404 * return local jalview object mapped to ID, if it exists
1408 * @return null or object bound to idcode
1410 private Object retrieveExistingObj(String idcode)
1412 if (idcode != null && vobj2jv != null)
1414 return vobj2jv.get(idcode);
1420 * binding from ID strings from external mapping table to jalview data model
1423 private Hashtable vobj2jv;
1425 private Sequence createVamsasSequence(String id, SequenceI jds)
1427 return createVamsasSequence(true, id, jds, null);
1430 private Sequence createVamsasSequence(boolean recurse, String id,
1431 SequenceI jds, SequenceI parentseq)
1433 Sequence vamsasSeq = new Sequence();
1434 vamsasSeq.setId(id);
1435 vamsasSeq.setName(jds.getName());
1436 vamsasSeq.setSequence(jds.getSequenceAsString());
1437 vamsasSeq.setDescription(jds.getDescription());
1438 jalview.datamodel.DBRefEntry[] dbrefs = null;
1439 if (jds.getDatasetSequence() != null)
1441 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
1442 if (jds.getDatasetSequence().getDBRef() != null)
1444 dbrefs = jds.getDatasetSequence().getDBRef();
1449 vamsasSeq.setDsseqid(id); // so we can tell which sequences really are
1450 // dataset sequences only
1451 dbrefs = jds.getDBRef();
1455 for (int d = 0; d < dbrefs.length; d++)
1457 DBRef dbref = new DBRef();
1458 dbref.setSource(dbrefs[d].getSource());
1459 dbref.setVersion(dbrefs[d].getVersion());
1460 dbref.setAccessionId(dbrefs[d].getAccessionId());
1461 if (dbrefs[d].hasMap())
1463 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
1465 dbref.setMapping(mp);
1467 vamsasSeq.addDBRef(dbref);
1473 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
1474 SequenceI parentseq, SequenceI jds, boolean recurse)
1477 if (jmp.getMap() != null)
1481 jalview.util.MapList mlst = jmp.getMap();
1482 int r[] = mlst.getFromRanges();
1483 for (int s = 0; s < r.length; s += 2)
1485 MapListFrom mfrom = new MapListFrom();
1486 mfrom.setStart(r[s]);
1487 mfrom.setEnd(r[s + 1]);
1488 mp.addMapListFrom(mfrom);
1490 r = mlst.getToRanges();
1491 for (int s = 0; s < r.length; s += 2)
1493 MapListTo mto = new MapListTo();
1495 mto.setEnd(r[s + 1]);
1496 mp.addMapListTo(mto);
1498 mp.setMapFromUnit(mlst.getFromRatio());
1499 mp.setMapToUnit(mlst.getToRatio());
1500 if (jmp.getTo() != null)
1502 MappingChoice mpc = new MappingChoice();
1504 && (parentseq != jmp.getTo() || parentseq
1505 .getDatasetSequence() != jmp.getTo()))
1507 mpc.setSequence(createVamsasSequence(false, seqHash(jmp.getTo()),
1513 SequenceI ps = null;
1514 if (parentseq != jmp.getTo()
1515 && parentseq.getDatasetSequence() != jmp.getTo())
1517 // chaining dbref rather than a handshaking one
1518 jmpid = seqHash(ps = jmp.getTo());
1522 jmpid = seqHash(ps = parentseq);
1524 mpc.setDseqFor(jmpid);
1525 if (!seqRefIds.containsKey(mpc.getDseqFor()))
1527 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
1528 seqRefIds.put(mpc.getDseqFor(), ps);
1532 jalview.bin.Cache.log.debug("reusing DseqFor ID");
1535 mp.setMappingChoice(mpc);
1541 String SetUserColourScheme(jalview.schemes.ColourSchemeI cs,
1542 Vector userColours, JalviewModelSequence jms)
1545 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
1546 boolean newucs = false;
1547 if (!userColours.contains(ucs))
1549 userColours.add(ucs);
1552 id = "ucs" + userColours.indexOf(ucs);
1555 // actually create the scheme's entry in the XML model
1556 java.awt.Color[] colours = ucs.getColours();
1557 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
1558 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
1560 for (int i = 0; i < colours.length; i++)
1562 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1563 col.setName(ResidueProperties.aa[i]);
1564 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1565 jbucs.addColour(col);
1567 if (ucs.getLowerCaseColours() != null)
1569 colours = ucs.getLowerCaseColours();
1570 for (int i = 0; i < colours.length; i++)
1572 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1573 col.setName(ResidueProperties.aa[i].toLowerCase());
1574 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1575 jbucs.addColour(col);
1580 uc.setUserColourScheme(jbucs);
1581 jms.addUserColours(uc);
1587 jalview.schemes.UserColourScheme GetUserColourScheme(
1588 JalviewModelSequence jms, String id)
1590 UserColours[] uc = jms.getUserColours();
1591 UserColours colours = null;
1593 for (int i = 0; i < uc.length; i++)
1595 if (uc[i].getId().equals(id))
1603 java.awt.Color[] newColours = new java.awt.Color[24];
1605 for (int i = 0; i < 24; i++)
1607 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1608 .getUserColourScheme().getColour(i).getRGB(), 16));
1611 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
1614 if (colours.getUserColourScheme().getColourCount() > 24)
1616 newColours = new java.awt.Color[23];
1617 for (int i = 0; i < 23; i++)
1619 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1620 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
1622 ucs.setLowerCaseColours(newColours);
1629 * contains last error message (if any) encountered by XML loader.
1631 String errorMessage = null;
1634 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
1635 * exceptions are raised during project XML parsing
1637 public boolean attemptversion1parse = true;
1640 * Load a jalview project archive from a jar file
1643 * - HTTP URL or filename
1645 public AlignFrame LoadJalviewAlign(final String file)
1648 jalview.gui.AlignFrame af = null;
1652 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
1653 // Workaround is to make sure caller implements the JarInputStreamProvider
1655 // so we can re-open the jar input stream for each entry.
1657 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
1658 af = LoadJalviewAlign(jprovider);
1659 } catch (MalformedURLException e)
1661 errorMessage = "Invalid URL format for '" + file + "'";
1667 private jarInputStreamProvider createjarInputStreamProvider(
1668 final String file) throws MalformedURLException
1671 errorMessage = null;
1672 uniqueSetSuffix = null;
1674 viewportsAdded = null;
1675 frefedSequence = null;
1677 if (file.startsWith("http://"))
1679 url = new URL(file);
1681 final URL _url = url;
1682 return new jarInputStreamProvider()
1686 public JarInputStream getJarInputStream() throws IOException
1690 return new JarInputStream(_url.openStream());
1694 return new JarInputStream(new FileInputStream(file));
1699 public String getFilename()
1707 * Recover jalview session from a jalview project archive. Caller may
1708 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
1709 * themselves. Any null fields will be initialised with default values,
1710 * non-null fields are left alone.
1715 public AlignFrame LoadJalviewAlign(final jarInputStreamProvider jprovider)
1717 errorMessage = null;
1718 if (uniqueSetSuffix == null)
1720 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
1722 if (seqRefIds == null)
1724 seqRefIds = new Hashtable();
1726 if (viewportsAdded == null)
1728 viewportsAdded = new Hashtable();
1730 if (frefedSequence == null)
1732 frefedSequence = new Vector();
1735 jalview.gui.AlignFrame af = null;
1736 Hashtable gatherToThisFrame = new Hashtable();
1737 final String file = jprovider.getFilename();
1740 JarInputStream jin = null;
1741 JarEntry jarentry = null;
1746 jin = jprovider.getJarInputStream();
1747 for (int i = 0; i < entryCount; i++)
1749 jarentry = jin.getNextJarEntry();
1752 if (jarentry != null && jarentry.getName().endsWith(".xml"))
1754 InputStreamReader in = new InputStreamReader(jin, "UTF-8");
1755 JalviewModel object = new JalviewModel();
1757 Unmarshaller unmar = new Unmarshaller(object);
1758 unmar.setValidation(false);
1759 object = (JalviewModel) unmar.unmarshal(in);
1760 if (true) // !skipViewport(object))
1762 af = LoadFromObject(object, file, true, jprovider);
1763 if (af.viewport.gatherViewsHere)
1765 gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
1770 else if (jarentry != null)
1772 // Some other file here.
1775 } while (jarentry != null);
1776 resolveFrefedSequences();
1777 } catch (java.io.FileNotFoundException ex)
1779 ex.printStackTrace();
1780 errorMessage = "Couldn't locate Jalview XML file : " + file;
1781 System.err.println("Exception whilst loading jalview XML file : "
1783 } catch (java.net.UnknownHostException ex)
1785 ex.printStackTrace();
1786 errorMessage = "Couldn't locate Jalview XML file : " + file;
1787 System.err.println("Exception whilst loading jalview XML file : "
1789 } catch (Exception ex)
1791 System.err.println("Parsing as Jalview Version 2 file failed.");
1792 ex.printStackTrace(System.err);
1793 if (attemptversion1parse)
1795 // Is Version 1 Jar file?
1798 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
1799 } catch (Exception ex2)
1801 System.err.println("Exception whilst loading as jalviewXMLV1:");
1802 ex2.printStackTrace();
1806 if (Desktop.instance != null)
1808 Desktop.instance.stopLoading();
1812 System.out.println("Successfully loaded archive file");
1815 ex.printStackTrace();
1817 System.err.println("Exception whilst loading jalview XML file : "
1819 } catch (OutOfMemoryError e)
1821 // Don't use the OOM Window here
1822 errorMessage = "Out of memory loading jalview XML file";
1823 System.err.println("Out of memory whilst loading jalview XML file");
1824 e.printStackTrace();
1827 if (Desktop.instance != null)
1829 Desktop.instance.stopLoading();
1832 Enumeration en = gatherToThisFrame.elements();
1833 while (en.hasMoreElements())
1835 Desktop.instance.gatherViews((AlignFrame) en.nextElement());
1837 if (errorMessage != null)
1845 * check errorMessage for a valid error message and raise an error box in the
1846 * GUI or write the current errorMessage to stderr and then clear the error
1849 protected void reportErrors()
1851 reportErrors(false);
1854 protected void reportErrors(final boolean saving)
1856 if (errorMessage != null)
1858 final String finalErrorMessage = errorMessage;
1861 javax.swing.SwingUtilities.invokeLater(new Runnable()
1866 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1867 finalErrorMessage, "Error "
1868 + (saving ? "saving" : "loading")
1869 + " Jalview file", JOptionPane.WARNING_MESSAGE);
1875 System.err.println("Problem loading Jalview file: " + errorMessage);
1878 errorMessage = null;
1881 Hashtable alreadyLoadedPDB;
1884 * when set, local views will be updated from view stored in JalviewXML
1885 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
1886 * sync if this is set to true.
1888 private final boolean updateLocalViews = false;
1890 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
1892 if (alreadyLoadedPDB == null)
1893 alreadyLoadedPDB = new Hashtable();
1895 if (alreadyLoadedPDB.containsKey(pdbId))
1896 return alreadyLoadedPDB.get(pdbId).toString();
1900 JarInputStream jin = jprovider.getJarInputStream();
1902 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
1903 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
1904 * FileInputStream(jprovider)); }
1907 JarEntry entry = null;
1910 entry = jin.getNextJarEntry();
1911 } while (entry != null && !entry.getName().equals(pdbId));
1914 BufferedReader in = new BufferedReader(new InputStreamReader(jin));
1915 File outFile = File.createTempFile("jalview_pdb", ".txt");
1916 outFile.deleteOnExit();
1917 PrintWriter out = new PrintWriter(new FileOutputStream(outFile));
1920 while ((data = in.readLine()) != null)
1927 } catch (Exception foo)
1932 String t=outFile.getAbsolutePath();
1933 alreadyLoadedPDB.put(pdbId, t);
1938 warn("Couldn't find PDB file entry in Jalview Jar for " + pdbId);
1940 } catch (Exception ex)
1942 ex.printStackTrace();
1948 private class JvAnnotRow
1950 public JvAnnotRow(int i, AlignmentAnnotation jaa)
1957 * persisted version of annotation row from which to take vis properties
1959 public jalview.datamodel.AlignmentAnnotation template;
1962 * original position of the annotation row in the alignment
1968 * Load alignment frame from jalview XML DOM object
1973 * filename source string
1974 * @param loadTreesAndStructures
1975 * when false only create Viewport
1977 * data source provider
1978 * @return alignment frame created from view stored in DOM
1980 AlignFrame LoadFromObject(JalviewModel object, String file,
1981 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
1983 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
1984 Sequence[] vamsasSeq = vamsasSet.getSequence();
1986 JalviewModelSequence jms = object.getJalviewModelSequence();
1988 Viewport view = jms.getViewport(0);
1989 // ////////////////////////////////
1992 Vector hiddenSeqs = null;
1993 jalview.datamodel.Sequence jseq;
1995 ArrayList tmpseqs = new ArrayList();
1997 boolean multipleView = false;
1999 JSeq[] JSEQ = object.getJalviewModelSequence().getJSeq();
2000 int vi = 0; // counter in vamsasSeq array
2001 for (int i = 0; i < JSEQ.length; i++)
2003 String seqId = JSEQ[i].getId();
2005 if (seqRefIds.get(seqId) != null)
2007 tmpseqs.add(seqRefIds.get(seqId));
2008 multipleView = true;
2012 jseq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2013 vamsasSeq[vi].getSequence());
2014 jseq.setDescription(vamsasSeq[vi].getDescription());
2015 jseq.setStart(JSEQ[i].getStart());
2016 jseq.setEnd(JSEQ[i].getEnd());
2017 jseq.setVamsasId(uniqueSetSuffix + seqId);
2018 seqRefIds.put(vamsasSeq[vi].getId(), jseq);
2023 if (JSEQ[i].getHidden())
2025 if (hiddenSeqs == null)
2027 hiddenSeqs = new Vector();
2030 hiddenSeqs.addElement(seqRefIds
2037 // Create the alignment object from the sequence set
2038 // ///////////////////////////////
2039 jalview.datamodel.Sequence[] orderedSeqs = new jalview.datamodel.Sequence[tmpseqs
2042 tmpseqs.toArray(orderedSeqs);
2044 jalview.datamodel.Alignment al = new jalview.datamodel.Alignment(
2047 // / Add the alignment properties
2048 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2050 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2051 al.setProperty(ssp.getKey(), ssp.getValue());
2055 // SequenceFeatures are added to the DatasetSequence,
2056 // so we must create or recover the dataset before loading features
2057 // ///////////////////////////////
2058 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2060 // older jalview projects do not have a dataset id.
2061 al.setDataset(null);
2065 recoverDatasetFor(vamsasSet, al);
2067 // ///////////////////////////////
2069 Hashtable pdbloaded = new Hashtable();
2072 // load sequence features, database references and any associated PDB
2073 // structures for the alignment
2074 for (int i = 0; i < vamsasSeq.length; i++)
2076 if (JSEQ[i].getFeaturesCount() > 0)
2078 Features[] features = JSEQ[i].getFeatures();
2079 for (int f = 0; f < features.length; f++)
2081 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2082 features[f].getType(), features[f].getDescription(),
2083 features[f].getStatus(), features[f].getBegin(),
2084 features[f].getEnd(), features[f].getFeatureGroup());
2086 sf.setScore(features[f].getScore());
2087 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2089 OtherData keyValue = features[f].getOtherData(od);
2090 if (keyValue.getKey().startsWith("LINK"))
2092 sf.addLink(keyValue.getValue());
2096 sf.setValue(keyValue.getKey(), keyValue.getValue());
2101 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
2104 if (vamsasSeq[i].getDBRefCount() > 0)
2106 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2108 if (JSEQ[i].getPdbidsCount() > 0)
2110 Pdbids[] ids = JSEQ[i].getPdbids();
2111 for (int p = 0; p < ids.length; p++)
2113 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2114 entry.setId(ids[p].getId());
2115 entry.setType(ids[p].getType());
2116 if (ids[p].getFile() != null)
2118 if (!pdbloaded.containsKey(ids[p].getFile()))
2120 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2124 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2128 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2132 } // end !multipleview
2134 // ///////////////////////////////
2135 // LOAD SEQUENCE MAPPINGS
2137 if (vamsasSet.getAlcodonFrameCount() > 0)
2139 // TODO Potentially this should only be done once for all views of an
2141 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2142 for (int i = 0; i < alc.length; i++)
2144 jalview.datamodel.AlignedCodonFrame cf = new jalview.datamodel.AlignedCodonFrame(
2145 alc[i].getAlcodonCount());
2146 if (alc[i].getAlcodonCount() > 0)
2148 Alcodon[] alcods = alc[i].getAlcodon();
2149 for (int p = 0; p < cf.codons.length; p++)
2151 if (alcods[p].hasPos1() && alcods[p].hasPos2()
2152 && alcods[p].hasPos3())
2154 // translated codons require three valid positions
2155 cf.codons[p] = new int[3];
2156 cf.codons[p][0] = (int) alcods[p].getPos1();
2157 cf.codons[p][1] = (int) alcods[p].getPos2();
2158 cf.codons[p][2] = (int) alcods[p].getPos3();
2162 cf.codons[p] = null;
2166 if (alc[i].getAlcodMapCount() > 0)
2168 AlcodMap[] maps = alc[i].getAlcodMap();
2169 for (int m = 0; m < maps.length; m++)
2171 SequenceI dnaseq = (SequenceI) seqRefIds
2172 .get(maps[m].getDnasq());
2174 jalview.datamodel.Mapping mapping = null;
2175 // attach to dna sequence reference.
2176 if (maps[m].getMapping() != null)
2178 mapping = addMapping(maps[m].getMapping());
2182 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
2187 frefedSequence.add(new Object[]
2188 { maps[m].getDnasq(), cf, mapping });
2192 al.addCodonFrame(cf);
2197 // ////////////////////////////////
2199 ArrayList<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
2201 * store any annotations which forward reference a group's ID
2203 Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>>();
2205 if (vamsasSet.getAnnotationCount() > 0)
2207 Annotation[] an = vamsasSet.getAnnotation();
2209 for (int i = 0; i < an.length; i++)
2212 * test if annotation is automatically calculated for this view only
2214 boolean autoForView = false;
2215 if (an[i].getLabel().equals("Quality")
2216 || an[i].getLabel().equals("Conservation")
2217 || an[i].getLabel().equals("Consensus"))
2219 // Kludge for pre 2.5 projects which lacked the autocalculated flag
2221 if (!an[i].hasAutoCalculated())
2223 an[i].setAutoCalculated(true);
2227 || (an[i].hasAutoCalculated() && an[i].isAutoCalculated()))
2229 // remove ID - we don't recover annotation from other views for
2230 // view-specific annotation
2234 // set visiblity for other annotation in this view
2235 if (an[i].getId() != null
2236 && annotationIds.containsKey(an[i].getId()))
2238 jalview.datamodel.AlignmentAnnotation jda = (jalview.datamodel.AlignmentAnnotation) annotationIds
2239 .get(an[i].getId());
2240 // in principle Visible should always be true for annotation displayed
2241 // in multiple views
2242 if (an[i].hasVisible())
2243 jda.visible = an[i].getVisible();
2245 al.addAnnotation(jda);
2249 // Construct new annotation from model.
2250 AnnotationElement[] ae = an[i].getAnnotationElement();
2251 jalview.datamodel.Annotation[] anot = null;
2253 if (!an[i].getScoreOnly())
2255 anot = new jalview.datamodel.Annotation[al.getWidth()];
2256 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
2258 if (ae[aa].getPosition() >= anot.length)
2261 anot[ae[aa].getPosition()] = new jalview.datamodel.Annotation(
2263 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
2264 (ae[aa].getSecondaryStructure() == null || ae[aa]
2265 .getSecondaryStructure().length() == 0) ? ' '
2266 : ae[aa].getSecondaryStructure().charAt(0),
2270 // JBPNote: Consider verifying dataflow for IO of secondary
2271 // structure annotation read from Stockholm files
2272 // this was added to try to ensure that
2273 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
2275 // anot[ae[aa].getPosition()].displayCharacter = "";
2277 anot[ae[aa].getPosition()].colour = new java.awt.Color(
2278 ae[aa].getColour());
2281 jalview.datamodel.AlignmentAnnotation jaa = null;
2283 if (an[i].getGraph())
2285 float llim = 0, hlim = 0;
2286 // if (autoForView || an[i].isAutoCalculated()) {
2289 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2290 an[i].getDescription(), anot, llim, hlim,
2291 an[i].getGraphType());
2293 jaa.graphGroup = an[i].getGraphGroup();
2295 if (an[i].getThresholdLine() != null)
2297 jaa.setThreshold(new jalview.datamodel.GraphLine(an[i]
2298 .getThresholdLine().getValue(), an[i]
2299 .getThresholdLine().getLabel(), new java.awt.Color(
2300 an[i].getThresholdLine().getColour())));
2303 if (autoForView || an[i].isAutoCalculated())
2305 // Hardwire the symbol display line to ensure that labels for
2306 // histograms are displayed
2312 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2313 an[i].getDescription(), anot);
2315 // register new annotation
2316 if (an[i].getId() != null)
2318 annotationIds.put(an[i].getId(), jaa);
2319 jaa.annotationId = an[i].getId();
2321 // recover sequence association
2322 if (an[i].getSequenceRef() != null)
2324 if (al.findName(an[i].getSequenceRef()) != null)
2326 jaa.createSequenceMapping(al.findName(an[i].getSequenceRef()),
2328 al.findName(an[i].getSequenceRef()).addAlignmentAnnotation(jaa);
2331 // and make a note of any group association
2332 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
2334 ArrayList<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
2335 .get(an[i].getGroupRef());
2338 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
2339 groupAnnotRefs.put(an[i].getGroupRef(), aal);
2344 if (an[i].hasScore())
2346 jaa.setScore(an[i].getScore());
2348 if (an[i].hasVisible())
2349 jaa.visible = an[i].getVisible();
2351 if (an[i].hasCentreColLabels())
2352 jaa.centreColLabels = an[i].getCentreColLabels();
2354 if (an[i].hasScaleColLabels())
2356 jaa.scaleColLabel = an[i].getScaleColLabels();
2358 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
2360 // newer files have an 'autoCalculated' flag and store calculation
2361 // state in viewport properties
2362 jaa.autoCalculated = true; // means annotation will be marked for
2363 // update at end of load.
2365 if (an[i].hasGraphHeight())
2367 jaa.graphHeight = an[i].getGraphHeight();
2369 if (an[i].hasBelowAlignment())
2371 jaa.belowAlignment=an[i].isBelowAlignment();
2373 jaa.setCalcId(an[i].getCalcId());
2375 if (jaa.autoCalculated)
2377 autoAlan.add(new JvAnnotRow(i, jaa));
2380 // if (!autoForView)
2382 // add autocalculated group annotation and any user created annotation
2384 al.addAnnotation(jaa);
2389 // ///////////////////////
2391 // Create alignment markup and styles for this view
2392 if (jms.getJGroupCount() > 0)
2394 JGroup[] groups = jms.getJGroup();
2396 for (int i = 0; i < groups.length; i++)
2398 ColourSchemeI cs = null;
2400 if (groups[i].getColour() != null)
2402 if (groups[i].getColour().startsWith("ucs"))
2404 cs = GetUserColourScheme(jms, groups[i].getColour());
2408 cs = ColourSchemeProperty.getColour(al, groups[i].getColour());
2413 cs.setThreshold(groups[i].getPidThreshold(), true);
2417 Vector seqs = new Vector();
2419 for (int s = 0; s < groups[i].getSeqCount(); s++)
2421 String seqId = groups[i].getSeq(s) + "";
2422 jalview.datamodel.SequenceI ts = (jalview.datamodel.SequenceI) seqRefIds
2427 seqs.addElement(ts);
2431 if (seqs.size() < 1)
2436 jalview.datamodel.SequenceGroup sg = new jalview.datamodel.SequenceGroup(
2437 seqs, groups[i].getName(), cs, groups[i].getDisplayBoxes(),
2438 groups[i].getDisplayText(), groups[i].getColourText(),
2439 groups[i].getStart(), groups[i].getEnd());
2441 sg.setOutlineColour(new java.awt.Color(groups[i].getOutlineColour()));
2443 sg.textColour = new java.awt.Color(groups[i].getTextCol1());
2444 sg.textColour2 = new java.awt.Color(groups[i].getTextCol2());
2445 sg.setShowNonconserved(groups[i].hasShowUnconserved() ? groups[i]
2446 .isShowUnconserved() : false);
2447 sg.thresholdTextColour = groups[i].getTextColThreshold();
2448 if (groups[i].hasShowConsensusHistogram())
2450 sg.setShowConsensusHistogram(groups[i].isShowConsensusHistogram());
2453 if (groups[i].hasShowSequenceLogo())
2455 sg.setshowSequenceLogo(groups[i].isShowSequenceLogo());
2457 if (groups[i].hasIgnoreGapsinConsensus())
2459 sg.setIgnoreGapsConsensus(groups[i].getIgnoreGapsinConsensus());
2461 if (groups[i].getConsThreshold() != 0)
2463 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
2464 "All", ResidueProperties.propHash, 3,
2465 sg.getSequences(null), 0, sg.getWidth() - 1);
2467 c.verdict(false, 25);
2468 sg.cs.setConservation(c);
2471 if (groups[i].getId() != null && groupAnnotRefs.size() > 0)
2473 // re-instate unique group/annotation row reference
2474 ArrayList<jalview.datamodel.AlignmentAnnotation> jaal = groupAnnotRefs
2475 .get(groups[i].getId());
2478 for (jalview.datamodel.AlignmentAnnotation jaa : jaal)
2481 if (jaa.autoCalculated)
2483 // match up and try to set group autocalc alignment row for this
2485 if (jaa.label.startsWith("Consensus for "))
2487 sg.setConsensus(jaa);
2489 // match up and try to set group autocalc alignment row for this
2491 if (jaa.label.startsWith("Conservation for "))
2493 sg.setConservationRow(jaa);
2504 // ///////////////////////////////
2507 // If we just load in the same jar file again, the sequenceSetId
2508 // will be the same, and we end up with multiple references
2509 // to the same sequenceSet. We must modify this id on load
2510 // so that each load of the file gives a unique id
2511 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
2512 String viewId = (view.getId() == null ? null : view.getId()
2514 AlignFrame af = null;
2515 AlignViewport av = null;
2516 // now check to see if we really need to create a new viewport.
2517 if (multipleView && viewportsAdded.size() == 0)
2519 // We recovered an alignment for which a viewport already exists.
2520 // TODO: fix up any settings necessary for overlaying stored state onto
2521 // state recovered from another document. (may not be necessary).
2522 // we may need a binding from a viewport in memory to one recovered from
2524 // and then recover its containing af to allow the settings to be applied.
2525 // TODO: fix for vamsas demo
2527 .println("About to recover a viewport for existing alignment: Sequence set ID is "
2529 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
2530 if (seqsetobj != null)
2532 if (seqsetobj instanceof String)
2534 uniqueSeqSetId = (String) seqsetobj;
2536 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
2542 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
2547 AlignmentPanel ap = null;
2548 boolean isnewview = true;
2551 // Check to see if this alignment already has a view id == viewId
2552 jalview.gui.AlignmentPanel views[] = Desktop
2553 .getAlignmentPanels(uniqueSeqSetId);
2554 if (views != null && views.length > 0)
2556 for (int v = 0; v < views.length; v++)
2558 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
2560 // recover the existing alignpanel, alignframe, viewport
2561 af = views[v].alignFrame;
2564 // TODO: could even skip resetting view settings if we don't want to
2565 // change the local settings from other jalview processes
2574 af = loadViewport(file, JSEQ, hiddenSeqs, al, jms, view,
2575 uniqueSeqSetId, viewId, autoAlan);
2580 // /////////////////////////////////////
2581 if (loadTreesAndStructures && jms.getTreeCount() > 0)
2585 for (int t = 0; t < jms.getTreeCount(); t++)
2588 Tree tree = jms.getTree(t);
2590 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
2593 tp = af.ShowNewickTree(
2594 new jalview.io.NewickFile(tree.getNewick()),
2595 tree.getTitle(), tree.getWidth(), tree.getHeight(),
2596 tree.getXpos(), tree.getYpos());
2597 if (tree.getId() != null)
2599 // perhaps bind the tree id to something ?
2604 // update local tree attributes ?
2605 // TODO: should check if tp has been manipulated by user - if so its
2606 // settings shouldn't be modified
2607 tp.setTitle(tree.getTitle());
2608 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
2609 .getWidth(), tree.getHeight()));
2610 tp.av = av; // af.viewport; // TODO: verify 'associate with all
2613 tp.treeCanvas.av = av; // af.viewport;
2614 tp.treeCanvas.ap = ap; // af.alignPanel;
2619 warn("There was a problem recovering stored Newick tree: \n"
2620 + tree.getNewick());
2624 tp.fitToWindow.setState(tree.getFitToWindow());
2625 tp.fitToWindow_actionPerformed(null);
2627 if (tree.getFontName() != null)
2629 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
2630 .getFontStyle(), tree.getFontSize()));
2634 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
2635 .getFontStyle(), tree.getFontSize()));
2638 tp.showPlaceholders(tree.getMarkUnlinked());
2639 tp.showBootstrap(tree.getShowBootstrap());
2640 tp.showDistances(tree.getShowDistances());
2642 tp.treeCanvas.threshold = tree.getThreshold();
2644 if (tree.getCurrentTree())
2646 af.viewport.setCurrentTree(tp.getTree());
2650 } catch (Exception ex)
2652 ex.printStackTrace();
2656 // //LOAD STRUCTURES
2657 if (loadTreesAndStructures)
2659 // run through all PDB ids on the alignment, and collect mappings between
2660 // jmol view ids and all sequences referring to it
2661 Hashtable<String, Object[]> jmolViewIds = new Hashtable();
2663 for (int i = 0; i < JSEQ.length; i++)
2665 if (JSEQ[i].getPdbidsCount() > 0)
2667 Pdbids[] ids = JSEQ[i].getPdbids();
2668 for (int p = 0; p < ids.length; p++)
2670 for (int s = 0; s < ids[p].getStructureStateCount(); s++)
2672 // check to see if we haven't already created this structure view
2673 String sviewid = (ids[p].getStructureState(s).getViewId() == null) ? null
2674 : ids[p].getStructureState(s).getViewId()
2676 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
2677 // Originally : ids[p].getFile()
2678 // : TODO: verify external PDB file recovery still works in normal
2679 // jalview project load
2680 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
2681 jpdb.setId(ids[p].getId());
2683 int x = ids[p].getStructureState(s).getXpos();
2684 int y = ids[p].getStructureState(s).getYpos();
2685 int width = ids[p].getStructureState(s).getWidth();
2686 int height = ids[p].getStructureState(s).getHeight();
2688 // Probably don't need to do this anymore...
2689 // Desktop.desktop.getComponentAt(x, y);
2690 // TODO: NOW: check that this recovers the PDB file correctly.
2691 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
2692 jalview.datamodel.SequenceI seq = (jalview.datamodel.SequenceI) seqRefIds
2693 .get(JSEQ[i].getId() + "");
2694 if (sviewid == null)
2696 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
2699 if (!jmolViewIds.containsKey(sviewid))
2701 jmolViewIds.put(sviewid, new Object[]
2703 { x, y, width, height }, "",
2704 new Hashtable<String, Object[]>(), new boolean[]
2705 { false, false, true } });
2706 // Legacy pre-2.7 conversion JAL-823 :
2707 // do not assume any view has to be linked for colour by
2711 // assemble String[] { pdb files }, String[] { id for each
2712 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
2713 // seqs_file 2}, boolean[] {
2714 // linkAlignPanel,superposeWithAlignpanel}} from hash
2715 Object[] jmoldat = jmolViewIds.get(sviewid);
2716 ((boolean[]) jmoldat[3])[0] |= ids[p].getStructureState(s)
2717 .hasAlignwithAlignPanel() ? ids[p].getStructureState(
2718 s).getAlignwithAlignPanel() : false;
2719 // never colour by linked panel if not specified
2720 ((boolean[]) jmoldat[3])[1] |= ids[p].getStructureState(s)
2721 .hasColourwithAlignPanel() ? ids[p]
2722 .getStructureState(s).getColourwithAlignPanel()
2724 // default for pre-2.7 projects is that Jmol colouring is enabled
2725 ((boolean[]) jmoldat[3])[2] &= ids[p].getStructureState(s)
2726 .hasColourByJmol() ? ids[p].getStructureState(s)
2727 .getColourByJmol() : true;
2729 if (((String) jmoldat[1]).length() < ids[p]
2730 .getStructureState(s).getContent().length())
2733 jmoldat[1] = ids[p].getStructureState(s).getContent();
2736 if (ids[p].getFile() != null)
2738 File mapkey=new File(ids[p].getFile());
2739 Object[] seqstrmaps = (Object[]) ((Hashtable) jmoldat[2])
2741 if (seqstrmaps == null)
2743 ((Hashtable) jmoldat[2]).put(
2745 seqstrmaps = new Object[]
2746 { pdbFile, ids[p].getId(), new Vector(),
2749 if (!((Vector) seqstrmaps[2]).contains(seq))
2751 ((Vector) seqstrmaps[2]).addElement(seq);
2752 // ((Vector)seqstrmaps[3]).addElement(n) :
2753 // in principle, chains
2754 // should be stored here : do we need to
2755 // TODO: store and recover seq/pdb_id :
2761 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");
2770 // Instantiate the associated Jmol views
2771 for (Entry<String, Object[]> entry : jmolViewIds.entrySet())
2773 String sviewid = entry.getKey();
2774 Object[] svattrib = entry.getValue();
2775 int[] geom = (int[]) svattrib[0];
2776 String state = (String) svattrib[1];
2777 Hashtable<File, Object[]> oldFiles = (Hashtable<File, Object[]>) svattrib[2];
2778 final boolean useinJmolsuperpos = ((boolean[]) svattrib[3])[0], usetoColourbyseq = ((boolean[]) svattrib[3])[1], jmolColouring = ((boolean[]) svattrib[3])[2];
2779 int x = geom[0], y = geom[1], width = geom[2], height = geom[3];
2780 // collate the pdbfile -> sequence mappings from this view
2781 Vector<String> pdbfilenames = new Vector<String>();
2782 Vector<SequenceI[]> seqmaps = new Vector<SequenceI[]>();
2783 Vector<String> pdbids = new Vector<String>();
2785 // Search to see if we've already created this Jmol view
2786 AppJmol comp = null;
2787 JInternalFrame[] frames = null;
2792 frames = Desktop.desktop.getAllFrames();
2793 } catch (ArrayIndexOutOfBoundsException e)
2795 // occasional No such child exceptions are thrown here...
2800 } catch (Exception f)
2805 } while (frames == null);
2806 // search for any Jmol windows already open from other
2807 // alignment views that exactly match the stored structure state
2808 for (int f = 0; comp == null && f < frames.length; f++)
2810 if (frames[f] instanceof AppJmol)
2813 && ((AppJmol) frames[f]).getViewId().equals(sviewid))
2815 // post jalview 2.4 schema includes structure view id
2816 comp = (AppJmol) frames[f];
2818 else if (frames[f].getX() == x && frames[f].getY() == y
2819 && frames[f].getHeight() == height
2820 && frames[f].getWidth() == width)
2822 comp = (AppJmol) frames[f];
2829 // create a new Jmol window.
2830 // First parse the Jmol state to translate filenames loaded into the
2831 // view, and record the order in which files are shown in the Jmol
2832 // view, so we can add the sequence mappings in same order.
2833 StringBuffer newFileLoc = null;
2834 int cp = 0, ncp, ecp;
2835 while ((ncp = state.indexOf("load ", cp)) > -1)
2837 if (newFileLoc == null)
2839 newFileLoc = new StringBuffer();
2842 // look for next filename in load statement
2843 newFileLoc.append(state.substring(cp,
2844 ncp = (state.indexOf("\"", ncp + 1) + 1)));
2845 String oldfilenam = state.substring(ncp,
2846 ecp = state.indexOf("\"", ncp));
2847 // recover the new mapping data for this old filename
2848 // have to normalize filename - since Jmol and jalview do filename
2849 // translation differently.
2850 Object[] filedat = oldFiles.get(new File(oldfilenam));
2851 newFileLoc.append(Platform.escapeString((String) filedat[0]));
2852 pdbfilenames.addElement((String) filedat[0]);
2853 pdbids.addElement((String) filedat[1]);
2854 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
2855 .toArray(new SequenceI[0]));
2856 newFileLoc.append("\"");
2857 cp = ecp + 1; // advance beyond last \" and set cursor so we can
2858 // look for next file statement.
2859 } while ((ncp=state.indexOf("/*file*/",cp))>-1);
2863 // just append rest of state
2864 newFileLoc.append(state.substring(cp));
2869 .print("Ignoring incomplete Jmol state for PDB ids: ");
2870 newFileLoc = new StringBuffer(state);
2871 newFileLoc.append("; load append ");
2872 for (File id : oldFiles.keySet())
2874 // add this and any other pdb files that should be present in
2876 Object[] filedat = oldFiles.get(id);
2878 newFileLoc.append(((String) filedat[0]));
2879 pdbfilenames.addElement((String) filedat[0]);
2880 pdbids.addElement((String) filedat[1]);
2881 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
2882 .toArray(new SequenceI[0]));
2883 newFileLoc.append(" \"");
2884 newFileLoc.append((String) filedat[0]);
2885 newFileLoc.append("\"");
2888 newFileLoc.append(";");
2891 if (newFileLoc != null)
2893 int histbug = newFileLoc.indexOf("history = ");
2895 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";",
2897 String val = (diff == -1) ? null : newFileLoc.substring(
2899 if (val != null && val.length() >= 4)
2901 if (val.contains("e"))
2903 if (val.trim().equals("true"))
2911 newFileLoc.replace(histbug, diff, val);
2914 // TODO: assemble String[] { pdb files }, String[] { id for each
2915 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
2916 // seqs_file 2}} from hash
2917 final String[] pdbf = pdbfilenames
2918 .toArray(new String[pdbfilenames.size()]), id = pdbids
2919 .toArray(new String[pdbids.size()]);
2920 final SequenceI[][] sq = seqmaps
2921 .toArray(new SequenceI[seqmaps.size()][]);
2922 final String fileloc = newFileLoc.toString(), vid = sviewid;
2923 final AlignFrame alf = af;
2924 final java.awt.Rectangle rect = new java.awt.Rectangle(x, y,
2928 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
2933 AppJmol sview = null;
2936 sview = new AppJmol(pdbf, id, sq, alf.alignPanel,
2937 useinJmolsuperpos, usetoColourbyseq,
2938 jmolColouring, fileloc, rect, vid);
2939 } catch (OutOfMemoryError ex)
2941 new OOMWarning("restoring structure view for PDB id "
2942 + id, (OutOfMemoryError) ex.getCause());
2943 if (sview != null && sview.isVisible())
2945 sview.closeViewer();
2946 sview.setVisible(false);
2952 } catch (InvocationTargetException ex)
2954 warn("Unexpected error when opening Jmol view.", ex);
2956 } catch (InterruptedException e)
2958 // e.printStackTrace();
2964 // if (comp != null)
2966 // NOTE: if the jalview project is part of a shared session then
2967 // view synchronization should/could be done here.
2969 // add mapping for sequences in this view to an already open Jmol
2971 for (File id : oldFiles.keySet())
2973 // add this and any other pdb files that should be present in the
2975 Object[] filedat = oldFiles.get(id);
2976 String pdbFile = (String) filedat[0];
2977 SequenceI[] seq = ((Vector<SequenceI>) filedat[2])
2978 .toArray(new SequenceI[0]);
2979 comp.jmb.ssm.setMapping(seq, null, pdbFile,
2980 jalview.io.AppletFormatAdapter.FILE);
2981 comp.jmb.addSequenceForStructFile(pdbFile, seq);
2983 // and add the AlignmentPanel's reference to the Jmol view
2984 comp.addAlignmentPanel(ap);
2985 if (useinJmolsuperpos)
2987 comp.useAlignmentPanelForSuperposition(ap);
2991 comp.excludeAlignmentPanelForSuperposition(ap);
2993 if (usetoColourbyseq)
2995 comp.useAlignmentPanelForColourbyseq(ap,
3000 comp.excludeAlignmentPanelForColourbyseq(ap);
3006 // and finally return.
3010 AlignFrame loadViewport(String file, JSeq[] JSEQ, Vector hiddenSeqs,
3011 Alignment al, JalviewModelSequence jms, Viewport view,
3012 String uniqueSeqSetId, String viewId,
3013 ArrayList<JvAnnotRow> autoAlan)
3015 AlignFrame af = null;
3016 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
3017 uniqueSeqSetId, viewId);
3019 af.setFileName(file, "Jalview");
3021 for (int i = 0; i < JSEQ.length; i++)
3023 af.viewport.setSequenceColour(af.viewport.getAlignment().getSequenceAt(i),
3024 new java.awt.Color(JSEQ[i].getColour()));
3027 af.viewport.gatherViewsHere = view.getGatheredViews();
3029 if (view.getSequenceSetId() != null)
3031 jalview.gui.AlignViewport av = (jalview.gui.AlignViewport) viewportsAdded
3032 .get(uniqueSeqSetId);
3034 af.viewport.setSequenceSetId(uniqueSeqSetId);
3037 // propagate shared settings to this new view
3038 af.viewport.historyList = av.historyList;
3039 af.viewport.redoList = av.redoList;
3043 viewportsAdded.put(uniqueSeqSetId, af.viewport);
3045 // TODO: check if this method can be called repeatedly without
3046 // side-effects if alignpanel already registered.
3047 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
3049 // apply Hidden regions to view.
3050 if (hiddenSeqs != null)
3052 for (int s = 0; s < JSEQ.length; s++)
3054 jalview.datamodel.SequenceGroup hidden = new jalview.datamodel.SequenceGroup();
3056 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
3059 al.getSequenceAt(JSEQ[s].getHiddenSequences(r)), false);
3061 af.viewport.hideRepSequences(al.getSequenceAt(s), hidden);
3064 jalview.datamodel.SequenceI[] hseqs = new jalview.datamodel.SequenceI[hiddenSeqs
3067 for (int s = 0; s < hiddenSeqs.size(); s++)
3069 hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s);
3072 af.viewport.hideSequence(hseqs);
3075 // recover view properties and display parameters
3076 if (view.getViewName() != null)
3078 af.viewport.viewName = view.getViewName();
3079 af.setInitialTabVisible();
3081 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
3084 af.viewport.setShowAnnotation(view.getShowAnnotation());
3085 af.viewport.setAbovePIDThreshold(view.getPidSelected());
3087 af.viewport.setColourText(view.getShowColourText());
3089 af.viewport.setConservationSelected(view.getConservationSelected());
3090 af.viewport.setShowJVSuffix(view.getShowFullId());
3091 af.viewport.rightAlignIds = view.getRightAlignIds();
3092 af.viewport.setFont(new java.awt.Font(view.getFontName(), view
3093 .getFontStyle(), view.getFontSize()));
3094 af.alignPanel.fontChanged();
3095 af.viewport.setRenderGaps(view.getRenderGaps());
3096 af.viewport.setWrapAlignment(view.getWrapAlignment());
3097 af.alignPanel.setWrapAlignment(view.getWrapAlignment());
3098 af.viewport.setShowAnnotation(view.getShowAnnotation());
3099 af.alignPanel.setAnnotationVisible(view.getShowAnnotation());
3101 af.viewport.setShowBoxes(view.getShowBoxes());
3103 af.viewport.setShowText(view.getShowText());
3105 af.viewport.textColour = new java.awt.Color(view.getTextCol1());
3106 af.viewport.textColour2 = new java.awt.Color(view.getTextCol2());
3107 af.viewport.thresholdTextColour = view.getTextColThreshold();
3108 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
3109 .isShowUnconserved() : false);
3110 af.viewport.setStartRes(view.getStartRes());
3111 af.viewport.setStartSeq(view.getStartSeq());
3113 ColourSchemeI cs = null;
3114 // apply colourschemes
3115 if (view.getBgColour() != null)
3117 if (view.getBgColour().startsWith("ucs"))
3119 cs = GetUserColourScheme(jms, view.getBgColour());
3121 else if (view.getBgColour().startsWith("Annotation"))
3123 // int find annotation
3124 if (af.viewport.getAlignment().getAlignmentAnnotation() != null)
3126 for (int i = 0; i < af.viewport.getAlignment()
3127 .getAlignmentAnnotation().length; i++)
3129 if (af.viewport.getAlignment().getAlignmentAnnotation()[i].label
3130 .equals(view.getAnnotationColours().getAnnotation()))
3132 if (af.viewport.getAlignment().getAlignmentAnnotation()[i]
3133 .getThreshold() == null)
3135 af.viewport.getAlignment().getAlignmentAnnotation()[i]
3136 .setThreshold(new jalview.datamodel.GraphLine(view
3137 .getAnnotationColours().getThreshold(),
3138 "Threshold", java.awt.Color.black)
3143 if (view.getAnnotationColours().getColourScheme()
3146 cs = new AnnotationColourGradient(
3147 af.viewport.getAlignment().getAlignmentAnnotation()[i],
3148 new java.awt.Color(view.getAnnotationColours()
3149 .getMinColour()), new java.awt.Color(view
3150 .getAnnotationColours().getMaxColour()),
3151 view.getAnnotationColours().getAboveThreshold());
3153 else if (view.getAnnotationColours().getColourScheme()
3156 cs = new AnnotationColourGradient(
3157 af.viewport.getAlignment().getAlignmentAnnotation()[i],
3158 GetUserColourScheme(jms, view
3159 .getAnnotationColours().getColourScheme()),
3160 view.getAnnotationColours().getAboveThreshold());
3164 cs = new AnnotationColourGradient(
3165 af.viewport.getAlignment().getAlignmentAnnotation()[i],
3166 ColourSchemeProperty.getColour(al, view
3167 .getAnnotationColours().getColourScheme()),
3168 view.getAnnotationColours().getAboveThreshold());
3171 // Also use these settings for all the groups
3172 if (al.getGroups() != null)
3174 for (int g = 0; g < al.getGroups().size(); g++)
3176 jalview.datamodel.SequenceGroup sg = al
3177 .getGroups().get(g);
3186 * (view.getAnnotationColours().getColourScheme().equals("None"
3187 * )) { sg.cs = new AnnotationColourGradient(
3188 * af.viewport.getAlignment().getAlignmentAnnotation()[i], new
3189 * java.awt.Color(view.getAnnotationColours().
3190 * getMinColour()), new
3191 * java.awt.Color(view.getAnnotationColours().
3193 * view.getAnnotationColours().getAboveThreshold()); } else
3196 sg.cs = new AnnotationColourGradient(
3197 af.viewport.getAlignment().getAlignmentAnnotation()[i],
3198 sg.cs, view.getAnnotationColours()
3199 .getAboveThreshold());
3213 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
3218 cs.setThreshold(view.getPidThreshold(), true);
3219 cs.setConsensus(af.viewport.getSequenceConsensusHash());
3223 af.viewport.setGlobalColourScheme(cs);
3224 af.viewport.setColourAppliesToAllGroups(false);
3226 if (view.getConservationSelected() && cs != null)
3228 cs.setConservationInc(view.getConsThreshold());
3231 af.changeColour(cs);
3233 af.viewport.setColourAppliesToAllGroups(true);
3235 if (view.getShowSequenceFeatures())
3237 af.viewport.showSequenceFeatures = true;
3239 if (view.hasCentreColumnLabels())
3241 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
3243 if (view.hasIgnoreGapsinConsensus())
3245 af.viewport.setIgnoreGapsConsensus(view
3246 .getIgnoreGapsinConsensus(), null);
3248 if (view.hasFollowHighlight())
3250 af.viewport.followHighlight = view.getFollowHighlight();
3252 if (view.hasFollowSelection())
3254 af.viewport.followSelection = view.getFollowSelection();
3256 if (view.hasShowConsensusHistogram())
3258 af.viewport.setShowConsensusHistogram(view
3259 .getShowConsensusHistogram());
3263 af.viewport.setShowConsensusHistogram(true);
3265 if (view.hasShowSequenceLogo())
3267 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
3271 af.viewport.setShowSequenceLogo(false);
3273 if (view.hasShowDbRefTooltip())
3275 af.viewport.setShowDbRefs(view.getShowDbRefTooltip());
3277 if (view.hasShowNPfeatureTooltip())
3279 af.viewport.setShowNpFeats(view.hasShowNPfeatureTooltip());
3281 if (view.hasShowGroupConsensus())
3283 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
3287 af.viewport.setShowGroupConsensus(false);
3289 if (view.hasShowGroupConservation())
3291 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
3295 af.viewport.setShowGroupConservation(false);
3298 // recover featre settings
3299 if (jms.getFeatureSettings() != null)
3301 af.viewport.featuresDisplayed = new Hashtable();
3302 String[] renderOrder = new String[jms.getFeatureSettings()
3303 .getSettingCount()];
3304 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
3306 Setting setting = jms.getFeatureSettings().getSetting(fs);
3307 if (setting.hasMincolour())
3309 GraduatedColor gc = setting.hasMin() ? new GraduatedColor(
3310 new java.awt.Color(setting.getMincolour()),
3311 new java.awt.Color(setting.getColour()),
3312 setting.getMin(), setting.getMax()) : new GraduatedColor(
3313 new java.awt.Color(setting.getMincolour()),
3314 new java.awt.Color(setting.getColour()), 0, 1);
3315 if (setting.hasThreshold())
3317 gc.setThresh(setting.getThreshold());
3318 gc.setThreshType(setting.getThreshstate());
3320 gc.setAutoScaled(true); // default
3321 if (setting.hasAutoScale())
3323 gc.setAutoScaled(setting.getAutoScale());
3325 if (setting.hasColourByLabel())
3327 gc.setColourByLabel(setting.getColourByLabel());
3329 // and put in the feature colour table.
3330 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3331 setting.getType(), gc);
3335 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3337 new java.awt.Color(setting.getColour()));
3339 renderOrder[fs] = setting.getType();
3340 if (setting.hasOrder())
3341 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3342 setting.getType(), setting.getOrder());
3344 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3346 fs / jms.getFeatureSettings().getSettingCount());
3347 if (setting.getDisplay())
3349 af.viewport.featuresDisplayed.put(setting.getType(), new Integer(
3350 setting.getColour()));
3353 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().renderOrder = renderOrder;
3355 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().featureGroups = fgtable = new Hashtable();
3356 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
3358 Group grp = jms.getFeatureSettings().getGroup(gs);
3359 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
3363 if (view.getHiddenColumnsCount() > 0)
3365 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
3367 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
3368 .getHiddenColumns(c).getEnd() // +1
3372 if (view.getCalcIdParam() != null)
3374 for (CalcIdParam calcIdParam : view.getCalcIdParam())
3376 if (calcIdParam != null)
3378 if (recoverCalcIdParam(calcIdParam, af.viewport))
3383 warn("Couldn't recover parameters for "
3384 + calcIdParam.getCalcId());
3389 af.setMenusFromViewport(af.viewport);
3390 // TODO: we don't need to do this if the viewport is aready visible.
3391 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
3393 af.alignPanel.updateAnnotation(false); // recompute any autoannotation
3394 reorderAutoannotation(af, al, autoAlan);
3398 private void reorderAutoannotation(AlignFrame af, Alignment al,
3399 ArrayList<JvAnnotRow> autoAlan)
3401 // copy over visualization settings for autocalculated annotation in the
3403 if (al.getAlignmentAnnotation() != null)
3406 * Kludge for magic autoannotation names (see JAL-811)
3408 String[] magicNames = new String[]
3409 { "Consensus", "Quality", "Conservation" };
3410 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
3411 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
3412 for (String nm : magicNames)
3414 visan.put(nm, nullAnnot);
3416 for (JvAnnotRow auan : autoAlan)
3418 visan.put(auan.template.label+(auan.template.getCalcId()==null ? "" : "\t"+auan.template.getCalcId()), auan);
3420 int hSize = al.getAlignmentAnnotation().length;
3421 ArrayList<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
3422 // work through any autoCalculated annotation already on the view
3423 // removing it if it should be placed in a different location on the
3424 // annotation panel.
3425 List<String> remains=new ArrayList(visan.keySet());
3426 for (int h = 0; h < hSize; h++)
3428 jalview.datamodel.AlignmentAnnotation jalan = al
3429 .getAlignmentAnnotation()[h];
3430 if (jalan.autoCalculated)
3433 JvAnnotRow valan = visan.get(k=jalan.label);
3434 if (jalan.getCalcId()!=null)
3436 valan = visan.get(k=jalan.label+ "\t"+jalan.getCalcId());
3441 // delete the auto calculated row from the alignment
3442 al.deleteAnnotation(jalan, false);
3446 if (valan != nullAnnot)
3448 if (jalan != valan.template)
3450 // newly created autoannotation row instance
3451 // so keep a reference to the visible annotation row
3452 // and copy over all relevant attributes
3453 if (valan.template.graphHeight >= 0)
3456 jalan.graphHeight = valan.template.graphHeight;
3458 jalan.visible = valan.template.visible;
3460 reorder.add(new JvAnnotRow(valan.order, jalan));
3465 // Add any (possibly stale) autocalculated rows that were not appended to the view during construction
3466 for (String other:remains)
3468 JvAnnotRow othera=visan.get(other);
3469 if (othera!=nullAnnot && othera.template.getCalcId()!=null && othera.template.getCalcId().length()>0)
3471 reorder.add(othera);
3474 // now put the automatic annotation in its correct place
3475 int s = 0, srt[] = new int[reorder.size()];
3476 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
3477 for (JvAnnotRow jvar : reorder)
3480 srt[s++] = jvar.order;
3483 jalview.util.QuickSort.sort(srt, rws);
3484 // and re-insert the annotation at its correct position
3485 for (JvAnnotRow jvar : rws)
3487 al.addAnnotation(jvar.template, jvar.order);
3489 af.alignPanel.adjustAnnotationHeight();
3493 Hashtable skipList = null;
3496 * TODO remove this method
3499 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
3500 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
3501 * throw new Error("Implementation Error. No skipList defined for this
3502 * Jalview2XML instance."); } return (AlignFrame)
3503 * skipList.get(view.getSequenceSetId()); }
3507 * Check if the Jalview view contained in object should be skipped or not.
3510 * @return true if view's sequenceSetId is a key in skipList
3512 private boolean skipViewport(JalviewModel object)
3514 if (skipList == null)
3519 if (skipList.containsKey(id = object.getJalviewModelSequence()
3520 .getViewport()[0].getSequenceSetId()))
3522 if (Cache.log != null && Cache.log.isDebugEnabled())
3524 Cache.log.debug("Skipping seuqence set id " + id);
3531 public void AddToSkipList(AlignFrame af)
3533 if (skipList == null)
3535 skipList = new Hashtable();
3537 skipList.put(af.getViewport().getSequenceSetId(), af);
3540 public void clearSkipList()
3542 if (skipList != null)
3549 private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al)
3551 jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId());
3552 Vector dseqs = null;
3555 // create a list of new dataset sequences
3556 dseqs = new Vector();
3558 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
3560 Sequence vamsasSeq = vamsasSet.getSequence(i);
3561 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs);
3563 // create a new dataset
3566 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
3567 dseqs.copyInto(dsseqs);
3568 ds = new jalview.datamodel.Alignment(dsseqs);
3569 debug("Created new dataset " + vamsasSet.getDatasetId()
3570 + " for alignment " + System.identityHashCode(al));
3571 addDatasetRef(vamsasSet.getDatasetId(), ds);
3573 // set the dataset for the newly imported alignment.
3574 if (al.getDataset() == null)
3583 * sequence definition to create/merge dataset sequence for
3587 * vector to add new dataset sequence to
3589 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
3590 AlignmentI ds, Vector dseqs)
3592 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
3594 jalview.datamodel.Sequence sq = (jalview.datamodel.Sequence) seqRefIds
3595 .get(vamsasSeq.getId());
3596 jalview.datamodel.SequenceI dsq = null;
3597 if (sq != null && sq.getDatasetSequence() != null)
3599 dsq = sq.getDatasetSequence();
3602 String sqid = vamsasSeq.getDsseqid();
3605 // need to create or add a new dataset sequence reference to this sequence
3608 dsq = (jalview.datamodel.SequenceI) seqRefIds.get(sqid);
3613 // make a new dataset sequence
3614 dsq = sq.createDatasetSequence();
3617 // make up a new dataset reference for this sequence
3618 sqid = seqHash(dsq);
3620 dsq.setVamsasId(uniqueSetSuffix + sqid);
3621 seqRefIds.put(sqid, dsq);
3626 dseqs.addElement(dsq);
3631 ds.addSequence(dsq);
3637 { // make this dataset sequence sq's dataset sequence
3638 sq.setDatasetSequence(dsq);
3642 // TODO: refactor this as a merge dataset sequence function
3643 // now check that sq (the dataset sequence) sequence really is the union of
3644 // all references to it
3645 // boolean pre = sq.getStart() < dsq.getStart();
3646 // boolean post = sq.getEnd() > dsq.getEnd();
3650 StringBuffer sb = new StringBuffer();
3651 String newres = jalview.analysis.AlignSeq.extractGaps(
3652 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
3653 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
3654 && newres.length() > dsq.getLength())
3656 // Update with the longer sequence.
3660 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
3661 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
3662 * sb.append(newres.substring(newres.length() - sq.getEnd() -
3663 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
3665 dsq.setSequence(sb.toString());
3667 // TODO: merges will never happen if we 'know' we have the real dataset
3668 // sequence - this should be detected when id==dssid
3669 System.err.println("DEBUG Notice: Merged dataset sequence"); // ("
3670 // + (pre ? "prepended" : "") + " "
3671 // + (post ? "appended" : ""));
3676 java.util.Hashtable datasetIds = null;
3678 java.util.IdentityHashMap dataset2Ids = null;
3680 private Alignment getDatasetFor(String datasetId)
3682 if (datasetIds == null)
3684 datasetIds = new Hashtable();
3687 if (datasetIds.containsKey(datasetId))
3689 return (Alignment) datasetIds.get(datasetId);
3694 private void addDatasetRef(String datasetId, Alignment dataset)
3696 if (datasetIds == null)
3698 datasetIds = new Hashtable();
3700 datasetIds.put(datasetId, dataset);
3704 * make a new dataset ID for this jalview dataset alignment
3709 private String getDatasetIdRef(jalview.datamodel.Alignment dataset)
3711 if (dataset.getDataset() != null)
3713 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
3715 String datasetId = makeHashCode(dataset, null);
3716 if (datasetId == null)
3718 // make a new datasetId and record it
3719 if (dataset2Ids == null)
3721 dataset2Ids = new IdentityHashMap();
3725 datasetId = (String) dataset2Ids.get(dataset);
3727 if (datasetId == null)
3729 datasetId = "ds" + dataset2Ids.size() + 1;
3730 dataset2Ids.put(dataset, datasetId);
3736 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
3738 for (int d = 0; d < sequence.getDBRefCount(); d++)
3740 DBRef dr = sequence.getDBRef(d);
3741 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
3742 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
3743 .getVersion(), sequence.getDBRef(d).getAccessionId());
3744 if (dr.getMapping() != null)
3746 entry.setMap(addMapping(dr.getMapping()));
3748 datasetSequence.addDBRef(entry);
3752 private jalview.datamodel.Mapping addMapping(Mapping m)
3754 SequenceI dsto = null;
3755 // Mapping m = dr.getMapping();
3756 int fr[] = new int[m.getMapListFromCount() * 2];
3757 Enumeration f = m.enumerateMapListFrom();
3758 for (int _i = 0; f.hasMoreElements(); _i += 2)
3760 MapListFrom mf = (MapListFrom) f.nextElement();
3761 fr[_i] = mf.getStart();
3762 fr[_i + 1] = mf.getEnd();
3764 int fto[] = new int[m.getMapListToCount() * 2];
3765 f = m.enumerateMapListTo();
3766 for (int _i = 0; f.hasMoreElements(); _i += 2)
3768 MapListTo mf = (MapListTo) f.nextElement();
3769 fto[_i] = mf.getStart();
3770 fto[_i + 1] = mf.getEnd();
3772 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
3773 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
3774 if (m.getMappingChoice() != null)
3776 MappingChoice mc = m.getMappingChoice();
3777 if (mc.getDseqFor() != null)
3779 String dsfor = "" + mc.getDseqFor();
3780 if (seqRefIds.containsKey(dsfor))
3785 jmap.setTo((SequenceI) seqRefIds.get(dsfor));
3789 frefedSequence.add(new Object[]
3796 * local sequence definition
3798 Sequence ms = mc.getSequence();
3799 jalview.datamodel.Sequence djs = null;
3800 String sqid = ms.getDsseqid();
3801 if (sqid != null && sqid.length() > 0)
3804 * recover dataset sequence
3806 djs = (jalview.datamodel.Sequence) seqRefIds.get(sqid);
3811 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
3812 sqid = ((Object) ms).toString(); // make up a new hascode for
3813 // undefined dataset sequence hash
3814 // (unlikely to happen)
3820 * make a new dataset sequence and add it to refIds hash
3822 djs = new jalview.datamodel.Sequence(ms.getName(),
3824 djs.setStart(jmap.getMap().getToLowest());
3825 djs.setEnd(jmap.getMap().getToHighest());
3826 djs.setVamsasId(uniqueSetSuffix + sqid);
3828 seqRefIds.put(sqid, djs);
3831 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
3840 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
3841 boolean keepSeqRefs)
3844 jalview.schemabinding.version2.JalviewModel jm = SaveState(ap, null,
3850 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
3854 uniqueSetSuffix = "";
3855 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
3860 if (this.frefedSequence == null)
3862 frefedSequence = new Vector();
3865 viewportsAdded = new Hashtable();
3867 AlignFrame af = LoadFromObject(jm, null, false, null);
3868 af.alignPanels.clear();
3869 af.closeMenuItem_actionPerformed(true);
3872 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
3873 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
3874 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
3875 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
3876 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
3879 return af.alignPanel;
3883 * flag indicating if hashtables should be cleared on finalization TODO this
3884 * flag may not be necessary
3886 private final boolean _cleartables = true;
3888 private Hashtable jvids2vobj;
3893 * @see java.lang.Object#finalize()
3896 protected void finalize() throws Throwable
3898 // really make sure we have no buried refs left.
3903 this.seqRefIds = null;
3904 this.seqsToIds = null;
3908 private void warn(String msg)
3913 private void warn(String msg, Exception e)
3915 if (Cache.log != null)
3919 Cache.log.warn(msg, e);
3923 Cache.log.warn(msg);
3928 System.err.println("Warning: " + msg);
3931 e.printStackTrace();
3936 private void debug(String string)
3938 debug(string, null);
3941 private void debug(String msg, Exception e)
3943 if (Cache.log != null)
3947 Cache.log.debug(msg, e);
3951 Cache.log.debug(msg);
3956 System.err.println("Warning: " + msg);
3959 e.printStackTrace();
3965 * set the object to ID mapping tables used to write/recover objects and XML
3966 * ID strings for the jalview project. If external tables are provided then
3967 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
3968 * object goes out of scope. - also populates the datasetIds hashtable with
3969 * alignment objects containing dataset sequences
3972 * Map from ID strings to jalview datamodel
3974 * Map from jalview datamodel to ID strings
3978 public void setObjectMappingTables(Hashtable vobj2jv,
3979 IdentityHashMap jv2vobj)
3981 this.jv2vobj = jv2vobj;
3982 this.vobj2jv = vobj2jv;
3983 Iterator ds = jv2vobj.keySet().iterator();
3985 while (ds.hasNext())
3987 Object jvobj = ds.next();
3988 id = jv2vobj.get(jvobj).toString();
3989 if (jvobj instanceof jalview.datamodel.Alignment)
3991 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
3993 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
3996 else if (jvobj instanceof jalview.datamodel.Sequence)
3998 // register sequence object so the XML parser can recover it.
3999 if (seqRefIds == null)
4001 seqRefIds = new Hashtable();
4003 if (seqsToIds == null)
4005 seqsToIds = new IdentityHashMap();
4007 seqRefIds.put(jv2vobj.get(jvobj).toString(), jvobj);
4008 seqsToIds.put(jvobj, id);
4010 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
4012 if (annotationIds == null)
4014 annotationIds = new Hashtable();
4017 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvobj);
4018 jalview.datamodel.AlignmentAnnotation jvann = (jalview.datamodel.AlignmentAnnotation) jvobj;
4019 if (jvann.annotationId == null)
4021 jvann.annotationId = anid;
4023 if (!jvann.annotationId.equals(anid))
4025 // TODO verify that this is the correct behaviour
4026 this.warn("Overriding Annotation ID for " + anid
4027 + " from different id : " + jvann.annotationId);
4028 jvann.annotationId = anid;
4031 else if (jvobj instanceof String)
4033 if (jvids2vobj == null)
4035 jvids2vobj = new Hashtable();
4036 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
4040 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
4045 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
4046 * objects created from the project archive. If string is null (default for
4047 * construction) then suffix will be set automatically.
4051 public void setUniqueSetSuffix(String string)
4053 uniqueSetSuffix = string;
4058 * uses skipList2 as the skipList for skipping views on sequence sets
4059 * associated with keys in the skipList
4063 public void setSkipList(Hashtable skipList2)
4065 skipList = skipList2;