예제 #1
0
    def __TreeFromBipartition(self, bp):
        """Generate an initial non-binary tree from a bipartition"""

        e = Edge(tree=self.__tree)
        left = Inner(edges=[e], tree=self.__tree)
        right = Inner(edges=[e], tree=self.__tree)

        [
            Edge(nodes=[Leaf(label=str(leaf), tree=self.__tree), left],
                 tree=self.__tree) for leaf in bp.left
        ]
        [
            Edge(nodes=[Leaf(label=str(leaf), tree=self.__tree), right],
                 tree=self.__tree) for leaf in bp.right
        ]
예제 #2
0
    def __AddNewEdge(self, smallerLeafIds, commonAncestorNodes):
        """Add a new edge to one of the common ancestor nodes"""

        # For each common ancestor find the subtrees containing
        # members of the smaller set.

        edgesToMove = []
        for ancestorNode in commonAncestorNodes:
            for downEdge in ancestorNode.edges:
                childNode = downEdge.Other(ancestorNode)
                if childNode not in commonAncestorNodes:
                    childLeafIds = set(
                        str(l) for l in childNode.Leaves(downEdge))
                    if len(childLeafIds.intersection(smallerLeafIds)):
                        edgesToMove.append((downEdge, ancestorNode))

        # Disconnect the subtrees from their common ancestors

        [edgeTuple[1].RemoveEdge(edgeTuple[0]) for edgeTuple in edgesToMove]

        # Find the new position for the edges looking for a node with the smallest number
        # of edges

        oldInner = min(commonAncestorNodes, key=lambda e: len(e.edges))
        newInner = Inner(edges=[e[0] for e in edgesToMove], tree=self.__tree)
        Edge(nodes=[newInner, oldInner], tree=self.__tree)

        # If any of the ancestor nodes now only have two edges, condense them out

        [
            self.__CondenseNode(n) for n in commonAncestorNodes
            if len(n.edges) == 2
        ]
예제 #3
0
    def MakeBinary(self):
        """Convert vertices of degree >3 to degree 3 by breaking off pairs of edges"""

        # Loop through the non-binary vertices

        for nbv in (v for v in self.__tree.vertices if len(v.edges) > 3):

            # Split off pair of edges until the vertex is properly binary

            while len(nbv.edges) > 3:
                depths = sorted(((e.Depth(nbv), e) for e in nbv.edges),
                                key=itemgetter(0))
                e1 = depths[0][1]
                e2 = depths[1][1]
                e1.RemoveNode(nbv)
                e2.RemoveNode(nbv)
                Edge(nodes=[nbv, Inner(edges=[e1, e2], tree=self.__tree)],
                     tree=self.__tree)
예제 #4
0
    def __SplitEdge(self, edge, id):
        """
        Add a new taxa by splitting an existing edge
        """

        # Disconnect the edge

        nright = edge.nodes[0]
        nleft = edge.nodes[1]
        nright.RemoveEdge(edge)
        nleft.RemoveEdge(edge)

        # Connect it all up

        Leaf(label=id, edge=edge, tree=self.__tree)
        Inner(edges=[
            Edge(nodes=[nleft], tree=self.__tree),
            Edge(nodes=[nright], tree=self.__tree), edge
        ],
              tree=self.__tree)