File Coverage

blib/lib/Bio/MUST/Core/Taxonomy/Classifier.pm
Criterion Covered Total %
statement 21 57 36.8
branch 0 2 0.0
condition 0 3 0.0
subroutine 7 13 53.8
pod 3 3 100.0
total 31 78 39.7


line stmt bran cond sub pod time code
1             package Bio::MUST::Core::Taxonomy::Classifier;
2             # ABSTRACT: Helper class for multiple-criterion classifier based on taxonomy
3             $Bio::MUST::Core::Taxonomy::Classifier::VERSION = '0.212670';
4 17     17   10888 use Moose;
  17         50  
  17         139  
5 17     17   121166 use namespace::autoclean;
  17         54  
  17         161  
6              
7             # use Smart::Comments;
8              
9 17     17   1658 use Const::Fast;
  17         56  
  17         171  
10 17     17   1829 use List::AllUtils qw(indexes mesh partition_by pairmap);
  17         61  
  17         1449  
11              
12 17     17   169 use Bio::MUST::Core::Types;
  17         57  
  17         546  
13 17     17   116 use aliased 'Bio::MUST::Core::IdList';
  17         53  
  17         128  
14 17     17   3439 use aliased 'Bio::MUST::Core::SeqMask';
  17         48  
  17         79  
15              
16              
17             has 'categories' => (
18             traits => ['Array'],
19             is => 'ro',
20             isa => 'ArrayRef[Bio::MUST::Core::Taxonomy::Category]',
21             required => 1,
22             handles => {
23             all_categories => 'elements',
24             },
25             );
26              
27              
28              
29             sub all_labels {
30 0     0 1   my $self = shift;
31 0           return map { $_->label } $self->all_categories;
  0            
32             }
33              
34              
35              
36             sub classify {
37 0     0 1   my $self = shift;
38 0           my $listable = shift;
39              
40             # loop through cats and return the first one matching input
41             # this means that the cat order may affect the classification
42 0           for my $cat ($self->all_categories) {
43 0 0         return $cat->label if $cat->matches($listable);
44             }
45              
46             # return undef if no suitable cat
47 0           return;
48             }
49              
50              
51             # "magic" name used when a pattern has no category
52             const my $NOCAT => '_NOCAT_';
53              
54             # TODO: come with better name for method?
55             # TODO: provide a shortcut if only one cat?
56              
57             sub tax_masks {
58 0     0 1   my $self = shift;
59 0           my $ali = shift;
60              
61             # TODO: profile and optimize as ideal_mask ?!?
62              
63 0           my $width = $ali->width;
64 0           my $regex = $ali->gapmiss_regex;
65              
66             # collect site patterns in terms of valid states
67 0           my %sites_for;
68 0           for (my $site = 0; $site < $width; $site++) {
69             my @indexes = # get seq indexes of states
70 0     0     indexes { $_ !~ m/$regex/xms } # which are valid
71 0           map { $_->state_at($site) } # and found at that site
  0            
72             $ali->all_seqs; # across all seqs
73             ;
74             #### @indexes
75              
76             # store site for index pattern
77 0           my $key = join q{,}, @indexes;
78 0           push @{ $sites_for{$key} }, $site;
  0            
79             }
80             #### %sites_for
81              
82             # setup keys from patterns
83 0           my @patterns = keys %sites_for;
84             #### @patterns
85              
86             # fetch id lists for site patterns
87             # Note: type coercion allows building an IdList from an ArrayRef[Seq]
88             my @lists = map {
89 0           IdList->new( ids => [ @{ $ali->seqs }[ split q{,} ] ] )
  0            
  0            
90             } @patterns;
91             #### @lists
92              
93             # attribute categories to site patterns based on corresponding id lists
94 0   0       my @cats = map { $self->classify($_) // $NOCAT } @lists;
  0            
95             #### @cats
96 0           my %cat_for = mesh @patterns, @cats;
97             #### %cat_for
98              
99             # partition patterns by category to build masks
100             # Note: masks are defined by flattening of patterns' site lists
101 0     0     my %patterns_for = partition_by { $cat_for{$_} } @patterns;
  0            
102 0           delete $patterns_for{$NOCAT};
103             #### %patterns_for
104              
105             my %mask_for = pairmap {
106             $a => SeqMask->custom_mask(
107 0     0     $width, [ map { @{$_} } @sites_for{ @{$b} } ]
  0            
  0            
  0            
108             )
109 0           } %patterns_for;
110             #### %mask_for
111              
112 0           return \%mask_for;
113             }
114              
115             __PACKAGE__->meta->make_immutable;
116             1;
117              
118             __END__
119              
120             =pod
121              
122             =head1 NAME
123              
124             Bio::MUST::Core::Taxonomy::Classifier - Helper class for multiple-criterion classifier based on taxonomy
125              
126             =head1 VERSION
127              
128             version 0.212670
129              
130             =head1 SYNOPSIS
131              
132             # TODO
133              
134             =head1 DESCRIPTION
135              
136             # TODO
137              
138             =head1 METHODS
139              
140             =head2 all_labels
141              
142             =head2 classify
143              
144             =head2 tax_masks
145              
146             =head1 AUTHOR
147              
148             Denis BAURAIN <denis.baurain@uliege.be>
149              
150             =head1 COPYRIGHT AND LICENSE
151              
152             This software is copyright (c) 2013 by University of Liege / Unit of Eukaryotic Phylogenomics / Denis BAURAIN.
153              
154             This is free software; you can redistribute it and/or modify it under
155             the same terms as the Perl 5 programming language system itself.
156              
157             =cut