File Coverage

blib/lib/Bio/Tools/Run/Meme.pm
Criterion Covered Total %
statement 24 96 25.0
branch 0 36 0.0
condition 0 8 0.0
subroutine 9 14 64.2
pod 5 5 100.0
total 38 159 23.9


line stmt bran cond sub pod time code
1             # BioPerl module for Meme
2             #
3             # Please direct questions and support issues to
4             #
5             # Cared for by Sendu Bala
6             #
7             # Copyright Sendu Bala
8             #
9             # You may distribute this module under the same terms as perl itself
10              
11             # POD documentation - main docs before the code
12              
13             =head1 NAME
14              
15             Bio::Tools::Run::Meme - Wrapper for Meme Program
16              
17             =head1 SYNOPSIS
18              
19             use Bio::Tools::Run::Meme;
20              
21             my $factory = Bio::Tools::Run::Meme->new(-dna => 1, -mod => 'zoops');
22              
23             # return a Bio::AlignIO given Bio::PrimarySeqI objects
24             my $alignio = $factory->run($seq1, $seq2, $seq3...);
25              
26             # add a Bio::Map::Prediction to the appropriate maps given Bio::Map::GeneMap
27             # objects (predict on the full map sequences supplied) or Bio::Map::Gene
28             # objects (predict on the full map sequences of the maps the supplied Genes
29             # are on) or Bio::Map::PositionWithSequence objects
30             my $prediction = $factory->run($biomap1, $biomap2, $biomap3...);
31              
32             =head1 DESCRIPTION
33              
34             This is a wrapper for running meme, a transcription factor binding site
35             prediction program. It can be found here:
36             http://meme.sdsc.edu/meme4/meme-download.html
37              
38             You can try supplying normal meme command-line arguments to new(), eg.
39             new(-mod => 'oops') or calling arg-named methods (excluding the initial
40             hyphen(s), eg. $factory->mod('oops') to set the -mod option to 'oops').
41              
42              
43             You will need to enable this MEME wrapper to find the meme program. During
44             standard installation of meme you will have set up an environment variable
45             called MEME_BIN which is used for this purpose.
46              
47             =head1 FEEDBACK
48              
49             =head2 Mailing Lists
50              
51             User feedback is an integral part of the evolution of this and other
52             Bioperl modules. Send your comments and suggestions preferably to one
53             of the Bioperl mailing lists. Your participation is much appreciated.
54              
55             bioperl-l@bioperl.org - General discussion
56             http://bioperl.org/wiki/Mailing_lists - About the mailing lists
57              
58             =head2 Support
59              
60             Please direct usage questions or support issues to the mailing list:
61              
62             I
63              
64             rather than to the module maintainer directly. Many experienced and
65             reponsive experts will be able look at the problem and quickly
66             address it. Please include a thorough description of the problem
67             with code and data examples if at all possible.
68              
69             =head2 Reporting Bugs
70              
71             Report bugs to the Bioperl bug tracking system to help us keep track
72             the bugs and their resolution. Bug reports can be submitted via the
73             web:
74              
75             http://redmine.open-bio.org/projects/bioperl/
76              
77             =head1 AUTHOR - Sendu Bala
78              
79             Email bix@sendu.me.uk
80              
81             =head1 APPENDIX
82              
83             The rest of the documentation details each of the object
84             methods. Internal methods are usually preceded with a "_".
85              
86             =cut
87              
88             package Bio::Tools::Run::Meme;
89              
90 1     1   100163 use strict;
  1         1  
  1         22  
91 1     1   456 use Bio::SeqIO;
  1         38726  
  1         28  
92 1     1   439 use Bio::AlignIO;
  1         52880  
  1         28  
93 1     1   506 use Bio::Map::Prediction;
  1         11145  
  1         30  
94 1     1   6 use Bio::Map::Position;
  1         2  
  1         19  
95              
96 1     1   4 use base qw(Bio::Tools::Run::WrapperBase);
  1         1  
  1         411  
97              
98             our $PROGRAM_NAME = 'meme';
99             our $PROGRAM_DIR = $ENV{'MEME_BIN'};
100              
101             # methods for the meme args we support
102             our @PARAMS = qw(mod nmotifs evt nsites minsites maxsites wnsites w minw maxw
103             wg ws bfile maxiter distance prior b plib spfuzz spmap cons
104             maxsize p time sf);
105             our @SWITCHES = qw(dna protein nomatrim noendgaps revcomp pal);
106              
107             # just to be explicit, args we don't support (yet) or we handle ourselves
108             our @UNSUPPORTED = qw(h text nostatus);
109              
110              
111             =head2 new
112              
113             Title : new
114             Usage : $rm->new($seq)
115             Function: creates a new wrapper
116             Returns: Bio::Tools::Run::Meme
117             Args : Most options understood by meme can be supplied as key =>
118             value pairs, with a boolean value for switches. -quiet can also be
119             set to silence meme completely.
120              
121             These options can NOT be used with this wrapper (they are handled
122             internally or don't make sense in this context):
123             -h -text -nostatus
124              
125             =cut
126              
127             sub new {
128 1     1 1 103 my ($class, @args) = @_;
129 1         12 my $self = $class->SUPER::new(@args);
130            
131 1         48 $self->_set_from_args(\@args, -methods => [@PARAMS, @SWITCHES, 'quiet'],
132             -create => 1);
133            
134 1         54 return $self;
135             }
136              
137             =head2 program_name
138              
139             Title : program_name
140             Usage : $factory>program_name()
141             Function: holds the program name
142             Returns: string
143             Args : None
144              
145             =cut
146              
147             sub program_name {
148 7     7 1 27 return $PROGRAM_NAME;
149             }
150              
151             =head2 program_dir
152              
153             Title : program_dir
154             Usage : $factory->program_dir(@params)
155             Function: returns the program directory, obtained from ENV variable.
156             Returns: string
157             Args :
158              
159             =cut
160              
161             sub program_dir {
162 4     4 1 1090 return $PROGRAM_DIR;
163             }
164              
165             =head2 version
166              
167             Title : version
168             Usage : n/a
169             Function: Determine the version number of the program, which is
170             non-discoverable for Meme
171             Returns : undef
172             Args : none
173              
174             =cut
175              
176             sub version {
177 0     0 1   return;
178             }
179              
180             =head2 run
181              
182             Title : run
183             Usage : $rm->run($seq1, $seq2, $seq3...);
184             Function: Run Meme on the sequences/Bio::Map::* set as the argument
185             Returns : Bio::AlignIO if sequence objects supplied, OR
186             Bio::Map::Prediction if Bio::Map::* objects supplied
187             undef if no executable found
188             Args : list of Bio::PrimarySeqI compliant objects, OR
189             list of Bio::Map::GeneMap objects, OR
190             list of Bio::Map::Gene objects, OR
191             list of Bio::Map::PositionWithSequence objects
192              
193             =cut
194              
195             sub run {
196 0     0 1   my ($self, @things) = @_;
197            
198 0           my $infile = $self->_setinput(@things);
199            
200 0           return $self->_run($infile);
201             }
202              
203             =head2 _run
204              
205             Title : _run
206             Usage : $rm->_run ($filename,$param_string)
207             Function: internal function that runs meme
208             Returns : as per run(), undef if no executable found
209             Args : the filename to the input sequence file
210              
211             =cut
212              
213             sub _run {
214 0     0     my ($self, $infile) = @_;
215            
216 0   0       my $exe = $self->executable || return;
217            
218 0           my $outfile = $infile.".out";
219            
220 0           my $command = $exe.$self->_setparams($infile, $outfile);
221 0           $self->debug("meme command = $command\n");
222            
223 0 0         open(my $pipe, "$command |") || $self->throw("meme call ($command) failed to start: $? | $!");
224 0           my $error = '';
225 0           while (<$pipe>) {
226 0 0         print unless $self->quiet;
227 0           $error .= $_;
228             }
229 0 0         close($pipe) || ($error ? $self->throw("meme call ($command) failed: $error") : $self->throw("meme call ($command) crashed: $?"));
    0          
230            
231             #my $status = system($cmd_str);
232             #$self->throw("Meme call ($cmd_str) crashed: $?\n") unless $status == 0;
233            
234 0           my $aio = Bio::AlignIO->new(-format => 'meme', -file => $outfile);
235 0 0         unless ($self->{map_mode}) {
236             # return directly the AlignIO
237 0           return $aio;
238             }
239             else {
240             # use the AlignIO meme parser to generate a Bio::Map::Prediction and
241             # return that
242 0           my $pred = Bio::Map::Prediction->new(-source => "meme");
243 0           while (my $aln = $aio->next_aln) {
244 0           foreach my $seq ($aln->each_seq) {
245 0           my $id = $seq->id;
246 0 0         unless ($id) {
247 0           $self->warn("Got a sequence in the alignment with no id, but I need one to determine the map");
248 0           next;
249             }
250 0           my ($uid) = $id =~ /^([^\[]+)/;
251 0           my $map = Bio::Map::GeneMap->get(-uid => $uid);
252            
253 0           my ($start, $end) = ($seq->start, $seq->end);
254 0 0         if ($seq->strand == -1) {
255 0           my $length;
256 0           my ($pos_s, $pos_e) = $id =~ /\[(\d+)\.\.(\d+)\]$/;
257 0 0 0       if (defined($pos_s) && defined($pos_e)) {
258 0           $length = $pos_e - $pos_s + 1;
259             }
260             else {
261 0           $length = length($map->seq);
262             }
263 0           my $motif_length = $end - $start + 1;
264 0           $end = $length - $start + 1;
265 0           $start = $end - $motif_length + 1;
266             }
267            
268 0           Bio::Map::Position->new(-element => $pred,
269             -start => $start,
270             -end => $end,
271             -map => $map);
272             }
273             }
274 0           delete $self->{map_mode};
275 0           return $pred;
276             }
277             }
278              
279             =head2 _setparams()
280              
281             Title : _setparams
282             Usage : Internal function, not to be called directly
283             Function: Create parameter inputs for meme program
284             Returns : parameter string to be passed to meme
285             Args : none
286              
287             =cut
288              
289             sub _setparams {
290 0     0     my ($self, $infile, $outfile) = @_;
291            
292 0           my $param_string = ' '.$infile;
293            
294             # -text and -nostatus must be set
295 0           $param_string .= ' -text -nostatus';
296            
297 0           $param_string .= $self->SUPER::_setparams(-params => \@PARAMS,
298             -switches => \@SWITCHES,
299             -dash => 1);
300            
301 0           $param_string .= " > $outfile";
302              
303 0 0         my $null = ($^O =~ m/mswin/i) ? 'NUL' : '/dev/null';
304 0 0 0       $param_string .= " 2> $null" if $self->quiet || $self->verbose < 0;
305            
306 0           return $param_string;
307             }
308              
309             =head2 _setinput()
310              
311             Title : _setinput
312             Usage : Internal function, not to be called directly
313             Function: writes input sequence to file and return the file name
314             Returns : string (file name)
315             Args : as per run()
316              
317             =cut
318              
319             sub _setinput {
320 0     0     my ($self, @inputs) = @_;
321 0 0         $self->throw("At least two sequence or map objects must be supplied") unless @inputs >= 2;
322 0 0         ref($inputs[0]) || $self->throw("Inputs must be object references");
323            
324 0           my ($fh, $outfile) = $self->io->tempfile(-dir => $self->tempdir);
325 0           my $out = Bio::SeqIO->new(-fh => $fh, '-format' => 'fasta');
326            
327 0           my %done;
328 0           foreach my $input (@inputs) {
329 0 0         if ($input->isa('Bio::Map::MappableI')) {
330             # we want to work on all its maps, since mappables themselves don't
331             # have sequences
332 0           push(@inputs, $input->known_maps);
333 0           next;
334             }
335            
336 0 0         $input->can('seq') || $self->throw("Supplied an input [$input] with no seq() method!");
337            
338 0 0         if ($input->isa('Bio::Map::EntityI')) {
339 0           $self->{map_mode} = 1;
340            
341 0 0         if ($input->isa('Bio::Map::MapI')) {
342             # change the id of the seq so we'll know what input object it
343             # came from later
344 0           my $id = $input->unique_id;
345 0 0         next if $done{$id};
346 0           $input->id($id);
347 0           $done{$id} = 1;
348             #*** should this be automatic in GeneMap? Anyway, we don't want
349             # to alter users genemap id here permanently...
350             }
351             else {
352 0           my $id = $input->id;
353 0 0         unless ($id) {
354 0           $input->id($input->map->unique_id.'['.$input->toString.']');
355             }
356             }
357             }
358            
359 0           $out->write_seq($input);
360             }
361 0           close($fh);
362            
363 0           return $outfile;
364             }
365              
366             =head1 Bio::Tools::Run::Wrapper methods
367              
368             =cut
369              
370             =head2 no_param_checks
371              
372             Title : no_param_checks
373             Usage : $obj->no_param_checks($newval)
374             Function: Boolean flag as to whether or not we should
375             trust the sanity checks for parameter values
376             Returns : value of no_param_checks
377             Args : newvalue (optional)
378              
379              
380             =cut
381              
382             =head2 save_tempfiles
383              
384             Title : save_tempfiles
385             Usage : $obj->save_tempfiles($newval)
386             Function:
387             Returns : value of save_tempfiles
388             Args : newvalue (optional)
389              
390              
391             =cut
392              
393             =head2 outfile_name
394              
395             Title : outfile_name
396             Usage : my $outfile = $codeml->outfile_name();
397             Function: Get/Set the name of the output file for this run
398             (if you wanted to do something special)
399             Returns : string
400             Args : [optional] string to set value to
401              
402              
403             =cut
404              
405             =head2 tempdir
406              
407             Title : tempdir
408             Usage : my $tmpdir = $self->tempdir();
409             Function: Retrieve a temporary directory name (which is created)
410             Returns : string which is the name of the temporary directory
411             Args : none
412              
413             =cut
414              
415             =head2 cleanup
416              
417             Title : cleanup
418             Usage : $codeml->cleanup();
419             Function: Will cleanup the tempdir directory
420             Returns : none
421             Args : none
422              
423             =cut
424              
425             =head2 io
426              
427             Title : io
428             Usage : $obj->io($newval)
429             Function: Gets a L object
430             Returns : L
431             Args : none
432              
433             =cut
434              
435             1;