Esempio n. 1
0
def sample_birth_death_gene_tree(stree,
                                 birth,
                                 death,
                                 genename=lambda sp, x: sp + "_" + str(x),
                                 removeloss=True):
    """Simulate a gene tree within a species tree with birth and death rates"""

    # initialize gene tree
    tree = treelib.Tree()
    tree.make_root()
    recon = {tree.root: stree.root}
    events = {tree.root: "spec"}
    losses = set()

    def walk(snode, node):
        if snode.is_leaf():
            tree.rename(node.name, genename(snode.name, node.name))
            events[node] = "gene"
        else:
            for child in snode:
                # determine if loss will occur
                tree2, doom = sample_birth_death_tree(child.dist,
                                                      birth,
                                                      death,
                                                      tree=tree,
                                                      node=node,
                                                      keepdoom=True)

                # record reconciliation
                next_nodes = []

                def walk2(node):
                    node.recurse(walk2)
                    recon[node] = child
                    if node in doom:
                        losses.add(node)
                        events[node] = "gene"
                    elif node.is_leaf():
                        events[node] = "spec"
                        next_nodes.append(node)
                    else:
                        events[node] = "dup"

                walk2(node.children[-1])

                # recurse
                for leaf in next_nodes:
                    walk(child, leaf)

            # if no child for node then it is a loss
            if node.is_leaf():
                losses.add(node)

    walk(stree.root, tree.root)

    # remove lost nodes
    if removeloss:
        treelib.remove_exposed_internal_nodes(tree,
                                              set(tree.leaves()) - losses)
        treelib.remove_single_children(tree, simplify_root=False)

        delnodes = set()
        for node in recon:
            if node.name not in tree.nodes:
                delnodes.add(node)
        for node in delnodes:
            del recon[node]
            del events[node]

    if len(tree.nodes) <= 1:
        tree.nodes = {tree.root.name: tree.root}
        recon = {tree.root: stree.root}
        events = {tree.root: "spec"}

    return tree, recon, events
Esempio n. 2
0
def sample_birth_death_gene_tree(stree, birth, death, 
                                 genename=lambda sp, x: sp + "_" + str(x),
                                 removeloss=True):
    """Simulate a gene tree within a species tree with birth and death rates"""
    
    # initialize gene tree
    tree = treelib.Tree()
    tree.make_root()
    recon = {tree.root: stree.root}
    events = {tree.root: "spec"}
    losses = set()
    
    def walk(snode, node):
        if snode.is_leaf():
            tree.rename(node.name, genename(snode.name, node.name))
            events[node] = "gene"
        else:
            for child in snode:
                # determine if loss will occur
                tree2, doom = sample_birth_death_tree(
                    child.dist, birth, death, 
                    tree=tree, node=node, keepdoom=True)
                
                # record reconciliation
                next_nodes = []
                def walk2(node):
                    node.recurse(walk2)
                    recon[node] = child
                    if node in doom:
                        losses.add(node)
                        events[node] = "gene"
                    elif node.is_leaf():
                        events[node] = "spec"
                        next_nodes.append(node)
                    else:
                        events[node] = "dup"
                walk2(node.children[-1])
                
                # recurse
                for leaf in next_nodes:
                    walk(child, leaf)
            
            # if no child for node then it is a loss
            if node.is_leaf():
                losses.add(node)
    walk(stree.root, tree.root)
    
    
    # remove lost nodes
    if removeloss:
        treelib.remove_exposed_internal_nodes(tree,
                                              set(tree.leaves()) - losses)
        treelib.remove_single_children(tree, simplify_root=False)
        
        delnodes = set()
        for node in recon:
            if node.name not in tree.nodes:
                delnodes.add(node)
        for node in delnodes:
            del recon[node]
            del events[node]

    if len(tree.nodes) <= 1:
        tree.nodes = {tree.root.name : tree.root}
        recon = {tree.root: stree.root}
        events = {tree.root: "spec"}
    
    return tree, recon, events