[Biopython] Phylo: rerooting a tree with a terminal node

Robert Beiko beiko at cs.dal.ca
Wed Jan 12 18:46:24 UTC 2011


Hi Eric,

Thank you very much for your quick reply.

Indeed the full script is doing something much more interesting (rolling 
up in-paralogs with attempts at alternative rootings), but this is my 
attempt to cut out all of the other things I might have done wrong :^>

The loop is crashing the first time I try it. Indeed, the following 
variation fails as well:

import io
import sys
from Bio import Phylo

infile = 'Example1.tre'
trees = Phylo.parse(infile,'newick')

for tree in trees:
     leafList = tree.get_terminals()
     tree.root_with_outgroup(leafList[0])

----

again, the same code with internals rather than terminals works fine.

Best wishes,
Rob
On 12/01/2011 2:31 PM, Eric Talevich wrote:
> On Wed, Jan 12, 2011 at 9:06 AM, Robert Beiko <beiko at cs.dal.ca 
> <mailto:beiko at cs.dal.ca>> wrote:
>
>     Hi,
>
>     I have been experimenting with the excellent Phylo package in
>     BioPython, and am having a bit of trouble with the
>     'root_with_outgroup' method.
>
>     Specifically, it seems to work fine when I apply it to internal
>     nodes, but when I try to root on a terminal, I get an error:
>
>     ---------------
>
>     Traceback (most recent call last):
>      File "C:/Projects/10000/Phylogenomics/TestTrees/test.py", line
>     16, in <module>
>        tree.root_with_outgroup(leaf)
>      File "C:\Python26\lib\site-packages\Bio\Phylo\BaseTree.py", line
>     777, in root_with_outgroup
>        parent.clades.pop(parent.clades.index(new_parent))
>     ValueError: list.index(x): x not in list
>
>     ---------------
>
>     Here is an example script:
>
>     import io
>     import sys
>     from Bio import Phylo
>
>     infile = 'Example1.tre'
>     trees = Phylo.parse(infile,'newick')
>
>     for tree in trees:
>        leafList = tree.get_terminals()
>        for leaf in leafList:
>            tree.root_with_outgroup(leaf)
>
>     ---------------
>
>     And here is the file 'Example1.tre'
>
>     ((AAA,BBB),(CCC,DDD));
>
>     [I have tried many permutations of the tree, and in no case have I
>     been able to root using a terminal].
>
>     Line 777 in 'BaseTree.py' is:
>     parent.clades.pop(parent.clades.index(new_parent))
>
>     so it appears that new_parent is not in the list 'parent.clades'.
>     My Python is rather rudimentary so I haven't been able to figure
>     out why this might arise.
>
>     If I change 'get_terminals()' to 'get_nonterminals()' in the
>     script above, everything works fine. I imagine I could get things
>     to work by introducing a dummy sister node for each terminal I
>     would like to root on, and then rooting on the LCA of the terminal
>     and its dummy sister. But is there something I am doing wrong in
>     the script above, that could easily be remedied without a hack?
>
>     Python version is 2.6, BioPython 1.56.
>
>     Best wishes and thanks,
>     Rob Beiko
>
>
>
> Hi Robert,
>
> Thanks for reporting this. It's certainly possible that there's a bug 
> here; I'll take a closer look at the code.
>
> The odd thing I notice about your code is that you're rerooting inside 
> a loop. The root_with_outgroup method operates in-place, so the "tree" 
> object is changing with each iteration. I assume your original code 
> was doing something after rerooting each time, like writing out a new 
> tree.
>
> The difference in the code between rooting with terminal versus 
> non-terminal nodes is that rooting with a terminal requires creating a 
> new internal node just above the terminal, then using the new node as 
> the new root. (Rerooting with an existing internal node just reroots 
> at that node without creating any new objects.) So if this is done 
> repeatedly, that could be the source of some trouble.
>
> Do you know if the loop is crashing in the first iteration or the second?
>
> Best regards,
> Eric




More information about the Biopython mailing list