File Coverage

Bio/TreeIO/TreeEventBuilder.pm
Criterion Covered Total %
statement 112 117 95.7
branch 29 38 76.3
condition 8 12 66.6
subroutine 14 14 100.0
pod 10 10 100.0
total 173 191 90.5


line stmt bran cond sub pod time code
1             #
2             # BioPerl module for Bio::TreeIO::TreeEventBuilder
3             #
4             # Please direct questions and support issues to
5             #
6             # Cared for by Jason Stajich
7             #
8             # Copyright Jason Stajich
9             #
10             # You may distribute this module under the same terms as perl itself
11              
12             # POD documentation - main docs before the code
13              
14             =head1 NAME
15              
16             Bio::TreeIO::TreeEventBuilder - Build Bio::Tree::Tree's and
17             Bio::Tree::Node's from Events
18              
19             =head1 SYNOPSIS
20              
21             # internal use only
22              
23             =head1 DESCRIPTION
24              
25             This object will take events and build a Bio::Tree::TreeI compliant
26             object makde up of Bio::Tree::NodeI objects.
27              
28             =head1 FEEDBACK
29              
30             =head2 Mailing Lists
31              
32             User feedback is an integral part of the evolution of this and other
33             Bioperl modules. Send your comments and suggestions preferably to
34             the Bioperl mailing list. Your participation is much appreciated.
35              
36             bioperl-l@bioperl.org - General discussion
37             http://bioperl.org/wiki/Mailing_lists - About the mailing lists
38              
39             =head2 Support
40              
41             Please direct usage questions or support issues to the mailing list:
42              
43             I
44              
45             rather than to the module maintainer directly. Many experienced and
46             reponsive experts will be able look at the problem and quickly
47             address it. Please include a thorough description of the problem
48             with code and data examples if at all possible.
49              
50             =head2 Reporting Bugs
51              
52             Report bugs to the Bioperl bug tracking system to help us keep track
53             of the bugs and their resolution. Bug reports can be submitted via the
54             web:
55              
56             https://github.com/bioperl/bioperl-live/issues
57              
58             =head1 AUTHOR - Jason Stajich
59              
60             Email jason-at-bioperl.org
61              
62             =head1 APPENDIX
63              
64             The rest of the documentation details each of the object methods.
65             Internal methods are usually preceded with a _
66              
67             =cut
68              
69              
70             # Let the code begin...
71              
72              
73             package Bio::TreeIO::TreeEventBuilder;
74 23     23   76 use strict;
  23         146  
  23         515  
75              
76 23     23   5299 use Bio::Tree::Tree;
  23         45  
  23         557  
77 23     23   6436 use Bio::Tree::Node;
  23         41  
  23         676  
78              
79 23     23   108 use base qw(Bio::Root::Root Bio::Event::EventHandlerI);
  23         33  
  23         7412  
80              
81             =head2 new
82              
83             Title : new
84             Usage : my $obj = Bio::TreeIO::TreeEventBuilder->new();
85             Function: Builds a new Bio::TreeIO::TreeEventBuilder object
86             Returns : Bio::TreeIO::TreeEventBuilder
87             Args :
88              
89              
90             =cut
91              
92             sub new {
93 1236     1236 1 2496 my($class,@args) = @_;
94              
95 1236         2616 my $self = $class->SUPER::new(@args);
96 1236         4202 my ($treetype, $nodetype) = $self->_rearrange([qw(TREETYPE
97             NODETYPE)], @args);
98 1236   50     4599 $treetype ||= 'Bio::Tree::Tree';
99 1236   100     4105 $nodetype ||= 'Bio::Tree::Node';
100              
101 1236         1432 eval {
102 1236         2537 $self->_load_module($treetype);
103 1236         2544 $self->_load_module($nodetype);
104             };
105              
106 1236 50       2434 if( $@ ) {
107 0         0 $self->throw("Could not load module $treetype or $nodetype. \n$@\n")
108             }
109 1236         3123 $self->treetype($treetype);
110 1236         2954 $self->nodetype($nodetype);
111 1236         1854 $self->{'_treelevel'} = 0;
112 1236         4981 return $self;
113             }
114              
115             =head2 treetype
116              
117             Title : treetype
118             Usage : $obj->treetype($newval)
119             Function:
120             Returns : value of treetype
121             Args : newvalue (optional)
122              
123              
124             =cut
125              
126             sub treetype{
127 1389     1389 1 2031 my ($self,$value) = @_;
128 1389 100       3087 if( defined $value) {
129 1236         2191 $self->{'treetype'} = $value;
130             }
131 1389         2121 return $self->{'treetype'};
132             }
133              
134             =head2 nodetype
135              
136             Title : nodetype
137             Usage : $obj->nodetype($newval)
138             Function:
139             Returns : value of nodetype
140             Args : newvalue (optional)
141              
142              
143             =cut
144              
145             sub nodetype{
146 6087     6087 1 5051 my ($self,$value) = @_;
147 6087 100       9486 if( defined $value) {
148 1236         2021 $self->{'nodetype'} = $value;
149             }
150 6087         11717 return $self->{'nodetype'};
151             }
152              
153              
154             =head2 SAX methods
155              
156             =cut
157              
158             =head2 start_document
159              
160             Title : start_document
161             Usage : $handler->start_document
162             Function: Begins a Tree event cycle
163             Returns : none
164             Args : none
165              
166             =cut
167              
168             sub start_document {
169 153     153 1 160 my ($self) = @_;
170 153         254 $self->{'_lastitem'} = {};
171 153         258 $self->{'_currentitems'} = [];
172 153         187 $self->{'_currentnodes'} = [];
173 153         188 return;
174             }
175              
176             =head2 end_document
177              
178             Title : end_document
179             Usage : my @trees = $parser->end_document
180             Function: Finishes a Phylogeny cycle
181             Returns : An array Bio::Tree::TreeI
182             Args : none
183              
184             =cut
185              
186             sub end_document {
187 153     153 1 202 my ($self,$label) = @_;
188              
189 153         134 my ($root) = @{$self->{'_currentnodes'}};
  153         228  
190              
191 153         330 $self->debug("Root node is " . $root->to_string()."\n");
192 153 50       305 if( $self->verbose > 0 ) {
193 0         0 foreach my $node ( $root->get_Descendents ) {
194 0         0 $self->debug("node is ". $node->to_string(). "\n");
195             }
196             }
197 153         317 my $tree = $self->treetype->new(-verbose => $self->verbose,
198             -root => $root);
199 153         287 return $tree;
200             }
201              
202             =head2 start_element
203              
204             Title : start_element
205             Usage :
206             Function:
207             Example :
208             Returns :
209             Args : $data => hashref with key 'Name'
210              
211             =cut
212              
213             sub start_element{
214 14003     14003 1 10866 my ($self,$data) =@_;
215 14003         13765 $self->{'_lastitem'}->{$data->{'Name'}}++;
216              
217 14003         25433 $self->debug("starting element: $data->{Name}\n");
218 14003         11388 push @{$self->{'_lastitem'}->{'current'}},$data->{'Name'};
  14003         19276  
219            
220 14003         10395 my %data;
221            
222 14003 100       29392 if( $data->{'Name'} eq 'node' ) {
    100          
223 4851         3436 push @{$self->{'_currentitems'}}, \%data;
  4851         5158  
224 4851         7435 $self->{'_treelevel'}++;
225             } elsif ( $data->{Name} eq 'tree' ) {
226             }
227             }
228              
229             =head2 end_element
230              
231             Title : end_element
232             Usage :
233             Function:
234             Returns : none
235             Args : $data => hashref with key 'Name'
236              
237             =cut
238              
239             sub end_element{
240 14003     14003 1 10475 my ($self,$data) = @_;
241              
242 14003         23101 $self->debug("end of element: $data->{Name}\n");
243             # this is the stack where we push/pop items from it
244 14003         10430 my $curcount = scalar @{$self->{'_currentnodes'}};
  14003         13448  
245 14003         10541 my $level = $self->{'_treelevel'};
246 14003   100     30158 my $levelct = $self->{'_nodect'}->[$self->{'_treelevel'}+1] || 0;
247              
248 14003 100       23107 if( $data->{'Name'} eq 'node' ) {
    100          
249 4851         3547 my $tnode;
250 4851         3209 my $node = pop @{$self->{'_currentitems'}};
  4851         5137  
251              
252             $tnode = $self->nodetype->new( -verbose => $self->verbose,
253 4851         7395 %{$node});
  4851         16947  
254 4851         9778 $self->debug( "new node will be ".$tnode->to_string."\n");
255 4851 100 66     16489 if ( !$node->{'-leaf'} && $levelct > 0) {
256 13076         15270 $self->debug(join(',', map { $_->to_string }
257 2308         1899 @{$self->{'_currentnodes'}}). "\n");
  2308         3004  
258 2308 50       4446 $self->throw("something wrong with event construction treelevel ".
259             "$level is recorded as having $levelct nodes ".
260             "but current nodes at this level is $curcount\n")
261             if( $levelct > $curcount);
262 2308         1787 for ( splice( @{$self->{'_currentnodes'}}, - $levelct)) {
  2308         5076  
263 4698         6407 $self->debug("adding desc: " . $_->to_string . "\n");
264 4698         8242 $tnode->add_Descendent($_);
265             }
266 2308         3485 $self->{'_nodect'}->[$self->{'_treelevel'}+1] = 0;
267             }
268 4851         3467 push @{$self->{'_currentnodes'}}, $tnode;
  4851         5880  
269 4851         5426 $self->{'_nodect'}->[$self->{'_treelevel'}]++;
270            
271 4851         3095 $curcount = scalar @{$self->{'_currentnodes'}};
  4851         4462  
272 4851         10830 $self->debug ("added node: count is now $curcount, treelevel: $level, nodect: $levelct\n");
273              
274 4851         8345 $self->{'_treelevel'}--;
275             } elsif( $data->{'Name'} eq 'tree' ) {
276 153         358 $self->debug("end of tree: nodes in stack is $curcount\n");
277             }
278              
279 14003         15233 $self->{'_lastitem'}->{ $data->{'Name'} }--;
280 14003         8864 pop @{$self->{'_lastitem'}->{'current'}};
  14003         23570  
281             }
282              
283              
284             =head2 in_element
285              
286             Title : in_element
287             Usage :
288             Function:
289             Example :
290             Returns :
291             Args :
292              
293              
294             =cut
295              
296             sub in_element{
297 25112     25112 1 17666 my ($self,$e) = @_;
298              
299             return 0 if ! defined $self->{'_lastitem'} ||
300 25112 50 33     49427 ! defined $self->{'_lastitem'}->{'current'}->[-1];
301 25112         43036 return ($e eq $self->{'_lastitem'}->{'current'}->[-1]);
302              
303             }
304              
305             =head2 within_element
306              
307             Title : within_element
308             Usage :
309             Function:
310             Example :
311             Returns :
312             Args :
313              
314              
315             =cut
316              
317             sub within_element{
318 8674     8674 1 6696 my ($self,$e) = @_;
319 8674         13899 return $self->{'_lastitem'}->{$e};
320             }
321              
322             =head2 characters
323              
324             Title : characters
325             Usage : $handler->characters($text);
326             Function: Processes characters
327             Returns : none
328             Args : text string
329              
330              
331             =cut
332              
333             sub characters{
334 8521     8521 1 7424 my ($self,$ch) = @_;
335 8521 50       9927 if( $self->within_element('node') ) {
336 8521         5340 my $hash = pop @{$self->{'_currentitems'}};
  8521         9327  
337 8521 100       10006 if( $self->in_element('bootstrap') ) {
    100          
    100          
    50          
    100          
    50          
    0          
338             # leading/trailing Whitespace-B-Gone
339 8         13 $ch =~ s/^\s+//; $ch =~ s/\s+$//;
  8         11  
340 8         14 $hash->{'-bootstrap'} = $ch;
341             } elsif( $self->in_element('branch_length') ) {
342             # leading/trailing Whitespace-B-Gone
343 4325         6112 $ch =~ s/^\s+//; $ch =~ s/\s+$//;
  4325         5221  
344 4325         5417 $hash->{'-branch_length'} = $ch;
345             } elsif( $self->in_element('id') ) {
346 2632         3484 $hash->{'-id'} = $ch;
347             } elsif( $self->in_element('description') ) {
348 0         0 $hash->{'-desc'} = $ch;
349             } elsif ( $self->in_element('tag_name') ) {
350 778         974 $hash->{'-NHXtagname'} = $ch;
351             } elsif ( $self->in_element('tag_value') ) {
352 778         1201 $hash->{'-nhx'}->{$hash->{'-NHXtagname'}} = $ch;
353 778         851 delete $hash->{'-NHXtagname'};
354             } elsif( $self->in_element('leaf') ) {
355 0         0 $hash->{'-leaf'} = $ch;
356             }
357 8521         7901 push @{$self->{'_currentitems'}}, $hash;
  8521         9371  
358             }
359 8521         15287 $self->debug("chars: $ch\n");
360             }
361              
362              
363             1;