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 16     16   60 use strict;
  16         18  
  16         402  
76              
77 16     16   54 use Bio::Event::EventGeneratorI;
  16         14  
  16         360  
78              
79 16     16   46 use base qw(Bio::TreeIO Bio::TreeIO::NewickParser);
  16         16  
  16         5793  
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 1215     1215   1561 my $self = shift;
95 1215         3542 $self->SUPER::_initialize(@_);
96 1215         4241 my ( $print_count ) = $self->_rearrange(
97             [
98             qw(PRINT_COUNT)
99             ],
100             @_
101             );
102 1215   50     6562 $self->print_tree_count( $print_count || 0 );
103 1215         1844 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 155     155 1 2505 my ($self) = @_;
118 155         563 local $/ = ";\n";
119 155 100       413 return unless $_ = $self->_readline;
120              
121 153         662 s/[\r\n]//gs;
122 153         139 my $score;
123 153     0   605 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 153         306 };
129 153         272 s/([^"]*)(".+?")([^"]*)/$despace->($1) . $dequote->($2) . $despace->($3)/egsx;
  0         0  
130              
131 153 100       426 if (s/^\s*\[([^\]]+)\]//) {
132 2         5 my $match = $1;
133 2         7 $match =~ s/\s//g;
134 2         4 $match =~ s/lh\=//;
135 2 50       8 if ( $match =~ /([-\d\.+]+)/ ) {
136 2         4 $score = $1;
137             }
138             }
139              
140 153         397 $self->_eventHandler->start_document;
141              
142             # Call the parse_newick method as defined in NewickParser.pm
143 153         447 $self->parse_newick($_);
144              
145 153         282 my $tree = $self->_eventHandler->end_document;
146              
147             # Add the tree score afterwards if it exists.
148 153 50       663 if (defined $tree) {
149 153         372 $tree->score($score);
150 153         1580 return $tree;
151             }
152             }
153              
154             # Returns the default set of parsing & writing parameters for the Newick format.
155             sub get_default_params {
156 1215     1215 0 1385 my $self = shift;
157              
158             return {
159 1215         9478 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 1076     1076 1 1559 my ( $self, @trees ) = @_;
183 1076 50       1778 if ( $self->print_tree_count ) {
184 0         0 $self->_print( sprintf( " %d\n", scalar @trees ) );
185             }
186              
187 1076         2163 my $params = $self->get_params;
188              
189 1076         1785 foreach my $tree (@trees) {
190 1076 50 33     9519 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 1076         2581 my @data = $self->_write_tree_Helper( $tree->get_root_node, $params);
198 1076         4867 $self->_print( join( ',', @data ).";" );
199             }
200            
201 1076 50 33     2436 $self->flush if $self->_flush_on_write && defined $self->_fh;
202 1076         1737 return;
203             }
204              
205             sub _write_tree_Helper {
206 5965     5965   4495 my $self = shift;
207 5965         4894 my ( $node, $params ) = @_;
208 5965         3940 my @data;
209              
210 5965         9871 foreach my $n ( $node->each_Descendent($params->{order_by}) ) {
211 4889         7748 push @data, $self->_write_tree_Helper( $n, $params );
212             }
213              
214 5965         10324 my $label = $self->_node_as_string($node,$params);
215              
216 5965 100       8749 if ( scalar(@data) >= 1) {
217 2425         3235 $data[0] = "(" . $data[0];
218 2425         2224 $data[-1] .= ")";
219 2425         2467 $data[-1] .= $label;
220             } else {
221 3540         3739 push @data, $label;
222             }
223              
224 5965         11031 return @data;
225             }
226              
227             sub _node_as_string {
228 5965     5965   4518 my $self = shift;
229 5965         4116 my $node = shift;
230 5965         3802 my $params = shift;
231              
232 5965         4918 my $label_stringbuffer = '';
233              
234 5965 100 66     14287 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         7 my $bootstrap = $node->bootstrap;
242 5 50       10 $label_stringbuffer .= $bootstrap if (defined $bootstrap);
243             } elsif ($params->{no_internal_node_labels} != 1) {
244 5960         8410 my $id = $node->id;
245 5960 100       10235 $label_stringbuffer .= $id if( defined $id );
246             }
247              
248 5965 50       9255 if ($params->{no_branch_lengths} != 1) {
249 5965         7959 my $blen = $node->branch_length;
250 5965 100       22097 $label_stringbuffer .= ":". $blen if (defined $blen);
251             }
252              
253 5965 50       9149 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 5965 50       7924 if ($params->{newline_each_node} == 1) {
259 0         0 $label_stringbuffer .= "\n";
260             }
261              
262 5965         7531 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 2291     2291 1 2272 my $self = shift;
278 2291 100       5392 return $self->{'_print_tree_count'} = shift if @_;
279 1076   50     4779 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;