[Bioperl-l] Question about Bio::TreeIO

Jason Stajich jason at cgt.duhs.duke.edu
Mon Dec 22 09:50:36 EST 2003


On Sun, 21 Dec 2003, iain wallace wrote:

> Hi all,
>
> I am trying to write a function that can read in a tree, go through
> each of the nodes, and tell me how many leaves are a descendent of that
> node.
> e.g the root node would be an ancestor to all the leaves.
>
> My code simply looks at all the nodes, and calls get_all_descendents(),
> and if any of the descendents is a leaf the count is incremented by
> one. However, my code below doesn't seem to work, as it says some nodes
> have no descendents which are leaves.

Well you're going to get leaf nodes in the outer get_all_Descendents
foreach loop which won't have descendents so that should be okay.

>
> Is there a flaw in my logic, or is my code simply wrong???
>
> Before I go, there is one other question i would like to ask, how can i
> pass a bioperl object (like a node) in this case to a function? I tried
> passing by reference function(\$node) but that wouldn't work for me...
>
> Any help would be great, Thanks
> Iain
>

You could do it bottom up with a little recursive function.

This code doesn't assign the counts since you you need to process the
whole tree before you'll have the final counts (although you could do it
as you, and assign the value within each node instead of using the %data
hash).  You can either update the values as you go, or post-process and
use this code:
 for my $id ( keys %data ) {
   my $node = $tree->find_node(-id => $id)
   $node->add_tag_value('count',$data{$id});
 }

This seems to work for me - the root node (id=9) has 6 leaf nodes below
it.

#!/usr/bin/perl -w
use strict;
use Bio::TreeIO;

my $in = new Bio::TreeIO(-fh     => \*DATA,
			 -format => 'newick');

my $tree = $in->next_tree;

my %data;

for my $node ( $tree->get_leaf_nodes ) {
    &inc_ancestor($node,\%data);
}

for my $id ( sort { $a <=> $b}  keys %data ) {
    print $id, " ", $data{$id}, "\n";
}

sub inc_ancestor {
    my $node = shift;
    my $data = shift;
    return unless defined $node && defined $node->ancestor;
    my $id = $node->ancestor->internal_id;
    $data->{$id}++;
    &inc_ancestor($node->ancestor,$data);
}

__DATA__
((((Bosta2,Preen),Homsa),Papan),Equca,Ratno1);



>
>
>  foreach my $node ( $rootnode->get_all_Descendents() ) {
>
>         $count=0;
>         foreach my $newnode ( $node-> get_all_Descendents()){
>                 if($newnode->is_Leaf){
>                 $count++;
>                 }
>         }
>
>         $nodeid=$node->internal_id;
>         $node->add_tag_value($count,1);
>         if ($count==0){
>         print "$nodeid has no leaves....";
>         }
>     }
>
>
>
> _______________________________________________
> Bioperl-l mailing list
> Bioperl-l at portal.open-bio.org
> http://portal.open-bio.org/mailman/listinfo/bioperl-l
>

--
Jason Stajich
Duke University
jason at cgt.mc.duke.edu


More information about the Bioperl-l mailing list