X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=forester%2Fjava%2Fsrc%2Forg%2Fforester%2Fphylogeny%2FPhylogenyNode.java;h=8dedcd20a9989d54049799d8a266d78fa12a6725;hb=e37b8c622b4d0a46d3dd170e3cd130bca39ee468;hp=253c4c3cd245e5752c13ced2713a6b718765f3b4;hpb=eee996a6476a1e3d84c07f8f690dcde3ff4b2ef5;p=jalview.git diff --git a/forester/java/src/org/forester/phylogeny/PhylogenyNode.java b/forester/java/src/org/forester/phylogeny/PhylogenyNode.java index 253c4c3..8dedcd2 100644 --- a/forester/java/src/org/forester/phylogeny/PhylogenyNode.java +++ b/forester/java/src/org/forester/phylogeny/PhylogenyNode.java @@ -32,25 +32,25 @@ import java.util.List; import org.forester.io.parsers.nhx.NHXFormatException; import org.forester.io.parsers.nhx.NHXParser; -import org.forester.io.parsers.util.PhylogenyParserException; +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 { +public final class PhylogenyNode implements PhylogenyNodeI, Comparable { - /** Value of -99.0 is used as default value. */ - public final static double DISTANCE_DEFAULT = -1024.0; 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 double _distance_parent = PhylogenyDataUtil.BRANCH_LENGTH_DEFAULT; private boolean _collapse; private PhylogenyNode _parent; private PhylogenyNode _link; @@ -64,43 +64,18 @@ public class PhylogenyNode implements PhylogenyNodeI, Comparable * Default constructor for PhylogenyNode. */ public PhylogenyNode() { - init(); + // init(); setId( PhylogenyNode.getNodeCount() ); PhylogenyNode.increaseNodeCount(); setSumExtNodes( 1 ); // For ext node, this number is 1 (not 0!!) } - public PhylogenyNode( final String nhx ) throws NHXFormatException { - this( nhx, ForesterUtil.TAXONOMY_EXTRACTION.NO ); - } - - public PhylogenyNode( final String nhx, final ForesterUtil.TAXONOMY_EXTRACTION taxonomy_extraction ) - throws NHXFormatException { - init(); - NHXParser.parseNHX( nhx, this, taxonomy_extraction, false ); - setId( PhylogenyNode.getNodeCount() ); - PhylogenyNode.increaseNodeCount(); - setSumExtNodes( 1 ); // For ext node, this number is 1 (not 0!!) - } - - /** - * Constructor for PhylogenyNode. - *

- * - * @param s - * String representing one PhylogenyNode in New Hampshire (NH) or - * New Hampshire X (NHX) format. - * @throws NHXFormatException - * @throws PhylogenyParserException - */ - public PhylogenyNode( final String nhx, - final ForesterUtil.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!!) + public void reset() { + _parent = null; + _link = null; + _descendants = null; + _node_data = null; + _branch_data = null; } /** @@ -367,6 +342,9 @@ public class PhylogenyNode implements PhylogenyNodeI, Comparable } final public List getDescendants() { + if ( _descendants == null ) { + _descendants = new ArrayList(); + } return _descendants; } @@ -445,6 +423,49 @@ public class PhylogenyNode implements PhylogenyNodeI, Comparable return current_node; } + public final PhylogenyNode getNextExternalNodeWhileTakingIntoAccountCollapsedNodes() { + //TODO work on me ~~ + if ( isInternal() && !isCollapse() ) { + throw new UnsupportedOperationException( "attempt to get next external node of an uncollapsed internal node" ); + } + if ( isRoot() ) { + return null; + } + if ( getParent().isCollapse() ) { + throw new UnsupportedOperationException( "attempt to get next external node of node with a collapsed parent" ); + } + // This checks if last node. + PhylogenyNode n = this; + boolean last = true; + while ( !n.isRoot() ) { + if ( !n.isLastChildNode() ) { + last = false; + break; + } + n = n.getParent(); + } + if ( last ) { + return null; + } + int index = getChildNodeIndex(); + PhylogenyNode previous_node = this; + PhylogenyNode current_node = getParent(); + while ( !current_node.isRoot() + && ( current_node.isCollapse() || ( current_node.getNumberOfDescendants() == 1 ) || previous_node + .isLastChildNode() ) ) { + index = current_node.getChildNodeIndex(); + previous_node = current_node; + current_node = current_node.getParent(); + } + if ( index < current_node.getNumberOfDescendants() - 1 ) { + current_node = current_node.getChildNode( index + 1 ); + } + while ( current_node.isInternal() && !current_node.isCollapse() ) { + current_node = current_node.getFirstChildNode(); + } + return current_node; + } + public final NodeData getNodeData() { if ( _node_data == null ) { _node_data = new NodeData(); @@ -476,6 +497,9 @@ public class PhylogenyNode implements PhylogenyNodeI, Comparable } final public int getNumberOfDescendants() { + if ( _descendants == null ) { + return 0; + } return _descendants.size(); } @@ -567,13 +591,12 @@ public class PhylogenyNode implements PhylogenyNodeI, Comparable return result; } - final private void init() { - _descendants = new ArrayList(); - _parent = null; - _id = 0; - initializeData(); - } - + // final private void init() { + //_descendants = new ArrayList(); + // _parent = null; //TODO not needed? + // _id = 0; //TODO not needed? + //initializeData(); //TODO not needed? + //} /** * 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 @@ -581,18 +604,17 @@ public class PhylogenyNode implements PhylogenyNodeI, Comparable * * @see #getLink() (Last modified: 12/20/03) */ - final public void initializeData() { - _indicator = 0; - _x = 0; - _y = 0; - //_node_name = ""; - _distance_parent = PhylogenyNode.DISTANCE_DEFAULT; - _collapse = false; - _link = null; - _branch_data = null; - _node_data = null; - } - + // final private 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. */ @@ -614,6 +636,9 @@ public class PhylogenyNode implements PhylogenyNodeI, Comparable * @return true if this PhylogenyNode is external, false otherwise */ final public boolean isExternal() { + if ( _descendants == null ) { + return true; + } return ( getNumberOfDescendants() < 1 ); } @@ -914,10 +939,20 @@ public class PhylogenyNode implements PhylogenyNodeI, Comparable // --------------------------------------------------------- // 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 simple_nh, + final boolean write_distance_to_parent, + final NH_CONVERSION_SUPPORT_VALUE_STYLE svs ) { final StringBuilder sb = new StringBuilder(); String data = ""; - if ( !ForesterUtil.isEmpty( getName() ) ) { + 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 ) ); + } + } + else if ( !ForesterUtil.isEmpty( getName() ) ) { data = getName(); } else if ( getNodeData().isHasTaxonomy() ) { @@ -953,14 +988,40 @@ public class PhylogenyNode implements PhylogenyNodeI, Comparable sb.append( data ); } } - if ( ( getDistanceToParent() != PhylogenyNode.DISTANCE_DEFAULT ) && write_distance_to_parent ) { + if ( write_distance_to_parent && ( getDistanceToParent() != PhylogenyDataUtil.BRANCH_LENGTH_DEFAULT ) ) { sb.append( ":" ); sb.append( getDistanceToParent() ); } + if ( ( svs == NH_CONVERSION_SUPPORT_VALUE_STYLE.IN_SQUARE_BRACKETS ) && !isExternal() + && getBranchData().isHasConfidences() + && ( 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 ) ) ); + sb.append( "]" ); + } return sb.toString(); } /** + * 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 ); + } + + /** * Converts this PhylogenyNode to a New Hampshire X (NHX) String * representation. */ @@ -978,7 +1039,7 @@ public class PhylogenyNode implements PhylogenyNodeI, Comparable sb.append( name ); } } - if ( getDistanceToParent() != PhylogenyNode.DISTANCE_DEFAULT ) { + if ( getDistanceToParent() != PhylogenyDataUtil.BRANCH_LENGTH_DEFAULT ) { sb.append( ":" ); sb.append( getDistanceToParent() ); } @@ -998,15 +1059,45 @@ public class PhylogenyNode implements PhylogenyNodeI, Comparable @Override final public String toString() { - final StringBuilder sb = new StringBuilder(); - if ( !ForesterUtil.isEmpty( getName() ) ) { + StringBuilder sb = new StringBuilder(); + if ( ForesterUtil.isEmpty( getName() ) ) { 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 ( !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( " " ); + } + else if ( !ForesterUtil.isEmpty( getNodeData().getSequence().getSymbol() ) ) { + sb.append( getNodeData().getSequence().getSymbol() ); + sb.append( " " ); + } + else if ( getNodeData().getSequence().getAccession() != null ) { + sb.append( getNodeData().getTaxonomy().getIdentifier().toString() ); + sb.append( " " ); + } + } + if ( sb.length() <= 1 ) { + sb.append( "[" ); + sb.append( getId() ); + sb.append( "]" ); + } + return sb.toString().trim(); } /** @@ -1038,4 +1129,31 @@ public class PhylogenyNode implements PhylogenyNodeI, Comparable synchronized final static void setNodeCount( final int i ) { PhylogenyNode._node_count = i; } + + 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, + final PhylogenyMethods.TAXONOMY_EXTRACTION taxonomy_extraction ) + throws NHXFormatException { + return new PhylogenyNode( nhx, taxonomy_extraction, false ); + } + + public static PhylogenyNode createInstanceFromNhxString( final String nhx, + final PhylogenyMethods.TAXONOMY_EXTRACTION taxonomy_extraction, + final boolean replace_underscores ) + throws NHXFormatException { + return new PhylogenyNode( nhx, taxonomy_extraction, replace_underscores ); + } + + 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!!) + } }