Skip to content

Commit

Permalink
Move resolve_polytomy() to operations.pyx.
Browse files Browse the repository at this point in the history
  • Loading branch information
jordibc committed Jan 19, 2024
1 parent bb3b954 commit d679d13
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 16 deletions.
29 changes: 29 additions & 0 deletions ete4/core/operations.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,35 @@ def to_ultrametric(tree, topological=False):
node.dist *= (dist_full - d) / node.size[0]


def resolve_polytomy(tree, descendants=True):
"""Convert tree to a series of dicotomies if it is a polytomy.
A polytomy is a node that has more than 2 children. This
function changes them to a ladderized series of dicotomic
branches. The tree topology modification is arbitrary (no
important results should depend on it!).
:param descendants: If True, resolve all polytomies in the tree,
including all root descendants. Otherwise, do it only for the root.
"""
for node in tree.traverse():
if len(node.children) > 2:
children = node.remove_children() # x ::: a,b,c,d,e

# Create "backbone" nodes: x --- * --- * ---
for i in range(len(children) - 2):
node = node.add_child(dist=0, support=0)

# Add children in order: x === d,* === c,* === b,a
node.add_child(children[0]) # first: x --- * --- * --- a
for i in range(1, len(children)):
node.add_child(children[i], support=0)
node = node.up

if not descendants:
break


# Traversing the tree.

# Position on the tree: current node, number of visited children.
Expand Down
17 changes: 1 addition & 16 deletions ete4/core/tree.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -1798,22 +1798,7 @@ cdef class Tree(object):
:param descendants: If True, resolve all polytomies under this
node too. Otherwise, do it only for the current node.
"""
for node in self.traverse():
if len(node.children) > 2:
children = node.remove_children() # x ::: a,b,c,d,e

# Create "backbone" nodes: x --- * --- * ---
for i in range(len(children) - 2):
node = node.add_child(dist=0, support=0)

# Add children in order: x === d,* === c,* === b,a
node.add_child(children[0]) # first: x --- * --- * --- a
for i in range(1, len(children)):
node.add_child(children[i], support=0)
node = node.up

if not descendants:
break
ops.resolve_polytomy(self, descendants)

def cophenetic_matrix(self):
"""Return a cophenetic distance matrix of the tree.
Expand Down

0 comments on commit d679d13

Please sign in to comment.