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 ]
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 ]
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)
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)