import jalview.gui.AlignViewport;
import jalview.gui.Desktop;
import jalview.gui.TreePanel;
+import jalview.io.vamsas.DatastoreItem;
+import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.IdentityHashMap;
public class VamsasAppDatastore
{
- Entry provEntry = null;
+ public static final String JALVIEW_ANNOTATION_ROW = "jalview:AnnotationRow";
- // AlignViewport av;
+ public static final String JALVIEW_GRAPH_TYPE = "jalview:graphType";
- org.exolab.castor.types.Date date = new org.exolab.castor.types.Date(
- new java.util.Date());
+ Entry provEntry = null;
IClientDocument cdoc;
this.jv2vobj = jv2vobj;
this.provEntry = provEntry;
}
-
- /*
- * public void storeJalview(String file, AlignFrame af) { try { // 1. Load the
- * mapping information from the file Mapping map = new
- * Mapping(getClass().getClassLoader()); java.net.URL url =
- * getClass().getResource("/jalview_mapping.xml"); map.loadMapping(url); // 2.
- * Unmarshal the data // Unmarshaller unmar = new Unmarshaller();
- * //unmar.setIgnoreExtraElements(true); //unmar.setMapping(map); // uni =
- * (UniprotFile) unmar.unmarshal(new FileReader(file)); // 3. marshal the data
- * with the total price back and print the XML in the console Marshaller
- * marshaller = new Marshaller( new FileWriter(file) );
- *
- * marshaller.setMapping(map); marshaller.marshal(af); } catch (Exception e) {
- * e.printStackTrace(); } }
- *
- *
- */
/**
* @return the Vobject bound to Jalview datamodel object
*/
}
if (aa[i].sequenceRef != null)
{
- uk.ac.vamsas.objects.core.AlignmentSequence alsref = (uk.ac.vamsas.
- objects.core.AlignmentSequence) getjv2vObj(aa[i].sequenceRef);
- uk.ac.vamsas.objects.core.AlignmentSequenceAnnotation an = (uk.ac.
- vamsas.objects.core.AlignmentSequenceAnnotation) getjv2vObj(aa[
- i]);
- int[] gapMap = null;
- if (AlSeqMaps.containsKey(aa[i].sequenceRef))
- {
- gapMap = (int[]) AlSeqMaps.get(aa[i].sequenceRef);
- }
- else
+ // Deal with sequence associated annotation
+ Vobject sref = getjv2vObj(aa[i].sequenceRef);
+ if (sref instanceof uk.ac.vamsas.objects.core.AlignmentSequence)
{
- gapMap = new int[aa[i].sequenceRef.getLength()];
- // map from alignment position to sequence position.
- int[] sgapMap = aa[i].sequenceRef.gapMap();
- for (int a = 0; a < sgapMap.length; a++)
- {
- gapMap[sgapMap[a]] = a;
- }
- }
- if (an == null)
+ saveAlignmentSequenceAnnotation(AlSeqMaps, (AlignmentSequence) sref, aa[i]);
+ } else
{
- an = new uk.ac.vamsas.objects.core.AlignmentSequenceAnnotation();
- Seg vSeg = new Seg();
- vSeg.setStart(1);
- vSeg.setInclusive(true);
- vSeg.setEnd(gapMap.length);
- an.addSeg(vSeg);
- an.setType("jalview:SecondaryStructurePrediction"); // TODO: better fix this rough guess ;)
- alsref.addAlignmentSequenceAnnotation(an);
- bindjvvobj(aa[i], an);
- // LATER: much of this is verbatim from the alignmentAnnotation
- // method below. suggests refactoring to make rangeAnnotation the
- // base class
- an.setDescription(aa[i].description);
- if (aa[i].graph > 0)
+ // first find the alignment sequence to associate this with.
+ SequenceI jvalsq=null;
+ Enumeration jval = av.getAlignment().getSequences().elements();
+ while (jval.hasMoreElements())
{
- an.setGraph(true); // aa[i].graph);
- }
- else
- {
- an.setGraph(false);
- }
- an.setLabel(aa[i].label);
- an.setProvenance(dummyProvenance()); // get provenance as user
- // created, or jnet, or
- // something else.
- an.setGroup(Integer.toString(aa[i].graphGroup)); // // JBPNote -
- // originally we
- // were going to
- // store
- // graphGroup in
- // the Jalview
- // specific
- // bits.
- AnnotationElement ae;
- for (int a = 0; a < aa[i].annotations.length; a++)
- {
- if (aa[i].annotations[a] == null)
- {
- continue;
- }
-
- ae = new AnnotationElement();
- ae.setDescription(aa[i].annotations[a].description);
- ae.addGlyph(new Glyph());
- ae.getGlyph(0)
- .setContent(aa[i].annotations[a].displayCharacter); // assume
- // jax-b
- // takes
- // care
- // of
- // utf8
- // translation
- if (aa[i].graph !=
- jalview.datamodel.AlignmentAnnotation.NO_GRAPH)
+ jvalsq = (SequenceI) jval.nextElement();
+ //saveDatasetSequenceAnnotation(AlSeqMaps,(uk.ac.vamsas.objects.core.Sequence) sref, aa[i]);
+ if (jvalsq.getDatasetSequence() == aa[i].sequenceRef)
{
- ae.addValue(aa[i].annotations[a].value);
- }
- ae.setPosition(gapMap[a] + 1); // position w.r.t. AlignmentSequence
- // symbols
- if (aa[i].annotations[a].secondaryStructure != ' ')
- {
- // we only write an annotation where it really exists.
- Glyph ss = new Glyph();
- ss
- .setDict(uk.ac.vamsas.objects.utils.GlyphDictionary.
- PROTEIN_SS_3STATE);
- ss.setContent(String
- .valueOf(aa[i].annotations[a].
- secondaryStructure));
- ae.addGlyph(ss);
- }
- an.addAnnotationElement(ae);
- }
- }
- else
- {
- // update reference sequence Annotation
- if (an.getModifiable()==null) // TODO: USE VAMSAS LIBRARY OBJECT LOCK METHODS)
- {
- // verify existing alignment sequence annotation is up to date
- System.out.println("update alignment sequence annotation.");
- }
- else
- {
- // verify existing alignment sequence annotation is up to date
- System.out
- .println(
- "make new alignment sequence annotation if modification has happened.");
+ Vobject alsref = getjv2vObj(jvalsq);
+ saveAlignmentSequenceAnnotation(AlSeqMaps, (AlignmentSequence) alsref, aa[i]);
+ break;
+ };
}
}
}
if (an == null)
{
an = new uk.ac.vamsas.objects.core.AlignmentAnnotation();
- an.setType("jalview:AnnotationRow");
+ an.setType(JALVIEW_ANNOTATION_ROW);
an.setDescription(aa[i].description);
alignment.addAlignmentAnnotation(an);
- Seg vSeg = new Seg();
+ Seg vSeg = new Seg(); // TODO: refactor to have a default rangeAnnotationType initer/updater that takes a set of int ranges.
vSeg.setStart(1);
vSeg.setInclusive(true);
vSeg.setEnd(jal.getWidth());
}
an.setLabel(aa[i].label);
an.setProvenance(dummyProvenance());
- if (aa[i].graph != aa[i].NO_GRAPH)
+ if (aa[i].graph != AlignmentAnnotation.NO_GRAPH)
{
an.setGroup(Integer.toString(aa[i].graphGroup)); // // JBPNote -
// originally we
{
an.setGraph(true);
an.setGroup(Integer.toString(aa[i].graphGroup));
- an.addProperty(newProperty("jalview:graphType", null,
+ an.addProperty(newProperty(JALVIEW_GRAPH_TYPE, null,
( (aa[i].graph ==
jalview.datamodel.AlignmentAnnotation.
BAR_GRAPH) ? "BAR_GRAPH" :
if (tp.getAlignment() == jal)
{
- Tree tree = (Tree) getjv2vObj(tp);
- if (tree == null)
- {
- tree = new Tree();
- bindjvvobj(tp, tree);
- tree.setTitle(tp.getTitle());
- Newick newick = new Newick();
- // TODO: translate sequenceI to leaf mappings to vamsas
- // references - see tree specification in schema.
- newick.setContent(tp.getTree().toString());
- newick.setTitle(tp.getTitle());
- tree.addNewick(newick);
- tree.setProvenance(makeTreeProvenance(jal, tp));
- alignment.addTree(tree);
- }
- else
- {
- if (tree.getModifiable()==null) // TODO: USE VAMSAS LIBRARY OBJECT LOCK METHODS)
- {
- // verify any changes.
- System.out.println("Update tree in document.");
- }
- else
- {
- System.out
- .println("Add modified tree as new tree in document.");
- }
- }
+ DatastoreItem vtree = new jalview.io.vamsas.Tree(this, tp, jal, alignment);
}
}
}
}
}
+ private void initRangeAnnotationType(RangeAnnotation an, AlignmentAnnotation alan, int[] gapMap)
+ {
+ Seg vSeg = new Seg();
+ vSeg.setStart(1);
+ vSeg.setInclusive(true);
+ vSeg.setEnd(gapMap.length);
+ an.addSeg(vSeg);
+
+ // LATER: much of this is verbatim from the alignmentAnnotation
+ // method below. suggests refactoring to make rangeAnnotation the
+ // base class
+ an.setDescription(alan.description);
+ an.setLabel(alan.label);
+ an.setGroup(Integer.toString(alan.graphGroup));
+ // // JBPNote -
+ // originally we
+ // were going to
+ // store
+ // graphGroup in
+ // the Jalview
+ // specific
+ // bits.
+ AnnotationElement ae;
+ for (int a = 0; a < alan.annotations.length; a++)
+ {
+ if (alan.annotations[a] == null)
+ {
+ continue;
+ }
+
+ ae = new AnnotationElement();
+ ae.setDescription(alan.annotations[a].description);
+ ae.addGlyph(new Glyph());
+ ae.getGlyph(0)
+ .setContent(alan.annotations[a].displayCharacter); // assume
+ // jax-b
+ // takes
+ // care
+ // of
+ // utf8
+ // translation
+ if (alan.graph !=
+ jalview.datamodel.AlignmentAnnotation.NO_GRAPH)
+ {
+ ae.addValue(alan.annotations[a].value);
+ }
+ ae.setPosition(gapMap[a] + 1); // position w.r.t. AlignmentSequence
+ // symbols
+ if (alan.annotations[a].secondaryStructure != ' ')
+ {
+ // we only write an annotation where it really exists.
+ Glyph ss = new Glyph();
+ ss
+ .setDict(uk.ac.vamsas.objects.utils.GlyphDictionary.
+ PROTEIN_SS_3STATE);
+ ss.setContent(String
+ .valueOf(alan.annotations[a].
+ secondaryStructure));
+ ae.addGlyph(ss);
+ }
+ an.addAnnotationElement(ae);
+ }
+ }
+ private void saveDatasetSequenceAnnotation(HashMap AlSeqMaps, uk.ac.vamsas.objects.core.Sequence sref, AlignmentAnnotation alan)
+ {
+ //{
+ // uk.ac.vamsas.
+ // objects.core.AlignmentSequence alsref = (uk.ac.vamsas.
+ // objects.core.AlignmentSequence) sref;
+ uk.ac.vamsas.objects.core.DataSetAnnotations an = (uk.ac.
+ vamsas.objects.core.DataSetAnnotations) getjv2vObj(alan);
+ int[] gapMap = getGapMap(AlSeqMaps, alan);
+ if (an == null)
+ {
+ an = new uk.ac.vamsas.objects.core.DataSetAnnotations();
+ initRangeAnnotationType(an, alan, gapMap);
+ an.setProvenance(dummyProvenance()); // get provenance as user
+ // created, or jnet, or
+ // something else.
+ an.setType("jalview:SecondaryStructurePrediction"); // TODO: better fix this rough guess ;)
+ // The properties below don't fit into the DataSet Sequence Annotation as it currently is defined.
+ if (alan.graph > 0)
+ {
+ an.addProperty(newProperty("jalview:displayAsGraph", "boolean", "true"));
+ }
+ an.setGroup(Integer.toString(alan.graphGroup)); // // JBPNote -
+ // originally we
+ // were going to
+ // store
+ // graphGroup in
+ // the Jalview
+ // specific
+ // bits.
+ ((DataSet) sref.getV_parent()).addDataSetAnnotations(an);
+ bindjvvobj(alan, an);
+ }
+ else
+ {
+ // update reference sequence Annotation
+ if (an.getModifiable()==null) // TODO: USE VAMSAS LIBRARY OBJECT LOCK METHODS)
+ {
+ // verify existing alignment sequence annotation is up to date
+ System.out.println("update dataset sequence annotation.");
+ }
+ else
+ {
+ // verify existing alignment sequence annotation is up to date
+ System.out
+ .println(
+ "make new alignment dataset sequence annotation if modification has happened.");
+ }
+ }
+
+ }
+ private int[] getGapMap(HashMap AlSeqMaps, AlignmentAnnotation alan)
+ {
+ int[] gapMap;
+ if (AlSeqMaps.containsKey(alan.sequenceRef))
+ {
+ gapMap = (int[]) AlSeqMaps.get(alan.sequenceRef);
+ }
+ else
+ {
+ gapMap = new int[alan.sequenceRef.getLength()];
+ // map from alignment position to sequence position.
+ int[] sgapMap = alan.sequenceRef.gapMap();
+ for (int a = 0; a < sgapMap.length; a++)
+ {
+ gapMap[sgapMap[a]] = a;
+ }
+ }
+ return gapMap;
+ }
+
+ private void saveAlignmentSequenceAnnotation(HashMap AlSeqMaps, AlignmentSequence alsref, AlignmentAnnotation alan)
+ {
+ //{
+ // uk.ac.vamsas.
+ // objects.core.AlignmentSequence alsref = (uk.ac.vamsas.
+ // objects.core.AlignmentSequence) sref;
+ uk.ac.vamsas.objects.core.AlignmentSequenceAnnotation an = (uk.ac.
+ vamsas.objects.core.AlignmentSequenceAnnotation) getjv2vObj(alan);
+ int[] gapMap = getGapMap(AlSeqMaps, alan);
+ if (an == null)
+ {
+ an = new uk.ac.vamsas.objects.core.AlignmentSequenceAnnotation();
+ initRangeAnnotationType(an, alan, gapMap);
+ /**
+ * I mean here that we don't actually have a semantic 'type' for the annotation (this might be - score, intrinsic property, measurement, something extracted from another program, etc)
+ */
+ an.setType("jalview:SecondaryStructurePrediction"); // TODO: better fix this rough guess ;)
+ alsref.addAlignmentSequenceAnnotation(an);
+ bindjvvobj(alan, an);
+ // These properties are directly supported by the AlignmentSequenceAnnotation type.
+ if (alan.graph != AlignmentAnnotation.NO_GRAPH)
+ {
+ an.setGraph(true);
+ an.addProperty(newProperty(JALVIEW_GRAPH_TYPE, "integer", ""+alan.graph));
+ }
+ else
+ {
+ an.setGraph(false);
+ }
+ an.setProvenance(dummyProvenance()); // get provenance as user
+ // created, or jnet, or
+ // something else.
+ }
+ else
+ {
+ // update reference sequence Annotation
+ if (an.getModifiable()==null) // TODO: USE VAMSAS LIBRARY OBJECT LOCK METHODS)
+ {
+ // verify existing alignment sequence annotation is up to date
+ System.out.println("update alignment sequence annotation.");
+ }
+ else
+ {
+ // verify existing alignment sequence annotation is up to date
+ System.out
+ .println(
+ "make new alignment sequence annotation if modification has happened.");
+ }
+ }
+ }
private Property newProperty(String name, String type, String content)
{
Property vProperty = new Property();
}
/**
- * correctly creates provenance for trees calculated on an alignment by
- * jalview.
- *
- * @param jal
- * @param tp
- * @return
- */
- private Provenance makeTreeProvenance(AlignmentI jal, TreePanel tp)
- {
- Provenance prov = new Provenance();
- prov.addEntry(new Entry());
- prov.getEntry(0).setAction("imported " + tp.getTitle());
- prov.getEntry(0).setUser(provEntry.getUser());
- prov.getEntry(0).setApp(provEntry.getApp());
- prov.getEntry(0).setDate(provEntry.getDate());
- if (tp.getTree().hasOriginalSequenceData())
- {
- Input vInput = new Input();
- // LATER: check to see if tree input data is contained in this alignment -
- // or just correctly resolve the tree's seqData to the correct alignment in
- // the document.
- // vInput.setObjRef(getjv2vObj(jal));
- vInput.setObjRef(new Object[] { getjv2vObj(tp.getViewPort())});
- prov.getEntry(0).setAction("created " + tp.getTitle());
- prov.getEntry(0).addInput(vInput);
- vInput.setName("jalview:seqdist");
- prov.getEntry(0).addParam(new Param());
- prov.getEntry(0).getParam(0).setName("treeType");
- prov.getEntry(0).getParam(0).setType("utf8");
- prov.getEntry(0).getParam(0).setContent("NJ");
-
- int ranges[] = tp.getTree().seqData.getVisibleContigs();
- // VisibleContigs are with respect to alignment coordinates. Still need offsets
- int start = tp.getTree().seqData.getAlignmentOrigin();
- for (int r = 0; r < ranges.length; r += 2)
- {
- Seg visSeg = new Seg();
- visSeg.setStart(1 + start + ranges[r]);
- visSeg.setEnd(start + ranges[r + 1]);
- visSeg.setInclusive(true);
- vInput.addSeg(visSeg);
- }
- }
- return prov;
- }
-
- /**
*
* @param tp
* @return Object[] { AlignmentView, AlignmentI - reference alignment for
{
Cache.log.debug(
"Inserting empty annotation row elements for a whole-alignment annotation.");
-
}
else
{
uk.ac.vamsas.objects.core.Property[] props = annotation.getProperty();
for (int p = 0; p < props.length; p++)
{
- if (props[p].getName().equalsIgnoreCase("jalview:graphType"))
+ if (props[p].getName().equalsIgnoreCase(JALVIEW_GRAPH_TYPE))
{
try
{
p.addEntry(dummyPEntry(action));
}
+ public Entry getProvEntry()
+ {
+ return provEntry;
+ }
+
+ public IClientDocument getClientDocument()
+ {
+ return cdoc;
+ }
+
+ public IdentityHashMap getJvObjectBinding()
+ {
+ return jv2vobj;
+ }
+ public Hashtable getVamsasObjectBinding() {
+ return vobj2jv;
+ }
+
}
--- /dev/null
+package jalview.io.vamsas;\r
+\r
+import jalview.bin.Cache;\r
+import jalview.gui.TreePanel;\r
+import jalview.io.VamsasAppDatastore;\r
+\r
+import java.util.Enumeration;\r
+import java.util.Hashtable;\r
+import java.util.IdentityHashMap;\r
+import java.util.Vector;\r
+\r
+import uk.ac.vamsas.client.IClientDocument;\r
+import uk.ac.vamsas.client.Vobject;\r
+import uk.ac.vamsas.client.VorbaId;\r
+import uk.ac.vamsas.objects.core.Entry;\r
+\r
+/**\r
+ * Holds all the common machinery for binding objects to vamsas objects\r
+ * @author JimP\r
+ *\r
+ */\r
+public class DatastoreItem\r
+{\r
+ /**\r
+ * \r
+ */\r
+ Entry provEntry = null;\r
+\r
+ IClientDocument cdoc;\r
+\r
+ Hashtable vobj2jv;\r
+\r
+ IdentityHashMap jv2vobj;\r
+ /**\r
+ * @return the Vobject bound to Jalview datamodel object\r
+ */\r
+ protected Vobject getjv2vObj(Object jvobj)\r
+ {\r
+ if (jv2vobj.containsKey(jvobj))\r
+ {\r
+ return cdoc.getObject( (VorbaId) jv2vobj.get(jvobj));\r
+ }\r
+ if (Cache.log.isDebugEnabled())\r
+ {\r
+ Cache.log.debug("Returning null VorbaID binding for jalview object "+jvobj);\r
+ }\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ *\r
+ * @param vobj\r
+ * @return Jalview datamodel object bound to the vamsas document object\r
+ */\r
+ protected Object getvObj2jv(uk.ac.vamsas.client.Vobject vobj)\r
+ {\r
+ VorbaId id = vobj.getVorbaId();\r
+ if (id == null)\r
+ {\r
+ id = cdoc.registerObject(vobj);\r
+ Cache.log\r
+ .debug("Registering new object and returning null for getvObj2jv");\r
+ return null;\r
+ }\r
+ if (vobj2jv.containsKey(vobj.getVorbaId()))\r
+ {\r
+ return vobj2jv.get(vobj.getVorbaId());\r
+ }\r
+ return null;\r
+ }\r
+\r
+ protected void bindjvvobj(Object jvobj, uk.ac.vamsas.client.Vobject vobj)\r
+ {\r
+ VorbaId id = vobj.getVorbaId();\r
+ if (id == null)\r
+ {\r
+ id = cdoc.registerObject(vobj);\r
+ if (id == null || vobj.getVorbaId() == null || cdoc.getObject(id)!=vobj)\r
+ {\r
+ Cache.log.error("Failed to get id for " +\r
+ (vobj.isRegisterable() ? "registerable" :\r
+ "unregisterable") + " object " + vobj);\r
+ }\r
+ }\r
+\r
+ if (vobj2jv.containsKey(vobj.getVorbaId()) &&\r
+ ! ( (VorbaId) vobj2jv.get(vobj.getVorbaId())).equals(jvobj))\r
+ {\r
+ Cache.log.debug("Warning? Overwriting existing vamsas id binding for " +\r
+ vobj.getVorbaId(),\r
+ new Exception("Overwriting vamsas id binding."));\r
+ }\r
+ else if (jv2vobj.containsKey(jvobj) &&\r
+ ! ( (VorbaId) jv2vobj.get(jvobj)).equals(vobj.getVorbaId()))\r
+ {\r
+ Cache.log.debug(\r
+ "Warning? Overwriting existing jalview object binding for " + jvobj,\r
+ new Exception("Overwriting jalview object binding."));\r
+ }\r
+ /* Cache.log.error("Attempt to make conflicting object binding! "+vobj+" id " +vobj.getVorbaId()+" already bound to "+getvObj2jv(vobj)+" and "+jvobj+" already bound to "+getjv2vObj(jvobj),new Exception("Excessive call to bindjvvobj"));\r
+ }*/\r
+ // we just update the hash's regardless!\r
+ Cache.log.debug("Binding "+vobj.getVorbaId()+" to "+jvobj);\r
+ vobj2jv.put(vobj.getVorbaId(), jvobj);\r
+ // JBPNote - better implementing a hybrid invertible hash.\r
+ jv2vobj.put(jvobj, vobj.getVorbaId());\r
+ }\r
+\r
+ public DatastoreItem() {\r
+ super();\r
+ }\r
+ public DatastoreItem(VamsasAppDatastore datastore)\r
+ {\r
+ this();\r
+ initDatastoreItem(datastore);\r
+ // TODO Auto-generated constructor stub\r
+ }\r
+\r
+ public void initDatastoreItem(VamsasAppDatastore ds)\r
+ {\r
+ initDatastoreItem(ds.getProvEntry(), ds.getClientDocument(), ds.getVamsasObjectBinding(), ds.getJvObjectBinding());\r
+ }\r
+ public void initDatastoreItem(Entry provEntry, IClientDocument cdoc, Hashtable vobj2jv, IdentityHashMap jv2vobj)\r
+ {\r
+ this.provEntry = provEntry;\r
+ this.cdoc = cdoc;\r
+ this.vobj2jv = vobj2jv;\r
+ this.jv2vobj = jv2vobj;\r
+ }\r
+\r
+ protected boolean isModifiable(String modifiable)\r
+ {\r
+ return modifiable==null; // TODO: USE VAMSAS LIBRARY OBJECT LOCK METHODS)\r
+ }\r
+\r
+ protected Vector getjv2vObjs(Vector alsq)\r
+ {\r
+ Vector vObjs = new Vector();\r
+ Enumeration elm = alsq.elements();\r
+ while (elm.hasMoreElements())\r
+ {\r
+ vObjs.addElement(getjv2vObj(elm.nextElement()));\r
+ }\r
+ return vObjs;\r
+ }\r
+}\r
--- /dev/null
+package jalview.io.vamsas;\r
+\r
+import java.util.Enumeration;\r
+import java.util.Hashtable;\r
+import java.util.Vector;\r
+\r
+import jalview.analysis.NJTree;\r
+import jalview.datamodel.AlignmentI;\r
+import jalview.datamodel.SeqCigar;\r
+import jalview.datamodel.SequenceI;\r
+import jalview.gui.TreePanel;\r
+import jalview.io.VamsasAppDatastore;\r
+import uk.ac.vamsas.client.Vobject;\r
+import uk.ac.vamsas.objects.core.Entry;\r
+import uk.ac.vamsas.objects.core.Input;\r
+import uk.ac.vamsas.objects.core.Newick;\r
+import uk.ac.vamsas.objects.core.Param;\r
+import uk.ac.vamsas.objects.core.Provenance;\r
+import uk.ac.vamsas.objects.core.Seg;\r
+import uk.ac.vamsas.objects.core.Treenode;\r
+import uk.ac.vamsas.objects.core.Vref;\r
+\r
+public class Tree extends DatastoreItem\r
+{\r
+ AlignmentI jal;\r
+ TreePanel tp;\r
+ uk.ac.vamsas.objects.core.Tree tree;\r
+ uk.ac.vamsas.objects.core.Alignment alignment; // may be null => dataset or other kind of tree\r
+ public Tree(VamsasAppDatastore datastore, TreePanel tp2, AlignmentI jal2, uk.ac.vamsas.objects.core.Alignment alignment2)\r
+ {\r
+ super(datastore);\r
+\r
+ jal = jal2;\r
+ tp = tp2;\r
+ alignment = alignment2;\r
+ \r
+ tree = (uk.ac.vamsas.objects.core.Tree) getjv2vObj(tp);\r
+ if (tree == null)\r
+ {\r
+ add();\r
+ }\r
+ else\r
+ {\r
+ if (isModifiable(tree.getModifiable()))\r
+ {\r
+ // synchronize(); // update();\r
+ // verify any changes.\r
+ System.out.println("Update tree in document.");\r
+ }\r
+ else\r
+ {\r
+ // handle conflict\r
+ System.out\r
+ .println("Add modified tree as new tree in document.");\r
+ }\r
+ }\r
+ }\r
+ /**\r
+ * correctly creates provenance for trees calculated on an alignment by\r
+ * jalview.\r
+ *\r
+ * @param jal\r
+ * @param tp\r
+ * @return\r
+ */\r
+ private Provenance makeTreeProvenance(AlignmentI jal, TreePanel tp)\r
+ {\r
+ Provenance prov = new Provenance();\r
+ prov.addEntry(new Entry());\r
+ prov.getEntry(0).setAction("imported " + tp.getTitle());\r
+ prov.getEntry(0).setUser(provEntry.getUser());\r
+ prov.getEntry(0).setApp(provEntry.getApp());\r
+ prov.getEntry(0).setDate(provEntry.getDate());\r
+ if (tp.getTree().hasOriginalSequenceData())\r
+ {\r
+ Input vInput = new Input();\r
+ // LATER: check to see if tree input data is contained in this alignment -\r
+ // or just correctly resolve the tree's seqData to the correct alignment in\r
+ // the document.\r
+ Vector alsqrefs = getjv2vObjs(findAlignmentSequences(jal, tp.getTree().seqData.getSequences()));\r
+ Object[] alsqs = new Object[alsqrefs.size()];\r
+ alsqrefs.copyInto(alsqs);\r
+ vInput.setObjRef(alsqs);\r
+ // now create main provenance data\r
+ prov.getEntry(0).setAction("created " + tp.getTitle());\r
+ prov.getEntry(0).addInput(vInput);\r
+ // jalview's special input parameter for distance matrix calculations\r
+ vInput.setName("jalview:seqdist");\r
+ prov.getEntry(0).addParam(new Param());\r
+ prov.getEntry(0).getParam(0).setName("treeType");\r
+ prov.getEntry(0).getParam(0).setType("utf8");\r
+ prov.getEntry(0).getParam(0).setContent("NJ");\r
+ int ranges[] = tp.getTree().seqData.getVisibleContigs();\r
+ // VisibleContigs are with respect to alignment coordinates. Still need offsets\r
+ int start = tp.getTree().seqData.getAlignmentOrigin();\r
+ for (int r = 0; r < ranges.length; r += 2)\r
+ {\r
+ Seg visSeg = new Seg();\r
+ visSeg.setStart(1 + start + ranges[r]);\r
+ visSeg.setEnd(start + ranges[r + 1]);\r
+ visSeg.setInclusive(true);\r
+ vInput.addSeg(visSeg);\r
+ }\r
+ }\r
+ return prov;\r
+ }\r
+ /**\r
+ * look up SeqCigars in an existing alignment.\r
+ * @param jal\r
+ * @param sequences\r
+ * @return vector of alignment sequences in order of SeqCigar array (but missing unfound seqcigars)\r
+ */\r
+ private Vector findAlignmentSequences(AlignmentI jal, SeqCigar[] sequences)\r
+ {\r
+ SeqCigar[] tseqs = new SeqCigar[sequences.length];\r
+ System.arraycopy(sequences, 0, tseqs, 0, sequences.length);\r
+ Vector alsq = new Vector();\r
+ Enumeration as = jal.getSequences().elements();\r
+ while (as.hasMoreElements())\r
+ {\r
+ SequenceI asq = (SequenceI) as.nextElement();\r
+ for (int t = 0; t<sequences.length; t++)\r
+ {\r
+ if (tseqs[t]!=null \r
+ && (tseqs[t].getRefSeq()==asq || tseqs[t].getRefSeq() == asq.getDatasetSequence())\r
+ && tseqs[t].getStart()>=asq.getStart() && tseqs[t].getEnd()<=asq.getEnd())\r
+ {\r
+ tseqs[t] = null;\r
+ alsq.add(asq);\r
+ }\r
+ }\r
+ }\r
+ return alsq;\r
+ }\r
+ public Treenode[] makeTreeNodes(NJTree ntree) {\r
+ Vector leaves = new Vector();\r
+ ntree.findLeaves(ntree.getTopNode(), leaves);\r
+ Vector tnv = new Vector();\r
+ Enumeration l = leaves.elements();\r
+ int i=0;\r
+ Hashtable nodespecs = new Hashtable();\r
+ while (l.hasMoreElements())\r
+ {\r
+ jalview.datamodel.BinaryNode tnode = (jalview.datamodel.BinaryNode) l.nextElement();\r
+ if (tnode instanceof jalview.datamodel.SequenceNode)\r
+ {\r
+ if (!((jalview.datamodel.SequenceNode) tnode).isPlaceholder())\r
+ {\r
+ Object assocseq = ((jalview.datamodel.SequenceNode) tnode).element();\r
+ if (assocseq instanceof SequenceI)\r
+ {\r
+ Vobject vobj = this.getjv2vObj(assocseq);\r
+ if (vobj!=null)\r
+ {\r
+ Treenode node = new Treenode();\r
+ node.setNodespec(makeNodeSpec(nodespecs, tnode));\r
+ node.setName(tnode.getName());\r
+ Vref vr = new Vref();\r
+ vr.addRefs(vobj);\r
+ node.addVref(vr);\r
+ tnv.addElement(node);\r
+ }\r
+ else\r
+ {\r
+ System.err.println("WARNING: Unassociated treeNode "+tnode.element().toString()+" "\r
+ +((tnode.getName()!=null) ? " label "+tnode.getName() : ""));\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ if (tnv.size()>0)\r
+ {\r
+ Treenode[] tn = new Treenode[tnv.size()];\r
+ tnv.copyInto(tn); \r
+ return tn;\r
+ }\r
+ return new Treenode[] {};\r
+ }\r
+ private String makeNodeSpec(Hashtable nodespecs, jalview.datamodel.BinaryNode tnode)\r
+ { \r
+ String nname = new String(tnode.getName());\r
+ Integer nindx = (Integer) nodespecs.get(nname);\r
+ if (nindx==null)\r
+ {\r
+ nindx = new Integer(1);\r
+ }\r
+ nname = nindx.toString()+" "+nname;\r
+ return nname;\r
+ }\r
+ /**\r
+ * call to match up Treenode specs to NJTree parsed from document object.\r
+ * @param nodespec\r
+ * @param leaves as returned from NJTree.findLeaves( .., ..) .. \r
+ * @return\r
+ */\r
+ private jalview.datamodel.BinaryNode findNodeSpec(String nodespec, Vector leaves)\r
+ {\r
+ int occurence=-1;\r
+ String nspec = nodespec.substring(nodespec.indexOf(' ')+1);\r
+ String oval = nodespec.substring(0, nodespec.indexOf(' '));\r
+ try {\r
+ occurence = new Integer(oval).intValue();\r
+ }\r
+ catch (Exception e)\r
+ {\r
+ System.err.println("Invalid nodespec '"+nodespec+"'");\r
+ return null;\r
+ }\r
+ jalview.datamodel.BinaryNode bn = null;\r
+ \r
+ int nocc = 0;\r
+ Enumeration en = leaves.elements();\r
+ while (en.hasMoreElements() && nocc<occurence)\r
+ {\r
+ bn = (jalview.datamodel.BinaryNode) en.nextElement();\r
+ if (bn instanceof jalview.datamodel.SequenceNode && bn.getName().equals(nspec))\r
+ {\r
+ --occurence;\r
+ } else \r
+ bn=null;\r
+ }\r
+ return bn;\r
+ }\r
+ \r
+ public void add() {\r
+ tree = new uk.ac.vamsas.objects.core.Tree();\r
+ bindjvvobj(tp, tree);\r
+ tree.setTitle(tp.getTitle());\r
+ Newick newick = new Newick();\r
+ newick.setContent(tp.getTree().toString());\r
+ newick.setTitle(tp.getTitle());\r
+ tree.addNewick(newick);\r
+ tree.setProvenance(makeTreeProvenance(jal, tp));\r
+ tree.setTreenode(makeTreeNodes(tp.getTree()));\r
+ \r
+ alignment.addTree(tree);\r
+ }\r
+}\r