def test_backfill_names_gap(self): """correctly backfill names""" consensus_tree = DndParser("(((s1,s2)g1,(s3,s4)g2,(s5,s6)g3)f1)o1;") rank_lookup = {'s':6,'g':5,'f':4,'o':3,'c':2,'p':1,'k':0} for n in consensus_tree.traverse(include_self=True): n.Rank = rank_lookup[n.Name[0]] input = "((((1)s1,(2)s2),((3)s3,(4)s5)))o1;" lookup = dict([(n.Name, n) for n in consensus_tree.traverse(include_self=True)]) #exp = "((((1)s1,(2)s2)g1,((3)'g2; s3',(4)'g3; s5')))'o1; f1'" t = DndParser(input) t.Rank = 3 t.Children[0].Rank = None t.Children[0].Children[0].Rank = None t.Children[0].Children[1].Rank = None t.Children[0].Children[0].Children[0].Rank = 6 t.Children[0].Children[0].Children[1].Rank = 6 t.Children[0].Children[1].Children[0].Rank = 6 t.Children[0].Children[1].Children[1].Rank = 6 backfill_names_gap(t, lookup) self.assertEqual(t.BackFillNames, ['o1']) self.assertEqual(t.Children[0].BackFillNames, []) self.assertEqual(t.Children[0].Children[0].BackFillNames, []) self.assertEqual(t.Children[0].Children[1].BackFillNames, []) self.assertEqual(t.Children[0].Children[0].Children[0].BackFillNames, ['f1','g1','s1']) self.assertEqual(t.Children[0].Children[0].Children[1].BackFillNames, ['f1','g1','s2']) self.assertEqual(t.Children[0].Children[1].Children[0].BackFillNames, ['f1','g2','s3']) self.assertEqual(t.Children[0].Children[1].Children[1].BackFillNames, ['f1','g3','s5'])
def test_reroot(self): """Should correctly reroot a tree""" t = DndParser("(((a,b)c,(d,e)f)g,(h,i)j);") tips = ['a','b'] for n in t.traverse(): n.Length = 1.0 # note, g is lost because it has a single descendent and gets pruned off exp = "((a:1.0,b:1.0)c:0.5,((d:1.0,e:1.0)f:1.0,(h:1.0,i:1.0)j:2.0):0.5);" obs = reroot(t, tips) self.assertEqual(obs.getNewick(with_distances=True), exp)
def test_commonname_promotion(self): """correctly promote names if possible""" consensus_tree = DndParser("(((s1,s2)g1,(s3,s4)g2,(s5,s6)g3)f1)o1;") rank_lookup = {'s':6,'g':5,'f':4,'o':3,'c':2,'p':1,'k':0} for n in consensus_tree.traverse(include_self=True): n.Rank = rank_lookup[n.Name[0]] input = "((((1)s1,(2)s2),((3)s3,(4)s5)))o1;" lookup = dict([(n.Name, n) for n in consensus_tree.traverse(include_self=True)]) exp = "((((1)s1,(2)s2)g1,((3)'g2; s3',(4)'g3; s5')))'o1; f1';" t = DndParser(input) t.Rank = 3 t.Children[0].Rank = None t.Children[0].Children[0].Rank = None t.Children[0].Children[1].Rank = None t.Children[0].Children[0].Children[0].Rank = 6 t.Children[0].Children[0].Children[1].Rank = 6 t.Children[0].Children[1].Children[0].Rank = 6 t.Children[0].Children[1].Children[1].Rank = 6 backfill_names_gap(t, lookup) commonname_promotion(t) self.assertEqual(t.getNewick(with_distances=False), exp)
def test_gnodedata(self): """DndParser should assign Name to internal nodes correctly""" t = DndParser(nodedata) self.assertEqual(len(t), 2) self.assertEqual(len(t[0]), 0) #first child is terminal self.assertEqual(len(t[1]), 2) #second child has two children self.assertEqual(str(t), '(abc:3.0,(def:4.0,ghi:5.0)jkl:6.0);') info_dict = {} for node in t.traverse(): info_dict[node.Name] = node.Length self.assertEqual(info_dict['abc'], 3.0) self.assertEqual(info_dict['def'], 4.0) self.assertEqual(info_dict['ghi'], 5.0) self.assertEqual(info_dict['jkl'], 6.0)
def test_gnodedata(self): """DndParser should assign Name to internal nodes correctly""" t = DndParser(nodedata) self.assertEqual(len(t), 2) self.assertEqual(len(t[0]), 0) #first child is terminal self.assertEqual(len(t[1]), 2) #second child has two children self.assertEqual(str(t), '(abc:3.0,(def:4.0,ghi:5.0)jkl:6.0);') info_dict = {} for node in t.traverse(): info_dict[node.Name] = node.Length self.assertEqual(info_dict['abc'], 3.0) self.assertEqual(info_dict['def'], 4.0) self.assertEqual(info_dict['ghi'], 5.0) self.assertEqual(info_dict['jkl'], 6.0)
def test_backfill_names_dangling(self): """correctly fill in dangling missing ranks""" consensus_tree = DndParser("(((s1,s2)g1,(s3,s4)g2,(s5,s6)g3)f1)o1;") input = "((((1),(2)),((3),(4))))'o1; f1';" lookup = dict([(n.Name, n) for n in consensus_tree.traverse(include_self=True)])
class OldPhyloNodeTests(TestCase): """Tests of the PhyloNode class -- these are all now methods of RangeNode.""" def setUp(self): """Make a couple of standard trees""" self.t1 = DndParser('((a,(b,c)),(d,e))', RangeNode) #selt.t1 indices: ((0,(1,2)5)6,(3,4)7)8 def test_makeIdIndex(self): """RangeNode makeIdIndex should assign ids to every node""" self.t1.makeIdIndex() result = self.t1.IdIndex nodes = list(self.t1.traverse(self_before=True)) #check we got an entry for each node self.assertEqual(len(result), len(nodes)) #check the ids are in the result for i in nodes: assert hasattr(i, 'Id') assert i.Id in result def test_assignQ_single_passed(self): """RangeNode assignQ should propagate single Q param down tree""" #should work if Q explicitly passed t = self.t1 Q = ['a'] t.assignQ(Q) for node in t.traverse(self_before=True): assert node.Q is Q def test_assignQ_single_set(self): """RangeNode assignQ should propagate single Q if set""" t = self.t1 Q = ['a'] assert not hasattr(t, 'Q') t.Q = Q t.assignQ() for node in t.traverse(self_before=True): assert node.Q is Q def test_assignQ_single_overwrite(self): """RangeNode assignQ should overwrite root Q if new Q passed""" t = self.t1 Q = ['a'] Q2 = ['b'] t.Q = Q t.assignQ(Q2) for node in t.traverse(self_before=True): assert node.Q is Q2 assert not node.Q is Q def test_assignQ_multiple(self): """RangeNode assignQ should propagate multiple Qs""" t = self.t1 Q1 = ['a'] Q2 = ['b'] Q3 = ['c'] t.makeIdIndex() t.IdIndex[7].Q = Q1 t.IdIndex[5].Q = Q2 t.assignQ(Q3) result = [i.Q for i in t.traverse(self_after=True)] assert t.Q is Q3 self.assertEqual(result, [Q3, Q2, Q2, Q2, Q3, Q1, Q1, Q1, Q3]) def test_assignQ_multiple_overwrite(self): """RangeNode assignQ should allow overwrite""" t = self.t1 Q1 = ['a'] Q2 = ['b'] Q3 = ['c'] t.makeIdIndex() t.IdIndex[7].Q = Q1 t.IdIndex[5].Q = Q2 t.assignQ(Q3, overwrite=True) for i in t.traverse(self_after=True): assert i.Q is Q3 def test_assignQ_special(self): """RangeNode assignQ should work with special Qs""" t = self.t1 Q1 = 'a' Q2 = 'b' Q3 = 'c' t.makeIdIndex() special = {7: Q1, 1: Q2} #won't work if no Q at root self.assertRaises(ValueError, t.assignQ, special_qs=special) t.assignQ(Q3, special_qs=special) result = [i.Q for i in t.traverse(self_after=True)] self.assertEqual(result, ['c', 'b', 'c', 'c', 'c', 'a', 'a', 'a', 'c']) def test_assignP(self): """RangeNode assignP should work when Qs set.""" t = self.t1 for i in t.traverse(self_before=True): i.Length = random() * 0.5 #range 0 to 0.5 t.Q = Rates.random(DnaPairs) t.assignQ() t.assignP() t.assignIds() for node in t.traverse(self_after=True): if node.Parent is not None: self.assertFloatEqual(average(1-diag(node.P._data), axis=0), \ node.Length) def test_assignLength(self): """RangeNode assignLength should set branch length""" t = self.t1 t.assignLength(0.3) for i in t.traverse(self_before=True): self.assertEqual(i.Length, 0.3) def test_evolve(self): """RangeNode evolve should work on a starting vector""" t = self.t1 t.Q = Rates.random(DnaPairs) t.assignQ() t.assignLength(0.1) t.assignP() start = array([ 1, 0, 2, 1, 0, 0, 2, 1, 2, 0, 1, 2, 1, 0, 2, 0, 0, 3, 0, 2, 1, 0, 3, 1, 0, 2, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3 ]) t.evolve(start) for i in t.traverse(): self.assertEqual(len(i.Sequence), len(start)) self.assertNotEqual(i.Sequence, start) #WARNING: Doesn't test base freqs etc. at this point, but those aren't #really evolve()'s responsibity (tested as self.P.mutate(seq) once #P is set, which we've already demonstrated works.) def test_assignPs(self): """RangeNode assignPs should assign multiple scaled P matrices""" t = self.t1 for i in t.traverse(self_before=True): i.Length = random() * 0.5 #range 0 to 0.5 t.Q = Rates.random(DnaPairs) t.assignQ() t.assignPs([1, 0.5, 0.25]) t.assignIds() for node in t.traverse(self_after=True): if node.Parent is not None: self.assertEqual(len(node.Ps), 3) self.assertFloatEqual(average(1-diag(node.Ps[0]._data), axis=0), \ node.Length) self.assertFloatEqual(average(1-diag(node.Ps[1]._data), axis=0), \ 0.5*node.Length) self.assertFloatEqual(average(1-diag(node.Ps[2]._data), axis=0), \ 0.25*node.Length) def test_evolveSeqs(self): """PhlyoNode evolveSeqs should evolve multiple sequences""" t = self.t1 for i in t.traverse(self_before=True): i.Length = 0.5 t.Q = Rates.random(DnaPairs) t.assignQ() t.assignPs([1, 1, 0.1]) t.assignIds() orig_seqs = [array(i) for i in [randint(0,4,200), randint(0,4,200), \ randint(0,4,200)]] t.evolveSeqs(orig_seqs) for node in t.traverse(): #only look at leaves if node.Parent is not None: self.assertEqual(len(node.Sequences), 3) for orig, new in zip(orig_seqs, node.Sequences): self.assertEqual(len(orig), len(new)) self.assertNotEqual(orig, new) assert sum(orig_seqs[1]!=node.Sequences[1]) > \ sum(orig_seqs[2]!=node.Sequences[2])
class OldPhyloNodeTests(TestCase): """Tests of the PhyloNode class -- these are all now methods of RangeNode.""" def setUp(self): """Make a couple of standard trees""" self.t1 = DndParser('((a,(b,c)),(d,e))', RangeNode) #selt.t1 indices: ((0,(1,2)5)6,(3,4)7)8 def test_makeIdIndex(self): """RangeNode makeIdIndex should assign ids to every node""" self.t1.makeIdIndex() result = self.t1.IdIndex nodes = list(self.t1.traverse(self_before=True)) #check we got an entry for each node self.assertEqual(len(result), len(nodes)) #check the ids are in the result for i in nodes: assert hasattr(i, 'Id') assert i.Id in result def test_assignQ_single_passed(self): """RangeNode assignQ should propagate single Q param down tree""" #should work if Q explicitly passed t = self.t1 Q = ['a'] t.assignQ(Q) for node in t.traverse(self_before=True): assert node.Q is Q def test_assignQ_single_set(self): """RangeNode assignQ should propagate single Q if set""" t = self.t1 Q = ['a'] assert not hasattr(t, 'Q') t.Q = Q t.assignQ() for node in t.traverse(self_before=True): assert node.Q is Q def test_assignQ_single_overwrite(self): """RangeNode assignQ should overwrite root Q if new Q passed""" t = self.t1 Q = ['a'] Q2 = ['b'] t.Q = Q t.assignQ(Q2) for node in t.traverse(self_before=True): assert node.Q is Q2 assert not node.Q is Q def test_assignQ_multiple(self): """RangeNode assignQ should propagate multiple Qs""" t = self.t1 Q1 = ['a'] Q2 = ['b'] Q3 = ['c'] t.makeIdIndex() t.IdIndex[7].Q = Q1 t.IdIndex[5].Q = Q2 t.assignQ(Q3) result = [i.Q for i in t.traverse(self_after=True)] assert t.Q is Q3 self.assertEqual(result, [Q3,Q2,Q2,Q2,Q3,Q1,Q1,Q1,Q3]) def test_assignQ_multiple_overwrite(self): """RangeNode assignQ should allow overwrite""" t = self.t1 Q1 = ['a'] Q2 = ['b'] Q3 = ['c'] t.makeIdIndex() t.IdIndex[7].Q = Q1 t.IdIndex[5].Q = Q2 t.assignQ(Q3, overwrite=True) for i in t.traverse(self_after=True): assert i.Q is Q3 def test_assignQ_special(self): """RangeNode assignQ should work with special Qs""" t = self.t1 Q1 = 'a' Q2 = 'b' Q3 = 'c' t.makeIdIndex() special = {7:Q1, 1:Q2} #won't work if no Q at root self.assertRaises(ValueError, t.assignQ, special_qs=special) t.assignQ(Q3, special_qs=special) result = [i.Q for i in t.traverse(self_after=True)] self.assertEqual(result, ['c','b','c','c','c','a','a','a','c']) def test_assignP(self): """RangeNode assignP should work when Qs set.""" t = self.t1 for i in t.traverse(self_before=True): i.Length = random() * 0.5 #range 0 to 0.5 t.Q = Rates.random(DnaPairs) t.assignQ() t.assignP() t.assignIds() for node in t.traverse(self_after=True): if node.Parent is not None: self.assertFloatEqual(average(1-diag(node.P._data), axis=0), \ node.Length) def test_assignLength(self): """RangeNode assignLength should set branch length""" t = self.t1 t.assignLength(0.3) for i in t.traverse(self_before=True): self.assertEqual(i.Length, 0.3) def test_evolve(self): """RangeNode evolve should work on a starting vector""" t = self.t1 t.Q = Rates.random(DnaPairs) t.assignQ() t.assignLength(0.1) t.assignP() start = array([1,0,2,1,0,0,2,1,2,0,1,2,1,0,2,0,0,3,0,2,1,0,3,1,0,2,0,0,0,0,0,1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,3]) t.evolve(start) for i in t.traverse(): self.assertEqual(len(i.Sequence), len(start)) self.assertNotEqual(i.Sequence, start) #WARNING: Doesn't test base freqs etc. at this point, but those aren't #really evolve()'s responsibity (tested as self.P.mutate(seq) once #P is set, which we've already demonstrated works.) def test_assignPs(self): """RangeNode assignPs should assign multiple scaled P matrices""" t = self.t1 for i in t.traverse(self_before=True): i.Length = random() * 0.5 #range 0 to 0.5 t.Q = Rates.random(DnaPairs) t.assignQ() t.assignPs([1, 0.5, 0.25]) t.assignIds() for node in t.traverse(self_after=True): if node.Parent is not None: self.assertEqual(len(node.Ps), 3) self.assertFloatEqual(average(1-diag(node.Ps[0]._data), axis=0), \ node.Length) self.assertFloatEqual(average(1-diag(node.Ps[1]._data), axis=0), \ 0.5*node.Length) self.assertFloatEqual(average(1-diag(node.Ps[2]._data), axis=0), \ 0.25*node.Length) def test_evolveSeqs(self): """PhlyoNode evolveSeqs should evolve multiple sequences""" t = self.t1 for i in t.traverse(self_before=True): i.Length = 0.5 t.Q = Rates.random(DnaPairs) t.assignQ() t.assignPs([1, 1, 0.1]) t.assignIds() orig_seqs = [array(i) for i in [randint(0,4,200), randint(0,4,200), \ randint(0,4,200)]] t.evolveSeqs(orig_seqs) for node in t.traverse(): #only look at leaves if node.Parent is not None: self.assertEqual(len(node.Sequences), 3) for orig, new in zip(orig_seqs, node.Sequences): self.assertEqual(len(orig), len(new)) self.assertNotEqual(orig, new) assert sum(orig_seqs[1]!=node.Sequences[1]) > \ sum(orig_seqs[2]!=node.Sequences[2])