net.maizegenetics.taxa.tree.SimpleNode Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of tassel Show documentation
Show all versions of tassel Show documentation
TASSEL is a software package to evaluate traits associations, evolutionary patterns, and linkage
disequilibrium.
// SimpleNode.java
//
// (c) 1999-2001 PAL Development Core Team
//
// This package may be distributed under the
// terms of the Lesser GNU General Public License (LGPL)
package net.maizegenetics.taxa.tree;
import net.maizegenetics.taxa.Taxon;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Enumeration;
import java.util.Hashtable;
/**
* data structure for a node (includes branch) in a binary/non-binary
* rooted/unrooted tree
*
* @version $Id: SimpleNode.java,v 1.1 2007/01/12 03:26:17 tcasstevens Exp $
*
* @author Korbinian Strimmer
* @author Alexei Drummond
*/
public class SimpleNode implements AttributeNode {
/**
* parent node
*/
private Node parent;
/**
* number of node as displayed
*/
private int number;
/**
* sequences associated with node
*/
private byte[] sequence;
/**
* length of branch to parent node
*/
private double length;
/**
* standard error of length of branch to parent node
*/
private double lengthSE;
/**
* height of this node
*/
private double height;
/**
* identifier of node/associated branch
*/
private Taxon identifier;
/**
* the attributes associated with this node.
*/
private Hashtable attributes = null;
//
// Private stuff
//
private Node[] child;
//
// Serialization Stuff
//
static final long serialVersionUID = 3472432765038556717L;
//serialver -classpath ./classes net.maizegenetics.pal.tree.SimpleNode
/**
* I like doing things my self!
*/
private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
out.writeByte(3); //Version number
out.writeObject(parent);
out.writeInt(number);
out.writeObject(sequence);
out.writeDouble(length);
out.writeDouble(lengthSE);
out.writeDouble(height);
out.writeObject(identifier);
out.writeObject(child);
out.writeObject(attributes);
}
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
byte version = in.readByte();
switch (version) {
case 1: {
parent = (Node) in.readObject();
number = in.readInt();
sequence = (byte[]) in.readObject();
Object partial = (double[][][]) in.readObject();
length = in.readDouble();
lengthSE = in.readDouble();
height = in.readDouble();
in.readDouble();
identifier = (Taxon) in.readObject();
child = (Node[]) in.readObject();
break;
}
case 2: {
//attributes are transient
parent = (Node) in.readObject();
number = in.readInt();
sequence = (byte[]) in.readObject();
length = in.readDouble();
lengthSE = in.readDouble();
height = in.readDouble();
identifier = (Taxon) in.readObject();
child = (Node[]) in.readObject();
break;
}
default: {
//attributes are not transient!
parent = (Node) in.readObject();
number = in.readInt();
sequence = (byte[]) in.readObject();
length = in.readDouble();
lengthSE = in.readDouble();
height = in.readDouble();
identifier = (Taxon) in.readObject();
child = (Node[]) in.readObject();
attributes = (Hashtable) in.readObject();
}
}
}
// the following constructors should eventually become
// "friendly" to prevent anyone calling them directly.
// Instead, the NodeFactory should be used!
/**
* constructor default node
*/
public SimpleNode() {
parent = null;
child = null;
length = 0.0;
lengthSE = 0.0;
height = 0.0;
identifier = Taxon.ANONYMOUS;
number = 0;
sequence = null;
}
public SimpleNode(String name, double branchLength) {
this();
identifier = new Taxon(name);
length = branchLength;
}
/**
* Constructor
*
* @param children
* @param branchLength
* @throws IllegalArgumentException if only one child!
*/
protected SimpleNode(Node[] children, double branchLength) {
this();
this.child = children;
if (children.length == 1) {
throw new IllegalArgumentException("Must have more than one child!");
}
for (int i = 0; i < child.length; i++) {
child[i].setParent(this);
}
this.length = branchLength;
}
protected SimpleNode(Node[] children) {
this(children, BranchLimits.MINARC);
}
/**
* constructor used to clone a node and all children
*/
public SimpleNode(Node n) {
this(n, true);
}
public void reset() {
parent = null;
child = null;
length = 0.0;
lengthSE = 0.0;
height = 0.0;
identifier = Taxon.ANONYMOUS;
number = 0;
sequence = null;
}
public SimpleNode(Node n, boolean keepIds) {
init(n, keepIds);
for (int i = 0; i < n.getChildCount(); i++) {
addChild(new SimpleNode(n.getChild(i), keepIds));
}
}
public SimpleNode(Node n, LabelMapping lm) {
init(n, true, lm);
for (int i = 0; i < n.getChildCount(); i++) {
addChild(new SimpleNode(n.getChild(i), lm));
}
}
protected void init(Node n) {
init(n, true);
}
/**
* Initialized node instance variables based on given Node. children are
* ignored.
*/
protected void init(Node n, boolean keepId) {
init(n, keepId, null);
}
/**
* Initialized node instance variables based on given Node. children are
* ignored.
*
* @param lm - may be null
*/
protected void init(Node n, boolean keepId, LabelMapping lm) {
parent = null;
length = n.getBranchLength();
lengthSE = n.getBranchLengthSE();
height = n.getNodeHeight();
if (keepId) {
if (lm != null) {
identifier = lm.getLabelIdentifier(n.getIdentifier());
} else {
identifier = n.getIdentifier();
}
} else {
identifier = Taxon.ANONYMOUS;
}
number = n.getNumber();
sequence = n.getSequence();
if (n instanceof AttributeNode) {
AttributeNode attNode = (AttributeNode) n;
Enumeration e = attNode.getAttributeNames();
while ((e != null) && e.hasMoreElements()) {
String name = (String) e.nextElement();
setAttribute(name, attNode.getAttribute(name));
}
}
child = null;
}
/**
* Returns the parent node of this node.
*/
public final Node getParent() {
return parent;
}
/**
* Set the parent node of this node.
*/
public void setParent(Node node) {
parent = node;
}
/**
* removes parent.
*/
public final void removeParent() {
parent = null;
}
/**
* Returns the sequence at this node, in the form of a String.
*/
public String getSequenceString() {
return new String(sequence);
}
/**
* Returns the sequence at this node, in the form of an array of bytes.
*/
public byte[] getSequence() {
return sequence;
}
/**
* Sets the sequence at this node, in the form of an array of bytes.
*/
public void setSequence(byte[] s) {
sequence = s;
}
/**
* Get the length of the branch attaching this node to its parent.
*/
public final double getBranchLength() {
return length;
}
/**
* Set the length of the branch attaching this node to its parent.
*/
public final void setBranchLength(double value) {
length = value;
}
/**
* Get the length SE of the branch attaching this node to its parent.
*/
public final double getBranchLengthSE() {
return lengthSE;
}
/**
* Set the length SE of the branch attaching this node to its parent.
*/
public final void setBranchLengthSE(double value) {
lengthSE = value;
}
/**
* Get the height of this node relative to the most recent node.
*/
public final double getNodeHeight() {
return height;
}
/**
* Set the height of this node relative to the most recent node.
*
* @note corrects children branch lengths
*/
public final void setNodeHeight(double value) {
if (value < 0) {
height = -value;
} else {
height = value;
}
/*if(child!=null) {
for(int i = 0 ; i= numChildren) {
throw new IllegalArgumentException("Nonexistent child");
}
Node[] newChild = new Node[numChildren - 1];
for (int i = 0; i < n; i++) {
newChild[i] = child[i];
}
for (int i = n; i < numChildren - 1; i++) {
newChild[i] = child[i + 1];
}
Node removed = child[n];
//remove parent link from removed child!
removed.setParent(null);
child = newChild;
return removed;
}
/**
* determines the height of this node and its descendants from branch
* lengths, assuming contemporaneous tips.
*/
public void lengths2HeightsContemp() {
double largestHeight = 0.0;
if (!isLeaf()) {
for (int i = 0; i < getChildCount(); i++) {
NodeUtils.lengths2Heights(getChild(i));
double newHeight
= getChild(i).getNodeHeight() + getChild(i).getBranchLength();
if (newHeight > largestHeight) {
largestHeight = newHeight;
}
}
}
setNodeHeight(largestHeight);
}
/**
* Sets a named attribute to the given value.
*
* @param name the name of the attribute
* @param value the value to set the attribute
*/
public final void setAttribute(String name, Object value) {
if (attributes == null) {
attributes = new Hashtable();
}
attributes.put(name, value);
}
/**
* @return the attribute with the given name or null if it doesn't exist.
* @param name the name of the attribute.
*/
public final Object getAttribute(String name) {
if (attributes == null) {
return null;
}
return attributes.get(name);
}
/**
* @return an enumeration of the attributes that this node has or null if
* the node has no attributes.
*/
public final Enumeration getAttributeNames() {
if (attributes == null) {
return null;
}
return attributes.keys();
}
/**
* Returns the number of children this node has.
*/
public final int getChildCount() {
if (child == null) {
return 0;
}
return child.length;
}
public String toString() {
StringWriter sw = new StringWriter();
try {
NodeUtils.printNH(new PrintWriter(sw), this, true, false, 0, false);
} catch (Exception e) {
e.printStackTrace();
}
return sw.toString();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy