File Coverage

blib/lib/Bio/NEXUS/TaxaBlock.pm
Criterion Covered Total %
statement 78 93 83.8
branch 11 20 55.0
condition 3 5 60.0
subroutine 16 17 94.1
pod 6 6 100.0
total 114 141 80.8


line stmt bran cond sub pod time code
1             ######################################################
2             # TaxaBlock.pm
3             ######################################################
4             # original version thanks to Chengzhi, Weigang, Eugene, Peter and Tom
5             # $Id: TaxaBlock.pm,v 1.45 2012/02/07 21:38:09 astoltzfus Exp $
6              
7             #################### START POD DOCUMENTATION ##################
8              
9             =head1 NAME
10              
11             Bio::NEXUS::TaxaBlock - Represents TAXA block of a NEXUS file
12              
13             =head1 SYNOPSIS
14              
15             if ( $type =~ /taxa/i ) {
16             $block_object = new Bio::NEXUS::TaxaBlock($type, $block, $verbose);
17             }
18              
19             =head1 DESCRIPTION
20              
21             If a NEXUS block is a taxa block, this module parses the block and stores the taxonomic data.
22              
23             =head1 FEEDBACK
24              
25             All feedback (bugs, feature enhancements, etc.) are greatly appreciated.
26              
27             =head1 VERSION
28              
29             $Id: TaxaBlock.pm,v 1.45 2012/02/07 21:38:09 astoltzfus Exp $
30              
31             =head1 METHODS
32              
33             =cut
34              
35             package Bio::NEXUS::TaxaBlock;
36              
37 34     34   231 use strict;
  34         72  
  34         1270  
38 34     34   191 use Bio::NEXUS::Functions;
  34         66  
  34         7753  
39 34     34   194 use Bio::NEXUS::Node;
  34         83  
  34         735  
40 34     34   204 use Bio::NEXUS::Block;
  34         74  
  34         760  
41 34     34   192 use Bio::NEXUS::TaxUnit;
  34         67  
  34         899  
42 34     34   177 use Bio::NEXUS::Util::Logger;
  34         74  
  34         848  
43 34     34   195 use Bio::NEXUS::Util::Exceptions 'throw';
  34         94  
  34         2037  
44 34     34   187 use vars qw(@ISA $VERSION $AUTOLOAD);
  34         68  
  34         2047  
45 34     34   215 use Bio::NEXUS; $VERSION = $Bio::NEXUS::VERSION;
  34         71  
  34         36494  
46              
47             @ISA = qw(Bio::NEXUS::Block);
48             my $logger = Bio::NEXUS::Util::Logger->new();
49              
50             =head2 new
51              
52             Title : new
53             Usage : block_object = new Bio::NEXUS::TaxaBlock($block_type, $commands, $verbose);
54             Function: Creates a new Bio::NEXUS::TaxaBlock object
55             Returns : Bio::NEXUS::TaxaBlock object
56             Args : type (string), the commands/comments to parse (array ref), and a verbose flag (0 or 1; optional)
57              
58             =cut
59              
60             sub new {
61 86     86 1 449 my ( $class, $type, $commands, $verbose ) = @_;
62 86 50       276 if ( not $type ) {
63 0         0 ( $type = lc $class ) =~ s/Bio::NEXUS::(.+)Block/$1/i;
64             }
65 86         365 my $self = {
66             'type' => $type,
67             };
68 86         285 bless $self, $class;
69 86 100 66     621 if ( defined $commands and @$commands ) {
70 79         3926 $self->_parse_block( $commands, $verbose );
71             }
72 85         294 return $self;
73             }
74              
75             =head2 is_taxon
76              
77             Title : is_taxon
78             Usage : $block->is_taxon($query_taxonlabel);
79             Function: Validates OTU names/taxlabels
80             Returns : Returns taxlabel if true, undef if false
81             Args : Query taxon label
82              
83             =cut
84              
85             sub is_taxon {
86 0     0 1 0 my ( $self, $query_taxon, $verbose ) = @_;
87 0         0 my $taxlabels = $self->get_taxlabels();
88 0         0 for my $taxlabel (@$taxlabels) {
89 0 0       0 if ( $taxlabel eq $query_taxon ) { return $taxlabel }
  0         0  
90             }
91 0         0 $logger->info("$query_taxon is not a valid OTU name");
92 0         0 return undef;
93             }
94              
95             =head2 get_ntax
96              
97             Title : get_ntax
98             Usage : $block->get_ntax();
99             Function: Returns the dimensions (that is, ntax) of the block
100             Returns : dimensions (integer)
101             Args : none
102              
103             =cut
104              
105             sub get_ntax {
106 5     5 1 983 my ($self) = @_;
107 5         8 return scalar @{ $self->get_taxlabels() };
  5         20  
108             }
109              
110             =head2 rename_otus
111              
112             Title : rename_otus
113             Usage : $block->rename_otus(\%translation);
114             Function: Renames all the OTUs to something else
115             Returns : none
116             Args : hash containing translation
117              
118             =cut
119              
120             sub rename_otus {
121 2     2 1 5 my ( $self, $translate ) = @_;
122 2         9 my $taxlabels = $self->get_taxlabels();
123 2         4 my $newtaxlabels;
124 2         5 for my $taxlabel (@$taxlabels) {
125 8 100       20 $taxlabel = $$translate{$taxlabel} if $$translate{$taxlabel};
126 8         20 push( @$newtaxlabels, $taxlabel );
127             }
128 2         11 $self->set_taxlabels($newtaxlabels);
129             }
130              
131             =head2 add_otu_clone
132              
133             Title : add_otu_clone
134             Usage : ...
135             Function: ...
136             Returns : ...
137             Args : ...
138              
139             =cut
140              
141             sub add_otu_clone {
142             # todo:
143             # rename the method
144 7     7 1 14 my ( $self, $original_otu_name, $copy_otu_name ) = @_;
145             # print "Warning: Bio::NEXUS::TaxaBlock::add_otu_clone() method not fully implemented\n";
146            
147 7 50       28 if (defined $self->{'dimensions'}{'ntax'}) {
148 7         18 $self->{'dimensions'}{'ntax'}++;
149             }
150             else {
151             # the execution should never reach this point,
152             # b/c if an OTU is being cloned, ntax should
153             # be > or = '1'
154 0         0 throw 'BadArgs' => "add_otu_clone(): at least 1 otu exists, but 'ntax' is not initialized";
155             }
156 7         40 $self->add_taxlabel($copy_otu_name);
157             }
158              
159             =head2 equals
160              
161             Name : equals
162             Usage : $taxa->equals($another);
163             Function: compare if two Bio::NEXUS::TaxaBlock objects are equal
164             Returns : boolean
165             Args : a Bio::NEXUS::TaxaBlock object
166              
167             =cut
168              
169             sub equals {
170 2     2 1 12 my ( $self, $block ) = @_;
171 2 50       35 if ( ! $self->SUPER::equals( $block ) ) {
172 0         0 return 0;
173             }
174            
175 2         3 my @labels1 = @{ $self->get_taxlabels() };
  2         10  
176 2         5 my @labels2 = @{ $block->get_taxlabels() };
  2         9  
177 2 50       11 if ( @labels1 != @labels2 ) { return 0; }
  0         0  
178 2         14 @labels1 = sort { $a cmp $b } @labels1;
  24         32  
179 2         6 @labels2 = sort { $a cmp $b } @labels2;
  24         26  
180 2         32 for my $i ( 0 .. $#labels1 ) {
181 16 50       60 if ( $labels1[$i] ne $labels2[$i] ) {
182 0         0 return 0;
183             }
184             }
185 2         21 return 1;
186             }
187              
188             =begin comment
189              
190             Name : _write
191             Usage : $taxa->_write($filehandle, $verbose);
192             Function: Writes NEXUS block from stored data
193             Returns : none
194             Args : none
195              
196             =end comment
197              
198             =cut
199              
200             sub _write {
201 2     2   4 my ( $self, $fh, $verbose ) = @_;
202 2   50     6 $fh ||= \*STDOUT;
203              
204 2         10 my $ntax = $self->get_ntax();
205 2         11 $self->SUPER::_write($fh);
206 2         11 print $fh "\tDIMENSIONS ntax=$ntax;\n";
207 2         5 print $fh "\tTAXLABELS ";
208 2         3 for my $OTU ( @{ $self->get_taxlabels() } ) {
  2         4  
209 12         25 $OTU = _nexus_formatted($OTU);
210 12         30 print $fh " $OTU";
211             }
212 2         7 print $fh ";\nEND;\n";
213             }
214              
215             sub AUTOLOAD {
216 1 50   1   4 return if $AUTOLOAD =~ /DESTROY$/;
217 1         3 my $package_name = __PACKAGE__ . '::';
218              
219             # The following methods are deprecated and are temporarily supported
220             # via a warning and a redirection
221 1         4 my %synonym_for =
222             ( "${package_name}parse_labels" => "${package_name}_parse_taxlabels", );
223              
224 1 50       4 if ( defined $synonym_for{$AUTOLOAD} ) {
225 0         0 $logger->warn("$AUTOLOAD() is deprecated; use $synonym_for{$AUTOLOAD}() instead");
226 0         0 goto &{ $synonym_for{$AUTOLOAD} };
  0         0  
227             }
228             else {
229 1         28 Bio::NEXUS::Util::Exceptions::UnknownMethod->throw(
230             'UnknownMethod' => "ERROR: Unknown method $AUTOLOAD called"
231             );
232             }
233             }
234              
235             1;