Bio-MUST-Core
view release on metacpan or search on metacpan
lib/Bio/MUST/Core/Tree.pm view on Meta::CPAN
# NODE-LABEL EDITING METHODS
sub shorten_ids { ## no critic (RequireArgUnpacking)
return shift->_change_ids_(1, @_);
}
sub restore_ids { ## no critic (RequireArgUnpacking)
return shift->_change_ids_(0, @_);
}
sub _change_ids_ {
my $self = shift;
my $abbr = shift;
my $id_mapper = shift;
# update only terminal nodes
for my $tip ( @{ $self->tree->get_terminals } ) {
my $seq_id = SeqId->new( full_id => $tip->get_name );
my $new_id = $abbr ? $id_mapper->abbr_id_for( $seq_id->full_id )
: $id_mapper->long_id_for( $seq_id->full_id );
$tip->set_name($new_id) if $new_id;
} # Note: leave id alone if not found
return;
}
sub switch_attributes_and_labels_for_terminals { ## no critic (RequireArgUnpacking)
return shift->_switch_attributes_and_labels_(0, @_);
}
sub switch_attributes_and_labels_for_internals { ## no critic (RequireArgUnpacking)
return shift->_switch_attributes_and_labels_(1, @_);
}
sub switch_attributes_and_labels_for_entities { ## no critic (RequireArgUnpacking)
return shift->_switch_attributes_and_labels_(2, @_);
}
sub _switch_attributes_and_labels_ {
my $self = shift;
my $mode = shift;
my $key = shift;
# TODO: investigate options of Bio::Phylo::Unparsers::Newick
# update either terminal or internal nodes
my $tree = $self->tree;
my @nodes = @{
$mode == 2 ? $tree->get_entities :
$mode == 1 ? $tree->get_internals :
$tree->get_terminals
};
# Note: old labels are backuped in specified attributes and vice-versa
# TODO: allow appending acc for terminal nodes?
for my $node (@nodes) {
my $label = $node->get_name;
my $attribute = $node->get_generic($key);
$node->set_generic($key => $label);
$node->set_name($attribute);
}
return;
}
sub switch_branch_lengths_and_labels_for_entities {
my $self = shift;
my $length = shift;
# use branch lengths as labels
my $tree = $self->tree;
for my $node ( @{ $tree->get_internals } ) {
$node->set_name($node->get_branch_length);
}
# delete branch lengths
for my $node ( @{ $tree->get_entities } ) {
$node->set_branch_length($length); # default is undef
}
return;
}
sub collapse_subtrees {
my $self = shift;
my $key = shift // 'taxon_collapse';
# compute maximal path length (from root)
my $tree_max_path = $self->tree->get_root->calc_max_path_to_tips;
# "balanced"-order tree traversal
my $collapsed; # will be defined when within a collapsed subtree
$self->tree->visit_depth_first(
# collapse subtrees with identical attributes
-pre_daughter => sub {
my $node = shift;
return if $node->is_terminal;
# reset collapsing for robustness
$node->set_generic('!collapse' => undef);
# do not further collapse children of a collapsed subtree
# to facilitate interactive uncollapsing (e.g., in FigTree)
return if $collapsed;
# collect children attributes
my @attrs;
for (my $i = 0; my $child = $node->get_child($i); $i++) {
push @attrs, $child->get_generic($key);
}
lib/Bio/MUST/Core/Tree.pm view on Meta::CPAN
my $alifile = $args->{alifile};
# optionally link to Ali (without path)
if ($alifile) {
my ($basename, $dir, $ext) = fileparse($alifile, qr{\.[^.]*}xms);
$self->insert_comment("$basename$ext");
}
# output ARB tree file
open my $out, '>', $outfile;
print {$out} $self->header;
say {$out} $self->newick_str( -nodelabels => 0 );
close $out;
return;
}
sub store_grp {
my $self = shift;
my $outfile = shift;
# extract tip ids, non-root nodes and support values
my @tip_ids = map { $_->foreign_id } $self->all_seq_ids;
my @nodes = grep { not $_->is_root } @{ $self->tree->get_internals };
my @bp_vals = map { $_->get_name } @nodes;
# determine support value type (BP or PP)
my $pp = List::AllUtils::all { $_ >= 0.0 && $_ <= 1.0 } @bp_vals;
open my $out, '>', $outfile;
for my $node (@nodes) {
# build bipartition string
my %in_bip = map {
SeqId->new( full_id => $_->get_name )->foreign_id => 1
} @{ $node->get_terminals };
my $bip = join q{}, map { $in_bip{$_} ? '*' : '.' } @tip_ids;
# fetch (and possibly fix) support value for bipartition
my $support = shift @bp_vals;
$support = int( $support * 100.0 ) if $pp;
# write bipartition line
say {$out} "$bip $support";
}
close $out;
return;
}
sub store_tpl {
my $self = shift;
my $outfile = shift;
# backup and discard branch lengths
# Note: I have to do that since I cannot clone the tree (Bio::Phylo bug?)
my @branch_lengths;
for my $node ( @{ $self->tree->get_entities } ) {
push @branch_lengths, $node->get_branch_length;
$node->set_branch_length(undef);
}
open my $out, '>', $outfile;
# output topology
say {$out} '1'; # TODO: improve this for multiple topologies
say {$out} $self->newick_str( -nodelabels => 0 );
# restore branch lengths
for my $node ( @{ $self->tree->get_entities } ) {
$node->set_branch_length( shift @branch_lengths );
}
close $out;
return;
}
__PACKAGE__->meta->make_immutable;
1;
__END__
=pod
=head1 NAME
Bio::MUST::Core::Tree - Thin wrapper around Bio::Phylo trees
=head1 VERSION
version 0.252040
=head1 SYNOPSIS
# TODO
=head1 DESCRIPTION
# TODO
=head1 METHODS
=head2 newick_str
=head2 all_seq_ids
=head2 shorten_ids
=head2 restore_ids
=head2 switch_attributes_and_labels_for_terminals
=head2 switch_attributes_and_labels_for_internals
( run in 1.336 second using v1.01-cache-2.11-cpan-39bf76dae61 )