def calc_doom_table(tree, birth, death, maxdoom=20, nodelookup=None): """Compute a doom table for a species tree 'tree'""" if nodelookup is None: ptree, nodes, nodelookup = spidir.make_ptree(tree) doomtable = [0] * len(tree.nodes) def walk(node): if node.is_leaf(): doomtable[nodelookup[node]] = -util.INF else: for child in node.children: walk(child) i = nodelookup[node] p = 1.0 for child in node: p *= sum( birthdeath.prob_birth_death1(d, child.dist, birth, death) * exp(doomtable[nodelookup[child]]) ** d for d in range(0, maxdoom + 1) ) doomtable[i] = util.safelog(p, e, -util.INF) walk(tree.root) return doomtable
def calc_doom_table(tree, birth, death, maxdoom=20, nodelookup=None): """Compute a doom table for a species tree 'tree'""" if nodelookup is None: ptree, nodes, nodelookup = spidir.make_ptree(tree) doomtable = [0] * len(tree.nodes) def walk(node): if node.is_leaf(): doomtable[nodelookup[node]] = -util.INF else: for child in node.children: walk(child) i = nodelookup[node] p = 1.0 for child in node: p *= sum( birthdeath.prob_birth_death1(d, child.dist, birth, death) * exp(doomtable[nodelookup[child]])**d for d in range(0, maxdoom + 1)) doomtable[i] = util.safelog(p, e, -util.INF) walk(tree.root) return doomtable
def dup_loss_topology_prior(tree, stree, recon, birth, death, maxdoom=20, events=None): """ Returns the log prior of a gene tree topology according to dup-loss model """ def gene2species(gene): return recon[tree.nodes[gene]].name if events is None: events = phylo.label_events(tree, recon) leaves = set(tree.leaves()) phylo.add_implied_spec_nodes(tree, stree, recon, events) pstree, snodes, snodelookup = spidir.make_ptree(stree) # get doomtable doomtable = calc_doom_table(stree, birth, death, maxdoom) prod = 0.0 for node in tree: if events[node] == "spec": for schild in recon[node].children: nodes2 = [x for x in node.children if recon[x] == schild] if len(nodes2) > 0: node2 = nodes2[0] subleaves = get_sub_tree(node2, schild, recon, events) nhist = birthdeath.num_topology_histories(node2, subleaves) s = len(subleaves) thist = stats.factorial(s) * stats.factorial(s - 1) / 2 ** (s - 1) if len(set(subleaves) & leaves) == 0: # internal prod += log(num_redundant_topology(node2, gene2species, subleaves, True)) else: # leaves prod += log(num_redundant_topology(node2, gene2species, subleaves, False)) else: nhist = 1.0 thist = 1.0 s = 0 t = sum( stats.choose(s + i, i) * birthdeath.prob_birth_death1(s + i, schild.dist, birth, death) * exp(doomtable[snodelookup[schild]]) ** i for i in range(maxdoom + 1) ) prod += log(nhist) - log(thist) + log(t) # correct for renumbering nt = num_redundant_topology(tree.root, gene2species) prod -= log(nt) # phylo.removeImpliedSpecNodes(tree, recon, events) treelib.remove_single_children(tree) return prod
def assert_doom_table(self, tree, l, u, maxdoom): ctree = spidir.tree2ctree(tree) ptree, nodes, nodelookup = spidir.make_ptree(tree) treelib.draw_tree(tree, scale=10) doomtable = [0] * len(tree.nodes) doomtable = spidir.c_list(ctypes.c_double, doomtable) spidir.calcDoomTable(ctree, l, u, maxdoom, doomtable) spidir.deleteTree(ctree) doomtable2 = calc_doom_table(tree, l, u, maxdoom) print list(doomtable) print doomtable2 for i, j in zip(doomtable, doomtable2): fequal(i, j)
def dup_loss_topology_prior(tree, stree, recon, birth, death, maxdoom=20, events=None): """ Returns the log prior of a gene tree topology according to dup-loss model """ def gene2species(gene): return recon[tree.nodes[gene]].name if events is None: events = phylo.label_events(tree, recon) leaves = set(tree.leaves()) phylo.add_implied_spec_nodes(tree, stree, recon, events) pstree, snodes, snodelookup = spidir.make_ptree(stree) # get doomtable doomtable = calc_doom_table(stree, birth, death, maxdoom) prod = 0.0 for node in tree: if events[node] == "spec": for schild in recon[node].children: nodes2 = [x for x in node.children if recon[x] == schild] if len(nodes2) > 0: node2 = nodes2[0] subleaves = get_sub_tree(node2, schild, recon, events) nhist = birthdeath.num_topology_histories(node2, subleaves) s = len(subleaves) thist = stats.factorial(s) * stats.factorial(s - 1) / 2**( s - 1) if len(set(subleaves) & leaves) == 0: # internal prod += log( num_redundant_topology(node2, gene2species, subleaves, True)) else: # leaves prod += log( num_redundant_topology(node2, gene2species, subleaves, False)) else: nhist = 1.0 thist = 1.0 s = 0 t = sum( stats.choose(s + i, i) * birthdeath.prob_birth_death1( s + i, schild.dist, birth, death) * exp(doomtable[snodelookup[schild]])**i for i in range(maxdoom + 1)) prod += log(nhist) - log(thist) + log(t) # correct for renumbering nt = num_redundant_topology(tree.root, gene2species) prod -= log(nt) #phylo.removeImpliedSpecNodes(tree, recon, events) treelib.remove_single_children(tree) return prod