From: jprocter Date: Fri, 18 Mar 2005 16:54:55 +0000 (+0000) Subject: Tree io modifications, including support for polytomous trees by the X-Git-Tag: Release_2_0~555 X-Git-Url: http://source.jalview.org/gitweb/?p=jalview.git;a=commitdiff_plain;h=f008025f6aa0c2df0e1fbf556a89393e7052db72 Tree io modifications, including support for polytomous trees by the generation of dummy nodes. --- diff --git a/src/jalview/datamodel/BinaryNode.java b/src/jalview/datamodel/BinaryNode.java index 77b5971..6fb3be2 100755 --- a/src/jalview/datamodel/BinaryNode.java +++ b/src/jalview/datamodel/BinaryNode.java @@ -1,73 +1,162 @@ -package jalview.datamodel; - -public class BinaryNode { - - Object element; - String name; - BinaryNode left; - BinaryNode right; - BinaryNode parent; - public int bootstrap; - - public BinaryNode() { - left = right = parent = null; - } - - public BinaryNode(Object element, BinaryNode parent,String name) { - this.element = element; - this.parent = parent; - this.name = name; - - left=right=null; - } - - public Object element() { - return element; - } - - public Object setElement(Object v) { - return element=v; - } - - public BinaryNode left() { - return left; - } - - public BinaryNode setLeft(BinaryNode n) { - return left=n; - } - - public BinaryNode right() { - return right; - } - - public BinaryNode setRight(BinaryNode n) { - return right=n; - } - - public BinaryNode parent() { - return parent; - } - - public BinaryNode setParent(BinaryNode n) { - return parent=n; - } - - public boolean isLeaf() { - return (left == null) && (right == null); - } - - public void setName(String name) { - this.name = name; - } - public String getName() { - return this.name; - } - public void setBootstrap(int boot) { - this.bootstrap = boot; - } - public int getBootstrap() { - return bootstrap; - } -} - +package jalview.datamodel; + +public class BinaryNode +{ + + Object element; + String name; + BinaryNode left; + BinaryNode right; + BinaryNode parent; + public int bootstrap; + + public BinaryNode() + { + left = right = parent = null; + bootstrap = 0; + } + + public BinaryNode(Object element, BinaryNode parent, String name) + { + this.element = element; + this.parent = parent; + this.name = name; + + left = right = null; + } + + public Object element() + { + return element; + } + + public Object setElement(Object v) + { + return element = v; + } + + public BinaryNode left() + { + return left; + } + + public BinaryNode setLeft(BinaryNode n) + { + return left = n; + } + + public BinaryNode right() + { + return right; + } + + public BinaryNode setRight(BinaryNode n) + { + return right = n; + } + + public BinaryNode parent() + { + return parent; + } + + public BinaryNode setParent(BinaryNode n) + { + return parent = n; + } + + public boolean isLeaf() + { + return (left == null) && (right == null); + } + + /** + * attaches FIRST and SECOND node arguments as the LEFT and RIGHT children of this node (removing any old references) + * a null parameter DOES NOT mean that the pointer to the corresponding child node is set to NULL - you should use + * setChild(null), or detach() for this. + * + */ + public void SetChildren(BinaryNode leftchild, BinaryNode rightchild) + { + if (leftchild != null) + { + this.setLeft(leftchild); + leftchild.detach(); + leftchild.setParent(this); + + } + if (rightchild != null) + { + this.setRight(rightchild); + rightchild.detach(); + rightchild.setParent(this); + } + } + + /** + * Detaches the node from the binary tree, along with all its child nodes. + * @return BinaryNode The detached node. + */ + public BinaryNode detach() + { + if (this.parent!=null) { + if (this.parent.left == this) + { + this.parent.left = null; + } + else + { + if (this.parent.right == this) + { + this.parent.right = null; + } + } + } + this.parent = null; + return this; + } + /** + * Traverses up through the tree until a node with a free leftchild is discovered. + * @return BinaryNode + */ + public BinaryNode ascendLeft() { + BinaryNode c = this; + do { + c = c.parent(); + } while (c!=null && c.left()!=null && !c.left().isLeaf()); + return c; + } + /** + * Traverses up through the tree until a node with a free rightchild is discovered. + * Jalview builds trees by descent on the left, so this may be unused. + * @return BinaryNode + */ + public BinaryNode ascendRight() { + BinaryNode c = this; + do { + c = c.parent(); + } while (c!=null && c.right()!=null && !c.right().isLeaf()); + return c; + } + + + public void setName(String name) + { + this.name = name; + } + + public String getName() + { + return this.name; + } + + public void setBootstrap(int boot) + { + this.bootstrap = boot; + } + + public int getBootstrap() + { + return bootstrap; + } +} diff --git a/src/jalview/datamodel/SequenceNode.java b/src/jalview/datamodel/SequenceNode.java index 6e35ee3..905bd15 100755 --- a/src/jalview/datamodel/SequenceNode.java +++ b/src/jalview/datamodel/SequenceNode.java @@ -9,13 +9,46 @@ public class SequenceNode extends BinaryNode { public float height; public float ycount; public Color color = Color.black; - + public boolean dummy = false; public SequenceNode() { super(); } - + public SequenceNode(Object val, SequenceNode parent, float dist,String name) { super(val,parent,name); this.dist = dist; } + public SequenceNode(Object val, SequenceNode parent, String name, float dist, int bootstrap, boolean dummy) { + super(val,parent,name); + this.dist = dist; + this.bootstrap = bootstrap; + this.dummy = dummy; + } + + + /** + * @param dummy true if node is created for the representation of polytomous trees + */ + + public boolean isDummy() { + return dummy; + } + public boolean setDummy(boolean newstate) { + boolean oldstate = dummy; + dummy = newstate; + return oldstate; + } + + /** + * ascends the tree but doesn't stop until a non-dummy node is discovered. + * This will probably break if the tree is a mixture of BinaryNodes and SequenceNodes. + */ + + public SequenceNode AscendTree() { + SequenceNode c = this; + do { + c = (SequenceNode) c.parent(); + } while (c!=null && c.dummy); + return c; + } } diff --git a/src/jalview/io/NewickFile.java b/src/jalview/io/NewickFile.java index 997903c..d0af8a7 100755 --- a/src/jalview/io/NewickFile.java +++ b/src/jalview/io/NewickFile.java @@ -14,6 +14,7 @@ public class NewickFile extends FileParse private boolean HasBootstrap = false; private boolean HasDistances = false; private boolean RootHasDistance = false; + private String ErrorStringrange(String Error, String Er, int r, int p, String s) { return ((Error==null) ? "" : Error) + Er + @@ -43,6 +44,8 @@ public class NewickFile extends FileParse super(inFile, type); } + // File IO Flags + boolean ReplaceUnderscores = false; public void parse() throws IOException { @@ -58,6 +61,7 @@ public class NewickFile extends FileParse } root = new SequenceNode(); + SequenceNode realroot = null; SequenceNode c = root; int d = -1; int cp = 0; @@ -114,6 +118,9 @@ public class NewickFile extends FileParse c.setLeft(new SequenceNode(null, c, 0, null)); c = (SequenceNode) c.left(); } + if (realroot==null) { + realroot = c; + } nodename = null; distance = -99999; bootstrap = -99999; @@ -163,7 +170,11 @@ public class NewickFile extends FileParse { if (nodename == null) { - nodename = uqnodename.stringMatched(1).replace('_', ' '); + if (ReplaceUnderscores) { + nodename = uqnodename.stringMatched(1).replace('_', ' '); + } else { + nodename = uqnodename.stringMatched(1); + } } else { @@ -189,16 +200,14 @@ public class NewickFile extends FileParse cp + nbootstrap.matchedFrom(), nf); } } - + boolean nodehasdistance=false; if (ndist.search(fstring)) { try { distance = (new Float(ndist.stringMatched(1))).floatValue(); HasDistances = true; - if (c.parent()==root) { - RootHasDistance = true; - } + nodehasdistance = true; } catch (Exception e) { @@ -213,6 +222,9 @@ public class NewickFile extends FileParse c.setName(nodename); c.dist = (HasDistances) ? distance : 0; c.setBootstrap((HasBootstrap) ? bootstrap : 0); + if (c==realroot) { + RootHasDistance = nodehasdistance; // JBPNote This is really UGLY!!! + } } else { @@ -283,6 +295,9 @@ public class NewickFile extends FileParse } root = (SequenceNode) root.right().detach(); // remove the imaginary root. + if (!RootHasDistance) { + root.dist = 0; + } } public NewickFile(SequenceNode newtree) {