File Coverage

Bio/Variation/AAChange.pm
Criterion Covered Total %
statement 127 148 85.8
branch 87 140 62.1
condition 54 135 40.0
subroutine 9 9 100.0
pod 5 5 100.0
total 282 437 64.5


line stmt bran cond sub pod time code
1             #
2             # BioPerl module for Bio::Variation::AAChange
3             #
4             # Please direct questions and support issues to
5             #
6             # Cared for by Heikki Lehvaslaiho
7             #
8             # Copyright Heikki Lehvaslaiho
9             #
10             # You may distribute this module under the same terms as perl itself
11              
12             # POD documentation - main docs before the code
13              
14             =head1 NAME
15              
16             Bio::Variation::AAChange - Sequence change class for polypeptides
17              
18             =head1 SYNOPSIS
19              
20             $aamut = Bio::Variation::AAChange->new
21             ('-start' => $start,
22             '-end' => $end,
23             '-length' => $len,
24             '-proof' => $proof,
25             '-isMutation' => 1,
26             '-mut_number' => $mut_number
27             );
28              
29             my $a1 = Bio::Variation::Allele->new;
30             $a1->seq($ori) if $ori;
31             $aamut->allele_ori($a1);
32             my $a2 = Bio::Variation::Allele->new;
33             $a2->seq($mut) if $mut;
34             $aachange->add_Allele($a2);
35             $aachange->allele_mut($a2);
36              
37             print "\n";
38              
39             # add it to a SeqDiff container object
40             $seqdiff->add_Variant($rnachange);
41              
42             # and create links to and from RNA level variant objects
43             $aamut->RNAChange($rnachange);
44             $rnachange->AAChange($rnachange);
45              
46             =head1 DESCRIPTION
47              
48             The instantiable class Bio::Variation::RNAChange describes basic
49             sequence changes at polypeptide level. It uses methods defined in
50             superclass Bio::Variation::VariantI, see L
51             for details.
52              
53             If the variation described by a AAChange object has a known
54             Bio::Variation::RNAAChange object, create the link with method
55             AAChange(). See L for more information.
56              
57             =head1 FEEDBACK
58              
59             =head2 Mailing Lists
60              
61             User feedback is an integral part of the evolution of this and other
62             Bioperl modules. Send your comments and suggestions preferably to the
63             Bioperl mailing lists Your participation is much appreciated.
64              
65             bioperl-l@bioperl.org - General discussion
66             http://bioperl.org/wiki/Mailing_lists - About the mailing lists
67              
68             =head2 Support
69              
70             Please direct usage questions or support issues to the mailing list:
71              
72             I
73              
74             rather than to the module maintainer directly. Many experienced and
75             reponsive experts will be able look at the problem and quickly
76             address it. Please include a thorough description of the problem
77             with code and data examples if at all possible.
78              
79             =head2 Reporting Bugs
80              
81             Report bugs to the Bioperl bug tracking system to help us keep track
82             the bugs and their resolution. Bug reports can be submitted via the
83             web:
84              
85             https://github.com/bioperl/bioperl-live/issues
86              
87             =head1 AUTHOR - Heikki Lehvaslaiho
88              
89             Email: heikki-at-bioperl-dot-org
90              
91             =head1 APPENDIX
92              
93             The rest of the documentation details each of the object
94             methods. Internal methods are usually preceded with a _
95              
96             =cut
97              
98              
99             # Let the code begin...
100              
101              
102             package Bio::Variation::AAChange;
103              
104 4     4   1609 use vars qw($MATRIX);
  4         4  
  4         144  
105 4     4   14 use strict;
  4         4  
  4         71  
106              
107             # Object preamble - inheritance
108              
109 4     4   11 use base qw(Bio::Variation::VariantI);
  4         5  
  4         1022  
110              
111             BEGIN {
112              
113 4     4   9 my $matrix = << "__MATRIX__";
114             # Matrix made by matblas from blosum62.iij
115             # * column uses minimum score
116             # BLOSUM Clustered Scoring Matrix in 1/2 Bit Units
117             # Blocks Database = /data/blocks_5.0/blocks.dat
118             # Cluster Percentage: >= 62
119             # Entropy = 0.6979, Expected = -0.5209
120             A R N D C Q E G H I L K M F P S T W Y V B Z X *
121             A 4 -1 -2 -2 0 -1 -1 0 -2 -1 -1 -1 -1 -2 -1 1 0 -3 -2 0 -2 -1 0 -4
122             R -1 5 0 -2 -3 1 0 -2 0 -3 -2 2 -1 -3 -2 -1 -1 -3 -2 -3 -1 0 -1 -4
123             N -2 0 6 1 -3 0 0 0 1 -3 -3 0 -2 -3 -2 1 0 -4 -2 -3 3 0 -1 -4
124             D -2 -2 1 6 -3 0 2 -1 -1 -3 -4 -1 -3 -3 -1 0 -1 -4 -3 -3 4 1 -1 -4
125             C 0 -3 -3 -3 9 -3 -4 -3 -3 -1 -1 -3 -1 -2 -3 -1 -1 -2 -2 -1 -3 -3 -2 -4
126             Q -1 1 0 0 -3 5 2 -2 0 -3 -2 1 0 -3 -1 0 -1 -2 -1 -2 0 3 -1 -4
127             E -1 0 0 2 -4 2 5 -2 0 -3 -3 1 -2 -3 -1 0 -1 -3 -2 -2 1 4 -1 -4
128             G 0 -2 0 -1 -3 -2 -2 6 -2 -4 -4 -2 -3 -3 -2 0 -2 -2 -3 -3 -1 -2 -1 -4
129             H -2 0 1 -1 -3 0 0 -2 8 -3 -3 -1 -2 -1 -2 -1 -2 -2 2 -3 0 0 -1 -4
130             I -1 -3 -3 -3 -1 -3 -3 -4 -3 4 2 -3 1 0 -3 -2 -1 -3 -1 3 -3 -3 -1 -4
131             L -1 -2 -3 -4 -1 -2 -3 -4 -3 2 4 -2 2 0 -3 -2 -1 -2 -1 1 -4 -3 -1 -4
132             K -1 2 0 -1 -3 1 1 -2 -1 -3 -2 5 -1 -3 -1 0 -1 -3 -2 -2 0 1 -1 -4
133             M -1 -1 -2 -3 -1 0 -2 -3 -2 1 2 -1 5 0 -2 -1 -1 -1 -1 1 -3 -1 -1 -4
134             F -2 -3 -3 -3 -2 -3 -3 -3 -1 0 0 -3 0 6 -4 -2 -2 1 3 -1 -3 -3 -1 -4
135             P -1 -2 -2 -1 -3 -1 -1 -2 -2 -3 -3 -1 -2 -4 7 -1 -1 -4 -3 -2 -2 -1 -2 -4
136             S 1 -1 1 0 -1 0 0 0 -1 -2 -2 0 -1 -2 -1 4 1 -3 -2 -2 0 0 0 -4
137             T 0 -1 0 -1 -1 -1 -1 -2 -2 -1 -1 -1 -1 -2 -1 1 5 -2 -2 0 -1 -1 0 -4
138             W -3 -3 -4 -4 -2 -2 -3 -2 -2 -3 -2 -3 -1 1 -4 -3 -2 11 2 -3 -4 -3 -2 -4
139             Y -2 -2 -2 -3 -2 -1 -2 -3 2 -1 -1 -2 -1 3 -3 -2 -2 2 7 -1 -3 -2 -1 -4
140             V 0 -3 -3 -3 -1 -2 -2 -3 -3 3 1 -2 1 -1 -2 -2 0 -3 -1 4 -3 -2 -1 -4
141             B -2 -1 3 4 -3 0 1 -1 0 -3 -4 0 -3 -3 -2 0 -1 -4 -3 -3 4 1 -1 -4
142             Z -1 0 0 1 -3 3 4 -2 0 -3 -3 1 -1 -3 -1 0 -1 -3 -2 -2 1 4 -1 -4
143             X 0 -1 -1 -1 -2 -1 -1 -1 -1 -1 -1 -1 -1 -1 -2 0 0 -2 -1 -1 -1 -1 -1 -4
144             * -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 1
145             __MATRIX__
146              
147 4         5 my %blosum = ();
148 4         133 $matrix =~ /^ +(.+)$/m;
149 4         54 my @aas = split / +/, $1;
150 4         8 foreach my $aa (@aas) {
151 96         68 my $tmp = $aa;
152 96 100       132 $tmp = "\\$aa" if $aa eq '*';
153 96         1187 $matrix =~ /^($tmp) +([-+]?\d.*)$/m;
154 96 50       799 my @scores = split / +/, $2 if defined $2;
155 96         74 my $count = 0;
156 96         85 foreach my $ak (@aas) {
157 2304         2276 $blosum{$aa}->{$aas[$count]} = $scores[$count];
158 2304         1473 $count++;
159             }
160             }
161             sub _matrix;
162 4         4217 $MATRIX = \%blosum;
163             }
164              
165             sub new {
166 19     19 1 161 my($class,@args) = @_;
167 19         85 my $self = $class->SUPER::new(@args);
168              
169 19         145 my ($start, $end, $length, $strand, $primary, $source,
170             $frame, $score, $gff_string,
171             $allele_ori, $allele_mut, $upstreamseq, $dnstreamseq,
172             $label, $status, $proof, $re_changes, $region, $region_value,
173             $region_dist,
174             $numbering, $mut_number, $ismutation) =
175             $self->_rearrange([qw(START
176             END
177             LENGTH
178             STRAND
179             PRIMARY
180             SOURCE
181             FRAME
182             SCORE
183             GFF_STRING
184             ALLELE_ORI
185             ALLELE_MUT
186             UPSTREAMSEQ
187             DNSTREAMSEQ
188             LABEL
189             STATUS
190             PROOF
191             RE_CHANGES
192             REGION
193             REGION_VALUE
194             REGION_DIST
195             NUMBERING
196             MUT_NUMBER
197             ISMUTATION
198             )],@args);
199              
200 19         122 $self->primary_tag("Variation");
201              
202 19         30 $self->{ 'alleles' } = [];
203              
204 19 100       65 $start && $self->start($start);
205 19 100       52 $end && $self->end($end);
206 19 100       51 $length && $self->length($length);
207 19 50       34 $strand && $self->strand($strand);
208 19 50       34 $primary && $self->primary_tag($primary);
209 19 50       30 $source && $self->source_tag($source);
210 19 50       32 $frame && $self->frame($frame);
211 19 50       28 $score && $self->score($score);
212 19 50       29 $gff_string && $self->_from_gff_string($gff_string);
213              
214 19 50       29 $allele_ori && $self->allele_ori($allele_ori);
215 19 50       33 $allele_mut && $self->allele_mut($allele_mut);
216 19 50       28 $upstreamseq && $self->upstreamseq($upstreamseq);
217 19 50       28 $dnstreamseq && $self->dnstreamseq($dnstreamseq);
218              
219 19 50       37 $label && $self->label($label);
220 19 50       37 $status && $self->status($status);
221 19 100       50 $proof && $self->proof($proof);
222 19 50       31 $region && $self->region($region);
223 19 50       34 $region_value && $self->region_value($region_value);
224 19 50       32 $region_dist && $self->region_dist($region_dist);
225 19 50       28 $numbering && $self->numbering($numbering);
226 19 100       37 $mut_number && $self->mut_number($mut_number);
227 19 50       33 $ismutation && $self->isMutation($ismutation);
228              
229 19         51 return $self; # success - we hope!
230             }
231              
232             =head2 RNAChange
233              
234             Title : RNAChange
235             Usage : $mutobj = $self->RNAChange;
236             : $mutobj = $self->RNAChange($objref);
237             Function: Returns or sets the link-reference to a mutation/change object.
238             If there is no link, it will return undef
239             Returns : an obj_ref or undef
240              
241             =cut
242              
243             sub RNAChange {
244 66     66 1 70 my ($self,$value) = @_;
245 66 100       122 if (defined $value) {
246 18 50       46 if( ! $value->isa('Bio::Variation::RNAChange') ) {
247 0         0 $self->throw("Is not a Bio::Variation::RNAChange object but a [$self]");
248 0         0 return;
249             }
250             else {
251 18         30 $self->{'RNAChange'} = $value;
252             }
253             }
254 66 50       96 unless (exists $self->{'RNAChange'}) {
255 0         0 return;
256             } else {
257 66         167 return $self->{'RNAChange'};
258             }
259             }
260              
261              
262              
263             =head2 label
264              
265             Title : label
266             Usage : $obj->label();
267             Function:
268              
269             Sets and returns mutation event label(s). If value is not
270             set, or no argument is given returns false. Each
271             instantiable subclass of L needs
272             to implement this method. Valid values are listed in
273             'Mutation event controlled vocabulary' in
274             http://www.ebi.ac.uk/mutations/recommendations/mutevent.html.
275              
276             Example :
277             Returns : string
278             Args : string
279              
280             =cut
281              
282              
283             sub label {
284 15     15 1 17 my ($self) = @_;
285 15         13 my ($o, $m, $type);
286 15 50 33     29 $o = $self->allele_ori->seq if $self->allele_ori and $self->allele_ori->seq;
287 15 100 66     31 $m = $self->allele_mut->seq if $self->allele_mut and $self->allele_mut->seq;
288              
289 15 50 33     38 if ($self->start == 1 ) {
    50 66        
    50 66        
    100 100        
    50 66        
    100 66        
    100 33        
    100 33        
      33        
      66        
      33        
      66        
      100        
      33        
      33        
      33        
      33        
      66        
290 0 0 0     0 if ($o and substr($o, 0, 1) ne substr($m, 0, 1)) {
    0 0        
      0        
291 0         0 $type = 'no translation';
292             }
293             elsif ($o and $m and $o eq $m ) {
294 0         0 $type = 'silent';
295             }
296             # more ...
297             }
298             elsif ($o and substr($o, 0, 1) eq '*' ) {
299 0 0 0     0 if ($m and substr($o, 0, 1) ne substr($m, 0, 1)) {
    0 0        
300 0         0 $type = 'post-elongation';
301             }
302             elsif ($m and $o eq $m ) {
303 0         0 $type = 'silent, conservative';
304             }
305             }
306             elsif ($o and $m and $o eq $m) {
307 0         0 $type = 'silent, conservative';
308             }
309             elsif ($m and $m eq '*') {
310 2         5 $type = 'truncation';
311             }
312             elsif ($o and $m and $o eq $m) {
313 0         0 $type = 'silent, conservative';
314             }
315             elsif (not $m or
316             ($o and $m and length($o) > length($m) and
317             substr($m, -1, 1) ne '*')) {
318 1         2 $type = 'deletion';
319 1 0 33     6 if ($o and $m and $o !~ $m and $o !~ $m) {
      33        
      33        
320 0         0 $type .= ', complex';
321             }
322             }
323             elsif (not $o or
324             ($o and $m and length($o) < length($m) and
325             substr($m, -1, 1) ne '*' ) ) {
326 1         2 $type = 'insertion';
327 1 50 33     21 if ($o and $m and $o !~ $m and $o !~ $m) {
      33        
      33        
328 1         2 $type .= ', complex';
329             }
330             }
331             elsif ($o and $m and $o ne $m and
332             length $o == 1 and length $m == 1 ) {
333 8         12 $type = 'substitution';
334 8         18 my $value = $self->similarity_score;
335 8 50       20 if (defined $value) {
336 8 100       25 my $cons = ($value < 0) ? 'nonconservative' : 'conservative';
337 8         21 $type .= ", ". $cons;
338             }
339             } else {
340 3         4 $type = 'out-of-frame translation, truncation';
341             }
342 15         26 $self->{'label'} = $type;
343 15         31 return $self->{'label'};
344             }
345              
346              
347             =head2 similarity_score
348              
349             Title : similarity_score
350             Usage : $self->similarity_score
351             Function: Measure for evolutionary conservativeness
352             of single amino substitutions. Uses BLOSUM62.
353             Negative numbers are noncoservative changes.
354             Returns : integer, undef if not single amino acid change
355              
356             =cut
357              
358             sub similarity_score {
359 9     9 1 11 my ($self) = @_;
360 9         9 my ($o, $m, $type);
361 9 50 33     16 $o = $self->allele_ori->seq if $self->allele_ori and $self->allele_ori->seq;
362 9 50 33     25 $m = $self->allele_mut->seq if $self->allele_mut and $self->allele_mut->seq;
363 9 50 33     73 return unless $o and $m and length $o == 1 and length $m == 1;
      33        
      33        
364 9 50 33     79 return unless $o =~ /[ARNDCQEGHILKMFPSTWYVBZX*]/i and
365             $m =~ /[ARNDCQEGHILKMFPSTWYVBZX*]/i;
366 9         37 return $MATRIX->{"\U$o"}->{"\U$m"};
367             }
368              
369             =head2 trivname
370              
371             Title : trivname
372             Usage : $self->trivname
373             Function:
374              
375             Given a Bio::Variation::AAChange object with linked
376             Bio::Variation::RNAChange and Bio::Variation::DNAMutation
377             objects, this subroutine creates a string corresponding to
378             the 'trivial name' of the mutation. Trivial name is
379             specified in Antonorakis & MDI Nomenclature Working Group:
380             Human Mutation 11:1-3, 1998.
381              
382             Returns : string
383              
384             =cut
385              
386              
387             sub trivname {
388 19     19 1 24 my ($self,$value) = @_;
389 19 50       34 if( defined $value) {
390 0         0 $self->{'trivname'} = $value;
391             } else {
392 19         33 my ( $aaori, $aamut,$aamutsymbol, $aatermnumber, $aamutterm) =
393             ('', '', '', '', '');
394 19 50 33     50 my $o = $self->allele_ori->seq if $self->allele_ori and $self->allele_ori->seq;
395             #my $m = $self->allele_mut->seq if $self->allele_mut and $self->allele_mut->seq;
396              
397 19 50       60 $aaori = substr ($o, 0, 1) if $o;
398 19         23 $aaori =~ tr/\*/X/;
399              
400 19         18 my $sep;
401 19 100       45 if ($self->isMutation) {
402 17         22 $sep = '>';
403             } else {
404 2         4 $sep = '|';
405             }
406 19         48 my $trivname = $aaori. $self->start;
407 19 100       45 $trivname .= $sep if $sep eq '|';
408              
409 19         48 my @alleles = $self->each_Allele;
410 19         30 foreach my $allele (@alleles) {
411 20 100       34 my $m = $allele->seq if $allele->seq;
412              
413 20         46 $self->allele_mut($allele);
414             #$trivname .= $sep. uc $m if $m;
415              
416 20 100       45 $aamutterm = substr ($m, -1, 1) if $m;
417 20 50 0     48 if ($self->RNAChange->label =~ /initiation codon/ and
    100 0        
    100 33        
    100 100        
    50          
    0          
418             ( $o and $m and $o ne $m)) {
419 0         0 $aamut = 'X';
420             }
421             elsif (CORE::length($o) == 1 and CORE::length($m) == 1 ) {
422 15         21 $aamutsymbol = '';
423 15         21 $aamut = $aamutterm;
424             }
425             elsif ($self->RNAChange->label =~ /deletion/) {
426 2         3 $aamutsymbol = 'del';
427 2 100       6 if ($aamutterm eq '*') {
428 1         3 $aatermnumber = $self->start + length($m) -1;
429 1         2 $aamut = 'X'. $aatermnumber;
430             }
431 2 100 66     3 if ($self->RNAChange && $self->RNAChange->label =~ /inframe/){
432 1         3 $aamut = '-'. length($self->RNAChange->allele_ori->seq)/3 ;
433             }
434             }
435             elsif ($self->RNAChange->label =~ /insertion/) {
436 2         3 $aamutsymbol = 'ins';
437 2 100 66     9 if (($aamutterm eq '*') && (length($m)-1 != 0)) {
438 1         3 $aatermnumber = $self->start + length($m)-1;
439 1         2 $aamut = $aatermnumber. 'X';
440             }
441 2 100       5 if ($self->RNAChange->label =~ /inframe/){
442 1         2 $aamut = '+'. int length($self->RNAChange->allele_mut->seq)/3 ;
443             }
444             }
445             elsif ($self->RNAChange->label =~ /complex/ ) {
446 1         2 my $diff = length($m) - length($o);
447 1 50       2 if ($diff >= 0 ) {
448 1         1 $aamutsymbol = 'ins';
449             } else {
450 0         0 $aamutsymbol = 'del' ;
451             }
452 1 50 33     7 if (($aamutterm eq '*') && (length($m)-1 != 0)) {
453 1         3 $aatermnumber = $self->start + length($m)-1;
454 1         3 $aamut = $aatermnumber. 'X';
455             }
456 1 50       2 if ($self->RNAChange->label =~ /inframe/){
457              
458 0 0       0 if ($diff >= 0 ) {
459 0         0 $aamut = '+'. $diff ;
460             } else {
461 0         0 $aamut = $diff ;
462             }
463             }
464             }
465             elsif ($self->label =~ /truncation/) {
466 0         0 $aamut = $m;
467             } else {
468 0         0 $aamutsymbol = '';
469 0         0 $aamut = $aamutterm;
470             }
471 20         25 $aamut =~ tr/\*/X/;
472 20         39 $trivname .= $aamutsymbol. $aamut. $sep;
473             }
474 19         28 chop $trivname;
475 19         45 $self->{'trivname'} = $trivname;
476             }
477 19         51 return $self->{'trivname'};
478             }
479              
480             1;