| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package Bio::Phylo::Forest::Tree; | 
| 2 | 30 |  |  | 30 |  | 128097 | use strict; | 
|  | 30 |  |  |  |  | 115 |  | 
|  | 30 |  |  |  |  | 875 |  | 
| 3 | 30 |  |  | 30 |  | 144 | use warnings; | 
|  | 30 |  |  |  |  | 55 |  | 
|  | 30 |  |  |  |  | 793 |  | 
| 4 | 30 |  |  | 30 |  | 8835 | use Bio::Phylo::Forest::DrawTreeRole; | 
|  | 30 |  |  |  |  | 91 |  | 
|  | 30 |  |  |  |  | 274 |  | 
| 5 | 30 |  |  | 30 |  | 174 | use base qw'Bio::Phylo::Forest::DrawTreeRole'; | 
|  | 30 |  |  |  |  | 63 |  | 
|  | 30 |  |  |  |  | 9179 |  | 
| 6 |  |  |  |  |  |  | { | 
| 7 |  |  |  |  |  |  | my @fields = \( my ( %default, %rooted ) ); | 
| 8 |  |  |  |  |  |  |  | 
| 9 |  |  |  |  |  |  | =head1 NAME | 
| 10 |  |  |  |  |  |  |  | 
| 11 |  |  |  |  |  |  | Bio::Phylo::Forest::Tree - Phylogenetic tree | 
| 12 |  |  |  |  |  |  |  | 
| 13 |  |  |  |  |  |  | =head1 SYNOPSIS | 
| 14 |  |  |  |  |  |  |  | 
| 15 |  |  |  |  |  |  | # some way to get a tree | 
| 16 |  |  |  |  |  |  | use Bio::Phylo::IO; | 
| 17 |  |  |  |  |  |  | my $string = '((A,B),C);'; | 
| 18 |  |  |  |  |  |  | my $forest = Bio::Phylo::IO->parse( | 
| 19 |  |  |  |  |  |  | -format => 'newick', | 
| 20 |  |  |  |  |  |  | -string => $string | 
| 21 |  |  |  |  |  |  | ); | 
| 22 |  |  |  |  |  |  | my $tree = $forest->first; | 
| 23 |  |  |  |  |  |  |  | 
| 24 |  |  |  |  |  |  | # do something: | 
| 25 |  |  |  |  |  |  | print $tree->calc_imbalance; | 
| 26 |  |  |  |  |  |  |  | 
| 27 |  |  |  |  |  |  | # prints "1" | 
| 28 |  |  |  |  |  |  |  | 
| 29 |  |  |  |  |  |  | =head1 DESCRIPTION | 
| 30 |  |  |  |  |  |  |  | 
| 31 |  |  |  |  |  |  | The package has the getters and setters that alter the | 
| 32 |  |  |  |  |  |  | internal state of a tree object. Additional tree-related | 
| 33 |  |  |  |  |  |  | behaviours (which are available also) are defined in the | 
| 34 |  |  |  |  |  |  | package L<Bio::Phylo::Forest::TreeRole>. | 
| 35 |  |  |  |  |  |  |  | 
| 36 |  |  |  |  |  |  | =head1 METHODS | 
| 37 |  |  |  |  |  |  |  | 
| 38 |  |  |  |  |  |  | =head2 MUTATORS | 
| 39 |  |  |  |  |  |  |  | 
| 40 |  |  |  |  |  |  | =over | 
| 41 |  |  |  |  |  |  |  | 
| 42 |  |  |  |  |  |  | =item set_as_unrooted() | 
| 43 |  |  |  |  |  |  |  | 
| 44 |  |  |  |  |  |  | Sets tree to be interpreted as unrooted. | 
| 45 |  |  |  |  |  |  |  | 
| 46 |  |  |  |  |  |  | Type    : Mutator | 
| 47 |  |  |  |  |  |  | Title   : set_as_unrooted | 
| 48 |  |  |  |  |  |  | Usage   : $tree->set_as_unrooted; | 
| 49 |  |  |  |  |  |  | Function: Sets tree to be interpreted as unrooted. | 
| 50 |  |  |  |  |  |  | Returns : $tree | 
| 51 |  |  |  |  |  |  | Args    : NONE | 
| 52 |  |  |  |  |  |  | Comments: This is a flag to indicate that the invocant | 
| 53 |  |  |  |  |  |  | is interpreted to be unrooted (regardless of | 
| 54 |  |  |  |  |  |  | topology). The object is otherwise unaltered, | 
| 55 |  |  |  |  |  |  | this method is only here to capture things such | 
| 56 |  |  |  |  |  |  | as the [&U] token in nexus files. | 
| 57 |  |  |  |  |  |  |  | 
| 58 |  |  |  |  |  |  | =cut | 
| 59 |  |  |  |  |  |  |  | 
| 60 |  |  |  |  |  |  | sub set_as_unrooted { | 
| 61 | 2 |  |  | 2 | 1 | 7 | my $self = shift; | 
| 62 | 2 |  |  |  |  | 10 | $rooted{ $self->get_id } = 1; | 
| 63 | 2 |  |  |  |  | 6 | return $self; | 
| 64 |  |  |  |  |  |  | } | 
| 65 |  |  |  |  |  |  |  | 
| 66 |  |  |  |  |  |  | =item set_as_default() | 
| 67 |  |  |  |  |  |  |  | 
| 68 |  |  |  |  |  |  | Sets tree to be the default tree in a forest | 
| 69 |  |  |  |  |  |  |  | 
| 70 |  |  |  |  |  |  | Type    : Mutator | 
| 71 |  |  |  |  |  |  | Title   : set_as_default | 
| 72 |  |  |  |  |  |  | Usage   : $tree->set_as_default; | 
| 73 |  |  |  |  |  |  | Function: Sets tree to be default tree in forest | 
| 74 |  |  |  |  |  |  | Returns : $tree | 
| 75 |  |  |  |  |  |  | Args    : NONE | 
| 76 |  |  |  |  |  |  | Comments: This is a flag to indicate that the invocant | 
| 77 |  |  |  |  |  |  | is the default tree in a forest, i.e. to | 
| 78 |  |  |  |  |  |  | capture the '*' token in nexus files. | 
| 79 |  |  |  |  |  |  |  | 
| 80 |  |  |  |  |  |  | =cut | 
| 81 |  |  |  |  |  |  |  | 
| 82 |  |  |  |  |  |  | sub set_as_default { | 
| 83 | 1 |  |  | 1 | 1 | 5 | my $self = shift; | 
| 84 | 1 | 50 |  |  |  | 7 | if ( my $forest = $self->_get_container ) { | 
| 85 | 0 | 0 |  |  |  | 0 | if ( my $tree = $forest->get_default_tree ) { | 
| 86 | 0 |  |  |  |  | 0 | $tree->set_not_default; | 
| 87 |  |  |  |  |  |  | } | 
| 88 |  |  |  |  |  |  | } | 
| 89 | 1 |  |  |  |  | 3 | $default{ $self->get_id } = 1; | 
| 90 | 1 |  |  |  |  | 2 | return $self; | 
| 91 |  |  |  |  |  |  | } | 
| 92 |  |  |  |  |  |  |  | 
| 93 |  |  |  |  |  |  | =item set_not_default() | 
| 94 |  |  |  |  |  |  |  | 
| 95 |  |  |  |  |  |  | Sets tree to NOT be the default tree in a forest | 
| 96 |  |  |  |  |  |  |  | 
| 97 |  |  |  |  |  |  | Type    : Mutator | 
| 98 |  |  |  |  |  |  | Title   : set_not_default | 
| 99 |  |  |  |  |  |  | Usage   : $tree->set_not_default; | 
| 100 |  |  |  |  |  |  | Function: Sets tree to not be default tree in forest | 
| 101 |  |  |  |  |  |  | Returns : $tree | 
| 102 |  |  |  |  |  |  | Args    : NONE | 
| 103 |  |  |  |  |  |  | Comments: This is a flag to indicate that the invocant | 
| 104 |  |  |  |  |  |  | is the default tree in a forest, i.e. to | 
| 105 |  |  |  |  |  |  | capture the '*' token in nexus files. | 
| 106 |  |  |  |  |  |  |  | 
| 107 |  |  |  |  |  |  | =cut | 
| 108 |  |  |  |  |  |  |  | 
| 109 |  |  |  |  |  |  | sub set_not_default { | 
| 110 | 0 |  |  | 0 | 1 | 0 | my $self = shift; | 
| 111 | 0 |  |  |  |  | 0 | $default{ $self->get_id } = 0; | 
| 112 | 0 |  |  |  |  | 0 | return $self; | 
| 113 |  |  |  |  |  |  | } | 
| 114 |  |  |  |  |  |  |  | 
| 115 |  |  |  |  |  |  | =back | 
| 116 |  |  |  |  |  |  |  | 
| 117 |  |  |  |  |  |  | =head2 TESTS | 
| 118 |  |  |  |  |  |  |  | 
| 119 |  |  |  |  |  |  | =over | 
| 120 |  |  |  |  |  |  |  | 
| 121 |  |  |  |  |  |  | =item is_default() | 
| 122 |  |  |  |  |  |  |  | 
| 123 |  |  |  |  |  |  | Test if tree is default tree. | 
| 124 |  |  |  |  |  |  |  | 
| 125 |  |  |  |  |  |  | Type    : Test | 
| 126 |  |  |  |  |  |  | Title   : is_default | 
| 127 |  |  |  |  |  |  | Usage   : if ( $tree->is_default ) { | 
| 128 |  |  |  |  |  |  | # do something | 
| 129 |  |  |  |  |  |  | } | 
| 130 |  |  |  |  |  |  | Function: Tests whether the invocant | 
| 131 |  |  |  |  |  |  | object is the default tree in the forest. | 
| 132 |  |  |  |  |  |  | Returns : BOOLEAN | 
| 133 |  |  |  |  |  |  | Args    : NONE | 
| 134 |  |  |  |  |  |  |  | 
| 135 |  |  |  |  |  |  | =cut | 
| 136 |  |  |  |  |  |  |  | 
| 137 |  |  |  |  |  |  | sub is_default { | 
| 138 | 152 |  |  | 152 | 1 | 282 | my $self = shift; | 
| 139 | 152 |  |  |  |  | 449 | return !!$default{ $self->get_id }; | 
| 140 |  |  |  |  |  |  | } | 
| 141 |  |  |  |  |  |  |  | 
| 142 |  |  |  |  |  |  | =item is_rooted() | 
| 143 |  |  |  |  |  |  |  | 
| 144 |  |  |  |  |  |  | Test if tree is rooted. | 
| 145 |  |  |  |  |  |  |  | 
| 146 |  |  |  |  |  |  | Type    : Test | 
| 147 |  |  |  |  |  |  | Title   : is_rooted | 
| 148 |  |  |  |  |  |  | Usage   : if ( $tree->is_rooted ) { | 
| 149 |  |  |  |  |  |  | # do something | 
| 150 |  |  |  |  |  |  | } | 
| 151 |  |  |  |  |  |  | Function: Tests whether the invocant | 
| 152 |  |  |  |  |  |  | object is rooted. | 
| 153 |  |  |  |  |  |  | Returns : BOOLEAN | 
| 154 |  |  |  |  |  |  | Args    : NONE | 
| 155 |  |  |  |  |  |  | Comments: A tree is considered unrooted if: | 
| 156 |  |  |  |  |  |  | - set_as_unrooted has been set, or | 
| 157 |  |  |  |  |  |  | - the basal split is a polytomy | 
| 158 |  |  |  |  |  |  |  | 
| 159 |  |  |  |  |  |  | =cut | 
| 160 |  |  |  |  |  |  |  | 
| 161 |  |  |  |  |  |  | sub is_rooted { | 
| 162 | 3 |  |  | 3 | 1 | 6 | my $self = shift; | 
| 163 | 3 |  |  |  |  | 9 | my $id   = $self->get_id; | 
| 164 | 3 | 100 |  |  |  | 11 | if ( defined $rooted{$id} ) { | 
| 165 | 2 |  |  |  |  | 6 | return ! $rooted{$id}; | 
| 166 |  |  |  |  |  |  | } | 
| 167 | 1 | 50 |  |  |  | 5 | if ( my $root = $self->get_root ) { | 
| 168 | 1 | 50 |  |  |  | 2 | if ( my $children = $root->get_children ) { | 
| 169 | 1 |  |  |  |  | 2 | return scalar @{$children} <= 2; | 
|  | 1 |  |  |  |  | 5 |  | 
| 170 |  |  |  |  |  |  | } | 
| 171 | 0 |  |  |  |  | 0 | return 1; | 
| 172 |  |  |  |  |  |  | } | 
| 173 | 0 |  |  |  |  | 0 | return 0; | 
| 174 |  |  |  |  |  |  | } | 
| 175 |  |  |  |  |  |  |  | 
| 176 |  |  |  |  |  |  | # the following methods are purely for internal consumption | 
| 177 |  |  |  |  |  |  | sub _cleanup : Destructor { | 
| 178 | 196 |  |  | 196 |  | 368 | my $self = shift; | 
| 179 | 196 | 50 |  |  |  | 529 | if ( defined( my $id = $self->get_id ) ) { | 
| 180 | 196 |  |  |  |  | 444 | for my $field (@fields) { | 
| 181 | 392 |  |  |  |  | 906 | delete $field->{$id}; | 
| 182 |  |  |  |  |  |  | } | 
| 183 |  |  |  |  |  |  | } | 
| 184 | 30 |  |  | 30 |  | 216 | } | 
|  | 30 |  |  |  |  | 71 |  | 
|  | 30 |  |  |  |  | 166 |  | 
| 185 |  |  |  |  |  |  |  | 
| 186 |  |  |  |  |  |  | sub _set_rooted : Clonable { | 
| 187 | 2 |  |  | 2 |  | 4 | my ( $self, $r ) = @_; | 
| 188 | 2 |  |  |  |  | 6 | $rooted{$self->get_id} = $r; | 
| 189 | 2 |  |  |  |  | 5 | return $self; | 
| 190 | 30 |  |  | 30 |  | 7507 | } | 
|  | 30 |  |  |  |  | 65 |  | 
|  | 30 |  |  |  |  | 119 |  | 
| 191 |  |  |  |  |  |  |  | 
| 192 | 2 |  |  | 2 |  | 6 | sub _get_rooted { $rooted{shift->get_id} } | 
| 193 |  |  |  |  |  |  |  | 
| 194 |  |  |  |  |  |  | sub _set_default : Clonable { | 
| 195 | 2 |  |  | 2 |  | 5 | my ( $self, $d ) = @_; | 
| 196 | 2 |  |  |  |  | 11 | $default{$self->get_id} = $d; | 
| 197 | 2 |  |  |  |  | 5 | return $self; | 
| 198 | 30 |  |  | 30 |  | 6693 | } | 
|  | 30 |  |  |  |  | 71 |  | 
|  | 30 |  |  |  |  | 113 |  | 
| 199 |  |  |  |  |  |  |  | 
| 200 | 2 |  |  | 2 |  | 7 | sub _get_default { $default{shift->get_id} } | 
| 201 |  |  |  |  |  |  |  | 
| 202 |  |  |  |  |  |  | =back | 
| 203 |  |  |  |  |  |  |  | 
| 204 |  |  |  |  |  |  | =cut | 
| 205 |  |  |  |  |  |  |  | 
| 206 |  |  |  |  |  |  | # podinherit_insert_token | 
| 207 |  |  |  |  |  |  |  | 
| 208 |  |  |  |  |  |  | =head1 SEE ALSO | 
| 209 |  |  |  |  |  |  |  | 
| 210 |  |  |  |  |  |  | There is a mailing list at L<https://groups.google.com/forum/#!forum/bio-phylo> | 
| 211 |  |  |  |  |  |  | for any user or developer questions and discussions. | 
| 212 |  |  |  |  |  |  |  | 
| 213 |  |  |  |  |  |  | =over | 
| 214 |  |  |  |  |  |  |  | 
| 215 |  |  |  |  |  |  | =item L<Bio::Phylo::Forest::TreeRole> | 
| 216 |  |  |  |  |  |  |  | 
| 217 |  |  |  |  |  |  | The L<Bio::Phylo::Forest::Tree> package inherits from | 
| 218 |  |  |  |  |  |  | the L<Bio::Phylo::Forest::TreeRole> package, so the methods defined | 
| 219 |  |  |  |  |  |  | therein also apply to trees. | 
| 220 |  |  |  |  |  |  |  | 
| 221 |  |  |  |  |  |  | =item L<Bio::Phylo::Manual> | 
| 222 |  |  |  |  |  |  |  | 
| 223 |  |  |  |  |  |  | Also see the manual: L<Bio::Phylo::Manual> and L<http://rutgervos.blogspot.com>. | 
| 224 |  |  |  |  |  |  |  | 
| 225 |  |  |  |  |  |  | =back | 
| 226 |  |  |  |  |  |  |  | 
| 227 |  |  |  |  |  |  | =head1 CITATION | 
| 228 |  |  |  |  |  |  |  | 
| 229 |  |  |  |  |  |  | If you use Bio::Phylo in published research, please cite it: | 
| 230 |  |  |  |  |  |  |  | 
| 231 |  |  |  |  |  |  | B<Rutger A Vos>, B<Jason Caravas>, B<Klaas Hartmann>, B<Mark A Jensen> | 
| 232 |  |  |  |  |  |  | and B<Chase Miller>, 2011. Bio::Phylo - phyloinformatic analysis using Perl. | 
| 233 |  |  |  |  |  |  | I<BMC Bioinformatics> B<12>:63. | 
| 234 |  |  |  |  |  |  | L<http://dx.doi.org/10.1186/1471-2105-12-63> | 
| 235 |  |  |  |  |  |  |  | 
| 236 |  |  |  |  |  |  | =cut | 
| 237 |  |  |  |  |  |  |  | 
| 238 |  |  |  |  |  |  | } | 
| 239 |  |  |  |  |  |  | 1; |