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
|
|
|
|
|
|
|
|