File Coverage

blib/lib/Bio/PrimerDesigner.pm
Criterion Covered Total %
statement 73 100 73.0
branch 38 62 61.2
condition 17 33 51.5
subroutine 13 19 68.4
pod 13 13 100.0
total 154 227 67.8


line stmt bran cond sub pod time code
1             package Bio::PrimerDesigner;
2              
3             # $Id: PrimerDesigner.pm 25 2008-11-10 20:22:18Z kyclark $
4              
5             =head1 NAME
6              
7             Bio::PrimerDesigner - Design PCR Primers using primer3 and epcr
8              
9             =head1 SYNOPSIS
10              
11             use Bio::PrimerDesigner;
12              
13             my $pd = Bio::PrimerDesigner->new;
14              
15             #
16             # Define the DNA sequence, etc.
17             #
18             my $dna = "CGTGC...TTCGC";
19             my $seqID = "sequence 1";
20              
21             #
22             # Define design parameters (native primer3 syntax)
23             #
24             my %params = (
25             PRIMER_NUM_RETURN => 2,
26             PRIMER_SEQUENCE_ID => $seqID,
27             SEQUENCE => $dna,
28             PRIMER_PRODUCT_SIZE => '500-600'
29             );
30              
31             #
32             # Or use input aliases
33             #
34             %param = (
35             num => 2,
36             id => $seqID,
37             seq => $dna,
38             sizerange => '500-600'
39             );
40              
41             #
42             # Design primers
43             #
44             my $results = $pd->design( %params ) or die $pd->error;
45              
46             #
47             # Make sure the design was successful
48             #
49             if ( !$results->left ) {
50             die "No primers found\n", $results->raw_data;
51             }
52              
53             #
54             # Get results (single primer set)
55             #
56             my $left_primer = $results->left;
57             my $right_primer = $results->right;
58             my $left_tm = $results->lefttm;
59              
60             #
61             # Get results (multiple primer sets)
62             #
63             my @left_primers = $results->left(1..3);
64             my @right_primers = $results->right(1..3);
65             my @left_tms = $results->lefttm(1..3);
66              
67             =head1 DESCRIPTION
68              
69             Bio::PrimerDesigner provides a low-level interface to the primer3 and
70             epcr binary executables and supplies methods to return the results.
71             Because primer3 and e-PCR are only available for Unix-like operating
72             systems, Bio::PrimerDesigner offers the ability to accessing the
73             primer3 binary via a remote server. Local installations of primer3 or
74             e-PCR on Unix hosts are also supported.
75              
76             =head1 METHODS
77              
78             =cut
79              
80 6     6   49828 use strict;
  6         13  
  6         230  
81 6     6   30 use warnings;
  6         12  
  6         225  
82 6     6   3751 use Bio::PrimerDesigner::primer3;
  6         16  
  6         197  
83 6     6   3705 use Bio::PrimerDesigner::epcr;
  6         14  
  6         160  
84 6     6   32 use Readonly;
  6         12  
  6         278  
85              
86 6     6   26 use base 'Class::Base';
  6         11  
  6         7917  
87              
88             Readonly my $EMPTY_STR => q{};
89             Readonly my %DEFAULT => (
90             method => 'local',
91             binary_path => '/usr/local/bin',
92             program => 'primer3',
93             url
94             => 'http://aceserver.biotech.ubc.ca/cgi-bin/primer_designer.cgi',
95             );
96             Readonly my %DESIGNER => (
97             primer3 => 'Bio::PrimerDesigner::primer3',
98             epcr => 'Bio::PrimerDesigner::epcr',
99             );
100             Readonly our
101             $VERSION => '0.04'; # must break like this for Module::Build to find
102              
103             # -------------------------------------------------------------------
104             sub init {
105 6     6 1 4429 my ( $self, $config ) = @_;
106              
107 6         18 for my $param ( qw[ program method url ] ) {
108 18 50       73 $self->$param( $config->{ $param } ) or return;
109             }
110              
111 6 100       66 if ($self->method eq 'local') {
112 5 50       29 $self->binary_path( $config->{'binary_path'} ) or return;
113             }
114              
115 6 100       37 my $loc = $self->method eq 'local' ? 'path' : 'url';
116 6   66     66 $self->{ $loc } = $config->{'path'} || $config->{'url'} || $EMPTY_STR;
117 6         59 return $self;
118             }
119              
120             # -------------------------------------------------------------------
121             sub binary_path {
122              
123             =pod
124              
125             =head2 binary_path
126              
127             Gets/sets path to the primer3 binary.
128              
129             =cut
130              
131 9     9 1 998 my $self = shift;
132              
133 9 100       32 if ( my $path = shift ) {
134 2 50       4 if ( ! $self->os_is_unix ) {
135 0         0 return $self->error("Cannot set binary_path on non-Unix-like OS");
136             }
137             else {
138 2 100       33 if ( -e $path ) {
139 1         3 $self->{'binary_path'} = $path;
140             }
141             else {
142 1         4 $self->error(
143             "Can't find path to " . $self->program->binary_name .
144             ":\nPath '$path' does not exist"
145             );
146 1         17 return $EMPTY_STR;
147             }
148             }
149             }
150              
151 8 100       30 unless ( defined $self->{'binary_path'} ) {
152 5 50       16 $self->{'binary_path'} =
153             ( $self->os_is_unix ) ? $DEFAULT{'binary_path'} : $EMPTY_STR;
154             }
155              
156 8         75 return $self->{'binary_path'};
157             }
158              
159             # -------------------------------------------------------------------
160             sub design {
161              
162             =pod
163              
164             =head2 design
165              
166             Makes the primer design or e-PCR request. Returns an
167             Bio::PrimerDesigner::Result object.
168              
169             =cut
170              
171 0     0 1 0 my $self = shift;
172 0 0       0 my %params = @_ or $self->error("no design parameters");
173 0         0 my $designer = $self->{'program'};
174 0         0 my $method = $self->method;
175 0 0       0 my $loc = $method eq 'local' ? $self->binary_path : $self->url;
176 0 0       0 my $function = $designer =~ /primer3/ ? 'design' : 'run';
177            
178 0 0       0 my $result = $designer->$function( $method, $loc, \%params )
179             or return $self->error( $designer->error );
180            
181 0         0 return $result;
182             }
183              
184             # -------------------------------------------------------------------
185             sub epcr_example {
186              
187             =head2 epcr_example
188              
189             Run test e-PCR job. Returns an Bio::PrimerDesigner::Results object.
190              
191             =cut
192              
193 0     0 1 0 my $self = shift;
194 0         0 my $epcr = Bio::PrimerDesigner::epcr->new;
195 0   0     0 return $epcr->verify( 'remote', $DEFAULT{'url'} )
196             || $self->error( $epcr->error );
197             }
198              
199             # -------------------------------------------------------------------
200             sub list_aliases {
201              
202             =pod
203              
204             =head2 list_aliases
205              
206             Lists aliases for primer3 input/output options
207              
208             =cut
209              
210 0     0 1 0 my $self = shift;
211 0 0       0 my $designer = $self->program or return $self->error;
212 0         0 return $designer->list_aliases;
213             }
214              
215             # -------------------------------------------------------------------
216             sub list_params {
217              
218             =pod
219              
220             =head2 list_params
221              
222             Lists input options for primer3 or epcr, depending on the context
223              
224             =cut
225              
226 0     0 1 0 my $self = shift;
227 0 0       0 my $designer = $self->program or return $self->error;
228 0         0 return $designer->list_params;
229             }
230              
231             # -------------------------------------------------------------------
232             sub method {
233              
234             =pod
235              
236             =head2 method
237              
238             Gets/sets method of accessing primer3 or epcr binaries.
239              
240             =cut
241              
242 23     23 1 1807 my $self = shift;
243              
244 23 100       1750 if ( my $arg = lc shift ) {
245 3 100 66     20 return $self->error("Invalid argument for method: '$arg'")
246             unless $arg eq 'local' || $arg eq 'remote';
247              
248 2 50 33     5 if ( !$self->os_is_unix && $arg eq 'local' ) {
249 0         0 return $self->error("Local method doesn't work on Windows");
250             }
251              
252 2         3 $self->{'method'} = $arg;
253             }
254              
255 22 100       86 unless ( defined $self->{'method'} ) {
256 5 50       25 $self->{'method'} = $self->os_is_unix ? $DEFAULT{'method'} : 'remote';
257             }
258              
259 22         135 return $self->{'method'};
260             }
261              
262             # -------------------------------------------------------------------
263             sub os_is_unix {
264              
265             =pod
266              
267             =head2 os_is_unix
268              
269             Returns 1 if it looks like the operating system is a Unix variant,
270             otherwise returns 0.
271              
272             =cut
273              
274 14     14 1 23 my $self = shift;
275              
276             # technically, this should be 'os_is_not_windows'
277 14 100       48 unless ( defined $self->{'os_is_unix'} ) {
278             #$self->{'os_is_unix'} = ( $^O =~ /(n[iu]x|darwin)/ ) ? 1 : 0;
279 6 50       52 $self->{'os_is_unix'} = ( $^O !~ /^MSWin/i ) ? 1 : 0;
280             }
281              
282 14         86 return $self->{'os_is_unix'};
283             }
284              
285             # -------------------------------------------------------------------
286             sub primer3_example {
287              
288             =head2 primer3_example
289              
290             Runs a sample design job for primers. Returns an
291             Bio::PrimerDesigner::Results object.
292              
293             =cut
294              
295 2     2 1 16 my $self = shift;
296 2         14 my $pcr = Bio::PrimerDesigner::primer3->new;
297 2   33     56 return $pcr->example || $self->error( $pcr->error );
298             }
299              
300             # -------------------------------------------------------------------
301             sub program {
302              
303             =pod
304              
305             =head2 program
306              
307             Gets/sets which program to use.
308              
309             =cut
310              
311 14     14 1 2142 my $self = shift;
312 14   66     98 my $program = shift || $EMPTY_STR;
313 14         111 my $reset = 0;
314              
315 14 100       39 if ( $program ) {
316 5 100       28 return $self->error("Invalid argument for program: '$program'")
317             unless $DESIGNER{ $program };
318 4         33 $reset = 1;
319             }
320              
321 13 100 100     97 if ( $reset || !defined $self->{'program'} ) {
322 9   66     57 $program ||= $DEFAULT{'program'};
323 9         86 my $class = $DESIGNER{ $program };
324 9 50       139 $self->{'program'} = $class->new or
325             return $self->error( $class->error );
326             }
327              
328 13         352 return $self->{'program'};
329             }
330              
331             # -------------------------------------------------------------------
332             sub run {
333              
334             =pod
335              
336             =head2 run
337              
338             Alias to "design."
339              
340             =cut
341 0     0 1 0 my $self = shift;
342 0         0 return $self->design( @_ );
343             }
344              
345             # -------------------------------------------------------------------
346             sub url {
347              
348             =pod
349              
350             =head2 url
351              
352             Gets/sets the URL for accessing the remote binaries.
353              
354             =cut
355              
356 8     8 1 14 my $self = shift;
357 8         16 my $url = shift;
358              
359 8 50 66     76 if ( defined $url && $url eq $EMPTY_STR ) {
    100          
360 0         0 $self->{'url'} = $EMPTY_STR;
361             }
362             elsif ( $url ) {
363 2 100       33 $url = 'http://' . $url unless $url =~ m{https?://};
364 2         6 $self->{'url'} = $url;
365             }
366              
367 8         14 eval { require Bio::PrimerDesigner::Config };
  8         3073  
368 8         35 my $local_url = $EMPTY_STR;
369 8 50       53 if ( !$@ ) {
370 8         17 $local_url = $Bio::PrimerDesigner::Config->{'local_url'};
371             }
372              
373 8   66     73 return $self->{'url'} || $local_url || $DEFAULT{'url'};
374             }
375              
376             # -------------------------------------------------------------------
377             sub verify {
378            
379             =head2 verify
380              
381             Tests local installations of primer3 or e-PCR to ensure that they are
382             working properly.
383              
384             =cut
385              
386 0     0 1   my $self = shift;
387 0           my $designer = $self->{'program'};
388 0           my $method = $self->method;
389 0 0         my $loc = $method eq 'local' ? $self->binary_path : $self->url;
390 0   0       return $designer->verify( $method, $loc ) ||
391             $self->error( $designer->error );
392             }
393              
394             1;
395              
396             # -------------------------------------------------------------------
397              
398             =pod
399              
400             =head1 AUTHORS
401              
402             Copyright (C) 2003-2009 Sheldon McKay Emckays@cshl.eduE,
403             Ken Youens-Clark Ekclark@cpan.orgE.
404              
405             =head1 LICENSE
406              
407             This program is free software; you can redistribute it and/or modify
408             it under the terms of the GNU General Public License as published by
409             the Free Software Foundation; version 3 or any later version.
410              
411             This program is distributed in the hope that it will be useful, but
412             WITHOUT ANY WARRANTY; without even the implied warranty of
413             MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
414             General Public License for more details.
415              
416             You should have received a copy of the GNU General Public License
417             along with this program; if not, write to the Free Software
418             Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
419             USA.
420              
421             =head1 SEE ALSO
422              
423             Bio::PrimerDesigner::primer3, Bio::PrimerDesigner::epcr.
424              
425             =cut