Pull out the 'recommends' table and refactor to make a bit more
[bioperl-live.git] / Bio / Variation / DNAMutation.pm
blob824b78bd339285dbba2ac8500892e7df258bbd85
2 # BioPerl module for Bio::Variation::DNAMutation
4 # Please direct questions and support issues to <bioperl-l@bioperl.org>
6 # Cared for by Heikki Lehvaslaiho <heikki-at-bioperl-dot-org>
8 # Copyright Heikki Lehvaslaiho
10 # You may distribute this module under the same terms as perl itself
12 # POD documentation - main docs before the code
14 =head1 NAME
16 Bio::Variation::DNAMutation - DNA level mutation class
18 =head1 SYNOPSIS
20 $dnamut = Bio::Variation::DNAMutation->new
21 ('-start' => $start,
22 '-end' => $end,
23 '-length' => $len,
24 '-upStreamSeq' => $upflank,
25 '-dnStreamSeq' => $dnflank,
26 '-proof' => $proof,
27 '-isMutation' => 1,
28 '-mut_number' => $mut_number
30 $a1 = Bio::Variation::Allele->new;
31 $a1->seq('a');
32 $dnamut->allele_ori($a1);
33 my $a2 = Bio::Variation::Allele->new;
34 $a2->seq('t');
35 $dnamut->add_Allele($a2);
37 print "Restriction changes are ", $dnamut->restriction_changes, "\n";
39 # add it to a SeqDiff container object
40 $seqdiff->add_Variant($dnamut);
43 =head1 DESCRIPTION
45 The instantiable class Bio::Variation::DNAMutation describes basic
46 sequence changes in genomic DNA level. It uses methods defined in
47 superclass Bio::Variation::VariantI. See L<Bio::Variation::VariantI>
48 for details.
50 If the variation described by a DNAMutation object is transcibed, link
51 the corresponding Bio::Variation::RNAChange object to it using
52 method RNAChange(). See L<Bio::Variation::RNAChange> for more information.
54 =head1 FEEDBACK
56 =head2 Mailing Lists
58 User feedback is an integral part of the evolution of this and other
59 Bioperl modules. Send your comments and suggestions preferably to the
60 Bioperl mailing lists Your participation is much appreciated.
62 bioperl-l@bioperl.org - General discussion
63 http://bioperl.org/wiki/Mailing_lists - About the mailing lists
65 =head2 Support
67 Please direct usage questions or support issues to the mailing list:
69 I<bioperl-l@bioperl.org>
71 rather than to the module maintainer directly. Many experienced and
72 reponsive experts will be able look at the problem and quickly
73 address it. Please include a thorough description of the problem
74 with code and data examples if at all possible.
76 =head2 Reporting Bugs
78 Report bugs to the Bioperl bug tracking system to help us keep track
79 the bugs and their resolution. Bug reports can be submitted via the
80 web:
82 https://redmine.open-bio.org/projects/bioperl/
84 =head1 AUTHOR - Heikki Lehvaslaiho
86 Email: heikki-at-bioperl-dot-org
88 =head1 APPENDIX
90 The rest of the documentation details each of the object
91 methods. Internal methods are usually preceded with a _
93 =cut
96 # Let the code begin...
99 package Bio::Variation::DNAMutation;
100 use strict;
102 # Object preamble - inheritance
104 use base qw(Bio::Variation::VariantI);
106 sub new {
107 my($class,@args) = @_;
108 my $self = $class->SUPER::new(@args);
110 my ($start, $end, $length, $strand, $primary, $source,
111 $frame, $score, $gff_string,
112 $allele_ori, $allele_mut, $upstreamseq, $dnstreamseq,
113 $label, $status, $proof, $region, $region_value, $region_dist, $numbering,
114 $cpg, $mut_number, $ismutation) =
115 $self->_rearrange([qw(START
117 LENGTH
118 STRAND
119 PRIMARY
120 SOURCE
121 FRAME
122 SCORE
123 GFF_STRING
124 ALLELE_ORI
125 ALLELE_MUT
126 UPSTREAMSEQ
127 DNSTREAMSEQ
128 LABEL
129 STATUS
130 PROOF
131 REGION
132 REGION_VALUE
133 REGION_DIST
134 NUMBERING
136 MUT_NUMBER
137 ISMUTATION
139 @args);
141 $self->primary_tag("Variation");
143 $self->{ 'alleles' } = [];
145 $start && $self->start($start);
146 $end && $self->end($end);
147 $length && $self->length($length);
148 $strand && $self->strand($strand);
149 $primary && $self->primary_tag($primary);
150 $source && $self->source_tag($source);
151 $frame && $self->frame($frame);
152 $score && $self->score($score);
153 $gff_string && $self->_from_gff_string($gff_string);
155 $allele_ori && $self->allele_ori($allele_ori);
156 $allele_mut && $self->allele_mut($allele_mut);
157 $upstreamseq && $self->upStreamSeq($upstreamseq);
158 $dnstreamseq && $self->dnStreamSeq($dnstreamseq);
160 $label && $self->label($label);
161 $status && $self->status($status);
162 $proof && $self->proof($proof);
163 $region && $self->region($region);
164 $region_value && $self->region_value($region_value);
165 $region_dist && $self->region_dist($region_dist);
166 $numbering && $self->numbering($numbering);
167 $mut_number && $self->mut_number($mut_number);
168 $ismutation && $self->isMutation($ismutation);
170 $cpg && $self->CpG($cpg);
172 return $self; # success - we hope!
176 =head2 CpG
178 Title : CpG
179 Usage : $obj->CpG()
180 Function: sets and returns boolean values for variation
181 hitting a CpG site. Unset value return -1.
182 Example : $obj->CpG()
183 Returns : boolean
184 Args : optional true of false value
187 =cut
190 sub CpG {
191 my ($obj,$value) = @_;
192 if( defined $value) {
193 $value ? ($value = 1) : ($value = 0);
194 $obj->{'cpg'} = $value;
196 elsif (not defined $obj->{'label'}) {
197 $obj->{'cpg'} = $obj->_CpG_value;
199 else {
200 return $obj->{'cpg'};
206 sub _CpG_value {
207 my ($self) = @_;
208 if ($self->allele_ori eq $self->allele_mut and length ($self->allele_ori) == 1 ) {
210 # valid only for point mutations
211 # CpG methylation-mediated deamination:
212 # CG -> TG | CG -> CA substitutions
213 # implementation here is less strict: if CpG dinucleotide was hit
215 if ( ( ($self->allele_ori eq 'c') && (substr($self->upStreamSeq, 0, 1) eq 'g') ) ||
216 ( ($self->allele_ori eq 'g') && (substr($self->dnStreamSeq, -1, 1) eq 'c') ) ) {
217 return 1;
219 else {
220 return 0;
222 } else {
223 $self->warn('CpG makes sense only in the context of point mutation');
224 return;
229 =head2 RNAChange
231 Title : RNAChange
232 Usage : $mutobj = $obj->RNAChange;
233 : $mutobj = $obj->RNAChange($objref);
234 Function: Returns or sets the link-reference to a mutation/change object.
235 If there is no link, it will return undef
236 Returns : an obj_ref or undef
238 =cut
241 sub RNAChange {
242 my ($self,$value) = @_;
243 if (defined $value) {
244 if( ! $value->isa('Bio::Variation::RNAChange') ) {
245 $self->throw("Is not a Bio::Variation::RNAChange object but a [$self]");
246 return;
248 else {
249 $self->{'RNAChange'} = $value;
252 unless (exists $self->{'RNAChange'}) {
253 return;
254 } else {
255 return $self->{'RNAChange'};
260 =head2 label
262 Title : label
263 Usage : $obj->label();
264 Function:
266 Sets and returns mutation event label(s). If value is not
267 set, or no argument is given returns false. Each
268 instantiable subclass of L<Bio::Variation::VariantI> needs
269 to implement this method. Valid values are listed in
270 'Mutation event controlled vocabulary' in
271 http://www.ebi.ac.uk/mutations/recommendations/mutevent.html.
273 Example :
274 Returns : string
275 Args : string
277 =cut
280 sub label {
281 my ($self, $value) = @_;
282 my ($o, $m, $type);
283 $o = $self->allele_ori->seq if $self->allele_ori and $self->allele_ori->seq;
284 $m = $self->allele_mut->seq if $self->allele_mut and $self->allele_mut->seq;
286 if (not $o and not $m ) {
287 $self->warn("[DNAMutation, label] Both alleles should not be empty!\n");
288 $type = 'no change'; # is this enough?
290 elsif ($o && $m && length($o) == length($m) && length($o) == 1) {
291 $type = 'point';
292 $type .= ", ". _point_type_label($o, $m);
294 elsif (not $o ) {
295 $type = 'insertion';
297 elsif (not $m ) {
298 $type = 'deletion';
300 else {
301 $type = 'complex';
303 $self->{'label'} = $type;
304 return $self->{'label'};
308 sub _point_type_label {
309 my ($o, $m) = @_;
310 my ($type);
311 my %transition = ('a' => 'g',
312 'g' => 'a',
313 'c' => 't',
314 't' => 'c');
315 $o = lc $o;
316 $m = lc $m;
317 if ($o eq $m) {
318 $type = 'no change';
320 elsif ($transition{$o} eq $m ) {
321 $type = 'transition';
323 else {
324 $type = 'transversion';
329 =head2 sysname
331 Title : sysname
332 Usage : $self->sysname
333 Function:
335 This subroutine creates a string corresponding to the
336 'systematic name' of the mutation. Systematic name is
337 specified in Antonorakis & MDI Nomenclature Working Group:
338 Human Mutation 11:1-3, 1998.
340 Returns : string
342 =cut
345 sub sysname {
346 my ($self,$value) = @_;
347 if( defined $value) {
348 $self->{'sysname'} = $value;
349 } else {
350 $self->warn('Mutation start position is not defined')
351 if not defined $self->start;
352 my $sysname = '';
353 # show the alphabet only if $self->SeqDiff->alphabet is set;
354 my $mol = '';
356 if ($self->SeqDiff ) {
357 if ($self->SeqDiff && $self->SeqDiff->alphabet && $self->SeqDiff->alphabet eq 'dna') {
358 $mol = 'g.';
360 elsif ($self->SeqDiff->alphabet && $self->SeqDiff->alphabet eq 'rna') {
361 $mol = 'c.';
364 my $sep;
365 if ($self->isMutation) {
366 $sep = '>';
367 } else {
368 $sep = '|';
370 my $sign = '+';
371 $sign = '' if $self->start < 1;
372 $sysname .= $mol ;#if $mol;
373 $sysname .= $sign. $self->start;
375 my @alleles = $self->each_Allele;
376 $self->allele_mut($alleles[0]);
378 $sysname .= 'del' if $self->label =~ /deletion/;
379 $sysname .= 'ins' if $self->label =~ /insertion/;
380 $sysname .= uc $self->allele_ori->seq if $self->allele_ori->seq;
384 #push @alleles, $self->allele_mut if $self->allele_mut;
385 foreach my $allele (@alleles) {
386 $self->allele_mut($allele);
387 $sysname .= $sep if $self->label =~ /point/ or $self->label =~ /complex/;
388 $sysname .= uc $self->allele_mut->seq if $self->allele_mut->seq;
390 $self->{'sysname'} = $sysname;
391 #$self->{'sysname'} = $sign. $self->start.
392 # uc $self->allele_ori->seq. $sep. uc $self->allele_mut->seq;
394 return $self->{'sysname'};