File Coverage

Bio/TreeIO/newick.pm
Criterion Covered Total %
statement 75 97 77.3
branch 24 42 57.1
condition 15 27 55.5
subroutine 10 14 71.4
pod 5 6 83.3
total 129 186 69.3


line stmt bran cond sub pod time code
1             #
2             # BioPerl module for Bio::TreeIO::newick
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::newick
17              
18             =head1 SYNOPSIS
19              
20             # do not use this module directly
21             use Bio::TreeIO;
22              
23             my $treeio = Bio::TreeIO->new(-format => 'newick',
24             -file => 't/data/LOAD_Ccd1.dnd');
25             my $tree = $treeio->next_tree;
26              
27             =head1 DESCRIPTION
28              
29             This module handles parsing and writing of Newick/PHYLIP/New Hampshire format.
30              
31             =head1 FEEDBACK
32              
33             =head2 Mailing Lists
34              
35             User feedback is an integral part of the evolution of this and other
36             Bioperl modules. Send your comments and suggestions preferably to the
37             Bioperl mailing list. Your participation is much appreciated.
38              
39             bioperl-l@bioperl.org - General discussion
40             http://bioperl.org/wiki/Mailing_lists - About the mailing lists
41              
42             =head2 Support
43              
44             Please direct usage questions or support issues to the mailing list:
45              
46             I
47              
48             rather than to the module maintainer directly. Many experienced and
49             reponsive experts will be able look at the problem and quickly
50             address it. Please include a thorough description of the problem
51             with code and data examples if at all possible.
52              
53             =head2 Reporting Bugs
54              
55             Report bugs to the Bioperl bug tracking system to help us keep track
56             of the bugs and their resolution. Bug reports can be submitted via the
57             web:
58              
59             https://github.com/bioperl/bioperl-live/issues
60              
61             =head1 AUTHOR - Jason Stajich
62              
63             Email jason-at-bioperl-dot-org
64              
65             =head1 APPENDIX
66              
67             The rest of the documentation details each of the object methods.
68             Internal methods are usually preceded with a _
69              
70             =cut
71              
72             # Let the code begin...
73              
74             package Bio::TreeIO::newick;
75 15     15   88 use strict;
  15         26  
  15         411  
76              
77 15     15   66 use Bio::Event::EventGeneratorI;
  15         22  
  15         410  
78              
79 15     15   72 use base qw(Bio::TreeIO Bio::TreeIO::NewickParser);
  15         25  
  15         4900  
80              
81             =head2 new
82              
83             Title : new
84             Args : -print_count => boolean default is false
85             -bootstrap_style => set the bootstrap style (one of nobranchlength,
86             molphy, traditional)
87             -order_by => set the order by sort method
88              
89             See L
90              
91             =cut
92              
93             sub _initialize {
94 639     639   1121 my $self = shift;
95 639         2741 $self->SUPER::_initialize(@_);
96 639         2660 my ( $print_count ) = $self->_rearrange(
97             [
98             qw(PRINT_COUNT)
99             ],
100             @_
101             );
102 639   50     4124 $self->print_tree_count( $print_count || 0 );
103 639         1332 return;
104             }
105              
106             =head2 next_tree
107              
108             Title : next_tree
109             Usage : my $tree = $treeio->next_tree
110             Function: Gets the next tree in the stream
111             Returns : L
112             Args : none
113              
114             =cut
115              
116             sub next_tree {
117 128     128 1 2526 my ($self) = @_;
118 128         677 local $/ = ";\n";
119 128 100       518 return unless $_ = $self->_readline;
120              
121 126         827 s/[\r\n]//gs;
122 126         202 my $score;
123 126     0   683 my $despace = sub { my $dirty = shift; $dirty =~ s/\s+//gs; return $dirty };
  0         0  
  0         0  
  0         0  
124             my $dequote = sub {
125 0     0   0 my $dirty = shift;
126 0         0 $dirty =~ s/^"?\s*(.+?)\s*"?$/$1/;
127 0         0 return $dirty;
128 126         399 };
129 126         307 s/([^"]*)(".+?")([^"]*)/$despace->($1) . $dequote->($2) . $despace->($3)/egsx;
  0         0  
130              
131 126 100       471 if (s/^\s*\[([^\]]+)\]//) {
132 2         8 my $match = $1;
133 2         14 $match =~ s/\s//g;
134 2         8 $match =~ s/lh\=//;
135 2 50       13 if ( $match =~ /([-\d\.+]+)/ ) {
136 2         7 $score = $1;
137             }
138             }
139              
140 126         464 $self->_eventHandler->start_document;
141              
142             # Call the parse_newick method as defined in NewickParser.pm
143 126         648 $self->parse_newick($_);
144              
145 126         344 my $tree = $self->_eventHandler->end_document;
146              
147             # Add the tree score afterwards if it exists.
148 126 50       421 if (defined $tree) {
149 126         477 $tree->score($score);
150 126         2058 return $tree;
151             }
152             }
153              
154             # Returns the default set of parsing & writing parameters for the Newick format.
155             sub get_default_params {
156 639     639 0 1103 my $self = shift;
157              
158             return {
159 639         5905 newline_each_node => 0,
160             order_by => '', # ???
161             bootstrap_style => 'traditional', # Can be 'traditional', 'molphy', 'nobranchlength'
162             internal_node_id => 'id', # Can be 'id' or 'bootstrap'
163            
164             no_branch_lengths => 0,
165             no_bootstrap_values => 0,
166             no_internal_node_labels => 0
167             };
168             }
169              
170              
171             =head2 write_tree
172              
173             Title : write_tree
174             Usage : $treeio->write_tree($tree);
175             Function: Write a tree out to data stream in newick/phylip format
176             Returns : none
177             Args : L object
178              
179             =cut
180              
181             sub write_tree {
182 527     527 1 1465 my ( $self, @trees ) = @_;
183 527 50       1191 if ( $self->print_tree_count ) {
184 0         0 $self->_print( sprintf( " %d\n", scalar @trees ) );
185             }
186              
187 527         1376 my $params = $self->get_params;
188              
189 527         1183 foreach my $tree (@trees) {
190 527 50 33     5223 if ( !defined $tree
      33        
191             || ref($tree) =~ /ARRAY/i
192             || !$tree->isa('Bio::Tree::TreeI') )
193             {
194 0         0 $self->throw(
195             "Calling write_tree with non Bio::Tree::TreeI object\n");
196             }
197 527         1943 my @data = $self->_write_tree_Helper( $tree->get_root_node, $params);
198 527         3460 $self->_print( join( ',', @data ).";" );
199             }
200            
201 527 50 33     1416 $self->flush if $self->_flush_on_write && defined $self->_fh;
202 527         1155 return;
203             }
204              
205             sub _write_tree_Helper {
206 3220     3220   3879 my $self = shift;
207 3220         4497 my ( $node, $params ) = @_;
208 3220         3503 my @data;
209              
210 3220         7249 foreach my $n ( $node->each_Descendent($params->{order_by}) ) {
211 2693         6000 push @data, $self->_write_tree_Helper( $n, $params );
212             }
213              
214 3220         6503 my $label = $self->_node_as_string($node,$params);
215              
216 3220 100       5887 if ( scalar(@data) >= 1) {
217 1327         3114 $data[0] = "(" . $data[0];
218 1327         1792 $data[-1] .= ")";
219 1327         1955 $data[-1] .= $label;
220             } else {
221 1893         2761 push @data, $label;
222             }
223              
224 3220         7813 return @data;
225             }
226              
227             sub _node_as_string {
228 3220     3220   3755 my $self = shift;
229 3220         3297 my $node = shift;
230 3220         3182 my $params = shift;
231              
232 3220         3930 my $label_stringbuffer = '';
233              
234 3220 100 66     9260 if ($params->{no_bootstrap_values} != 1 &&
    50 100        
      66        
      100        
235             !$node->is_Leaf &&
236             defined $node->bootstrap &&
237             $params->{bootstrap_style} eq 'traditional' &&
238             $params->{internal_node_id} eq 'bootstrap') {
239             # If we're an internal node and we're using 'traditional' bootstrap style,
240             # we output the bootstrap instead of any label.
241 5         9 my $bootstrap = $node->bootstrap;
242 5 50       9 $label_stringbuffer .= $bootstrap if (defined $bootstrap);
243             } elsif ($params->{no_internal_node_labels} != 1) {
244 3215         6212 my $id = $node->id;
245 3215 100       7123 $label_stringbuffer .= $id if( defined $id );
246             }
247              
248 3220 50       6165 if ($params->{no_branch_lengths} != 1) {
249 3220         6151 my $blen = $node->branch_length;
250 3220 100       12059 $label_stringbuffer .= ":". $blen if (defined $blen);
251             }
252              
253 3220 50       6082 if ($params->{bootstrap_style} eq 'molphy') {
254 0         0 my $bootstrap = $node->bootstrap;
255 0 0       0 $label_stringbuffer .= "[$bootstrap]" if (defined $bootstrap);
256             }
257              
258 3220 50       5025 if ($params->{newline_each_node} == 1) {
259 0         0 $label_stringbuffer .= "\n";
260             }
261              
262 3220         5494 return $label_stringbuffer;
263             }
264              
265              
266             =head2 print_tree_count
267              
268             Title : print_tree_count
269             Usage : $obj->print_tree_count($newval)
270             Function: Get/Set flag for printing out the tree count (paml,protml way)
271             Returns : value of print_tree_count (a scalar)
272             Args : on set, new value (a scalar or undef, optional)
273              
274             =cut
275              
276             sub print_tree_count {
277 1166     1166 1 1835 my $self = shift;
278 1166 100       2907 return $self->{'_print_tree_count'} = shift if @_;
279 527   50     2512 return $self->{'_print_tree_count'} || 0;
280             }
281              
282             =head2 bootstrap_style
283              
284             Title : bootstrap_style
285             Usage : $obj->bootstrap_style($newval)
286             Function: A description of how bootstraps and branch lengths are
287             written, as the ID part of the internal node or else in []
288             in the branch length (Molphy-like; I am sure there is a
289             better name for this but am not sure where to go for some
290             sort of format documentation)
291              
292             If no branch lengths are requested then no bootstraps are usually
293             written (unless someone REALLY wants this functionality...)
294              
295             Can take on strings which contain the possible values of
296             'nobranchlength' --> don't draw any branch lengths - this
297             is helpful if you don't want to have to
298             go through and delete branch len on all nodes
299             'molphy' --> draw bootstraps (100) like
300             (A:0.11,B:0.22):0.33[100];
301             'traditional' --> draw bootstraps (100) like
302             (A:0.11,B:0.22)100:0.33;
303             Returns : value of bootstrap_style (a scalar)
304             Args : on set, new value (a scalar or undef, optional)
305              
306             =cut
307              
308             sub bootstrap_style {
309 0     0 1   my $self = shift;
310 0           my $val = shift;
311 0 0         if ( defined $val ) {
312              
313 0 0         if ( $val !~ /^nobranchlength|molphy|traditional/i ) {
314 0           $self->warn(
315             "requested an unknown bootstrap style $val, expect one of nobranchlength,molphy,traditional, not updating value.\n"
316             );
317             }
318             else {
319 0           $self->{'_bootstrap_style'} = $val;
320             }
321             }
322 0   0       return $self->{'_bootstrap_style'} || 'traditional';
323             }
324              
325             =head2 order_by
326              
327             Title : order_by
328             Usage : $obj->order_by($newval)
329             Function: Allow node order to be specified (typically "alpha")
330             See L
331             Returns : value of order_by (a scalar)
332             Args : on set, new value (a scalar or undef, optional)
333              
334             =cut
335              
336             sub order_by {
337 0     0 1   my $self = shift;
338              
339 0 0         return $self->{'order_by'} = shift if @_;
340 0           return $self->{'order_by'};
341             }
342              
343             1;