Mercurial > repos > willmclaren > ensembl_vep
comparison variant_effect_predictor/Bio/EnsEMBL/Variation/BaseVariationFeatureOverlap.pm @ 0:21066c0abaf5 draft
Uploaded
author | willmclaren |
---|---|
date | Fri, 03 Aug 2012 10:04:48 -0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:21066c0abaf5 |
---|---|
1 =head1 LICENSE | |
2 | |
3 Copyright (c) 1999-2012 The European Bioinformatics Institute and | |
4 Genome Research Limited. All rights reserved. | |
5 | |
6 This software is distributed under a modified Apache license. | |
7 For license details, please see | |
8 | |
9 http://www.ensembl.org/info/about/code_licence.html | |
10 | |
11 =head1 CONTACT | |
12 | |
13 Please email comments or questions to the public Ensembl | |
14 developers list at <dev@ensembl.org>. | |
15 | |
16 Questions may also be sent to the Ensembl help desk at | |
17 <helpdesk@ensembl.org>. | |
18 | |
19 =cut | |
20 | |
21 =head1 NAME | |
22 | |
23 Bio::EnsEMBL::Variation::BaseVariationFeatureOverlap | |
24 | |
25 =head1 SYNOPSIS | |
26 | |
27 use Bio::EnsEMBL::Variation::BaseVariationFeatureOverlap; | |
28 | |
29 my $bvfo = Bio::EnsEMBL::Variation::BaseVariationFeatureOverlap->new( | |
30 -feature => $feature, | |
31 -base_variation_feature => $var_feat | |
32 ); | |
33 | |
34 print "consequence type: ", (join ",", @{ $bvfo->consequence_type }), "\n"; | |
35 print "most severe consequence: ", $bvfo->display_consequence, "\n"; | |
36 | |
37 =head1 DESCRIPTION | |
38 | |
39 A BaseVariationFeatureOverlap represents a BaseVariationFeature which is in close | |
40 proximity to another Ensembl Feature. It is the superclass of variation feature | |
41 specific classes such as VariationFeatureOverlap and StructuralVariationOverlap | |
42 and has methods common to all such objects. You will not normally instantiate this | |
43 class directly, instead instantiating one of the more specific subclasses. | |
44 | |
45 =cut | |
46 | |
47 package Bio::EnsEMBL::Variation::BaseVariationFeatureOverlap; | |
48 | |
49 use strict; | |
50 use warnings; | |
51 | |
52 use Bio::EnsEMBL::Utils::Argument qw(rearrange); | |
53 use Bio::EnsEMBL::Utils::Scalar qw(assert_ref); | |
54 use Bio::EnsEMBL::Utils::Exception qw(throw warning); | |
55 use Bio::EnsEMBL::Variation::Utils::VariationEffect qw(overlap within_cds); | |
56 | |
57 sub new { | |
58 my $class = shift; | |
59 | |
60 my ( | |
61 $adaptor, | |
62 $base_variation_feature, | |
63 $feature, | |
64 $no_transfer | |
65 ) = rearrange([qw( | |
66 ADAPTOR | |
67 BASE_VARIATION_FEATURE | |
68 FEATURE | |
69 NO_TRANSFER | |
70 )], @_); | |
71 | |
72 assert_ref($base_variation_feature, 'Bio::EnsEMBL::Variation::BaseVariationFeature'); | |
73 | |
74 if (defined $feature) { | |
75 | |
76 assert_ref($feature, 'Bio::EnsEMBL::Feature'); | |
77 | |
78 # we need to ensure the Feature and the BaseVariationFeature live on the same slice | |
79 # so we explicitly transfer the Feature here | |
80 unless($no_transfer && $no_transfer == 1) { | |
81 $feature = $feature->transfer($base_variation_feature->slice) | |
82 or throw("Unable to transfer the supplied feature to the same slice as the base variation feature"); | |
83 } | |
84 } | |
85 | |
86 my $self = bless { | |
87 base_variation_feature => $base_variation_feature, | |
88 feature => $feature, | |
89 adaptor => $adaptor, | |
90 }, $class; | |
91 | |
92 return $self; | |
93 } | |
94 | |
95 sub new_fast { | |
96 my ($class, $hashref) = @_; | |
97 return bless $hashref, $class; | |
98 } | |
99 | |
100 =head2 feature | |
101 | |
102 Arg [1] : (optional) A Bio::EnsEMBL::Feature | |
103 Description: Get/set the associated Feature, lazy-loading it if required | |
104 Returntype : Bio::EnsEMBL::Feature | |
105 Exceptions : throws isf the argument is the wrong type | |
106 Status : At Risk | |
107 | |
108 =cut | |
109 | |
110 sub feature { | |
111 my ($self, $feature, $type) = @_; | |
112 | |
113 if ($feature) { | |
114 assert_ref($feature, 'Bio::EnsEMBL::Feature'); | |
115 $self->{feature} = $feature; | |
116 } | |
117 | |
118 if ($type && !$self->{feature}) { | |
119 | |
120 # try to lazy load the feature | |
121 | |
122 if (my $adap = $self->{adaptor}) { | |
123 | |
124 my $get_method = 'get_'.$type.'Adaptor'; | |
125 | |
126 # XXX: this can doesn't work because the method is AUTOLOADed, need to rethink this... | |
127 #if ($adap->db->dnadb->can($get_method)) { | |
128 if (my $fa = $adap->db->dnadb->$get_method) { | |
129 | |
130 # if we have a stable id for the feature use that | |
131 if (my $feature_stable_id = $self->{_feature_stable_id}) { | |
132 if (my $f = $fa->fetch_by_stable_id($feature_stable_id)) { | |
133 $self->{feature} = $f; | |
134 delete $self->{_feature_stable_id}; | |
135 } | |
136 } | |
137 elsif (my $feature_label = $self->{_feature_label}) { | |
138 # get a slice covering the vf | |
139 | |
140 #for my $f ($fa->fetch_all_by_Slice_constraint) | |
141 } | |
142 } | |
143 #} | |
144 else { | |
145 warn "Cannot get an adaptor for type: $type"; | |
146 } | |
147 } | |
148 } | |
149 | |
150 return $self->{feature}; | |
151 } | |
152 | |
153 sub _fetch_feature_for_stable_id { | |
154 | |
155 # we shouldn't actually need this method as there will apparently | |
156 # soon be core support for fetching any feature by its stable id, | |
157 # but I'm waiting for core to add this... | |
158 | |
159 my ($self, $feature_stable_id) = @_; | |
160 | |
161 my $type_lookup = { | |
162 G => { type => 'Gene', group => 'core' }, | |
163 T => { type => 'Transcript', group => 'core' }, | |
164 R => { type => 'RegulatoryFeature', group => 'funcgen' }, | |
165 }; | |
166 | |
167 if ($feature_stable_id =~ /^ENS[A-Z]*([G|R|T])\d+$/) { | |
168 | |
169 my $type = $type_lookup->{$1}->{type}; | |
170 my $group = $type_lookup->{$1}->{group}; | |
171 | |
172 if (my $adap = $self->{adaptor}) { | |
173 | |
174 my $get_method = 'get_'.$type.'Adaptor'; | |
175 | |
176 if ($adap->db->dnadb->can($get_method)) { | |
177 if (my $fa = $adap->db->dnadb->$get_method) { | |
178 | |
179 # if we have a stable id for the feature use that | |
180 if (my $feature_stable_id = $self->{_feature_stable_id}) { | |
181 if (my $f = $fa->fetch_by_stable_id($feature_stable_id)) { | |
182 $self->{feature} = $f; | |
183 delete $self->{_feature_stable_id}; | |
184 } | |
185 } | |
186 elsif (my $feature_label = $self->{_feature_label}) { | |
187 # get a slice covering the vf | |
188 | |
189 | |
190 #for my $f ($fa->fetch_all_by_Slice_constraint) | |
191 } | |
192 } | |
193 } | |
194 else { | |
195 warn "Cannot get an adaptor for type: $type"; | |
196 } | |
197 } | |
198 } | |
199 } | |
200 | |
201 sub _fetch_adaptor_for_group { | |
202 my ($self, $group) = @_; | |
203 | |
204 } | |
205 | |
206 sub _feature_stable_id { | |
207 my $self = shift; | |
208 if ($self->feature && $self->feature->can('stable_id')) { | |
209 return $self->feature->stable_id; | |
210 } | |
211 elsif (my $id = $self->{_feature_stable_id}) { | |
212 return $id; | |
213 } | |
214 else { | |
215 return undef; | |
216 } | |
217 } | |
218 | |
219 =head2 base_variation_feature | |
220 | |
221 Arg [1] : (optional) A Bio::EnsEMBL::Variation::BaseVariationFeature | |
222 Description: Get/set the associated BaseVariationFeature | |
223 Returntype : Bio::EnsEMBL::Variation::BaseVariationFeature | |
224 Exceptions : throws if the argument is the wrong type | |
225 Status : At Risk | |
226 | |
227 =cut | |
228 | |
229 sub base_variation_feature { | |
230 my ($self, $bvf) = @_; | |
231 | |
232 if ($bvf) { | |
233 assert_ref($bvf, 'Bio::EnsEMBL::Variation::BaseVariationFeature'); | |
234 $self->{base_variation_feature} = $bvf; | |
235 } | |
236 | |
237 return $self->{base_variation_feature}; | |
238 } | |
239 | |
240 =head2 add_BaseVariationFeatureOverlapAllele | |
241 | |
242 Arg [1] : A Bio::EnsEMBL::Variation::BaseVariationFeatureOverlapAllele instance | |
243 Description: Add an allele to this BaseVariationFeatureOverlap | |
244 Returntype : none | |
245 Exceptions : throws if the argument is not the expected type | |
246 Status : At Risk | |
247 | |
248 =cut | |
249 | |
250 sub add_BaseVariationFeatureOverlapAllele { | |
251 my ($self, $bvfoa) = @_; | |
252 | |
253 assert_ref($bvfoa, 'Bio::EnsEMBL::Variation::BaseVariationFeatureOverlapAllele'); | |
254 | |
255 if ($bvfoa->is_reference) { | |
256 $self->{reference_allele} = $bvfoa; | |
257 } | |
258 else { | |
259 my $alt_alleles = $self->{alt_alleles} ||= []; | |
260 push @$alt_alleles, $bvfoa; | |
261 } | |
262 } | |
263 | |
264 =head2 get_reference_BaseVariationFeatureOverlapAllele | |
265 | |
266 Description: Get the object representing the reference allele of this BaseVariationFeatureOverlapAllele | |
267 Returntype : Bio::EnsEMBL::Variation::BaseVariationFeatureOverlapAllele instance | |
268 Exceptions : none | |
269 Status : At Risk | |
270 | |
271 =cut | |
272 | |
273 sub get_reference_BaseVariationFeatureOverlapAllele { | |
274 my $self = shift; | |
275 return $self->{reference_allele}; | |
276 } | |
277 | |
278 =head2 get_all_alternate_BaseVariationFeatureOverlapAlleles | |
279 | |
280 Description: Get a list of the alternate alleles of this BaseVariationFeatureOverlapAllele | |
281 Returntype : listref of Bio::EnsEMBL::Variation::BaseVariationFeatureOverlapAllele objects | |
282 Exceptions : none | |
283 Status : At Risk | |
284 | |
285 =cut | |
286 | |
287 sub get_all_alternate_BaseVariationFeatureOverlapAlleles { | |
288 my $self = shift; | |
289 | |
290 $self->{alt_alleles} ||= []; | |
291 | |
292 return $self->{alt_alleles}; | |
293 } | |
294 | |
295 =head2 get_all_BaseVariationFeatureOverlapAlleles | |
296 | |
297 Description: Get a list of the all the alleles, both reference and alternate, of this | |
298 BaseVariationFeatureOverlap | |
299 Returntype : listref of Bio::EnsEMBL::Variation::BaseVariationFeatureOverlapAllele objects | |
300 Exceptions : none | |
301 Status : At Risk | |
302 | |
303 =cut | |
304 | |
305 sub get_all_BaseVariationFeatureOverlapAlleles { | |
306 my $self = shift; | |
307 | |
308 my @alleles = @{ $self->get_all_alternate_BaseVariationFeatureOverlapAlleles }; | |
309 | |
310 my $ref = $self->get_reference_BaseVariationFeatureOverlapAllele; | |
311 | |
312 unshift @alleles, $ref if defined $ref; | |
313 | |
314 return \@alleles; | |
315 } | |
316 | |
317 =head2 consequence_type | |
318 | |
319 Arg [1] : (optional) String $term_type | |
320 Description: Get a list of all the unique consequence terms of the alleles of this | |
321 BaseVariationFeatureOverlap. By default returns Ensembl display terms | |
322 (e.g. 'NON_SYNONYMOUS_CODING'). $term_type can also be 'label' | |
323 (e.g. 'Non-synonymous coding'), 'SO' (Sequence Ontology, e.g. | |
324 'non_synonymous_codon') or 'NCBI' (e.g. 'missense') | |
325 Returntype : listref of strings | |
326 Exceptions : none | |
327 Status : At Risk | |
328 | |
329 =cut | |
330 | |
331 sub consequence_type { | |
332 my $self = shift; | |
333 my $term_type = shift; | |
334 | |
335 my $method_name; | |
336 | |
337 # delete cached term | |
338 if(defined($term_type)) { | |
339 delete $self->{_consequence_type}; | |
340 $method_name = $term_type.($term_type eq 'label' ? '' : '_term'); | |
341 $method_name = 'SO_term' unless defined $self->most_severe_OverlapConsequence && $self->most_severe_OverlapConsequence->can($method_name); | |
342 } | |
343 | |
344 $method_name ||= 'SO_term'; | |
345 | |
346 unless ($self->{_consequence_type}) { | |
347 | |
348 # use a hash to ensure we don't include redundant terms (because more than one | |
349 # allele may have the same consequence SO_term) | |
350 | |
351 my %cons_types; | |
352 | |
353 for my $allele (@{ $self->get_all_alternate_BaseVariationFeatureOverlapAlleles }) { | |
354 for my $cons (@{ $allele->get_all_OverlapConsequences }) { | |
355 $cons_types{$cons->$method_name} = $cons->rank; | |
356 } | |
357 } | |
358 | |
359 # sort the consequence types by rank such that the more severe terms are earlier in the list | |
360 | |
361 $self->{_consequence_type} = [ sort { $cons_types{$a} <=> $cons_types{$b} } keys %cons_types ]; | |
362 } | |
363 | |
364 return $self->{_consequence_type}; | |
365 } | |
366 | |
367 =head2 most_severe_OverlapConsequence | |
368 | |
369 Description: Get the OverlapConsequence considered (by Ensembl) to be the most severe | |
370 consequence of all the alleles of this VariationFeatureOverlap | |
371 Returntype : Bio::EnsEMBL::Variation::OverlapConsequence | |
372 Exceptions : none | |
373 Status : At Risk | |
374 | |
375 =cut | |
376 | |
377 sub most_severe_OverlapConsequence { | |
378 my $self = shift; | |
379 | |
380 unless ($self->{_most_severe_consequence}) { | |
381 | |
382 my $highest; | |
383 | |
384 for my $allele (@{ $self->get_all_alternate_BaseVariationFeatureOverlapAlleles }) { | |
385 for my $cons (@{ $allele->get_all_OverlapConsequences }) { | |
386 $highest ||= $cons; | |
387 if ($cons->rank < $highest->rank) { | |
388 $highest = $cons; | |
389 } | |
390 } | |
391 } | |
392 | |
393 $self->{_most_severe_consequence} = $highest; | |
394 } | |
395 | |
396 return $self->{_most_severe_consequence}; | |
397 } | |
398 | |
399 =head2 display_consequence | |
400 | |
401 Arg [1] : (optional) String $term_type | |
402 Description: Get the term for the most severe OverlapConsequence of this | |
403 VariationFeatureOverlap. By default returns Ensembl display terms | |
404 (e.g. 'NON_SYNONYMOUS_CODING'). $term_type can also be 'label' | |
405 (e.g. 'Non-synonymous coding'), 'SO' (Sequence Ontology, e.g. | |
406 'non_synonymous_codon') or 'NCBI' (e.g. 'missense') | |
407 Returntype : string | |
408 Exceptions : none | |
409 Status : At Risk | |
410 | |
411 =cut | |
412 | |
413 sub display_consequence { | |
414 my $self = shift; | |
415 my $term_type = shift; | |
416 | |
417 my $method_name; | |
418 | |
419 # delete cached term | |
420 if(defined($term_type)) { | |
421 $method_name = $term_type.($term_type eq 'label' ? '' : '_term'); | |
422 $method_name = 'SO_term' unless @{$self->get_all_OverlapConsequences} && $self->get_all_OverlapConsequences->[0]->can($method_name); | |
423 } | |
424 | |
425 $method_name ||= 'SO_term'; | |
426 | |
427 my $worst_conseq = $self->most_severe_OverlapConsequence; | |
428 | |
429 return $worst_conseq ? $worst_conseq->$method_name : ''; | |
430 } | |
431 | |
432 sub adaptor { | |
433 my $self = shift; | |
434 $self->{adaptor} = shift if @_; | |
435 | |
436 # make adaptor an anonymous hash in its absence | |
437 # this allows the VEP to cache OverlapConsequences in offline mode | |
438 $self->{adaptor} ||= {}; | |
439 | |
440 return $self->{adaptor}; | |
441 } | |
442 | |
443 1; | |
444 |