Ejemplo n.º 1
0
def newick_node_to_shape(node):
    """
    Create a `Shape` object from a `Node` object.
    :param node: a `Node`.
    :return: `Shape` instance.
    """
    if not bool(node.descendants):
        return Shape(None)
    return Shape(sorted([newick_node_to_shape(x) for x in node.descendants]))
Ejemplo n.º 2
0
 def shape(self):
     """
     Returns the `Shape` associated to self. Namely, it "forgets" the names of the leaves.
     :return: `Shape` instance.
     """
     if self.is_leaf():
         return Shape(None)
     else:
         return Shape([x.shape() for x in self.children])
Ejemplo n.º 3
0
    def test_shape(self):
        self.assertEqual(Shape.LEAF, Shape())

        self.assertEqual(Shape.CHERRY, Shape([Shape.LEAF, Shape.LEAF]))

        self.assertEqual(Shape.LEAF.shape(), Shape.LEAF)

        self.assertEqual(Shape.CHERRY.shape(), Shape.CHERRY)

        self.assertEqual(Shape([Shape.LEAF, Shape.CHERRY]),
                         Shape([Shape.LEAF, Shape.CHERRY]))
Ejemplo n.º 4
0
    def go(t, dis):
        if dis:
            if dis[0] != 0:
                return Shape(
                    [go(t.children[0], [di - 1 for di in dis]), t.children[1]])
            else:
                return Shape([
                    Shape.LEAF,
                    go(t.children[1], [di - 1 for di in dis[1:]])
                ])

        else:
            return t
Ejemplo n.º 5
0
def star(n):
    """
    Returns a star `Shape` with n leaves.
    :param n: `int` instance.
    :return: `Shape` instance.
    """
    return Shape([Shape.LEAF for _ in range(n)])
Ejemplo n.º 6
0
def alphagamma_from_t(t, prob):
    """
    Returns a list of tuples containing each shape obtained from `Shape` sh (assuming sh has probability prob) with
    their associate probability under the Alpha-Gamma model.
    :param sh: `Shape` instance.
    :param prob: `function` instance.
    :return: `list` instance.
    """
    n = count_leaves(t)
    if t.is_leaf():
        return [(add_leaf_to_edge(t),
                 lambda a, c: simplify(prob(a, c) * (1 - a) / (n - a)))]
    else:
        for i in range(len(t.children)):
            k = count_leaves(t.children[i])
            if n > 1:
                p_times_m = lambda a, c, k=k: simplify(
                    prob(a, c) * (k - a) / (n - a))
            else:
                p_times_m = prob
            for ti, q in alphagamma_from_t(t.children[i], p_times_m):
                ts2 = list(iter_replace_tree_at(t.children, i, ti))
                yield (Shape(ts2), q)

        yield (add_leaf_to_edge(t),
               lambda a, c: simplify(prob(a, c) * c / (n - a)))

        k = len(t.children)
        if k > 1:
            prob2 = lambda a, c, k=k: simplify(
                prob(a, c) * ((k - 1) * a - c) / (n - a))
        else:
            prob2 = prob

        yield (add_leaf_to_node(t), prob2)
Ejemplo n.º 7
0
def add_leaf_to_edge(t):
    """
    Returns a `Shape` instance with a new root; both a new leaf and the input `Shape` pend from it.
    :param t: `Shape` instance.
    :return: `Shape` instance.
    """
    return Shape([Shape.LEAF, t])
Ejemplo n.º 8
0
def quartet_index(tree, vs=range(5)):
    Q = get_quartets()
    t0 = Shape([Shape.LEAF, Shape.LEAF, Shape.LEAF])

    def go(t):
        if t.is_leaf():
            return 0, 0, 1

        ts = t.children
        quartets, triples, kappas = zip(*map(go, ts))
        kappa = sum(kappas)

        if kappa < 3:
            triple = 0
        elif isomorphic(t, t0):
            triple = 1
        else:
            t_s0 = sum(triples)

            t_s1 = sum(kappas[i1] * kappas[i2] * kappas[i3]
                       for i1 in range(len(ts))
                       for i2 in range(i1 + 1, len(ts))
                       for i3 in range(i2 + 1, len(ts)))

            triple = t_s0 + t_s1

        if kappa < 4:
            return 0, triple, kappa

        for q, v in zip(Q, vs):
            if isomorphic(t, q):
                return v, triple, kappa

            s0 = sum(quartets)

            s1 = sum(
                binom2(kappas[i1]) * kappas[i2] * kappas[i3] +
                binom2(kappas[i2]) * kappas[i1] * kappas[i3] +
                binom2(kappas[i3]) * kappas[i1] * kappas[i2]
                for i1 in range(len(ts)) for i2 in range(i1 + 1, len(ts))
                for i3 in range(i2 + 1, len(ts)))

            s2 = sum(kappas[i1] * triples[i2] + kappas[i2] * triples[i1]
                     for i1 in range(len(ts)) for i2 in range(i1 + 1, len(ts)))

            s3 = sum(
                binom2(kappas[i1]) * binom2(kappas[i2])
                for i1 in range(len(ts)) for i2 in range(i1 + 1, len(ts)))

            s4 = sum(kappas[i1] * kappas[i2] * kappas[i3] * kappas[i4]
                     for i1 in range(len(ts)) for i2 in range(i1 + 1, len(ts))
                     for i3 in range(i2 + 1, len(ts))
                     for i4 in range(i3 + 1, len(ts)))

            return s0 + vs[1] * s1 + vs[2] * s2 + vs[3] * s3 + vs[
                4] * s4, triple, kappa

    return go(tree)[0]
Ejemplo n.º 9
0
def add_leaf_to_node(t):
    """
    Returns a `Shape` instance with the same root; we have added a pending leaf to it.
    :param t: `Shape` instance.
    :return: `Shape` instance.
    """
    if t.is_leaf():
        return add_leaf_to_edge(t)
    else:
        return Shape([Shape.LEAF] + t.children)
Ejemplo n.º 10
0
    def test_deg(self):
        self.assertEqual(rooted_deg(Shape.LEAF), 0)
        self.assertEqual(rooted_deg(Shape.CHERRY), 2)

        self.assertEqual(unrooted_deg(Shape.LEAF), 1)
        self.assertEqual(unrooted_deg(Shape.CHERRY), 3)

        t = Shape([Shape.LEAF, Shape.CHERRY])

        self.assertEqual(rooted_deg(t), 2)
        self.assertEqual(unrooted_deg(t), 3)
        self.assertEqual(unrooted_deg(t, root=True), 2)
Ejemplo n.º 11
0
def comb(n):
    """
    Returns a comb `Shape` with n leaves.
    :param n: `int` instance.
    :return: `Shape` instance.
    """
    if n == 1:
        return Shape.LEAF
    elif n == 2:
        return Shape.CHERRY
    else:
        return Shape([Shape.LEAF, comb(n - 1)])
Ejemplo n.º 12
0
def all_binary_trees_from_t(t):
    """
    Returns a list with all the binary `Shape` instances that can be obtained from the input tree.
    :param t: `Shape` instance.
    :return: `list` instance.
    """
    if not t.is_leaf():
        for i in range(len(t.children)):
            for ti in all_binary_trees_from_t(t.children[i]):
                ts2 = list(iter_replace_tree_at(t.children, i, ti))
                yield Shape(ts2)

    yield add_leaf_to_edge(t)
Ejemplo n.º 13
0
def delete_nodes_with_out_degree_one(t):
    """
    Deletes all nodes in the input `Shape` instance with only one child, for they are redundant
    :return: `Shape` instance
    """
    if t.is_leaf():
        return t
    else:
        if len(t.children) == 1:
            return delete_nodes_with_out_degree_one(t.children[0])
        else:
            return Shape(
                [delete_nodes_with_out_degree_one(ch) for ch in t.children])
Ejemplo n.º 14
0
def all_binary_trees_with_n_leaves(n):
    """
    Returns a list with all the binary `Shape` instances that have n leaves.
    :param n: `int` instance.
    :return: `list` instance.
    """
    if n <= 0:
        pass
    elif n == 1:
        yield Shape.LEAF
    elif n == 2:
        yield Shape([Shape.LEAF, Shape.LEAF])
    else:
        for t in all_binary_trees_with_n_leaves(n - 1):
            yield from all_binary_trees_from_t(t)
Ejemplo n.º 15
0
def binary_max_balanced(n):
    """
    Returns a binary maximum balanced `Shape` with n leaves.
    :param n: `int` instance.
    :return: `Shape` instance.
    """
    if n == 1:
        return Shape.LEAF
    elif n == 2:
        return Shape.CHERRY
    else:
        s = n % 2
        return Shape([
            binary_max_balanced((n - s) // 2),
            binary_max_balanced((n - s) // 2 + s)
        ])
Ejemplo n.º 16
0
def alphagamma(n):
    """
    Returns a list of tuples containing all the shapes of n leaves that can be obtained under the Alpha-Gamma model and
    their corresponding probability.
    :param n: `int` instance.
    :return: `list` instance.
    """
    if n <= 0:
        pass
    elif n == 1:
        yield (Shape.LEAF, lambda a, c: 1)
    elif n == 2:
        yield (Shape([Shape.LEAF, Shape.LEAF]), lambda a, c: 1)
    else:
        for t, prob in alphagamma(n - 1):
            yield from alphagamma_from_t(t, prob)
Ejemplo n.º 17
0
    def test_shape(self):
        self.assertEqual(
            L1.shape(),
            L2.shape())

        self.assertEqual(
            C12.shape(),
            C31.shape())

        self.assertEqual(
            L1.shape(),
            Shape.LEAF)

        self.assertEqual(
            C23.shape(),
            Shape.CHERRY)

        self.assertEqual(
            PhyloTree(None, [L1, C31]).shape(),
            Shape([Shape.LEAF, Shape.CHERRY]))
Ejemplo n.º 18
0
def min_colless(n):
    """
    Returns all the `Shape` instances that attain the minimum Colless index with `int` n leaves.
    :param n: `int` instance.
    :return: `list` instance.
    """

    if n == 0:
        return []
    elif n == 1:
        return [Shape.LEAF]
    elif n == 2:
        return [Shape.CHERRY]
    else:
        tss = []
        for n1, n2 in min_colless_root(n):
            ts = unique([
                Shape(sorted([t1, t2])) for t1 in min_colless(n1)
                for t2 in min_colless(n2)
            ])
            tss.extend(ts)
        return tss
Ejemplo n.º 19
0
def get_quartets():
    q0 = Shape(
        [Shape.LEAF,
         Shape([Shape.LEAF, Shape([Shape.LEAF, Shape.LEAF])])])
    q1 = Shape([Shape.LEAF, Shape.LEAF, Shape([Shape.LEAF, Shape.LEAF])])
    q2 = Shape([Shape.LEAF, Shape([Shape.LEAF, Shape.LEAF, Shape.LEAF])])
    q3 = Shape(
        [Shape([Shape.LEAF, Shape.LEAF]),
         Shape([Shape.LEAF, Shape.LEAF])])
    q4 = Shape([Shape.LEAF, Shape.LEAF, Shape.LEAF, Shape.LEAF])
    return [q0, q1, q2, q3, q4]