ete2.phylo.reconciliation

Package ete2 :: Package phylo :: Module reconciliation |
[hide private]
[frames] | no frames]

# Source Code for Module ete2.phylo.reconciliation

      1  __VERSION__="ete2-2.0rev95"
      2  # #START_LICENSE###########################################################
      3  #
      4  # Copyright (C) 2009 by Jaime Huerta Cepas. All rights reserved.
      5  # email: jhcepas@gmail.com
      6  #
      7  # This file is part of the Environment for Tree Exploration program (ETE).
      8  # http://ete.cgenomics.org
      9  #
     10  # ETE is free software: you can redistribute it and/or modify it
     11  # under the terms of the GNU General Public License as published by
     12  # the Free Software Foundation, either version 3 of the License, or
     13  # (at your option) any later version.
     14  #
     15  # ETE is distributed in the hope that it will be useful,
     16  # but WITHOUT ANY WARRANTY; without even the implied warranty of
     17  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     18  # GNU General Public License for more details.
     19  #
     20  # You should have received a copy of the GNU General Public License
     21  # along with ETE.  If not, see <http://www.gnu.org/licenses/>.
     22  #
     23  # #END_LICENSE#############################################################
     24
     25  import copy
     26  from evolevents import EvolEvent
     27
     28 -def get_reconciled_tree(node, sptree, events):
     29      """ Returns the recoliation gene tree with a provided species
     30      topology """
     31
     32      if len(node.children)==2:
     33          # First visit childs
     34          morphed_childs =[]
     35          for ch in node.children:
     36              mc, ev = get_reconciled_tree(ch, sptree, events)
     37              morphed_childs.append(mc)
     38
     39          # morphed childs are the the reconcialiated childs. We trust
     40          # its topology. Remember tree is visited on recursive
     41          # post-order
     42          sp_child_0 = morphed_childs[0].get_species()
     43          sp_child_1 = morphed_childs[1].get_species()
     44          all_species =  sp_child_1 | sp_child_0
     45
     46          # If childs represents a duplication (duplicated species)
     47          # Check that both are reconciliated to the same species
     48          if len(sp_child_0 & sp_child_1)>0:
     49              newnode = copy.deepcopy(node)
     50              newnode.up = None
     51              newnode.children = []
     52              template = _get_expected_topology(sptree, all_species)
     53              # replaces child0 partition on the template
     54              newmorphed0, matchnode = _replace_on_template(template, morphed_childs[0])
     55              # replaces child1 partition on the template
     56              newmorphed1, matchnode = _replace_on_template(template, morphed_childs[1])
     57              newnode.add_child(newmorphed0)
     58              newnode.add_child(newmorphed1)
     59              newnode.add_feature("evoltype","D")
     60              node.add_feature("evoltype","D")
     61              e = EvolEvent()
     62              e.etype = "D"
     63              e.inparalogs = node.children[0].get_leaf_names()
     64              e.outparalogs = node.children[1].get_leaf_names()
     65              e.in_seqs  = node.children[0].get_leaf_names()
     66              e.out_seqs = node.children[1].get_leaf_names()
     67              events.append(e)
     68              return newnode, events
     69
     70          # Otherwise, we need to reconciliate species at both sides
     71          # into a single partition.
     72          else:
     73              # gets the topology expected by the observed species
     74              template = _get_expected_topology(sptree, all_species)
     75              # replaces child0 partition on the template
     76              template, matchnode = _replace_on_template(template, morphed_childs[0] )
     77              # replaces child1 partition on the template
     78              template, matchnode = _replace_on_template(template, morphed_childs[1])
     79              template.add_feature("evoltype","S")
     80              node.add_feature("evoltype","S")
     81              e = EvolEvent()
     82              e.etype = "S"
     83              e.inparalogs = node.children[0].get_leaf_names()
     84              e.orthologs = node.children[1].get_leaf_names()
     85              e.in_seqs  = node.children[0].get_leaf_names()
     86              e.out_seqs = node.children[1].get_leaf_names()
     87              events.append(e)
     88              return template, events
     89      elif len(node.children)==0:
     90          return copy.deepcopy(node), events
     91      else:
     92          raise ValueError, "Algorithm can only work with binary trees."
     93
     94 -def _replace_on_template(orig_template, node):
     95      template = copy.deepcopy(orig_template)
     96      # detects partition within topo that matchs child1 species
     97      nodespcs = node.get_species()
     98      spseed = list(nodespcs)[0]  # any sp name woulbe ok
     99      # Set an start point
    100      subtopo = template.search_nodes(children=[], name=spseed)[0]
    101      # While subtopo does not cover all child species
    102      while len(nodespcs - set(subtopo.get_leaf_names() ) )>0:
    103          subtopo= subtopo.up
    104      # Puts original partition on the expected topology template
    105      nodecp = copy.deepcopy(node)
    106      if subtopo.up is None:
    107          return nodecp, nodecp
    108      else:
    109          parent = subtopo.up
    110          parent.remove_child(subtopo)
    111          parent.add_child(nodecp)
    112          return template, nodecp
    113
    114 -def _get_expected_topology(t, species):
    115      missing_sp = set(species) - set(t.get_leaf_names())
    116      if missing_sp:
    117          raise KeyError, \
    118              "Follwing species are not contained in species the tree: "+ ','.join(missing_sp)
    119      node = t.search_nodes(children=[], name=list(species)[0])[0]
    120
    121      sps = set(species)
    122      while sps-set(node.get_leaf_names()) != set([]):
    123          node = node.up
    124      template = copy.deepcopy(node)
    125      # make get_species() to work
    126      template._speciesFunction = _get_species_on_TOL
    127      template.detach()
    128      for n in [template]+template.get_descendants():
    129          n.add_feature("evoltype","L")
    130          n.dist = 1
    131      return template
    132
    133 -def _get_species_on_TOL(name):
    134      return name
    135