X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=forester%2Fjava%2Fsrc%2Forg%2Fforester%2Fphylogeny%2FPhylogenyNode.java;h=d37cc3b849b584335b7770a04239f05906d3c92f;hb=803a2b32992b5944b73c6dfcb80ceb58c09b81c1;hp=f0f2a538a9a560cdd98f7882f396b2694df6cb81;hpb=ca77b890e4cf571db9a7d01e1de5427670078d2e;p=jalview.git diff --git a/forester/java/src/org/forester/phylogeny/PhylogenyNode.java b/forester/java/src/org/forester/phylogeny/PhylogenyNode.java index f0f2a53..d37cc3b 100644 --- a/forester/java/src/org/forester/phylogeny/PhylogenyNode.java +++ b/forester/java/src/org/forester/phylogeny/PhylogenyNode.java @@ -23,7 +23,7 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA // // Contact: phylosoft @ gmail . com -// WWW: www.phylosoft.org/forester +// WWW: https://sites.google.com/site/cmzmasek/home/software/forester package org.forester.phylogeny; @@ -32,71 +32,119 @@ import java.util.List; import org.forester.io.parsers.nhx.NHXFormatException; import org.forester.io.parsers.nhx.NHXParser; +import org.forester.io.parsers.phyloxml.PhyloXmlDataFormatException; import org.forester.io.parsers.phyloxml.PhyloXmlUtil; import org.forester.phylogeny.data.BranchData; import org.forester.phylogeny.data.Confidence; import org.forester.phylogeny.data.NodeData; import org.forester.phylogeny.data.PhylogenyDataUtil; -import org.forester.phylogeny.iterators.ChildNodeIteratorForward; -import org.forester.phylogeny.iterators.PhylogenyNodeIterator; import org.forester.phylogeny.iterators.PreorderTreeIterator; import org.forester.util.ForesterUtil; -public class PhylogenyNode implements PhylogenyNodeI, Comparable { +/** + * Warning. Implementation of method 'compareTo' only looks at + * node name. Thus, use of this class in SortedSets might lead + * to unexpected behavior. + * + */ +public final class PhylogenyNode implements Comparable { - private static int _node_count = 0; - private byte _indicator; - private int _id; - private int _sum_ext_nodes; - private float _x; - private float _y; - private double _distance_parent; + private static long NODE_COUNT = 0; + private BranchData _branch_data; private boolean _collapse; - private PhylogenyNode _parent; - private PhylogenyNode _link; private ArrayList _descendants; + private double _distance_parent = PhylogenyDataUtil.BRANCH_LENGTH_DEFAULT; + private long _id; + private byte _indicator; + private PhylogenyNode _link; private NodeData _node_data; - private BranchData _branch_data; + private PhylogenyNode _parent; + private int _sum_ext_nodes; + private float _x; private float _x_secondary; + private float _y; private float _y_secondary; /** * Default constructor for PhylogenyNode. */ public PhylogenyNode() { - init(); setId( PhylogenyNode.getNodeCount() ); PhylogenyNode.increaseNodeCount(); setSumExtNodes( 1 ); // For ext node, this number is 1 (not 0!!) } + public PhylogenyNode( final String node_name ) { + setId( PhylogenyNode.getNodeCount() ); + PhylogenyNode.increaseNodeCount(); + setSumExtNodes( 1 ); // For ext node, this number is 1 (not 0!!) + if ( node_name != null ) { + getNodeData().setNodeName( node_name ); + } + } + + private PhylogenyNode( final String nhx, + final NHXParser.TAXONOMY_EXTRACTION taxonomy_extraction, + final boolean replace_underscores ) throws NHXFormatException, PhyloXmlDataFormatException { + NHXParser.parseNHX( nhx, this, taxonomy_extraction, replace_underscores, false, false, false ); + setId( PhylogenyNode.getNodeCount() ); + PhylogenyNode.increaseNodeCount(); + setSumExtNodes( 1 ); // For ext node, this number is 1 (not 0!!). + } + + private PhylogenyNode( final String nhx, + final NHXParser.TAXONOMY_EXTRACTION taxonomy_extraction, + final boolean replace_underscores, + final boolean parse_extended_tags ) throws NHXFormatException, PhyloXmlDataFormatException { + NHXParser.parseNHX( nhx, + this, + taxonomy_extraction, + replace_underscores, + false, + false, + parse_extended_tags ); + setId( PhylogenyNode.getNodeCount() ); + PhylogenyNode.increaseNodeCount(); + setSumExtNodes( 1 ); // For ext node, this number is 1 (not 0!!). + } + /** * Adds PhylogenyNode n to the list of child nodes and sets the _parent of n * to this. - * + * * @param n * the PhylogenyNode to add */ - @Override - final public void addAsChild( final PhylogenyNodeI node ) { - final PhylogenyNode n = ( PhylogenyNode ) node; + final public void addAsChild( final PhylogenyNode node ) { + final PhylogenyNode n = node; addChildNode( n ); n.setParent( this ); } - /** - * Adds PhylogenyNode n to the list of child nodes. But does NOT set the - * _parent of n to this. - * - * @see addAsChild( PhylogenyNode n ) - * @param n - * the PhylogenyNode to add - */ - final private void addChildNode( final PhylogenyNode child ) { - getDescendants().add( child ); + public final int calculateDepth() { + PhylogenyNode n = this; + int steps = 0; + while ( n._parent != null ) { + steps++; + n = n._parent; + } + return steps; + } + + public final double calculateDistanceToRoot() { + PhylogenyNode n = this; + double d = 0.0; + while ( n._parent != null ) { + if ( n._distance_parent > 0.0 ) { + d += n._distance_parent; + } + n = n._parent; + } + return d; } @Override + // this is poor, as it only compares on names! final public int compareTo( final PhylogenyNode o ) { final PhylogenyNode n = o; if ( ( getName() == null ) || ( n.getName() == null ) ) { @@ -105,15 +153,12 @@ public class PhylogenyNode implements PhylogenyNodeI, Comparable return getName().compareTo( n.getName() ); } - // --------------------------------------------------------- - // Copy and delete Nodes, copy subtress - // --------------------------------------------------------- /** * Returns a new PhylogenyNode which has its data copied from this * PhylogenyNode. Links to the other Nodes in the same Phylogeny are NOT * copied (e.g. _link to _parent). Field "_link" IS copied. - * - * @see #getLink() + * + * @see #getLink() */ final public PhylogenyNode copyNodeData() { final PhylogenyNode node = new PhylogenyNode(); @@ -139,8 +184,8 @@ public class PhylogenyNode implements PhylogenyNodeI, Comparable * Returns a new PhylogenyNode which has the same data as this * PhylogenyNode. Links to the other Nodes in the same Phylogeny are NOT * copied (e.g. _link to _parent). Field "_link" IS copied. - * - * @see #getLink() + * + * @see #getLink() */ final public PhylogenyNode copyNodeDataShallow() { final PhylogenyNode node = new PhylogenyNode(); @@ -161,8 +206,8 @@ public class PhylogenyNode implements PhylogenyNodeI, Comparable @Override /** * Based on node name, sequence, and taxonomy. - * - * + * + * */ final public boolean equals( final Object o ) { if ( this == o ) { @@ -187,12 +232,12 @@ public class PhylogenyNode implements PhylogenyNodeI, Comparable return ( this_data.getTaxonomy().isEqual( other_data.getTaxonomy() ) && this_data.getSequence() .isEqual( other_data.getSequence() ) ); } - else if ( this_data.isHasSequence() && other_data.isHasSequence() ) { - return ( this_data.getSequence().isEqual( other_data.getSequence() ) ); - } else if ( this_data.isHasTaxonomy() && other_data.isHasTaxonomy() ) { return ( this_data.getTaxonomy().isEqual( other_data.getTaxonomy() ) ); } + else if ( this_data.isHasSequence() && other_data.isHasSequence() ) { + return ( this_data.getSequence().isEqual( other_data.getSequence() ) ); + } else if ( getName().length() > 0 ) { // Node name is not empty, and equal. return true; @@ -203,13 +248,14 @@ public class PhylogenyNode implements PhylogenyNodeI, Comparable } } - // --------------------------------------------------------- - // Obtaining of Nodes - // --------------------------------------------------------- + final public List getAllDescendants() { + return _descendants; + } + /** * Returns a List containing references to all external children of this * PhylogenyNode. - * + * * @return List of references to external Nodes */ final public List getAllExternalDescendants() { @@ -237,7 +283,7 @@ public class PhylogenyNode implements PhylogenyNodeI, Comparable /** * Returns a List containing references to all names of the external * children of this PhylogenyNode. - * + * * @return List of references to names of external Nodes */ final public List getAllExternalDescendantsNames() { @@ -256,20 +302,15 @@ public class PhylogenyNode implements PhylogenyNodeI, Comparable return _branch_data; } - final BranchData getBranchDataDirectly() { - return _branch_data; - } - /** * This return child node n of this node. - * + * * @param n * the index of the child to get * @return the child node with index n * @throws IllegalArgumentException * if n is out of bounds */ - @Override final public PhylogenyNode getChildNode( final int i ) { if ( isExternal() ) { throw new UnsupportedOperationException( "attempt to get the child node of an external node." ); @@ -302,7 +343,7 @@ public class PhylogenyNode implements PhylogenyNodeI, Comparable /** * This gets the child node index of this node. *

- * + * * @return the child node index of this node * @throws UnsupportedOperationException * if this node is a root node @@ -316,7 +357,7 @@ public class PhylogenyNode implements PhylogenyNodeI, Comparable * parent *

* [last modified Aug 14, 2006 by CMZ] - * + * * @return the child node index of this node * @throws UnsupportedOperationException * if this node is a root node @@ -334,6 +375,9 @@ public class PhylogenyNode implements PhylogenyNodeI, Comparable } final public List getDescendants() { + if ( _descendants == null ) { + _descendants = new ArrayList(); + } return _descendants; } @@ -341,7 +385,6 @@ public class PhylogenyNode implements PhylogenyNodeI, Comparable * Returns the length of the branch leading to the _parent of this * PhylogenyNode (double). */ - @Override final public double getDistanceToParent() { return _distance_parent; } @@ -350,7 +393,7 @@ public class PhylogenyNode implements PhylogenyNodeI, Comparable * Convenience method. Returns the first child node of this node. *

* [last modified May 18, 2005 by CMZ] - * + * * @return the first child node of this node */ public final PhylogenyNode getFirstChildNode() { @@ -358,6 +401,13 @@ public class PhylogenyNode implements PhylogenyNodeI, Comparable } /** + * Returns the ID (int) of this PhylogenyNode. + */ + final public long getId() { + return _id; + } + + /** * Returns the _indicator value of this PhylogenyNode. */ public final byte getIndicator() { @@ -368,7 +418,7 @@ public class PhylogenyNode implements PhylogenyNodeI, Comparable * Convenience method. Returns the last child node of this node. *

* [last modified May 18, 2005 by CMZ] - * + * * @return the last child node of this node */ public final PhylogenyNode getLastChildNode() { @@ -384,6 +434,10 @@ public class PhylogenyNode implements PhylogenyNodeI, Comparable return _link; } + final public String getName() { + return getNodeData().getNodeName(); + } + /** * Returns a refernce to the next external PhylogenyNode of this * PhylogenyNode. TODO should be in Phylogeny. Returns null if no next @@ -446,7 +500,7 @@ public class PhylogenyNode implements PhylogenyNodeI, Comparable previous_node = current_node; current_node = current_node.getParent(); } - if ( index < current_node.getNumberOfDescendants() - 1 ) { + if ( index < ( current_node.getNumberOfDescendants() - 1 ) ) { current_node = current_node.getChildNode( index + 1 ); } while ( current_node.isInternal() && !current_node.isCollapse() ) { @@ -462,30 +516,10 @@ public class PhylogenyNode implements PhylogenyNodeI, Comparable return _node_data; } - final NodeData getNodeDataDirectly() { - return _node_data; - } - - // --------------------------------------------------------- - // Set and get methods for Nodes - // --------------------------------------------------------- - /** - * Returns the ID (int) of this PhylogenyNode. - */ - @Override - final public int getId() { - return _id; - } - - /** - * Returns the name of this node. - */ - @Override - final public String getName() { - return getNodeData().getNodeName(); - } - final public int getNumberOfDescendants() { + if ( _descendants == null ) { + return 0; + } return _descendants.size(); } @@ -577,32 +611,6 @@ public class PhylogenyNode implements PhylogenyNodeI, Comparable return result; } - final private void init() { - _descendants = new ArrayList(); - _parent = null; - _id = 0; - initializeData(); - } - - /** - * Deletes data of this PhylogenyNode. Links to the other Nodes in the - * Phylogeny, the ID and the sum of external nodes are NOT deleted. Field - * "_link" (_link to Nodes in other Phylogeny) IS deleted. - * - * @see #getLink() (Last modified: 12/20/03) - */ - final public void initializeData() { - _indicator = 0; - _x = 0; - _y = 0; - //_node_name = ""; - _distance_parent = PhylogenyDataUtil.BRANCH_LENGTH_DEFAULT; - _collapse = false; - _link = null; - _branch_data = null; - _node_data = null; - } - /** * Returns whether this PhylogenyNode should be drawn as collapsed. */ @@ -618,20 +626,22 @@ public class PhylogenyNode implements PhylogenyNodeI, Comparable return getNodeData().isHasEvent() && getNodeData().getEvent().isDuplication(); } + public boolean isEmpty() { + return ( ( _node_data == null ) || _node_data.isEmpty() ); + } + /** * Checks whether this PhylogenyNode is external (tip). - * + * * @return true if this PhylogenyNode is external, false otherwise */ final public boolean isExternal() { + if ( _descendants == null ) { + return true; + } return ( getNumberOfDescendants() < 1 ); } - /** - * DOCUMENT ME! - * - * @return DOCUMENT ME! - */ final public boolean isFirstChildNode() { if ( isRoot() /* and tree is rooted TODO */) { throw new UnsupportedOperationException( "Cannot determine whether the root is the first child node of its _parent." ); @@ -639,11 +649,6 @@ public class PhylogenyNode implements PhylogenyNodeI, Comparable return ( getChildNodeIndex() == 0 ); } - /** - * DOCUMENT ME! - * - * @return DOCUMENT ME! - */ final public boolean isFirstExternalNode() { if ( isInternal() ) { return false; @@ -674,7 +679,7 @@ public class PhylogenyNode implements PhylogenyNodeI, Comparable /** * Checks whether this PhylogenyNode is internal (tip). - * + * * @return true if this PhylogenyNode is external, false otherwise */ final public boolean isInternal() { @@ -685,7 +690,7 @@ public class PhylogenyNode implements PhylogenyNodeI, Comparable * Returns true if this node is the last child node of its _parent. *

* [last modified June 01, 2005 by CMZ] - * + * * @return true if this node is the last child node of its _parent, false * otherwise */ @@ -696,11 +701,6 @@ public class PhylogenyNode implements PhylogenyNodeI, Comparable return ( getChildNodeIndex() == ( getParent().getNumberOfDescendants() - 1 ) ); } - /** - * DOCUMENT ME! - * - * @return DOCUMENT ME! - */ final public boolean isLastExternalNode() { if ( isInternal() ) { return false; @@ -717,7 +717,7 @@ public class PhylogenyNode implements PhylogenyNodeI, Comparable /** * Checks whether this PhylogenyNode is a root. - * + * * @return true if this PhylogenyNode is the root, false otherwise */ final public boolean isRoot() { @@ -729,13 +729,6 @@ public class PhylogenyNode implements PhylogenyNodeI, Comparable } // --------------------------------------------------------- - // Iterator - // --------------------------------------------------------- - final public PhylogenyNodeIterator iterateChildNodesForward() { - return new ChildNodeIteratorForward( this ); - } - - // --------------------------------------------------------- // Basic printing // --------------------------------------------------------- /** @@ -766,6 +759,12 @@ public class PhylogenyNode implements PhylogenyNodeI, Comparable removeChildNode( remove_me.getChildNodeIndex() ); } + public void removeConnections() { + _parent = null; + _link = null; + _descendants = null; + } + final public void setBranchData( final BranchData branch_data ) { _branch_data = branch_data; } @@ -789,7 +788,7 @@ public class PhylogenyNode implements PhylogenyNodeI, Comparable * child nodes. This does not allow null slots in the list of child nodes: * If i is larger than the number of child nodes, n is just added to the * list, not place at index i. - * + * * @param i * the index of position where to add the child * @param n @@ -805,15 +804,6 @@ public class PhylogenyNode implements PhylogenyNodeI, Comparable } } - final void setChildNodeOnly( final int i, final PhylogenyNode node ) { - if ( getNumberOfDescendants() <= i ) { - addChildNode( node ); - } - else { - getDescendants().set( i, node ); - } - } - /** * Sets whether this PhylogenyNode should be drawn as collapsed. */ @@ -825,7 +815,6 @@ public class PhylogenyNode implements PhylogenyNodeI, Comparable * Sets the length of the branch leading to the _parent of this * PhylogenyNode to double d. */ - @Override final public void setDistanceToParent( final double d ) { _distance_parent = d; } @@ -837,19 +826,6 @@ public class PhylogenyNode implements PhylogenyNodeI, Comparable _indicator = i; } - // -------------------------------------------------------------------- - // Adjust methods (related to Phylogeny construction and - // Phylogeny modification) - // -------------------------------------------------------------------- - /** - * Sets the indicators of all the children of this PhylogenyNode to zero. - */ - final void setIndicatorsToZero() { - for( final PreorderTreeIterator it = new PreorderTreeIterator( this ); it.hasNext(); ) { - it.next().setIndicator( ( byte ) 0 ); - } - } - /** * Sets the linked PhylogenyNode of this PhylogenyNode to n. Currently, this * method is only used for the speciation-_duplication assignment @@ -862,27 +838,13 @@ public class PhylogenyNode implements PhylogenyNodeI, Comparable /** * Sets the name of this node. */ - @Override final public void setName( final String node_name ) { getNodeData().setNodeName( node_name ); } /** - * Sets the Id of this PhylogenyNode to i. In most cases, this number - * should not be set to values lower than getNodeCount() -- which this method - * does not allow. - */ - synchronized final protected void setId( final int i ) { - if ( i < getNodeCount() ) { - throw new IllegalArgumentException( "attempt to set node id to a value less than total node count (thus violating the uniqueness of node ids)" ); - } - _id = i; - } - - /** * Sets the _parent PhylogenyNode of this PhylogenyNode to n. */ - @Override final public void setParent( final PhylogenyNode n ) { _parent = n; } @@ -921,20 +883,35 @@ public class PhylogenyNode implements PhylogenyNodeI, Comparable _y_secondary = y_secondary; } + /** + * Swaps the the two childern of a PhylogenyNode node of this Phylogeny. + */ + public final void swapChildren() throws RuntimeException { + if ( isExternal() ) { + throw new RuntimeException( "attempt to swap descendants of external node" ); + } + if ( getNumberOfDescendants() != 2 ) { + throw new RuntimeException( "attempt to swap descendants of node with " + getNumberOfDescendants() + + " descendants" ); + } + final PhylogenyNode a = getChildNode( 0 ); + final PhylogenyNode b = getChildNode( 1 ); + setChildNode( 0, b ); + setChildNode( 1, a ); + } + // --------------------------------------------------------- // Writing of Nodes to Strings // --------------------------------------------------------- - final public String toNewHampshire( final boolean simple_nh, - final boolean write_distance_to_parent, + final public String toNewHampshire( final boolean write_distance_to_parent, final NH_CONVERSION_SUPPORT_VALUE_STYLE svs ) { - final StringBuilder sb = new StringBuilder(); String data = ""; if ( ( svs == NH_CONVERSION_SUPPORT_VALUE_STYLE.AS_INTERNAL_NODE_NAMES ) && !isExternal() ) { if ( getBranchData().isHasConfidences() && ( getBranchData().getConfidence( 0 ).getValue() != Confidence.CONFIDENCE_DEFAULT_VALUE ) ) { data = Confidence.FORMATTER.format( ForesterUtil - .round( getBranchData().getConfidence( 0 ).getValue(), - PhyloXmlUtil.ROUNDING_DIGITS_FOR_PHYLOXML_DOUBLE_OUTPUT ) ); + .round( getBranchData().getConfidence( 0 ).getValue(), + PhyloXmlUtil.ROUNDING_DIGITS_FOR_PHYLOXML_DOUBLE_OUTPUT ) ); } } else if ( !ForesterUtil.isEmpty( getName() ) ) { @@ -950,29 +927,19 @@ public class PhylogenyNode implements PhylogenyNodeI, Comparable else if ( !ForesterUtil.isEmpty( getNodeData().getTaxonomy().getCommonName() ) ) { data = getNodeData().getTaxonomy().getCommonName(); } - else if ( getNodeData().getTaxonomy().getTaxonomyCode() != null ) { - data = getNodeData().getTaxonomy().getTaxonomyCode(); - } } else if ( getNodeData().isHasSequence() ) { if ( !ForesterUtil.isEmpty( getNodeData().getSequence().getName() ) ) { data = getNodeData().getSequence().getName(); } - } - if ( data.length() > 0 ) { - data = ForesterUtil.replaceIllegalNhCharacters( data ); - if ( simple_nh && ( data.length() > 10 ) ) { - data = data.substring( 0, 11 ); - } - if ( ForesterUtil.isContainsParanthesesableNhCharacter( data ) ) { - sb.append( '\'' ); - sb.append( data ); - sb.append( '\'' ); + else if ( !ForesterUtil.isEmpty( getNodeData().getSequence().getSymbol() ) ) { + data = getNodeData().getSequence().getSymbol(); } - else { - sb.append( data ); + else if ( !ForesterUtil.isEmpty( getNodeData().getSequence().getGeneName() ) ) { + data = getNodeData().getSequence().getGeneName(); } } + final StringBuilder sb = ForesterUtil.santitizeStringForNH( data ); if ( write_distance_to_parent && ( getDistanceToParent() != PhylogenyDataUtil.BRANCH_LENGTH_DEFAULT ) ) { sb.append( ":" ); sb.append( getDistanceToParent() ); @@ -982,8 +949,8 @@ public class PhylogenyNode implements PhylogenyNodeI, Comparable && ( getBranchData().getConfidence( 0 ).getValue() != Confidence.CONFIDENCE_DEFAULT_VALUE ) ) { sb.append( "[" ); sb.append( Confidence.FORMATTER.format( ForesterUtil - .round( getBranchData().getConfidence( 0 ).getValue(), - PhyloXmlUtil.ROUNDING_DIGITS_FOR_PHYLOXML_DOUBLE_OUTPUT ) ) ); + .round( getBranchData().getConfidence( 0 ).getValue(), + PhyloXmlUtil.ROUNDING_DIGITS_FOR_PHYLOXML_DOUBLE_OUTPUT ) ) ); sb.append( "]" ); } return sb.toString(); @@ -994,18 +961,10 @@ public class PhylogenyNode implements PhylogenyNodeI, Comparable * representation. */ final public String toNewHampshireX() { - final StringBuffer sb = new StringBuffer(); + final StringBuilder sb = new StringBuilder(); final StringBuffer s_nhx = new StringBuffer(); if ( !ForesterUtil.isEmpty( getName() ) ) { - final String name = ForesterUtil.replaceIllegalNhCharacters( getName() ); - if ( ForesterUtil.isContainsParanthesesableNhCharacter( name ) ) { - sb.append( '\'' ); - sb.append( name ); - sb.append( '\'' ); - } - else { - sb.append( name ); - } + sb.append( ForesterUtil.santitizeStringForNH( getName() ) ); } if ( getDistanceToParent() != PhylogenyDataUtil.BRANCH_LENGTH_DEFAULT ) { sb.append( ":" ); @@ -1032,66 +991,157 @@ public class PhylogenyNode implements PhylogenyNodeI, Comparable sb.append( getName() ); sb.append( " " ); } - sb.append( "[" ); - sb.append( getId() ); - sb.append( "]" ); - return sb.toString(); + if ( getNodeData().isHasTaxonomy() ) { + if ( !ForesterUtil.isEmpty( getNodeData().getTaxonomy().getScientificName() ) ) { + sb.append( getNodeData().getTaxonomy().getScientificName() ); + sb.append( " " ); + } + else if ( ( sb.length() <= 1 ) && !ForesterUtil.isEmpty( getNodeData().getTaxonomy().getTaxonomyCode() ) ) { + sb.append( getNodeData().getTaxonomy().getTaxonomyCode() ); + sb.append( " " ); + } + else if ( getNodeData().getTaxonomy().getIdentifier() != null ) { + sb.append( getNodeData().getTaxonomy().getIdentifier().toString() ); + sb.append( " " ); + } + } + if ( getNodeData().isHasSequence() ) { + if ( !ForesterUtil.isEmpty( getNodeData().getSequence().getName() ) ) { + sb.append( getNodeData().getSequence().getName() ); + sb.append( " " ); + } + if ( !ForesterUtil.isEmpty( getNodeData().getSequence().getSymbol() ) ) { + sb.append( getNodeData().getSequence().getSymbol() ); + sb.append( " " ); + } + if ( !ForesterUtil.isEmpty( getNodeData().getSequence().getGeneName() ) ) { + sb.append( getNodeData().getSequence().getGeneName() ); + sb.append( " " ); + } + if ( getNodeData().getSequence().getAccession() != null ) { + sb.append( getNodeData().getSequence().getAccession().toString() ); + sb.append( " " ); + } + if ( !ForesterUtil.isEmpty( getNodeData().getSequence().getMolecularSequence() ) ) { + sb.append( getNodeData().getSequence().getMolecularSequence() ); + sb.append( " " ); + } + } + if ( sb.length() <= 1 ) { + sb.append( "[" ); + sb.append( getId() ); + sb.append( "]" ); + } + return sb.toString().trim(); } /** - * Decreases the total number of all Nodes created so far by one. + * Sets the Id of this PhylogenyNode to i. In most cases, this number + * should not be set to values lower than getNodeCount() -- which this method + * does not allow. */ - final static synchronized void decreaseNodeCount() { - --PhylogenyNode._node_count; + synchronized final protected void setId( final long i ) { + if ( i < getNodeCount() ) { + throw new IllegalArgumentException( "attempt to set node id to a value less than total node count (thus violating the uniqueness of node ids)" ); + } + _id = i; } - /** - * Returns the total number of all Nodes created so far. - * - * @return total number of Nodes (int) - */ - synchronized final public static int getNodeCount() { - return PhylogenyNode._node_count; + final BranchData getBranchDataDirectly() { + return _branch_data; + } + + final NodeData getNodeDataDirectly() { + return _node_data; + } + + final void setChildNodeOnly( final int i, final PhylogenyNode node ) { + if ( getNumberOfDescendants() <= i ) { + addChildNode( node ); + } + else { + getDescendants().set( i, node ); + } } /** - * Increases the total number of all Nodes created so far by one. + * Sets the indicators of all the children of this PhylogenyNode to zero. */ - synchronized final private static void increaseNodeCount() { - ++PhylogenyNode._node_count; + final void setIndicatorsToZero() { + for( final PreorderTreeIterator it = new PreorderTreeIterator( this ); it.hasNext(); ) { + it.next().setIndicator( ( byte ) 0 ); + } } /** - * Sets the total number of all Nodes created so far to i (int). + * Adds PhylogenyNode n to the list of child nodes. But does NOT set the + * _parent of n to this. + * + * @see addAsChild( PhylogenyNode n ) + * @param n + * the PhylogenyNode to add */ - synchronized final static void setNodeCount( final int i ) { - PhylogenyNode._node_count = i; + final private void addChildNode( final PhylogenyNode child ) { + getDescendants().add( child ); } - public static PhylogenyNode createInstanceFromNhxString( final String nhx ) throws NHXFormatException { - return new PhylogenyNode( nhx, PhylogenyMethods.TAXONOMY_EXTRACTION.NO, false ); + public static PhylogenyNode createInstanceFromNhxString( final String nhx ) throws NHXFormatException, + PhyloXmlDataFormatException { + return new PhylogenyNode( nhx, NHXParser.TAXONOMY_EXTRACTION.NO, false ); } public static PhylogenyNode createInstanceFromNhxString( final String nhx, - final PhylogenyMethods.TAXONOMY_EXTRACTION taxonomy_extraction ) - throws NHXFormatException { + final NHXParser.TAXONOMY_EXTRACTION taxonomy_extraction ) + throws NHXFormatException, PhyloXmlDataFormatException { return new PhylogenyNode( nhx, taxonomy_extraction, false ); } public static PhylogenyNode createInstanceFromNhxString( final String nhx, - final PhylogenyMethods.TAXONOMY_EXTRACTION taxonomy_extraction, + final NHXParser.TAXONOMY_EXTRACTION taxonomy_extraction, final boolean replace_underscores ) - throws NHXFormatException { + throws NHXFormatException, PhyloXmlDataFormatException { return new PhylogenyNode( nhx, taxonomy_extraction, replace_underscores ); } + + public static PhylogenyNode createInstanceFromNhxString( final String nhx, + final NHXParser.TAXONOMY_EXTRACTION taxonomy_extraction, + final boolean replace_underscores, + final boolean parse_extended_tags ) + throws NHXFormatException, PhyloXmlDataFormatException { + return new PhylogenyNode( nhx, taxonomy_extraction, replace_underscores, parse_extended_tags ); + } - private PhylogenyNode( final String nhx, - final PhylogenyMethods.TAXONOMY_EXTRACTION taxonomy_extraction, - final boolean replace_underscores ) throws NHXFormatException { - init(); - NHXParser.parseNHX( nhx, this, taxonomy_extraction, replace_underscores ); - setId( PhylogenyNode.getNodeCount() ); - PhylogenyNode.increaseNodeCount(); - setSumExtNodes( 1 ); // For ext node, this number is 1 (not 0!!) + /** + * Returns the total number of all Nodes created so far. + * + * @return total number of Nodes (long) + */ + synchronized final public static long getNodeCount() { + return NODE_COUNT; + } + + /** + * Decreases the total number of all Nodes created so far by one. + */ + final static synchronized void decreaseNodeCount() { + --NODE_COUNT; + } + + /** + * Sets the total number of all Nodes created so far to i. + */ + synchronized final static void setNodeCount( final long i ) { + PhylogenyNode.NODE_COUNT = i; + } + + /** + * Increases the total number of all Nodes created so far by one. + */ + synchronized final private static void increaseNodeCount() { + ++NODE_COUNT; + } + + public enum NH_CONVERSION_SUPPORT_VALUE_STYLE { + AS_INTERNAL_NODE_NAMES, IN_SQUARE_BRACKETS, NONE; } }