def generate_single_labeled_history(tree, pop_size=None, rng=None): # get collection of nodes organized by the order # of coalescence as given by the level node_event_order = {} event_nodes = {} num_leaves = 0 for nd in tree.postorder_node_iter(): if nd.is_leaf(): node_event_order[nd] = 0 num_leaves += 1 else: eo = max([node_event_order[ch] for ch in nd.child_nodes()]) + 1 node_event_order[nd] = eo try: event_nodes[node_event_order[nd]].append(nd) except KeyError: event_nodes[node_event_order[nd]] = [nd] # set the node ages node_ages = {} event_idx_list = sorted(event_nodes.keys()) for nd in event_nodes[0]: node_ages[nd] = 0.0 current_tree_max_age = 0.0 num_nodes_remaining = num_leaves for event_idx in event_idx_list[1:]: for nd in event_nodes[event_idx]: child_nodes = nd.child_nodes() max_ch_age = max([node_ages[ch] for ch in child_nodes]) min_age = max(current_tree_max_age, max_ch_age) if rng is None: # rng is not given: use expected waiting time wt = coalescent.expected_tmrca( n_genes=num_nodes_remaining, pop_size=pop_size, n_to_coalesce=len(child_nodes)) else: # rng is given: draw random waiting time wt = coalescent.time_to_coalescence( n_genes=num_nodes_remaining, pop_size=pop_size, n_to_coalesce=len(child_nodes)) node_ages[nd] = min_age + wt current_tree_max_age += wt num_nodes_remaining = num_nodes_remaining - len(child_nodes) + 1 # set the edge lengths according to the node ages for nd in tree.preorder_node_iter(): if nd.parent_node is None: nd.edge.length = 0.0 else: nd.edge.length = node_ages[nd.parent_node] - node_ages[nd] return tree
def generate_single_labeled_history(tree, pop_size=None, rng=None): # get collection of nodes organized by the order # of coalescence as given by the level node_event_order = {} event_nodes = {} num_leaves = 0 for nd in tree.postorder_node_iter(): if nd.is_leaf(): node_event_order[nd] = 0 num_leaves += 1 else: eo = max([node_event_order[ch] for ch in nd.child_nodes()]) + 1 node_event_order[nd] = eo try: event_nodes[node_event_order[nd]].append(nd) except KeyError: event_nodes[node_event_order[nd]] = [nd] # set the node ages node_ages = {} event_idx_list = sorted(event_nodes.keys()) for nd in event_nodes[0]: node_ages[nd] = 0.0 current_tree_max_age = 0.0 num_nodes_remaining = num_leaves for event_idx in event_idx_list[1:]: for nd in event_nodes[event_idx]: child_nodes = nd.child_nodes() max_ch_age = max([node_ages[ch] for ch in child_nodes]) min_age = max(current_tree_max_age, max_ch_age) if rng is None: # rng is not given: use expected waiting time wt = coalescent.expected_tmrca(n_genes=num_nodes_remaining, pop_size=pop_size, n_to_coalesce=len(child_nodes)) else: # rng is given: draw random waiting time wt = coalescent.time_to_coalescence( n_genes=num_nodes_remaining, pop_size=pop_size, n_to_coalesce=len(child_nodes)) node_ages[nd] = min_age + wt current_tree_max_age += wt num_nodes_remaining = num_nodes_remaining - len(child_nodes) + 1 # set the edge lengths according to the node ages for nd in tree.preorder_node_iter(): if nd.parent_node is None: nd.edge.length = 0.0 else: nd.edge.length = node_ages[nd.parent_node] - node_ages[nd] return tree
def _generate_labeled_history(tree, coal_event_list, num_leaves=None, pop_size=None, rng=None): # set the node ages node_ages = {} for nd in coal_event_list[0]: node_ages[nd] = 0.0 current_tree_max_age = 0.0 if num_leaves is None: num_nodes_remaining = num_leaves else: num_nodes_remaining = len([lf for lf in tree.leaf_iter()]) # process events in order of occurrence for event_nodes in coal_event_list[1:]: for nd in event_nodes: child_nodes = nd.child_nodes() max_ch_age = max([node_ages[ch] for ch in child_nodes]) min_age = max(current_tree_max_age, max_ch_age) if rng is None: # rng is not given: use expected waiting time wt = coalescent.expected_tmrca( n_genes=num_nodes_remaining, pop_size=pop_size, n_to_coalesce=len(child_nodes)) else: # rng is given: draw random waiting time wt = coalescent.time_to_coalescence( n_genes=num_nodes_remaining, pop_size=pop_size, n_to_coalesce=len(child_nodes)) node_ages[nd] = min_age + wt current_tree_max_age += wt num_nodes_remaining = num_nodes_remaining - len(child_nodes) + 1 # set the edge lengths according to the node ages for nd in tree.preorder_node_iter(): if nd.parent_node is None: nd.edge.length = 0.0 else: nd.edge.length = node_ages[nd.parent_node] - node_ages[nd] return tree
def _generate_labeled_history(tree, coal_event_list, num_leaves=None, pop_size=None, rng=None): # set the node ages node_ages = {} for nd in coal_event_list[0]: node_ages[nd] = 0.0 current_tree_max_age = 0.0 if num_leaves is None: num_nodes_remaining = num_leaves else: num_nodes_remaining = len([lf for lf in tree.leaf_iter()]) # process events in order of occurrence for event_nodes in coal_event_list[1:]: for nd in event_nodes: child_nodes = nd.child_nodes() max_ch_age = max([node_ages[ch] for ch in child_nodes]) min_age = max(current_tree_max_age, max_ch_age) if rng is None: # rng is not given: use expected waiting time wt = coalescent.expected_tmrca(n_genes=num_nodes_remaining, pop_size=pop_size, n_to_coalesce=len(child_nodes)) else: # rng is given: draw random waiting time wt = coalescent.time_to_coalescence( n_genes=num_nodes_remaining, pop_size=pop_size, n_to_coalesce=len(child_nodes)) node_ages[nd] = min_age + wt current_tree_max_age += wt num_nodes_remaining = num_nodes_remaining - len(child_nodes) + 1 # set the edge lengths according to the node ages for nd in tree.preorder_node_iter(): if nd.parent_node is None: nd.edge.length = 0.0 else: nd.edge.length = node_ages[nd.parent_node] - node_ages[nd] return tree
def main(): """ Main CLI handler. """ parser = argparse.ArgumentParser() parser.add_argument("-f", "--format", dest="schema", type=str, default="nexus", choices=["nexus", "newick"], help="input data format (default='%(default)s')") parser.add_argument("-l", "--label", type=str, default="[TESTING]", help="label for test") parser.add_argument( "-r", "--regime", dest="regime", type=str, default="mean", choices=[ "mean-coalescent", "converse-coalescent", "uniform-coalescent" ], help= "expected regime under which the coalescent intervals were generated (default='%(default)s')" ) parser.add_argument("-p", "--precision", type=float, default=0.01, help="numerical precision (default=%(default)s)") args = parser.parse_args() fails = 0 trees = dendropy.TreeList.get_from_stream(sys.stdin, schema=args.schema) for tidx, tree in enumerate(trees): tree_fails = 0 # check structure if not tree._debug_tree_is_valid(): sys.stderr.write("{} Tree {}: structure is invalid".format( args.label, tidx + 1)) tree_fails += 1 # ensure parent ages > child ages tree.calc_node_ages(check_prec=args.precision) for nd in tree.postorder_node_iter(): if nd.parent_node is not None: if nd.age > nd.parent_node.age: sys.stderr.write( "{} Tree {}: Node '{}': age ({}) is greater than parent age ({})" .format(args.label, tidx + 1, nd.label, nd.age, nd.parent_node.age)) tree_fails += 1 # check waiting times num_tips = len(tree.leaf_nodes()) wf = coalescent.extract_coalescent_frames( tree, check_ultrametricity_prec=args.precision) num_lineages = sorted(wf.keys()) for n in num_lineages: wt = wf[n] if args.regime == "mean-coalescent": exp_wt = coalescent.expected_tmrca(n) elif args.regime == "converse-coalescent": exp_wt = coalescent.expected_tmrca(num_tips - n + 2) elif args.regime == "uniform-coalescent": exp_wt = 1.0 else: raise RuntimeError("Unsupported regime: '{}'".format( args.regime)) if abs(exp_wt - wt) > args.precision: sys.stderr.write( "{} Tree {}: Waiting time for coalescence event with {} lineages: expecting {} but found {}\n" .format(args.label, tidx + 1, n, exp_wt, wt)) tree_fails += 1 if tree_fails > 0: sys.stderr.write("{} Tree {} failed: {}\n".format( args.label, tidx + 1, tree.compose_newick())) fails += tree_fails if fails > 0: sys.exit(1) else: sys.exit(0)
def main(): """ Main CLI handler. """ parser = argparse.ArgumentParser() parser.add_argument("-f", "--format", dest="schema", type=str, default="nexus", choices=["nexus", "newick"], help="input data format (default='%(default)s')") parser.add_argument("-l", "--label", type=str, default="[TESTING]", help="label for test") parser.add_argument("-r", "--regime", dest="regime", type=str, default="mean", choices=["mean-coalescent", "converse-coalescent", "uniform-coalescent"], help="expected regime under which the coalescent intervals were generated (default='%(default)s')") parser.add_argument("-p", "--precision", type=float, default=0.01, help="numerical precision (default=%(default)s)") args = parser.parse_args() fails = 0 trees = dendropy.TreeList.get_from_stream(sys.stdin, schema=args.schema) for tidx, tree in enumerate(trees): tree_fails = 0 # check structure if not tree._debug_tree_is_valid(): sys.stderr.write("{} Tree {}: structure is invalid".format(args.label, tidx+1)) tree_fails += 1 # ensure parent ages > child ages tree.calc_node_ages(check_prec=args.precision) for nd in tree.postorder_node_iter(): if nd.parent_node is not None: if nd.age > nd.parent_node.age: sys.stderr.write("{} Tree {}: Node '{}': age ({}) is greater than parent age ({})".format( args.label, tidx+1, nd.label, nd.age, nd.parent_node.age)) tree_fails += 1 # check waiting times num_tips = len(tree.leaf_nodes()) wf = coalescent.extract_coalescent_frames(tree, check_ultrametricity_prec=args.precision) num_lineages = sorted(wf.keys()) for n in num_lineages: wt = wf[n] if args.regime == "mean-coalescent": exp_wt = coalescent.expected_tmrca(n) elif args.regime == "converse-coalescent": exp_wt = coalescent.expected_tmrca(num_tips - n + 2) elif args.regime == "uniform-coalescent": exp_wt = 1.0 else: raise RuntimeError("Unsupported regime: '{}'".format(args.regime)) if abs(exp_wt - wt) > args.precision: sys.stderr.write("{} Tree {}: Waiting time for coalescence event with {} lineages: expecting {} but found {}\n".format( args.label, tidx+1, n, exp_wt, wt)) tree_fails += 1 if tree_fails > 0: sys.stderr.write("{} Tree {} failed: {}\n".format(args.label, tidx+1, tree.compose_newick())) fails += tree_fails if fails > 0: sys.exit(1) else: sys.exit(0)