/*\r
+ * originally from \r
+ * \r
* Jalview - A Sequence Alignment Editor and Viewer\r
* Copyright (C) 2007 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
*\r
// TODO: Extended SequenceNodeI to hold parsed NHX strings\r
package uk.ac.vamsas.objects.utils.trees;\r
\r
+\r
import java.io.*;\r
import java.util.Enumeration;\r
import java.util.Hashtable;\r
import java.util.regex.Pattern;\r
\r
import uk.ac.vamsas.client.Vobject;\r
-import uk.ac.vamsas.client.VorbaId;\r
-import uk.ac.vamsas.objects.core.SequenceType;\r
import uk.ac.vamsas.objects.core.Treenode;\r
import uk.ac.vamsas.objects.core.Vref;\r
\r
* @version $Revision: 1.12 $\r
*/\r
public class NewickFile {\r
- public class BinaryNode {\r
- VorbaId element;\r
-\r
- String name;\r
-\r
- BinaryNode left;\r
-\r
- BinaryNode right;\r
-\r
- BinaryNode parent;\r
-\r
- /** DOCUMENT ME!! */\r
- public int bootstrap;\r
-\r
- /**\r
- * Creates a new BinaryNode object.\r
- */\r
- public BinaryNode() {\r
- left = right = parent = null;\r
- bootstrap = 0;\r
- }\r
-\r
- /**\r
- * Creates a new BinaryNode object.\r
- * \r
- * @param element\r
- * DOCUMENT ME!\r
- * @param parent\r
- * DOCUMENT ME!\r
- * @param name\r
- * DOCUMENT ME!\r
- */\r
- public BinaryNode(VorbaId element, BinaryNode parent, String name) {\r
- this.element = element;\r
- this.parent = parent;\r
- this.name = name;\r
-\r
- left = right = null;\r
- }\r
-\r
- /**\r
- * DOCUMENT ME!\r
- * \r
- * @return DOCUMENT ME!\r
- */\r
- public VorbaId element() {\r
- return element;\r
- }\r
-\r
- /**\r
- * DOCUMENT ME!\r
- * \r
- * @param v\r
- * DOCUMENT ME!\r
- * \r
- * @return DOCUMENT ME!\r
- */\r
- public VorbaId setElement(VorbaId v) {\r
- return element = v;\r
- }\r
-\r
- /**\r
- * DOCUMENT ME!\r
- * \r
- * @return DOCUMENT ME!\r
- */\r
- public BinaryNode left() {\r
- return left;\r
- }\r
-\r
- /**\r
- * DOCUMENT ME!\r
- * \r
- * @param n\r
- * DOCUMENT ME!\r
- * \r
- * @return DOCUMENT ME!\r
- */\r
- public BinaryNode setLeft(BinaryNode n) {\r
- return left = n;\r
- }\r
-\r
- /**\r
- * DOCUMENT ME!\r
- * \r
- * @return DOCUMENT ME!\r
- */\r
- public BinaryNode right() {\r
- return right;\r
- }\r
-\r
- /**\r
- * DOCUMENT ME!\r
- * \r
- * @param n\r
- * DOCUMENT ME!\r
- * \r
- * @return DOCUMENT ME!\r
- */\r
- public BinaryNode setRight(BinaryNode n) {\r
- return right = n;\r
- }\r
-\r
- /**\r
- * DOCUMENT ME!\r
- * \r
- * @return DOCUMENT ME!\r
- */\r
- public BinaryNode parent() {\r
- return parent;\r
- }\r
-\r
- /**\r
- * DOCUMENT ME!\r
- * \r
- * @param n\r
- * DOCUMENT ME!\r
- * \r
- * @return DOCUMENT ME!\r
- */\r
- public BinaryNode setParent(BinaryNode n) {\r
- return parent = n;\r
- }\r
-\r
- /**\r
- * DOCUMENT ME!\r
- * \r
- * @return DOCUMENT ME!\r
- */\r
- public boolean isLeaf() {\r
- return (left == null) && (right == null);\r
- }\r
-\r
- /**\r
- * attaches FIRST and SECOND node arguments as the LEFT and RIGHT children\r
- * of this node (removing any old references) a null parameter DOES NOT mean\r
- * that the pointer to the corresponding child node is set to NULL - you\r
- * should use setChild(null), or detach() for this.\r
- * \r
- */\r
- public void SetChildren(BinaryNode leftchild, BinaryNode rightchild) {\r
- if (leftchild != null) {\r
- this.setLeft(leftchild);\r
- leftchild.detach();\r
- leftchild.setParent(this);\r
- }\r
-\r
- if (rightchild != null) {\r
- this.setRight(rightchild);\r
- rightchild.detach();\r
- rightchild.setParent(this);\r
- }\r
- }\r
-\r
- /**\r
- * Detaches the node from the binary tree, along with all its child nodes.\r
- * \r
- * @return BinaryNode The detached node.\r
- */\r
- public BinaryNode detach() {\r
- if (this.parent != null) {\r
- if (this.parent.left == this) {\r
- this.parent.left = null;\r
- } else {\r
- if (this.parent.right == this) {\r
- this.parent.right = null;\r
- }\r
- }\r
- }\r
-\r
- this.parent = null;\r
-\r
- return this;\r
- }\r
-\r
- /**\r
- * Traverses up through the tree until a node with a free leftchild is\r
- * discovered.\r
- * \r
- * @return BinaryNode\r
- */\r
- public BinaryNode ascendLeft() {\r
- BinaryNode c = this;\r
-\r
- do {\r
- c = c.parent();\r
- } while ((c != null) && (c.left() != null) && !c.left().isLeaf());\r
-\r
- return c;\r
- }\r
-\r
- /**\r
- * Traverses up through the tree until a node with a free rightchild is\r
- * discovered. Jalview builds trees by descent on the left, so this may be\r
- * unused.\r
- * \r
- * @return BinaryNode\r
- */\r
- public BinaryNode ascendRight() {\r
- BinaryNode c = this;\r
-\r
- do {\r
- c = c.parent();\r
- } while ((c != null) && (c.right() != null) && !c.right().isLeaf());\r
-\r
- return c;\r
- }\r
-\r
- /**\r
- * DOCUMENT ME!\r
- * \r
- * @param name\r
- * DOCUMENT ME!\r
- */\r
- public void setName(String name) {\r
- this.name = name;\r
- }\r
-\r
- /**\r
- * DOCUMENT ME!\r
- * \r
- * @return DOCUMENT ME!\r
- */\r
- public String getName() {\r
- return this.name;\r
- }\r
-\r
- /**\r
- * DOCUMENT ME!\r
- * \r
- * @param boot\r
- * DOCUMENT ME!\r
- */\r
- public void setBootstrap(int boot) {\r
- this.bootstrap = boot;\r
- }\r
-\r
- /**\r
- * DOCUMENT ME!\r
- * \r
- * @return DOCUMENT ME!\r
- */\r
- public int getBootstrap() {\r
- return bootstrap;\r
- }\r
- /**\r
- * \r
- * @return unquoted string of form VorbaId|v|node name string\r
- */\r
- public String getNewickNodeName() {\r
- if (element!=null || name!=null)\r
- {\r
- return ((element!=null) ? element.getId()+"|v|" : "")\r
- + ((name == null) ? "" : name);\r
- }\r
- return "";\r
- }\r
- public boolean parseNodeNameString(uk.ac.vamsas.client.ClientDocument binder)\r
- {\r
- \r
- if (element==null && name!=null && name.indexOf("|v|")>-1)\r
- {\r
- element = binder.getObject(null).getVorbaId(); // TODO: fix THIS ! name.substring(0, name.indexOf("|v")));\r
- \r
- }\r
- return false;\r
- }\r
- }\r
-\r
- public class SequenceNode extends BinaryNode {\r
- /** DOCUMENT ME!! */\r
- public float dist;\r
-\r
- /** DOCUMENT ME!! */\r
- public boolean dummy = false;\r
-\r
- private boolean placeholder = false;\r
-\r
- /**\r
- * Creates a new SequenceNode object.\r
- */\r
- public SequenceNode() {\r
- super();\r
- }\r
-\r
- /**\r
- * Creates a new SequenceNode object.\r
- * \r
- * @param val\r
- * DOCUMENT ME!\r
- * @param parent\r
- * DOCUMENT ME!\r
- * @param dist\r
- * DOCUMENT ME!\r
- * @param name\r
- * DOCUMENT ME!\r
- */\r
- public SequenceNode(VorbaId val, SequenceNode parent, float dist, String name) {\r
- super(val, parent, name);\r
- this.dist = dist;\r
- }\r
- public SequenceNode(Vobject val, SequenceNode parent, float dist, String name) {\r
- super(val.getVorbaId(), parent, name);\r
- this.dist = dist;\r
- }\r
-\r
- /**\r
- * Creates a new SequenceNode object.\r
- * \r
- * @param val\r
- * DOCUMENT ME!\r
- * @param parent\r
- * DOCUMENT ME!\r
- * @param name\r
- * DOCUMENT ME!\r
- * @param dist\r
- * DOCUMENT ME!\r
- * @param bootstrap\r
- * DOCUMENT ME!\r
- * @param dummy\r
- * DOCUMENT ME!\r
- */\r
- public SequenceNode(Vobject val, SequenceNode parent, String name,\r
- float dist, int bootstrap, boolean dummy) {\r
- super(val.getVorbaId(), parent, name);\r
- this.dist = dist;\r
- this.bootstrap = bootstrap;\r
- this.dummy = dummy;\r
- }\r
-\r
- /**\r
- * @param dummy\r
- * true if node is created for the representation of polytomous\r
- * trees\r
- */\r
- public boolean isDummy() {\r
- return dummy;\r
- }\r
-\r
- /*\r
- * @param placeholder is true if the sequence refered to in the element node\r
- * is not actually present in the associated alignment\r
- */\r
- public boolean isPlaceholder() {\r
- return placeholder;\r
- }\r
-\r
- /**\r
- * DOCUMENT ME!\r
- * \r
- * @param newstate\r
- * DOCUMENT ME!\r
- * \r
- * @return DOCUMENT ME!\r
- */\r
- public boolean setDummy(boolean newstate) {\r
- boolean oldstate = dummy;\r
- dummy = newstate;\r
-\r
- return oldstate;\r
- }\r
-\r
- /**\r
- * DOCUMENT ME!\r
- * \r
- * @param Placeholder\r
- * DOCUMENT ME!\r
- */\r
- public void setPlaceholder(boolean Placeholder) {\r
- this.placeholder = Placeholder;\r
- }\r
-\r
- /**\r
- * ascends the tree but doesn't stop until a non-dummy node is discovered.\r
- * This will probably break if the tree is a mixture of BinaryNodes and\r
- * SequenceNodes.\r
- */\r
- public SequenceNode AscendTree() {\r
- SequenceNode c = this;\r
-\r
- do {\r
- c = (SequenceNode) c.parent();\r
- } while ((c != null) && c.dummy);\r
-\r
- return c;\r
- }\r
-\r
- }\r
-\r
SequenceNode root;\r
\r
private boolean HasBootstrap = false;\r
* @return DOCUMENT ME!\r
*/\r
private String printNodeField(SequenceNode c) {\r
- return c.getNewickNodeName()\r
- + ((HasBootstrap) ? ((c.getBootstrap() > -1) ? (" " + c.getBootstrap())\r
+ return //c.getNewickNodeName()\r
+ ((c.getName() == null) ? "" : nodeName(c.getName()))\r
+ + ((HasBootstrap) ? ((c.getBootstrap() > -1) ? (" " + c.getBootstrap())\r
: "") : "") + ((HasDistances) ? (":" + c.dist) : "");\r
}\r
\r
* @param ntree\r
* @return\r
*/\r
- public Treenode[] makeTreeNodes() { // NJTree ntree) {\r
+ public Treenode[] makeTreeNodes() { \r
Vector leaves = new Vector();\r
findLeaves(root, 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
}\r
return bn;\r
}\r
+ /**\r
+ *\r
+ * re-decorate the newick node representation with the VorbaId of an object mapped by its corresponding TreeNode. \r
+ * Note: this only takes the first object in the first set of references.\r
+ * @param tn\r
+ * @return vector of mappings { treenode, SequenceNode, Vobject for VorbaId on sequence node }\r
+ */\r
+ public Vector attachTreeMap(Treenode[] tn)\r
+ {\r
+ if (root!=null || tn==null)\r
+ return null;\r
+ Vector leaves = new Vector();\r
+ Vector nodemap=new Vector();\r
+ findLeaves(root, leaves);\r
+ int sz = tn.length;\r
+ int i = 0;\r
+ \r
+ while (i < sz)\r
+ {\r
+ Treenode node = tn[i++];\r
+ BinaryNode mappednode = findNodeSpec(node.getNodespec(),leaves);\r
+ if (mappednode!=null && mappednode instanceof SequenceNode) {\r
+ SequenceNode leaf = (SequenceNode) leaves.elementAt(i++);\r
+ // check if we can make the specified association\r
+ Vobject noderef = null;\r
+ int vrf=0,refv=0;\r
+ while (noderef==null && vrf<node.getVrefCount())\r
+ {\r
+ if (refv<node.getVref(vrf).getRefsCount())\r
+ {\r
+ Object ref = node.getVref(vrf).getRefs(refv++);\r
+ if (ref instanceof Vobject)\r
+ {\r
+ noderef = (Vobject) ref;\r
+ }\r
+ } else {\r
+ refv=0;\r
+ vrf++;\r
+ }\r
+ }\r
+ if (noderef!=null)\r
+ {\r
+ nodemap.addElement(new Object[] { node, leaf, noderef });\r
+ leaf.setElement(noderef);\r
+ leaf.setPlaceholder(false);\r
+ } else {\r
+ leaf.setPlaceholder(true);\r
+ }\r
+ }\r
+ }\r
+ return nodemap;\r
+}\r
\r
}\r