File Coverage

blib/lib/Bio/Polloc/RuleIO.pm
Criterion Covered Total %
statement 92 141 65.2
branch 37 64 57.8
condition 14 23 60.8
subroutine 18 24 75.0
pod 16 16 100.0
total 177 268 66.0


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             Bio::Polloc::RuleIO - I/O interface for the sets of rules (L<Bio::Polloc::RuleI>)
4              
5             =head1 AUTHOR - Luis M. Rodriguez-R
6              
7             Email lmrodriguezr at gmail dot com
8              
9             =head1 IMPLEMENTS OR EXTENDS
10              
11             =over
12              
13             =item *
14              
15             L<Bio::Polloc::Polloc::Root>
16              
17             =item *
18              
19             L<Bio::Polloc::Polloc::IO>
20              
21             =back
22              
23             =cut
24              
25             package Bio::Polloc::RuleIO;
26 10     10   1816 use strict;
  10         37  
  10         370  
27 10     10   50 use base qw(Bio::Polloc::Polloc::Root Bio::Polloc::Polloc::IO);
  10         17  
  10         18154  
28             our $VERSION = 1.0503; # [a-version] from Bio::Polloc::Polloc::Version
29              
30              
31             =head1 PUBLIC METHODS
32              
33             Methods provided by the package
34              
35             =cut
36              
37             =head2 new
38              
39             The basic initialization method
40              
41             B<Arguments>
42              
43             The same arguments of L<Bio::Polloc::Polloc::IO>, plus:
44              
45             =over
46              
47             =item -format
48              
49             The format of the file
50              
51             =item -genomes
52              
53             The genomes to be scaned
54              
55             =back
56              
57             =cut
58              
59             sub new {
60 3     3 1 2553 my($caller,@args) = @_;
61 3   33     31 my $class = ref($caller) || $caller;
62            
63 3 50       17 if($class !~ m/Bio::Polloc::RuleSet::(\S+)/){
64 3         24 my $bme = Bio::Polloc::Polloc::Root->new(@args);
65 3         23 my($format,$file) = $bme->_rearrange([qw(FORMAT FILE)], @args);
66            
67 3 50 33     44 ($format = $file) =~ s/.*\.// if $file and not $format;
68 3 50       41 if($format){
69 3         15 $format = Bio::Polloc::RuleIO->_qualify_format($format);
70 3 50       28 $class = "Bio::Polloc::RuleSet::" . $format if $format;
71             }
72             }
73              
74 3 50       180 if($class =~ m/Bio::Polloc::RuleSet::(\S+)/){
75 3 50       400 if(Bio::Polloc::RuleIO->_load_module($class)){;
76 3         43 my $self = $class->SUPER::new(@args);
77 3         45 $self->debug("Got the RuleIO class $class ($1)");
78 3         22 $self->format($1);
79 3         30 my ($genomes) = $self->_rearrange([qw(GENOMES)], @args);
80 3         26 $self->genomes($genomes);
81 3         12 $self->_initialize(@args);
82 3         26 return $self;
83             }
84 0         0 my $bme = Bio::Polloc::Polloc::Root->new(@args);
85 0         0 $bme->throw("Impossible to load the module", $class);
86             } else {
87 0         0 my $bme = Bio::Polloc::Polloc::Root->new(@args);
88 0         0 $bme->throw("Impossible to load the proper Bio::Polloc::RuleIO class with [".
89             join("; ",@args)."]", $class);
90             }
91             }
92              
93             =head2 prefix_id
94              
95             Sets/gets the prefix ID, unique for the RuleSet
96              
97             B<Purpose>
98              
99             To allow the identification of children in a unique namespace
100              
101             B<Arguments>
102              
103             A string, supposedly unique. Any colon (:) will be changed to '_'
104              
105             B<Returns>
106              
107             The prefix ID.
108              
109             =cut
110              
111             sub prefix_id {
112 13     13 1 1142 my($self,$value) = @_;
113 13 50 33     42 if(defined $value && "$value"){ #<- to avoid empty string ('') but allow zero (0)
114 0         0 $value =~ s/:/_/g;
115 0         0 $self->{'_prefix_id'} = "$value";
116             }
117             # Attempt to set from the parsed values if not explicitly setted
118 13 100       41 $self->{'_prefix_id'} = $self->safe_value('prefix_id') unless defined $self->{'_prefix_id'};
119 13         56 return $self->{'_prefix_id'};
120             }
121              
122             =head2 init_id
123              
124             =cut
125              
126             sub init_id {
127 7     7 1 15 my($self,$value) = @_;
128 7 50       21 $self->{'_init_id'} = $value if defined $value;
129 7   100     31 $self->{'_init_id'} ||= 1;
130 7         22 return $self->{'_init_id'};
131             }
132              
133             =head2 format
134              
135             =cut
136              
137             sub format {
138 10     10 1 20 my($self,$value) = @_;
139 10         45 $value = $self->_qualify_format($value);
140 10 100       31 $self->{'_format'} = $value if $value;
141 10         51 return $self->{'_format'};
142             }
143              
144              
145              
146             =head2 add_rule
147              
148             Appends rules to the rules set.
149              
150             =head2 Arguments
151              
152             One or more L<Bio::Polloc::RuleI> objects
153              
154             =head2 Returns
155              
156             The index of the last rule
157              
158             =head2 Throws
159              
160             A L<Bio::Polloc::Polloc::Error> exception if some object is not a L<Bio::Polloc::RuleI>
161              
162             =cut
163              
164             sub add_rule {
165 6     6 1 12 my($self, @rules) = @_;
166 6 50       22 return unless $#rules >= 0;
167 6         30 $self->get_rules; #<- to initialize the array if does not exist
168 6         15 for my $rule (@rules){
169 6 50       47 $self->throw("Trying to add an illegal class of Rule", $rule)
170             unless $rule->isa('Bio::Polloc::RuleI');
171 6         39 $rule->ruleset($self);
172 6         9 push @{$self->{'_registered_rules'}}, $rule;
  6         22  
173             }
174 6         9 return $#{$self->{'_registered_rules'}};
  6         22  
175             }
176              
177              
178             =head2 get_rule
179              
180             Gets the rule at the given index
181              
182             B<Arguments>
183              
184             The index (int)
185              
186             B<Returns>
187              
188             A L<Bio::Polloc::RuleI> object or undef
189              
190             =cut
191              
192             sub get_rule {
193 22     22 1 34 my($self,$index) = @_;
194 22 50       42 return unless defined $index;
195 22 50       42 return if $index < 0;
196 22 100       21 return if $index > $#{$self->get_rules};
  22         42  
197 21         40 return $self->get_rules->[$index];
198             }
199              
200             =head2 get_rules
201              
202             =cut
203              
204             sub get_rules {
205 50     50 1 63 my($self, @args) = @_;
206 50   100     114 $self->{'_registered_rules'} ||= [];
207 50         142 return $self->{'_registered_rules'};
208             }
209              
210             =head2 next_rule
211              
212             B<Returns>
213              
214             A L<Bio::Polloc::RuleI> object
215              
216             =cut
217             sub next_rule {
218 4     4 1 8 my($self, @args) = @_;
219 4   100     23 my $rule = $self->get_rule($self->{'_loop_index_rules'} || 0);
220 4         8 $self->{'_loop_index_rules'}++;
221 4 100       26 $self->_end_rules_loop unless $rule;
222 4         12 return $rule;
223             }
224              
225             =head2 groupcriteria
226              
227             Sets/gets the group criteria objects.
228              
229             B<Arguments>
230              
231             A L<Bio::Polloc::GroupCriteria> array ref (optional)
232              
233             B<Returns>
234              
235             A L<Bio::Polloc::GroupCriteria> array ref or undef
236              
237             =cut
238              
239             sub groupcriteria {
240 8     8 1 722 my($self,$value) = @_;
241 8 50       24 $self->{'_grouprules'} = $value if defined $value;
242 8         44 return $self->{'_grouprules'};
243             }
244              
245             =head2 grouprules
246              
247             Alias of L<groupcriteria> (for backwards-compatibility).
248              
249             =cut
250              
251 4     4 1 35 sub grouprules { return shift->groupcriteria(@_) }
252              
253             =head2 addgrouprules
254              
255             Adds a grouprules object
256              
257             B<Arguments>
258              
259             A L<Bio::Polloc::GroupCriteria> object
260              
261             B<Throws>
262              
263             A L<Bio::Polloc::Polloc::Error> if not a proper object
264              
265             =cut
266              
267             sub addgrouprules {
268 3     3 1 8 my($self,$value) = @_;
269 3 50       30 $self->throw("Illegal grouprules object",$value) unless $value->isa("Bio::Polloc::GroupCriteria");
270 3 50       17 $self->{'_grouprules'} = [] unless defined $self->{'_grouprules'};
271 3         6 push @{$self->{'_grouprules'}}, $value;
  3         30  
272             }
273              
274             =head2 execute
275              
276             Executes the executable rules only over the whole list of genomes
277              
278             B<Arguments>
279              
280             Any argument supported/required by the rules, plus:
281              
282             =over
283              
284             =item -advance L<sub ref>
285              
286             A reference to a method to be called to report the advance
287             of the execution. The method must accept four arguments,
288             namely:
289              
290             =over
291              
292             =item 1
293              
294             The number of loci detected so far
295              
296             =item 2
297              
298             The number of genomes scanned so far
299              
300             =item 3
301              
302             The total number of genomes to scan
303              
304             =item 4
305              
306             The ID of the running rule
307              
308             =back
309              
310             =back
311              
312             B<Returns>
313              
314             A L<Bio::Polloc::LociGroup> object.
315              
316             =cut
317              
318             sub execute {
319 0     0 1 0 my($self, @args) = @_;
320 0         0 $self->debug("Evaluating executable rules");
321 0         0 my($advance) = $self->_rearrange([qw(ADVANCE)], @args);
322 0         0 my $locigroup = Bio::Polloc::LociGroup->new(
323             -name=>'Full collection - '.time().".".rand(1000),
324             -genomes=>$self->genomes);
325 0 0       0 $self->throw("Impossible to execute without genomes") unless defined $self->genomes;
326 0         0 for my $gk (0 .. $#{$self->genomes}){
  0         0  
327 0         0 my $genome = $self->genomes->[$gk];
328 0         0 $self->_end_rules_loop;
329 0         0 my $rulek = 0;
330 0         0 while ( my $rule = $self->next_rule ){
331 0         0 $rulek++;
332 0         0 $self->debug("On " . $self->{'_loop_index_rules'});
333 0 0       0 if($rule->executable){
334 0         0 $self->debug("RUN! on ".($#{$genome->get_sequences}+1)." sequences");
  0         0  
335 0         0 for my $seq (@{$genome->get_sequences}){
  0         0  
336 0         0 for my $locus (@{ $rule->execute(-seq=>$seq, @args) }){
  0         0  
337 0         0 $locus->genome($genome);
338 0         0 $locigroup->add_loci($locus);
339             }
340 0 0       0 &$advance($#{$locigroup->loci}+1, $gk+1, $#{$self->genomes}+1, $rulek)
  0         0  
  0         0  
341             if defined $advance;
342             }
343             }
344             }
345 0         0 $self->_increase_index;
346             }
347 0         0 $self->debug("Got ".($#{$locigroup->loci}+1)." loci");
  0         0  
348 0         0 return $locigroup;
349             }
350              
351             =head2 safe_value
352              
353             Sets/gets a parameter of arbitrary name and value
354              
355             B<Purpose>
356              
357             To provide a safe interface for setting values from the parsed file
358              
359             B<Arguments>
360              
361             =over
362              
363             =item -param
364              
365             The parameter's name (case insensitive)
366              
367             =item -value
368              
369             The value of the parameter (optional)
370              
371             =back
372              
373             B<Returns>
374              
375             The value of the parameter or undef
376              
377             =cut
378              
379             sub safe_value {
380 18     18 1 42 my ($self,@args) = @_;
381 18         79 my($param,$value) = $self->_rearrange([qw(PARAM VALUE)], @args);
382 18   100     70 $self->{'_values'} ||= {};
383 18 50       41 return unless $param;
384 18         31 $param = lc $param;
385 18 100       49 if(defined $value){
386 9         41 $self->{'_values'}->{$param} = $value;
387             }
388 18         99 return $self->{'_values'}->{$param};
389             }
390              
391              
392             =head2 parameter
393              
394             B<Purpose>
395              
396             Gets/sets some generic parameter. It is intended to provide an
397             interface between L<Bio::Polloc::RuleIO>'s general configuration and
398             L<Bio::Polloc::RuleI>, regardless of the format.
399              
400             B<Arguments>
401              
402             The key (str) and the value (mix, optional)
403              
404             B<Returns>
405              
406             The value (mix or undef)
407              
408             B<Throws>
409              
410             A L<Bio::Polloc::Polloc::NotImplementedException> if not implemented
411              
412             =cut
413              
414             sub parameter {
415 0     0 1 0 my $self = shift;
416 0         0 $self->throw("parameter",$self,"Bio::Polloc::Polloc::NotImplementedException");
417             }
418              
419             =head2 read
420              
421             =cut
422              
423             sub read {
424 0     0 1 0 my $self = shift;
425 0         0 $self->throw("read",$self,"Bio::Polloc::Polloc::NotImplementedException");
426             }
427              
428             =head2 genomes
429              
430             Gets/sets the genomes to be used as analysis base.
431              
432             B<Arguments>
433              
434             A reference to an array of L<Bio::Polloc::Genome> objects.
435              
436             =cut
437              
438             sub genomes {
439 7     7 1 18 my($self, $value) = @_;
440 7 100       24 $self->{'_genomes'} = $value if defined $value;
441 7 100       23 return unless defined $self->{'_genomes'};
442 4 50 33     31 $self->throw("Unexpected type of genomes collection", $self->{'_genomes'})
443             unless ref($self->{'_genomes'}) and ref($self->{'_genomes'})=~m/ARRAY/i;
444 4         16 return $self->{'_genomes'};
445             }
446              
447             =head1 INTERNAL METHODS
448              
449             Methods intended to be used only within the scope of Bio::Polloc::*
450              
451             =head2 _register_rule_parse
452              
453             =cut
454              
455             sub _register_rule_parse {
456 0     0   0 my $self = shift;
457 0         0 $self->throw("_register_rule_parse",$self,"Bio:Polloc::Polloc::NotImplementedException");
458             }
459              
460             =head2 _increase_index
461              
462             =cut
463              
464             sub _increase_index {
465 0     0   0 my $self = shift;
466 0         0 while ( my $rule = $self->next_rule ){
467 0         0 my $nid = $self->_next_child_id;
468 0 0       0 $rule->id($nid) if defined $nid;
469 0         0 $rule->restart_index;
470             }
471             }
472              
473             =head2 _next_child_id
474              
475             =cut
476              
477             sub _next_child_id {
478 6     6   9 my $self = shift;
479 6 50       41 return unless defined $self->prefix_id;
480 6   66     28 $self->{'_next_child_id'} ||= $self->init_id;
481 6         21 return $self->prefix_id . ":" . ($self->{'_next_child_id'}++);
482             }
483              
484             =head2 _initialize
485              
486             =cut
487              
488             sub _initialize {
489 0     0   0 my($self,@args) = @_;
490 0         0 $self->throw("_initialize", $self, "Bio::Polloc::Polloc::NotImplementedException");
491             }
492              
493             =head2 _qualify_format
494              
495             =cut
496              
497             sub _qualify_format {
498 13     13   29 my($caller, $format) = @_;
499 13 100       36 return unless $format;
500 6         18 $format = lc $format;
501 6 100       47 $format = "cfg" if $format =~ /^(conf|config|bme)$/;
502 6 50       37 return $format if $format =~ /^(cfg)$/;
503 0         0 return;
504             }
505              
506             =head2 _end_rules_loop
507              
508             =cut
509              
510 1     1   2 sub _end_rules_loop { shift->{'_loop_index_rules'} = 0 }
511              
512             1;