Example #1
0
    def test_ignores_non_sample_leaves(self):
        nodes = io.StringIO("""\
        id  is_sample   time    population  individual  metadata
        0   1   0.000000    0   -1
        1   0   0.000000    0   -1
        2   1   0.000000    0   -1
        3   0   0.000000    0   -1
        4   1   0.000000    0   -1
        5   0   1.000000    0   -1
        6   0   1.000000    0   -1
        7   0   2.000000    0   -1
        8   0   3.000000    0   -1
        """)
        edges = io.StringIO("""\
        left    right   parent  child
        0.000000    1.000000    5  0
        0.000000    1.000000    5  1
        0.000000    1.000000    6  2
        0.000000    1.000000    6  3
        0.000000    1.000000    7  5
        0.000000    1.000000    7  6
        0.000000    1.000000    8  4
        0.000000    1.000000    8  7
        """)
        ts = tskit.load_text(nodes,
                             edges,
                             sequence_length=1,
                             strict=False,
                             base64_metadata=False)

        sample_sets = [[0], [2], [4]]

        expected = comb.TopologyCounter()
        expected[0] = collections.Counter({(0, 0): 1})
        expected[1] = collections.Counter({(0, 0): 1})
        expected[2] = collections.Counter({(0, 0): 1})
        expected[0, 1] = collections.Counter({(0, 0): 1})
        expected[0, 2] = collections.Counter({(0, 0): 1})
        expected[1, 2] = collections.Counter({(0, 0): 1})
        expected[0, 1, 2] = collections.Counter({(1, 2): 1})

        tree_topologies = ts.first().count_topologies(sample_sets)
        treeseq_topologies = list(ts.count_topologies(sample_sets))
        assert tree_topologies == expected
        assert treeseq_topologies == [expected]
Example #2
0
    def test_three_populations(self):
        nodes = io.StringIO(
            """\
        id  is_sample   time    population  individual  metadata
        0   1   0.000000    0   -1
        1   1   0.000000    1   -1
        2   1   0.000000    1   -1
        3   1   0.000000    2   -1
        4   1   0.000000    2   -1
        5   1   0.000000    0   -1
        6   0   1.000000    0   -1
        7   0   2.000000    0   -1
        8   0   2.000000    0   -1
        9   0   3.000000    0   -1
        10  0   4.000000    0   -1
        """
        )
        edges = io.StringIO(
            """\
        left    right   parent  child
        0.000000    1.000000    6  4
        0.000000    1.000000    6  5
        0.000000    1.000000    7  1
        0.000000    1.000000    7  2
        0.000000    1.000000    8  3
        0.000000    1.000000    8  6
        0.000000    1.000000    9  7
        0.000000    1.000000    9  8
        0.000000    1.000000    10  0
        0.000000    1.000000    10  9
        """
        )
        ts = tskit.load_text(
            nodes, edges, sequence_length=1, strict=False, base64_metadata=False
        )

        expected = comb.TopologyCounter()
        expected[0] = collections.Counter({(0, 0): 2})
        expected[1] = collections.Counter({(0, 0): 2})
        expected[2] = collections.Counter({(0, 0): 2})
        expected[0, 1] = collections.Counter({(0, 0): 4})
        expected[0, 2] = collections.Counter({(0, 0): 4})
        expected[1, 2] = collections.Counter({(0, 0): 4})
        expected[0, 1, 2] = collections.Counter({(1, 0): 4, (1, 1): 4})
        self.verify_topologies(ts, expected=[expected])
Example #3
0
def single_tree_ts_n2():
    r"""
    Simple case where we have n = 2 and one tree.
         2
        / \
       0   1
    """
    nodes = io.StringIO("""\
    id      is_sample   time
    0       1           0
    1       1           0
    2       0           1
    """)
    edges = io.StringIO("""\
    left    right   parent  child
    0       1       2       0,1
    """)
    return(tskit.load_text(nodes=nodes, edges=edges, strict=False))
Example #4
0
 def ts(self):
     nodes = io.StringIO("""\
     id      is_sample   time
     0       1           0
     1       1           0
     2       1           1
     3       1           1
     4       0           2
     5       0           2
     """)
     edges = io.StringIO("""\
     left    right   parent  child
     0       1       2       0
     0       1       3       1
     0       1       4       2
     0       1       5       3
     """)
     return tskit.load_text(nodes=nodes, edges=edges, strict=False)
Example #5
0
    def test_simple_tree_long_label(self):
        nodes = io.StringIO("""\
        id  is_sample   time
        0   1           0
        1   1           0
        2   1           2
        """)
        edges = io.StringIO("""\
        left    right   parent  child
        0       1       2       0
        0       1       2       1
        """)
        tree = (
            "ABCDEF\n"
            "┏┻┓   \n"
            "0 1   \n")
        ts = tskit.load_text(nodes, edges, strict=False)
        t = next(ts.trees())
        drawn = t.draw_text(node_labels={0: "0", 1: "1", 2: "ABCDEF"})
        self.verify_text_rendering(drawn, tree)

        tree = (
            "0┓      \n"
            " ┣ABCDEF\n"
            "1┛      \n")
        drawn = t.draw_text(
            node_labels={0: "0", 1: "1", 2: "ABCDEF"}, orientation="right")
        self.verify_text_rendering(drawn, tree)

        drawn = t.draw_text(
            node_labels={0: "ABCDEF", 1: "1", 2: "2"}, orientation="right")
        tree = (
            "ABCDEF┓ \n"
            "      ┣2\n"
            "1━━━━━┛ \n")
        self.verify_text_rendering(drawn, tree)

        tree = (
            "      ┏0\n"
            "ABCDEF┫ \n"
            "      ┗1\n")
        drawn = t.draw_text(
            node_labels={0: "0", 1: "1", 2: "ABCDEF"}, orientation="left")
        self.verify_text_rendering(drawn, tree)
Example #6
0
 def test_trident_tree(self):
     nodes = io.StringIO("""\
     id  is_sample   time
     0   1           0
     1   1           0
     2   1           0
     3   1           2
     """)
     edges = io.StringIO("""\
     left    right   parent  child
     0       1       3       0
     0       1       3       1
     0       1       3       2
     """)
     tree = ("  3  \n" "┏━╋━┓\n" "0 1 2\n")
     ts = tskit.load_text(nodes, edges, strict=False)
     t = next(ts.trees())
     drawn = t.draw(format="unicode")
     self.verify_text_rendering(drawn, tree)
Example #7
0
 def test_simple_example_internal_focal_node(self):
     ts = tskit.load_text(nodes=io.StringIO(self.small_tree_ex_nodes),
                          edges=io.StringIO(self.small_tree_ex_edges),
                          strict=False)
     focal = [7]  # An internal node
     reference_sets = [[4, 0, 1], [2, 3]]
     GNN = naive_genealogical_nearest_neighbours(ts, focal, reference_sets)
     self.assertTrue(np.allclose(GNN[0], np.array([1.0, 0.0])))
     GNN = tsutil.genealogical_nearest_neighbours(ts, focal, reference_sets)
     self.assertTrue(np.allclose(GNN[0], np.array([1.0, 0.0])))
     GNN = ts.genealogical_nearest_neighbours(focal, reference_sets)
     self.assertTrue(np.allclose(GNN[0], np.array([1.0, 0.0])))
     focal = [8]  # The root
     GNN = naive_genealogical_nearest_neighbours(ts, focal, reference_sets)
     self.assertTrue(np.allclose(GNN[0], np.array([0.6, 0.4])))
     GNN = tsutil.genealogical_nearest_neighbours(ts, focal, reference_sets)
     self.assertTrue(np.allclose(GNN[0], np.array([0.6, 0.4])))
     GNN = ts.genealogical_nearest_neighbours(focal, reference_sets)
     self.assertTrue(np.allclose(GNN[0], np.array([0.6, 0.4])))
Example #8
0
    def test_max_tree_height(self):
        nodes = io.StringIO("""\
        id  is_sample   time
        0   1           0
        1   1           0
        2   1           0
        3   0           1
        4   0           2
        5   0           3
        """)
        edges = io.StringIO("""\
        left    right   parent  child
        0       1       5       2
        0       1       5       3
        1       2       4       2
        1       2       4       3
        0       2       3       0
        0       2       3       1
        """)
        ts = tskit.load_text(nodes, edges, strict=False)

        svg1 = ts.at_index(0).draw()
        svg2 = ts.at_index(1).draw()
        # if not scaled to ts, node 3 is at a different height in both trees, because the
        # root is at a different height. We expect a label looking something like
        # <text x="10.0" y="XXXX">3</text> where XXXX is different
        str_pos = svg1.find('>3<')
        snippet1 = svg1[svg1.rfind("<", 0, str_pos):str_pos]
        str_pos = svg2.find('>3<')
        snippet2 = svg2[svg2.rfind("<", 0, str_pos):str_pos]
        self.assertNotEqual(snippet1, snippet2)

        svg1 = ts.at_index(0).draw(max_tree_height="ts")
        svg2 = ts.at_index(1).draw(max_tree_height="ts")
        # when scaled, node 3 should be at the *same* height in both trees, so the label
        # should be the same
        self.verify_basic_svg(svg1)
        self.verify_basic_svg(svg2)
        str_pos = svg1.find('>3<')
        snippet1 = svg1[svg1.rfind("<", 0, str_pos):str_pos]
        str_pos = svg2.find('>3<')
        snippet2 = svg2[svg2.rfind("<", 0, str_pos):str_pos]
        self.assertEqual(snippet1, snippet2)
Example #9
0
def polytomy_tree_ts():
    r"""
    Simple case where we have n = 3 and a polytomy.
          3
         /|\
        0 1 2
    """
    nodes = io.StringIO("""\
    id      is_sample   time
    0       1           0
    1       1           0
    2       1           0
    3       0           1
    """)
    edges = io.StringIO("""\
    left    right   parent  child
    0       1       3       0,1,2
    """)
    return tskit.load_text(nodes=nodes, edges=edges, strict=False)
Example #10
0
    def test_pitchfork_tree(self):
        nodes = io.StringIO("""\
        id  is_sample   time
        0   1           0
        1   1           0
        2   1           0
        3   1           0
        4   1           2
        """)
        edges = io.StringIO("""\
        left    right   parent  child
        0       1       4       0
        0       1       4       1
        0       1       4       2
        0       1       4       3
        """)
        ts = tskit.load_text(nodes, edges, strict=False)
        t = next(ts.trees())
        tree = ("   4   \n" "┏━┳┻┳━┓\n" "0 1 2 3\n")
        drawn = t.draw(format="unicode")
        self.verify_text_rendering(drawn, tree)
        self.verify_text_rendering(t.draw_text(), tree)

        # No labels
        tree = ("   ┃   \n" "┏━┳┻┳━┓\n" "┃ ┃ ┃ ┃\n")
        drawn = t.draw(format="unicode", node_labels={})
        self.verify_text_rendering(drawn, tree)
        self.verify_text_rendering(t.draw_text(node_labels={}), tree)
        # Some labels
        tree = ("   ┃   \n" "┏━┳┻┳━┓\n" "0 ┃ ┃ 3\n")
        labels = {0: "0", 3: "3"}
        drawn = t.draw(format="unicode", node_labels=labels)
        self.verify_text_rendering(drawn, tree)
        self.verify_text_rendering(t.draw_text(node_labels=labels), tree)

        tree = (" ┏0\n" " ┃\n" " ┣1\n" "4┫\n" " ┣2\n" " ┃\n" " ┗3\n")
        drawn = t.draw_text(orientation="left")
        self.verify_text_rendering(drawn, tree)

        tree = ("0┓\n" " ┃\n" "1┫\n" " ┣4\n" "2┫\n" " ┃\n" "3┛\n")
        drawn = t.draw_text(orientation="right")
        self.verify_text_rendering(drawn, tree)
Example #11
0
    def test_simple_tree(self):
        nodes = io.StringIO("""\
        id  is_sample   time
        0   1           0
        1   1           0
        2   1           2
        """)
        edges = io.StringIO("""\
        left    right   parent  child
        0       1       2       0
        0       1       2       1
        """)
        tree = (
            " 2 \n"
            "┏┻┓\n"
            "0 1")
        ts = tskit.load_text(nodes, edges, strict=False)
        t = next(ts.trees())
        drawn = t.draw(format="unicode")
        self.verify_text_rendering(drawn, tree)
        drawn = t.draw_text()
        self.verify_text_rendering(drawn, tree)

        tree = (
            " 2 \n"
            "+++\n"
            "0 1\n")
        drawn = t.draw_text(use_ascii=True)
        self.verify_text_rendering(drawn, tree)

        tree = (
            " ┏0\n"
            "2┫  \n"
            " ┗1\n")
        drawn = t.draw_text(orientation="left")
        self.verify_text_rendering(drawn, tree)
        tree = (
            " +0\n"
            "2+  \n"
            " +1\n")
        drawn = t.draw_text(orientation="left", use_ascii=True)
        self.verify_text_rendering(drawn, tree)
Example #12
0
class TestIbdDifferentPaths2:
    #
    #        5         |
    #       / \        |
    #      /   4       |      4
    #     /   / \      |     / \
    #    /   /   \     |    /   \
    #   /   /     \    |   3     \
    #  /   /       \   |  / \     \
    # 0   1         2  | 0   2     1
    #                  |
    #                  0.2

    nodes = io.StringIO("""\
    id      is_sample   time
    0       1           0
    1       1           0
    2       1           0
    3       0           1
    4       0           2.5
    5       0           3.5
    """)
    edges = io.StringIO("""\
    left    right   parent  child
    0.2     1.0     3       0
    0.2     1.0     3       2
    0.0     1.0     4       1
    0.0     0.2     4       2
    0.2     1.0     4       3
    0.0     0.2     5       0
    0.0     0.2     5       4
    """)
    ts = tskit.load_text(nodes=nodes, edges=edges, strict=False)

    def test_defaults(self):
        ibd_segs = find_ibd(self.ts, sample_pairs=[(1, 2)])
        true_segs = {
            (1, 2): [ibd.Segment(0.0, 0.2, 4),
                     ibd.Segment(0.2, 1.0, 4)],
        }
        assert ibd_is_equal(ibd_segs, true_segs)
Example #13
0
class TestIbdUnrelatedSamples(unittest.TestCase):

    #
    #    2   3
    #    |   |
    #    0   1

    nodes = io.StringIO("""\
    id      is_sample   time
    0       1           0
    1       1           0
    2       0           1
    3       0           1
    """)
    edges = io.StringIO("""\
    left    right   parent  child
    0       1       2       0
    0       1       3       1
    """)
    ts = tskit.load_text(nodes=nodes, edges=edges, strict=False)

    def test_basic(self):
        ibd_f = ibd.IbdFinder(self.ts)
        ibd_segs = ibd_f.find_ibd_segments()
        ibd_segs = convert_dict_of_segmentlists(ibd_segs)
        true_segs = {(0, 1): []}
        assert ibd_is_equal(ibd_segs, true_segs)

    def test_time(self):
        ibd_f = ibd.IbdFinder(self.ts, max_time=1.2)
        ibd_segs = ibd_f.find_ibd_segments()
        ibd_segs = convert_dict_of_segmentlists(ibd_segs)
        true_segs = {(0, 1): []}
        assert ibd_is_equal(ibd_segs, true_segs)

    def test_length(self):
        ibd_f = ibd.IbdFinder(self.ts, min_length=0.2)
        ibd_segs = ibd_f.find_ibd_segments()
        ibd_segs = convert_dict_of_segmentlists(ibd_segs)
        true_segs = {(0, 1): []}
        assert ibd_is_equal(ibd_segs, true_segs)
Example #14
0
 def ts(self):
     nodes = io.StringIO("""\
     id      is_sample   time
     0       1           0
     1       1           0
     2       1           0
     3       1           0
     4       0           2.5
     5       0           3.5
     """)
     edges = io.StringIO("""\
     left    right   parent  child
     0.0     1.0     4       0
     0.0     1.0     4       1
     0.0     0.3     4       2
     0.3     1.0     4       3
     0.3     1.0     5       2
     0.0     0.3     5       3
     0.0     1.0     5       4
     """)
     return tskit.load_text(nodes=nodes, edges=edges, strict=False)
Example #15
0
 def ts(self):
     nodes = io.StringIO("""\
     id      is_sample   time
     0       1           0
     1       1           0
     2       0           1
     3       0           1.5
     4       0           2.5
     """)
     edges = io.StringIO("""\
     left    right   parent  child
     0.2     0.7     2       0
     0.2     0.7     3       1
     0.0     0.2     4       0
     0.0     0.2     4       1
     0.7     1.0     4       0
     0.7     1.0     4       1
     0.2     0.7     4       2
     0.2     0.7     4       3
     """)
     return tskit.load_text(nodes=nodes, edges=edges, strict=False)
Example #16
0
    def test_stick_tree(self):
        nodes = io.StringIO("""\
        id  is_sample   time
        0   1           0
        1   1           1
        2   1           2
        """)
        edges = io.StringIO("""\
        left    right   parent  child
        0       1       1       0
        0       1       2       1
        """)
        tree = (
            "2\n"
            "┃\n"
            "1\n"
            "┃\n"
            "0\n")
        ts = tskit.load_text(nodes, edges, strict=False)
        t = next(ts.trees())
        drawn = t.draw(format="unicode")
        self.verify_text_rendering(drawn, tree)
        self.verify_text_rendering(t.draw_text(), tree)

        tree = (
            "0\n"
            "┃\n"
            "1\n"
            "┃\n"
            "2\n")
        drawn = t.draw_text(orientation="bottom")
        self.verify_text_rendering(drawn, tree)

        tree = "2━1━0\n"
        drawn = t.draw_text(orientation="left")
        self.verify_text_rendering(drawn, tree)

        tree = "0━1━2\n"
        drawn = t.draw_text(orientation="right")
        self.verify_text_rendering(drawn, tree)
Example #17
0
def loopy_tree():
    r"""
    Simple case where we have n = 3, 2 trees, three mutations.
                   .          7
                   .         / \
                   .        /  |
                   .       /   |
         6         .      /    6
        / \        .     /    / \
       /   5       .    /    /   |
      /   / \      .   /    /    |
     |   /   \     .  |    |     |
     |   |    \    .  |    |     |
     |   4     |    . |    4     |
     |  / \    |    . |   / \    |
     0 1   2   3    . 0  1   2   3
    """
    nodes = io.StringIO("""\
    id      is_sample   time
    0       1           0
    1       1           0
    2       1           0
    3       1           0
    4       0           1
    5       0           2
    6       0           3
    7       0           4
    """)
    edges = io.StringIO("""\
    left    right   parent  child
    0       1       4       0,1
    0       0.2     5       2,4
    0       0.2     6       5
    0       1       6       3
    0.2     1       6       4
    0.2     1       7       2
    0.2     1       7       6
    """)
    return tskit.load_text(nodes=nodes, edges=edges, strict=False)
Example #18
0
 def ts(self):
     #
     # 2        4
     #         / \
     # 1      3   \
     #       / \   \
     # 0    0   1   2
     print("evaluating ts")
     nodes = io.StringIO("""\
     id      is_sample   time
     0       1           0
     1       1           0
     2       1           0
     3       0           1
     4       0           2
     """)
     edges = io.StringIO("""\
     left    right   parent  child
     0       1       3       0,1
     0       1       4       2,3
     """)
     return tskit.load_text(nodes=nodes, edges=edges, strict=False)
Example #19
0
 def test_no_samples(self):
     #
     #     2
     #    / \
     #   /   \
     #  /     \
     # (0)   (1)
     nodes = io.StringIO("""\
     id      is_sample   time
     0       0           0
     1       0           0
     2       0           1
     3       0           1
     """)
     edges = io.StringIO("""\
     left    right   parent  child
     0       1       2       0
     0       1       3       1
     """)
     ts = tskit.load_text(nodes=nodes, edges=edges, strict=False)
     with pytest.raises(ValueError):
         ibd.IbdFinder(ts, sample_pairs=[(0, 1)])
Example #20
0
 def test_odd_num_children_tree(self):
     nodes = io.StringIO("""\
     id  is_sample   time
     0   1           0
     1   1           1
     2   1           2
     3   1           1
     4   1           4
     5   1           5
     """)
     edges = io.StringIO("""\
     left    right   parent  child
     0       1       5       0
     0       1       5       1
     0       1       5       2
     0       1       5       3
     0       1       5       4
     """)
     ts = tskit.load_text(nodes, edges, strict=False)
     t = next(ts.trees())
     text = t.draw(format=self.drawing_format)
     self.verify_basic_text(text)
Example #21
0
def single_tree_ts_n3():
    r"""
    Simple case where we have n = 3 and one tree.
            4
           / \
          3   \
         / \   \
        0   1   2
    """
    nodes = io.StringIO("""\
    id      is_sample   time
    0       1           0
    1       1           0
    2       1           0
    3       0           1
    4       0           2
    """)
    edges = io.StringIO("""\
    left    right   parent  child
    0       1       3       0,1
    0       1       4       2,3
    """)
    return tskit.load_text(nodes=nodes, edges=edges, strict=False)
Example #22
0
def single_tree_ts_2mutations_n3():
    r"""
    Simple case where we have n = 3 and one tree.
    Site has two mutations with different times.
            4
           x \
          3   \
         / x   \
       [0] [1] [2]
    """
    nodes = io.StringIO("""\
    id      is_sample   time
    0       1           0
    1       1           0
    2       1           0
    3       0           1
    4       0           2
    """)
    edges = io.StringIO("""\
    left    right   parent  child
    0       1       3       0,1
    0       1       4       2,3
    """)
    sites = io.StringIO("""\
    position    ancestral_state
    0.5         0
    """)
    mutations = io.StringIO("""\
    site    node    derived_state
    0       3       1
    0       1       0
    """)
    return tskit.load_text(nodes=nodes,
                           edges=edges,
                           sites=sites,
                           mutations=mutations,
                           strict=False)
Example #23
0
class TestIbdUnrelatedSamples:

    #
    #    2   3
    #    |   |
    #    0   1

    nodes = io.StringIO("""\
    id      is_sample   time
    0       1           0
    1       1           0
    2       0           1
    3       0           1
    """)
    edges = io.StringIO("""\
    left    right   parent  child
    0       1       2       0
    0       1       3       1
    """)

    ts = tskit.load_text(nodes=nodes, edges=edges, strict=False)

    def test_basic(self):
        ibd_segs = find_ibd(self.ts, sample_pairs=[(0, 1)])
        true_segs = {(0, 1): []}
        assert ibd_is_equal(ibd_segs, true_segs)

    def test_time(self):
        ibd_segs = find_ibd(self.ts, sample_pairs=[(0, 1)], max_time=1.2)
        true_segs = {(0, 1): []}
        assert ibd_is_equal(ibd_segs, true_segs)

    def test_length(self):
        ibd_segs = find_ibd(self.ts, sample_pairs=[(0, 1)], min_length=0.2)
        true_segs = {(0, 1): []}
        assert ibd_is_equal(ibd_segs, true_segs)
Example #24
0
def two_tree_two_mrcas():
    r"""
    Simple case where we have n = 4, 2 trees.
             6             |
            / \            |            7
           /   \           |           / \
          /     \          |          /   \
         /       \         |         /     \
        /         \        |        /       \
       4           5       |       4         5
      / \         / \      |      / \       / \
     /   \       /   \     |     /   \     /   \
    |     |     |     |    |    |     |   |     |
    0     1     2     3    |    0     1   2     3
    """
    nodes = io.StringIO("""\
    id      is_sample   time
    0       1           0
    1       1           0
    2       1           0
    3       1           0
    4       1           1
    5       0           1
    6       0           3
    7       0           2
    """)
    edges = io.StringIO("""\
    left    right   parent  child
    0       1       4       0,1
    0       1       5       2,3
    0       0.3     6       4
    0       0.3     6       5
    0.3     1       7       4
    0.3     1       7       5
    """)
    return tskit.load_text(nodes=nodes, edges=edges, strict=False)
Example #25
0
def tree_structure():
    def write_table(tree):
        fmt = "{:<12}"
        heading = [
            "node",
            "parent",
            "left_child",
            "right_child",
            "left_sib",
            "right_sib",
        ]
        line = "".join(fmt.format(s) for s in heading)
        col_def = " ".join(["=" * 11] * 6)
        print(col_def)
        print(line)
        print(col_def)

        for u in range(ts.num_nodes):
            line = "".join(
                fmt.format(v) for v in [
                    u,
                    tree.parent(u),
                    tree.left_child(u),
                    tree.right_child(u),
                    tree.left_sib(u),
                    tree.right_sib(u),
                ])
            print(line)
        print(col_def)

    nodes = """\
    id      is_sample   time
    0       1           0
    1       1           0
    2       1           0
    3       1           0
    4       1           0
    5       0           1
    6       0           2
    7       0           3
    """
    edges = """\
    left    right   parent  child
    0       1       5       0,1,2
    0       1       6       3,4
    0       1       7       5,6
    """
    ts = tskit.load_text(nodes=io.StringIO(nodes),
                         edges=io.StringIO(edges),
                         strict=False)
    tree = ts.first()

    write_table(tree)
    print(tree.draw_text())
    tree.draw_svg("_static/tree_structure1.svg", tree_height_scale="rank")

    edges = """\
    left    right   parent  child
    0       1       5       0,1,2
    0       1       6       3,4
    0       1       7       5
    """
    ts = tskit.load_text(nodes=io.StringIO(nodes),
                         edges=io.StringIO(edges),
                         strict=False)
    tree = ts.first()

    write_table(tree)
    print(tree.draw_text())
    tree.draw_svg("_static/tree_structure2.svg", tree_height_scale="rank")
Example #26
0
class TestParsimonyExamples(TestParsimonyBase):
    """
    Some examples on a given tree.
    """
    #
    #          8
    #         / \
    #        /   \
    #       /     \
    #      7       \
    #     / \       6
    #    /   5     / \
    #   /   / \   /   \
    #  4   0   1 2     3
    small_tree_ex_nodes = """\
    id      is_sample   population      time
    0       1       0               0.00000000000000
    1       1       0               0.00000000000000
    2       1       0               0.00000000000000
    3       1       0               0.00000000000000
    4       1       0               0.00000000000000
    5       0       0               0.14567111023387
    6       0       0               0.21385545626353
    7       0       0               0.43508024345063
    8       0       0               1.60156352971203
    """
    small_tree_ex_edges = """\
    id      left            right           parent  child
    0       0.00000000      1.00000000      5       0,1
    1       0.00000000      1.00000000      6       2,3
    2       0.00000000      1.00000000      7       4,5
    3       0.00000000      1.00000000      8       6,7
    """
    tree = tskit.load_text(nodes=io.StringIO(small_tree_ex_nodes),
                           edges=io.StringIO(small_tree_ex_edges),
                           strict=False).first()

    def test_mutation_over_0(self):
        genotypes = [1, 0, 0, 0, 0]
        ancestral_state, transitions = self.do_map_mutations(
            self.tree, genotypes)
        self.assertEqual(ancestral_state, "0")
        self.assertEqual(len(transitions), 1)
        self.assertEqual(transitions[0],
                         tskit.Mutation(node=0, parent=-1, derived_state="1"))

    def test_mutation_over_5(self):
        genotypes = [1, 1, 0, 0, 0]
        ancestral_state, transitions = self.do_map_mutations(
            self.tree, genotypes)
        self.assertEqual(ancestral_state, "0")
        self.assertEqual(len(transitions), 1)
        self.assertEqual(transitions[0],
                         tskit.Mutation(node=5, parent=-1, derived_state="1"))

    def test_mutation_over_7(self):
        genotypes = [1, 1, 0, 0, 1]
        ancestral_state, transitions = self.do_map_mutations(
            self.tree, genotypes)
        self.assertEqual(ancestral_state, "0")
        self.assertEqual(len(transitions), 1)
        self.assertEqual(transitions[0],
                         tskit.Mutation(node=7, parent=-1, derived_state="1"))

    def test_mutation_over_7_0(self):
        genotypes = [2, 1, 0, 0, 1]
        ancestral_state, transitions = self.do_map_mutations(
            self.tree, genotypes)
        self.assertEqual(ancestral_state, "0")
        self.assertEqual(len(transitions), 2)
        self.assertEqual(transitions[0],
                         tskit.Mutation(node=7, parent=-1, derived_state="1"))
        self.assertEqual(transitions[1],
                         tskit.Mutation(node=0, parent=0, derived_state="2"))

    def test_mutation_over_7_0_alleles(self):
        genotypes = [2, 1, 0, 0, 1]
        alleles = ["ANC", "ONE", "TWO"]
        ancestral_state, transitions = self.do_map_mutations(
            self.tree, genotypes, alleles)
        self.assertEqual(ancestral_state, "ANC")
        self.assertEqual(len(transitions), 2)
        self.assertEqual(
            transitions[0],
            tskit.Mutation(node=7, parent=-1, derived_state="ONE"))
        self.assertEqual(transitions[1],
                         tskit.Mutation(node=0, parent=0, derived_state="TWO"))

    def test_mutation_over_7_missing_data_0(self):
        genotypes = [-1, 1, 0, 0, 1]
        ancestral_state, transitions = self.do_map_mutations(
            self.tree, genotypes)
        self.assertEqual(ancestral_state, "0")
        self.assertEqual(len(transitions), 1)
        self.assertEqual(transitions[0],
                         tskit.Mutation(node=7, parent=-1, derived_state="1"))

    def test_mutation_over_leaf_sibling_missing(self):
        genotypes = [0, 0, 1, -1, 0]
        ancestral_state, transitions = self.do_map_mutations(
            self.tree, genotypes)
        self.assertEqual(ancestral_state, "0")
        self.assertEqual(len(transitions), 1)
        # We assume that the mutation is over the parent of 2 and the missing data
        # so we impute that 3 also has allele 1. This suprising behaviour to me:
        # I would have thought it was more parsimonious to assume that the missing
        # data had the ancestral state. However, the number of *state changes*
        # is the same, which is what the algorithm is minimising.
        self.assertEqual(transitions[0],
                         tskit.Mutation(node=6, parent=-1, derived_state="1"))

        # Reverse is the same
        genotypes = [0, 0, -1, 1, 0]
        ancestral_state, transitions = self.do_map_mutations(
            self.tree, genotypes)
        self.assertEqual(ancestral_state, "0")
        self.assertEqual(len(transitions), 1)
        self.assertEqual(transitions[0],
                         tskit.Mutation(node=6, parent=-1, derived_state="1"))

    def test_mutation_over_6_missing_data_0(self):
        genotypes = [-1, 0, 1, 1, 0]
        ancestral_state, transitions = self.do_map_mutations(
            self.tree, genotypes)
        self.assertEqual(ancestral_state, "0")
        self.assertEqual(len(transitions), 1)
        self.assertEqual(transitions[0],
                         tskit.Mutation(node=6, parent=-1, derived_state="1"))

    def test_mutation_over_0_missing_data_4(self):
        genotypes = [1, 0, 0, 0, -1]
        ancestral_state, transitions = self.do_map_mutations(
            self.tree, genotypes)
        self.assertEqual(ancestral_state, "0")
        self.assertEqual(len(transitions), 1)
        self.assertEqual(transitions[0],
                         tskit.Mutation(node=0, parent=-1, derived_state="1"))

    def test_multi_mutation_missing_data(self):
        genotypes = [1, 2, -1, 0, 0]
        ancestral_state, transitions = self.do_map_mutations(
            self.tree, genotypes)
        self.assertEqual(ancestral_state, "0")
        self.assertEqual(len(transitions), 2)
        self.assertEqual(transitions[0],
                         tskit.Mutation(node=5, parent=-1, derived_state="1"))
        self.assertEqual(transitions[1],
                         tskit.Mutation(node=1, parent=0, derived_state="2"))
Example #27
0
    def test_max_tree_height(self):
        nodes = io.StringIO("""\
            id      is_sample   population      individual      time    metadata
            0       1       0       -1      0.00000000000000
            1       1       0       -1      0.00000000000000
            2       1       0       -1      0.00000000000000
            3       1       0       -1      0.00000000000000
            4       0       0       -1      0.02445014598813
            5       0       0       -1      0.11067965364865
            6       0       0       -1      1.75005250750382
            7       0       0       -1      2.31067154311640
            8       0       0       -1      3.57331354884652
            9       0       0       -1      9.08308317451295
        """)
        edges = io.StringIO("""\
            id      left            right           parent  child
            0       0.00000000      1.00000000      4       0
            1       0.00000000      1.00000000      4       1
            2       0.00000000      1.00000000      5       2
            3       0.00000000      1.00000000      5       3
            4       0.79258618      0.90634460      6       4
            5       0.79258618      0.90634460      6       5
            6       0.05975243      0.79258618      7       4
            7       0.90634460      0.91029435      7       4
            8       0.05975243      0.79258618      7       5
            9       0.90634460      0.91029435      7       5
            10      0.91029435      1.00000000      8       4
            11      0.91029435      1.00000000      8       5
            12      0.00000000      0.05975243      9       4
            13      0.00000000      0.05975243      9       5
        """)
        ts = tskit.load_text(nodes, edges, strict=False)
        tree = (
           "   9   \n"
           " ┏━┻━┓ \n"
           " ┃   ┃ \n"
           " ┃   ┃ \n"
           " ┃   ┃ \n"
           " ┃   ┃ \n"
           " ┃   ┃ \n"
           " ┃   ┃ \n"
           " ┃   5 \n"
           " ┃  ┏┻┓\n"
           " 4  ┃ ┃\n"
           "┏┻┓ ┃ ┃\n"
           "0 1 2 3\n")
        t = ts.first()
        self.verify_text_rendering(t.draw_text(max_tree_height="ts"), tree)

        tree = (
           "   9   \n"
           " ┏━┻━┓ \n"
           " ┃   5 \n"
           " ┃  ┏┻┓\n"
           " 4  ┃ ┃\n"
           "┏┻┓ ┃ ┃\n"
           "0 1 2 3\n")
        t = ts.first()
        self.verify_text_rendering(t.draw_text(max_tree_height="tree"), tree)
        for bad_max_tree_height in [1, "sdfr", ""]:
            with self.assertRaises(ValueError):
                t.draw_text(max_tree_height=bad_max_tree_height)
Example #28
0
    def test_simple_tree_sequence(self):
        nodes = io.StringIO("""\
            id      is_sample   population      individual      time    metadata
            0       1       0       -1      0.00000000000000
            1       1       0       -1      0.00000000000000
            2       1       0       -1      0.00000000000000
            3       1       0       -1      0.00000000000000
            4       0       0       -1      0.02445014598813
            5       0       0       -1      0.11067965364865
            6       0       0       -1      1.75005250750382
            7       0       0       -1      2.31067154311640
            8       0       0       -1      3.57331354884652
            9       0       0       -1      9.08308317451295
        """)
        edges = io.StringIO("""\
            id      left            right           parent  child
            0       0.00000000      1.00000000      4       0
            1       0.00000000      1.00000000      4       1
            2       0.00000000      1.00000000      5       2
            3       0.00000000      1.00000000      5       3
            4       0.79258618      0.90634460      6       4
            5       0.79258618      0.90634460      6       5
            6       0.05975243      0.79258618      7       4
            7       0.90634460      0.91029435      7       4
            8       0.05975243      0.79258618      7       5
            9       0.90634460      0.91029435      7       5
            10      0.91029435      1.00000000      8       4
            11      0.91029435      1.00000000      8       5
            12      0.00000000      0.05975243      9       4
            13      0.00000000      0.05975243      9       5
        """)
        ts = tskit.load_text(nodes, edges, strict=False)

        ts_drawing = (
            "9.08┊    9    ┊         ┊         ┊         ┊         ┊\n"
            "    ┊  ┏━┻━┓  ┊         ┊         ┊         ┊         ┊\n"
            "3.57┊  ┃   ┃  ┊         ┊         ┊         ┊    8    ┊\n"
            "    ┊  ┃   ┃  ┊         ┊         ┊         ┊  ┏━┻━┓  ┊\n"
            "2.31┊  ┃   ┃  ┊    7    ┊         ┊    7    ┊  ┃   ┃  ┊\n"
            "    ┊  ┃   ┃  ┊  ┏━┻━┓  ┊         ┊  ┏━┻━┓  ┊  ┃   ┃  ┊\n"
            "1.75┊  ┃   ┃  ┊  ┃   ┃  ┊    6    ┊  ┃   ┃  ┊  ┃   ┃  ┊\n"
            "    ┊  ┃   ┃  ┊  ┃   ┃  ┊  ┏━┻━┓  ┊  ┃   ┃  ┊  ┃   ┃  ┊\n"
            "0.11┊  ┃   5  ┊  ┃   5  ┊  ┃   5  ┊  ┃   5  ┊  ┃   5  ┊\n"
            "    ┊  ┃  ┏┻┓ ┊  ┃  ┏┻┓ ┊  ┃  ┏┻┓ ┊  ┃  ┏┻┓ ┊  ┃  ┏┻┓ ┊\n"
            "0.02┊  4  ┃ ┃ ┊  4  ┃ ┃ ┊  4  ┃ ┃ ┊  4  ┃ ┃ ┊  4  ┃ ┃ ┊\n"
            "    ┊ ┏┻┓ ┃ ┃ ┊ ┏┻┓ ┃ ┃ ┊ ┏┻┓ ┃ ┃ ┊ ┏┻┓ ┃ ┃ ┊ ┏┻┓ ┃ ┃ ┊\n"
            "0.00┊ 0 1 2 3 ┊ 0 1 2 3 ┊ 0 1 2 3 ┊ 0 1 2 3 ┊ 0 1 2 3 ┊\n"
            "  0.00      0.06      0.79      0.91      0.91      1.00\n")
        self.verify_text_rendering(ts.draw_text(), ts_drawing)

        ts_drawing = (
            "9.08|    9    |         |         |         |         |\n"
            "    |  +-+-+  |         |         |         |         |\n"
            "3.57|  |   |  |         |         |         |    8    |\n"
            "    |  |   |  |         |         |         |  +-+-+  |\n"
            "2.31|  |   |  |    7    |         |    7    |  |   |  |\n"
            "    |  |   |  |  +-+-+  |         |  +-+-+  |  |   |  |\n"
            "1.75|  |   |  |  |   |  |    6    |  |   |  |  |   |  |\n"
            "    |  |   |  |  |   |  |  +-+-+  |  |   |  |  |   |  |\n"
            "0.11|  |   5  |  |   5  |  |   5  |  |   5  |  |   5  |\n"
            "    |  |  +++ |  |  +++ |  |  +++ |  |  +++ |  |  +++ |\n"
            "0.02|  4  | | |  4  | | |  4  | | |  4  | | |  4  | | |\n"
            "    | +++ | | | +++ | | | +++ | | | +++ | | | +++ | | |\n"
            "0.00| 0 1 2 3 | 0 1 2 3 | 0 1 2 3 | 0 1 2 3 | 0 1 2 3 |\n"
            "  0.00      0.06      0.79      0.91      0.91      1.00\n")
        self.verify_text_rendering(ts.draw_text(use_ascii=True), ts_drawing)

        ts_drawing = (
            "┊    9    ┊         ┊         ┊         ┊         ┊\n"
            "┊  ┏━┻━┓  ┊         ┊         ┊         ┊         ┊\n"
            "┊  ┃   ┃  ┊         ┊         ┊         ┊    8    ┊\n"
            "┊  ┃   ┃  ┊         ┊         ┊         ┊  ┏━┻━┓  ┊\n"
            "┊  ┃   ┃  ┊    7    ┊         ┊    7    ┊  ┃   ┃  ┊\n"
            "┊  ┃   ┃  ┊  ┏━┻━┓  ┊         ┊  ┏━┻━┓  ┊  ┃   ┃  ┊\n"
            "┊  ┃   ┃  ┊  ┃   ┃  ┊    6    ┊  ┃   ┃  ┊  ┃   ┃  ┊\n"
            "┊  ┃   ┃  ┊  ┃   ┃  ┊  ┏━┻━┓  ┊  ┃   ┃  ┊  ┃   ┃  ┊\n"
            "┊  ┃   5  ┊  ┃   5  ┊  ┃   5  ┊  ┃   5  ┊  ┃   5  ┊\n"
            "┊  ┃  ┏┻┓ ┊  ┃  ┏┻┓ ┊  ┃  ┏┻┓ ┊  ┃  ┏┻┓ ┊  ┃  ┏┻┓ ┊\n"
            "┊  4  ┃ ┃ ┊  4  ┃ ┃ ┊  4  ┃ ┃ ┊  4  ┃ ┃ ┊  4  ┃ ┃ ┊\n"
            "┊ ┏┻┓ ┃ ┃ ┊ ┏┻┓ ┃ ┃ ┊ ┏┻┓ ┃ ┃ ┊ ┏┻┓ ┃ ┃ ┊ ┏┻┓ ┃ ┃ ┊\n"
            "┊ 0 1 2 3 ┊ 0 1 2 3 ┊ 0 1 2 3 ┊ 0 1 2 3 ┊ 0 1 2 3 ┊\n"
            "0.00    0.06      0.79      0.91      0.91      1.00\n")
        self.verify_text_rendering(ts.draw_text(time_label_format=""), ts_drawing)

        ts_drawing = (
            "┊    9    ┊         ┊         ┊         ┊         ┊\n"
            "┊  ┏━┻━┓  ┊         ┊         ┊         ┊         ┊\n"
            "┊  ┃   ┃  ┊         ┊         ┊         ┊    8    ┊\n"
            "┊  ┃   ┃  ┊         ┊         ┊         ┊  ┏━┻━┓  ┊\n"
            "┊  ┃   ┃  ┊    7    ┊         ┊    7    ┊  ┃   ┃  ┊\n"
            "┊  ┃   ┃  ┊  ┏━┻━┓  ┊         ┊  ┏━┻━┓  ┊  ┃   ┃  ┊\n"
            "┊  ┃   ┃  ┊  ┃   ┃  ┊    6    ┊  ┃   ┃  ┊  ┃   ┃  ┊\n"
            "┊  ┃   ┃  ┊  ┃   ┃  ┊  ┏━┻━┓  ┊  ┃   ┃  ┊  ┃   ┃  ┊\n"
            "┊  ┃   5  ┊  ┃   5  ┊  ┃   5  ┊  ┃   5  ┊  ┃   5  ┊\n"
            "┊  ┃  ┏┻┓ ┊  ┃  ┏┻┓ ┊  ┃  ┏┻┓ ┊  ┃  ┏┻┓ ┊  ┃  ┏┻┓ ┊\n"
            "┊  4  ┃ ┃ ┊  4  ┃ ┃ ┊  4  ┃ ┃ ┊  4  ┃ ┃ ┊  4  ┃ ┃ ┊\n"
            "┊ ┏┻┓ ┃ ┃ ┊ ┏┻┓ ┃ ┃ ┊ ┏┻┓ ┃ ┃ ┊ ┏┻┓ ┃ ┃ ┊ ┏┻┓ ┃ ┃ ┊\n"
            "┊ 0 1 2 3 ┊ 0 1 2 3 ┊ 0 1 2 3 ┊ 0 1 2 3 ┊ 0 1 2 3 ┊\n"
            "┊         ┊         ┊         ┊         ┊         ┊\n")
        self.verify_text_rendering(
            ts.draw_text(time_label_format="", position_label_format=""), ts_drawing)
Example #29
0
    def test_draw_forky_tree(self):
        tree = (
           "      14            \n"
           "  ┏━━━━┻━━━━┓       \n"
           "  ┃        13       \n"
           "  ┃   ┏━┳━┳━╋━┳━━┓  \n"
           "  ┃   ┃ ┃ ┃ ┃ ┃ 12  \n"
           "  ┃   ┃ ┃ ┃ ┃ ┃ ┏┻┓ \n"
           " 11   ┃ ┃ ┃ ┃ ┃ ┃ ┃ \n"
           "┏━┻┓  ┃ ┃ ┃ ┃ ┃ ┃ ┃ \n"
           "┃ 10  ┃ ┃ ┃ ┃ ┃ ┃ ┃ \n"
           "┃ ┏┻┓ ┃ ┃ ┃ ┃ ┃ ┃ ┃ \n"
           "8 0 3 2 4 5 6 9 1 7 \n")

        nodes = io.StringIO("""\
            id      is_sample   population      individual      time    metadata
            0       1       0       -1      0.00000000000000
            1       1       0       -1      0.00000000000000
            2       1       0       -1      0.00000000000000
            3       1       0       -1      0.00000000000000
            4       1       0       -1      0.00000000000000
            5       1       0       -1      0.00000000000000
            6       1       0       -1      0.00000000000000
            7       1       0       -1      0.00000000000000
            8       1       0       -1      0.00000000000000
            9       1       0       -1      0.00000000000000
            10      0       0       -1      0.02398248117831
            11      0       0       -1      0.17378680550869
            12      0       0       -1      0.19950200178411
            13      0       0       -1      0.20000000000000
            14      0       0       -1      5.68339203134457
        """)
        edges = io.StringIO("""\
            left            right           parent  child
            0.00000000      1.00000000      10      0
            0.00000000      1.00000000      10      3
            0.00000000      1.00000000      11      8
            0.00000000      1.00000000      11      10
            0.00000000      1.00000000      12      1
            0.00000000      1.00000000      12      7
            0.00000000      1.00000000      13      2
            0.00000000      1.00000000      13      4
            0.00000000      1.00000000      13      5
            0.00000000      1.00000000      13      6
            0.00000000      1.00000000      13      9
            0.00000000      1.00000000      13      12
            0.00000000      1.00000000      14      11
            0.00000000      1.00000000      14      13
        """)
        ts = tskit.load_text(nodes, edges, strict=False)
        t = next(ts.trees())
        drawn = t.draw(format="unicode")
        self.verify_text_rendering(drawn, tree)
        self.verify_text_rendering(t.draw_text(), tree)

        tree = (
           "        14              \n"
           "  ┏━━━━━━┻━━━━━━┓       \n"
           "  ┃            13       \n"
           "  ┃        ┏━┳━┳┻┳━┳━━┓ \n"
           "  ┃        ┃ ┃ ┃ ┃ ┃ 12 \n"
           "  ┃        ┃ ┃ ┃ ┃ ┃ ┏┻┓\n"
           "x11xxxxxxx ┃ ┃ ┃ ┃ ┃ ┃ ┃\n"
           "┏━┻┓       ┃ ┃ ┃ ┃ ┃ ┃ ┃\n"
           "┃ 10       ┃ ┃ ┃ ┃ ┃ ┃ ┃\n"
           "┃ ┏┻┓      ┃ ┃ ┃ ┃ ┃ ┃ ┃\n"
           "8 0 3      2 4 5 6 9 1 7\n")
        labels = {u: str(u) for u in t.nodes()}
        labels[11] = "x11xxxxxxx"
        self.verify_text_rendering(t.draw_text(node_labels=labels), tree)
Example #30
0
    def test_four_leaves(self):
        nodes = io.StringIO("""\
        id      is_sample   population      individual      time    metadata
        0       1       0       -1      0.00000000000000
        1       1       0       -1      0.00000000000000
        2       1       0       -1      0.00000000000000
        3       1       0       -1      0.00000000000000
        4       0       0       -1      0.26676079696421
        5       0       0       -1      1.48826948286480
        6       0       0       -1      2.91835007758007
        """)
        edges = io.StringIO("""\
        left            right           parent  child
        0.00000000      1.00000000      4       0
        0.00000000      1.00000000      4       3
        0.00000000      1.00000000      5       2
        0.00000000      1.00000000      5       4
        0.00000000      1.00000000      6       1
        0.00000000      1.00000000      6       5
        """)
        tree = (
            "  6     \n"
            "┏━┻━┓   \n"
            "┃   5   \n"
            "┃ ┏━┻┓  \n"
            "┃ ┃  4  \n"
            "┃ ┃ ┏┻┓ \n"
            "1 2 0 3 \n")
        ts = tskit.load_text(nodes, edges, strict=False)
        t = ts.first()
        drawn = t.draw(format="unicode")
        self.verify_text_rendering(drawn, tree)
        self.verify_text_rendering(t.draw_text(), tree)

        drawn = t.draw_text(orientation="bottom")
        tree = (
            "1 2 0 3\n"
            "┃ ┃ ┗┳┛\n"
            "┃ ┃  4 \n"
            "┃ ┗━┳┛ \n"
            "┃   5  \n"
            "┗━┳━┛  \n"
            "  6    \n")
        self.verify_text_rendering(drawn, tree)

        tree = (
            " ┏━━━━1\n"
            " ┃     \n"
            "6┫ ┏━━2\n"
            " ┃ ┃   \n"
            " ┗5┫ ┏0\n"
            "   ┗4┫  \n"
            "     ┗3\n")
        self.verify_text_rendering(t.draw_text(orientation="left"), tree)

        tree = (
            "2.92┊   6     ┊\n"
            "    ┊ ┏━┻━┓   ┊\n"
            "1.49┊ ┃   5   ┊\n"
            "    ┊ ┃ ┏━┻┓  ┊\n"
            "0.27┊ ┃ ┃  4  ┊\n"
            "    ┊ ┃ ┃ ┏┻┓ ┊\n"
            "0.00┊ 1 2 0 3 ┊\n"
            "  0.00      1.00\n")
        self.verify_text_rendering(ts.draw_text(), tree)

        tree = (
            "  6    \n"
            "+-+-+  \n"
            "|   5  \n"
            "| +-++ \n"
            "| |  4 \n"
            "| | +++\n"
            "1 2 0 3\n")
        drawn = t.draw(format="ascii")
        self.verify_text_rendering(drawn, tree)

        tree = (
            "  6     \n"
            "┏━┻━┓   \n"
            "┃xxxxxxxxxx\n"
            "┃ ┏━┻┓  \n"
            "┃ ┃  4  \n"
            "┃ ┃ ┏┻┓ \n"
            "1 2 0 3 \n")
        labels = {u: str(u) for u in t.nodes()}
        labels[5] = "xxxxxxxxxx"
        drawn = t.draw_text(node_labels=labels)
        self.verify_text_rendering(drawn, tree)

        tree = (
            " ┏━━━━━━━━━━━━━1\n"
            " ┃              \n"
            "6┫          ┏━━2\n"
            " ┃          ┃   \n"
            " ┗xxxxxxxxxx┫ ┏0\n"
            "            ┗4┫ \n"
            "              ┗3\n")
        drawn = t.draw_text(node_labels=labels, orientation="left")
        self.verify_text_rendering(drawn, tree)

        tree = (
            "2.92┊   6         ┊\n"
            "    ┊ ┏━┻━┓       ┊\n"
            "1.49┊ ┃xxxxxxxxxx ┊\n"
            "    ┊ ┃ ┏━┻┓      ┊\n"
            "0.27┊ ┃ ┃  4      ┊\n"
            "    ┊ ┃ ┃ ┏┻┓     ┊\n"
            "0.00┊ 1 2 0 3     ┊\n"
            "  0.00          1.00\n")
        drawn = ts.draw_text(node_labels=labels)
        self.verify_text_rendering(drawn, tree)