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   114 use strict;
  16         32  
  16         434  
3 16     16   73 use base 'Bio::Phylo::Listable';
  16         31  
  16         3636  
4 16     16   102 use Bio::Phylo::Util::Exceptions 'throw';
  16         31  
  16         793  
5 16     16   90 use Bio::Phylo::Util::CONSTANT qw'_MATRIX_ /looks_like/';
  16         34  
  16         2469  
6 16     16   5997 use Bio::Phylo::Matrices::Datatype;
  16         41  
  16         110  
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 1699 my $class = shift;
56              
57             # process args
58 988         2837 my %args = looks_like_hash @_;
59              
60             # notify user
61 988 100 100     3238 if ( not $args{'-type'} and not $args{'-type_object'} ) {
62 112         419 $logger->info("No data type provided, will use 'standard'");
63 112         323 unshift @_, '-type', 'standard';
64             }
65 988 100       2167 if ( $args{'-characters'} ) {
66 38 100       146 if ( $args{'-type'} ) {
    50          
67 20         80 $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         3403 $logger->debug("constructor called for '$class'");
76              
77             # go up inheritance tree, eventually get an ID
78 988         3284 return $class->SUPER::new(@_);
79 16     16   139 }
  16         38  
  16         76  
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 4212 my $self = shift;
104 786         1136 my $arg = shift;
105 786         1218 my ( $type, @args );
106 786 50       1919 if ( looks_like_instance( $arg, 'ARRAY' ) ) {
107 0         0 @args = @{$arg};
  0         0  
108 0         0 $type = shift @args;
109             }
110             else {
111 786         1324 @args = @_;
112 786         1178 $type = $arg;
113             }
114 786         2523 $logger->info("setting type '$type'");
115 786         2778 my $obj = Bio::Phylo::Matrices::Datatype->new( $type, @args );
116 785         2379 $self->set_type_object($obj);
117 785 100 66     3213 if ( UNIVERSAL::can($self,'_type') and $self->_type == $MATRIX_CONSTANT ) {
118 47         96 for my $row ( @{ $self->get_entities } ) {
  47         122  
119 0         0 $row->set_type_object($obj);
120             }
121             }
122 785         1783 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 29 my ( $self, $missing ) = @_;
141 9 50 33     68 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         58 $logger->info("setting missing '$missing'");
147 9         29 $self->get_type_object->set_missing($missing);
148 9         27 $self->validate;
149 9         37 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 29 my ( $self, $gap ) = @_;
168 9 50 33     212 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         68 $logger->info("setting gap '$gap'");
173 9         79 $self->get_type_object->set_gap($gap);
174 9         31 $self->validate;
175 9         40 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 7 my ( $self, $lookup ) = @_;
198 2         5 $logger->info("setting character state lookup hash");
199 2         8 $self->get_type_object->set_lookup($lookup);
200 2         9 $self->validate;
201 2         8 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 1891 my ( $self, $obj ) = @_;
220 1078         2686 $logger->info("setting character type object");
221 1078         2425 $type{ $self->get_id } = $obj;
222 1078         1989 eval { $self->validate };
  1078         2339  
223 1078 100       2397 if ($@) {
224 3         51 undef($@);
225 3 50       16 if ( my @char = $self->get_char ) {
226 3         14 $self->clear;
227 3         20 $logger->warn(
228             "Data contents of $self were invalidated by new type object."
229             );
230             }
231             }
232 1078         1772 return $self;
233 16     16   10313 }
  16         39  
  16         67  
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 123 my $to = shift->get_type_object;
256 34 50       132 if ($to) {
257 34         148 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 1267 my $to = shift->get_type_object;
279 724 50       1598 if ($to) {
280 724         1613 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 30 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 6983 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 2929 shift->_validate;
355             }
356              
357             sub _validate {
358 0     0   0 throw 'NotImplemented' => 'Not implemented!';
359             }
360              
361             sub _cleanup {
362 1978     1978   2866 my $self = shift;
363 1978 50 33     5277 if ( $self and defined( my $id = $self->get_id ) ) {
364 1978         3690 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
378             for any user or developer questions and discussions.
379              
380             =over
381              
382             =item L
383              
384             This object inherits from L, so the methods defined
385             therein are also applicable to L objects.
386              
387             =item L
388              
389             Also see the manual: L and L.
390              
391             =back
392              
393             =head1 CITATION
394              
395             If you use Bio::Phylo in published research, please cite it:
396              
397             B, B, B, B
398             and B, 2011. Bio::Phylo - phyloinformatic analysis using Perl.
399             I B<12>:63.
400             L
401              
402             =cut
403              
404             1;