Mercurial > repos > mahtabm > ensembl
diff variant_effect_predictor/Bio/EnsEMBL/Variation/BaseVariationFeatureOverlap.pm @ 0:1f6dce3d34e0
Uploaded
author | mahtabm |
---|---|
date | Thu, 11 Apr 2013 02:01:53 -0400 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/variant_effect_predictor/Bio/EnsEMBL/Variation/BaseVariationFeatureOverlap.pm Thu Apr 11 02:01:53 2013 -0400 @@ -0,0 +1,444 @@ +=head1 LICENSE + + Copyright (c) 1999-2012 The European Bioinformatics Institute and + Genome Research Limited. All rights reserved. + + This software is distributed under a modified Apache license. + For license details, please see + + http://www.ensembl.org/info/about/code_licence.html + +=head1 CONTACT + + Please email comments or questions to the public Ensembl + developers list at <dev@ensembl.org>. + + Questions may also be sent to the Ensembl help desk at + <helpdesk@ensembl.org>. + +=cut + +=head1 NAME + +Bio::EnsEMBL::Variation::BaseVariationFeatureOverlap + +=head1 SYNOPSIS + + use Bio::EnsEMBL::Variation::BaseVariationFeatureOverlap; + + my $bvfo = Bio::EnsEMBL::Variation::BaseVariationFeatureOverlap->new( + -feature => $feature, + -base_variation_feature => $var_feat + ); + + print "consequence type: ", (join ",", @{ $bvfo->consequence_type }), "\n"; + print "most severe consequence: ", $bvfo->display_consequence, "\n"; + +=head1 DESCRIPTION + +A BaseVariationFeatureOverlap represents a BaseVariationFeature which is in close +proximity to another Ensembl Feature. It is the superclass of variation feature +specific classes such as VariationFeatureOverlap and StructuralVariationOverlap +and has methods common to all such objects. You will not normally instantiate this +class directly, instead instantiating one of the more specific subclasses. + +=cut + +package Bio::EnsEMBL::Variation::BaseVariationFeatureOverlap; + +use strict; +use warnings; + +use Bio::EnsEMBL::Utils::Argument qw(rearrange); +use Bio::EnsEMBL::Utils::Scalar qw(assert_ref); +use Bio::EnsEMBL::Utils::Exception qw(throw warning); +use Bio::EnsEMBL::Variation::Utils::VariationEffect qw(overlap within_cds); + +sub new { + my $class = shift; + + my ( + $adaptor, + $base_variation_feature, + $feature, + $no_transfer + ) = rearrange([qw( + ADAPTOR + BASE_VARIATION_FEATURE + FEATURE + NO_TRANSFER + )], @_); + + assert_ref($base_variation_feature, 'Bio::EnsEMBL::Variation::BaseVariationFeature'); + + if (defined $feature) { + + assert_ref($feature, 'Bio::EnsEMBL::Feature'); + + # we need to ensure the Feature and the BaseVariationFeature live on the same slice + # so we explicitly transfer the Feature here + unless($no_transfer && $no_transfer == 1) { + $feature = $feature->transfer($base_variation_feature->slice) + or throw("Unable to transfer the supplied feature to the same slice as the base variation feature"); + } + } + + my $self = bless { + base_variation_feature => $base_variation_feature, + feature => $feature, + adaptor => $adaptor, + }, $class; + + return $self; +} + +sub new_fast { + my ($class, $hashref) = @_; + return bless $hashref, $class; +} + +=head2 feature + + Arg [1] : (optional) A Bio::EnsEMBL::Feature + Description: Get/set the associated Feature, lazy-loading it if required + Returntype : Bio::EnsEMBL::Feature + Exceptions : throws isf the argument is the wrong type + Status : At Risk + +=cut + +sub feature { + my ($self, $feature, $type) = @_; + + if ($feature) { + assert_ref($feature, 'Bio::EnsEMBL::Feature'); + $self->{feature} = $feature; + } + + if ($type && !$self->{feature}) { + + # try to lazy load the feature + + if (my $adap = $self->{adaptor}) { + + my $get_method = 'get_'.$type.'Adaptor'; + + # XXX: this can doesn't work because the method is AUTOLOADed, need to rethink this... + #if ($adap->db->dnadb->can($get_method)) { + if (my $fa = $adap->db->dnadb->$get_method) { + + # if we have a stable id for the feature use that + if (my $feature_stable_id = $self->{_feature_stable_id}) { + if (my $f = $fa->fetch_by_stable_id($feature_stable_id)) { + $self->{feature} = $f; + delete $self->{_feature_stable_id}; + } + } + elsif (my $feature_label = $self->{_feature_label}) { + # get a slice covering the vf + + #for my $f ($fa->fetch_all_by_Slice_constraint) + } + } + #} + else { + warn "Cannot get an adaptor for type: $type"; + } + } + } + + return $self->{feature}; +} + +sub _fetch_feature_for_stable_id { + + # we shouldn't actually need this method as there will apparently + # soon be core support for fetching any feature by its stable id, + # but I'm waiting for core to add this... + + my ($self, $feature_stable_id) = @_; + + my $type_lookup = { + G => { type => 'Gene', group => 'core' }, + T => { type => 'Transcript', group => 'core' }, + R => { type => 'RegulatoryFeature', group => 'funcgen' }, + }; + + if ($feature_stable_id =~ /^ENS[A-Z]*([G|R|T])\d+$/) { + + my $type = $type_lookup->{$1}->{type}; + my $group = $type_lookup->{$1}->{group}; + + if (my $adap = $self->{adaptor}) { + + my $get_method = 'get_'.$type.'Adaptor'; + + if ($adap->db->dnadb->can($get_method)) { + if (my $fa = $adap->db->dnadb->$get_method) { + + # if we have a stable id for the feature use that + if (my $feature_stable_id = $self->{_feature_stable_id}) { + if (my $f = $fa->fetch_by_stable_id($feature_stable_id)) { + $self->{feature} = $f; + delete $self->{_feature_stable_id}; + } + } + elsif (my $feature_label = $self->{_feature_label}) { + # get a slice covering the vf + + + #for my $f ($fa->fetch_all_by_Slice_constraint) + } + } + } + else { + warn "Cannot get an adaptor for type: $type"; + } + } + } +} + +sub _fetch_adaptor_for_group { + my ($self, $group) = @_; + +} + +sub _feature_stable_id { + my $self = shift; + if ($self->feature && $self->feature->can('stable_id')) { + return $self->feature->stable_id; + } + elsif (my $id = $self->{_feature_stable_id}) { + return $id; + } + else { + return undef; + } +} + +=head2 base_variation_feature + + Arg [1] : (optional) A Bio::EnsEMBL::Variation::BaseVariationFeature + Description: Get/set the associated BaseVariationFeature + Returntype : Bio::EnsEMBL::Variation::BaseVariationFeature + Exceptions : throws if the argument is the wrong type + Status : At Risk + +=cut + +sub base_variation_feature { + my ($self, $bvf) = @_; + + if ($bvf) { + assert_ref($bvf, 'Bio::EnsEMBL::Variation::BaseVariationFeature'); + $self->{base_variation_feature} = $bvf; + } + + return $self->{base_variation_feature}; +} + +=head2 add_BaseVariationFeatureOverlapAllele + + Arg [1] : A Bio::EnsEMBL::Variation::BaseVariationFeatureOverlapAllele instance + Description: Add an allele to this BaseVariationFeatureOverlap + Returntype : none + Exceptions : throws if the argument is not the expected type + Status : At Risk + +=cut + +sub add_BaseVariationFeatureOverlapAllele { + my ($self, $bvfoa) = @_; + + assert_ref($bvfoa, 'Bio::EnsEMBL::Variation::BaseVariationFeatureOverlapAllele'); + + if ($bvfoa->is_reference) { + $self->{reference_allele} = $bvfoa; + } + else { + my $alt_alleles = $self->{alt_alleles} ||= []; + push @$alt_alleles, $bvfoa; + } +} + +=head2 get_reference_BaseVariationFeatureOverlapAllele + + Description: Get the object representing the reference allele of this BaseVariationFeatureOverlapAllele + Returntype : Bio::EnsEMBL::Variation::BaseVariationFeatureOverlapAllele instance + Exceptions : none + Status : At Risk + +=cut + +sub get_reference_BaseVariationFeatureOverlapAllele { + my $self = shift; + return $self->{reference_allele}; +} + +=head2 get_all_alternate_BaseVariationFeatureOverlapAlleles + + Description: Get a list of the alternate alleles of this BaseVariationFeatureOverlapAllele + Returntype : listref of Bio::EnsEMBL::Variation::BaseVariationFeatureOverlapAllele objects + Exceptions : none + Status : At Risk + +=cut + +sub get_all_alternate_BaseVariationFeatureOverlapAlleles { + my $self = shift; + + $self->{alt_alleles} ||= []; + + return $self->{alt_alleles}; +} + +=head2 get_all_BaseVariationFeatureOverlapAlleles + + Description: Get a list of the all the alleles, both reference and alternate, of this + BaseVariationFeatureOverlap + Returntype : listref of Bio::EnsEMBL::Variation::BaseVariationFeatureOverlapAllele objects + Exceptions : none + Status : At Risk + +=cut + +sub get_all_BaseVariationFeatureOverlapAlleles { + my $self = shift; + + my @alleles = @{ $self->get_all_alternate_BaseVariationFeatureOverlapAlleles }; + + my $ref = $self->get_reference_BaseVariationFeatureOverlapAllele; + + unshift @alleles, $ref if defined $ref; + + return \@alleles; +} + +=head2 consequence_type + + Arg [1] : (optional) String $term_type + Description: Get a list of all the unique consequence terms of the alleles of this + BaseVariationFeatureOverlap. By default returns Ensembl display terms + (e.g. 'NON_SYNONYMOUS_CODING'). $term_type can also be 'label' + (e.g. 'Non-synonymous coding'), 'SO' (Sequence Ontology, e.g. + 'non_synonymous_codon') or 'NCBI' (e.g. 'missense') + Returntype : listref of strings + Exceptions : none + Status : At Risk + +=cut + +sub consequence_type { + my $self = shift; + my $term_type = shift; + + my $method_name; + + # delete cached term + if(defined($term_type)) { + delete $self->{_consequence_type}; + $method_name = $term_type.($term_type eq 'label' ? '' : '_term'); + $method_name = 'SO_term' unless defined $self->most_severe_OverlapConsequence && $self->most_severe_OverlapConsequence->can($method_name); + } + + $method_name ||= 'SO_term'; + + unless ($self->{_consequence_type}) { + + # use a hash to ensure we don't include redundant terms (because more than one + # allele may have the same consequence SO_term) + + my %cons_types; + + for my $allele (@{ $self->get_all_alternate_BaseVariationFeatureOverlapAlleles }) { + for my $cons (@{ $allele->get_all_OverlapConsequences }) { + $cons_types{$cons->$method_name} = $cons->rank; + } + } + + # sort the consequence types by rank such that the more severe terms are earlier in the list + + $self->{_consequence_type} = [ sort { $cons_types{$a} <=> $cons_types{$b} } keys %cons_types ]; + } + + return $self->{_consequence_type}; +} + +=head2 most_severe_OverlapConsequence + + Description: Get the OverlapConsequence considered (by Ensembl) to be the most severe + consequence of all the alleles of this VariationFeatureOverlap + Returntype : Bio::EnsEMBL::Variation::OverlapConsequence + Exceptions : none + Status : At Risk + +=cut + +sub most_severe_OverlapConsequence { + my $self = shift; + + unless ($self->{_most_severe_consequence}) { + + my $highest; + + for my $allele (@{ $self->get_all_alternate_BaseVariationFeatureOverlapAlleles }) { + for my $cons (@{ $allele->get_all_OverlapConsequences }) { + $highest ||= $cons; + if ($cons->rank < $highest->rank) { + $highest = $cons; + } + } + } + + $self->{_most_severe_consequence} = $highest; + } + + return $self->{_most_severe_consequence}; +} + +=head2 display_consequence + + Arg [1] : (optional) String $term_type + Description: Get the term for the most severe OverlapConsequence of this + VariationFeatureOverlap. By default returns Ensembl display terms + (e.g. 'NON_SYNONYMOUS_CODING'). $term_type can also be 'label' + (e.g. 'Non-synonymous coding'), 'SO' (Sequence Ontology, e.g. + 'non_synonymous_codon') or 'NCBI' (e.g. 'missense') + Returntype : string + Exceptions : none + Status : At Risk + +=cut + +sub display_consequence { + my $self = shift; + my $term_type = shift; + + my $method_name; + + # delete cached term + if(defined($term_type)) { + $method_name = $term_type.($term_type eq 'label' ? '' : '_term'); + $method_name = 'SO_term' unless @{$self->get_all_OverlapConsequences} && $self->get_all_OverlapConsequences->[0]->can($method_name); + } + + $method_name ||= 'SO_term'; + + my $worst_conseq = $self->most_severe_OverlapConsequence; + + return $worst_conseq ? $worst_conseq->$method_name : ''; +} + +sub adaptor { + my $self = shift; + $self->{adaptor} = shift if @_; + + # make adaptor an anonymous hash in its absence + # this allows the VEP to cache OverlapConsequences in offline mode + $self->{adaptor} ||= {}; + + return $self->{adaptor}; +} + +1; +