def __call__(self, T, leafRanks=None): self.__init__() # to indicate whether we are in the 2nd pass self.setLeafRanks = leafRanks T.dfs_traverse(self) lca = LCA.LCA(self.pa) return (lca, self.nodes, self.getLeafRanks)
def test_LCA(): assert LCA.LCA(LCA.testTree, 8, 9).value == 2 assert LCA.LCA(LCA.testTree, 10, 3).value == 1 assert LCA.LCA(LCA.testTree, 5, 6).value == 5 assert LCA.LCA(LCA.testTree, 1, 6).value == 1 assert LCA.LCA(LCA.testTree, 9, 6).value == 1 assert LCA.LCA(LCA.testTree, 4, 6).value == 3
def test_LCA_sameValue(self): self.assertEqual("A", LCA.LCA(LCA.graph, "A", "A")) self.assertEqual("D", LCA.LCA(LCA.graph, "D", "D"))
def test_LCA_invalidValue(self): self.assertEqual("", LCA.LCA(LCA.graph, "Z", "X"))
def test_LCA_normal(self): self.assertEqual("A", LCA.LCA(LCA.graph, "A", "B")) self.assertEqual("B", LCA.LCA(LCA.graph, "C", "D"))
def test_none_node_LCA(): test = LCA.Node(None) assert LCA.LCA(test, None, None).value == None assert LCA.LCA(test, None, 1) == -1 assert LCA.LCA(test, 1, None) == -1 assert LCA.LCA(test, 1, 1) == -1
def test_none_LCA(): assert LCA.LCA(LCA.testTree, None, 1) == -1 assert LCA.LCA(LCA.testTree, 1, None) == -1 assert LCA.LCA(LCA.testTree, None, None) == -1
def test_LCA(): assert LCA.LCA(LCA.testTree, 10, 16) == -1 assert LCA.LCA(LCA.testTree, 22, 0) == -1 assert LCA.LCA(LCA.testTree, 22, 2) == -1
def build_LCA(G, S, verbose=False): """ build the LCA mapping from given G to given S: 1. preprocess S 2. construct leaf-mapping 3. DFS through G, map G to S """ class DFS_species_preLCA(newick.tree.TreeVisitor): """ preprocess S for LCA: 1. build the child-parent dictionary for LCA 2. build the leaf-node dictionary """ def __init__(self): self.Pa = {} # child-parent relation, Pa() self.Le = {} # 'id'-leaf relation, Le('id') self.nodes = [] def pre_visit_edge(self, src, bootstrap, length, dst): self.Pa.setdefault(dst, src) def post_visit_tree(self, t): self.nodes.append(t) def visit_leaf(self, s): id = s.leaves_ids[0] if self.Le.has_key(id): raise "ERROR: Species tree has duplicated taxon: %s" % id self.Le.setdefault(s.leaves_ids[0], s) self.nodes.append(s) class DFS_gene_LCA(newick.tree.TreeVisitor): """ recursively build up the LCA mapping """ def __init__(self, Ls, LCAs): self.Ls = Ls # leaves of S, Ls['id'] = leave self.LCAs = LCAs # LCA of S self.nodes = [] def pre_visit_tree(self, t): t.M = None def post_visit_tree(self, t): self.nodes.append(t) def post_visit_edge(self, src, bo, le, trg): if not trg.M: raise "ERROR: Gene tree failed LCA mapping at: %s" % trg.leaves src.M = self.LCAs(src.M, trg.M) def visit_leaf(self, g): if hasattr(g, "interleaf"): g.M = self.LCAs(*g.interleaf) else: id = g.leaves_ids[0] if not self.Ls.has_key(id): raise "ERROR: Gene tree has orphan taxon: %s" % id g.M = self.Ls[id] self.nodes.append(g) # step 1: preprocess S dfsS = DFS_species_preLCA() S.dfs_traverse(dfsS) lcaS = LCA.LCA(dfsS.Pa) # test: #print dfsS.Pa #print dfsS.Le #print dfsS.Le['a'], dfsS.Le['b'] #print lcaS(dfsS.Le['a'], dfsS.Le['b']) # step 2: build the leaf-mapping # step 3: build the LCA-mapping dfsG = DFS_gene_LCA(dfsS.Le, lcaS) G.dfs_traverse(dfsG) # test: # a little short-cut for testing purpose if verbose: S.nodes = dfsS.nodes G.nodes = dfsG.nodes