File Coverage

blib/lib/Bio/NEXUS/TreesBlock.pm
Criterion Covered Total %
statement 180 261 68.9
branch 33 68 48.5
condition 8 21 38.1
subroutine 28 34 82.3
pod 20 20 100.0
total 269 404 66.5


line stmt bran cond sub pod time code
1             ######################################################
2             # TreesBlock.pm
3             ######################################################
4             # Author: Chengzhi Liang, Eugene Melamud, Weigang Qiu, Peter Yang, Thomas Hladish
5             # $Id: TreesBlock.pm,v 1.63 2007/09/24 04:52:14 rvos Exp $
6              
7             #################### START POD DOCUMENTATION ##################
8              
9             =head1 NAME
10              
11             Bio::NEXUS::TreesBlock - Represents TREES block of a NEXUS file
12              
13             =head1 SYNOPSIS
14              
15             if ( $type =~ /trees/i ) {
16             $block_object = new Bio::NEXUS::TreesBlock( $block_type, $block, $verbose );
17             }
18              
19             =head1 DESCRIPTION
20              
21             If a NEXUS block is a Trees Block, this module parses the block and stores the tree data.
22              
23             =head1 FEEDBACK
24              
25             All feedback (bugs, feature enhancements, etc.) are all greatly appreciated.
26              
27             =head1 AUTHORS
28              
29             Chengzhi Liang (liangc@umbi.umd.edu)
30             Eugene Melamud (melamud@carb.nist.gov)
31             Weigang Qiu (weigang@genectr.hunter.cuny.edu)
32             Peter Yang (pyang@rice.edu)
33             Thomas Hladish (tjhladish at yahoo)
34              
35             =head1 VERSION
36              
37             $Revision: 1.63 $
38              
39             =head1 METHODS
40              
41             =cut
42              
43             package Bio::NEXUS::TreesBlock;
44              
45 34     34   199 use strict;
  34         73  
  34         1389  
46             #use Carp; # XXX this is not used, might as well not import it!
47             #use Data::Dumper; # XXX this is not used, might as well not import it!
48 34     34   252 use Bio::NEXUS::Functions;
  34         68  
  34         8588  
49             #use Bio::NEXUS::Node; # XXX loaded dynamically
50             #use Bio::NEXUS::Tree; # XXX loaded dynamically
51 34     34   1468 use Bio::NEXUS::Block;
  34         70  
  34         1098  
52 34     34   194 use Bio::NEXUS::Util::Exceptions 'throw';
  34         69  
  34         1811  
53 34     34   211 use Bio::NEXUS::Util::Logger;
  34         127  
  34         920  
54 34     34   181 use vars qw(@ISA $VERSION $AUTOLOAD);
  34         66  
  34         2399  
55 34     34   187 use Bio::NEXUS; $VERSION = $Bio::NEXUS::VERSION;
  34         113  
  34         120830  
56              
57             @ISA = qw(Bio::NEXUS::Block);
58             my $logger = Bio::NEXUS::Util::Logger->new;
59              
60             my %factories = (
61             'treetype' => __PACKAGE__->_load_module('Bio::NEXUS::Tree'),
62             'nodetype' => __PACKAGE__->_load_module('Bio::NEXUS::Node'),
63             );
64              
65             sub import {
66 68     68   245 my $class = shift;
67 68         171 my %args;
68 68 50       250 if ( @_ ) {
69 0         0 %args = @_;
70             }
71 68         196 for ( qw(treetype nodetype) ) {
72 136 50       2295 $factories{$_} = $class->_load_module( $args{$_} ) if $args{$_};
73             }
74             }
75              
76             =head2 new
77              
78             Title : new
79             Usage : block_object = new Bio::NEXUS::TreesBlock($block_type, $commands, $verbose );
80             Function: Creates a new Bio::NEXUS::TreesBlock object and automatically reads the file
81             Returns : Bio::NEXUS::TreesBlock object
82             Args : type (string), the commands/comments to parse (array ref), and a verbose flag (0 or 1; optional)
83              
84             =cut
85              
86             sub new {
87 54     54 1 177 my ( $class, $type, $commands, $verbose ) = @_;
88 54         391 $logger->info("constructor called for $class");
89 54   66     272 ( $type ||= lc $class ) =~ s/Bio::NEXUS::(.+)Block/$1/i;
90 54         458 my $self = {
91             'type' => $type,
92             'treetype' => $factories{'treetype'},
93             'nodetype' => $factories{'nodetype'},
94             };
95 54         195 bless $self, $class;
96 54 100 66     250 if ( defined $commands and @{ $commands } ) {
  51         243  
97 51         374 $self->_parse_block( $commands, $verbose );
98             }
99 53         262 return $self;
100             }
101              
102             =begin comment
103              
104             Title : _parse_translate
105             Usage : $self->_parse_translate($buffer);
106             Function: Process the 'translate' section of the Trees Block
107             Returns : the translation hash ref
108             Args : the buffer to parse (string)
109              
110             =end comment
111              
112             =cut
113              
114             sub _parse_translate {
115 3     3   8 my ( $self, $buffer ) = @_;
116 3         51 $buffer =~ s/,//g;
117 3         7 my $translate = { @{ _parse_nexus_words($buffer) } };
  3         14  
118 3         25 $self->{'translation'} = $translate;
119 3         20 return $translate;
120             }
121              
122             =begin comment
123              
124             Title : _parse_tree
125             Usage : $self->_parse_tree($buffer);
126             Function: Process the 'tree' section of the Trees Block
127             Returns : none
128             Args : buffer (string)
129             Method : Separates the buffer by the equal sign (example:
130             tree tree_name = tree_string)
131             Creates a new Bio::NEXUS::Tree object, sets the name as the name
132             and the tree as the tree. (duh)
133             Retrieves list of nodes from the Bio::NEXUS::Tree object. For each node,
134             checks to see if a translation is defined. If it is, then it
135             performs the appropriate translation. If not, then it just leaves
136             the name as it is. Then it adds itself to the list blockTrees.
137              
138             =end comment
139              
140             =cut
141              
142             sub _parse_tree {
143 82     82   220 my ( $self, $buffer, $verbose ) = @_;
144              
145 82         484 $logger->info("Entering tree");;
146 82         360 my $tree = $self->treetype->new();
147 82         173 my @tree_words = @{ _parse_nexus_words($buffer) };
  82         412  
148              
149             # If there's an asterisk, set the 'default' attribute, then get rid of the asterisk
150 82 100       778 if ( $tree_words[0] eq '*' ) {
151 1         4 shift @tree_words;
152 1         10 $tree->set_as_default();
153             }
154              
155             # separate out the name of the tree and the '=' symbol
156 82         287 my ( $name, $equals_symb ) = splice @tree_words, 0, 2;
157 82         521 $tree->set_name($name);
158              
159             # mark the tree as unrooted if it's prepended with [&U]
160 82 50       467 if ( lc $tree_words[0] eq lc '[&U]' ) {
    100          
161 0         0 $logger->info("setting tree as unrooted");
162 0         0 $tree->set_as_unrooted();
163 0         0 shift @tree_words;
164             }
165              
166             # if it's prepended with the rooted flag, nothing needs to change
167             elsif ( lc $tree_words[0] eq lc '[&R]' ) {
168 2         17 $logger->info("tree is rooted");
169 2         6 shift @tree_words;
170             }
171              
172 82         572 $logger->info("going to parse newick string");
173 82         409 $tree->_parse_newick( \@tree_words );
174 82         609 $logger->info($tree->as_string);
175              
176 82         365 my $nodes = $tree->get_nodes();
177 82         222 for my $node (@$nodes) {
178 1064 100       2651 if ( $node->is_otu() ) { #check for translation
179 603         1477 $name = $node->get_name();
180 603         3366 $logger->info("node is terminal, setting translation '$name'");
181 603         1798 $node->set_name( $self->translate($name) );
182             }
183             }
184              
185 82         383 $self->add_tree($tree);
186 82         778 return $tree;
187             }
188              
189             =head2 treetype
190              
191             Title : treetype
192             Usage : $block->treetype('Bio::NEXUS::Tree');
193             Function: sets a tree type class to instantiate on parse
194             Returns : none
195             Args : a tree class
196              
197             =cut
198              
199             sub treetype {
200 82     82 1 171 my $self = shift;
201 82 50       3495 if ( @_ ) {
202 0         0 $self->{'treetype'} = $self->_load_module(shift);
203             }
204 82   66     1004 return $self->{'treetype'} || $self->_load_module('Bio::NEXUS::Tree');
205             }
206              
207             =head2 nodetype
208              
209             Title : nodetype
210             Usage : $block->nodetype('Bio::NEXUS::Node');
211             Function: sets a node type class to instantiate on parse
212             Returns : none
213             Args : a node class
214              
215             =cut
216              
217             sub nodetype {
218 5     5 1 8 my $self = shift;
219 5 50       17 if ( @_ ) {
220 0         0 $self->{'nodetype'} = $self->_load_module(shift);
221             }
222 5   33     36 return $self->{'nodetype'} || $self->_load_module('Bio::NEXUS::Node');
223             }
224              
225             =head2 clone
226              
227             Title : clone
228             Usage : my $newblock = $block->clone();
229             Function: clone a block object (shallow)
230             Returns : Block object
231             Args : none
232              
233             =cut
234              
235             sub clone {
236 3     3 1 7 my ($self) = @_;
237 3         7 my $class = ref($self);
238 3         6 my $TreesBlock = bless( { %{$self} }, $class );
  3         27  
239              
240             # clone trees
241 3         10 my @trees = ();
242 3         8 for my $tree ( @{ $self->get_trees() } ) {
  3         12  
243 3         10 push @trees, $tree;
244             }
245 3         14 $TreesBlock->set_trees( \@trees );
246 3         12 return $TreesBlock;
247             }
248              
249             =head2 set_trees
250              
251             Title : set_trees
252             Usage : $block->set_trees($trees);
253             Function: Sets the list of trees (Bio::NEXUS::Tree objects)
254             Returns : none
255             Args : ref to array of Bio::NEXUS::Tree objects
256              
257             =cut
258              
259             sub set_trees {
260 7     7 1 23 my ( $self, $trees ) = @_;
261 7         18 $self->{'blockTrees'} = $trees;
262             }
263              
264             =head2 add_tree
265              
266             Title : add_tree
267             Usage : $block->add_tree($tree);
268             Function: Add trees (Bio::NEXUS::Tree object)
269             Returns : none
270             Args : a Bio::NEXUS::Tree object
271              
272             =cut
273              
274             sub add_tree {
275 87     87 1 957 my ( $self, $tree ) = @_;
276 87         137 push @{ $self->{'blockTrees'} }, $tree;
  87         360  
277             }
278              
279             =head2 add_tree_from_newick
280              
281             Title : add_tree_from_newick
282             Usage : $block->add_tree_from_newick($newick_tree, $tree_name);
283             Function: Add a tree (Bio::NEXUS::Tree object)
284             Returns : none
285             Args : a tree string in newick format and a name for the tree (scalars)
286              
287             =cut
288              
289             sub add_tree_from_newick {
290 6     6 1 32 my ( $self, $tree, $tree_name ) = @_;
291 6         19 $tree = "$tree_name = $tree";
292 6         25 $self->_parse_tree($tree);
293 6         23 return;
294             }
295              
296             =head2 get_trees
297              
298             Title : get_trees
299             Usage : $block->get_trees();
300             Function: Gets the list of trees (Bio::NEXUS::Tree objects) and returns it
301             Returns : ref to array of Bio::NEXUS::Tree objects
302             Args : none
303              
304             =cut
305              
306             sub get_trees {
307 108     108 1 3315 my $self = shift;
308 108   50     575 return $self->{'blockTrees'} || [];
309             }
310              
311             =head2 get_tree
312              
313             Title : get_tree
314             Usage : $block->get_tree($treename);
315             Function: Gets the first tree (Bio::NEXUS::Tree object) that matches the name given or the first tree if $treename is not specified. If no tree matches, returns undef.
316             Returns : a Bio::NEXUS::Tree object
317             Args : tree name or none
318              
319             =cut
320              
321             sub get_tree {
322 85     85 1 37011 my ( $self, $treename ) = @_;
323 85 100       361 return $self->get_trees()->[0] unless $treename;
324 43         49 for my $t ( @{ $self->get_trees() } ) {
  43         98  
325 345 100       872 return $t if ( $t->get_name() =~ /^$treename/ );
326             }
327 3         14 return undef;
328             }
329              
330             =head2 set_translate
331              
332             Title : set_translate
333             Usage : $block->set_translate($translate);
334             Function: Sets the hash of translates for nodes names
335             Returns : none
336             Args : hash of translates
337              
338             =cut
339              
340             sub set_translate {
341 2     2 1 9 my ( $self, $translate ) = @_;
342 2         7 $self->{'translation'} = $translate;
343             }
344              
345             =head2 translate
346              
347             Title : translate
348             Usage : $self->translate($num);
349             Function: Translates a number with its associated name.
350             Returns : integer or string
351             Args : integer
352             Method : Returns the name associated with that number's translated name.
353             If it can't find an association, returns the number.
354              
355             =cut
356              
357             sub translate {
358 605     605 1 887 my ( $self, $num ) = @_;
359 605 100       1634 if ( defined $self->{'translation'}{$num} ) {
360 112         653 return $self->{'translation'}{$num};
361             }
362             else {
363 493         1818 return $num;
364             }
365             }
366              
367             =head2 reroot_tree
368              
369             Title : reroot_tree
370             Usage : $block->reroot_tree($outgroup,$root_position, $treename);
371             Function: Reroot a tree using an OTU as new outgroup.
372             Returns : none
373             Args : outgroup name, the distance before the root position and tree name
374              
375             =cut
376              
377             sub reroot_tree {
378 0     0 1 0 my ( $self, $outgroup, $root_position, $treename ) = @_;
379 0 0 0     0 if ( not defined $treename and not defined $outgroup ) {
380 0         0 throw 'BadArgs' => 'Need to specify a tree name and outgroup name for rerooting';
381             }
382 0         0 my $tree = $self->get_tree($treename);
383 0         0 my @rerooted_trees;
384 0         0 foreach my $tree ( @{ $self->get_trees() } ) {
  0         0  
385 0 0       0 if ( $tree->get_name ne $treename ) {
386 0         0 push @rerooted_trees, $tree;
387             }
388             else {
389 0         0 push @rerooted_trees, $tree->reroot( $outgroup, $root_position );
390             }
391             }
392 0         0 $self->set_trees( \@rerooted_trees );
393 0         0 return $self;
394             }
395              
396             =head2 reroot_all_trees
397              
398             Title : reroot_all_trees
399             Usage : $block->reroot_all_trees($outgroup, $root_position);
400             Function: Reroot all the trees in the treesblock tree. use an OTU as new outgroup
401             Returns : none
402             Args : outgroup name and root position
403              
404             =cut
405              
406             sub reroot_all_trees {
407 0     0 1 0 my ( $self, $outgroup, $root_position ) = @_;
408 0 0       0 return if not defined $self->get_tree;
409 0         0 my @rerooted_trees;
410 0         0 foreach my $tree ( @{ $self->get_trees() } ) {
  0         0  
411 0         0 push @rerooted_trees, $tree->reroot( $outgroup, $root_position );
412             }
413 0         0 $self->set_trees( \@rerooted_trees );
414 0         0 return $self;
415             }
416              
417             =head2 rename_otus
418              
419             Title : rename_otus
420             Usage : $block->rename_otus(\%translation);
421             Function: Renames nodes based on a translation hash
422             Returns : none
423             Args : hash containing translation (e.g., { old_name => new_name} )
424             Comments: nodes not included in translation hash are unaffected
425              
426             =cut
427              
428             sub rename_otus {
429 3     3 1 6 my ( $self, $translate ) = @_;
430 3 50       11 return if not defined $self->get_tree;
431 3         9 for my $tree ( @{ $self->get_trees() } ) {
  3         8  
432 3         15 my $nodes = $tree->get_nodes();
433 3         9 for my $node (@$nodes) {
434 21         61 my $name = $node->get_name();
435 21         38 my $translatedname = $translate->{$name};
436 21 100       62 if ($translatedname) {
437 3         13 $node->set_name($translatedname);
438             }
439             }
440             }
441 3         11 my $newnames = $self->get_tree()->get_node_names();
442 3         31 $self->set_taxlabels($newnames);
443             }
444              
445             =head2 select_otus
446              
447             Name : select_otus
448             Usage : $nexus->select_otus(\@otunames);
449             Function: select a subset of OTUs
450             Returns : a new nexus object
451             Args : a ref to array of OTU names
452              
453             =cut
454              
455             sub select_otus {
456 1     1 1 3 my ( $self, $otunames ) = @_;
457 1         2 for my $tree ( @{ $self->get_trees() } ) {
  1         3  
458 1         3 $tree->prune("@{$otunames}");
  1         7  
459             }
460 1         4 $self->set_taxlabels($otunames);
461 1         3 return $self;
462             }
463              
464             =head2 add_otu_clone
465              
466             Title : add_otu_clone
467             Usage : ...
468             Function: ...
469             Returns : ...
470             Args : ...
471              
472             =cut
473              
474             sub add_otu_clone {
475 5     5 1 11 my ( $self, $original_otu_name, $copy_otu_name ) = @_;
476             # print "Warning: Bio::NEXUS::TreesBlock::add_otu_clone() method not fully implemented\n";
477            
478             # . iterate through all trees:
479 5         10 foreach my $tree ( @{ $self->{'blockTrees'} }) {
  5         15  
480             # . find the original node
481             # if not found, something must be done !
482 5         34 my $original_node = $tree->find($original_otu_name);
483 5 50       17 print "TreesBlock::add_otu_clone(): original otu [$original_otu_name] was not found.\n" if (! defined $original_node);
484             # . clone the node
485 5         36 my $cloned_node = $original_node->clone();
486             # . rename the new node
487 5         23 $cloned_node->set_name($copy_otu_name);
488            
489             # find the parent of the original node, add to it a new
490             # child that will be parent of both original and
491             # clone nodes. Remove the original node from the
492             # list of children of its original parent
493 5         21 my $original_parent = $original_node->get_parent();
494            
495 5         9 foreach my $child ( @{ $original_parent->get_children() }) {
  5         19  
496             # print "Child name: ", $child->get_name(), "\n";
497 6 100       21 if ($child->get_name() eq $original_otu_name) {
498 5         33 my $new_parent = $self->nodetype->new();
499              
500 5         20 $new_parent->set_length($original_node->get_length());
501            
502 5         17 $cloned_node->set_length(0);
503 5         17 $original_node->set_length(0);
504            
505 5         26 $new_parent->add_child($cloned_node);
506 5         93 $cloned_node->set_parent_node($new_parent);
507 5         17 $new_parent->add_child($original_node);
508 5         18 $original_node->set_parent_node($new_parent);
509              
510 5         13 $new_parent->set_parent_node($original_parent);
511 5         6 $child = $new_parent;
512 5         28 last;
513             }
514             }
515             }
516            
517             # todo:
518             # add the clone to {'translation'} if the original is also there
519             }
520              
521             =head2 select_tree
522              
523             Name : select_tree
524             Usage : $nexus->select_tree($treename);
525             Function: select a tree
526             Returns : a new nexus object
527             Args : a tree name
528              
529             =cut
530              
531             sub select_tree {
532 1     1 1 3 my ( $self, $treename ) = @_;
533 1         3 my @oldtrees = @{ $self->get_trees() };
  1         4  
534 1         5 $self->set_trees();
535 1         3 for my $tree (@oldtrees) {
536 1 50       5 if ( $tree->get_name() eq $treename ) {
537 1         4 $self->add_tree($tree);
538 1         2 last;
539             }
540             }
541 1         11 return $self;
542             }
543              
544             =head2 select_subtree
545              
546             Name : select_subtree
547             Usage : $nexus->select_subtree($inodename);
548             Function: select a subtree
549             Returns : a new nexus object
550             Args : an internal node name for subtree to be selected
551              
552             =cut
553              
554             sub select_subtree {
555 2     2 1 592 my ( $self, $nodename, $treename ) = @_;
556 2 50       6 if ( not $nodename ) {
557 0         0 throw 'BadArgs' => 'Need to specify an internal node name for subtree';
558             }
559 2         5 my $tree = $self->get_tree($treename);
560 2 50       7 if ( not $tree ) {
561 0         0 throw 'BadArgs' => "Tree $treename not found.";
562             }
563 2         11 $tree = $tree->select_subtree($nodename);
564 1         6 $self->set_trees();
565 1         5 $self->add_tree($tree);
566 1         5 $self->set_taxlabels( $tree->get_node_names() );
567              
568 1         4 return $self;
569             }
570              
571             =head2 exclude_subtree
572              
573             Name : exclude_subtree
574             Usage : $nexus->exclude_subtree($inodename);
575             Function: remove a subtree
576             Returns : a new nexus object
577             Args : an internal node for subtree to be removed
578              
579             =cut
580              
581             sub exclude_subtree {
582 0     0 1 0 my ( $self, $nodename, $treename ) = @_;
583 0 0       0 if ( not $nodename ) {
584 0         0 throw 'BadArgs' => 'Need to specify an internal node name for subtree';
585             }
586              
587 0         0 my $tree = $self->get_tree($treename);
588 0 0       0 if ( not $tree ) {
589 0         0 throw 'BadArgs' => "Tree $treename not found.";
590             }
591              
592 0         0 $tree = $tree->exclude_subtree($nodename);
593 0         0 $self->set_trees();
594 0         0 $self->add_tree($tree);
595 0         0 $self->set_taxlabels( $tree->get_node_names() );
596              
597 0         0 return $self;
598             }
599              
600             =head2 equals
601              
602             Name : equals
603             Usage : $nexus->equals($another);
604             Function: compare if two NEXUS objects are equal
605             Returns : boolean
606             Args : a NEXUS object
607              
608             =cut
609              
610             sub equals {
611 2     2 1 6 my ( $self, $block ) = @_;
612 2 50       9 if ( !Bio::NEXUS::Block::equals( $self, $block ) ) { return 0; }
  0         0  
613              
614             # if ($self->get_type() ne $block->get_type()) {return 0;}
615 2         4 my @trees1 = @{ $self->get_trees() };
  2         10  
616 2         4 my @trees2 = @{ $block->get_trees() };
  2         7  
617 2 50       7 if ( @trees1 != @trees2 ) { return 0; }
  0         0  
618 2         5 @trees1 = sort { $a->get_name() cmp $b->get_name() } @trees1;
  0         0  
619 2         3 @trees2 = sort { $a->get_name() cmp $b->get_name() } @trees2;
  0         0  
620 2         8 for ( my $i = 0; $i < @trees1; $i++ ) {
621 2 50       14 if ( !$trees1[$i]->equals( $trees2[$i] ) ) { return 0; }
  0         0  
622             }
623 2         17 return 1;
624             }
625              
626             # method under testing
627             sub _equals_test {
628 0     0   0 my ( $self, $block ) = @_;
629 0 0       0 if ( !Bio::NEXUS::Block::equals( $self, $block ) ) { return 0; }
  0         0  
630              
631             # if ($self->get_type() ne $block->get_type()) {return 0;}
632 0         0 my @trees1 = @{ $self->get_trees() };
  0         0  
633 0         0 my @trees2 = @{ $block->get_trees() };
  0         0  
634 0 0       0 if ( @trees1 != @trees2 ) { return 0; }
  0         0  
635 0         0 @trees1 = sort { $a->get_name() cmp $b->get_name() } @trees1;
  0         0  
636 0         0 @trees2 = sort { $a->get_name() cmp $b->get_name() } @trees2;
  0         0  
637 0         0 for ( my $i = 0; $i < @trees1; $i++ ) {
638 0 0       0 if ( !$trees1[$i]->_equals_test( $trees2[$i] ) ) { return 0; }
  0         0  
639             }
640 0         0 return 1;
641             }
642              
643             =begin comment
644              
645             Name : _write
646             Usage : $block->_write($file_handle,verbose);
647             Function: Writes Trees Block object into the filehandle or STDOUT
648             Returns : none
649             Args : File handle for writing the trees and verbose option( 0 or 1).
650             If file handle is empty then the output it written on STDOUT.
651              
652             =end comment
653              
654             =cut
655              
656             sub _write {
657 0     0   0 my ( $self, $fh, $verbose ) = @_;
658 0   0     0 $fh ||= \*STDOUT;
659              
660 0         0 Bio::NEXUS::Block::_write( $self, $fh );
661 0         0 $self->_write_trees( $fh, $verbose );
662 0         0 print $fh "END;\n";
663             }
664              
665             =begin comment
666              
667             Name : _write_trees
668             Usage : $block->_write_trees($file_handle,verbose);
669             Function: Writes trees in the object into the file handle or STDOUT as string.(used in $self->_write)
670             Returns : none
671             Args : File handle for writing the trees and verbose option( 0 or 1).
672             If file handle is empty then the output it written on STDOUT.
673              
674             =end comment
675              
676             =cut
677              
678             sub _write_trees {
679 0     0   0 my ( $self, $fh, $verbose ) = @_;
680 0   0     0 $fh ||= \*STDOUT;
681              
682 0         0 for my $tree ( @{ $self->get_trees() } ) {
  0         0  
683 0         0 print $fh "\tTREE ";
684 0 0       0 if ( $tree->is_default() ) {
685 0         0 print $fh "* ";
686             }
687             # tree name has to be protected if it contains quotations
688 0         0 print $fh _nexus_formatted($tree->get_name()), " = ";
689 0 0       0 if ( !$tree->is_rooted() ) {
690 0         0 print $fh "[&U] ";
691             }
692 0         0 print $fh $tree->as_string(), "\n";
693             }
694              
695             }
696              
697             sub AUTOLOAD {
698 1 50   1   6 return if $AUTOLOAD =~ /DESTROY$/;
699 1         2 my $package_name = __PACKAGE__ . '::';
700              
701             # The following methods are deprecated and are temporarily supported
702             # via a warning and a redirection
703 1         5 my %synonym_for = (
704              
705             # "${package_name}parse" => "${package_name}_parse_tree", # example
706             );
707              
708 1 50       4 if ( defined $synonym_for{$AUTOLOAD} ) {
709 0         0 $logger->warn("$AUTOLOAD() is deprecated; use $synonym_for{$AUTOLOAD}() instead");
710 0         0 goto &{ $synonym_for{$AUTOLOAD} };
  0         0  
711             }
712             else {
713 1         7 throw 'UnknownMethod' => "ERROR: Unknown method $AUTOLOAD called";
714             }
715 0           return;
716             }
717              
718             1;