File Coverage

blib/lib/Bio/CUA.pm
Criterion Covered Total %
statement 62 96 64.5
branch 13 30 43.3
condition 2 13 15.3
subroutine 13 17 76.4
pod 3 6 50.0
total 93 162 57.4


line stmt bran cond sub pod time code
1             package Bio::CUA;
2              
3 6     6   25815 use 5.006;
  6         19  
  6         322  
4 6     6   36 use strict;
  6         10  
  6         221  
5 6     6   33 use warnings;
  6         17  
  6         205  
6 6     6   34 use Carp;
  6         7  
  6         8783  
7              
8             # some global variables
9             our $VERSION = '1.02';
10             my $sep = "\t";
11             #my @openFHs; # all file handles opened by this class
12              
13             =pod
14              
15             =head1 NAME
16              
17             Bio::CUA - Codon Usage Analyzer.
18              
19             =head1 VERSION
20              
21             Version 1.02
22              
23             =head1 SYNOPSIS
24              
25             This is the root class for the whole distribution of
26             L,
27             providing some routine methods used by all classs in the
28             distribution L. Users should not use this class
29             directly. Please start with its child classes such as
30             L, L.
31              
32             =head1 DESCRIPTION
33              
34             The aim of this distribution is to provide comprehensive and flexible
35             tools to analyze codon usage bias (CUB) and relevant problems, so that
36             users can speed up the genetic research by taking advantage of this
37             convenience.
38              
39             One amino acid can be encoded by more than one synonymous codon, and
40             synonymous codons are unevenly used. For example, some codons are used
41             more often than other synonymous ones in highly expressed genes (I
42             and Li 1987>). To measure the unevenness of codon usage, multiple
43             metrics of codon usage bias have been developed, such as Fop
44             (Frequency of optimal codons), CAI (Codon Adaptation Index), tAI (tRNA
45             Adaptation Index), and ENC (Effective Number of Codons). The causes of
46             CUB phenomena are complicated, including, mutational bias, selection on
47             translational efficiency or accurancy. CUB is one fundamental concept
48             in genetics.
49              
50             So far, no software exists to compute all the above CUB metrics, and
51             more importantly parameters of CUB calculations are often fixed in
52             software, so one can only analyze genes in a limited list of species
53             and one can not incorporate its own parameters such as sequences of
54             highly expressed genes in a tissue.
55              
56             This package mainly solves these two problems. We also extend some
57             methods, such as GC-content corrected ENC, background-data normalized
58             CAI, etc. See the relevant methods in CUB classes for more details.
59              
60             =head1 METHODS
61              
62             =cut
63              
64             sub new
65             {
66 119     119 0 420 my ($caller, @args) = @_;
67 119         216 my $self = {};
68 119 50       304 my $class = ref($caller)? ref($caller) : $caller;
69              
70 119         424 bless $self, $class;
71 119         487 my $hashRef = $self->_array_to_hash(\@args);
72              
73             # only process its own argument
74 119 50       411 $self->debug(1) if($hashRef->{'debug'});
75              
76 119         616 return $self;
77             }
78              
79             # store and retrieve tag values
80             sub get_tag
81             {
82 286     286 0 454 my ($self, $tag) = @_;
83 286         1674 return $self->{'_tags'}->{$tag};
84             }
85              
86             sub set_tag
87             {
88 323     323 0 620 my ($self, $tag, $val) = @_;
89 323         1229 $self->{'_tags'}->{$tag} = $val;
90             }
91              
92             =head2 debug
93              
94             Title : debug
95             Usage : $true_of_false=$self->debug([$bool]);
96             Function: get/set the boolean value.
97             Returns : 0 as false, 1 as true
98             Args : optional. 0 or 1 for false and true, respectively.
99              
100             =cut
101              
102             sub debug
103             {
104 74     74 1 174 my ($self, $val) = @_;
105 74 50       131 $self->set_tag('debug', $val) if($val);
106 74         155 return $self->get_tag('debug');
107             }
108              
109              
110             =head2 throw
111              
112             Title : throw
113             Usage : $self->throw("Some fatal errors");
114             Function: stop and report when fatal errors in formatted message
115             Returns : None
116             Args : error message
117              
118             =cut
119              
120             # simplified version
121             sub throw
122             {
123 0     0 1 0 my ($self, @args) = @_;
124 0   0     0 my $class = ref($self) || $self;
125 0 0       0 $class = ' '.$class if $class;
126 0         0 my $title = "------------- EXCEPTION$class -------------";
127 0         0 my $footer = ('-' x length($title))."\n";
128             #my $text = join("\n", @args);
129 0         0 my $text = _format_text(join(' ',@args));
130 0         0 croak "\n$title\n", "MSG: $text\n", $footer, "\n";
131             }
132              
133             =head2 warn
134              
135             Title : warn
136             Usage : $self->warn("Please pay attention here")
137             Function: report warning message when something looks not good
138             Returns : None
139             Args : warning messages.
140              
141             =cut
142              
143             sub warn
144             {
145 0     0 1 0 my ($self, @args) = @_;
146              
147 0   0     0 my $class = ref($self) || $self;
148 0 0       0 $class = ' '.$class if $class;
149 0         0 my $title = "------------- WARNING$class -------------";
150 0         0 my $footer = ('-' x length($title))."\n";
151 0         0 my $text = _format_text(join(' ',@args));
152             #my $text = join("\n", @args);
153 0         0 carp "\n$title\n", "MSG: $text\n", $footer, "\n";
154             }
155              
156             # format the text into blocks with same line length
157             sub _format_text
158             {
159 0     0   0 my ($text, $lineLen) = @_;
160              
161 0   0     0 $lineLen ||= 60;
162 0         0 chomp($text);
163 0         0 my $result = '';
164              
165 0         0 my @blocks = split /\n/, $text;
166              
167 0         0 foreach my $b (@blocks)
168             {
169 0         0 my $newB = _break_into_lines($b, $lineLen);
170 0         0 $result .= $newB;
171             }
172 0         0 return $result;
173             }
174              
175             sub _break_into_lines
176             {
177 0     0   0 my ($text, $size) = @_;
178              
179 0         0 my $lines = '';
180 0         0 my $textLen = length($text);
181              
182 0         0 my $accuLen = 0;
183 0         0 while($accuLen < $textLen)
184             {
185 0 0       0 my $lineLen = $accuLen + $size > $textLen? $textLen - $accuLen
186             : $size;
187 0         0 my $l = substr($text,$accuLen,$lineLen);
188 0         0 $accuLen += $lineLen;
189 0         0 $lines .= $l."\n";
190             }
191              
192 0         0 return $lines;
193             }
194              
195             # return hash ref by reading into an array ref
196             sub _array_to_hash
197             {
198 240     240   328 my ($self,$arrayRef,$nc) = @_;
199              
200 240 50       672 $self->throw("parameter '$arrayRef' to _array_to_hash is not an array reference")
201             unless(ref($arrayRef) eq 'ARRAY');
202              
203 240         248 my %hash;
204              
205 240 50       662 $self->throw("Odd number of elements are in the array fed to",
206             "_array_to_hash, check the array $arrayRef")
207             unless($#$arrayRef % 2);
208              
209 240         706 for(my $i = 0; $i < $#$arrayRef; $i += 2)
210             {
211 674         816 my $k = $arrayRef->[$i];
212 674         2065 $k =~ s/^\-*//; # removing leading '-'
213 674 50       1532 $k = lc($k) unless($nc);
214 674         2543 $hash{$k} = $arrayRef->[$i+1];
215             }
216              
217 240         688 return \%hash;
218             }
219              
220              
221             # write out hash to an outfile
222             sub _write_out_hash
223             {
224 2     2   7 my ($self, $outFile, $hashRef) = @_;
225              
226 2         5 my $fh;
227 2 50       248 open($fh, "> $outFile") or die "Can not open $outFile:$!";
228 2         18 while(my ($k,$v) = each %$hashRef)
229             {
230 119         594 print $fh join($sep, $k, $v),"\n";
231             }
232 2         92 close $fh;
233              
234 2         12 return 1;
235             }
236              
237             # open a file and return its file handle
238             sub _open_file
239             {
240 15     15   36 my ($self, $file, $mode) = @_;
241              
242 15   50     97 $mode ||= ' ';
243              
244 15         25 my $fh;
245 15 50       827 open($fh, "$mode $file") or $self->throw("can not open $file:$!");
246             #push @openFHs, $fh;
247 15         120 return $fh;
248             }
249              
250             # parse the first $num fields of input file, and use the vaule at the
251             # first column as key
252             sub _parse_file
253             {
254 2     2   3 my ($self, $file, $num) = @_;
255              
256 2         3 my %hash;
257 2         10 my $fh = $self->_open_file($file);
258 2         36 while(<$fh>)
259             {
260 119 50 33     690 next if /^#/ or /^\s*$/;
261 119         179 chomp;
262 119         313 s/^\s+//; # remove leading blanks
263 119         507 my @fields = split /\s+/;
264 119 50       307 if($num > 1)
265             {
266 119 50       858 $hash{uc($fields[0])} = $num > 2?
267             [@fields[1..($num-1)]] : $fields[1];
268             }else
269             {
270 0         0 $hash{uc($fields[0])}++;
271             }
272             }
273 2         22 close $fh;
274 2         21 return \%hash;
275             }
276              
277             # this method is called when object of this or child classes is being
278             # destroyed
279             # close the file handle if the object has one
280             sub DESTROY
281             {
282 119     119   17792 my $self = shift;
283             #print $self;
284 119 100       2018 close $self->{'_fh'} if(exists $self->{'_fh'});
285             # $self->SUPER::DESTROY(@_);
286             }
287              
288             =head1 AUTHOR
289              
290             Zhenguo Zhang, C<< >>
291              
292             =head1 BUGS
293              
294             Please report any bugs or feature requests to C
295             rt.cpan.org> or through the web interface at
296             L. I will be
297             notified, and then you'll automatically be notified of progress on
298             your bug as I make changes.
299              
300             =cut
301              
302             =head1 SUPPORT
303              
304             You can find documentation for this class with the perldoc command.
305              
306             perldoc Bio::CUA
307              
308             You can also look for information at:
309              
310             =over 4
311              
312             =item * RT: CPAN's request tracker (report bugs here)
313              
314             L
315              
316             =item * AnnoCPAN: Annotated CPAN documentation
317              
318             L
319              
320             =item * CPAN Ratings
321              
322             L
323              
324             =item * Search CPAN
325              
326             L
327              
328             =back
329              
330              
331             =head1 ACKNOWLEDGEMENTS
332              
333              
334             =head1 LICENSE AND COPYRIGHT
335              
336             Copyright 2015 Zhenguo Zhang.
337              
338             This program is free software: you can redistribute it and/or modify
339             it under the terms of the GNU General Public License as published by
340             the Free Software Foundation, either version 3 of the License, or
341             (at your option) any later version.
342              
343             This program is distributed in the hope that it will be useful,
344             but WITHOUT ANY WARRANTY; without even the implied warranty of
345             MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
346             GNU General Public License for more details.
347              
348             You should have received a copy of the GNU General Public License
349             along with this program. If not, see L.
350              
351              
352             =cut
353              
354             1; # End of Bio::CUA
355