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
예제 #2
0
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
예제 #4
0
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
예제 #5
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)
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)