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 22     22   136 use strict;
  22         88  
  22         663  
75              
76 22     22   4843 use Bio::Tree::Tree;
  22         67  
  22         750  
77 22     22   7086 use Bio::Tree::Node;
  22         70  
  22         943  
78              
79 22     22   191 use base qw(Bio::Root::Root Bio::Event::EventHandlerI);
  22         850  
  22         8569  
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 660     660 1 2688 my($class,@args) = @_;
94              
95 660         2233 my $self = $class->SUPER::new(@args);
96 660         3060 my ($treetype, $nodetype) = $self->_rearrange([qw(TREETYPE
97             NODETYPE)], @args);
98 660   50     3262 $treetype ||= 'Bio::Tree::Tree';
99 660   100     2748 $nodetype ||= 'Bio::Tree::Node';
100              
101 660         1055 eval {
102 660         2125 $self->_load_module($treetype);
103 660         1808 $self->_load_module($nodetype);
104             };
105              
106 660 50       1854 if( $@ ) {
107 0         0 $self->throw("Could not load module $treetype or $nodetype. \n$@\n")
108             }
109 660         2598 $self->treetype($treetype);
110 660         2521 $self->nodetype($nodetype);
111 660         1493 $self->{'_treelevel'} = 0;
112 660         3583 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 786     786 1 1964 my ($self,$value) = @_;
128 786 100       2115 if( defined $value) {
129 660         1675 $self->{'treetype'} = $value;
130             }
131 786         1644 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 5287     5287 1 8774 my ($self,$value) = @_;
147 5287 100       9319 if( defined $value) {
148 660         1508 $self->{'nodetype'} = $value;
149             }
150 5287         12118 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 126     126 1 234 my ($self) = @_;
170 126         412 $self->{'_lastitem'} = {};
171 126         306 $self->{'_currentitems'} = [];
172 126         294 $self->{'_currentnodes'} = [];
173 126         248 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 126     126 1 279 my ($self,$label) = @_;
188              
189 126         203 my ($root) = @{$self->{'_currentnodes'}};
  126         308  
190              
191 126         365 $self->debug("Root node is " . $root->to_string()."\n");
192 126 50       337 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 126         435 my $tree = $self->treetype->new(-verbose => $self->verbose,
198             -root => $root);
199 126         346 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 13414     13414 1 20319 my ($self,$data) =@_;
215 13414         20524 $self->{'_lastitem'}->{$data->{'Name'}}++;
216              
217 13414         36210 $self->debug("starting element: $data->{Name}\n");
218 13414         17213 push @{$self->{'_lastitem'}->{'current'}},$data->{'Name'};
  13414         25557  
219            
220 13414         16416 my %data;
221            
222 13414 100       32592 if( $data->{'Name'} eq 'node' ) {
    100          
223 4627         5256 push @{$self->{'_currentitems'}}, \%data;
  4627         7237  
224 4627         9706 $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 13414     13414 1 18578 my ($self,$data) = @_;
241              
242 13414         36057 $self->debug("end of element: $data->{Name}\n");
243             # this is the stack where we push/pop items from it
244 13414         19412 my $curcount = scalar @{$self->{'_currentnodes'}};
  13414         19560  
245 13414         16557 my $level = $self->{'_treelevel'};
246 13414   100     33066 my $levelct = $self->{'_nodect'}->[$self->{'_treelevel'}+1] || 0;
247              
248 13414 100       27875 if( $data->{'Name'} eq 'node' ) {
    100          
249 4627         5231 my $tnode;
250 4627         4629 my $node = pop @{$self->{'_currentitems'}};
  4627         7016  
251              
252             $tnode = $self->nodetype->new( -verbose => $self->verbose,
253 4627         8930 %{$node});
  4627         22766  
254 4627         12453 $self->debug( "new node will be ".$tnode->to_string."\n");
255 4627 100 66     16588 if ( !$node->{'-leaf'} && $levelct > 0) {
256 12827         23037 $self->debug(join(',', map { $_->to_string }
257 2223         3353 @{$self->{'_currentnodes'}}). "\n");
  2223         4688  
258 2223 50       5981 $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 2223         3474 for ( splice( @{$self->{'_currentnodes'}}, - $levelct)) {
  2223         6511  
263 4501         8946 $self->debug("adding desc: " . $_->to_string . "\n");
264 4501         11243 $tnode->add_Descendent($_);
265             }
266 2223         5135 $self->{'_nodect'}->[$self->{'_treelevel'}+1] = 0;
267             }
268 4627         5367 push @{$self->{'_currentnodes'}}, $tnode;
  4627         8167  
269 4627         8078 $self->{'_nodect'}->[$self->{'_treelevel'}]++;
270            
271 4627         5166 $curcount = scalar @{$self->{'_currentnodes'}};
  4627         6818  
272 4627         15693 $self->debug ("added node: count is now $curcount, treelevel: $level, nodect: $levelct\n");
273              
274 4627         11852 $self->{'_treelevel'}--;
275             } elsif( $data->{'Name'} eq 'tree' ) {
276 126         429 $self->debug("end of tree: nodes in stack is $curcount\n");
277             }
278              
279 13414         21355 $self->{'_lastitem'}->{ $data->{'Name'} }--;
280 13414         13376 pop @{$self->{'_lastitem'}->{'current'}};
  13414         30749  
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 24292     24292 1 31351 my ($self,$e) = @_;
298              
299             return 0 if ! defined $self->{'_lastitem'} ||
300 24292 50 33     63274 ! defined $self->{'_lastitem'}->{'current'}->[-1];
301 24292         57395 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 8309     8309 1 11376 my ($self,$e) = @_;
319 8309         17025 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 8183     8183 1 12156 my ($self,$ch) = @_;
335 8183 50       13152 if( $self->within_element('node') ) {
336 8183         8743 my $hash = pop @{$self->{'_currentitems'}};
  8183         12679  
337 8183 100       13424 if( $self->in_element('bootstrap') ) {
    100          
    100          
    50          
    100          
    50          
    0          
338             # leading/trailing Whitespace-B-Gone
339 8         32 $ch =~ s/^\s+//; $ch =~ s/\s+$//;
  8         42  
340 8         27 $hash->{'-bootstrap'} = $ch;
341             } elsif( $self->in_element('branch_length') ) {
342             # leading/trailing Whitespace-B-Gone
343 4131         9396 $ch =~ s/^\s+//; $ch =~ s/\s+$//;
  4131         7981  
344 4131         7369 $hash->{'-branch_length'} = $ch;
345             } elsif( $self->in_element('id') ) {
346 2488         4939 $hash->{'-id'} = $ch;
347             } elsif( $self->in_element('description') ) {
348 0         0 $hash->{'-desc'} = $ch;
349             } elsif ( $self->in_element('tag_name') ) {
350 778         1521 $hash->{'-NHXtagname'} = $ch;
351             } elsif ( $self->in_element('tag_value') ) {
352 778         1956 $hash->{'-nhx'}->{$hash->{'-NHXtagname'}} = $ch;
353 778         1293 delete $hash->{'-NHXtagname'};
354             } elsif( $self->in_element('leaf') ) {
355 0         0 $hash->{'-leaf'} = $ch;
356             }
357 8183         11651 push @{$self->{'_currentitems'}}, $hash;
  8183         12800  
358             }
359 8183         21698 $self->debug("chars: $ch\n");
360             }
361              
362              
363             1;