File Coverage

blib/lib/Bio/PrimerDesigner/epcr.pm
Criterion Covered Total %
statement 72 116 62.0
branch 11 38 28.9
condition 3 31 9.6
subroutine 14 14 100.0
pod 6 6 100.0
total 106 205 51.7


line stmt bran cond sub pod time code
1             package Bio::PrimerDesigner::epcr;
2              
3             # $Id: epcr.pm 9 2008-11-06 22:48:20Z kyclark $
4              
5             =head1 NAME
6              
7             Bio::PrimerDesigner::epcr - A class for accessing the epcr binary
8              
9             =head1 SYNOPSIS
10              
11             use Bio::PrimerDesigner::epcr;
12              
13             =head1 DESCRIPTION
14              
15             A low-level interface to the e-PCR binary. Uses supplied PCR primers,
16             DNA sequence and stringency parameters to predict both expected
17             and unexpected PCR products.
18              
19             =head1 METHODS
20              
21             =cut
22              
23 6     6   29 use strict;
  6         12  
  6         197  
24 6     6   29 use warnings;
  6         13  
  6         172  
25 6     6   38 use File::Spec::Functions 'catfile';
  6         11  
  6         342  
26 6     6   30 use File::Temp 'tempfile';
  6         15  
  6         1359  
27 6     6   207 use Bio::PrimerDesigner::Remote;
  6         342  
  6         1013  
28 6     6   31 use Bio::PrimerDesigner::Result;
  6         40  
  6         1006  
29 6     6   29 use Readonly;
  6         180  
  6         2893  
30              
31             Readonly our
32             $VERSION => sprintf "%s", q$Revision: 24 $ =~ /(\d+)/;
33              
34 6     6   37 use base 'Class::Base';
  6         10  
  6         7756  
35              
36             # -------------------------------------------------------------------
37             sub run {
38              
39             =head2 run
40              
41             Sets up the e-PCR request for a single primer combination and returns
42             an Bio::PrimerDesigner::Result object
43              
44             If the permute flag is true, all three possible primer combinations
45             will be tested (ie: forward + reverse, forward + forward, reverse + reverse)
46              
47             =cut
48              
49 2     2 1 580 my $self = shift;
50 2         3 my @result = ();
51 2 100       12 my @params = @_ or return $self->error("No arguments for run method");
52 1         1 my $args = $_[2];
53 1 50       4 my $permute = $args->{'permute'} ? 1 : 0;
54 1 50       4 my $left = $args->{'left'} or $self->error("No left primer");
55 1 50       3 my $right = $args->{'right'} or $self->error("No right primer");
56            
57 1         1 $args->{'permute'} = 0;
58            
59 1 50       4 if ( $permute ) {
60 0         0 for my $combo ( 1 .. 3 ) {
61 0         0 my %seen = ();
62 0 0       0 local $args->{'right'} = $left if $combo == 2;
63 0 0       0 local $args->{'left'} = $right if $combo == 3;
64 0         0 $params[2] = $args;
65 0         0 my @pre_result = $self->request(@params);
66              
67             #
68             # e-pcr quirk, same-primer comparisons give two identical
69             # results, we will ignore duplicates
70             #
71 0         0 for my $line (@pre_result) {
72 0 0       0 push @result, $line unless $seen{$line};
73 0 0       0 $seen{$line} = 1 if !$seen{$line};
74             }
75             }
76             }
77             else {
78 1         3 @result = $self->request( @params );
79             }
80            
81 1         8 my $out = Bio::PrimerDesigner::Result->new;
82              
83 1         11 $out->{1}->{'products'} = @result;
84 1         3 $out->{1}->{'raw_output'} = join '', grep {defined} @result;
  1         5  
85 1         2 my $count = 0;
86              
87 1         2 for (@result) {
88 1         10 $count++;
89 1 50 33     6 next unless $_ && /\.\./;
90 0         0 my ($start, $stop) = /(\d+)\.\.(\d+)/;
91 0         0 my $size = abs($stop - $start);
92 0         0 $out->{$count}->{'start'} = $start - 1;
93 0         0 $out->{$count}->{'stop'} = $out->{$count}->{'end'} = $stop - 1;
94 0         0 $out->{$count}->{'size'} = $size;
95             }
96            
97 1         4 return $out;
98             }
99              
100             # -------------------------------------------------------------------
101             sub request {
102              
103             =head2 request
104              
105             Assembles the e-PCR config file and command-line arguments and send
106             the e-PCR request to the local e-PCR binary or remote server.
107              
108             =cut
109              
110 1     1 1 1 my $self = shift;
111 1         2 my ($method, $loc, $args) = @_;
112 1         2 my @data = ();
113 1   50     4 $method ||= 'remote';
114            
115 1 50       3 if ( $method eq 'remote' ) {
    0          
116 1 50       3 if ( ! defined $args->{'seq'} ) {
117 0         0 $self->error(
118             "A sequence must be supplied (not a file name) for remote epcr"
119             );
120 0         0 return '';
121             }
122              
123 1         8 my $cgi = Bio::PrimerDesigner::Remote->new;
124 1         25 $cgi->{'program'} = 'e-PCR';
125 1         2 $args->{'program'} = 'e-PCR';
126            
127 1         19 @data = $cgi->CGI_request( $loc, $args );
128             }
129             elsif ( $method eq 'local') { # run ePCR locally
130             #
131             # required parameters
132             #
133 0   0     0 my $left = uc $args->{'left'} || $self->error("no left primer");
134 0   0     0 my $right = uc $args->{'right'} || $self->error("no right primer");
135 0   0     0 my $seq = $args->{'seq'} || '';
136 0   0     0 my $file = $args->{'seqfile'} || '';
137 0 0 0     0 $self->error("No sequence supplied") unless $seq || $file;
138              
139             #
140             # optional parameters
141             #
142 0   0     0 my $prod_size = $args->{'prod_size'} || 2000;
143 0   0     0 my $margin = $args->{'margin'} || 2000;
144 0   0     0 my $word_size = $args->{'word_size'} || 7;
145 0   0     0 my $num_mismatch = $args->{'mismatch'} || 2;
146            
147             #
148             # e-PCR config file
149             #
150 0         0 my ( $temp_loc_fh, $temp_loc ) = tempfile;
151 0         0 print $temp_loc_fh "ePCR_test\t$left\t$right\t$prod_size\t\n";
152 0         0 close $temp_loc_fh;
153            
154             #
155             # e-PCR sequence file (fasta format)
156             #
157 0         0 my ($seq_loc_fh, $seq_loc, $seq_file, $seq_temp);
158 0 0       0 if ($seq) {
159 0         0 ( $seq_loc_fh, $seq_loc ) = tempfile;
160 0         0 $seq_temp = $seq_loc;
161 0         0 print $seq_loc_fh ">Test sequence\n$seq\n";
162 0         0 close $seq_loc_fh;
163             }
164             else {
165 0 0       0 $seq_loc = $file or $self->error('No sequence file');
166             }
167              
168             #
169             # e-PCR command-line arguments
170             #
171 0         0 my $params = "$temp_loc $seq_loc ";
172 0         0 $params .= "M=$margin W=$word_size N=$num_mismatch";
173 0         0 $loc = catfile( $loc, $self->binary_name );
174            
175             #
176             # run e-PCR
177             #
178 0         0 open EPCR, "$loc $params |";
179 0         0 @data = ;
180 0         0 close EPCR;
181              
182 0         0 unlink $temp_loc;
183 0 0 0     0 unlink $seq_temp if $seq_temp && -e $seq_temp;
184             }
185              
186 1         16 return @data;
187             }
188              
189             # -------------------------------------------------------------------
190             sub verify {
191              
192             =head2 verify
193              
194             Check to make that the e-PCR binary is installed and functioning
195             properly. Since e-PCR returns nothing if no PCR product is found
196             in the sequence, we have to be able to distinguish between a valid,
197             undefined output from a functioning e-PCR and an undefined output
198             for some other reason. verify uses sham e-PCR data that is known
199             to produce a PCR product.
200              
201             =cut
202              
203 1     1 1 2 my $self = shift;
204 1 50       10 my ($method, $loc) = @_ or $self->error('No verify parameters');
205 1         9 my %param = ();
206 1         3 $param{'left'} = 'TTGCGCATTTACGATTACGA';
207 1         2 $param{'right'} = 'ATGCTGTAATCGGCTGTCCT';
208 1         2 $param{'seq'} = 'GCAGCGAGTTGCGCATTTACGATTACGACATACGACACGA' .
209             'TTACAGACAGGACAGCCGATTACAGCATATCGACAGCAT';
210 1         2 $param{'prod_size'} = 70;
211 1         2 $param{'margin'} = 20;
212            
213 1         3 my $result = $self->run( $method, $loc, \%param );
214 1   50     4 my $output = $result->raw_output || '';
215              
216 1 50       10 unless ( $output =~ /\d+\.\.\d+/ ) {
217 1         3 return $self->error("e-PCR did not verify!");
218             }
219             else {
220 0         0 return $result;
221             }
222             }
223              
224             # -------------------------------------------------------------------
225             sub binary_name {
226              
227             =pod
228              
229             =head2 binary_name
230              
231             Defines the binary's name on the system.
232              
233             =cut
234              
235 1     1 1 249 my $self = shift;
236 1         5 return 'e-PCR';
237             }
238              
239             # -------------------------------------------------------------------
240             sub list_aliases {
241              
242             =pod
243              
244             =head2 list_aliases
245              
246             There are no aliases to list for epcr.
247              
248             =cut
249              
250 1     1 1 2 my $self = shift;
251 1         3 return;
252             }
253              
254             # -------------------------------------------------------------------
255             sub list_params {
256              
257             =pod
258              
259             =head2 list_params
260              
261             Returns a list of e-PCR configuration options. Required e-PCR input is
262             a sequence string or file and the left and right primers. Default values
263             will be used for the remaining options if none are supplied.
264              
265              
266             =cut
267              
268 1     1 1 2 my $self = shift;
269              
270             return (
271 1         5 'REQUIRED:',
272             'seq (string) Raw DNA sequence to search for PCR products',
273             'OR',
274             'seqfile (string) Fasta file to search for PCR products',
275             '',
276             'left (string) Left primer sequence',
277             'right (string) Right primer sequence',
278             '', 'OPTIONAL:',
279             'word_size (int; default 7) The size of the perfect match at 3\' end',
280             'mismatch (int; default 2) Allowed number of mismatches',
281             'prod_size (int; default 2000) Expected PCR product size',
282             'margin (int; default 2000) Allowed size variation',
283             'permute (true) Try all primer combinations (l/r, l/l, r/r)'
284             );
285             }
286              
287             1;
288              
289             # -------------------------------------------------------------------
290              
291             =head1 AUTHOR
292              
293             Copyright (C) 2003-2009 Sheldon McKay Emckays@cshl.eduE,
294             Ken Youens-Clark Ekclark@cpan.orgE.
295              
296             =head1 LICENSE
297              
298             This program is free software; you can redistribute it and/or modify
299             it under the terms of the GNU General Public License as published by
300             the Free Software Foundation; version 3 or any later version.
301              
302             This program is distributed in the hope that it will be useful, but
303             WITHOUT ANY WARRANTY; without even the implied warranty of
304             MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
305             General Public License for more details.
306              
307             You should have received a copy of the GNU General Public License
308             along with this program; if not, write to the Free Software
309             Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
310             USA.
311              
312             =head1 SEE ALSO
313              
314             Bio::PrimerDesigner::primer3.
315              
316             =cut