def collapse_vertically(tree, columns):
    """
    Collapses a child node into its parent if they are in the same state.
    :param columns: a list of characters
    :param tree: ete3.Tree
    :return: void, modifies the input tree
    """

    def _same_states(node1, node2, columns):
        for column in columns:
            if getattr(node1, column, set()) != getattr(node2, column, set()):
                return False
        return True

    num_collapsed = 0
    for n in tree.traverse('postorder'):
        if n.is_leaf():
            continue

        children = list(n.children)
        for child in children:
            # merge the child into this node if their states are the same
            if _same_states(n, child, columns):
                getattr(n, TIPS_INSIDE).extend(getattr(child, TIPS_INSIDE))
                getattr(n, INTERNAL_NODES_INSIDE).extend(getattr(child, INTERNAL_NODES_INSIDE))

                n.remove_child(child)
                grandchildren = list(child.children)
                for grandchild in grandchildren:
                    n.add_child(grandchild)
                num_collapsed += 1
    if num_collapsed:
        logging.getLogger('pastml').debug('Collapsed vertically {} internal nodes without state change.'
                                          .format(num_collapsed))
def collapse_vertically ( tree , columns ) : def _same_states ( node1 , node2 , columns ) : for column in columns : if getattr ( node1 , column , set ( ) ) != getattr ( node2 , column , set ( ) ) : return False return True num_collapsed = 0 for n in tree . traverse ( 'postorder' ) : if n . is_leaf ( ) : continue children = list ( n . children ) for child in children : if _same_states ( n , child , columns ) : getattr ( n , TIPS_INSIDE ) . extend ( getattr ( child , TIPS_INSIDE ) ) getattr ( n , INTERNAL_NODES_INSIDE ) . extend ( getattr ( child , INTERNAL_NODES_INSIDE ) ) n . remove_child ( child ) grandchildren = list ( child . children ) for grandchild in grandchildren : n . add_child ( grandchild ) num_collapsed += 1 if num_collapsed : logging . getLogger ( 'pastml' ) . debug ( 'Collapsed vertically {} internal nodes without state change.' . format ( num_collapsed ) )
Collapses a child node into its parent if they are in the same state.
    :param columns: a list of characters
    :param tree: ete3.Tree
    :return: void, modifies the input tree