File Coverage

blib/lib/Bio/CUA/CUB/Builder.pm
Criterion Covered Total %
statement 156 167 93.4
branch 50 80 62.5
condition 12 27 44.4
subroutine 13 14 92.8
pod 5 6 83.3
total 236 294 80.2


line stmt bran cond sub pod time code
1             package Bio::CUA::CUB::Builder;
2              
3             =pod
4              
5             =head1 NAME
6              
7             Bio::CUA::CUB::Builder -- A module to calculate codon usage bias (CUB)
8             metrics at codon level and other parameters
9              
10             =head1 SYNOPSIS
11              
12             use Bio::CUA::CUB::Builder;
13              
14             # initialize the builder
15             my $builder = Bio::CUA::CUB::Builder->new(
16             codon_table => 1 ); # using stardard genetic code
17            
18             # calculate RSCU for each codon, and result is stored in "rscu.out" as
19             # well as returned as a hash reference
20             my $rscuHash = $builder->build_rscu("seqs.fa",undef, 0.5,"rscu.out");
21              
22             # calculate CAI for each codon, normalizing RSCU values of codons
23             # for each amino acid by the expected RSCUs under even usage,
24             # rather than the maximal RSCU used by the traditional CAI method.
25             my $caiHash = $builder->build_cai($codonList,2,'mean',"cai.out");
26              
27             # calculate tAI for each codon
28             my $taiHash = $builder->build_tai("tRNA_copy_number.txt","tai.out", undef, 1);
29              
30             =head1 DESCRIPTION
31              
32             Codon usage bias (CUB) can be represented at two levels, codon and
33             sequence. The latter is often computed as the geometric means of the
34             sequence's codons. This module caculates CUB metrics at codon level.
35              
36             Supported CUB metrics include CAI (codon adaptation index), tAI (tRNA
37             adaptation index), RSCU (relative synonymous codon usage), and their
38             variants. See the methods below for details.
39              
40             The output can be stored in a file which is then used by methods in
41             L to calculate CUB indice for each
42             protein-coding sequence.
43              
44             =cut
45              
46 2     2   18520 use 5.006;
  2         4  
47 2     2   9 use strict;
  2         2  
  2         32  
48 2     2   7 use warnings;
  2         2  
  2         56  
49 2     2   436 use parent qw/Bio::CUA::CUB/;
  2         249  
  2         10  
50              
51             # paired codon bases for each anticodon base at wobble position.
52             # According to Crick, FH, 1966, JMB
53             my %wobbleBasePairsAnti = (
54             #Anti => Codon at 3rd position
55             A => [qw/T/],
56             C => [qw/G/],
57             T => [qw/A G/],
58             G => [qw/C T/],
59             I => [qw/A C T/]
60             );
61              
62             # get the version using codon's position as key
63             sub _build_pairing_anti_base
64             {
65 1     1   2 my $self = shift;
66             my %wobbleAntiKey = $self->get_tag('anti_wobble_pair')?
67 1 50       18 %{$self->get_tag('anti_wobble_pair')} : %wobbleBasePairsAnti;
  0         0  
68              
69 1 50       5 if($self->_a_to_i)
70             {
71 1         2 $wobbleAntiKey{'A'} = $wobbleAntiKey{'I'};
72             }
73 1         2 my %wobbleBasePairs;
74 1         7 while(my ($antiPos, $codonMatches) = each %wobbleAntiKey)
75             {
76 5         11 foreach (@$codonMatches)
77             {
78 11         13 push @{$wobbleBasePairs{$_}}, $antiPos;
  11         47  
79             }
80             }
81 1         5 $self->{'_wobble_pair'} = \%wobbleBasePairs;
82             }
83              
84             #default codon selective constraints from dos Reis, et al., 2004 NAR.
85             # key is anticodon-codon at wobbling site
86             my %defaultSC = (
87             'I-T' => 0, # 1
88             'A-T' => 0,
89             'G-C' => 0,
90             'T-A' => 0,
91             'C-G' => 0, # 5
92             'G-T' => 0.41,
93             'I-C' => 0.28,
94             'I-A' => 0.9999,
95             'A-C' => 0.28, # for cases when A is
96             'A-A' => 0.9999, # regarded as I
97             'T-G' => 0.68,
98             'L-A' => 0.89 # 10, L=lysidine present in prokaryotes
99             );
100              
101             =head1 METHODS
102              
103             =head2 new
104              
105             Title : new
106             Usage : $analyzer = Bio::CUA::CUB::Builder->new(-codon_table => 1)
107             Function: initiate the analyzer
108             Returns : an object
109             Args : accepted options are as follows
110              
111             B
112              
113             =over
114              
115             =item C<-codon_table>
116              
117             the genetic code table applied for following sequence analyses. It can
118             be specified by an integer (genetic code table id), an object of
119             L, or a map-file. See the method
120             L for details.
121              
122             =back
123              
124             B
125              
126             =over
127              
128             =item C<-a_to_i>
129              
130             a switch option. If true (any nonzero values), all
131             'A' nucleotides at the 1st position of anticodon will be regarded as I
132             (inosine) which can pair with more nucleotides at codons's wobbling
133             position (A,T,C at the 3rd position). The default is true.
134              
135             =item C<-no_atg>
136              
137             a switch option to indicate whether ATG codons should be
138             excluded in tAI calculation. Default is true, following I
139             et al., 2004, NAR>. To include ATG in tAI calculation, provide '0' here.
140              
141             =item C<-wobble>
142              
143             reference to a hash containing anticodon-codon basepairs at
144             wobbling position, such as ('U' is equivalent to 'T')
145             %wobblePairs = (
146             A => [qw/T/],
147             C => [qw/G/],
148             T => [qw/A G/],
149             G => [qw/C T/],
150             I => [qw/A C T/]
151             ); # this is the default setting
152             Hash keys are the bases in anticodons and hash values are paired
153             bases in codons's 3rd positions. This option is optional and default
154             value is shown above by the example.
155              
156             =back
157              
158             =cut
159              
160             sub new
161             {
162 1     1 1 8070 my ($caller, @args) = @_;
163 1 50       5 my $class = ref($caller)? ref($caller) : $caller;
164 1         15 my $self = $class->SUPER::new(@args);
165              
166 1         6 my $hashRef = $self->_array_to_hash(\@args);
167 1 50       5 if(exists $hashRef->{'a_to_i'})
168             {
169 0         0 $self->set_tag('a2i',$hashRef->{'a_to_i'});
170             }else
171             {
172 1         9 $self->set_tag('a2i', 1); # true, default
173             }
174 1 50       4 if(exists $hashRef->{'no_atg'})
175             {
176 0         0 $self->set_tag('no_atg', $hashRef->{'no_atg'});
177             }else
178             {
179 1         5 $self->set_tag('no_atg',1); # default is true
180             }
181 1 50       4 if(exists $hashRef->{'wobble'})
182             {
183 0         0 $self->set_tag('anti_wobble_pair', $hashRef->{'wobble'});
184             }
185              
186 1         5 $self->_build_pairing_anti_base; # make wobble pairing hash
187 1         7 return $self;
188             }
189              
190             # indicator whether A should be regarded as I
191             sub _a_to_i
192             {
193 1     1   2 my $self = shift;
194 1         4 $self->get_tag('a2i');
195             }
196              
197             =head2 no_atg
198              
199             Title : no_atg
200             Usage : $status = $self->no_atg([$newVal])
201             Function: get/set the status whether ATG should be excluded in tAI
202             calculation.
203             Returns : current status after updating
204             Args : optional. 1 for true, 0 for false
205              
206             =cut
207             # implement in parent class Bio::CUA
208              
209             #=head2 detect_optimal_codons
210             #
211             # Title : detect_optimal_codons
212             # Usage : $ok = $self->detect_optimal_codons();
213             # Function:
214             # Returns :
215             # Args :
216             #
217             #=cut
218              
219             sub detect_optimal_codons
220             {
221 0     0 0 0 die "detect_optimal_codons has not implemented, yet.$!";
222             }
223              
224             =head2 build_rscu
225              
226             Title : build_rscu
227             Usage : $ok = $self->build_rscu($input,[$minTotal,$pseudoCnt,$output]);
228             Function: calculate RSCU values for all sense codons
229             Returns : reference of a hash using the format 'codon => RSCU value'.
230             return undef if failed.
231             Args : accepted arguments are as follows (note: not as hash):
232              
233             =over
234              
235             =item C
236              
237             name of a file containing fasta CDS sequences of interested
238             genes, or a sequence object with method I to extract sequence
239             string, or a plain sequence string, or reference to a hash containing
240             codon counts with structure like I<{ AGC => 50, GTC => 124}>.
241              
242             =item C
243              
244             optional, name of the file to store the result. If omitted,
245             no result will be written.
246              
247             =item C
248              
249             optional, minimal count of an amino acid in sequences; if observed
250             count is smaller than this minimum, all codons of this amino acid would
251             be assigned equal RSCU values. This is to reduce sampling errors in
252             rarely observed amino acids. Default value is 5.
253              
254             =item C
255              
256             optional. Pseudo-counts for unobserved codons. Default is 0.5.
257              
258             =back
259              
260             =cut
261              
262             sub build_rscu
263             {
264 5     5 1 18 my ($self, $input, $minTotal, $pseudoCnt, $output) = @_;
265              
266 5 50 33     48 $pseudoCnt = 0.5 unless($pseudoCnt and $pseudoCnt > 0);
267 5 50 33     33 $minTotal = 5 unless($minTotal and $minTotal > 0);
268 5 50       31 my $codonList = $self->get_codon_list($input) or return;
269              
270 5         31 my @allAAs = $self->all_AAs_in_table; # get all the amino acids in the codon table
271 5         10 my %rscu;
272 5         10 foreach my $AA (@allAAs)
273             {
274             # get the codons encoding this AA
275 100         180 my @codons = $self->codons_of_AA($AA);
276 100         89 my $cntSum = 0; # total observations of this AA's codons
277 100         75 my $zeroCnt = 0; # number of codons with zero values
278 100         121 foreach (@codons)
279             {
280 305 50 0     398 ++$zeroCnt and next unless($codonList->{$_});
281 305         326 $cntSum += $codonList->{$_};
282             }
283             # get the rscu values
284 100 50       124 if($cntSum < $minTotal) # too small sample
285             {
286             # assign equal usage to all codons of this amino acid
287 0         0 foreach (@codons)
288             {
289 0         0 $rscu{$_} = 1/($#codons+1);
290             }
291             }else
292             {
293             # add the pseudoCnt correction
294 100         101 $cntSum += $zeroCnt*$pseudoCnt;
295 100         106 foreach (@codons)
296             {
297 305   33     920 $rscu{$_} = ($codonList->{$_} || $pseudoCnt)/($cntSum || 1);
      50        
298             }
299             }
300             }
301              
302 5 50       13 $self->_write_out_hash($output, \%rscu) if($output);
303 5         47 return \%rscu;
304             }
305              
306             =head2 build_cai
307              
308             Title : build_cai
309             Usage : $ok = $self->build_cai($input,[$minTotal,$norm_method,$output]);
310             Function: calculate CAI values for all sense codons
311             Returns : reference of a hash in which codons are keys and CAI values
312             are values. return undef if failed.
313             Args : accepted arguments are as follows:
314              
315             =over
316              
317             =item C
318              
319             name of a file containing fasta CDS sequences of interested
320             genes, or a sequence object with method I to derive sequence
321             string, or a plain sequence string, or reference to a hash containing
322             codon list with structure like I<{ AGC => 50, GTC => 124}>.
323              
324             =item C
325              
326             optional, minimal codon count for an amino acid; if observed
327             count is smaller than this count, all codons of this amino acid would
328             be assigned equal CAI values. This is to reduce sampling errors in
329             rarely observed amino acids. Default value is 5.
330              
331             =item C
332              
333             optional, indicating how to normalize RSCU to get CAI
334             values. Valid values are 'max' and 'mean'; the former represents the
335             original method used by I, i.e., dividing
336             all RSCUs by the maximum of an amino acid, while 'mean' indicates
337             dividing RSCU by expected average fraction assuming even usage of
338             all codons, i.e., 0.5 for amino acids encoded by 2 codons, 0.25 for
339             amino acids encoded by 4 codons, etc. The CAI metric determined by
340             the latter method is named I. mCAI can assign
341             different CAI values for the most preferred codons of different
342             amino acids, which otherwise would be the same by CAI (i.e., 1).
343              
344             =item C
345              
346             optional. If provided, result will be stored in the file
347             specified by this argument.
348            
349             =back
350              
351             Note: for codons which are not observed will be assigned a count of
352             0.5, and codons which are not degenerate (such as AUG and UGG in
353             standard genetic code table) are excluded. These are the default of
354             the paper I. Here you can also reduce
355             sampling error by setting parameter $minTotal.
356              
357             =cut
358              
359             sub build_cai
360             {
361 2     2 1 19 my ($self, $input, $minTotal, $norm, $output) = @_;
362              
363 2 50       9 $minTotal = 5 unless(defined $minTotal);
364             # get RSCU values first
365 2         8 my $rscuHash = $self->build_rscu($input,$minTotal,0.5);
366              
367 2         7 my @AAs = $self->all_AAs_in_table;
368              
369 2         4 my %cai;
370 2         4 my $maxCAI = 0; # the maximum value of CAI in this dataset
371 2         6 foreach my $AA (@AAs)
372             {
373 40         75 my @codons = $self->codons_of_AA($AA);
374             # skip non-degenerate codons
375 40 100       75 next unless($#codons > 0);
376              
377             # determine the factor to normalize the values
378 36         29 my $scaleFactor;
379 36 100 66     161 if($norm and $norm =~ /mean/i) # normalized by average
380             {
381 18         22 $scaleFactor = $#codons + 1;
382             }else # old method, by maximum
383             {
384             # get the maximum RSCU value for this codon
385 18         15 my $maxRSCU = 0;
386 18         19 foreach (@codons)
387             {
388 59         50 my $rscu = $rscuHash->{$_};
389 59 100       98 $maxRSCU = $rscu if($maxRSCU < $rscu);
390             }
391 18 50       29 $scaleFactor = $maxRSCU > 0? 1/$maxRSCU : 0;
392             }
393             # get CAI values now
394 36         43 foreach (@codons)
395             {
396 118         100 my $rscu = $rscuHash->{$_};
397 118         126 $cai{$_} = $rscu*$scaleFactor;
398             # global maximum of CAI
399 118 100       240 $maxCAI = $cai{$_} if($cai{$_} > $maxCAI);
400             }
401             }
402              
403             #***********************
404             # further normalize all CAI by the global maximal CAI, like tAI,
405             # but one can opt out this, because without normalize by maxCAI
406             # one can distinguish genes more often use less-preferred codons.
407             # In this way, value 1 means no bias, > 1 means towards preferred
408             # codons while < 1 means towards non-preferred codons
409 2 100 66     22 map { $cai{$_} /= $maxCAI } keys(%cai)
  59   66     53  
410             if($norm and $norm =~ /mean/i and $maxCAI);
411              
412 2 100       19 $self->_write_out_hash($output, \%cai) if($output);
413 2         41 return \%cai;
414             }
415              
416             =head2 build_b_cai
417              
418             Title : build_b_cai
419             Usage : $caiHash =
420             $self->build_b_cai($input,$background,[$minTotal,$output]);
421             Function: calculate CAI values for all sense codons. Instead of
422             normalizing RSCUs by maximal RSCU or expected fractions, each RSCU value is
423             normalized by the corresponding background RSCU, then these
424             normalized RSCUs are used to calculate CAI values.
425             Returns : reference of a hash in which codons are keys and CAI values
426             are values. return undef if failed.
427             Args : accepted arguments are as follows:
428              
429             =over
430              
431             =item C
432              
433             name of a file containing fasta CDS sequences of interested
434             genes, or a sequence object with metho I to derive sequence
435             string, or a plain sequence string, or reference to a hash containing
436             codon list with structure like I<{ AGC => 50, GTC => 124}>.
437              
438             =item C
439              
440             background data from which background codon usage (RSCUs)
441             is computed. Acceptable formats are the same as the above argument
442             'input'.
443              
444             =item C
445              
446             optional, minimal codon count for an amino acid; if observed
447             count is smaller than this count, all codons of this amino acid would
448             be assigned equal RSCU values. This is to reduce sampling errors in
449             rarely observed amino acids. Default value is 5.
450              
451             =item C
452              
453             optional. If provided, result will be stored in the file
454             specified by this argument.
455              
456             =back
457              
458             Note: for codons which are not observed will be assigned a count of
459             0.5, and codons which are not degenerate (such as AUG and UGG in
460             standard genetic code table) are excluded.
461              
462             =cut
463              
464             sub build_b_cai
465             {
466 1     1 1 8 my ($self, $input, $background, $minTotal, $output) = @_;
467              
468 1 50       5 $minTotal = 5 unless(defined $minTotal);
469             # get RSCU values first for input as well as background
470 1         5 my $rscuHash = $self->build_rscu($input,$minTotal,0.5);
471 1         5 my $backRscuHash = $self->build_rscu($background,$minTotal,0.5);
472              
473             # normalize all RSCU values by background RSCUs
474 1         17 my @senseCodons = $self->all_sense_codons();
475 1         4 foreach (@senseCodons)
476             {
477 61         67 $rscuHash->{$_} /= $backRscuHash->{$_};
478             }
479              
480             # now calculate CAIs for each amino acid
481 1         4 my @AAs = $self->all_AAs_in_table;
482              
483 1         4 my %cai;
484 1         3 my $maxCAI = 0; # the maximum value of CAI in this dataset
485 1         4 foreach my $AA (@AAs)
486             {
487 20         36 my @codons = $self->codons_of_AA($AA);
488             # skip non-degenerate codons
489 20 100       35 next unless($#codons > 0);
490              
491             # get the maximum RSCU value for this amino acid
492 18         17 my $maxRSCU = 0;
493 18         21 foreach (@codons)
494             {
495 59         46 my $rscu = $rscuHash->{$_};
496 59 100       107 $maxRSCU = $rscu if($maxRSCU < $rscu);
497             }
498              
499             # get CAI values now
500 18         19 foreach (@codons)
501             {
502 59         41 my $rscu = $rscuHash->{$_}; # normalized one
503 59         94 $cai{$_} = $rscu/$maxRSCU;
504             }
505             }
506              
507 1 50       4 $self->_write_out_hash($output, \%cai) if($output);
508 1         17 return \%cai;
509             }
510              
511             =head2 build_tai
512              
513             Title : build_tai
514             Usage : $taiHash =
515             $self->build_tai($input,[$output,$selective_constraints, $kingdom]);
516             Function: build tAI values for all sense codons
517             Returns : reference of a hash in which codons are keys and tAI indice
518             are values. return undef if failed. See Formula 1 and 2 in I
519             Reis, 2004, NAR> to see how they are computed.
520             Args : accepted arguments are as follows:
521            
522             =over
523              
524             =item C
525              
526             name of a file containing tRNA copies/abundance in the format
527             'anticodoncount' per line, where 'anticodon' is anticodon in
528             the tRNA and count can be the tRNA gene copy number or abundance.
529              
530             =item C
531              
532             optional. If provided, result will be stored in the file
533             specified by this argument.
534              
535             =item C
536              
537             optional, reference to hash containing wobble base-pairing and its
538             selective constraint compared to Watson-Crick base-pair, the format
539             is like this:
540             $selective_constraints = {
541             ... ... ...
542             'C-G' => 0,
543             'G-T' => 0.41,
544             'I-C' => 0.28,
545             ... ... ...
546             };
547             The key follows the 'anticodon-codon' order, and the values are codon
548             selective constraints. The smaller the constraint, the stronger the
549             pairing, so all Watson-Crick pairings have value 0.
550             If this option is omitted, values will be searched for in the 'input' file,
551             following the section of anticodons and started with a line '>SC'. If it is
552             not in the input file, then the values in the Table 2 of
553             I are used.
554              
555             =item C
556              
557             kingdom = 1 for prokaryota and 0 or undef for eukaryota, which
558             affects the cacluation for bacteria isoleucine ATA codon. Default is
559             undef for eukaryota
560              
561             =back
562            
563             =cut
564              
565             sub build_tai
566             {
567 1     1 1 8 my ($self, $input, $output, $SC, $kingdom) = @_;
568              
569             # the input copy number of each tRNA
570 1         12 my $fh = $self->_open_file($input);
571              
572             # read into tRNA abundance and if provided, selective constraints
573 1         2 my %antiCodonCopyNum;
574             my %scHash;
575 1         2 my $metSC = 0;
576 1         22 while(<$fh>)
577             {
578 45 50       71 if(/^>SC/) # constraint section
579             {
580 0 0       0 last if $SC; # provided in this call
581             # otherwise record it
582 0         0 $metSC = 1;
583 0         0 next;
584             }
585 45         48 chomp;
586 45         130 my ($k, $v) = split /\s+/;
587 45 50       174 $metSC? $scHash{$k} = $v : $antiCodonCopyNum{$k} = $v;
588             }
589 1         73 close $fh;
590 1 50 0     5 $SC ||= \%scHash if(%scHash);
591 1 50       3 unless($SC)
592             {
593 1 50       11 $self->warn("default codon selective constraints (dos Reis) are used")
594             if($self->debug);
595 1         3 $SC = \%defaultSC;
596             }
597              
598             # now calculate tAI for each codon
599 1         3 my $allSenseCodons = $self->all_sense_codons;
600 1         2 my $maxW = 0; # maximum W of all codons
601 1         1 my %codonWs;
602 1         2 my $nonzeroWcnt = 0;
603 1         1 my $nonzeroWsumLog = 0;
604 1         7 my $excludeATG = $self->no_atg;
605 1         3 foreach my $codon (@$allSenseCodons)
606             {
607             # exclude ATG
608 61 100 66     202 next if($excludeATG and $codon eq 'ATG');
609             # find its recognizable anticodons
610 60         75 my $antiCodons = $self->_find_anticodons($codon);
611 60 50       107 $self->throw("No anticodons found for codon '$codon'")
612             unless($#$antiCodons > 0);
613             #print "$codon: ", join(',', @$antiCodons), "\n";
614 60         56 my $W = 0;
615             # this codon may have no anticodons at all, so $W will be 0
616 60         69 foreach my $anti (@$antiCodons)
617             {
618             # check whether this tRNA exists here
619 166 100       272 next unless(exists $antiCodonCopyNum{$anti});
620             # now determine the wobble pair
621 80         111 my $wobble = substr($anti,0,1).'-'.substr($codon,2,1);
622             #my $s = $SC->{$wobble} || 0;
623             $self->throw("Unknow wobble '$wobble' pair found")
624 80 50       116 unless(exists $SC->{$wobble});
625 80         72 my $s = $SC->{$wobble};
626 80         194 $W += (1-$s)*$antiCodonCopyNum{$anti};
627             }
628 60 100       146 $maxW = $W if($W > $maxW);
629 60         112 $codonWs{$codon} = $W;
630 60 50       116 if($W > 0)
631             {
632 60         51 $nonzeroWcnt++;
633 60         101 $nonzeroWsumLog += log($W);
634             }
635 60 50       119 $self->warn("The raw W for codon $codon is 0")
636             if($self->debug);
637             }
638              
639             # geometric mean of non-zero ws
640 1         18 my $geoMean = exp($nonzeroWsumLog/$nonzeroWcnt)/$maxW;
641             # normalize all W values by the max
642 1         8 while(my ($c, $w) = each %codonWs)
643             {
644             # assign zero w an geometric mean of other ws
645 60 50       233 $codonWs{$c} = $w > 0? $w/$maxW : $geoMean;
646             }
647              
648             # modify prokaryotic ATA if present
649 1 50       12 if($kingdom)
650             {
651 0         0 $codonWs{'ATA'} = (1-$SC->{'L-A'})/$maxW;
652             }
653              
654 1 50       10 $self->_write_out_hash($output, \%codonWs) if($output);
655              
656 1         15 return \%codonWs;
657             }
658              
659             sub _find_anticodons
660             {
661 60     60   59 my ($self, $codon) = @_;
662              
663 60         100 my @bases = split //, $codon;
664 60         78 my $fixedBases = _complement($bases[0])._complement($bases[1]);
665 60         65 my $wobbleBasePairs = $self->{'_wobble_pair'};
666 60         65 my $matchAntiBases = $wobbleBasePairs->{$bases[2]};
667 60         43 my @antiCodons;
668 60         75 foreach (@$matchAntiBases)
669             {
670 166         138 my $anti = $fixedBases.$_;
671 166         233 push @antiCodons, scalar(reverse($anti)); # convert to 5'->3'
672             }
673              
674 60         109 return \@antiCodons;
675             }
676              
677             sub _complement
678             {
679 120     120   99 my ($base) = @_;
680              
681 120         94 $base =~ tr/ATCG/TAGC/;
682              
683 120         178 return $base;
684             }
685              
686             =head1 AUTHOR
687              
688             Zhenguo Zhang, C<< >>
689              
690             =head1 BUGS
691              
692             Please report any bugs or feature requests to C, or through
693             the web interface at L. I will be notified, and then you'll
694             automatically be notified of progress on your bug as I make changes.
695              
696              
697             =head1 SUPPORT
698              
699             You can find documentation for this module with the perldoc command.
700              
701             perldoc Bio::CUA::CUB::Builder
702              
703              
704             You can also look for information at:
705              
706             =over 4
707              
708             =item * RT: CPAN's request tracker (report bugs here)
709              
710             L
711              
712             =item * AnnoCPAN: Annotated CPAN documentation
713              
714             L
715              
716             =item * CPAN Ratings
717              
718             L
719              
720             =item * Search CPAN
721              
722             L
723              
724             =back
725              
726              
727             =head1 ACKNOWLEDGEMENTS
728              
729              
730             =head1 LICENSE AND COPYRIGHT
731              
732             Copyright 2015 Zhenguo Zhang.
733              
734             This program is free software: you can redistribute it and/or modify
735             it under the terms of the GNU General Public License as published by
736             the Free Software Foundation, either version 3 of the License, or
737             (at your option) any later version.
738              
739             This program is distributed in the hope that it will be useful,
740             but WITHOUT ANY WARRANTY; without even the implied warranty of
741             MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
742             GNU General Public License for more details.
743              
744             You should have received a copy of the GNU General Public License
745             along with this program. If not, see L.
746              
747              
748             =cut
749              
750             1; # End of Bio::CUA::CUB::Builder
751