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   120 use strict;
  23         166  
  23         511  
75              
76 23     23   5132 use Bio::Tree::Tree;
  23         38  
  23         512  
77 23     23   5993 use Bio::Tree::Node;
  23         32  
  23         637  
78              
79 23     23   95 use base qw(Bio::Root::Root Bio::Event::EventHandlerI);
  23         26  
  23         7343  
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 701     701 1 1183 my($class,@args) = @_;
94              
95 701         1275 my $self = $class->SUPER::new(@args);
96 701         1768 my ($treetype, $nodetype) = $self->_rearrange([qw(TREETYPE
97             NODETYPE)], @args);
98 701   50     2164 $treetype ||= 'Bio::Tree::Tree';
99 701   100     1627 $nodetype ||= 'Bio::Tree::Node';
100              
101 701         651 eval {
102 701         1277 $self->_load_module($treetype);
103 701         1061 $self->_load_module($nodetype);
104             };
105              
106 701 50       1126 if( $@ ) {
107 0         0 $self->throw("Could not load module $treetype or $nodetype. \n$@\n")
108             }
109 701         1177 $self->treetype($treetype);
110 701         1024 $self->nodetype($nodetype);
111 701         671 $self->{'_treelevel'} = 0;
112 701         2198 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 854     854 1 934 my ($self,$value) = @_;
128 854 100       1392 if( defined $value) {
129 701         872 $self->{'treetype'} = $value;
130             }
131 854         1111 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 5552     5552 1 4872 my ($self,$value) = @_;
147 5552 100       7439 if( defined $value) {
148 701         802 $self->{'nodetype'} = $value;
149             }
150 5552         10934 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 156 my ($self) = @_;
170 153         250 $self->{'_lastitem'} = {};
171 153         241 $self->{'_currentitems'} = [];
172 153         193 $self->{'_currentnodes'} = [];
173 153         195 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 161 my ($self,$label) = @_;
188              
189 153         141 my ($root) = @{$self->{'_currentnodes'}};
  153         247  
190              
191 153         337 $self->debug("Root node is " . $root->to_string()."\n");
192 153 50       287 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         327 my $tree = $self->treetype->new(-verbose => $self->verbose,
198             -root => $root);
199 153         262 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 10643 my ($self,$data) =@_;
215 14003         14045 $self->{'_lastitem'}->{$data->{'Name'}}++;
216              
217 14003         25856 $self->debug("starting element: $data->{Name}\n");
218 14003         11661 push @{$self->{'_lastitem'}->{'current'}},$data->{'Name'};
  14003         19145  
219            
220 14003         10238 my %data;
221            
222 14003 100       30443 if( $data->{'Name'} eq 'node' ) {
    100          
223 4851         3095 push @{$self->{'_currentitems'}}, \%data;
  4851         5379  
224 4851         7929 $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 10845 my ($self,$data) = @_;
241              
242 14003         23429 $self->debug("end of element: $data->{Name}\n");
243             # this is the stack where we push/pop items from it
244 14003         10561 my $curcount = scalar @{$self->{'_currentnodes'}};
  14003         13926  
245 14003         11154 my $level = $self->{'_treelevel'};
246 14003   100     30631 my $levelct = $self->{'_nodect'}->[$self->{'_treelevel'}+1] || 0;
247              
248 14003 100       23179 if( $data->{'Name'} eq 'node' ) {
    100          
249 4851         3394 my $tnode;
250 4851         3038 my $node = pop @{$self->{'_currentitems'}};
  4851         5391  
251              
252             $tnode = $self->nodetype->new( -verbose => $self->verbose,
253 4851         7090 %{$node});
  4851         16539  
254 4851         9709 $self->debug( "new node will be ".$tnode->to_string."\n");
255 4851 100 66     16076 if ( !$node->{'-leaf'} && $levelct > 0) {
256 13068         15267 $self->debug(join(',', map { $_->to_string }
257 2308         1992 @{$self->{'_currentnodes'}}). "\n");
  2308         3072  
258 2308 50       4294 $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         1713 for ( splice( @{$self->{'_currentnodes'}}, - $levelct)) {
  2308         4937  
263 4698         6390 $self->debug("adding desc: " . $_->to_string . "\n");
264 4698         8336 $tnode->add_Descendent($_);
265             }
266 2308         3533 $self->{'_nodect'}->[$self->{'_treelevel'}+1] = 0;
267             }
268 4851         3357 push @{$self->{'_currentnodes'}}, $tnode;
  4851         5887  
269 4851         5618 $self->{'_nodect'}->[$self->{'_treelevel'}]++;
270            
271 4851         3361 $curcount = scalar @{$self->{'_currentnodes'}};
  4851         4561  
272 4851         10954 $self->debug ("added node: count is now $curcount, treelevel: $level, nodect: $levelct\n");
273              
274 4851         8267 $self->{'_treelevel'}--;
275             } elsif( $data->{'Name'} eq 'tree' ) {
276 153         355 $self->debug("end of tree: nodes in stack is $curcount\n");
277             }
278              
279 14003         14783 $self->{'_lastitem'}->{ $data->{'Name'} }--;
280 14003         8625 pop @{$self->{'_lastitem'}->{'current'}};
  14003         25086  
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 18027 my ($self,$e) = @_;
298              
299             return 0 if ! defined $self->{'_lastitem'} ||
300 25112 50 33     50723 ! defined $self->{'_lastitem'}->{'current'}->[-1];
301 25112         43716 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 6402 my ($self,$e) = @_;
319 8674         14044 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 7344 my ($self,$ch) = @_;
335 8521 50       9721 if( $self->within_element('node') ) {
336 8521         5475 my $hash = pop @{$self->{'_currentitems'}};
  8521         9258  
337 8521 100       10073 if( $self->in_element('bootstrap') ) {
    100          
    100          
    50          
    100          
    50          
    0          
338             # leading/trailing Whitespace-B-Gone
339 8         15 $ch =~ s/^\s+//; $ch =~ s/\s+$//;
  8         12  
340 8         11 $hash->{'-bootstrap'} = $ch;
341             } elsif( $self->in_element('branch_length') ) {
342             # leading/trailing Whitespace-B-Gone
343 4325         6450 $ch =~ s/^\s+//; $ch =~ s/\s+$//;
  4325         5347  
344 4325         5657 $hash->{'-branch_length'} = $ch;
345             } elsif( $self->in_element('id') ) {
346 2632         3452 $hash->{'-id'} = $ch;
347             } elsif( $self->in_element('description') ) {
348 0         0 $hash->{'-desc'} = $ch;
349             } elsif ( $self->in_element('tag_name') ) {
350 778         953 $hash->{'-NHXtagname'} = $ch;
351             } elsif ( $self->in_element('tag_value') ) {
352 778         1323 $hash->{'-nhx'}->{$hash->{'-NHXtagname'}} = $ch;
353 778         917 delete $hash->{'-NHXtagname'};
354             } elsif( $self->in_element('leaf') ) {
355 0         0 $hash->{'-leaf'} = $ch;
356             }
357 8521         7812 push @{$self->{'_currentitems'}}, $hash;
  8521         9329  
358             }
359 8521         16277 $self->debug("chars: $ch\n");
360             }
361              
362              
363             1;