def next_proposal(self): self.locus_search.propose() # TODO: propose other reconciliations beside LCA locus_tree = self.locus_search.get_tree().copy() phylo.recon_root(locus_tree, self.reconer.stree, self.reconer.gene2species, newCopy=False) locus_recon = phylo.reconcile(locus_tree, self.reconer.stree, self.reconer.gene2species) locus_events = phylo.label_events(locus_tree, locus_recon) # propose daughters (TODO) daughters = set() # propose coal recon (TODO: propose others beside LCA) coal_recon = phylo.reconcile(self.reconer.coal_tree, locus_tree, lambda x: x) recon = {"coal_recon": coal_recon, "locus_tree": locus_tree, "locus_recon": locus_recon, "locus_events": locus_events, "daughters": daughters} return recon
def next_proposal(self): if len(self._locus_search.get_tree().leaves()) <= 2: return self._recon # if locus_tree has not yet been accepted, then revert it if not self._accept_locus: self._locus_search.revert() # propose new locus_tree self._locus_search.propose() self._accept_locus = False locus_tree = self._locus_search.get_tree().copy() # TODO: make recon root optional phylo.recon_root(locus_tree, self._stree, self._gene2species, newCopy=False) common.rename_nodes(locus_tree) # propose remaining parts of dlcoal recon self._recon = self._recon_lca(locus_tree) return self._recon
def recon_root(self, gtree, newCopy=True, returnCost=False): """Reroots the tree by minimizing the duplication/loss cost""" return phylo.recon_root( gtree, self.stree, self.gene2species, newCopy=newCopy, keepName=True, returnCost=returnCost, dupcost=self.dupcost, losscost=self.losscost, )
def next_proposal(self): # if leaves <= 2, no need to propose another tree if len(self._coal_search.get_tree().leaves()) <= 2: return self._recon # always tree now because _num_coal_recon is set 0 if self._i_coal_recons >= self._num_coal_recons: # propose new locus_tree # if locus_tree has not yet been accepted, then revert it if not self._accept_coal: self._coal_search.revert() # propose a new coal tree using _coal_search self._coal_search.propose() self._accept_coal = False self._i_coal_recons = 1 # set coal_tree to be the proposed one coal_tree = self._coal_search.get_tree().copy() # make recon root optimal phylo.recon_root(coal_tree, self._locus_tree, newCopy=False) dlcoal.rename_nodes(coal_tree) # propose remaining parts of dlcoal recon # reconciliation is given by lca self._recon = self._recon_lca(coal_tree) else: # modify coal_recon try: self._i_coal_recons += 1 self._coal_recon_enum.next() except StopIteration: self._i_coal_recon = self._num_coal_recons return self.next_proposal() return self._recon
def recon_root(self, gtree, newCopy=True, returnCost=False): """ Reroots the tree by minimizing the duplication/loss cost Note, may NOT minimize the cost function """ if self.simplereroot: tree = phylo.recon_root(gtree, self.stree, self.gene2species, newCopy = newCopy, keepName = True, returnCost = False) if returnCost: return tree, self.compute_cost(tree) else: return tree else: return CostModel.recon_root(self, gtree, newCopy, returnCost)
def next_proposal(self): if len(self._locus_search.get_tree().leaves()) <= 2: return self._recon if self._i_coal_recons >= self._num_coal_recons: # propose new locus_tree # if locus_tree has not yet been accepted, then revert it if not self._accept_locus: self._locus_search.revert() self._locus_search.propose() self._accept_locus = False self._i_coal_recons = 0 locus_tree = self._locus_search.get_tree().copy() # TODO: make recon root optional phylo.recon_root(locus_tree, self._stree, self._gene2species, newCopy=False) dlcoal.rename_nodes(locus_tree) # propose remaining parts of dlcoal recon self._recon = self._recon_lca(locus_tree) else: # modify coal_recon try: self._i_coal_recons += 1 self._coal_recon_enum.next() except StopIteration: self._i_coal_recon = self._num_coal_recons return self.next_proposal() return self._recon
def dlcoal_recon_old(tree, stree, gene2species, n, duprate, lossrate, pretime=None, premean=None, nsearch=1000, maxdoom=20, nsamples=100, search=phylo.TreeSearchNni): """ Perform reconciliation using the DLCoal model Returns (maxp, maxrecon) where 'maxp' is the probability of the MAP reconciliation 'maxrecon' which further defined as maxrecon = {'coal_recon': coal_recon, 'locus_tree': locus_tree, 'locus_recon': locus_recon, 'locus_events': locus_events, 'daughters': daughters} """ # init coal tree coal_tree = tree # init locus tree as congruent to coal tree # equivalent to assuming no ILS locus_tree = coal_tree.copy() maxp = - util.INF maxrecon = None # init search locus_search = search(locus_tree) for i in xrange(nsearch): # TODO: propose other reconciliations beside LCA locus_tree2 = locus_tree.copy() phylo.recon_root(locus_tree2, stree, gene2species, newCopy=False) locus_recon = phylo.reconcile(locus_tree2, stree, gene2species) locus_events = phylo.label_events(locus_tree2, locus_recon) # propose daughters (TODO) daughters = set() # propose coal recon (TODO: propose others beside LCA) coal_recon = phylo.reconcile(coal_tree, locus_tree2, lambda x: x) # compute recon probability phylo.add_implied_spec_nodes(locus_tree2, stree, locus_recon, locus_events) p = prob_dlcoal_recon_topology(coal_tree, coal_recon, locus_tree2, locus_recon, locus_events, daughters, stree, n, duprate, lossrate, pretime, premean, maxdoom=maxdoom, nsamples=nsamples, add_spec=False) treelib.remove_single_children(locus_tree2) if p > maxp: maxp = p maxrecon = {"coal_recon": coal_recon, "locus_tree": locus_tree2, "locus_recon": locus_recon, "locus_events": locus_events, "daughters": daughters} locus_tree = locus_tree2.copy() locus_search.set_tree(locus_tree) else: locus_search.revert() # perform local rearrangement to locus tree locus_search.propose() return maxp, maxrecon
def compute_cost(self, gtree): """Returns the duplication-loss-coalescence cost""" # start with locus tree equal to gene tree ltree = self.locustree treelib.set_tree_topology(ltree, gtree) # initialize search self.search.set_tree(ltree) treehash = phylo.hash_tree(ltree) uniques = set([treehash]) # initalize optimal locus tree and DLC cost ntrees = 0 minltree = ltree mincost = self._compute_cost_helper(gtree, ltree) # random values random.seed(self.seed) randvec = nprnd.random(self.niter) if NUMPY: nprnd.seed(self.seed) randvec = [random.random() for _ in xrange(self.niter)] # search locus trees for i in xrange(self.niter): # propose locus tree ltree = self.search.propose() treehash = phylo.hash_tree(ltree) if treehash in uniques and ntrees >= 0.1*i: self.search.revert() continue if phylo.robinson_foulds_error(gtree, ltree) > self.rf: self.search.revert() continue # save tree if treehash not in uniques: uniques.add(treehash) ntrees += 1 # reconroot (some percentage of the time depending on freconroot) if randvec[i] < self.freconroot: ltree, dlcost = phylo.recon_root(ltree, self.stree, self.gene2species, newCopy=True, keepName=True, returnCost=True, dupcost=self.dupcost, losscost=self.losscost) coalcost = self._compute_coalcost(gtree, ltree) cost = dlcost + coalcost else: cost = self._compute_cost_helper(gtree, ltree) # update min cost and decide how to continue proposals from here if cost < mincost: minltree = ltree if randvec[i] < self.freconroot else ltree.copy() mincost = cost else: self.search.revert() # set optimal locus tree self.locustree = minltree self.locustree.write(self.output) return mincost