[Biopython] Phylo: rerooting a tree with a terminal node
Robert Beiko
beiko at cs.dal.ca
Wed Jan 12 13:46:24 EST 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