def join_nodes(parsed): """Join the nodes from tips up expects parsed to go from high -> low similarity, ie: 99, 97, 94, ... """ last_lookup, last_nodes = parsed[0] for lookup, nodes in parsed[1:]: for n in nodes: replace_nodes = [last_lookup[c.Name] for c in n.Children] new_c = [] todelete = set([]) for c in n.Children: last_lookup[c.Name].Length = c.Length new_c.append(last_lookup[c.Name]) todelete.add(c) n.removeDeleted(lambda x: x in todelete) for c in new_c: n.append(c) last_lookup = lookup last_nodes = nodes root = PhyloNode() for c in last_nodes: root.append(c) return root
def test_missing_tip_name(self): """DndParser should produce the correct tree when missing a name""" obs = DndParser(missing_tip_name) exp = PhyloNode() exp.append(PhyloNode()) exp.append(PhyloNode()) exp.Children[0].append(PhyloNode(Name='a')) exp.Children[0].append(PhyloNode(Name='b')) exp.Children[1].append(PhyloNode(Name='c')) exp.Children[1].append(PhyloNode()) self.assertEqual(str(obs), str(exp))
def test_nonames(self): """DndParser should produce the correct tree when there are no names""" obs = DndParser(no_names) exp = PhyloNode() exp.append(PhyloNode()) exp.append(PhyloNode()) exp.Children[0].append(PhyloNode()) exp.Children[0].append(PhyloNode()) exp.Children[1].append(PhyloNode()) exp.Children[1].append(PhyloNode()) self.assertEqual(str(obs), str(exp))
def condense_node_order(matrix, smallest_index, node_order): """condenses two nodes in node_order based on smallest_index info This function is used to create a tree while condensing a matrix with the condense_matrix function. The smallest_index is retrieved with find_smallest_index. The first index is replaced with a node object that combines the two nodes corresponding to the indices in node order. The second index in smallest_index is replaced with None. Also sets the branch length of the nodes to 1/2 of the distance between the nodes in the matrix""" index1, index2 = smallest_index node1 = node_order[index1] node2 = node_order[index2] #get the distance between the nodes and assign 1/2 the distance to the #Length property of each node distance = matrix[index1, index2] nodes = [node1, node2] d = distance / 2.0 for n in nodes: if n.Children: n.Length = d - n.Children[0].TipLength else: n.Length = d n.TipLength = d #combine the two nodes into a new PhyloNode object new_node = PhyloNode() new_node.Children.append(node1) new_node.Children.append(node2) node1.Parent = new_node node2.Parent = new_node #replace the object at index1 with the combined node node_order[index1] = new_node #replace the object at index2 with None node_order[index2] = None return node_order
def make_nodes(otu_map, length, level): """returns nodes that have been created outta the map""" nodedist = length / 2.0 nodes = [] lookup = {} for clusterid, seqids in otu_map: rep = seqids[0] children = [] for id_ in seqids: node = PhyloNode(Name=id_, Length=nodedist) children.append(node) parent = PhyloNode(Name="_".join(map(str, [level,clusterid,rep])), Length=None, Children=children) nodes.append(parent) lookup[rep] = parent return lookup,nodes
def inputs_from_dict2D(dict2d_matrix): """makes inputs for UPGMA_cluster from a Dict2D object Dict2D object is a distance matrix with labeled Rows. The diagonal elements should have a very large positive number assigned (e.g.1e305). The returned array is a numpy array with the distances. PhyloNode_order is a list of PhyloNode objects with the Data property assigned from the Dict2D Row order. """ matrix_lists = list(dict2d_matrix.Rows) matrix = array(matrix_lists, Float) row_order = dict2d_matrix.RowOrder PhyloNode_order = [] for i in row_order: PhyloNode_order.append(PhyloNode(Name=i)) return matrix, PhyloNode_order
def test_make_nodes(self): """makes nodes...""" exp_99_0_10 = PhyloNode(Name="10",Length=0.005) exp_99_0_20 = PhyloNode(Name="20",Length=0.005) exp_99_0_30 = PhyloNode(Name="30",Length=0.005) exp_99_0 = PhyloNode(Name="99_0_10",Length=None, Children=\ [exp_99_0_10,exp_99_0_20,exp_99_0_30]) exp_99_1_1 = PhyloNode(Name="1",Length=0.005) exp_99_1_6 = PhyloNode(Name="6",Length=0.005) exp_99_1 = PhyloNode(Name="99_1_1",Length=None, Children=\ [exp_99_1_1,exp_99_1_6]) exp_99_2_3 = PhyloNode(Name="3", Length=0.005) exp_99_2 = PhyloNode(Name="99_2_3", Length=None, Children=[exp_99_2_3]) exp_99_3_8 = PhyloNode(Name="8", Length=0.005) exp_99_3_7 = PhyloNode(Name="7", Length=0.005) exp_99_3 = PhyloNode(Name="99_3_8", Length=None, Children=\ [exp_99_3_8,exp_99_3_7]) exp_lookup = {'10':exp_99_0,'1':exp_99_1,'3':exp_99_2,'8':exp_99_3} lookup, nodes = make_nodes(self.clst_99, 0.01, 99) self.assertEqual(nodes[0].getNewick(with_distances=True), exp_99_0.getNewick(with_distances=True)) self.assertEqual(nodes[1].getNewick(with_distances=True), exp_99_1.getNewick(with_distances=True)) self.assertEqual(nodes[2].getNewick(with_distances=True), exp_99_2.getNewick(with_distances=True)) self.assertEqual(nodes[3].getNewick(with_distances=True), exp_99_3.getNewick(with_distances=True)) self.assertEqual(len(nodes), 4) self.assertEqual(lookup.keys(), exp_lookup.keys()) self.assertEqual(map(str, lookup.values()), map(str,exp_lookup.values()))
def test_gops(self): """Basic PhyloNode operations should work as expected""" p = PhyloNode() self.assertEqual(str(p), ';') p.Name = 'abc' self.assertEqual(str(p), 'abc;') p.Length = 3 self.assertEqual(str(p), 'abc:3;') #don't suppress branch from root q = PhyloNode() p.append(q) self.assertEqual(str(p), '()abc:3;') r = PhyloNode() q.append(r) self.assertEqual(str(p), '(())abc:3;') r.Name = 'xyz' self.assertEqual(str(p), '((xyz))abc:3;') q.Length = 2 self.assertEqual(str(p), '((xyz):2)abc:3;')
def test_minimal(self): """DndParser should produce the correct minimal tree""" obs = DndParser(minimal) exp = PhyloNode() exp.append(PhyloNode()) self.assertEqual(str(obs), str(exp))
def test_make_nodes(self): """makes nodes...""" exp_99_0_10 = PhyloNode(Name="10", Length=0.005) exp_99_0_20 = PhyloNode(Name="20", Length=0.005) exp_99_0_30 = PhyloNode(Name="30", Length=0.005) exp_99_0 = PhyloNode(Name="99_0_10",Length=None, Children=\ [exp_99_0_10,exp_99_0_20,exp_99_0_30]) exp_99_1_1 = PhyloNode(Name="1", Length=0.005) exp_99_1_6 = PhyloNode(Name="6", Length=0.005) exp_99_1 = PhyloNode(Name="99_1_1",Length=None, Children=\ [exp_99_1_1,exp_99_1_6]) exp_99_2_3 = PhyloNode(Name="3", Length=0.005) exp_99_2 = PhyloNode(Name="99_2_3", Length=None, Children=[exp_99_2_3]) exp_99_3_8 = PhyloNode(Name="8", Length=0.005) exp_99_3_7 = PhyloNode(Name="7", Length=0.005) exp_99_3 = PhyloNode(Name="99_3_8", Length=None, Children=\ [exp_99_3_8,exp_99_3_7]) exp_lookup = { '10': exp_99_0, '1': exp_99_1, '3': exp_99_2, '8': exp_99_3 } lookup, nodes = make_nodes(self.clst_99, 0.01, 99) self.assertEqual(nodes[0].getNewick(with_distances=True), exp_99_0.getNewick(with_distances=True)) self.assertEqual(nodes[1].getNewick(with_distances=True), exp_99_1.getNewick(with_distances=True)) self.assertEqual(nodes[2].getNewick(with_distances=True), exp_99_2.getNewick(with_distances=True)) self.assertEqual(nodes[3].getNewick(with_distances=True), exp_99_3.getNewick(with_distances=True)) self.assertEqual(len(nodes), 4) self.assertEqual(lookup.keys(), exp_lookup.keys()) self.assertEqual(map(str, lookup.values()), map(str, exp_lookup.values()))
def test_gops(self): """Basic PhyloNode operations should work as expected""" p = PhyloNode() self.assertEqual(str(p), ";") p.Name = "abc" self.assertEqual(str(p), "abc;") p.Length = 3 self.assertEqual(str(p), "abc:3;") # don't suppress branch from root q = PhyloNode() p.append(q) self.assertEqual(str(p), "()abc:3;") r = PhyloNode() q.append(r) self.assertEqual(str(p), "(())abc:3;") r.Name = "xyz" self.assertEqual(str(p), "((xyz))abc:3;") q.Length = 2 self.assertEqual(str(p), "((xyz):2)abc:3;")