File Coverage

blib/lib/Bio/Polloc/TypingI.pm
Criterion Covered Total %
statement 43 87 49.4
branch 18 38 47.3
condition 1 21 4.7
subroutine 7 18 38.8
pod 9 9 100.0
total 78 173 45.0


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             Bio::Polloc::TypingI - Generic typing interface
4              
5             =head1 DESCRIPTION
6              
7             Use this interface to initialize the Bio::Polloc::Typing::* objects. Any
8             rule inherits from this Interface. Usually, rules are initialized
9             from files (via the L<Bio::Polloc::TypingIO> package).
10              
11             =head1 AUTHOR - Luis M. Rodriguez-R
12              
13             Email lrr at cpan dot org
14              
15             =head1 IMPLEMENTS OR EXTENDS
16              
17             =over
18              
19             =item *
20              
21             L<Bio::Polloc::Polloc::Root>
22              
23             =back
24              
25             =cut
26              
27             package Bio::Polloc::TypingI;
28 2     2   12 use strict;
  2         4  
  2         82  
29 2     2   10 use base qw(Bio::Polloc::Polloc::Root);
  2         4  
  2         200  
30 2     2   10 use Error qw(:try);
  2         3  
  2         19  
31             our $VERSION = 1.0503; # [a-version] from Bio::Polloc::Polloc::Version
32              
33              
34             =head1 APPENDIX
35              
36             Methods provided by the package
37              
38             =cut
39              
40             =head2 new
41              
42             Attempts to initialize a C<Bio::Polloc::Typing::*> object
43              
44             B<Arguments>
45              
46             =over
47              
48             =item -type I<str>
49              
50             The typing method. For further description of the
51             different type, see:
52              
53             Li, W., Raoult, D., & Fournier, P.-E. (2009).
54             Bacterial strain typing in the genomic era.
55             FEMS Microbiology Reviews, 33(5), 892-916.
56              
57             L<http://www.mendeley.com/research/bacterial-strain-typing-in-the-genomic-era/>.
58              
59             One of:
60              
61             =over
62              
63             =item bandingPattern
64              
65             "DNA banding pattern-based methods which classify bacteria
66             according to the size of fragments generated by amplification
67             and/or enzymatic digestion of genomic DNA" (Li I<et al> 2009)
68              
69             =item bandingPattern::amplification
70              
71             Same of C<bandingPattern>, but specifying fragments generated
72             B<by amplification>.
73              
74             =item bandingPattern::restriction
75              
76             Same of C<bandingPattern>, but specifying fragments generated
77             B<by enzymatic digestion>.
78              
79             =item sequencing
80              
81             "DNA sequencing-based methods, which study the polymorphism of
82             DNA sequences" (Li I<et al> 2009)
83              
84             =item hybridization
85              
86             "DNA hybridization-based methods using nucleotidic probes" (Li
87             I<et al> 2009)
88              
89             =back
90              
91             =item -locigroup I<Bio::Polloc::LociGroup object>
92              
93             Group of loci (L<Bio::Polloc::LociGroup>) to be use for typing.
94              
95             =back
96              
97             B<Returns>
98              
99             The C<Bio::Polloc::Typing::*> object
100              
101             B<Throws>
102              
103             L<Bio::Polloc::Polloc::Error> if unable to initialize the proper object
104              
105             =cut
106              
107             sub new {
108 2     2 1 7 my($caller,@args) = @_;
109 2   33     12 my $class = ref($caller) || $caller;
110            
111             # Pre-fix based on type, unless the caller is a proper class
112 2 50       7 if($class !~ m/Bio::Polloc::Typing::(\S+)/){
113 2         14 my $bme = Bio::Polloc::Polloc::Root->new(@args);
114 2         10 my($type) = $bme->_rearrange([qw(TYPE)], @args);
115            
116 2 50       9 if($type){
117 2         9 $type = Bio::Polloc::TypingI->_qualify_type($type);
118 2 50       16 $class = "Bio::Polloc::Typing::" . $type if $type;
119             }
120             }
121              
122             # Try to load the object
123 2 50       12 if($class =~ m/Bio::Polloc::Typing::(\S+)/){
124 2 50       18 if(Bio::Polloc::TypingI->_load_module($class)){;
125 2         55 my $self = $class->SUPER::new(@args);
126 2         26 my($locigroup) = $self->_rearrange([qw(LOCIGROUP)], @args);
127 2         34 $self->debug("Got the TypingI class $class ($1)");
128 2         25 $self->locigroup($locigroup);
129 2         17 $self->_initialize(@args);
130 2         33 return $self;
131             }
132 0         0 my $bme = Bio::Polloc::Polloc::Root->new(@args);
133 0         0 $bme->throw("Impossible to load the module", $class);
134             }
135              
136             # Throws exception if any previous return
137 0         0 my $bme = Bio::Polloc::Polloc::Root->new(@args);
138 0         0 $bme->throw("Impossible to load the proper Bio::Polloc::TypingI class with ".
139             "[".join("; ",@args)."]", $class);
140             }
141              
142             =head2 type
143              
144             Gets/sets the type of typing method
145              
146             B<Arguments>
147              
148             Value (I<str>). See L<new> and the corresponding C<Bio::Polloc::Typing::*>
149             objects for further details.
150              
151             Some variations can be introduced, like case variations or short versions like
152             B<banding> or B<seq>.
153              
154             B<Return>
155              
156             Value (I<str>). The typing method, or C<undef> if undefined.
157             The value returned is undef or a string from the above list, regardless of the
158             input variations.
159              
160             B<Throws>
161              
162             L<Bio::Polloc::Polloc::Error> if an unsupported type is received.
163              
164             =cut
165              
166             sub type {
167 5     5 1 783 my($self,$value) = @_;
168 5 100       15 if($value){
169 4         20 my $v = $self->_qualify_type($value);
170 4 50       13 $self->throw("Attempting to set an invalid type of rule",$value) unless $v;
171 4         11 $self->{'_type'} = $v;
172             }
173 5         18 return $self->{'_type'};
174             }
175              
176             =head2 locigroup
177              
178             Sets/gets the group of loci to be used.
179              
180             B<Arguments>
181              
182             A L<Bio::Polloc::LociGroup> object (optional).
183              
184             B<Returns>
185              
186             A L<Bio::Polloc::LociGroup> object or C<undef>.
187              
188             =cut
189              
190             sub locigroup {
191 3     3 1 8 my($self, $value) = @_;
192 3 100       14 $self->{'_locigroup'} = $value if defined $value;
193 3         12 return $self->{'_locigroup'};
194             }
195              
196             =head2 matrix
197              
198             Generates a matrix of values for the given group of loci.
199              
200             B<Arguments>
201              
202             =over
203              
204             =item -locigroup I<Bio::Polloc::LociGroup object>
205              
206             The group of loci to be used as base. If not provided,
207             attempts to find the last value returned by L<scan>.
208             If never called (or not cached by the implementation)
209             looks for the base loci (setted via L<locigroup> or
210             at initialization). If everything fails to provide a
211             base group of loci, warns about it and returns C<undef>.
212              
213             =item -binary I<bool (int)>
214              
215             If true, returns a binary matrix (presence/absence)
216             instead of the native typing value.
217              
218             =item -names I<bool (int)>
219              
220             If true, returns a hash with the names of the genomes as
221             keys instead of an array.
222              
223             =back
224              
225             B<Returns>
226              
227             A reference to an array or a hash (if C<-names> is true). The
228             key correspond to the incremental number or the name of the
229             genomes, and the values can be either numeric or an array of
230             numeric values, depending on the L<typing_value> implemented
231             by the genotyping method. If C<-binary> is true, the values
232             are always 0 or 1, regardless of the typing method.
233              
234             =cut
235              
236             sub matrix {
237 0     0 1 0 my($self, @args) = @_;
238 0         0 my($locigroup, $binary, $names) = $self->_rearrange([qw(LOCIGROUP BINARY NAMES)], @args);
239 0   0     0 $locigroup ||= $self->_scan_locigroup();
240 0   0     0 $locigroup ||= $self->locigroup();
241 0 0       0 unless(defined $locigroup){
242 0         0 $self->warn("Impossible to find the group of loci");
243 0         0 return;
244             }
245 0         0 my $out = $locigroup->structured_loci;
246 0         0 for my $g (0 .. $#$out){
247 0 0       0 $out->[$g] = $binary ? (($#{$out->[$g]}>=0)+0) : $self->typing_value($out->[$g]);
  0         0  
248             }
249 0 0       0 return $out unless $names;
250 0         0 my $outN = {};
251 0         0 $outN->{$locigroup->genomes->[$_]->name} = $out->[$_] for (0 .. $#$out);
252 0         0 return $outN;
253             }
254              
255             =head2 binary
256              
257             Alias of L<matrix> with C<-binary> true.
258              
259             =cut
260              
261             sub binary {
262 0     0 1 0 my($self, @args) = @_;
263 0         0 return $self->matrix(-binary=>1, @args);
264             }
265              
266             =head2 graph
267              
268             Returns a L<GD::Simple> object containing the graphic representation
269             of the typing results.
270              
271             B<Arguments>
272              
273             =over
274              
275             =item -locigroup I<Bio::Polloc::LociGroup>
276              
277             The group to be used as a basis. If any, attempts to locate
278             the last value returned by L<scan>. If never called, looks
279             for the value stored via L<locigroup> or at initialization.
280             Otherwise, warns about it and returns C<undef>,
281              
282             =item -width I<int>
283              
284             Width of the image in pixels. 600 by default.
285              
286             =item -height I<int>
287              
288             Height of the image in pixels. 300 by default.
289              
290             =item -font I<str>
291              
292             Font of the text in the image (if any). 'Times' by default, but
293             certain images require a TrueType Font in order to work properly.
294             This argument is optional, but we strongly reccomend to provide
295             the path to Lucida Sans Regular, or any other similar TrueType
296             Font.
297              
298             =back
299              
300             B<Returns>
301              
302             A L<GD::Simple> object.
303              
304             B<Synopsis>
305              
306             # ...
307             $typing->scan($lociGroup);
308             my $graph = $typing->graph(-font=>'/path/to/LucidaSansRegular.ttf');
309             if($graph){
310             open IMG, ">", "graph.png" or die "I can not open graph.png: $!\n";
311             binmode IMG;
312             print IMG $graph->png;
313             close IMG;
314             }
315              
316             =cut
317              
318             sub graph {
319 0     0 1 0 my($self, @args) = @_;
320 0         0 my($locigroup, $width, $height, $font) = $self->_rearrange([qw(LOCIGROUP WIDTH HEIGHT FONT)], @args);
321 0   0     0 $locigroup ||= $self->_scan_locigroup || $self->locigroup;
      0        
322 0 0       0 unless($locigroup){
323 0         0 $self->warn("Impossible to find a group of loci.");
324 0         0 return;
325             }
326 0     0   0 try { $self->_load_module('GD::Simple'); }
327             catch Bio::Polloc::Polloc::Error with {
328 0     0   0 $self->warn("I need GD::Simple to create the image, impossible to locate it.\n".shift);
329 0         0 return;
330 0     0   0 } otherwise { $self->throw("Non-native error", shift); };
  0         0  
331 0   0     0 $width ||= 600;
332 0   0     0 $height ||= 300;
333 0   0     0 $font ||= 'Times';
334 0         0 return $self->graph_content($locigroup, $width, $height, $font);
335             }
336              
337             =head1 METHODS TO BE IMPLEMENTED
338              
339             Methods that should be implemented by objects using this
340             interface as base. All the methods in this section can
341             throw L<Bio::Polloc::Polloc::NotImplementedException> if not
342             implemented.
343              
344             =head2 scan
345              
346             Scans the genomes using the specified loci as base.
347              
348             B<Arguments>
349              
350             =over
351              
352             =item -locigroup I<Bio::Polloc::LociGroup>
353              
354             Loci to use as genotyping base. Optional if provided via
355             L<locigroup> or at initialization.
356              
357             =back
358              
359             B<Returns>
360              
361             A L<Bio::Polloc::LociGroup> object containing the actual loci
362             employed for typing.
363              
364             =cut
365              
366 0     0 1 0 sub scan { $_[0]->throw("scan", $_[0], "Bio::Polloc::Polloc::NotImplementedException") }
367              
368             =head2 cluster
369              
370             Clusters the genomes based on the provided loci.
371              
372             B<Arguments>
373              
374             =over
375              
376             =item -locigroup I<Bio::Polloc::LociGroup object>
377              
378             The base group of loci. Same behavior as L<matrix>.
379              
380             =back
381              
382             B<Returns>
383              
384             A L<Bio::Tree> object.
385              
386             =cut
387              
388 0     0 1 0 sub cluster { $_[0]->throw("cluster", $_[0], "Bio::Polloc::Polloc::NotImplementedException") }
389              
390             =head2 typing_value
391              
392             Provides a value for the passed loci associated with
393             the typing method.
394              
395             B<Arguments>
396              
397             =over
398              
399             =item -loci I<Array of Bio::Polloc::LocusI>
400              
401             The loci to be evaluated. Note that it is a reference array
402             of L<Bio::Polloc::LocusI> objects, and B<NOT> a L<Bio::Polloc::LociGroup>.
403             This is because all the loci are expected to be part of the
404             same genome, and the same group (if grouped). This argument
405             is mandatory.
406              
407             =back
408              
409             B<Returns>
410              
411             A numeric value or a reference to an array of numeric values,
412             depending on the genotyping method.
413              
414             =cut
415              
416             sub typing_value {
417 0     0 1 0 $_[0]->throw("typing_value", $_[0], "Bio::Polloc::Polloc::NotImplementedException")
418             }
419              
420             =head1 INTERNAL METHODS
421              
422             Methods intended to be used only witin the scope of Bio::Polloc::*
423              
424             =head2 _qualify_type
425              
426             =cut
427              
428             sub _qualify_type {
429 6     6   12 my($self,$value) = @_;
430 6 50       18 return unless $value;
431 6         13 $value = lc $value;
432 6 100       33 $value = "bandingPattern" if $value=~/^banding(?:patt(?:ern)?)?$/;
433 6 100       30 $value = "bandingPattern::amplification"
434             if $value=~/^banding(?:patt(?:ern)?)?::ampl(?:if(?:ication)?)?$/;
435 6 50       20 $value = "bandingPattern::restriction"
436             if $value=~/^banding(?:patt(?:ern)?)?::rest(?:r(?:iction)?)?$/;
437 6 50       16 $value = "sequencing" if $value=~/^seq(?:uenc(?:e|ing))?$/;
438 6 50       14 $value = "hibridization" if $value=~/^hib(?:ridization)?$/;
439 6         13 return $value;
440             }
441              
442             =head2 _scan_locigroup
443              
444             Gets/sets the group of loci after scanning. This should be
445             called at the end of all the implementations of L<scan>.
446              
447             =cut
448              
449             sub _scan_locigroup {
450 0     0     my($self,$value) = @_;
451 0 0         $self->{'_scan_locigroup'} = $value if defined $value;
452 0           return $self->{'_scan_locigroup'};
453             }
454              
455             =head2 _initialize
456              
457             =cut
458              
459             sub _initialize {
460 0     0     my $self = shift;
461 0           $self->throw("_initialize", $self, "Bio::Polloc::Polloc::NotImplementedException");
462             }
463              
464             1;