Bio::Tree
TreeFunctionsI
Summary
Bio::Tree::TreeFunctionsI - Decorated Interface implementing basic Tree exploration methods
Package variables
No package variables defined.
Included modules
Inherit
Synopsis
use Bio::TreeIO;
my $in = new Bio::TreeIO(-format => 'newick', -file => 'tree.tre');
my $tree = $in->next_tree;
my @nodes = $tree->find_nodes('id1');
if( $tree->is_monophyletic(-clade => @nodes, -outgroup => $outnode) ){
}
Description
Describe the interface here
Methods
Methods description
Title : find_node
Usage : my @nodes = $self->find_node(-id => 'node1');
Function: returns all nodes that match a specific field, by default this
is id, but different branch_length,
Returns : List of nodes which matched search
Args : text string to search for
OR
-fieldname => $textstring |
Title : get_lca
Usage : get_lca(-nodes => \@nodes )
Function: given two nodes, returns the lowest common ancestor
Returns : node object
Args : -nodes => arrayref of nodes to test |
Title : distance
Usage : distance(-nodes => \@nodes )
Function: returns the distance between two given nodes
Returns : numerical distance
Args : -nodes => arrayref of nodes to test |
Title : is_monophyletic
Usage : if( $tree->is_monophyletic(-nodes => \@nodes,
-outgroup => $outgroup)
Function: Will do a test of monophyly for the nodes specified
in comparison to a chosen outgroup
Returns : boolean
Args : -nodes => arrayref of nodes to test
-outgroup => outgroup to serve as a reference |
Title : is_paraphyletic
Usage : if( $tree->is_paraphyletic(-nodes =>\@nodes,
-outgroup => $node) ){ }
Function: Tests whether or not a given set of nodes are paraphyletic
(representing the full clade) given an outgroup
Returns : [-1,0,1] , -1 if the group is not monophyletic
0 if the group is not paraphyletic
1 if the group is paraphyletic
Args : -nodes => Array of Bio::Tree::NodeI objects which are in the tree
-outgroup => a Bio::Tree::NodeI to compare the nodes to |
Methods code
sub find_node
{ my ($self,$type,$field) = @_;
if( ! defined $type ) {
$self->warn("Must request a either a string or field and string when searching");
}
if( ! defined $field ) {
$field= $type;
$type = 'id';
} else {
$type =~ s/^-//;
}
unless( $type eq 'id' || $type eq 'name' ||
$type eq 'bootstrap' || $type eq 'description' ||
$type eq 'internal_id') {
$self->warn("unknown search type $type - will try anyways");
}
my @nodes = grep { $_->can($type) && defined $_->$type() &&
$_->$type() eq $field } $self->get_nodes();
if ( wantarray) {
return @nodes;
} else {
if( @nodes > 1 ) {
$self->warn("More than 1 node found but caller requested scalar, only returning first node");
}
return shift @nodes;
}} |
sub get_lca
{ my ($self,@args) = @_;
my ($nodes) = $self->_rearrange([qw(NODES)],@args);
if( ! defined $nodes ) {
$self->warn("Must supply -nodes parameter to get_lca() method");
return undef;
}
my ($node1,$node2) = $self->_check_two_nodes($nodes);
return undef unless $node1 && $node2;
my %node1_ancestors; my $place = $node1;
while ( $place ){
$node1_ancestors{$place->internal_id} = $place;
$place = $place->ancestor;
}
$place = $node2; while ( $place ){
foreach my $key ( keys %node1_ancestors ){ if ( $place->internal_id == $key){
return $node1_ancestors{$key};
}
}
$place = $place->ancestor;
}
$self->warn("Could not find lca!"); return undef;} |
sub distance
{ my ($self,@args) = @_;
my ($nodes) = $self->_rearrange([qw(NODES)],@args);
if( ! defined $nodes ) {
$self->warn("Must supply -nodes parameter to distance() method");
return undef;
}
my ($node1,$node2) = $self->_check_two_nodes($nodes);
my %node1_ancestors; my %node1_cumul_dist; my $place = $node1; my $cumul_dist = 0;
while ( $place ){
$node1_ancestors{$place->internal_id} = $place;
$node1_cumul_dist{$place->internal_id} = $cumul_dist;
if ($place->branch_length) {
$cumul_dist += $place->branch_length; }
$place = $place->ancestor;
}
$place = $node2; $cumul_dist = 0;
while ( $place ){
foreach my $key ( keys %node1_ancestors ){ if ( $place->internal_id == $key){ return $node1_cumul_dist{$key} + $cumul_dist;
}
}
$cumul_dist += $place->branch_length;
$place = $place->ancestor;
}
$self->warn("Could not find distance!"); return undef;} |
sub _check_two_nodes
{ my ($self, $nodes) = @_;
if( ref($nodes) !~ /ARRAY/i ||
!ref($nodes->[0]) ||
!ref($nodes->[1])
) {
$self->warn("Must provide a valid array reference for -nodes");
return undef;
} elsif( scalar(@$nodes) > 2 ){
$self->warn("More than two nodes given, using first two");
} elsif( scalar(@$nodes) < 2 ){
$self->warn("-nodes parameter does not contain reference to two nodes");
return undef;
}
unless( $nodes->[0]->isa('Bio::Tree::NodeI') &&
$nodes->[1]->isa('Bio::Tree::NodeI') ) {
$self->warn("Did not provide valid Bio::Tree::NodeI objects as nodes\n");
return undef;
}
return @$nodes;} |
sub is_monophyletic
{ my ($self,@args) = @_;
my ($nodes,$outgroup) = $self->_rearrange([qw(NODES OUTGROUP)],@args);
if( ! defined $nodes || ! defined $outgroup ) {
$self->warn("Must supply -nodes and -outgroup parameters to the method
is_monophyletic");
return undef;
}
if( ref($nodes) !~ /ARRAY/i ) {
$self->warn("Must provide a valid array reference for -nodes");
}
my $clade_root;
while( @$nodes > 2 ) {
my ($a,$b) = ( shift @$nodes, shift @$nodes);
$clade_root = $self->get_lca(-nodes => [$a,$b] );
unshift @$nodes, $clade_root;
}
$clade_root = $self->get_lca(-nodes => $nodes );
my $og_ancestor = $outgroup->ancestor;
while( defined ($og_ancestor ) ) {
if( $og_ancestor->internal_id == $clade_root->internal_id ) {
return 0;
}
$og_ancestor = $og_ancestor->ancestor;
}
return 1;} |
sub is_paraphyletic
{ my ($self,@args) = @_;
my ($nodes,$outgroup) = $self->_rearrange([qw(NODES OUTGROUP)],@args);
if( ! defined $nodes || ! defined $outgroup ) {
$self->warn("Must suply -nodes and -outgroup parameters to the method is_paraphyletic");
return undef;
}
if( ref($nodes) !~ /ARRAY/i ) {
$self->warn("Must provide a valid array reference for -nodes");
}
my %nodehash;
foreach my $n ( @$nodes ) {
$nodehash{$n->internal_id} = $n;
}
while( @$nodes > 2 ) {
unshift @$nodes, $self->get_lca(-nodes => [( shift @$nodes,
shift @$nodes)] );
}
my $clade_root = $self->get_lca(-nodes => $nodes );
my $og_ancestor = $outgroup->ancestor;
while( defined ($og_ancestor ) ) {
if( $og_ancestor->internal_id == $clade_root->internal_id ) {
return -1;
}
$og_ancestor = $og_ancestor->ancestor;
}
my $tree = new Bio::Tree::Tree(-root => $clade_root);
foreach my $n ( $tree->get_nodes() ) {
next unless $n->is_Leaf();
return 1 unless ( $nodehash{$n->internal_id} );
}
return 0;} |
General documentation
User feedback is an integral part of the evolution of this and other
Bioperl modules. Send your comments and suggestions preferably to
the Bioperl mailing list. Your participation is much appreciated.
bioperl-l@bioperl.org - General discussion
http://bioperl.org/MailList.shtml - About the mailing lists
Report bugs to the Bioperl bug tracking system to help us keep track
of the bugs and their resolution. Bug reports can be submitted via
email or the web:
bioperl-bugs@bioperl.org
http://bugzilla.bioperl.org/
| AUTHOR - Jason Stajich, Aaron Mackey, Justin Reese | Top |
Additional contributors names and emails here
The rest of the documentation details each of the object methods.
Internal methods are usually preceded with a _