2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8)
3 * Copyright (C) 2012 J Procter, AM Waterhouse, LM Lui, J Engelhardt, G Barton, M Clamp, S Searle
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
11 * Jalview is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty
13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along with Jalview. If not, see <http://www.gnu.org/licenses/>.
20 import java.awt.Rectangle;
22 import java.lang.reflect.InvocationTargetException;
25 import java.util.Map.Entry;
26 import java.util.jar.*;
30 import org.exolab.castor.xml.*;
32 import jalview.bin.Cache;
33 import jalview.datamodel.Alignment;
34 import jalview.datamodel.AlignmentAnnotation;
35 import jalview.datamodel.AlignmentI;
36 import jalview.datamodel.SequenceI;
37 import jalview.schemabinding.version2.*;
38 import jalview.schemes.*;
39 import jalview.util.Platform;
40 import jalview.util.jarInputStreamProvider;
41 import jalview.ws.jws2.Jws2Discoverer;
42 import jalview.ws.jws2.dm.AAConSettings;
43 import jalview.ws.jws2.jabaws2.Jws2Instance;
44 import jalview.ws.params.ArgumentI;
45 import jalview.ws.params.AutoCalcSetting;
46 import jalview.ws.params.WsParamSetI;
49 * Write out the current jalview desktop state as a Jalview XML stream.
51 * Note: the vamsas objects referred to here are primitive versions of the
52 * VAMSAS project schema elements - they are not the same and most likely never
56 * @version $Revision: 1.134 $
58 public class Jalview2XML
61 * create/return unique hash string for sq
64 * @return new or existing unique string for sq
66 String seqHash(SequenceI sq)
68 if (seqsToIds == null)
72 if (seqsToIds.containsKey(sq))
74 return (String) seqsToIds.get(sq);
78 // create sequential key
79 String key = "sq" + (seqsToIds.size() + 1);
80 key = makeHashCode(sq, key); // check we don't have an external reference
82 seqsToIds.put(sq, key);
91 if (seqRefIds != null)
95 if (seqsToIds != null)
105 warn("clearSeqRefs called when _cleartables was not set. Doing nothing.");
106 // seqRefIds = new Hashtable();
107 // seqsToIds = new IdentityHashMap();
113 if (seqsToIds == null)
115 seqsToIds = new IdentityHashMap();
117 if (seqRefIds == null)
119 seqRefIds = new Hashtable();
124 * SequenceI reference -> XML ID string in jalview XML. Populated as XML reps
125 * of sequence objects are created.
127 java.util.IdentityHashMap seqsToIds = null;
130 * jalview XML Sequence ID to jalview sequence object reference (both dataset
131 * and alignment sequences. Populated as XML reps of sequence objects are
134 java.util.Hashtable seqRefIds = null; // key->SequenceI resolution
136 Vector frefedSequence = null;
138 boolean raiseGUI = true; // whether errors are raised in dialog boxes or not
144 public Jalview2XML(boolean raiseGUI)
146 this.raiseGUI = raiseGUI;
149 public void resolveFrefedSequences()
151 if (frefedSequence.size() > 0)
153 int r = 0, rSize = frefedSequence.size();
156 Object[] ref = (Object[]) frefedSequence.elementAt(r);
159 String sref = (String) ref[0];
160 if (seqRefIds.containsKey(sref))
162 if (ref[1] instanceof jalview.datamodel.Mapping)
164 SequenceI seq = (SequenceI) seqRefIds.get(sref);
165 while (seq.getDatasetSequence() != null)
167 seq = seq.getDatasetSequence();
169 ((jalview.datamodel.Mapping) ref[1]).setTo(seq);
173 if (ref[1] instanceof jalview.datamodel.AlignedCodonFrame)
175 SequenceI seq = (SequenceI) seqRefIds.get(sref);
176 while (seq.getDatasetSequence() != null)
178 seq = seq.getDatasetSequence();
181 && ref[2] instanceof jalview.datamodel.Mapping)
183 jalview.datamodel.Mapping mp = (jalview.datamodel.Mapping) ref[2];
184 ((jalview.datamodel.AlignedCodonFrame) ref[1]).addMap(
185 seq, mp.getTo(), mp.getMap());
190 .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for AlcodonFrames involving "
191 + ref[2].getClass() + " type objects.");
197 .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for "
198 + ref[1].getClass() + " type objects.");
201 frefedSequence.remove(r);
207 .println("IMPLEMENTATION WARNING: Unresolved forward reference for hash string "
209 + " with objecttype "
210 + ref[1].getClass());
217 frefedSequence.remove(r);
225 * This maintains a list of viewports, the key being the seqSetId. Important
226 * to set historyItem and redoList for multiple views
228 Hashtable viewportsAdded;
230 Hashtable annotationIds = new Hashtable();
232 String uniqueSetSuffix = "";
235 * List of pdbfiles added to Jar
237 Vector pdbfiles = null;
239 // SAVES SEVERAL ALIGNMENT WINDOWS TO SAME JARFILE
240 public void SaveState(File statefile)
244 FileOutputStream fos = new FileOutputStream(statefile);
245 JarOutputStream jout = new JarOutputStream(fos);
248 } catch (Exception e)
250 // TODO: inform user of the problem - they need to know if their data was
252 if (errorMessage == null)
254 errorMessage = "Couldn't write Jalview Archive to output file '"
255 + statefile + "' - See console error log for details";
259 errorMessage += "(output file was '" + statefile + "')";
267 * Writes a jalview project archive to the given Jar output stream.
271 public void SaveState(JarOutputStream jout)
273 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
283 // NOTE UTF-8 MUST BE USED FOR WRITING UNICODE CHARS
284 // //////////////////////////////////////////////////
285 // NOTE ALSO new PrintWriter must be used for each new JarEntry
286 PrintWriter out = null;
288 Vector shortNames = new Vector();
291 for (int i = frames.length - 1; i > -1; i--)
293 if (frames[i] instanceof AlignFrame)
295 AlignFrame af = (AlignFrame) frames[i];
298 && skipList.containsKey(af.getViewport()
299 .getSequenceSetId()))
304 String shortName = af.getTitle();
306 if (shortName.indexOf(File.separatorChar) > -1)
308 shortName = shortName.substring(shortName
309 .lastIndexOf(File.separatorChar) + 1);
314 while (shortNames.contains(shortName))
316 if (shortName.endsWith("_" + (count - 1)))
318 shortName = shortName
319 .substring(0, shortName.lastIndexOf("_"));
322 shortName = shortName.concat("_" + count);
326 shortNames.addElement(shortName);
328 if (!shortName.endsWith(".xml"))
330 shortName = shortName + ".xml";
333 int ap, apSize = af.alignPanels.size();
334 for (ap = 0; ap < apSize; ap++)
336 AlignmentPanel apanel = (AlignmentPanel) af.alignPanels
338 String fileName = apSize == 1 ? shortName : ap + shortName;
339 if (!fileName.endsWith(".xml"))
341 fileName = fileName + ".xml";
344 SaveState(apanel, fileName, jout);
351 } catch (Exception foo)
356 } catch (Exception ex)
358 // TODO: inform user of the problem - they need to know if their data was
360 if (errorMessage == null)
362 errorMessage = "Couldn't write Jalview Archive - see error output for details";
364 ex.printStackTrace();
368 // USE THIS METHOD TO SAVE A SINGLE ALIGNMENT WINDOW
369 public boolean SaveAlignment(AlignFrame af, String jarFile,
374 int ap, apSize = af.alignPanels.size();
375 FileOutputStream fos = new FileOutputStream(jarFile);
376 JarOutputStream jout = new JarOutputStream(fos);
377 for (ap = 0; ap < apSize; ap++)
379 AlignmentPanel apanel = (AlignmentPanel) af.alignPanels
381 String jfileName = apSize == 1 ? fileName : fileName + ap;
382 if (!jfileName.endsWith(".xml"))
384 jfileName = jfileName + ".xml";
386 SaveState(apanel, jfileName, jout);
392 } catch (Exception foo)
398 } catch (Exception ex)
400 errorMessage = "Couldn't Write alignment view to Jalview Archive - see error output for details";
401 ex.printStackTrace();
407 * create a JalviewModel from an algnment view and marshall it to a
411 * panel to create jalview model for
413 * name of alignment panel written to output stream
419 public JalviewModel SaveState(AlignmentPanel ap, String fileName,
420 JarOutputStream jout)
423 Vector jmolViewIds = new Vector(); //
424 Vector userColours = new Vector();
426 AlignViewport av = ap.av;
428 JalviewModel object = new JalviewModel();
429 object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel());
431 object.setCreationDate(new java.util.Date(System.currentTimeMillis()));
432 object.setVersion(jalview.bin.Cache.getProperty("VERSION"));
434 jalview.datamodel.AlignmentI jal = av.getAlignment();
436 if (av.hasHiddenRows())
438 jal = jal.getHiddenSequences().getFullAlignment();
441 SequenceSet vamsasSet = new SequenceSet();
443 JalviewModelSequence jms = new JalviewModelSequence();
445 vamsasSet.setGapChar(jal.getGapCharacter() + "");
447 if (jal.getDataset() != null)
449 // dataset id is the dataset's hashcode
450 vamsasSet.setDatasetId(getDatasetIdRef(jal.getDataset()));
452 if (jal.getProperties() != null)
454 Enumeration en = jal.getProperties().keys();
455 while (en.hasMoreElements())
457 String key = en.nextElement().toString();
458 SequenceSetProperties ssp = new SequenceSetProperties();
460 ssp.setValue(jal.getProperties().get(key).toString());
461 vamsasSet.addSequenceSetProperties(ssp);
466 Set<String> calcIdSet = new HashSet<String>();
470 jalview.datamodel.SequenceI jds;
471 for (int i = 0; i < jal.getHeight(); i++)
473 jds = jal.getSequenceAt(i);
476 if (seqRefIds.get(id) != null)
478 // This happens for two reasons: 1. multiple views are being serialised.
479 // 2. the hashCode has collided with another sequence's code. This DOES
480 // HAPPEN! (PF00072.15.stk does this)
481 // JBPNote: Uncomment to debug writing out of files that do not read
482 // back in due to ArrayOutOfBoundExceptions.
483 // System.err.println("vamsasSeq backref: "+id+"");
484 // System.err.println(jds.getName()+"
485 // "+jds.getStart()+"-"+jds.getEnd()+" "+jds.getSequenceAsString());
486 // System.err.println("Hashcode: "+seqHash(jds));
487 // SequenceI rsq = (SequenceI) seqRefIds.get(id + "");
488 // System.err.println(rsq.getName()+"
489 // "+rsq.getStart()+"-"+rsq.getEnd()+" "+rsq.getSequenceAsString());
490 // System.err.println("Hashcode: "+seqHash(rsq));
494 vamsasSeq = createVamsasSequence(id, jds);
495 vamsasSet.addSequence(vamsasSeq);
496 seqRefIds.put(id, jds);
500 jseq.setStart(jds.getStart());
501 jseq.setEnd(jds.getEnd());
502 jseq.setColour(av.getSequenceColour(jds).getRGB());
504 jseq.setId(id); // jseq id should be a string not a number
506 if (av.hasHiddenRows())
508 jseq.setHidden(av.getAlignment().getHiddenSequences().isHidden(jds));
510 if (av.isHiddenRepSequence(jal.getSequenceAt(i)))
512 jalview.datamodel.SequenceI[] reps = av.getRepresentedSequences(
513 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()
874 || aa[i] == av.getAlignmentConservationAnnotation()
875 || aa[i] == av.getAlignmentConsensusAnnotation()
876 || aa[i].autoCalculated)
878 // new way of indicating autocalculated annotation -
879 an.setAutoCalculated(aa[i].autoCalculated);
881 if (aa[i].hasScore())
883 an.setScore(aa[i].getScore());
886 if (aa[i].getCalcId() != null)
888 calcIdSet.add(aa[i].getCalcId());
889 an.setCalcId(aa[i].getCalcId());
892 AnnotationElement ae;
893 if (aa[i].annotations != null)
895 an.setScoreOnly(false);
896 for (int a = 0; a < aa[i].annotations.length; a++)
898 if ((aa[i] == null) || (aa[i].annotations[a] == null))
903 ae = new AnnotationElement();
904 if (aa[i].annotations[a].description != null)
905 ae.setDescription(aa[i].annotations[a].description);
906 if (aa[i].annotations[a].displayCharacter != null)
907 ae.setDisplayCharacter(aa[i].annotations[a].displayCharacter);
909 if (!Float.isNaN(aa[i].annotations[a].value))
910 ae.setValue(aa[i].annotations[a].value);
913 if (aa[i].annotations[a].secondaryStructure != ' '
914 && aa[i].annotations[a].secondaryStructure != '\0')
915 ae.setSecondaryStructure(aa[i].annotations[a].secondaryStructure
918 if (aa[i].annotations[a].colour != null
919 && aa[i].annotations[a].colour != java.awt.Color.black)
921 ae.setColour(aa[i].annotations[a].colour.getRGB());
924 an.addAnnotationElement(ae);
925 if (aa[i].autoCalculated)
927 // only write one non-null entry into the annotation row -
928 // sufficient to get the visualization attributes necessary to
936 an.setScoreOnly(true);
938 vamsasSet.addAnnotation(an);
942 if (jal.getGroups() != null)
944 JGroup[] groups = new JGroup[jal.getGroups().size()];
946 for (jalview.datamodel.SequenceGroup sg : jal.getGroups())
948 groups[++i] = new JGroup();
950 groups[i].setStart(sg.getStartRes());
951 groups[i].setEnd(sg.getEndRes());
952 groups[i].setName(sg.getName());
953 if (groupRefs.containsKey(sg))
955 // group has references so set it's ID field
956 groups[i].setId(groupRefs.get(sg).toString());
960 if (sg.cs.conservationApplied())
962 groups[i].setConsThreshold(sg.cs.getConservationInc());
964 if (sg.cs instanceof jalview.schemes.UserColourScheme)
966 groups[i].setColour(SetUserColourScheme(sg.cs, userColours,
972 .setColour(ColourSchemeProperty.getColourName(sg.cs));
975 else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient)
978 .setColour(ColourSchemeProperty
979 .getColourName(((jalview.schemes.AnnotationColourGradient) sg.cs)
982 else if (sg.cs instanceof jalview.schemes.UserColourScheme)
985 .setColour(SetUserColourScheme(sg.cs, userColours, jms));
989 groups[i].setColour(ColourSchemeProperty.getColourName(sg.cs));
992 groups[i].setPidThreshold(sg.cs.getThreshold());
995 groups[i].setOutlineColour(sg.getOutlineColour().getRGB());
996 groups[i].setDisplayBoxes(sg.getDisplayBoxes());
997 groups[i].setDisplayText(sg.getDisplayText());
998 groups[i].setColourText(sg.getColourText());
999 groups[i].setTextCol1(sg.textColour.getRGB());
1000 groups[i].setTextCol2(sg.textColour2.getRGB());
1001 groups[i].setTextColThreshold(sg.thresholdTextColour);
1002 groups[i].setShowUnconserved(sg.getShowNonconserved());
1003 groups[i].setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
1004 groups[i].setShowConsensusHistogram(sg.isShowConsensusHistogram());
1005 groups[i].setShowSequenceLogo(sg.isShowSequenceLogo());
1006 groups[i].setNormaliseSequenceLogo(sg.isNormaliseSequenceLogo());
1007 for (int s = 0; s < sg.getSize(); s++)
1009 jalview.datamodel.Sequence seq = (jalview.datamodel.Sequence) sg
1011 groups[i].addSeq(seqHash(seq));
1015 jms.setJGroup(groups);
1018 // /////////SAVE VIEWPORT
1019 Viewport view = new Viewport();
1020 view.setTitle(ap.alignFrame.getTitle());
1021 view.setSequenceSetId(makeHashCode(av.getSequenceSetId(),
1022 av.getSequenceSetId()));
1023 view.setId(av.getViewId());
1024 view.setViewName(av.viewName);
1025 view.setGatheredViews(av.gatherViewsHere);
1027 if (ap.av.explodedPosition != null)
1029 view.setXpos(av.explodedPosition.x);
1030 view.setYpos(av.explodedPosition.y);
1031 view.setWidth(av.explodedPosition.width);
1032 view.setHeight(av.explodedPosition.height);
1036 view.setXpos(ap.alignFrame.getBounds().x);
1037 view.setYpos(ap.alignFrame.getBounds().y);
1038 view.setWidth(ap.alignFrame.getBounds().width);
1039 view.setHeight(ap.alignFrame.getBounds().height);
1042 view.setStartRes(av.startRes);
1043 view.setStartSeq(av.startSeq);
1045 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1047 view.setBgColour(SetUserColourScheme(av.getGlobalColourScheme(),
1050 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1052 jalview.schemes.AnnotationColourGradient acg = (jalview.schemes.AnnotationColourGradient) av
1053 .getGlobalColourScheme();
1055 AnnotationColours ac = new AnnotationColours();
1056 ac.setAboveThreshold(acg.getAboveThreshold());
1057 ac.setThreshold(acg.getAnnotationThreshold());
1058 ac.setAnnotation(acg.getAnnotation());
1059 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1061 ac.setColourScheme(SetUserColourScheme(acg.getBaseColour(),
1066 ac.setColourScheme(ColourSchemeProperty.getColourName(acg
1070 ac.setMaxColour(acg.getMaxColour().getRGB());
1071 ac.setMinColour(acg.getMinColour().getRGB());
1072 view.setAnnotationColours(ac);
1073 view.setBgColour("AnnotationColourGradient");
1077 view.setBgColour(ColourSchemeProperty.getColourName(av
1078 .getGlobalColourScheme()));
1081 ColourSchemeI cs = av.getGlobalColourScheme();
1085 if (cs.conservationApplied())
1087 view.setConsThreshold(cs.getConservationInc());
1088 if (cs instanceof jalview.schemes.UserColourScheme)
1090 view.setBgColour(SetUserColourScheme(cs, userColours, jms));
1094 if (cs instanceof ResidueColourScheme)
1096 view.setPidThreshold(cs.getThreshold());
1100 view.setConservationSelected(av.getConservationSelected());
1101 view.setPidSelected(av.getAbovePIDThreshold());
1102 view.setFontName(av.font.getName());
1103 view.setFontSize(av.font.getSize());
1104 view.setFontStyle(av.font.getStyle());
1105 view.setRenderGaps(av.renderGaps);
1106 view.setShowAnnotation(av.getShowAnnotation());
1107 view.setShowBoxes(av.getShowBoxes());
1108 view.setShowColourText(av.getColourText());
1109 view.setShowFullId(av.getShowJVSuffix());
1110 view.setRightAlignIds(av.rightAlignIds);
1111 view.setShowSequenceFeatures(av.showSequenceFeatures);
1112 view.setShowText(av.getShowText());
1113 view.setShowUnconserved(av.getShowUnconserved());
1114 view.setWrapAlignment(av.getWrapAlignment());
1115 view.setTextCol1(av.textColour.getRGB());
1116 view.setTextCol2(av.textColour2.getRGB());
1117 view.setTextColThreshold(av.thresholdTextColour);
1118 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1119 view.setShowSequenceLogo(av.isShowSequenceLogo());
1120 view.setNormaliseSequenceLogo(av.isNormaliseSequenceLogo());
1121 view.setShowGroupConsensus(av.isShowGroupConsensus());
1122 view.setShowGroupConservation(av.isShowGroupConservation());
1123 view.setShowNPfeatureTooltip(av.isShowNpFeats());
1124 view.setShowDbRefTooltip(av.isShowDbRefs());
1125 view.setFollowHighlight(av.followHighlight);
1126 view.setFollowSelection(av.followSelection);
1127 view.setIgnoreGapsinConsensus(av.getIgnoreGapsConsensus());
1128 if (av.featuresDisplayed != null)
1130 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1132 String[] renderOrder = ap.seqPanel.seqCanvas.getFeatureRenderer().renderOrder;
1134 Vector settingsAdded = new Vector();
1135 Object gstyle = null;
1136 GraduatedColor gcol = null;
1137 if (renderOrder != null)
1139 for (int ro = 0; ro < renderOrder.length; ro++)
1141 gstyle = ap.seqPanel.seqCanvas.getFeatureRenderer()
1142 .getFeatureStyle(renderOrder[ro]);
1143 Setting setting = new Setting();
1144 setting.setType(renderOrder[ro]);
1145 if (gstyle instanceof GraduatedColor)
1147 gcol = (GraduatedColor) gstyle;
1148 setting.setColour(gcol.getMaxColor().getRGB());
1149 setting.setMincolour(gcol.getMinColor().getRGB());
1150 setting.setMin(gcol.getMin());
1151 setting.setMax(gcol.getMax());
1152 setting.setColourByLabel(gcol.isColourByLabel());
1153 setting.setAutoScale(gcol.isAutoScale());
1154 setting.setThreshold(gcol.getThresh());
1155 setting.setThreshstate(gcol.getThreshType());
1159 setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer()
1160 .getColour(renderOrder[ro]).getRGB());
1163 setting.setDisplay(av.featuresDisplayed
1164 .containsKey(renderOrder[ro]));
1165 float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer()
1166 .getOrder(renderOrder[ro]);
1169 setting.setOrder(rorder);
1171 fs.addSetting(setting);
1172 settingsAdded.addElement(renderOrder[ro]);
1176 // Make sure we save none displayed feature settings
1177 Iterator en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureColours
1178 .keySet().iterator();
1179 while (en.hasNext())
1181 String key = en.next().toString();
1182 if (settingsAdded.contains(key))
1187 Setting setting = new Setting();
1188 setting.setType(key);
1189 setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer()
1190 .getColour(key).getRGB());
1192 setting.setDisplay(false);
1193 float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer().getOrder(
1197 setting.setOrder(rorder);
1199 fs.addSetting(setting);
1200 settingsAdded.addElement(key);
1202 en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups
1203 .keySet().iterator();
1204 Vector groupsAdded = new Vector();
1205 while (en.hasNext())
1207 String grp = en.next().toString();
1208 if (groupsAdded.contains(grp))
1212 Group g = new Group();
1214 g.setDisplay(((Boolean) ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups
1215 .get(grp)).booleanValue());
1217 groupsAdded.addElement(grp);
1219 jms.setFeatureSettings(fs);
1223 if (av.hasHiddenColumns())
1225 if (av.getColumnSelection() == null
1226 || av.getColumnSelection().getHiddenColumns() == null)
1228 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1232 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1235 int[] region = (int[]) av.getColumnSelection().getHiddenColumns()
1237 HiddenColumns hc = new HiddenColumns();
1238 hc.setStart(region[0]);
1239 hc.setEnd(region[1]);
1240 view.addHiddenColumns(hc);
1244 if (calcIdSet.size() > 0)
1246 for (String calcId : calcIdSet)
1248 if (calcId.trim().length() > 0)
1250 CalcIdParam cidp = createCalcIdParam(calcId, av);
1251 // Some calcIds have no parameters.
1254 view.addCalcIdParam(cidp);
1260 jms.addViewport(view);
1262 object.setJalviewModelSequence(jms);
1263 object.getVamsasModel().addSequenceSet(vamsasSet);
1265 if (jout != null && fileName != null)
1267 // We may not want to write the object to disk,
1268 // eg we can copy the alignViewport to a new view object
1269 // using save and then load
1272 JarEntry entry = new JarEntry(fileName);
1273 jout.putNextEntry(entry);
1274 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1276 org.exolab.castor.xml.Marshaller marshaller = new org.exolab.castor.xml.Marshaller(
1278 marshaller.marshal(object);
1281 } catch (Exception ex)
1283 // TODO: raise error in GUI if marshalling failed.
1284 ex.printStackTrace();
1290 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1292 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1293 if (settings != null)
1295 CalcIdParam vCalcIdParam = new CalcIdParam();
1296 vCalcIdParam.setCalcId(calcId);
1297 vCalcIdParam.addServiceURL(settings.getServiceURI());
1298 // generic URI allowing a third party to resolve another instance of the
1299 // service used for this calculation
1300 for (String urls : settings.getServiceURLs())
1302 vCalcIdParam.addServiceURL(urls);
1304 vCalcIdParam.setVersion("1.0");
1305 if (settings.getPreset() != null)
1307 WsParamSetI setting = settings.getPreset();
1308 vCalcIdParam.setName(setting.getName());
1309 vCalcIdParam.setDescription(setting.getDescription());
1313 vCalcIdParam.setName("");
1314 vCalcIdParam.setDescription("Last used parameters");
1316 // need to be able to recover 1) settings 2) user-defined presets or
1317 // recreate settings from preset 3) predefined settings provided by
1318 // service - or settings that can be transferred (or discarded)
1319 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1321 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1322 // todo - decide if updateImmediately is needed for any projects.
1324 return vCalcIdParam;
1329 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1332 if (calcIdParam.getVersion().equals("1.0"))
1334 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1335 .getPreferredServiceFor(calcIdParam.getServiceURL());
1336 if (service != null)
1338 WsParamSetI parmSet = null;
1341 parmSet = service.getParamStore().parseServiceParameterFile(
1342 calcIdParam.getName(), calcIdParam.getDescription(),
1343 calcIdParam.getServiceURL(),
1344 calcIdParam.getParameters().replace("|\\n|", "\n"));
1345 } catch (IOException x)
1347 warn("Couldn't parse parameter data for "
1348 + calcIdParam.getCalcId(), x);
1351 List<ArgumentI> argList = null;
1352 if (calcIdParam.getName().length() > 0)
1354 parmSet = service.getParamStore()
1355 .getPreset(calcIdParam.getName());
1356 if (parmSet != null)
1358 // TODO : check we have a good match with settings in AACon -
1359 // otherwise we'll need to create a new preset
1364 argList = parmSet.getArguments();
1367 AAConSettings settings = new AAConSettings(
1368 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1369 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1370 calcIdParam.isNeedsUpdate());
1375 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1379 throw new Error("Unsupported Version for calcIdparam "
1380 + calcIdParam.toString());
1384 * External mapping between jalview objects and objects yielding a valid and
1385 * unique object ID string. This is null for normal Jalview project IO, but
1386 * non-null when a jalview project is being read or written as part of a
1389 IdentityHashMap jv2vobj = null;
1392 * Construct a unique ID for jvobj using either existing bindings or if none
1393 * exist, the result of the hashcode call for the object.
1396 * jalview data object
1397 * @return unique ID for referring to jvobj
1399 private String makeHashCode(Object jvobj, String altCode)
1401 if (jv2vobj != null)
1403 Object id = jv2vobj.get(jvobj);
1406 return id.toString();
1408 // check string ID mappings
1409 if (jvids2vobj != null && jvobj instanceof String)
1411 id = jvids2vobj.get(jvobj);
1415 return id.toString();
1417 // give up and warn that something has gone wrong
1418 warn("Cannot find ID for object in external mapping : " + jvobj);
1424 * return local jalview object mapped to ID, if it exists
1428 * @return null or object bound to idcode
1430 private Object retrieveExistingObj(String idcode)
1432 if (idcode != null && vobj2jv != null)
1434 return vobj2jv.get(idcode);
1440 * binding from ID strings from external mapping table to jalview data model
1443 private Hashtable vobj2jv;
1445 private Sequence createVamsasSequence(String id, SequenceI jds)
1447 return createVamsasSequence(true, id, jds, null);
1450 private Sequence createVamsasSequence(boolean recurse, String id,
1451 SequenceI jds, SequenceI parentseq)
1453 Sequence vamsasSeq = new Sequence();
1454 vamsasSeq.setId(id);
1455 vamsasSeq.setName(jds.getName());
1456 vamsasSeq.setSequence(jds.getSequenceAsString());
1457 vamsasSeq.setDescription(jds.getDescription());
1458 jalview.datamodel.DBRefEntry[] dbrefs = null;
1459 if (jds.getDatasetSequence() != null)
1461 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
1462 if (jds.getDatasetSequence().getDBRef() != null)
1464 dbrefs = jds.getDatasetSequence().getDBRef();
1469 vamsasSeq.setDsseqid(id); // so we can tell which sequences really are
1470 // dataset sequences only
1471 dbrefs = jds.getDBRef();
1475 for (int d = 0; d < dbrefs.length; d++)
1477 DBRef dbref = new DBRef();
1478 dbref.setSource(dbrefs[d].getSource());
1479 dbref.setVersion(dbrefs[d].getVersion());
1480 dbref.setAccessionId(dbrefs[d].getAccessionId());
1481 if (dbrefs[d].hasMap())
1483 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
1485 dbref.setMapping(mp);
1487 vamsasSeq.addDBRef(dbref);
1493 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
1494 SequenceI parentseq, SequenceI jds, boolean recurse)
1497 if (jmp.getMap() != null)
1501 jalview.util.MapList mlst = jmp.getMap();
1502 int r[] = mlst.getFromRanges();
1503 for (int s = 0; s < r.length; s += 2)
1505 MapListFrom mfrom = new MapListFrom();
1506 mfrom.setStart(r[s]);
1507 mfrom.setEnd(r[s + 1]);
1508 mp.addMapListFrom(mfrom);
1510 r = mlst.getToRanges();
1511 for (int s = 0; s < r.length; s += 2)
1513 MapListTo mto = new MapListTo();
1515 mto.setEnd(r[s + 1]);
1516 mp.addMapListTo(mto);
1518 mp.setMapFromUnit(mlst.getFromRatio());
1519 mp.setMapToUnit(mlst.getToRatio());
1520 if (jmp.getTo() != null)
1522 MappingChoice mpc = new MappingChoice();
1524 && (parentseq != jmp.getTo() || parentseq
1525 .getDatasetSequence() != jmp.getTo()))
1527 mpc.setSequence(createVamsasSequence(false, seqHash(jmp.getTo()),
1533 SequenceI ps = null;
1534 if (parentseq != jmp.getTo()
1535 && parentseq.getDatasetSequence() != jmp.getTo())
1537 // chaining dbref rather than a handshaking one
1538 jmpid = seqHash(ps = jmp.getTo());
1542 jmpid = seqHash(ps = parentseq);
1544 mpc.setDseqFor(jmpid);
1545 if (!seqRefIds.containsKey(mpc.getDseqFor()))
1547 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
1548 seqRefIds.put(mpc.getDseqFor(), ps);
1552 jalview.bin.Cache.log.debug("reusing DseqFor ID");
1555 mp.setMappingChoice(mpc);
1561 String SetUserColourScheme(jalview.schemes.ColourSchemeI cs,
1562 Vector userColours, JalviewModelSequence jms)
1565 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
1566 boolean newucs = false;
1567 if (!userColours.contains(ucs))
1569 userColours.add(ucs);
1572 id = "ucs" + userColours.indexOf(ucs);
1575 // actually create the scheme's entry in the XML model
1576 java.awt.Color[] colours = ucs.getColours();
1577 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
1578 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
1580 for (int i = 0; i < colours.length; i++)
1582 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1583 col.setName(ResidueProperties.aa[i]);
1584 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1585 jbucs.addColour(col);
1587 if (ucs.getLowerCaseColours() != null)
1589 colours = ucs.getLowerCaseColours();
1590 for (int i = 0; i < colours.length; i++)
1592 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1593 col.setName(ResidueProperties.aa[i].toLowerCase());
1594 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1595 jbucs.addColour(col);
1600 uc.setUserColourScheme(jbucs);
1601 jms.addUserColours(uc);
1607 jalview.schemes.UserColourScheme GetUserColourScheme(
1608 JalviewModelSequence jms, String id)
1610 UserColours[] uc = jms.getUserColours();
1611 UserColours colours = null;
1613 for (int i = 0; i < uc.length; i++)
1615 if (uc[i].getId().equals(id))
1623 java.awt.Color[] newColours = new java.awt.Color[24];
1625 for (int i = 0; i < 24; i++)
1627 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1628 .getUserColourScheme().getColour(i).getRGB(), 16));
1631 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
1634 if (colours.getUserColourScheme().getColourCount() > 24)
1636 newColours = new java.awt.Color[23];
1637 for (int i = 0; i < 23; i++)
1639 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1640 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
1642 ucs.setLowerCaseColours(newColours);
1649 * contains last error message (if any) encountered by XML loader.
1651 String errorMessage = null;
1654 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
1655 * exceptions are raised during project XML parsing
1657 public boolean attemptversion1parse = true;
1660 * Load a jalview project archive from a jar file
1663 * - HTTP URL or filename
1665 public AlignFrame LoadJalviewAlign(final String file)
1668 jalview.gui.AlignFrame af = null;
1672 // create list to store references for any new Jmol viewers created
1673 newStructureViewers=new Vector<AppJmol>();
1674 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
1675 // Workaround is to make sure caller implements the JarInputStreamProvider
1677 // so we can re-open the jar input stream for each entry.
1679 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
1680 af = LoadJalviewAlign(jprovider);
1681 setLoadingFinishedForNewStructureViewers();
1682 } catch (MalformedURLException e)
1684 errorMessage = "Invalid URL format for '" + file + "'";
1690 private jarInputStreamProvider createjarInputStreamProvider(
1691 final String file) throws MalformedURLException
1694 errorMessage = null;
1695 uniqueSetSuffix = null;
1697 viewportsAdded = null;
1698 frefedSequence = null;
1700 if (file.startsWith("http://"))
1702 url = new URL(file);
1704 final URL _url = url;
1705 return new jarInputStreamProvider()
1709 public JarInputStream getJarInputStream() throws IOException
1713 return new JarInputStream(_url.openStream());
1717 return new JarInputStream(new FileInputStream(file));
1722 public String getFilename()
1730 * Recover jalview session from a jalview project archive. Caller may
1731 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
1732 * themselves. Any null fields will be initialised with default values,
1733 * non-null fields are left alone.
1738 public AlignFrame LoadJalviewAlign(final jarInputStreamProvider jprovider)
1740 errorMessage = null;
1741 if (uniqueSetSuffix == null)
1743 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
1745 if (seqRefIds == null)
1747 seqRefIds = new Hashtable();
1749 if (viewportsAdded == null)
1751 viewportsAdded = new Hashtable();
1753 if (frefedSequence == null)
1755 frefedSequence = new Vector();
1758 jalview.gui.AlignFrame af = null;
1759 Hashtable gatherToThisFrame = new Hashtable();
1760 final String file = jprovider.getFilename();
1763 JarInputStream jin = null;
1764 JarEntry jarentry = null;
1769 jin = jprovider.getJarInputStream();
1770 for (int i = 0; i < entryCount; i++)
1772 jarentry = jin.getNextJarEntry();
1775 if (jarentry != null && jarentry.getName().endsWith(".xml"))
1777 InputStreamReader in = new InputStreamReader(jin, "UTF-8");
1778 JalviewModel object = new JalviewModel();
1780 Unmarshaller unmar = new Unmarshaller(object);
1781 unmar.setValidation(false);
1782 object = (JalviewModel) unmar.unmarshal(in);
1783 if (true) // !skipViewport(object))
1785 af = LoadFromObject(object, file, true, jprovider);
1786 if (af.viewport.gatherViewsHere)
1788 gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
1793 else if (jarentry != null)
1795 // Some other file here.
1798 } while (jarentry != null);
1799 resolveFrefedSequences();
1800 } catch (java.io.FileNotFoundException ex)
1802 ex.printStackTrace();
1803 errorMessage = "Couldn't locate Jalview XML file : " + file;
1804 System.err.println("Exception whilst loading jalview XML file : "
1806 } catch (java.net.UnknownHostException ex)
1808 ex.printStackTrace();
1809 errorMessage = "Couldn't locate Jalview XML file : " + file;
1810 System.err.println("Exception whilst loading jalview XML file : "
1812 } catch (Exception ex)
1814 System.err.println("Parsing as Jalview Version 2 file failed.");
1815 ex.printStackTrace(System.err);
1816 if (attemptversion1parse)
1818 // Is Version 1 Jar file?
1821 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
1822 } catch (Exception ex2)
1824 System.err.println("Exception whilst loading as jalviewXMLV1:");
1825 ex2.printStackTrace();
1829 if (Desktop.instance != null)
1831 Desktop.instance.stopLoading();
1835 System.out.println("Successfully loaded archive file");
1838 ex.printStackTrace();
1840 System.err.println("Exception whilst loading jalview XML file : "
1842 } catch (OutOfMemoryError e)
1844 // Don't use the OOM Window here
1845 errorMessage = "Out of memory loading jalview XML file";
1846 System.err.println("Out of memory whilst loading jalview XML file");
1847 e.printStackTrace();
1850 if (Desktop.instance != null)
1852 Desktop.instance.stopLoading();
1855 Enumeration en = gatherToThisFrame.elements();
1856 while (en.hasMoreElements())
1858 Desktop.instance.gatherViews((AlignFrame) en.nextElement());
1860 if (errorMessage != null)
1868 * check errorMessage for a valid error message and raise an error box in the
1869 * GUI or write the current errorMessage to stderr and then clear the error
1872 protected void reportErrors()
1874 reportErrors(false);
1877 protected void reportErrors(final boolean saving)
1879 if (errorMessage != null)
1881 final String finalErrorMessage = errorMessage;
1884 javax.swing.SwingUtilities.invokeLater(new Runnable()
1889 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1890 finalErrorMessage, "Error "
1891 + (saving ? "saving" : "loading")
1892 + " Jalview file", JOptionPane.WARNING_MESSAGE);
1898 System.err.println("Problem loading Jalview file: " + errorMessage);
1901 errorMessage = null;
1904 Hashtable alreadyLoadedPDB;
1907 * when set, local views will be updated from view stored in JalviewXML
1908 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
1909 * sync if this is set to true.
1911 private final boolean updateLocalViews = false;
1913 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
1915 if (alreadyLoadedPDB == null)
1916 alreadyLoadedPDB = new Hashtable();
1918 if (alreadyLoadedPDB.containsKey(pdbId))
1919 return alreadyLoadedPDB.get(pdbId).toString();
1923 JarInputStream jin = jprovider.getJarInputStream();
1925 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
1926 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
1927 * FileInputStream(jprovider)); }
1930 JarEntry entry = null;
1933 entry = jin.getNextJarEntry();
1934 } while (entry != null && !entry.getName().equals(pdbId));
1937 BufferedReader in = new BufferedReader(new InputStreamReader(jin));
1938 File outFile = File.createTempFile("jalview_pdb", ".txt");
1939 outFile.deleteOnExit();
1940 PrintWriter out = new PrintWriter(new FileOutputStream(outFile));
1943 while ((data = in.readLine()) != null)
1950 } catch (Exception foo)
1955 String t = outFile.getAbsolutePath();
1956 alreadyLoadedPDB.put(pdbId, t);
1961 warn("Couldn't find PDB file entry in Jalview Jar for " + pdbId);
1963 } catch (Exception ex)
1965 ex.printStackTrace();
1971 private class JvAnnotRow
1973 public JvAnnotRow(int i, AlignmentAnnotation jaa)
1980 * persisted version of annotation row from which to take vis properties
1982 public jalview.datamodel.AlignmentAnnotation template;
1985 * original position of the annotation row in the alignment
1991 * Load alignment frame from jalview XML DOM object
1996 * filename source string
1997 * @param loadTreesAndStructures
1998 * when false only create Viewport
2000 * data source provider
2001 * @return alignment frame created from view stored in DOM
2003 AlignFrame LoadFromObject(JalviewModel object, String file,
2004 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2006 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2007 Sequence[] vamsasSeq = vamsasSet.getSequence();
2009 JalviewModelSequence jms = object.getJalviewModelSequence();
2011 Viewport view = jms.getViewport(0);
2012 // ////////////////////////////////
2015 Vector hiddenSeqs = null;
2016 jalview.datamodel.Sequence jseq;
2018 ArrayList tmpseqs = new ArrayList();
2020 boolean multipleView = false;
2022 JSeq[] JSEQ = object.getJalviewModelSequence().getJSeq();
2023 int vi = 0; // counter in vamsasSeq array
2024 for (int i = 0; i < JSEQ.length; i++)
2026 String seqId = JSEQ[i].getId();
2028 if (seqRefIds.get(seqId) != null)
2030 tmpseqs.add(seqRefIds.get(seqId));
2031 multipleView = true;
2035 jseq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2036 vamsasSeq[vi].getSequence());
2037 jseq.setDescription(vamsasSeq[vi].getDescription());
2038 jseq.setStart(JSEQ[i].getStart());
2039 jseq.setEnd(JSEQ[i].getEnd());
2040 jseq.setVamsasId(uniqueSetSuffix + seqId);
2041 seqRefIds.put(vamsasSeq[vi].getId(), jseq);
2046 if (JSEQ[i].getHidden())
2048 if (hiddenSeqs == null)
2050 hiddenSeqs = new Vector();
2053 hiddenSeqs.addElement(seqRefIds.get(seqId));
2059 // Create the alignment object from the sequence set
2060 // ///////////////////////////////
2061 jalview.datamodel.Sequence[] orderedSeqs = new jalview.datamodel.Sequence[tmpseqs
2064 tmpseqs.toArray(orderedSeqs);
2066 jalview.datamodel.Alignment al = new jalview.datamodel.Alignment(
2069 // / Add the alignment properties
2070 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2072 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2073 al.setProperty(ssp.getKey(), ssp.getValue());
2077 // SequenceFeatures are added to the DatasetSequence,
2078 // so we must create or recover the dataset before loading features
2079 // ///////////////////////////////
2080 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2082 // older jalview projects do not have a dataset id.
2083 al.setDataset(null);
2087 recoverDatasetFor(vamsasSet, al);
2089 // ///////////////////////////////
2091 Hashtable pdbloaded = new Hashtable();
2094 // load sequence features, database references and any associated PDB
2095 // structures for the alignment
2096 for (int i = 0; i < vamsasSeq.length; i++)
2098 if (JSEQ[i].getFeaturesCount() > 0)
2100 Features[] features = JSEQ[i].getFeatures();
2101 for (int f = 0; f < features.length; f++)
2103 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2104 features[f].getType(), features[f].getDescription(),
2105 features[f].getStatus(), features[f].getBegin(),
2106 features[f].getEnd(), features[f].getFeatureGroup());
2108 sf.setScore(features[f].getScore());
2109 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2111 OtherData keyValue = features[f].getOtherData(od);
2112 if (keyValue.getKey().startsWith("LINK"))
2114 sf.addLink(keyValue.getValue());
2118 sf.setValue(keyValue.getKey(), keyValue.getValue());
2123 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
2126 if (vamsasSeq[i].getDBRefCount() > 0)
2128 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2130 if (JSEQ[i].getPdbidsCount() > 0)
2132 Pdbids[] ids = JSEQ[i].getPdbids();
2133 for (int p = 0; p < ids.length; p++)
2135 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2136 entry.setId(ids[p].getId());
2137 entry.setType(ids[p].getType());
2138 if (ids[p].getFile() != null)
2140 if (!pdbloaded.containsKey(ids[p].getFile()))
2142 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2146 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2150 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2154 } // end !multipleview
2156 // ///////////////////////////////
2157 // LOAD SEQUENCE MAPPINGS
2159 if (vamsasSet.getAlcodonFrameCount() > 0)
2161 // TODO Potentially this should only be done once for all views of an
2163 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2164 for (int i = 0; i < alc.length; i++)
2166 jalview.datamodel.AlignedCodonFrame cf = new jalview.datamodel.AlignedCodonFrame(
2167 alc[i].getAlcodonCount());
2168 if (alc[i].getAlcodonCount() > 0)
2170 Alcodon[] alcods = alc[i].getAlcodon();
2171 for (int p = 0; p < cf.codons.length; p++)
2173 if (alcods[p].hasPos1() && alcods[p].hasPos2()
2174 && alcods[p].hasPos3())
2176 // translated codons require three valid positions
2177 cf.codons[p] = new int[3];
2178 cf.codons[p][0] = (int) alcods[p].getPos1();
2179 cf.codons[p][1] = (int) alcods[p].getPos2();
2180 cf.codons[p][2] = (int) alcods[p].getPos3();
2184 cf.codons[p] = null;
2188 if (alc[i].getAlcodMapCount() > 0)
2190 AlcodMap[] maps = alc[i].getAlcodMap();
2191 for (int m = 0; m < maps.length; m++)
2193 SequenceI dnaseq = (SequenceI) seqRefIds
2194 .get(maps[m].getDnasq());
2196 jalview.datamodel.Mapping mapping = null;
2197 // attach to dna sequence reference.
2198 if (maps[m].getMapping() != null)
2200 mapping = addMapping(maps[m].getMapping());
2204 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
2209 frefedSequence.add(new Object[]
2210 { maps[m].getDnasq(), cf, mapping });
2214 al.addCodonFrame(cf);
2219 // ////////////////////////////////
2221 ArrayList<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
2223 * store any annotations which forward reference a group's ID
2225 Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>>();
2227 if (vamsasSet.getAnnotationCount() > 0)
2229 Annotation[] an = vamsasSet.getAnnotation();
2231 for (int i = 0; i < an.length; i++)
2234 * test if annotation is automatically calculated for this view only
2236 boolean autoForView = false;
2237 if (an[i].getLabel().equals("Quality")
2238 || an[i].getLabel().equals("Conservation")
2239 || an[i].getLabel().equals("Consensus"))
2241 // Kludge for pre 2.5 projects which lacked the autocalculated flag
2243 if (!an[i].hasAutoCalculated())
2245 an[i].setAutoCalculated(true);
2249 || (an[i].hasAutoCalculated() && an[i].isAutoCalculated()))
2251 // remove ID - we don't recover annotation from other views for
2252 // view-specific annotation
2256 // set visiblity for other annotation in this view
2257 if (an[i].getId() != null
2258 && annotationIds.containsKey(an[i].getId()))
2260 jalview.datamodel.AlignmentAnnotation jda = (jalview.datamodel.AlignmentAnnotation) annotationIds
2261 .get(an[i].getId());
2262 // in principle Visible should always be true for annotation displayed
2263 // in multiple views
2264 if (an[i].hasVisible())
2265 jda.visible = an[i].getVisible();
2267 al.addAnnotation(jda);
2271 // Construct new annotation from model.
2272 AnnotationElement[] ae = an[i].getAnnotationElement();
2273 jalview.datamodel.Annotation[] anot = null;
2274 java.awt.Color firstColour = null;
2276 if (!an[i].getScoreOnly())
2278 anot = new jalview.datamodel.Annotation[al.getWidth()];
2279 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
2281 anpos = ae[aa].getPosition();
2283 if (anpos >= anot.length)
2286 anot[anpos] = new jalview.datamodel.Annotation(
2288 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
2289 (ae[aa].getSecondaryStructure() == null || ae[aa]
2290 .getSecondaryStructure().length() == 0) ? ' '
2291 : ae[aa].getSecondaryStructure().charAt(0),
2295 // JBPNote: Consider verifying dataflow for IO of secondary
2296 // structure annotation read from Stockholm files
2297 // this was added to try to ensure that
2298 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
2300 // anot[ae[aa].getPosition()].displayCharacter = "";
2302 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
2303 if (firstColour == null)
2305 firstColour = anot[anpos].colour;
2309 jalview.datamodel.AlignmentAnnotation jaa = null;
2311 if (an[i].getGraph())
2313 float llim = 0, hlim = 0;
2314 // if (autoForView || an[i].isAutoCalculated()) {
2317 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2318 an[i].getDescription(), anot, llim, hlim,
2319 an[i].getGraphType());
2321 jaa.graphGroup = an[i].getGraphGroup();
2322 jaa._linecolour = firstColour;
2323 if (an[i].getThresholdLine() != null)
2325 jaa.setThreshold(new jalview.datamodel.GraphLine(an[i]
2326 .getThresholdLine().getValue(), an[i]
2327 .getThresholdLine().getLabel(), new java.awt.Color(
2328 an[i].getThresholdLine().getColour())));
2331 if (autoForView || an[i].isAutoCalculated())
2333 // Hardwire the symbol display line to ensure that labels for
2334 // histograms are displayed
2340 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2341 an[i].getDescription(), anot);
2342 jaa._linecolour = firstColour;
2344 // register new annotation
2345 if (an[i].getId() != null)
2347 annotationIds.put(an[i].getId(), jaa);
2348 jaa.annotationId = an[i].getId();
2350 // recover sequence association
2351 if (an[i].getSequenceRef() != null)
2353 if (al.findName(an[i].getSequenceRef()) != null)
2355 jaa.createSequenceMapping(al.findName(an[i].getSequenceRef()),
2357 al.findName(an[i].getSequenceRef()).addAlignmentAnnotation(jaa);
2360 // and make a note of any group association
2361 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
2363 ArrayList<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
2364 .get(an[i].getGroupRef());
2367 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
2368 groupAnnotRefs.put(an[i].getGroupRef(), aal);
2373 if (an[i].hasScore())
2375 jaa.setScore(an[i].getScore());
2377 if (an[i].hasVisible())
2378 jaa.visible = an[i].getVisible();
2380 if (an[i].hasCentreColLabels())
2381 jaa.centreColLabels = an[i].getCentreColLabels();
2383 if (an[i].hasScaleColLabels())
2385 jaa.scaleColLabel = an[i].getScaleColLabels();
2387 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
2389 // newer files have an 'autoCalculated' flag and store calculation
2390 // state in viewport properties
2391 jaa.autoCalculated = true; // means annotation will be marked for
2392 // update at end of load.
2394 if (an[i].hasGraphHeight())
2396 jaa.graphHeight = an[i].getGraphHeight();
2398 if (an[i].hasBelowAlignment())
2400 jaa.belowAlignment = an[i].isBelowAlignment();
2402 jaa.setCalcId(an[i].getCalcId());
2404 if (jaa.autoCalculated)
2406 autoAlan.add(new JvAnnotRow(i, jaa));
2409 // if (!autoForView)
2411 // add autocalculated group annotation and any user created annotation
2413 al.addAnnotation(jaa);
2418 // ///////////////////////
2420 // Create alignment markup and styles for this view
2421 if (jms.getJGroupCount() > 0)
2423 JGroup[] groups = jms.getJGroup();
2425 for (int i = 0; i < groups.length; i++)
2427 ColourSchemeI cs = null;
2429 if (groups[i].getColour() != null)
2431 if (groups[i].getColour().startsWith("ucs"))
2433 cs = GetUserColourScheme(jms, groups[i].getColour());
2437 cs = ColourSchemeProperty.getColour(al, groups[i].getColour());
2442 cs.setThreshold(groups[i].getPidThreshold(), true);
2446 Vector seqs = new Vector();
2448 for (int s = 0; s < groups[i].getSeqCount(); s++)
2450 String seqId = groups[i].getSeq(s) + "";
2451 jalview.datamodel.SequenceI ts = (jalview.datamodel.SequenceI) seqRefIds
2456 seqs.addElement(ts);
2460 if (seqs.size() < 1)
2465 jalview.datamodel.SequenceGroup sg = new jalview.datamodel.SequenceGroup(
2466 seqs, groups[i].getName(), cs, groups[i].getDisplayBoxes(),
2467 groups[i].getDisplayText(), groups[i].getColourText(),
2468 groups[i].getStart(), groups[i].getEnd());
2470 sg.setOutlineColour(new java.awt.Color(groups[i].getOutlineColour()));
2472 sg.textColour = new java.awt.Color(groups[i].getTextCol1());
2473 sg.textColour2 = new java.awt.Color(groups[i].getTextCol2());
2474 sg.setShowNonconserved(groups[i].hasShowUnconserved() ? groups[i]
2475 .isShowUnconserved() : false);
2476 sg.thresholdTextColour = groups[i].getTextColThreshold();
2477 if (groups[i].hasShowConsensusHistogram())
2479 sg.setShowConsensusHistogram(groups[i].isShowConsensusHistogram());
2482 if (groups[i].hasShowSequenceLogo())
2484 sg.setshowSequenceLogo(groups[i].isShowSequenceLogo());
2486 if (groups[i].hasNormaliseSequenceLogo())
2488 sg.setNormaliseSequenceLogo(groups[i].isNormaliseSequenceLogo());
2490 if (groups[i].hasIgnoreGapsinConsensus())
2492 sg.setIgnoreGapsConsensus(groups[i].getIgnoreGapsinConsensus());
2494 if (groups[i].getConsThreshold() != 0)
2496 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
2497 "All", ResidueProperties.propHash, 3,
2498 sg.getSequences(null), 0, sg.getWidth() - 1);
2500 c.verdict(false, 25);
2501 sg.cs.setConservation(c);
2504 if (groups[i].getId() != null && groupAnnotRefs.size() > 0)
2506 // re-instate unique group/annotation row reference
2507 ArrayList<jalview.datamodel.AlignmentAnnotation> jaal = groupAnnotRefs
2508 .get(groups[i].getId());
2511 for (jalview.datamodel.AlignmentAnnotation jaa : jaal)
2514 if (jaa.autoCalculated)
2516 // match up and try to set group autocalc alignment row for this
2518 if (jaa.label.startsWith("Consensus for "))
2520 sg.setConsensus(jaa);
2522 // match up and try to set group autocalc alignment row for this
2524 if (jaa.label.startsWith("Conservation for "))
2526 sg.setConservationRow(jaa);
2537 // ///////////////////////////////
2540 // If we just load in the same jar file again, the sequenceSetId
2541 // will be the same, and we end up with multiple references
2542 // to the same sequenceSet. We must modify this id on load
2543 // so that each load of the file gives a unique id
2544 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
2545 String viewId = (view.getId() == null ? null : view.getId()
2547 AlignFrame af = null;
2548 AlignViewport av = null;
2549 // now check to see if we really need to create a new viewport.
2550 if (multipleView && viewportsAdded.size() == 0)
2552 // We recovered an alignment for which a viewport already exists.
2553 // TODO: fix up any settings necessary for overlaying stored state onto
2554 // state recovered from another document. (may not be necessary).
2555 // we may need a binding from a viewport in memory to one recovered from
2557 // and then recover its containing af to allow the settings to be applied.
2558 // TODO: fix for vamsas demo
2560 .println("About to recover a viewport for existing alignment: Sequence set ID is "
2562 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
2563 if (seqsetobj != null)
2565 if (seqsetobj instanceof String)
2567 uniqueSeqSetId = (String) seqsetobj;
2569 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
2575 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
2580 AlignmentPanel ap = null;
2581 boolean isnewview = true;
2584 // Check to see if this alignment already has a view id == viewId
2585 jalview.gui.AlignmentPanel views[] = Desktop
2586 .getAlignmentPanels(uniqueSeqSetId);
2587 if (views != null && views.length > 0)
2589 for (int v = 0; v < views.length; v++)
2591 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
2593 // recover the existing alignpanel, alignframe, viewport
2594 af = views[v].alignFrame;
2597 // TODO: could even skip resetting view settings if we don't want to
2598 // change the local settings from other jalview processes
2607 af = loadViewport(file, JSEQ, hiddenSeqs, al, jms, view,
2608 uniqueSeqSetId, viewId, autoAlan);
2613 // /////////////////////////////////////
2614 if (loadTreesAndStructures && jms.getTreeCount() > 0)
2618 for (int t = 0; t < jms.getTreeCount(); t++)
2621 Tree tree = jms.getTree(t);
2623 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
2626 tp = af.ShowNewickTree(
2627 new jalview.io.NewickFile(tree.getNewick()),
2628 tree.getTitle(), tree.getWidth(), tree.getHeight(),
2629 tree.getXpos(), tree.getYpos());
2630 if (tree.getId() != null)
2632 // perhaps bind the tree id to something ?
2637 // update local tree attributes ?
2638 // TODO: should check if tp has been manipulated by user - if so its
2639 // settings shouldn't be modified
2640 tp.setTitle(tree.getTitle());
2641 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
2642 .getWidth(), tree.getHeight()));
2643 tp.av = av; // af.viewport; // TODO: verify 'associate with all
2646 tp.treeCanvas.av = av; // af.viewport;
2647 tp.treeCanvas.ap = ap; // af.alignPanel;
2652 warn("There was a problem recovering stored Newick tree: \n"
2653 + tree.getNewick());
2657 tp.fitToWindow.setState(tree.getFitToWindow());
2658 tp.fitToWindow_actionPerformed(null);
2660 if (tree.getFontName() != null)
2662 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
2663 .getFontStyle(), tree.getFontSize()));
2667 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
2668 .getFontStyle(), tree.getFontSize()));
2671 tp.showPlaceholders(tree.getMarkUnlinked());
2672 tp.showBootstrap(tree.getShowBootstrap());
2673 tp.showDistances(tree.getShowDistances());
2675 tp.treeCanvas.threshold = tree.getThreshold();
2677 if (tree.getCurrentTree())
2679 af.viewport.setCurrentTree(tp.getTree());
2683 } catch (Exception ex)
2685 ex.printStackTrace();
2689 // //LOAD STRUCTURES
2690 if (loadTreesAndStructures)
2692 // run through all PDB ids on the alignment, and collect mappings between
2693 // jmol view ids and all sequences referring to it
2694 Hashtable<String, Object[]> jmolViewIds = new Hashtable();
2696 for (int i = 0; i < JSEQ.length; i++)
2698 if (JSEQ[i].getPdbidsCount() > 0)
2700 Pdbids[] ids = JSEQ[i].getPdbids();
2701 for (int p = 0; p < ids.length; p++)
2703 for (int s = 0; s < ids[p].getStructureStateCount(); s++)
2705 // check to see if we haven't already created this structure view
2706 String sviewid = (ids[p].getStructureState(s).getViewId() == null) ? null
2707 : ids[p].getStructureState(s).getViewId()
2709 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
2710 // Originally : ids[p].getFile()
2711 // : TODO: verify external PDB file recovery still works in normal
2712 // jalview project load
2713 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
2714 jpdb.setId(ids[p].getId());
2716 int x = ids[p].getStructureState(s).getXpos();
2717 int y = ids[p].getStructureState(s).getYpos();
2718 int width = ids[p].getStructureState(s).getWidth();
2719 int height = ids[p].getStructureState(s).getHeight();
2721 // Probably don't need to do this anymore...
2722 // Desktop.desktop.getComponentAt(x, y);
2723 // TODO: NOW: check that this recovers the PDB file correctly.
2724 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
2725 jalview.datamodel.SequenceI seq = (jalview.datamodel.SequenceI) seqRefIds
2726 .get(JSEQ[i].getId() + "");
2727 if (sviewid == null)
2729 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
2732 if (!jmolViewIds.containsKey(sviewid))
2734 jmolViewIds.put(sviewid, new Object[]
2736 { x, y, width, height }, "",
2737 new Hashtable<String, Object[]>(), new boolean[]
2738 { false, false, true } });
2739 // Legacy pre-2.7 conversion JAL-823 :
2740 // do not assume any view has to be linked for colour by
2744 // assemble String[] { pdb files }, String[] { id for each
2745 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
2746 // seqs_file 2}, boolean[] {
2747 // linkAlignPanel,superposeWithAlignpanel}} from hash
2748 Object[] jmoldat = jmolViewIds.get(sviewid);
2749 ((boolean[]) jmoldat[3])[0] |= ids[p].getStructureState(s)
2750 .hasAlignwithAlignPanel() ? ids[p].getStructureState(
2751 s).getAlignwithAlignPanel() : false;
2752 // never colour by linked panel if not specified
2753 ((boolean[]) jmoldat[3])[1] |= ids[p].getStructureState(s)
2754 .hasColourwithAlignPanel() ? ids[p]
2755 .getStructureState(s).getColourwithAlignPanel()
2757 // default for pre-2.7 projects is that Jmol colouring is enabled
2758 ((boolean[]) jmoldat[3])[2] &= ids[p].getStructureState(s)
2759 .hasColourByJmol() ? ids[p].getStructureState(s)
2760 .getColourByJmol() : true;
2762 if (((String) jmoldat[1]).length() < ids[p]
2763 .getStructureState(s).getContent().length())
2766 jmoldat[1] = ids[p].getStructureState(s).getContent();
2769 if (ids[p].getFile() != null)
2771 File mapkey = new File(ids[p].getFile());
2772 Object[] seqstrmaps = (Object[]) ((Hashtable) jmoldat[2])
2774 if (seqstrmaps == null)
2776 ((Hashtable) jmoldat[2]).put(mapkey,
2777 seqstrmaps = new Object[]
2778 { pdbFile, ids[p].getId(), new Vector(),
2781 if (!((Vector) seqstrmaps[2]).contains(seq))
2783 ((Vector) seqstrmaps[2]).addElement(seq);
2784 // ((Vector)seqstrmaps[3]).addElement(n) :
2785 // in principle, chains
2786 // should be stored here : do we need to
2787 // TODO: store and recover seq/pdb_id :
2793 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");
2802 // Instantiate the associated Jmol views
2803 for (Entry<String, Object[]> entry : jmolViewIds.entrySet())
2805 String sviewid = entry.getKey();
2806 Object[] svattrib = entry.getValue();
2807 int[] geom = (int[]) svattrib[0];
2808 String state = (String) svattrib[1];
2809 Hashtable<File, Object[]> oldFiles = (Hashtable<File, Object[]>) svattrib[2];
2810 final boolean useinJmolsuperpos = ((boolean[]) svattrib[3])[0], usetoColourbyseq = ((boolean[]) svattrib[3])[1], jmolColouring = ((boolean[]) svattrib[3])[2];
2811 int x = geom[0], y = geom[1], width = geom[2], height = geom[3];
2812 // collate the pdbfile -> sequence mappings from this view
2813 Vector<String> pdbfilenames = new Vector<String>();
2814 Vector<SequenceI[]> seqmaps = new Vector<SequenceI[]>();
2815 Vector<String> pdbids = new Vector<String>();
2817 // Search to see if we've already created this Jmol view
2818 AppJmol comp = null;
2819 JInternalFrame[] frames = null;
2824 frames = Desktop.desktop.getAllFrames();
2825 } catch (ArrayIndexOutOfBoundsException e)
2827 // occasional No such child exceptions are thrown here...
2832 } catch (Exception f)
2837 } while (frames == null);
2838 // search for any Jmol windows already open from other
2839 // alignment views that exactly match the stored structure state
2840 for (int f = 0; comp == null && f < frames.length; f++)
2842 if (frames[f] instanceof AppJmol)
2845 && ((AppJmol) frames[f]).getViewId().equals(sviewid))
2847 // post jalview 2.4 schema includes structure view id
2848 comp = (AppJmol) frames[f];
2850 else if (frames[f].getX() == x && frames[f].getY() == y
2851 && frames[f].getHeight() == height
2852 && frames[f].getWidth() == width)
2854 comp = (AppJmol) frames[f];
2861 // create a new Jmol window.
2862 // First parse the Jmol state to translate filenames loaded into the
2863 // view, and record the order in which files are shown in the Jmol
2864 // view, so we can add the sequence mappings in same order.
2865 StringBuffer newFileLoc = null;
2866 int cp = 0, ncp, ecp;
2867 while ((ncp = state.indexOf("load ", cp)) > -1)
2869 if (newFileLoc == null)
2871 newFileLoc = new StringBuffer();
2875 // look for next filename in load statement
2876 newFileLoc.append(state.substring(cp,
2877 ncp = (state.indexOf("\"", ncp + 1) + 1)));
2878 String oldfilenam = state.substring(ncp,
2879 ecp = state.indexOf("\"", ncp));
2880 // recover the new mapping data for this old filename
2881 // have to normalize filename - since Jmol and jalview do
2883 // translation differently.
2884 Object[] filedat = oldFiles.get(new File(oldfilenam));
2885 newFileLoc.append(Platform
2886 .escapeString((String) filedat[0]));
2887 pdbfilenames.addElement((String) filedat[0]);
2888 pdbids.addElement((String) filedat[1]);
2889 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
2890 .toArray(new SequenceI[0]));
2891 newFileLoc.append("\"");
2892 cp = ecp + 1; // advance beyond last \" and set cursor so we can
2893 // look for next file statement.
2894 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
2898 // just append rest of state
2899 newFileLoc.append(state.substring(cp));
2904 .print("Ignoring incomplete Jmol state for PDB ids: ");
2905 newFileLoc = new StringBuffer(state);
2906 newFileLoc.append("; load append ");
2907 for (File id : oldFiles.keySet())
2909 // add this and any other pdb files that should be present in
2911 Object[] filedat = oldFiles.get(id);
2913 newFileLoc.append(((String) filedat[0]));
2914 pdbfilenames.addElement((String) filedat[0]);
2915 pdbids.addElement((String) filedat[1]);
2916 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
2917 .toArray(new SequenceI[0]));
2918 newFileLoc.append(" \"");
2919 newFileLoc.append((String) filedat[0]);
2920 newFileLoc.append("\"");
2923 newFileLoc.append(";");
2926 if (newFileLoc != null)
2928 int histbug = newFileLoc.indexOf("history = ");
2930 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";",
2932 String val = (diff == -1) ? null : newFileLoc.substring(
2934 if (val != null && val.length() >= 4)
2936 if (val.contains("e"))
2938 if (val.trim().equals("true"))
2946 newFileLoc.replace(histbug, diff, val);
2949 // TODO: assemble String[] { pdb files }, String[] { id for each
2950 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
2951 // seqs_file 2}} from hash
2952 final String[] pdbf = pdbfilenames
2953 .toArray(new String[pdbfilenames.size()]), id = pdbids
2954 .toArray(new String[pdbids.size()]);
2955 final SequenceI[][] sq = seqmaps
2956 .toArray(new SequenceI[seqmaps.size()][]);
2957 final String fileloc = newFileLoc.toString(), vid = sviewid;
2958 final AlignFrame alf = af;
2959 final java.awt.Rectangle rect = new java.awt.Rectangle(x, y,
2963 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
2968 AppJmol sview = null;
2971 sview = new AppJmol(pdbf, id, sq, alf.alignPanel,
2972 useinJmolsuperpos, usetoColourbyseq,
2973 jmolColouring, fileloc, rect, vid);
2974 addNewStructureViewer(sview);
2975 } catch (OutOfMemoryError ex)
2977 new OOMWarning("restoring structure view for PDB id "
2978 + id, (OutOfMemoryError) ex.getCause());
2979 if (sview != null && sview.isVisible())
2981 sview.closeViewer();
2982 sview.setVisible(false);
2988 } catch (InvocationTargetException ex)
2990 warn("Unexpected error when opening Jmol view.", ex);
2992 } catch (InterruptedException e)
2994 // e.printStackTrace();
3000 // if (comp != null)
3002 // NOTE: if the jalview project is part of a shared session then
3003 // view synchronization should/could be done here.
3005 // add mapping for sequences in this view to an already open Jmol
3007 for (File id : oldFiles.keySet())
3009 // add this and any other pdb files that should be present in the
3011 Object[] filedat = oldFiles.get(id);
3012 String pdbFile = (String) filedat[0];
3013 SequenceI[] seq = ((Vector<SequenceI>) filedat[2])
3014 .toArray(new SequenceI[0]);
3015 comp.jmb.ssm.setMapping(seq, null, pdbFile,
3016 jalview.io.AppletFormatAdapter.FILE);
3017 comp.jmb.addSequenceForStructFile(pdbFile, seq);
3019 // and add the AlignmentPanel's reference to the Jmol view
3020 comp.addAlignmentPanel(ap);
3021 if (useinJmolsuperpos)
3023 comp.useAlignmentPanelForSuperposition(ap);
3027 comp.excludeAlignmentPanelForSuperposition(ap);
3029 if (usetoColourbyseq)
3031 comp.useAlignmentPanelForColourbyseq(ap, !jmolColouring);
3035 comp.excludeAlignmentPanelForColourbyseq(ap);
3041 // and finally return.
3044 Vector<AppJmol> newStructureViewers=null;
3045 protected void addNewStructureViewer(AppJmol sview)
3047 if (newStructureViewers!=null)
3049 sview.jmb.setFinishedLoadingFromArchive(false);
3050 newStructureViewers.add(sview);
3053 protected void setLoadingFinishedForNewStructureViewers()
3055 if (newStructureViewers!=null)
3057 for (AppJmol sview:newStructureViewers)
3059 sview.jmb.setFinishedLoadingFromArchive(true);
3061 newStructureViewers.clear();
3062 newStructureViewers=null;
3066 AlignFrame loadViewport(String file, JSeq[] JSEQ, Vector hiddenSeqs,
3067 Alignment al, JalviewModelSequence jms, Viewport view,
3068 String uniqueSeqSetId, String viewId,
3069 ArrayList<JvAnnotRow> autoAlan)
3071 AlignFrame af = null;
3072 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
3073 uniqueSeqSetId, viewId);
3075 af.setFileName(file, "Jalview");
3077 for (int i = 0; i < JSEQ.length; i++)
3079 af.viewport.setSequenceColour(af.viewport.getAlignment()
3080 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
3083 af.viewport.gatherViewsHere = view.getGatheredViews();
3085 if (view.getSequenceSetId() != null)
3087 jalview.gui.AlignViewport av = (jalview.gui.AlignViewport) viewportsAdded
3088 .get(uniqueSeqSetId);
3090 af.viewport.setSequenceSetId(uniqueSeqSetId);
3093 // propagate shared settings to this new view
3094 af.viewport.historyList = av.historyList;
3095 af.viewport.redoList = av.redoList;
3099 viewportsAdded.put(uniqueSeqSetId, af.viewport);
3101 // TODO: check if this method can be called repeatedly without
3102 // side-effects if alignpanel already registered.
3103 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
3105 // apply Hidden regions to view.
3106 if (hiddenSeqs != null)
3108 for (int s = 0; s < JSEQ.length; s++)
3110 jalview.datamodel.SequenceGroup hidden = new jalview.datamodel.SequenceGroup();
3112 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
3115 al.getSequenceAt(JSEQ[s].getHiddenSequences(r)), false);
3117 af.viewport.hideRepSequences(al.getSequenceAt(s), hidden);
3120 jalview.datamodel.SequenceI[] hseqs = new jalview.datamodel.SequenceI[hiddenSeqs
3123 for (int s = 0; s < hiddenSeqs.size(); s++)
3125 hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s);
3128 af.viewport.hideSequence(hseqs);
3131 // recover view properties and display parameters
3132 if (view.getViewName() != null)
3134 af.viewport.viewName = view.getViewName();
3135 af.setInitialTabVisible();
3137 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
3140 af.viewport.setShowAnnotation(view.getShowAnnotation());
3141 af.viewport.setAbovePIDThreshold(view.getPidSelected());
3143 af.viewport.setColourText(view.getShowColourText());
3145 af.viewport.setConservationSelected(view.getConservationSelected());
3146 af.viewport.setShowJVSuffix(view.getShowFullId());
3147 af.viewport.rightAlignIds = view.getRightAlignIds();
3148 af.viewport.setFont(new java.awt.Font(view.getFontName(), view
3149 .getFontStyle(), view.getFontSize()));
3150 af.alignPanel.fontChanged();
3151 af.viewport.setRenderGaps(view.getRenderGaps());
3152 af.viewport.setWrapAlignment(view.getWrapAlignment());
3153 af.alignPanel.setWrapAlignment(view.getWrapAlignment());
3154 af.viewport.setShowAnnotation(view.getShowAnnotation());
3155 af.alignPanel.setAnnotationVisible(view.getShowAnnotation());
3157 af.viewport.setShowBoxes(view.getShowBoxes());
3159 af.viewport.setShowText(view.getShowText());
3161 af.viewport.textColour = new java.awt.Color(view.getTextCol1());
3162 af.viewport.textColour2 = new java.awt.Color(view.getTextCol2());
3163 af.viewport.thresholdTextColour = view.getTextColThreshold();
3164 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
3165 .isShowUnconserved() : false);
3166 af.viewport.setStartRes(view.getStartRes());
3167 af.viewport.setStartSeq(view.getStartSeq());
3169 ColourSchemeI cs = null;
3170 // apply colourschemes
3171 if (view.getBgColour() != null)
3173 if (view.getBgColour().startsWith("ucs"))
3175 cs = GetUserColourScheme(jms, view.getBgColour());
3177 else if (view.getBgColour().startsWith("Annotation"))
3179 // int find annotation
3180 if (af.viewport.getAlignment().getAlignmentAnnotation() != null)
3182 for (int i = 0; i < af.viewport.getAlignment()
3183 .getAlignmentAnnotation().length; i++)
3185 if (af.viewport.getAlignment().getAlignmentAnnotation()[i].label
3186 .equals(view.getAnnotationColours().getAnnotation()))
3188 if (af.viewport.getAlignment().getAlignmentAnnotation()[i]
3189 .getThreshold() == null)
3191 af.viewport.getAlignment().getAlignmentAnnotation()[i]
3192 .setThreshold(new jalview.datamodel.GraphLine(view
3193 .getAnnotationColours().getThreshold(),
3194 "Threshold", java.awt.Color.black)
3199 if (view.getAnnotationColours().getColourScheme()
3202 cs = new AnnotationColourGradient(af.viewport
3203 .getAlignment().getAlignmentAnnotation()[i],
3204 new java.awt.Color(view.getAnnotationColours()
3205 .getMinColour()), new java.awt.Color(view
3206 .getAnnotationColours().getMaxColour()),
3207 view.getAnnotationColours().getAboveThreshold());
3209 else if (view.getAnnotationColours().getColourScheme()
3212 cs = new AnnotationColourGradient(af.viewport
3213 .getAlignment().getAlignmentAnnotation()[i],
3214 GetUserColourScheme(jms, view
3215 .getAnnotationColours().getColourScheme()),
3216 view.getAnnotationColours().getAboveThreshold());
3220 cs = new AnnotationColourGradient(af.viewport
3221 .getAlignment().getAlignmentAnnotation()[i],
3222 ColourSchemeProperty.getColour(al, view
3223 .getAnnotationColours().getColourScheme()),
3224 view.getAnnotationColours().getAboveThreshold());
3227 // Also use these settings for all the groups
3228 if (al.getGroups() != null)
3230 for (int g = 0; g < al.getGroups().size(); g++)
3232 jalview.datamodel.SequenceGroup sg = al.getGroups()
3242 * (view.getAnnotationColours().getColourScheme().equals("None"
3243 * )) { sg.cs = new AnnotationColourGradient(
3244 * af.viewport.getAlignment().getAlignmentAnnotation()[i], new
3245 * java.awt.Color(view.getAnnotationColours().
3246 * getMinColour()), new
3247 * java.awt.Color(view.getAnnotationColours().
3249 * view.getAnnotationColours().getAboveThreshold()); } else
3252 sg.cs = new AnnotationColourGradient(af.viewport
3253 .getAlignment().getAlignmentAnnotation()[i],
3254 sg.cs, view.getAnnotationColours()
3255 .getAboveThreshold());
3269 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
3274 cs.setThreshold(view.getPidThreshold(), true);
3275 cs.setConsensus(af.viewport.getSequenceConsensusHash());
3279 af.viewport.setGlobalColourScheme(cs);
3280 af.viewport.setColourAppliesToAllGroups(false);
3282 if (view.getConservationSelected() && cs != null)
3284 cs.setConservationInc(view.getConsThreshold());
3287 af.changeColour(cs);
3289 af.viewport.setColourAppliesToAllGroups(true);
3291 if (view.getShowSequenceFeatures())
3293 af.viewport.showSequenceFeatures = true;
3295 if (view.hasCentreColumnLabels())
3297 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
3299 if (view.hasIgnoreGapsinConsensus())
3301 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
3304 if (view.hasFollowHighlight())
3306 af.viewport.followHighlight = view.getFollowHighlight();
3308 if (view.hasFollowSelection())
3310 af.viewport.followSelection = view.getFollowSelection();
3312 if (view.hasShowConsensusHistogram())
3314 af.viewport.setShowConsensusHistogram(view
3315 .getShowConsensusHistogram());
3319 af.viewport.setShowConsensusHistogram(true);
3321 if (view.hasShowSequenceLogo())
3323 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
3327 af.viewport.setShowSequenceLogo(false);
3329 if (view.hasNormaliseSequenceLogo())
3331 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
3333 if (view.hasShowDbRefTooltip())
3335 af.viewport.setShowDbRefs(view.getShowDbRefTooltip());
3337 if (view.hasShowNPfeatureTooltip())
3339 af.viewport.setShowNpFeats(view.hasShowNPfeatureTooltip());
3341 if (view.hasShowGroupConsensus())
3343 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
3347 af.viewport.setShowGroupConsensus(false);
3349 if (view.hasShowGroupConservation())
3351 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
3355 af.viewport.setShowGroupConservation(false);
3358 // recover featre settings
3359 if (jms.getFeatureSettings() != null)
3361 af.viewport.featuresDisplayed = new Hashtable();
3362 String[] renderOrder = new String[jms.getFeatureSettings()
3363 .getSettingCount()];
3364 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
3366 Setting setting = jms.getFeatureSettings().getSetting(fs);
3367 if (setting.hasMincolour())
3369 GraduatedColor gc = setting.hasMin() ? new GraduatedColor(
3370 new java.awt.Color(setting.getMincolour()),
3371 new java.awt.Color(setting.getColour()),
3372 setting.getMin(), setting.getMax()) : new GraduatedColor(
3373 new java.awt.Color(setting.getMincolour()),
3374 new java.awt.Color(setting.getColour()), 0, 1);
3375 if (setting.hasThreshold())
3377 gc.setThresh(setting.getThreshold());
3378 gc.setThreshType(setting.getThreshstate());
3380 gc.setAutoScaled(true); // default
3381 if (setting.hasAutoScale())
3383 gc.setAutoScaled(setting.getAutoScale());
3385 if (setting.hasColourByLabel())
3387 gc.setColourByLabel(setting.getColourByLabel());
3389 // and put in the feature colour table.
3390 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3391 setting.getType(), gc);
3395 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3397 new java.awt.Color(setting.getColour()));
3399 renderOrder[fs] = setting.getType();
3400 if (setting.hasOrder())
3401 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3402 setting.getType(), setting.getOrder());
3404 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3406 fs / jms.getFeatureSettings().getSettingCount());
3407 if (setting.getDisplay())
3409 af.viewport.featuresDisplayed.put(setting.getType(), new Integer(
3410 setting.getColour()));
3413 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().renderOrder = renderOrder;
3415 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().featureGroups = fgtable = new Hashtable();
3416 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
3418 Group grp = jms.getFeatureSettings().getGroup(gs);
3419 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
3423 if (view.getHiddenColumnsCount() > 0)
3425 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
3427 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
3428 .getHiddenColumns(c).getEnd() // +1
3432 if (view.getCalcIdParam() != null)
3434 for (CalcIdParam calcIdParam : view.getCalcIdParam())
3436 if (calcIdParam != null)
3438 if (recoverCalcIdParam(calcIdParam, af.viewport))
3443 warn("Couldn't recover parameters for "
3444 + calcIdParam.getCalcId());
3449 af.setMenusFromViewport(af.viewport);
3450 // TODO: we don't need to do this if the viewport is aready visible.
3451 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
3453 af.alignPanel.updateAnnotation(false, true); // recompute any autoannotation
3454 reorderAutoannotation(af, al, autoAlan);
3458 private void reorderAutoannotation(AlignFrame af, Alignment al,
3459 ArrayList<JvAnnotRow> autoAlan)
3461 // copy over visualization settings for autocalculated annotation in the
3463 if (al.getAlignmentAnnotation() != null)
3466 * Kludge for magic autoannotation names (see JAL-811)
3468 String[] magicNames = new String[]
3469 { "Consensus", "Quality", "Conservation" };
3470 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
3471 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
3472 for (String nm : magicNames)
3474 visan.put(nm, nullAnnot);
3476 for (JvAnnotRow auan : autoAlan)
3478 visan.put(auan.template.label
3479 + (auan.template.getCalcId() == null ? "" : "\t"
3480 + auan.template.getCalcId()), auan);
3482 int hSize = al.getAlignmentAnnotation().length;
3483 ArrayList<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
3484 // work through any autoCalculated annotation already on the view
3485 // removing it if it should be placed in a different location on the
3486 // annotation panel.
3487 List<String> remains = new ArrayList(visan.keySet());
3488 for (int h = 0; h < hSize; h++)
3490 jalview.datamodel.AlignmentAnnotation jalan = al
3491 .getAlignmentAnnotation()[h];
3492 if (jalan.autoCalculated)
3495 JvAnnotRow valan = visan.get(k = jalan.label);
3496 if (jalan.getCalcId() != null)
3498 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
3503 // delete the auto calculated row from the alignment
3504 al.deleteAnnotation(jalan, false);
3508 if (valan != nullAnnot)
3510 if (jalan != valan.template)
3512 // newly created autoannotation row instance
3513 // so keep a reference to the visible annotation row
3514 // and copy over all relevant attributes
3515 if (valan.template.graphHeight >= 0)
3518 jalan.graphHeight = valan.template.graphHeight;
3520 jalan.visible = valan.template.visible;
3522 reorder.add(new JvAnnotRow(valan.order, jalan));
3527 // Add any (possibly stale) autocalculated rows that were not appended to
3528 // the view during construction
3529 for (String other : remains)
3531 JvAnnotRow othera = visan.get(other);
3532 if (othera != nullAnnot && othera.template.getCalcId() != null
3533 && othera.template.getCalcId().length() > 0)
3535 reorder.add(othera);
3538 // now put the automatic annotation in its correct place
3539 int s = 0, srt[] = new int[reorder.size()];
3540 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
3541 for (JvAnnotRow jvar : reorder)
3544 srt[s++] = jvar.order;
3547 jalview.util.QuickSort.sort(srt, rws);
3548 // and re-insert the annotation at its correct position
3549 for (JvAnnotRow jvar : rws)
3551 al.addAnnotation(jvar.template, jvar.order);
3553 af.alignPanel.adjustAnnotationHeight();
3557 Hashtable skipList = null;
3560 * TODO remove this method
3563 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
3564 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
3565 * throw new Error("Implementation Error. No skipList defined for this
3566 * Jalview2XML instance."); } return (AlignFrame)
3567 * skipList.get(view.getSequenceSetId()); }
3571 * Check if the Jalview view contained in object should be skipped or not.
3574 * @return true if view's sequenceSetId is a key in skipList
3576 private boolean skipViewport(JalviewModel object)
3578 if (skipList == null)
3583 if (skipList.containsKey(id = object.getJalviewModelSequence()
3584 .getViewport()[0].getSequenceSetId()))
3586 if (Cache.log != null && Cache.log.isDebugEnabled())
3588 Cache.log.debug("Skipping seuqence set id " + id);
3595 public void AddToSkipList(AlignFrame af)
3597 if (skipList == null)
3599 skipList = new Hashtable();
3601 skipList.put(af.getViewport().getSequenceSetId(), af);
3604 public void clearSkipList()
3606 if (skipList != null)
3613 private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al)
3615 jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId());
3616 Vector dseqs = null;
3619 // create a list of new dataset sequences
3620 dseqs = new Vector();
3622 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
3624 Sequence vamsasSeq = vamsasSet.getSequence(i);
3625 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs);
3627 // create a new dataset
3630 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
3631 dseqs.copyInto(dsseqs);
3632 ds = new jalview.datamodel.Alignment(dsseqs);
3633 debug("Created new dataset " + vamsasSet.getDatasetId()
3634 + " for alignment " + System.identityHashCode(al));
3635 addDatasetRef(vamsasSet.getDatasetId(), ds);
3637 // set the dataset for the newly imported alignment.
3638 if (al.getDataset() == null)
3647 * sequence definition to create/merge dataset sequence for
3651 * vector to add new dataset sequence to
3653 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
3654 AlignmentI ds, Vector dseqs)
3656 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
3658 jalview.datamodel.Sequence sq = (jalview.datamodel.Sequence) seqRefIds
3659 .get(vamsasSeq.getId());
3660 jalview.datamodel.SequenceI dsq = null;
3661 if (sq != null && sq.getDatasetSequence() != null)
3663 dsq = sq.getDatasetSequence();
3666 String sqid = vamsasSeq.getDsseqid();
3669 // need to create or add a new dataset sequence reference to this sequence
3672 dsq = (jalview.datamodel.SequenceI) seqRefIds.get(sqid);
3677 // make a new dataset sequence
3678 dsq = sq.createDatasetSequence();
3681 // make up a new dataset reference for this sequence
3682 sqid = seqHash(dsq);
3684 dsq.setVamsasId(uniqueSetSuffix + sqid);
3685 seqRefIds.put(sqid, dsq);
3690 dseqs.addElement(dsq);
3695 ds.addSequence(dsq);
3701 { // make this dataset sequence sq's dataset sequence
3702 sq.setDatasetSequence(dsq);
3706 // TODO: refactor this as a merge dataset sequence function
3707 // now check that sq (the dataset sequence) sequence really is the union of
3708 // all references to it
3709 // boolean pre = sq.getStart() < dsq.getStart();
3710 // boolean post = sq.getEnd() > dsq.getEnd();
3714 StringBuffer sb = new StringBuffer();
3715 String newres = jalview.analysis.AlignSeq.extractGaps(
3716 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
3717 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
3718 && newres.length() > dsq.getLength())
3720 // Update with the longer sequence.
3724 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
3725 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
3726 * sb.append(newres.substring(newres.length() - sq.getEnd() -
3727 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
3729 dsq.setSequence(sb.toString());
3731 // TODO: merges will never happen if we 'know' we have the real dataset
3732 // sequence - this should be detected when id==dssid
3733 System.err.println("DEBUG Notice: Merged dataset sequence"); // ("
3734 // + (pre ? "prepended" : "") + " "
3735 // + (post ? "appended" : ""));
3740 java.util.Hashtable datasetIds = null;
3742 java.util.IdentityHashMap dataset2Ids = null;
3744 private Alignment getDatasetFor(String datasetId)
3746 if (datasetIds == null)
3748 datasetIds = new Hashtable();
3751 if (datasetIds.containsKey(datasetId))
3753 return (Alignment) datasetIds.get(datasetId);
3758 private void addDatasetRef(String datasetId, Alignment dataset)
3760 if (datasetIds == null)
3762 datasetIds = new Hashtable();
3764 datasetIds.put(datasetId, dataset);
3768 * make a new dataset ID for this jalview dataset alignment
3773 private String getDatasetIdRef(jalview.datamodel.Alignment dataset)
3775 if (dataset.getDataset() != null)
3777 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
3779 String datasetId = makeHashCode(dataset, null);
3780 if (datasetId == null)
3782 // make a new datasetId and record it
3783 if (dataset2Ids == null)
3785 dataset2Ids = new IdentityHashMap();
3789 datasetId = (String) dataset2Ids.get(dataset);
3791 if (datasetId == null)
3793 datasetId = "ds" + dataset2Ids.size() + 1;
3794 dataset2Ids.put(dataset, datasetId);
3800 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
3802 for (int d = 0; d < sequence.getDBRefCount(); d++)
3804 DBRef dr = sequence.getDBRef(d);
3805 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
3806 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
3807 .getVersion(), sequence.getDBRef(d).getAccessionId());
3808 if (dr.getMapping() != null)
3810 entry.setMap(addMapping(dr.getMapping()));
3812 datasetSequence.addDBRef(entry);
3816 private jalview.datamodel.Mapping addMapping(Mapping m)
3818 SequenceI dsto = null;
3819 // Mapping m = dr.getMapping();
3820 int fr[] = new int[m.getMapListFromCount() * 2];
3821 Enumeration f = m.enumerateMapListFrom();
3822 for (int _i = 0; f.hasMoreElements(); _i += 2)
3824 MapListFrom mf = (MapListFrom) f.nextElement();
3825 fr[_i] = mf.getStart();
3826 fr[_i + 1] = mf.getEnd();
3828 int fto[] = new int[m.getMapListToCount() * 2];
3829 f = m.enumerateMapListTo();
3830 for (int _i = 0; f.hasMoreElements(); _i += 2)
3832 MapListTo mf = (MapListTo) f.nextElement();
3833 fto[_i] = mf.getStart();
3834 fto[_i + 1] = mf.getEnd();
3836 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
3837 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
3838 if (m.getMappingChoice() != null)
3840 MappingChoice mc = m.getMappingChoice();
3841 if (mc.getDseqFor() != null)
3843 String dsfor = "" + mc.getDseqFor();
3844 if (seqRefIds.containsKey(dsfor))
3849 jmap.setTo((SequenceI) seqRefIds.get(dsfor));
3853 frefedSequence.add(new Object[]
3860 * local sequence definition
3862 Sequence ms = mc.getSequence();
3863 jalview.datamodel.Sequence djs = null;
3864 String sqid = ms.getDsseqid();
3865 if (sqid != null && sqid.length() > 0)
3868 * recover dataset sequence
3870 djs = (jalview.datamodel.Sequence) seqRefIds.get(sqid);
3875 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
3876 sqid = ((Object) ms).toString(); // make up a new hascode for
3877 // undefined dataset sequence hash
3878 // (unlikely to happen)
3884 * make a new dataset sequence and add it to refIds hash
3886 djs = new jalview.datamodel.Sequence(ms.getName(),
3888 djs.setStart(jmap.getMap().getToLowest());
3889 djs.setEnd(jmap.getMap().getToHighest());
3890 djs.setVamsasId(uniqueSetSuffix + sqid);
3892 seqRefIds.put(sqid, djs);
3895 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
3904 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
3905 boolean keepSeqRefs)
3908 jalview.schemabinding.version2.JalviewModel jm = SaveState(ap, null,
3914 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
3918 uniqueSetSuffix = "";
3919 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
3924 if (this.frefedSequence == null)
3926 frefedSequence = new Vector();
3929 viewportsAdded = new Hashtable();
3931 AlignFrame af = LoadFromObject(jm, null, false, null);
3932 af.alignPanels.clear();
3933 af.closeMenuItem_actionPerformed(true);
3936 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
3937 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
3938 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
3939 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
3940 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
3943 return af.alignPanel;
3947 * flag indicating if hashtables should be cleared on finalization TODO this
3948 * flag may not be necessary
3950 private final boolean _cleartables = true;
3952 private Hashtable jvids2vobj;
3957 * @see java.lang.Object#finalize()
3960 protected void finalize() throws Throwable
3962 // really make sure we have no buried refs left.
3967 this.seqRefIds = null;
3968 this.seqsToIds = null;
3972 private void warn(String msg)
3977 private void warn(String msg, Exception e)
3979 if (Cache.log != null)
3983 Cache.log.warn(msg, e);
3987 Cache.log.warn(msg);
3992 System.err.println("Warning: " + msg);
3995 e.printStackTrace();
4000 private void debug(String string)
4002 debug(string, null);
4005 private void debug(String msg, Exception e)
4007 if (Cache.log != null)
4011 Cache.log.debug(msg, e);
4015 Cache.log.debug(msg);
4020 System.err.println("Warning: " + msg);
4023 e.printStackTrace();
4029 * set the object to ID mapping tables used to write/recover objects and XML
4030 * ID strings for the jalview project. If external tables are provided then
4031 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
4032 * object goes out of scope. - also populates the datasetIds hashtable with
4033 * alignment objects containing dataset sequences
4036 * Map from ID strings to jalview datamodel
4038 * Map from jalview datamodel to ID strings
4042 public void setObjectMappingTables(Hashtable vobj2jv,
4043 IdentityHashMap jv2vobj)
4045 this.jv2vobj = jv2vobj;
4046 this.vobj2jv = vobj2jv;
4047 Iterator ds = jv2vobj.keySet().iterator();
4049 while (ds.hasNext())
4051 Object jvobj = ds.next();
4052 id = jv2vobj.get(jvobj).toString();
4053 if (jvobj instanceof jalview.datamodel.Alignment)
4055 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
4057 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
4060 else if (jvobj instanceof jalview.datamodel.Sequence)
4062 // register sequence object so the XML parser can recover it.
4063 if (seqRefIds == null)
4065 seqRefIds = new Hashtable();
4067 if (seqsToIds == null)
4069 seqsToIds = new IdentityHashMap();
4071 seqRefIds.put(jv2vobj.get(jvobj).toString(), jvobj);
4072 seqsToIds.put(jvobj, id);
4074 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
4076 if (annotationIds == null)
4078 annotationIds = new Hashtable();
4081 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvobj);
4082 jalview.datamodel.AlignmentAnnotation jvann = (jalview.datamodel.AlignmentAnnotation) jvobj;
4083 if (jvann.annotationId == null)
4085 jvann.annotationId = anid;
4087 if (!jvann.annotationId.equals(anid))
4089 // TODO verify that this is the correct behaviour
4090 this.warn("Overriding Annotation ID for " + anid
4091 + " from different id : " + jvann.annotationId);
4092 jvann.annotationId = anid;
4095 else if (jvobj instanceof String)
4097 if (jvids2vobj == null)
4099 jvids2vobj = new Hashtable();
4100 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
4104 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
4109 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
4110 * objects created from the project archive. If string is null (default for
4111 * construction) then suffix will be set automatically.
4115 public void setUniqueSetSuffix(String string)
4117 uniqueSetSuffix = string;
4122 * uses skipList2 as the skipList for skipping views on sequence sets
4123 * associated with keys in the skipList
4127 public void setSkipList(Hashtable skipList2)
4129 skipList = skipList2;