3 # BioPerl module for Bio::TreeIO::pag
5 # Cared for by Jason Stajich <jason-at-bioperl-dot-org>
7 # Copyright Jason Stajich
9 # You may distribute this module under the same terms as perl itself
11 # POD documentation - main docs before the code
15 Bio::TreeIO::pag - Bio::TreeIO driver for Pagel format
20 my $in = Bio::TreeIO->new(-format => 'nexus',
21 -file => 't/data/adh.mb_tree.nexus');
23 my $out = Bio::TreeIO->new(-format => 'pag');
24 while( my $tree = $in->next_tree ) {
25 $out->write_tree($tree);
30 Convert a Bio::TreeIO to Pagel format.
31 More information here http://sapc34.rdg.ac.uk/meade/Mark/
37 User feedback is an integral part of the evolution of this and other
38 Bioperl modules. Send your comments and suggestions preferably to
39 the Bioperl mailing list. Your participation is much appreciated.
41 bioperl-l@bioperl.org - General discussion
42 http://bioperl.org/wiki/Mailing_lists - About the mailing lists
46 Report bugs to the Bioperl bug tracking system to help us keep track
47 of the bugs and their resolution. Bug reports can be submitted via
50 http://bugzilla.open-bio.org/
52 =head1 AUTHOR - Jason Stajich
54 Email jason-at-bioperl-dot-org
58 The rest of the documentation details each of the object methods.
59 Internal methods are usually preceded with a _
64 # Let the code begin...
67 package Bio
::TreeIO
::pag
;
70 our $TaxonNameLen = 10;
72 use base
qw(Bio::TreeIO);
77 Usage : my $obj = Bio::TreeIO::pag->new();
78 Function: Builds a new Bio::TreeIO::pag object
79 Returns : an instance of Bio::TreeIO::pag
80 Args : -file/-fh for filename or filehandles
81 -name_length for minimum name length (default = 10)
87 $self->SUPER::_initialize
(@_);
88 my ( $name_length ) = $self->_rearrange(
94 $self->name_length( defined $name_length ?
$name_length : $TaxonNameLen );
101 Function: Write a tree out in Pagel format
102 Some options are only appropriate for bayesianmultistate and
103 the simpler output is only proper for discrete
105 Args : -no_outgroups => (number)
106 -print_header => 0/1 (leave 0 for discrete, 1 for bayesianms)
107 -special_node => special node - not sure what they wanted to do here
108 -keep_outgroup => 0/1 (keep the outgroup node in the output)
109 -outgroup_ancestor => Bio::Tree::Node (if we want to exclude or include the outgroup this is what we operate on)
110 -tree_no => a tree number label - only useful for BayesianMultistate
116 my ($self,$tree,@args) = @_;
123 my $name_len = $self->name_length;
130 $keep_outgroup) = $self->_rearrange([qw(
137 NAME_LENGTH)],@args);
139 my $newname_base = 1;
141 my $root = $tree->get_root_node;
144 my @nodes = $tree->get_nodes;
147 for my $node ( @nodes ) {
148 if ((defined $special_node) && ($node eq $special_node)) {
149 my $no_of_tree_nodes = scalar(@nodes);
150 my $node_name = sprintf("N%d",$no_of_tree_nodes+1);
151 $names{$node->internal_id} = $node_name;
153 } elsif ($node->is_Leaf) {
156 my $node_name = $node->id;
157 if( length($node_name)> $name_len ) {
158 $self->warn( "Found a taxon name longer than $name_len letters, \n",
159 "name will be abbreviated.\n");
160 $node_name = substr($node_name, 0,$name_len);
162 # $node_name = sprintf("%-".$TaxonNameLen."s",$node_name);
164 $names{$node->internal_id} = $node_name;
165 my @tags = sort $node->get_all_tags;
166 my @charstates = map { ($node->get_tag_values($_))[0] } @tags;
167 $traitct = scalar @charstates unless defined $traitct;
168 $chars{$node->internal_id} = [@charstates];
170 $names{$node->internal_id} = sprintf("N%d", $newname_base++);
174 # generate PAG representation
175 if( $print_header ) {
176 if ($keep_outgroup) {
177 $self->_print(sprintf("%d %d\n",$species_ct,$traitct));
179 $self->_print( sprintf("%d %d\n",$species_ct-$no_outgroups,$traitct));
184 if ($keep_outgroup) {
185 push @ancestors, $root;
187 push @ancestors, ( $root, $outgroup_ancestor);
190 foreach my $node (@nodes) {
192 foreach my $anc (@ancestors) {
193 if ($anc && $node eq $anc) { $i = 1; last }
195 unless ($i > 0) { # root not given in PAG
196 my $current_name = $names{$node->internal_id};
197 my $branch_length_to_output;
198 if ($node->branch_length < $eps) {
199 my $msg_nodename = $current_name;
200 $msg_nodename =~ s/\s+$//;
201 warn( "TREE $tree_no, node \"$msg_nodename\": branch too ",
202 "short (", $node->branch_length, "): increasing length to ",
204 $branch_length_to_output = $eps;
206 $branch_length_to_output = $node->branch_length;
208 my @line = ( $current_name,
209 $names{$node->ancestor->internal_id},
210 $branch_length_to_output);
212 if ($node->is_Leaf) {
213 push @line, @
{$chars{$node->internal_id}};
214 $self->_print(join(',', @line),"\n");
221 $self->_print(join(',', @
$_),"\n");
238 my ($self,@args) = @_;
239 $self->throw_not_implemented();
245 Usage : $self->name_length(20);
246 Function: set mininum taxon name length
247 Returns : integer (length of name)
253 my ($self, $val) = @_;
254 return $self->{'name_len'} = $val if $val;
255 return $self->{'name_len'};