69
63
package Bio::TreeIO::nexus;
74
66
use Bio::Event::EventGeneratorI;
77
@ISA = qw(Bio::TreeIO );
69
use base qw(Bio::TreeIO);
74
Args : -header => boolean default is true
75
print/do not print #NEXUS header
76
-translate => boolean default is true
77
print/do not print Node Id translation to a number
83
$self->SUPER::_initialize(@_);
84
my ($hdr,$trans) = $self->_rearrange([qw(HEADER
87
$self->header(defined $hdr ? $hdr : 1 );
88
$self->translate_node(defined $trans ? $trans : 1);
116
128
$self->warn("File does not start with #NEXUS"); #'
121
134
while( defined ( $_ = $self->_readline ) ) {
127
} elsif( /^\s*Translate/ ) {
129
} elsif( $state == 3) {
130
if( /^\s+(\S+)\s+(\S+)\,\s*$/ ) {
135
} elsif( /^tree\s+(\S+)\s+\=\s+(?:\[\S+\])?\s+(.+\;)\s*$/ ) {
136
my $buf = new IO::String($2);
137
my $treeio = new Bio::TreeIO(-format => 'newick',
139
my $tree = $treeio->next_tree;
140
foreach my $node ( grep { $_->is_Leaf } $tree->get_nodes ) {
142
my $lookup = $translate{$id};
143
$node->id($lookup || $id);
145
push @{$self->{'_trees'}},$tree;
147
} elsif( /^\s*Begin\s+trees;/i ) {
149
} elsif( /^\s*End(\s+trees);/i ) {
138
my @sections = split(/#NEXUS/i, $line);
139
for my $s ( @sections ) {
140
if( $self->verbose > 0 ) {
141
while( $s =~ s/(\[[^\]]+\])// ) {
142
$self->debug("removing comment $1\n");
145
$s =~ s/(\[[^\]]+\])//g;
147
if( $s =~ /begin trees;(.+)(end;)?/i ) {
149
if( $trees =~ s/\s+translate\s+([^;]+);//i ) {
151
for my $n ( split(/\s*,\s*/,$trans) ) {
152
my ($id,$tag) = split(/\s+/,$n);
153
$translate{$id} = $tag;
156
$self->debug("no translate in: $trees\n");
158
while( $trees =~ /\s+tree\s+(\S+)\s*\=
159
\s*(?:\[\S+\])?\s*([^\;]+;)\s*/igx) {
160
my ($tree_name,$tree_str) = ($1,$2);
162
# MrBayes does not print colons for node label
163
# $tree_str =~ s/\)(\d*\.\d+)\)/:$1/g;
164
my $buf = new IO::String($tree_str);
165
my $treeio = new Bio::TreeIO(-format => 'newick',
167
my $tree = $treeio->next_tree;
168
foreach my $node ( grep { $_->is_Leaf } $tree->get_nodes ) {
170
my $lookup = $translate{$id};
171
$node->id($lookup || $id);
173
$tree->id($tree_name) if defined $tree_name;
174
push @{$self->{'_trees'}},$tree;
177
$self->debug("begin_trees failed: $s\n");
181
$self->debug("warn no sections: $line\n");
169
my ($self,$tree) = @_;
170
$self->throw("Cannot call method write_tree on Bio::TreeIO object must use a subclass");
198
my ($self,@trees) = @_;
199
if ( $self->header ) {
200
$self->_print("#NEXUS\n\n");
202
my $translate = $self->translate_node;
203
my $time = localtime();
204
$self->_print(sprintf("Begin trees; [Treefile created %s]\n",$time));
206
my ($first,$nodecter,%node2num) = (0,1);
207
foreach my $tree ( @trees ) {
211
$self->_print("\tTranslate\n");
212
$self->_print(join(",\n",
213
map { $node2num{$_->id} = $nodecter;
214
sprintf("\t\t%d %s",$nodecter++,$_->id) }
215
grep { $_->is_Leaf } $tree->get_nodes),
218
my @data = _write_tree_Helper($tree->get_root_node,\%node2num);
219
if($data[-1] !~ /\)$/ ) {
220
$data[0] = "(".$data[0];
223
# by default all trees in bioperl are currently rooted
224
# something we'll try and fix one day....
225
$self->_print(sprintf("\t tree %s = [&%s] %s;\n",
227
sprintf("Bioperl_%d",$first+1)),
228
( $tree->get_root_node ) ? 'R' : 'U',
232
$self->_print("End;\n");
233
$self->flush if $self->_flush_on_write && defined $self->_fh;
237
sub _write_tree_Helper {
238
my ($node,$node2num) = @_;
239
return () if (!defined $node);
242
foreach my $n ( $node->each_Descendent() ) {
243
push @data, _write_tree_Helper($n,$node2num);
246
$data[0] = "(" . $data[0];
248
# let's explicitly write out the bootstrap if we've got it
251
my $bl = $node->branch_length;
252
if( ! defined $bl ) {
253
} elsif($bl =~ /\#/ ) {
258
if( defined ($b = $node->bootstrap) ) {
259
$data[-1] .= sprintf("[%s]",$b);
260
} elsif( defined ($b = $node->id) ) {
261
$b = $node2num->{$b} if( $node2num->{$b} ); # translate node2num
262
$data[-1] .= sprintf("[%s]",$b);
266
if( defined $node->id || defined $node->branch_length ) {
267
my $id= defined $node->id ? $node->id : '';
268
if( length($id) && $node2num->{$id} ) {
269
$id = $node2num->{$id};
271
push @data, sprintf("%s%s",$id,
272
defined $node->branch_length ? ":" .
273
$node->branch_length : '');
282
Usage : $obj->header($newval)
285
Returns : value of header (a scalar)
286
Args : on set, new value (a scalar or undef, optional)
294
return $self->{'header'} = shift if @_;
295
return $self->{'header'};
298
=head2 translate_node
300
Title : translate_node
301
Usage : $obj->translate_node($newval)
304
Returns : value of translate_node (a scalar)
305
Args : on set, new value (a scalar or undef, optional)
313
return $self->{'translate_node'} = shift if @_;
314
return $self->{'translate_node'};