def remove_mediators(tree, columns):
    """
    Removes intermediate nodes that are just mediators between their parent and child states.
    :param columns: list of characters
    :param tree: ete3.Tree
    :return: void, modifies the input tree
    """
    num_removed = 0
    for n in tree.traverse('postorder'):
        if getattr(n, METACHILD, False) or n.is_leaf() or len(n.children) > 1 or n.is_root() \
                or getattr(n, NUM_TIPS_INSIDE) > 0:
            continue

        parent = n.up
        child = n.children[0]

        compatible = True
        for column in columns:
            states = getattr(n, column, set())
            parent_states = getattr(parent, column, set())
            child_states = getattr(child, column, set())
            # if mediator has unresolved states, it should hesitate between the parent and the child:
            if states != child_states | parent_states:
                compatible = False
                break

        if compatible:
            parent.remove_child(n)
            parent.add_child(child)
            num_removed += 1
    if num_removed:
        logging.getLogger('pastml').debug("Removed {} internal node{}"
                                          " with the state unresolved between the parent's and the only child's."
                                          .format(num_removed, '' if num_removed == 1 else 's'))
def remove_mediators ( tree , columns ) : num_removed = 0 for n in tree . traverse ( 'postorder' ) : if getattr ( n , METACHILD , False ) or n . is_leaf ( ) or len ( n . children ) > 1 or n . is_root ( ) or getattr ( n , NUM_TIPS_INSIDE ) > 0 : continue parent = n . up child = n . children [ 0 ] compatible = True for column in columns : states = getattr ( n , column , set ( ) ) parent_states = getattr ( parent , column , set ( ) ) child_states = getattr ( child , column , set ( ) ) if states != child_states | parent_states : compatible = False break if compatible : parent . remove_child ( n ) parent . add_child ( child ) num_removed += 1 if num_removed : logging . getLogger ( 'pastml' ) . debug ( "Removed {} internal node{}" " with the state unresolved between the parent's and the only child's." . format ( num_removed , '' if num_removed == 1 else 's' ) )
Removes intermediate nodes that are just mediators between their parent and child states.
    :param columns: list of characters
    :param tree: ete3.Tree
    :return: void, modifies the input tree