File Coverage

blib/lib/Bio/NEXUS/HistoryBlock.pm
Criterion Covered Total %
statement 69 113 61.0
branch 7 24 29.1
condition 1 5 20.0
subroutine 12 17 70.5
pod 4 4 100.0
total 93 163 57.0


line stmt bran cond sub pod time code
1             #######################################################################
2             # HistoryBlock.pm
3             #######################################################################
4             # Author: Chengzhi Liang, Justin Reese, Thomas Hladish
5             # $Id: HistoryBlock.pm,v 1.28 2007/09/21 23:09:09 rvos Exp $
6              
7             #################### START POD DOCUMENTATION ##########################
8              
9             =head1 NAME
10              
11             Bio::NEXUS::HistoryBlock - Represents a HISTORY block of a NEXUS file
12              
13             =head1 SYNOPSIS
14              
15             $block_object = new Bio::NEXUS::HistoryBlock('history', $block, $verbose);
16              
17             =head1 DESCRIPTION
18              
19             This is a class representing a history block in NEXUS file
20              
21             =head1 FEEDBACK
22              
23             All feedback (bugs, feature enhancements, etc.) are greatly appreciated.
24              
25             =head1 AUTHORS
26              
27             Chengzhi Liang (liangc@umbi.umd.edu)
28             Justin Reese
29             Tom Hladish (tjhladish at yahoo)
30              
31             =head1 VERSION
32              
33             $Revision: 1.28 $
34              
35             =head1 METHODS
36              
37             =cut
38              
39             package Bio::NEXUS::HistoryBlock;
40              
41 34     34   209 use strict;
  34         72  
  34         1523  
42             #use Data::Dumper; # XXX this is not used, might as well not import it!
43             #use Carp; # XXX this is not used, might as well not import it!
44 34     34   213 use Bio::NEXUS::Functions;
  34         65  
  34         9595  
45 34     34   228 use Bio::NEXUS::TaxUnitSet;
  34         74  
  34         778  
46 34     34   198 use Bio::NEXUS::Block;
  34         74  
  34         769  
47 34     34   185 use Bio::NEXUS::Node;
  34         77  
  34         708  
48 34     34   247 use Bio::NEXUS::Tree;
  34         80  
  34         1090  
49 34     34   175 use Bio::NEXUS::Util::Logger;
  34         73  
  34         782  
50 34     34   195 use Bio::NEXUS::Util::Exceptions;
  34         68  
  34         1652  
51 34     34   206 use vars qw(@ISA $VERSION $AUTOLOAD);
  34         91  
  34         2416  
52 34     34   188 use Bio::NEXUS; $VERSION = $Bio::NEXUS::VERSION;
  34         64  
  34         39954  
53              
54             @ISA = qw(Bio::NEXUS::CharactersBlock Bio::NEXUS::TreesBlock);
55             my $logger = Bio::NEXUS::Util::Logger->new();
56              
57             =head2 new
58              
59             Title : new
60             Usage : block_object = new Bio::NEXUS::HistoryBlock($block_type, $commands, $verbose);
61             Function: Creates a new Bio::NEXUS::HistoryBlock object
62             Returns : Bio::NEXUS::HistoryBlock object
63             Args : type (string), the commands/comments to parse (array ref), and a verbose flag (0 or 1; optional)
64             Comments:
65              
66             =cut
67              
68             sub new {
69 2     2 1 9 my ( $class, $type, $commands, $verbose ) = @_;
70 2 50       12 if ( not $type ) {
71 0         0 ( $type = lc $class ) =~ s/Bio::NEXUS::(.+)Block/$1/i;
72             }
73 2         10 my $self = {
74             'type' => $type
75             };
76 2         8 bless $self, $class;
77 2         19 $self->{'otuset'} = new Bio::NEXUS::TaxUnitSet();
78 2 50 33     18 if ( ( defined $commands ) and @$commands ) {
79 2         42 $self->_parse_block( $commands, $verbose )
80             }
81 2         13 return $self;
82             }
83              
84             =begin comment
85              
86             Name :_parse_nodelabels
87             Usage : $block->nodelabels($label_text);
88             Function: Parse node labels like taxlabels in taxa block
89             Returns : Labels as the array reference
90             Args : $labels_text as string
91              
92             =end comment
93              
94             =cut
95              
96             sub _parse_nodelabels {
97 0     0   0 my ( $self, $labeltext ) = @_;
98 0         0 my @labels = split( /\s+/, $labeltext );
99 0         0 return \@labels;
100             }
101              
102             =head2 equals
103              
104             Name : equals
105             Usage : $block->equals($another);
106             Function: compare if two Block objects are equal
107             Returns : boolean
108             Args : a Block object
109              
110             =cut
111              
112             sub equals {
113 0     0 1 0 my ( $self, $block ) = @_;
114 0 0       0 if ( !Bio::NEXUS::Block::equals( $self, $block ) ) {
115 0         0 $logger->warn("First equals failed");
116 0         0 return 0;
117             }
118 0         0 my $historytree1 = $self->get_tree();
119 0         0 my $historytree2 = $block->get_tree();
120 0 0       0 if ( !$historytree1->equals($historytree2) ) {
121 0         0 $logger->warn("Trees do not appear to be the same, failing equals");
122 0         0 return 0;
123             }
124              
125             # check otus
126              
127 0 0       0 if ( !$self->get_otuset()->equals( $block->get_otuset() ) ) {
128 0         0 $logger->warn("otusets do not appear to be the same, failing equals");
129 0         0 return 0;
130             }
131              
132 0         0 return 1;
133             }
134              
135             =head2 rename_otus
136              
137             Name : rename_otus
138             Usage : $nexus->rename_otus(\%translation);
139             Function: rename all OTUs
140             Returns : a new nexus object with new OTU names
141             Args : a ref to hash based on OTU name pairs
142              
143             =cut
144              
145             sub rename_otus {
146 0     0 1 0 my ( $self, $translation ) = @_;
147 0         0 for my $parent (@ISA) {
148 0 0       0 if ( my $coderef = $self->can( $parent . "::rename_otus" ) ) {
149 0         0 $self->$coderef($translation);
150             }
151             }
152             }
153              
154             =head2 add_otu_clone
155              
156             Title : add_otu_clone
157             Usage : ...
158             Function: ...
159             Returns : ...
160             Args : ...
161              
162             =cut
163              
164             sub add_otu_clone {
165 2     2 1 5 my ( $self, $original_otu_name, $copy_otu_name ) = @_;
166             # print "Warning: Bio::NEXUS::HistoryBlock::add_otu_clone() method not fully implemented\n";
167             # add the clone to the taxlabels list
168 2         13 $self->add_taxlabel($copy_otu_name);
169              
170             # add the clone to the list
171 2         4 my @otus = @{ $self->{'otuset'}->get_otus() };
  2         10  
172 2         4 for my $otu (@otus) {
173 15 50       27 if (defined $otu) {
174 15 100       32 if ($otu->get_name() eq $original_otu_name) {
175 2         8 my $otu_clone = $otu->clone();
176 2         11 $otu_clone->set_name($copy_otu_name);
177 2         8 $self->{'otuset'}->add_otu($otu_clone);
178             }
179             }
180             }
181            
182             # . iterate through all trees:
183 2         4 for my $tree ( @{ $self->{'blockTrees'} }) {
  2         7  
184             # . find the original node
185             # if not found, something must be done !
186 2         9 my $original_node = $tree->find($original_otu_name);
187 2 50       6 if (! defined $original_node) {
188 0         0 $logger->info("TreesBlock::add_otu_clone(): original otu [$original_otu_name] was not found");
189             }
190             # . clone the node
191 2         8 my $cloned_node = $original_node->clone();
192             # . rename the new node
193 2         9 $cloned_node->set_name($copy_otu_name);
194            
195             # find the parent of the original node, add to it a new
196             # child that will be parent of both original and
197             # clone nodes. Remove the original node from the
198             # list of children of its original parent
199 2         6 my $original_parent = $original_node->get_parent();
200            
201 2         4 for my $child ( @{ $original_parent->get_children() }) {
  2         7  
202             # print "Child name: ", $child->get_name(), "\n";
203 2 50       6 if ($child->get_name() eq $original_otu_name) {
204 2         10 my $new_parent = new Bio::NEXUS::Node();
205              
206 2         8 $new_parent->set_length($original_node->get_length());
207            
208 2         6 $cloned_node->set_length(0);
209 2         96 $original_node->set_length(0);
210            
211 2         8 $new_parent->add_child($cloned_node);
212 2         8 $cloned_node->set_parent_node($new_parent);
213 2         7 $new_parent->add_child($original_node);
214 2         6 $original_node->set_parent_node($new_parent);
215              
216 2         3 $child = $new_parent;
217 2         6 $new_parent->set_parent_node($original_parent);
218 2         18 last;
219             }
220             }
221             }
222             }
223              
224             =begin comment
225              
226             Name : _write
227             Usage : $block->_write();
228             Function: Writes NEXUS block containing history data
229             Returns : none
230             Args : file name (string)
231              
232             =end comment
233              
234             =cut
235              
236             sub _write {
237 0     0     my ( $self, $fh, $verbose ) = @_;
238 0   0       $fh ||= \*STDOUT;
239              
240 0           Bio::NEXUS::Block::_write( $self, $fh );
241 0           $self->_write_dimensions( $fh, $verbose );
242 0           $self->_write_format( $fh, $verbose );
243 0           $self->_write_labels( $fh, $verbose );
244 0           print $fh "\tNODELABELS ";
245 0           for my $label ( @{ $self->get_otuset->get_otu_names } ) {
  0            
246 0           print $fh _nexus_formatted($label) . ' ';
247             }
248 0           print $fh ";\n";
249 0           $self->_write_matrix( $fh, $verbose );
250 0           $self->_write_trees( $fh, $verbose );
251 0           print $fh "END;\n";
252             }
253              
254             sub AUTOLOAD {
255 0 0   0     return if $AUTOLOAD =~ /DESTROY$/;
256 0           my $package_name = __PACKAGE__ . '::';
257              
258             # The following methods are deprecated and are temporarily supported
259             # via a warning and a redirection
260 0           my %synonym_for = (
261              
262             # "${package_name}parse" => "${package_name}_parse_tree", # example
263             );
264              
265 0 0         if ( defined $synonym_for{$AUTOLOAD} ) {
266 0           $logger->warn("$AUTOLOAD() is deprecated; use $synonym_for{$AUTOLOAD}() instead");
267 0           goto &{ $synonym_for{$AUTOLOAD} };
  0            
268             }
269             else {
270 0           Bio::NEXUS::Util::Exceptions::UnknownMethod->throw(
271             'error' => "ERROR: Unknown method $AUTOLOAD called"
272             );
273             }
274             }
275              
276             1;