File Coverage

blib/lib/Bio/ProteaseI.pm
Criterion Covered Total %
statement 61 61 100.0
branch 22 22 100.0
condition 18 18 100.0
subroutine 11 11 100.0
pod 4 4 100.0
total 116 116 100.0


line stmt bran cond sub pod time code
1             package Bio::ProteaseI;
2             {
3             $Bio::ProteaseI::VERSION = '1.112900'; # TRIAL
4             }
5              
6             # ABSTRACT: A role to build your customized Protease
7              
8 6     6   4528 use Moose::Role;
  6         7187  
  6         38  
9 6     6   21878 use Carp 'croak';
  6         11  
  6         302  
10 6     6   985 use namespace::autoclean;
  6         12084  
  6         36  
11              
12             requires '_cuts';
13              
14             sub cut {
15 42     42 1 5871 my ( $self, $substrate, $pos ) = @_;
16              
17 42 100 100     126 croak "Incorrect substrate argument"
18             unless ( defined $substrate and _looks_like_string($substrate) );
19              
20 40 100 100     198 unless ( defined $pos and $pos > 0 and $pos <= length $substrate ) {
      100        
21              
22 3         22 croak "Incorrect position.";
23             }
24              
25 37         42 $substrate = uc $substrate;
26 37         48 $substrate = _cap_head($substrate);
27 37         37 $pos += 3;
28              
29 37         83 my $pep = substr($substrate, $pos - 4, 8);
30              
31 37 100       71 if ( $self->_cuts($pep) ) {
32 8         24 my $product = substr($substrate, 0, $pos);
33 8         14 substr($substrate, 0, $pos) = '';
34              
35 8         16 _uncap($product, $substrate);
36              
37 8         45 return ($product, $substrate);
38             }
39              
40 29         75 else { return }
41             }
42              
43             sub digest {
44 58     58 1 165 my ( $self, $substrate ) = @_;
45              
46 58 100 100     259 croak "Incorrect substrate argument"
47             unless ( defined $substrate and _looks_like_string($substrate) );
48              
49             # Get the positions where the enzyme cuts
50 56 100       186 my @sites = $self->cleavage_sites($substrate) or return $substrate;
51              
52             # Get the peptide products;
53 54         77 my @products;
54 54         61 my $start = 0;
55 54         153 while ( my $site = shift @sites ) {
56 1483         884 my $length = $site - $start;
57 1483         1144 my $product = substr($substrate, $start, $length);
58 1483         1150 push @products, $product;
59 1483         1877 $start += $length;
60             }
61              
62             # Last peptide: cut from last position to the end.
63 54         85 push @products, substr($substrate, $start);
64              
65 54         365 return @products;
66             }
67              
68             sub is_substrate {
69 9     9 1 67 my ($self, $substrate) = @_;
70              
71 9 100 100     31 croak "Incorrect substrate argument"
72             unless ( defined $substrate and _looks_like_string($substrate) );
73              
74 7         14 for my $pos (1 .. length $substrate) {
75 32 100       43 return 1 if $self->cut($substrate, $pos);
76             }
77              
78 3         11 return;
79             }
80              
81             around _cuts => sub {
82              
83             my ($orig, $self, $substrate) = @_;
84              
85             $substrate = _cap_tail($substrate) or return;
86              
87             $self->$orig($substrate);
88             };
89              
90             sub _cap_tail {
91 55161     55161   37818 my $substrate = shift;
92              
93 55161         35388 my $length = length $substrate;
94 55161 100       63330 if ( $length < 8 ) {
95 671 100       773 if ( $length > 4 ) {
96 288         568 $substrate .= 'X' x (8 - $length);
97             }
98 383         917 else { return }
99             }
100              
101 54778         77273 return $substrate;
102             }
103              
104 132     132   312 sub _cap_head { return 'XXX' . shift }
105              
106 8     8   37 sub _uncap { s/X//g for @_ }
107              
108 202     202   2127 sub _looks_like_string { $_[0] ~~ /[a-z]+/i }
109              
110             sub cleavage_sites {
111 97     97 1 210 my ( $self, $substrate ) = @_;
112              
113 97 100 100     307 croak "Incorrect substrate argument"
114             unless ( defined $substrate and _looks_like_string($substrate) );
115              
116 95         427 $substrate = uc $substrate;
117 95         103 my @sites;
118 95         85 my $i = 1;
119              
120 95         191 $substrate = _cap_head($substrate);
121 95         239 while ( my $pep = substr($substrate, $i-1, 8 ) ) {
122 55124 100       76448 if ( $self->_cuts( $pep ) ) { push @sites, $i };
  5340         4151  
123 55124         90183 ++$i;
124             }
125 95         1219 return @sites;
126             }
127              
128             1;
129              
130              
131              
132              
133              
134              
135              
136              
137             __END__
138             =pod
139              
140             =head1 NAME
141              
142             Bio::ProteaseI - A role to build your customized Protease
143              
144             =head1 VERSION
145              
146             version 1.112900
147              
148             =head1 SYNOPSIS
149              
150             package My::Protease;
151             use Moose;
152             with 'Bio::ProteaseI';
153              
154             sub _cuts {
155             my ($self, $peptide) = @_;
156              
157             # some code that decides
158             # if $peptide should be cut or not
159              
160             if ( $peptide_should_be_cut ) { return 1 }
161             else { return }
162             };
163              
164             =head1 DESCRIPTION
165              
166             This module describes the interface for L<Bio::Protease>. You only need
167             to use this if you want to build your custom specificity protease and
168             regular expressions won't do; otherwise look at L<Bio::Protease>
169             instead.
170              
171             All of the methods provided in L<Bio::Protease> are defined here.
172             The consuming class just has to implement a C<_cuts> method.
173              
174             =head1 METHODS
175              
176             =head2 cut
177              
178             Attempt to cleave C<$peptide> at the C-terminal end of the C<$i>-th
179             residue (ie, at the right). If the bond is indeed cleavable (determined
180             by the enzyme's specificity), then a list with the two products of the
181             hydrolysis will be returned. Otherwise, returns false.
182              
183             my @products = $enzyme->cut($peptide, $i);
184              
185             =head2 digest
186              
187             Performs a complete digestion of the peptide argument, returning a list
188             with possible products. It does not do partial digests (see method
189             C<cut> for that).
190              
191             my @products = $enzyme->digest($protein);
192              
193             =head2 is_substrate
194              
195             Returns true or false whether the peptide argument is a substrate or
196             not. Esentially, it's equivalent to calling C<cleavage_sites> in boolean
197             context, but with the difference that this method short-circuits when it
198             finds its first cleavable site. Thus, it's useful for CPU-intensive
199             tasks where the only information required is whether a polypeptide is a
200             substrate of a particular enzyme or not
201              
202             =head2 cleavage_sites
203              
204             Returns a list with siscile bonds (bonds susceptible to be cleaved as
205             determined by the enzyme's specificity). Bonds are numbered starting
206             from 1, from N to C-terminal. Takes a string with the protein sequence
207             as an argument:
208              
209             my @sites = $enzyme->cleavage_sites($peptide);
210              
211             =head1 How to implement your own Protease class.
212              
213             =head2 Step 1: create a class that does ProteaseI.
214              
215             package My::Protease;
216             use Moose;
217             with 'Bio::ProteaseI';
218              
219             1;
220              
221             Simply create a new Moose class, and consume the L<Bio::ProteaseI>
222             role.
223              
224             =head2 Step 2: Implement a _cuts() method.
225              
226             The C<_cuts> method will be used by the methods C<digest>, C<cut>,
227             C<cleavage_sites> and C<is_substrate>. It will B<always> be passed a
228             string of 8 characters; if the method returns true, then the peptide
229             bond between the 4th and 5th residues will be marked as siscile, and the
230             appropiate action will be performed depending on which method was
231             called.
232              
233             Your specificity logic should only be concerned in deciding whether the
234             8-residue long peptide passed to it as an argument should be cut between
235             the 4th and 5th residues. This is done in the private C<_cuts> method,
236             like so:
237              
238             sub _cuts {
239             my ( $self, $peptide ) = @_;
240              
241             # some code that decides
242             # if $peptide should be cut or not
243              
244             if ( $peptide_should_be_cut ) { return 1 }
245             else { return }
246             };
247              
248             And that's it. Your class will be composed with all the methods
249             mentioned above, and will work according to the specificity logic that
250             you define in your C<_cuts()> method.
251              
252             =head2 Example: a ridiculously specific protease
253              
254             Suppose you want to model a protease that only cleaves the sequence
255             C<MAEL^VIKP>. Your Protease class would be like this:
256              
257             package My::Ridiculously::Specific::Protease;
258             use Moose;
259             with 'Bio::ProteaseI';
260              
261             sub _cuts {
262             my ( $self, $substrate ) = @_;
263              
264             if ( $substrate eq 'MAELVIKP' ) { return 1 }
265             else { return }
266             };
267              
268             1;
269              
270             Then you can use your class easily in your application:
271              
272             #!/usr/bin/env perl
273             use Modern::Perl;
274              
275             use My::Ridiculously::Specific::Protease;
276              
277             my $protease = My::Ridiculously::Specific::Protease->new;
278             my @products = $protease->digest( 'AAAAMAELVIKPYYYYYYY' );
279              
280             say for @products; # ["AAAAMAEL", "VIKPYYYYYYY"]
281              
282             Of course, this specificity model is too simple to deserve a new class,
283             as it could be perfectly defined by a regex and passed to the
284             C<specificity> attribute of L<Bio::Protease>. It's only used here as an
285             example.
286              
287             =head1 AUTHOR
288              
289             Bruno Vecchi <vecchi.b gmail.com>
290              
291             =head1 COPYRIGHT AND LICENSE
292              
293             This software is copyright (c) 2011 by Bruno Vecchi.
294              
295             This is free software; you can redistribute it and/or modify it under
296             the same terms as the Perl 5 programming language system itself.
297              
298             =cut
299