File Coverage

blib/lib/Bio/Phylo/Matrices/TypeSafeData.pm
Criterion Covered Total %
statement 84 95 88.4
branch 18 26 69.2
condition 10 21 47.6
subroutine 19 21 90.4
pod 12 12 100.0
total 143 175 81.7


line stmt bran cond sub pod time code
1             package Bio::Phylo::Matrices::TypeSafeData;
2 16     16   105 use strict;
  16         30  
  16         395  
3 16     16   66 use base 'Bio::Phylo::Listable';
  16         28  
  16         3305  
4 16     16   91 use Bio::Phylo::Util::Exceptions 'throw';
  16         30  
  16         719  
5 16     16   90 use Bio::Phylo::Util::CONSTANT qw'_MATRIX_ /looks_like/';
  16         29  
  16         2094  
6 16     16   5548 use Bio::Phylo::Matrices::Datatype;
  16         45  
  16         91  
7             {
8             my $logger = __PACKAGE__->get_logger;
9             my %type;
10             my $MATRIX_CONSTANT = _MATRIX_;
11              
12             =head1 NAME
13              
14             Bio::Phylo::Matrices::TypeSafeData - Superclass for objects that contain
15             character data
16              
17             =head1 SYNOPSIS
18              
19             # No direct usage
20              
21             =head1 DESCRIPTION
22              
23             This is a superclass for objects holding character data. Objects that inherit
24             from this class (typically matrices and datum objects) yield functionality to
25             handle datatype objects and use them to validate data such as DNA sequences,
26             continuous data etc.
27              
28             =head1 METHODS
29              
30             =head2 CONSTRUCTOR
31              
32             =over
33              
34             =item new()
35              
36             TypeSafeData constructor.
37              
38             Type : Constructor
39             Title : new
40             Usage : No direct usage, is called by child class;
41             Function: Instantiates a Bio::Phylo::Matrices::TypeSafeData
42             Returns : a Bio::Phylo::Matrices::TypeSafeData child class
43             Args : -type => (data type - required)
44             Optional:
45             -missing => (the symbol for missing data)
46             -gap => (the symbol for gaps)
47             -lookup => (a character state lookup hash)
48             -type_object => (a datatype object)
49              
50             =cut
51              
52             sub new : Constructor {
53              
54             # is child class
55 988     988 1 2153 my $class = shift;
56              
57             # process args
58 988         4353 my %args = looks_like_hash @_;
59              
60             # notify user
61 988 100 100     4040 if ( not $args{'-type'} and not $args{'-type_object'} ) {
62 112         413 $logger->info("No data type provided, will use 'standard'");
63 112         307 unshift @_, '-type', 'standard';
64             }
65 988 100       3218 if ( $args{'-characters'} ) {
66 38 100       125 if ( $args{'-type'} ) {
    50          
67 20         85 $args{'-characters'}->set_type( $args{'-type'} );
68             }
69             elsif ( $args{'-type_object'} ) {
70 0         0 $args{'-characters'}->set_type_object( $args{'-type_object'} );
71             }
72             }
73              
74             # notify user
75 988         4656 $logger->debug("constructor called for '$class'");
76              
77             # go up inheritance tree, eventually get an ID
78 988         4562 return $class->SUPER::new(@_);
79 16     16   123 }
  16         35  
  16         354  
80              
81             =back
82              
83             =head2 MUTATORS
84              
85             =over
86              
87             =item set_type()
88              
89             Set data type.
90              
91             Type : Mutator
92             Title : set_type
93             Usage : $obj->set_type($type);
94             Function: Sets the object's datatype.
95             Returns : Modified object.
96             Args : Argument must be a string, one of
97             continuous, custom, dna, mixed,
98             protein, restriction, rna, standard
99              
100             =cut
101              
102             sub set_type {
103 786     786 1 3112 my $self = shift;
104 786         1516 my $arg = shift;
105 786         1524 my ( $type, @args );
106 786 50       2773 if ( looks_like_instance( $arg, 'ARRAY' ) ) {
107 0         0 @args = @{$arg};
  0         0  
108 0         0 $type = shift @args;
109             }
110             else {
111 786         2128 @args = @_;
112 786         1661 $type = $arg;
113             }
114 786         3934 $logger->info("setting type '$type'");
115 786         4225 my $obj = Bio::Phylo::Matrices::Datatype->new( $type, @args );
116 785         3356 $self->set_type_object($obj);
117 785 100 66     4490 if ( UNIVERSAL::can($self,'_type') and $self->_type == $MATRIX_CONSTANT ) {
118 47         86 for my $row ( @{ $self->get_entities } ) {
  47         113  
119 0         0 $row->set_type_object($obj);
120             }
121             }
122 785         2244 return $self;
123             }
124              
125             =item set_missing()
126              
127             Set missing data symbol.
128              
129             Type : Mutator
130             Title : set_missing
131             Usage : $obj->set_missing('?');
132             Function: Sets the symbol for missing data
133             Returns : Modified object.
134             Args : Argument must be a single
135             character, default is '?'
136              
137             =cut
138              
139             sub set_missing {
140 9     9 1 20 my ( $self, $missing ) = @_;
141 9 50 33     53 if ( $self->can('get_matchchar') and $self->get_matchchar and $missing eq $self->get_matchchar )
      33        
142             {
143 0         0 throw 'BadArgs' =>
144             "Missing character '$missing' already in use as match character";
145             }
146 9         43 $logger->info("setting missing '$missing'");
147 9         24 $self->get_type_object->set_missing($missing);
148 9         27 $self->validate;
149 9         28 return $self;
150             }
151              
152             =item set_gap()
153              
154             Set gap data symbol.
155              
156             Type : Mutator
157             Title : set_gap
158             Usage : $obj->set_gap('-');
159             Function: Sets the symbol for gaps
160             Returns : Modified object.
161             Args : Argument must be a single
162             character, default is '-'
163              
164             =cut
165              
166             sub set_gap {
167 9     9 1 24 my ( $self, $gap ) = @_;
168 9 50 33     148 if ( $self->can('get_matchchar') and $self->get_matchchar and $self->get_matchchar eq $gap ) {
      33        
169 0         0 throw 'BadArgs' =>
170             "Gap character '$gap' already in use as match character";
171             }
172 9         66 $logger->info("setting gap '$gap'");
173 9         34 $self->get_type_object->set_gap($gap);
174 9         26 $self->validate;
175 9         31 return $self;
176             }
177              
178             =item set_lookup()
179              
180             Set ambiguity lookup table.
181              
182             Type : Mutator
183             Title : set_lookup
184             Usage : $obj->set_gap($hashref);
185             Function: Sets the symbol for gaps
186             Returns : Modified object.
187             Args : Argument must be a hash
188             reference that maps allowed
189             single character symbols
190             (including ambiguity symbols)
191             onto the equivalent set of
192             non-ambiguous symbols
193              
194             =cut
195              
196             sub set_lookup {
197 2     2 1 11 my ( $self, $lookup ) = @_;
198 2         8 $logger->info("setting character state lookup hash");
199 2         3 $self->get_type_object->set_lookup($lookup);
200 2         4 $self->validate;
201 2         6 return $self;
202             }
203              
204             =item set_type_object()
205              
206             Set data type object.
207              
208             Type : Mutator
209             Title : set_type_object
210             Usage : $obj->set_gap($obj);
211             Function: Sets the datatype object
212             Returns : Modified object.
213             Args : Argument must be a subclass
214             of Bio::Phylo::Matrices::Datatype
215              
216             =cut
217              
218             sub set_type_object : Clonable DeepClonable {
219 1078     1078 1 2403 my ( $self, $obj ) = @_;
220 1078         3221 $logger->info("setting character type object");
221 1078         3167 $type{ $self->get_id } = $obj;
222 1078         2506 eval { $self->validate };
  1078         2985  
223 1078 100       3082 if ($@) {
224 3         30 undef($@);
225 3 50       10 if ( my @char = $self->get_char ) {
226 3         9 $self->clear;
227 3         14 $logger->warn(
228             "Data contents of $self were invalidated by new type object."
229             );
230             }
231             }
232 1078         2041 return $self;
233 16     16   9257 }
  16         32  
  16         60  
234              
235             =back
236              
237             =head2 ACCESSORS
238              
239             =over
240              
241             =item get_type()
242              
243             Get data type.
244              
245             Type : Accessor
246             Title : get_type
247             Usage : my $type = $obj->get_type;
248             Function: Returns the object's datatype
249             Returns : A string
250             Args : None
251              
252             =cut
253              
254             sub get_type {
255 34     34 1 119 my $to = shift->get_type_object;
256 34 50       94 if ($to) {
257 34         122 return $to->get_type;
258             }
259             else {
260 0         0 throw 'API' => "Missing data type object!";
261             }
262             }
263              
264             =item get_missing()
265              
266             Get missing data symbol.
267              
268             Type : Accessor
269             Title : get_missing
270             Usage : my $missing = $obj->get_missing;
271             Function: Returns the object's missing data symbol
272             Returns : A string
273             Args : None
274              
275             =cut
276              
277             sub get_missing {
278 724     724 1 2371 my $to = shift->get_type_object;
279 724 50       2043 if ($to) {
280 724         2398 return $to->get_missing;
281             }
282             else {
283 0         0 throw 'API' => "Missing data type object!";
284             }
285             }
286              
287             =item get_gap()
288              
289             Get gap symbol.
290              
291             Type : Accessor
292             Title : get_gap
293             Usage : my $gap = $obj->get_gap;
294             Function: Returns the object's gap symbol
295             Returns : A string
296             Args : None
297              
298             =cut
299              
300 11     11 1 27 sub get_gap { shift->get_type_object->get_gap }
301              
302             =item get_lookup()
303              
304             Get ambiguity lookup table.
305              
306             Type : Accessor
307             Title : get_lookup
308             Usage : my $lookup = $obj->get_lookup;
309             Function: Returns the object's lookup hash
310             Returns : A hash reference
311             Args : None
312              
313             =cut
314              
315 0     0 1 0 sub get_lookup { shift->get_type_object->get_lookup }
316              
317             =item get_type_object()
318              
319             Get data type object.
320              
321             Type : Accessor
322             Title : get_type_object
323             Usage : my $obj = $obj->get_type_object;
324             Function: Returns the object's linked datatype object
325             Returns : A subclass of Bio::Phylo::Matrices::Datatype
326             Args : None
327              
328             =cut
329              
330 3497     3497 1 9071 sub get_type_object { $type{ $_[0]->get_id } }
331              
332             =back
333              
334             =head2 INTERFACE METHODS
335              
336             =over
337              
338             =item validate()
339              
340             Validates the object's contents
341              
342             Type : Interface method
343             Title : validate
344             Usage : $obj->validate
345             Function: Validates the object's contents
346             Returns : True or throws Bio::Phylo::Util::Exceptions::InvalidData
347             Args : None
348             Comments: This is an abstract method, i.e. this class doesn't
349             implement the method, child classes have to
350              
351             =cut
352              
353             sub validate {
354 1098     1098 1 4097 shift->_validate;
355             }
356              
357             sub _validate {
358 0     0   0 throw 'NotImplemented' => 'Not implemented!';
359             }
360              
361             sub _cleanup {
362 1978     1978   3616 my $self = shift;
363 1978 50 33     7503 if ( $self and defined( my $id = $self->get_id ) ) {
364 1978         4591 delete $type{ $self->get_id };
365             }
366             }
367             }
368              
369             =back
370              
371             =cut
372              
373             # podinherit_insert_token
374              
375             =head1 SEE ALSO
376              
377             There is a mailing list at L<https://groups.google.com/forum/#!forum/bio-phylo>
378             for any user or developer questions and discussions.
379              
380             =over
381              
382             =item L<Bio::Phylo::Listable>
383              
384             This object inherits from L<Bio::Phylo::Listable>, so the methods defined
385             therein are also applicable to L<Bio::Phylo::Matrices::TypeSafeData> objects.
386              
387             =item L<Bio::Phylo::Manual>
388              
389             Also see the manual: L<Bio::Phylo::Manual> and L<http://rutgervos.blogspot.com>.
390              
391             =back
392              
393             =head1 CITATION
394              
395             If you use Bio::Phylo in published research, please cite it:
396              
397             B<Rutger A Vos>, B<Jason Caravas>, B<Klaas Hartmann>, B<Mark A Jensen>
398             and B<Chase Miller>, 2011. Bio::Phylo - phyloinformatic analysis using Perl.
399             I<BMC Bioinformatics> B<12>:63.
400             L<http://dx.doi.org/10.1186/1471-2105-12-63>
401              
402             =cut
403              
404             1;