def test_restore_rooting(self): # rooted source source = TreeNode.read(['(((e,f),g),((c,d),(b,a)));']) target = TreeNode.read(['(((a,b),(c,d)),(e,f),g);']) rooted = restore_rooting(source, target) self.assertTrue(_exact_compare(rooted, source)) # unrooted source source = TreeNode.read(['(((e,f),g),(a,b),(c,d));']) unrooted = restore_rooting(source, target) self.assertTrue(_exact_compare(unrooted, source)) # test support handling source = TreeNode.read(['(((e,f),g),((c,d),(b,a)));']) target = TreeNode.read(['(((a,b)95,(c,d)90)80,(e,f)100,g);']) assign_supports(target) obs = restore_rooting(source, target) exp = TreeNode.read(['(((e,f)100,g)80,((c,d)90,(b,a)95)80);']) assign_supports(exp) self.assertTrue(_exact_compare(obs, exp)) # taxa don't match msg = 'Source and target trees have different taxa.' with self.assertRaisesRegex(ValueError, msg): restore_rooting(source, TreeNode.read(['((a,b),(c,d));']))
def test_root_above(self): # test rooted tree tree1 = TreeNode.read([ '(((a:1.0,b:0.8)c:2.4,(d:0.8,e:0.6)f:1.2)g:0.4,' '(h:0.5,i:0.7)j:1.8)k;' ]) tree1_cg = root_above(tree1.find('c')) exp = TreeNode.read([ '((a:1.0,b:0.8)c:1.2,((d:0.8,e:0.6)f:1.2,(h:0.5,' 'i:0.7)j:2.2)g:1.2);' ]) self.assertTrue(_exact_compare(exp, tree1_cg)) tree1_ij = root_above(tree1.find('i')) exp = TreeNode.read([ '(i:0.35,(h:0.5,((a:1.0,b:0.8)c:2.4,(d:0.8,' 'e:0.6)f:1.2)g:2.2)j:0.35);' ]) self.assertTrue(_exact_compare(exp, tree1_ij)) # test unrooted tree tree2 = TreeNode.read([ '(((a:0.6,b:0.5)g:0.3,c:0.8)h:0.4,(d:0.4,' 'e:0.5)i:0.5,f:0.9)j;' ]) tree2_ag = root_above(tree2.find('a')) exp = TreeNode.read([ '(a:0.3,(b:0.5,(c:0.8,((d:0.4,e:0.5)i:0.5,' 'f:0.9)j:0.4)h:0.3)g:0.3);' ]) self.assertTrue(_exact_compare(exp, tree2_ag)) tree2_gh = root_above(tree2.find('g')) exp = TreeNode.read([ '((a:0.6,b:0.5)g:0.15,(c:0.8,((d:0.4,e:0.5)i:0.5,' 'f:0.9)j:0.4)h:0.15);' ]) self.assertTrue(_exact_compare(exp, tree2_gh)) # test unrooted tree with 1 basal node tree3 = TreeNode.read( ['(((a:0.4,b:0.3)e:0.1,(c:0.4,' 'd:0.1)f:0.2)g:0.6)h:0.2;']) tree3_ae = root_above(tree3.find('a')) exp = TreeNode.read( ['(a:0.2,(b:0.3,((c:0.4,d:0.1)f:0.2,' 'h:0.6)g:0.1)e:0.2);']) self.assertTrue(_exact_compare(exp, tree3_ae))
def test_root_by_outgroup(self): tree = TreeNode.read(['((((a,b),(c,d)),(e,f)),g);']) # outgroup is monophyletic obs = root_by_outgroup(tree, outgroup=['a', 'b']) exp = TreeNode.read(['((a,b),((c,d),((e,f),g)));']) self.assertTrue(_exact_compare(obs, exp)) # outgroup is monophyletic after rotating obs = root_by_outgroup(tree, outgroup=['e', 'f', 'g']) exp = TreeNode.read(['(((e,f),g),((c,d),(b,a)));']) self.assertTrue(_exact_compare(obs, exp)) # outgroup is not monophyletic msg = 'Outgroup is not monophyletic in tree.' with self.assertRaisesRegex(ValueError, msg): root_by_outgroup(tree, outgroup=['a', 'c']) # outgroup is single taxon obs = root_by_outgroup(tree, outgroup=['a']) exp = TreeNode.read(['(a,(b,((c,d),((e,f),g))));']) self.assertTrue(_exact_compare(obs, exp)) # outgroup has extra taxa obs = root_by_outgroup(tree, outgroup=['a', 'b', 'x']) exp = TreeNode.read(['((a,b),((c,d),((e,f),g)));']) self.assertTrue(_exact_compare(obs, exp)) # outgroup has extra taxa but strict mode msg = 'Outgroup is not a subset of tree taxa.' with self.assertRaisesRegex(ValueError, msg): root_by_outgroup(tree, outgroup=['a', 'b', 'x'], strict=True) # outgroup is not in tree msg = 'None of outgroup taxa are present in tree.' with self.assertRaisesRegex(ValueError, msg): root_by_outgroup(tree, outgroup=['x', 'y']) # outgroup is the whole tree msg = 'Outgroup constitutes the entire tree.' with self.assertRaisesRegex(ValueError, msg): root_by_outgroup(tree, outgroup='abcdefg') # generate unrooted tree obs = root_by_outgroup(tree, outgroup=['a', 'b'], unroot=True) exp = TreeNode.read(['(((e,f),g),(a,b),(c,d));']) self.assertTrue(_exact_compare(obs, exp))
def test_restore_node_labels(self): # simple case source = TreeNode.read(['((a,b)x,(c,d)y);']) target = TreeNode.read(['((a:0.5,b:0.6):1.2,(c:1.0,d:1.4):0.4);']) obs = restore_node_labels(source, target) exp = TreeNode.read(['((a:0.5,b:0.6)x:1.2,(c:1.0,d:1.4)y:0.4);']) self.assertTrue(_exact_compare(obs, exp)) # complex case with missing label, extra taxa, label overwrittern source = TreeNode.read(['(((a,b)85,c)90,((d,e)98,(f,g)93));']) target = TreeNode.read(['((((g,f),(e,d))x,(c,(a,b))y),h);']) obs = restore_node_labels(source, target) exp = TreeNode.read(['((((g,f)93,(e,d)98)x,(c,(a,b)85)90),h);']) self.assertTrue(_exact_compare(obs, exp)) # a duplicated node label msg = 'Duplicated node label "x" found.' with self.assertRaisesRegex(ValueError, msg): restore_node_labels(TreeNode.read(['((a,b)x,(c,d)x);']), target)
def test_unroot_at(self): # sample example from doctest of scikit-bio's `root_at` tree = TreeNode.read(['(((a,b)c,(d,e)f)g,h)i;']) obs = unroot_at(tree.find('c')) exp = TreeNode.read(['(((d,e)f,h)g,a,b)c;']) self.assertTrue(_exact_compare(obs, exp)) # test branch support handling tree.find('c').support = 95 tree.find('f').support = 99 obs = unroot_at(tree.find('c')) exp = TreeNode.read(["(((d,e)'99:f',h)'95:g',a,b)c;"]) assign_supports(exp) self.assertTrue(_exact_compare(obs, exp)) # test branch length handling tree = TreeNode.read( ['(((a:1.1,b:2.2)c:1.3,(d:1.4,e:0.8)f:0.6)g:0.4,h:3.1)i;']) obs = unroot_at(tree.find('c')) exp = TreeNode.read( ['(((d:1.4,e:0.8)f:0.6,h:3.5)g:1.3,a:1.1,b:2.2)c;']) self.assertTrue(_exact_compare(obs, exp))
def test_restore_node_order(self): source = TreeNode.read(['(((a,b),(c,d)),((e,f),g));']) target = TreeNode.read(['((g,(e,f)100),((d,c)80,(a,b)90));']) obs = restore_node_order(source, target) exp = TreeNode.read(['(((a,b)90,(c,d)80),((e,f)100,g));']) self.assertTrue(_exact_compare(obs, exp)) msg = 'Two trees have different sizes.' with self.assertRaisesRegex(ValueError, msg): restore_node_order(TreeNode.read(['((a,b),(c,d));']), target) msg = 'Two trees have different topologies.' with self.assertRaisesRegex(ValueError, msg): restore_node_order(TreeNode.read(['((((a,b),c),d),(e,(f,g)));']), target)
def test_exact_compare(self): # test name tree0 = TreeNode.read(['((e,d)f,(c,(a,b)));']) tree1 = TreeNode.read(['(((a,b),c),(d,e)f);']) self.assertTrue(_exact_compare(tree1, tree1)) self.assertFalse(_exact_compare(tree0, tree1)) # test length tree2 = TreeNode.read(['(((a:1,b):2,c:1),(d:1,e:2)f:1);']) self.assertTrue(_exact_compare(tree2, tree2)) self.assertFalse(_exact_compare(tree1, tree2)) tree3 = TreeNode.read(['(((a:1,b:0.0):2,c:1):0.0,(d:1,e:2)f:1);']) self.assertTrue(_exact_compare(tree3, tree3)) self.assertFalse(_exact_compare(tree2, tree3)) # test support tree4 = TreeNode.read(['(((a:1,b:1)95:2,c:1)98:3,(d:1,e:2)0.0:1);']) tree5 = TreeNode.read(['(((a:1,b:1)95:2,c:1)98:3,(d:1,e:2):1);']) assign_supports(tree4) self.assertTrue(_exact_compare(tree4, tree4)) self.assertFalse(_exact_compare(tree4, tree5)) assign_supports(tree5) self.assertFalse(_exact_compare(tree4, tree5))
def test_walk_copy(self): tree1 = TreeNode.read([ '(((a:1.0,b:0.8)c:2.4,(d:0.8,e:0.6)f:1.2)g:0.4,' '(h:0.5,i:0.7)j:1.8)k;' ]) # test pos = root msg = 'Cannot walk from root of a rooted tree.' with self.assertRaisesRegex(ValueError, msg): walk_copy(tree1.find('k'), tree1.find('j')) msg = 'Source and node are not neighbors.' # test pos = derived with self.assertRaisesRegex(ValueError, msg): walk_copy(tree1.find('a'), tree1.find('b')) with self.assertRaisesRegex(ValueError, msg): walk_copy(tree1.find('c'), tree1.find('f')) with self.assertRaisesRegex(ValueError, msg): walk_copy(tree1.find('f'), tree1.find('j')) with self.assertRaisesRegex(ValueError, msg): walk_copy(tree1.find('f'), tree1.find('k')) # test pos = basal with self.assertRaisesRegex(ValueError, msg): walk_copy(tree1.find('g'), tree1.find('a')) with self.assertRaisesRegex(ValueError, msg): walk_copy(tree1.find('g'), tree1.find('k')) # pos = derived, move = up exp = TreeNode.read( ['(b:0.8,((d:0.8,e:0.6)f:1.2,(h:0.5,i:0.7)j:2.2)' 'g:2.4)c:1.0;']) obs = walk_copy(tree1.find('c'), tree1.find('a')) self.assertTrue(_exact_compare(exp, obs)) # pos = derived, move = down exp = TreeNode.read(['(d:0.8,e:0.6)f:1.2;']) obs = walk_copy(tree1.find('f'), tree1.find('g')) self.assertTrue(_exact_compare(exp, obs)) # pos = basal, move = top exp = TreeNode.read(['((d:0.8,e:0.6)f:1.2,(h:0.5,i:0.7)j:2.2)g:2.4;']) obs = walk_copy(tree1.find('g'), tree1.find('c')) self.assertTrue(_exact_compare(exp, obs)) # pos = basal, move = bottom exp = TreeNode.read(['(h:0.5,i:0.7)j:2.2;']) obs = walk_copy(tree1.find('j'), tree1.find('g')) self.assertTrue(_exact_compare(exp, obs)) tree2 = TreeNode.read( ['(((a:1.0,b:0.8)c:2.4,d:0.8)e:0.6,f:1.2,' 'g:0.4)h:0.5;']) # pos = basal, move = down exp = TreeNode.read(['((a:1.0,b:0.8)c:2.4,d:0.8)e:0.6;']) obs = walk_copy(tree2.find('e'), tree2.find('h')) self.assertTrue(_exact_compare(exp, obs)) # pos = basal, move = up exp = TreeNode.read(['(d:0.8,(f:1.2,g:0.4)h:0.6)e:2.4;']) obs = walk_copy(tree2.find('e'), tree2.find('c')) self.assertTrue(_exact_compare(exp, obs))