Mercurial > repos > mahtabm > ensemb_rep_gvl
diff variant_effect_predictor/Bio/EnsEMBL/Translation.pm @ 0:2bc9b66ada89 draft default tip
Uploaded
author | mahtabm |
---|---|
date | Thu, 11 Apr 2013 06:29:17 -0400 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/variant_effect_predictor/Bio/EnsEMBL/Translation.pm Thu Apr 11 06:29:17 2013 -0400 @@ -0,0 +1,1227 @@ +=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::Translation - A class representing the translation of a +transcript + +=head1 SYNOPSIS + + my $translation = Bio::EnsEMBL::Translation->new( + -START_EXON => $exon1, + -END_EXON => $exon2, + -SEQ_START => 98, + -SEQ_END => 39 + ); + + # stable ID setter + $translation->stable_id('ENSP00053458'); + + # get start and end position in start/end exons + my $start = $translation->start; + my $end = $translation->end; + +=head1 DESCRIPTION + +A Translation object defines the CDS and UTR regions of a Transcript +through the use of start_Exon/end_Exon, and start/end attributes. + +=cut + + +package Bio::EnsEMBL::Translation; + +use vars qw($AUTOLOAD @ISA); +use strict; + +use Scalar::Util qw(weaken isweak); + +use Bio::EnsEMBL::Utils::Exception qw( deprecate throw warning ); +use Bio::EnsEMBL::Utils::Argument qw( rearrange ); +use Bio::EnsEMBL::Utils::Scalar qw( assert_ref ); + +use Bio::EnsEMBL::Storable; + +@ISA = qw(Bio::EnsEMBL::Storable); + + +=head2 new + + Arg [-START_EXON] : The Exon object in which the translation (CDS) starts + Arg [-END_EXON] : The Exon object in which the translation (CDS) ends + Arg [-SEQ_START] : The offset in the start_Exon indicating the start + position of the CDS. + Arg [-SEQ_END] : The offset in the end_Exon indicating the end + position of the CDS. + Arg [-STABLE_ID] : The stable identifier for this Translation + Arg [-VERSION] : The version of the stable identifier + Arg [-DBID] : The internal identifier of this Translation + Arg [-ADAPTOR] : The TranslationAdaptor for this Translation + Arg [-SEQ] : Manually sets the peptide sequence of this translation. + May be useful if this translation is not stored in + a database. + Arg [-CREATED_DATE]: the date the translation was created + Arg [-MODIFIED_DATE]: the date the translation was modified + Example : my $tl = Bio::EnsEMBL::Translation->new + (-START_EXON => $ex1, + -END_EXON => $ex2, + -SEQ_START => 98, + -SEQ_END => 39); + Description: Constructor. Creates a new Translation object + Returntype : Bio::EnsEMBL::Translation + Exceptions : none + Caller : general + Status : Stable + +=cut + +sub new { + my $caller = shift; + + my $class = ref($caller) || $caller; + + my ( $start_exon, $end_exon, $seq_start, $seq_end, + $stable_id, $version, $dbID, $adaptor, $seq, + $created_date, $modified_date ) = + rearrange( [ "START_EXON", "END_EXON", "SEQ_START", "SEQ_END", + "STABLE_ID", "VERSION", "DBID", "ADAPTOR", + "SEQ", "CREATED_DATE", "MODIFIED_DATE" ], @_ ); + + my $self = bless { + 'start_exon' => $start_exon, + 'end_exon' => $end_exon, + 'dbID' => $dbID, + 'start' => $seq_start, + 'end' => $seq_end, + 'stable_id' => $stable_id, + 'version' => $version, + 'created_date' => $created_date, + 'modified_date' => $modified_date, + 'seq' => $seq + }, $class; + + $self->adaptor($adaptor); + + return $self; +} + +=head2 new_fast + + Arg [1] : hashref to be blessed + Description: Construct a new Bio::EnsEMBL::Translation using the hashref. + Exceptions : none + Returntype : Bio::EnsEMBL::Translation + Caller : general, subclass constructors + Status : Stable + +=cut + + +sub new_fast { + my $class = shift; + my $hashref = shift; + my $self = bless $hashref, $class; + weaken($self->{adaptor}) if ( ! isweak($self->{adaptor}) ); + return $self; +} + +=head2 transcript + + Arg [1] : Transcript object (optional) + Description : Sets or retrieves the transcript object associated + with this translation object. + Exceptions : Throws if there is no adaptor or no dbID defined for + the translation object. + Returntype : Bio::EnsEMBL::Transcript +=cut + +sub transcript { + my ( $self, $transcript ) = @_; + + if ( defined($transcript) ) { + assert_ref( $transcript, 'Bio::EnsEMBL::Transcript' ); + + $self->{'transcript'} = $transcript; + + weaken( $self->{'transcript'} ); # Avoid circular references. + + } elsif ( @_ > 1 ) { + # Break connection to transcript. + delete( $self->{'transcript'} ); + } elsif ( !defined( $self->{'transcript'} ) ) { + my $adaptor = $self->adaptor; + if ( !defined($adaptor) ) { + throw( "Adaptor is not set for translation, " + . "can not fetch its transcript." ); + } + + my $dbID = $self->{'dbID'}; + if ( !defined($dbID) ) { + throw( "dbID is not set for translation, " + . " can not fetch its transcript." ); + } + + $self->{'transcript'} = + $adaptor->db()->get_TranscriptAdaptor() + ->fetch_by_translation_id($dbID); + + # Do not weaken the reference if we had to get the transcript from the + # database. The user is probably working on translations directly, + # not going through transcripts. + #weaken( $self->{'transcript'} ); # Avoid circular references. + } + + return $self->{'transcript'}; +} ## end sub transcript + + +=head2 start + + Arg [1] : (optional) int $start - start position to set + Example : $translation->start(17); + Description: Getter/setter for the value of start, which is a position within + the exon given by start_Exon. + + If you need genomic coordinates, use the genomic_start() + method. + Returntype : int + Exceptions : none + Caller : general + Status : Stable + +=cut + +sub start{ + my $obj = shift; + if( @_ ) { + my $value = shift; + + $obj->{'start'} = $value; + } + return $obj->{'start'}; + +} + + +=head2 end + + Arg [1] : (optional) int $end - end position to set + Example : $translation->end(8); + Description: Getter/setter for the value of end, which is a position within + the exon given by end_Exon. + + If you need genomic coordinates, use the genomic_end() + method. + Returntype : int + Exceptions : none + Caller : general + Status : Stable + +=cut + +sub end { + my $self = shift; + if( @_ ) { + my $value = shift; + + $self->{'end'} = $value; + } + return $self->{'end'}; + +} + + +=head2 start_Exon + + Arg [1] : (optional) Bio::EnsEMBL::Exon - start exon to assign + Example : $translation->start_Exon($exon1); + Description: Getter/setter for the value of start_Exon, which denotes the + exon at which translation starts (and within this exon, at the + position indicated by start, see above). + Returntype : Bio::EnsEMBL::Exon + Exceptions : thrown on wrong argument type + Caller : general + Status : Stable + +=cut + +sub start_Exon { + my $self = shift; + + if( @_ ) { + my $value = shift; + if( !ref $value || !$value->isa('Bio::EnsEMBL::Exon') ) { + throw("Got to have an Exon object, not a $value"); + } + $self->{'start_exon'} = $value; + } + return $self->{'start_exon'}; +} + + +=head2 end_Exon + + Arg [1] : (optional) Bio::EnsEMBL::Exon - start exon to assign + Example : $translation->start_Exon($exon1); + Description: Getter/setter for the value of end_Exon, which denotes the + exon at which translation ends (and within this exon, at the + position indicated by end, see above). + Returntype : Bio::EnsEMBL::Exon + Exceptions : thrown on wrong argument type + Caller : general + Status : Stable + +=cut + +sub end_Exon { + my $self = shift; + if( @_ ) { + my $value = shift; + if( !ref $value || !$value->isa('Bio::EnsEMBL::Exon') ) { + throw("Got to have an Exon object, not a $value"); + } + $self->{'end_exon'} = $value; + } + + return $self->{'end_exon'}; +} + +=head2 cdna_start + + Arg [1] : (optional) Bio::EnsEMBL::Transcript $transcript + The transcript which this is a translation of. + Example : $translation_cdna_start = $translation->cdna_start(); + Description : Returns the start position of the translation in cDNA + coordinates. + If no transcript is given, the method will use + TranscriptAdaptor->fetch_by_translation_id() to locate + the correct transcript. + Return type : Integer + Exceptions : Throws if the given (optional) argument is not a + transcript. + Caller : General + Status : At Risk (Under Development) + +=cut + +sub cdna_start { + my ( $self, $transcript ) = @_; + + if ( defined($transcript) + && ( !ref($transcript) + || !$transcript->isa('Bio::EnsEMBL::Transcript') ) ) + { + throw("Argument is not a transcript"); + } + + if ( !exists( $self->{'cdna_start'} ) ) { + if ( !defined($transcript) ) { + # We were not given a transcript, get the transcript out of + # the database. + $transcript = $self->transcript(); + } + + $self->{'cdna_start'} = + $self->start_Exon()->cdna_coding_start($transcript); + } + + return $self->{'cdna_start'}; +} + +=head2 cdna_end + + Arg [1] : (optional) Bio::EnsEMBL::Transcript $transcript + The transcript which this is a translation of. + Example : $translation_cdna_end = $translation->cdna_end(); + Description : Returns the end position of the translation in cDNA + coordinates. + If no transcript is given, the method will use + TranscriptAdaptor->fetch_by_translation_id() to locate + the correct transcript. + Return type : Integer + Exceptions : Throws if the given (optional) argument is not a + transcript. + Caller : General + Status : At Risk (Under Development) + +=cut + +sub cdna_end { + my ( $self, $transcript ) = @_; + + if ( defined($transcript) + && ( !ref($transcript) + || !$transcript->isa('Bio::EnsEMBL::Transcript') ) ) + { + throw("Argument is not a transcript"); + } + + if ( !exists( $self->{'cdna_end'} ) ) { + if ( !defined($transcript) ) { + # We were not given a transcript, get the transcript out of + # the database. + $transcript = $self->transcript(); + } + + $self->{'cdna_end'} = + $self->end_Exon()->cdna_coding_end($transcript); + } + + return $self->{'cdna_end'}; +} + +=head2 genomic_start + + Args : None + Example : $translation_genomic_start = + $translation->genomic_start(); + Description : Returns the start position of the translation in + genomic coordinates on the forward strand. + Return type : Integer + Exceptions : None + Caller : General + Status : At Risk (Under Development) + +=cut + +sub genomic_start { + my $self = shift; + + if ( !exists $self->{'genomic_start'} ) { + if ( $self->start_Exon()->strand() >= 0 ) { + $self->{'genomic_start'} = + $self->start_Exon()->start() + ( $self->start() - 1 ); + } else { + $self->{'genomic_start'} = + $self->end_Exon()->end() - ( $self->end() - 1 ); + } + } + + return $self->{'genomic_start'}; +} + +=head2 genomic_end + + Args : None + Example : $translation_genomic_end = $translation->genomic_end(); + Description : Returns the end position of the translation in genomic + coordinates on the forward strand. + Return type : Integer + Exceptions : None + Caller : General + Status : At Risk (Under Development) + +=cut + +sub genomic_end { + my $self = shift; + + if ( !exists $self->{'genomic_end'} ) { + if ( $self->end_Exon()->strand() >= 0 ) { + $self->{'genomic_end'} = + $self->end_Exon()->start() + ( $self->end() - 1 ); + } else { + $self->{'genomic_end'} = + $self->start_Exon()->end() - ( $self->start() - 1 ); + } + } + + return $self->{'genomic_end'}; +} + +=head2 version + + Arg [1] : (optional) string $version - version to set + Example : $translation->version(2); + Description: Getter/setter for attribute version + Returntype : string + Exceptions : none + Caller : general + Status : Stable + +=cut + +sub version { + my $self = shift; + $self->{'version'} = shift if( @_ ); + return $self->{'version'}; +} + + +=head2 stable_id + + Arg [1] : (optional) string $stable_id - stable ID to set + Example : $translation->stable_id('ENSP0059890'); + Description: Getter/setter for attribute stable_id + Returntype : string + Exceptions : none + Caller : general + Status : Stable + +=cut + +sub stable_id { + my $self = shift; + $self->{'stable_id'} = shift if( @_ ); + return $self->{'stable_id'}; +} + +=head2 created_date + + Arg [1] : (optional) string $created_date - created date to set + Example : $translation->created_date('2007-01-10 20:52:00'); + Description: Getter/setter for attribute created date + Returntype : string + Exceptions : none + Caller : general + Status : Stable + +=cut + +sub created_date { + my $self = shift; + $self->{'created_date'} = shift if ( @_ ); + return $self->{'created_date'}; +} + + +=head2 modified_date + + Arg [1] : (optional) string $modified_date - modification date to set + Example : $translation->modified_date('2007-01-10 20:52:00'); + Description: Getter/setter for attribute modified date + Returntype : string + Exceptions : none + Caller : general + Status : Stable + +=cut + +sub modified_date { + my $self = shift; + $self->{'modified_date'} = shift if ( @_ ); + return $self->{'modified_date'}; +} + + + +=head2 transform + + Arg [1] : hashref $old_new_exon_map + a hash that maps old to new exons for a whole gene + Description: maps start end end exon according to mapping table. + If an exon is not mapped, just keep the old one. + Returntype : none + Exceptions : none + Caller : Transcript->transform() + Status : Stable + +=cut + +sub transform { + my $self = shift; + my $href_exons = shift; + + my $start_exon = $self->start_Exon(); + my $end_exon = $self->end_Exon(); + + if ( exists $href_exons->{$start_exon} ) { + $self->start_Exon($href_exons->{$start_exon}); + } else { + # do nothing, the start exon wasnt mapped + } + + if ( exists $href_exons->{$end_exon} ) { + $self->end_Exon($href_exons->{$end_exon}); + } else { + # do nothing, the end exon wasnt mapped + } +} + + +=head2 get_all_DBEntries + + Arg [1] : (optional) String, external database name + + Arg [2] : (optional) String, external_db type + + Example : @dbentries = @{ $translation->get_all_DBEntries() }; + + Description: Retrieves DBEntries (xrefs) for this translation. + + This method will attempt to lazy-load DBEntries + from a database if an adaptor is available and no + DBEntries are present on the translation (i.e. they + have not already been added or loaded). + + Returntype : Listref to Bio::EnsEMBL::DBEntry objects + Exceptions : none + Caller : TranslationAdaptor::store + Status : Stable + +=cut + +sub get_all_DBEntries { + my ( $self, $ex_db_exp, $ex_db_type ) = @_; + + my $cache_name = 'dbentries'; + + if ( defined($ex_db_exp) ) { + $cache_name .= $ex_db_exp; + } + + if ( defined($ex_db_type) ) { + $cache_name .= $ex_db_type; + } + + # if not cached, retrieve all of the xrefs for this translation + if ( !defined( $self->{$cache_name} ) && defined( $self->adaptor() ) ) + { + $self->{$cache_name} = + $self->adaptor()->db()->get_DBEntryAdaptor() + ->fetch_all_by_Translation( $self, $ex_db_exp, $ex_db_type ); + } + + $self->{$cache_name} ||= []; + + return $self->{$cache_name}; +} ## end sub get_all_DBEntries + +=head2 get_all_object_xrefs + + Arg [1] : (optional) String, external database name + + Arg [2] : (optional) String, external_db type + + Example : @oxrefs = @{ $translation->get_all_object_xrefs() }; + + Description: Retrieves xrefs for this translation. + + This method will attempt to lazy-load xrefs from a + database if an adaptor is available and no xrefs + are present on the translation (i.e. they have not + already been added or loaded). + + NB: This method is an alias for the + get_all_DBentries() method. + + Return type: Listref of Bio::EnsEMBL::DBEntry objects + + Status : Stable + +=cut + +sub get_all_object_xrefs { + my $self = shift; + return $self->get_all_DBEntries(@_); +} + +=head2 add_DBEntry + + Arg [1] : Bio::EnsEMBL::DBEntry $dbe + The dbEntry to be added + Example : $translation->add_DBEntry($xref); + Description: Associates a DBEntry with this translation. Note that adding + DBEntries will prevent future lazy-loading of DBEntries for this + translation (see get_all_DBEntries). + Returntype : none + Exceptions : thrown on incorrect argument type + Caller : general + Status : Stable + +=cut + +sub add_DBEntry { + my $self = shift; + my $dbe = shift; + + unless($dbe && ref($dbe) && $dbe->isa('Bio::EnsEMBL::DBEntry')) { + throw('Expected DBEntry argument'); + } + + $self->{'dbentries'} ||= []; + push @{$self->{'dbentries'}}, $dbe; +} + + +=head2 get_all_DBLinks + + Arg [1] : String database name (optional) + SQL wildcard characters (_ and %) can be used to + specify patterns. + + Example : my @dblinks = @{ $translation->get_all_DBLinks() }; + my @dblinks = @{ $translation->get_all_DBLinks('Uniprot%') }; + + Description: This is here for consistancy with the Transcript + and Gene classes. It is a synonym for the + get_all_DBEntries() method. + + Return type: Listref to Bio::EnsEMBL::DBEntry objects + Exceptions : none + Caller : general + Status : Stable + +=cut + +sub get_all_DBLinks { + my $self = shift; + return $self->get_all_DBEntries(@_); +} + +=head2 get_all_xrefs + + Arg [1] : String database name (optional) + SQL wildcard characters (_ and %) can be used to + specify patterns. + + Example : @xrefs = @{ $translation->get_all_xrefs() }; + @xrefs = @{ $translation->get_all_xrefs('Uniprot%') }; + + Description: This method is here for consistancy with the Gene + and Transcript classes. It is an alias for the + get_all_DBLinks() method, which in turn directly + calls get_all_DBEntries(). + + Return type: Listref of Bio::EnsEMBL::DBEntry objects + + Status : Stable + +=cut + +sub get_all_xrefs { + my $self = shift; + return $self->get_all_DBLinks(@_); +} + +=head2 get_all_ProteinFeatures + + Arg [1] : (optional) string $logic_name + The analysis logic_name of the features to retrieve. If not + specified, all features are retrieved instead. + Example : $features = $self->get_all_ProteinFeatures('PFam'); + Description: Retrieves all ProteinFeatures associated with this + Translation. If a logic_name is specified, only features with + that logic_name are returned. If no logic_name is provided all + associated protein_features are returned. + + ProteinFeatures are lazy-loaded from the database unless they + added manually to the Translation or had already been loaded. + Returntype : Bio::EnsEMBL::ProteinFeature + Exceptions : none + Caller : general + Status : Stable + +=cut + +sub get_all_ProteinFeatures { + my $self = shift; + my $logic_name = shift; + + if(!$self->{'protein_features'}) { + my $adaptor = $self->adaptor(); + my $dbID = $self->dbID(); + + return [] if (!$adaptor || !$dbID); + + my %hash; + $self->{'protein_features'} = \%hash; + + my $pfa = $adaptor->db()->get_ProteinFeatureAdaptor(); + my $name; + foreach my $f (@{$pfa->fetch_all_by_translation_id($dbID)}) { + my $analysis = $f->analysis(); + if($analysis) { + $name = lc($f->analysis->logic_name()); + } else { + warning("ProteinFeature has no attached analysis\n"); + $name = ''; + } + $hash{$name} ||= []; + push @{$hash{$name}}, $f; + } + } + + # a specific type of protein feature was requested + if(defined($logic_name)) { + $logic_name = lc($logic_name); + return $self->{'protein_features'}->{$logic_name} || []; + } + + my @features = (); + + # all protein features were requested + foreach my $type (keys %{$self->{'protein_features'}}) { + push @features, @{$self->{'protein_features'}->{$type}}; + } + + return \@features; +} + + +=head2 get_all_DomainFeatures + + Example : @domain_feats = @{$translation->get_all_DomainFeatures}; + Description: A convenience method which retrieves all protein features + that are considered to be 'Domain' features. Features which + are 'domain' features are those with analysis logic names: + 'pfscan', 'scanprosite', 'superfamily', 'pfam', 'prints', + 'smart', 'pirsf', 'tigrfam'. + Returntype : listref of Bio::EnsEMBL::ProteinFeatures + Exceptions : none + Caller : webcode (protview) + Status : Stable + +=cut + +sub get_all_DomainFeatures{ + my ($self) = @_; + + my @features; + + my @types = ('pfscan', #profile (prosite or pfam motifs) + 'scanprosite', #prosite + 'superfamily', + 'pfam', + 'smart', + 'tigrfam', + 'pirsf', + 'prints'); + + foreach my $type (@types) { + push @features, @{$self->get_all_ProteinFeatures($type)}; + } + + return \@features; +} + + +=head2 add_ProteinFeature + + Arg [1] : Bio::EnsEMBL::ProteinFeature $pf + The ProteinFeature to be added + Example : $translation->add_ProteinFeature($pf); + Description: Associates a ProteinFeature with this translation. Note that + adding ProteinFeatures will prevent future lazy-loading of + ProteinFeatures for this translation (see + get_all_ProteinFeatures). + Returntype : none + Exceptions : thrown on incorrect argument type + Caller : general + Status : Stable + +=cut + +sub add_ProteinFeature { + my $self = shift; + my $pf = shift; + + unless ($pf && ref($pf) && $pf->isa('Bio::EnsEMBL::ProteinFeature')) { + throw('Expected ProteinFeature argument'); + } + + my $analysis = $pf->analysis; + throw("ProteinFeature has no attached Analysis.") unless $analysis; + + push @{ $self->{'protein_features'}->{$analysis->logic_name} }, $pf; +} + + +=head2 display_id + + Example : print $translation->display_id(); + Description: This method returns a string that is considered to be + the 'display' identifier. For translations this is (depending on + availability and in this order) the stable Id, the dbID or an + empty string. + Returntype : string + Exceptions : none + Caller : web drawing code + Status : Stable + +=cut + +sub display_id { + my $self = shift; + return $self->{'stable_id'} || $self->dbID || ''; +} + + +=head2 length + + Example : print "Peptide length =", $translation->length(); + Description: Retrieves the length of the peptide sequence (i.e. number of + amino acids) represented by this Translation object. + Returntype : int + Exceptions : none + Caller : webcode (protview etc.) + Status : Stable + +=cut + +sub length { + my $self = shift; + my $seq = $self->seq(); + + return ($seq) ? CORE::length($seq) : 0; +} + + +=head2 seq + + Example : print $translation->seq(); + Description: Retrieves a string representation of the peptide sequence + of this Translation. This retrieves the transcript from the + database and gets its sequence, or retrieves the sequence which + was set via the constructor. + Returntype : string + Exceptions : warning if the sequence is not set and cannot be retrieved from + the database. + Caller : webcode (protview etc.) + Status : Stable + +=cut + +sub seq { + my ( $self, $sequence ) = @_; + + if ( defined($sequence) ) { + + $self->{'seq'} = $sequence; + + } elsif ( !defined( $self->{'seq'} ) ) { + + my $transcript = $self->transcript(); + + my $canonical_translation = $transcript->translation(); + my $is_alternative; + if(!$canonical_translation) { + throw "Transcript does not have a canonical translation"; + } + if ( defined( $canonical_translation->stable_id() ) + && defined( $self->stable_id() ) ) + { + # Try stable ID. + $is_alternative = + ( $canonical_translation->stable_id() ne $self->stable_id() ); + } elsif ( defined( $canonical_translation->dbID() ) + && defined( $self->dbID() ) ) + { + # Try dbID. + $is_alternative = + ( $canonical_translation->dbID() != $self->dbID() ); + } else { + # Resort to using geomic start/end coordinates. + $is_alternative = ( ($canonical_translation->genomic_start() != + $self->genomic_start() ) + || ( $canonical_translation->genomic_end() != + $self->genomic_end() ) ); + } + + if ($is_alternative) { + # To deal with non-canonical (alternative) translations, subsitute + # the canonical translation in the transcript with $self for a + # while. + + $transcript->translation($self); + } + + my $seq = $transcript->translate(); + if ( defined($seq) ) { + $self->{'seq'} = $seq->seq(); + } + + if ($is_alternative) { + # Reinstate the real canonical translation. + + $transcript->translation($canonical_translation); + } + + } ## end elsif ( !defined( $self->...)) + + if ( !defined( $self->{'seq'} ) ) { + return ''; # Empty string + } + + return $self->{'seq'}; + +} ## end sub seq + + +=head2 get_all_Attributes + + Arg [1] : optional string $attrib_code + The code of the attribute type to retrieve values for. + Example : ($sc_attr) = @{$tl->get_all_Attributes('_selenocysteine')}; + @tl_attributes = @{$translation->get_all_Attributes()}; + Description: Gets a list of Attributes of this translation. + Optionally just get Attrubutes for given code. + Recognized attribute "_selenocysteine" + Returntype : listref Bio::EnsEMBL::Attribute + Exceptions : warning if translation does not have attached adaptor and + attempts lazy load. + Caller : general, modify_translation + Status : Stable + +=cut + +sub get_all_Attributes { + my $self = shift; + my $attrib_code = shift; + + if( ! exists $self->{'attributes' } ) { + if(!$self->adaptor() ) { +# warning('Cannot get attributes without an adaptor.'); + return []; + } + + my $aa = $self->adaptor->db->get_AttributeAdaptor(); + $self->{'attributes'} = $aa->fetch_all_by_Translation( $self ); + } + + if( defined $attrib_code ) { + my @results = grep { uc($_->code()) eq uc($attrib_code) } + @{$self->{'attributes'}}; + return \@results; + } else { + return $self->{'attributes'}; + } +} + + +=head2 add_Attributes + + Arg [1..N] : Bio::EnsEMBL::Attribute $attribute + Attributes to add. + Example : $translation->add_Attributes($selenocysteine_attribute); + Description: Adds an Attribute to the Translation. Usefull to + do _selenocysteine. + If you add an attribute before you retrieve any from database, + lazy load will be disabled. + Returntype : none + Exceptions : throw on incorrect arguments + Caller : general + Status : Stable + +=cut + +sub add_Attributes { + my $self = shift; + my @attribs = @_; + + if( ! exists $self->{'attributes'} ) { + $self->{'attributes'} = []; + } + + for my $attrib ( @attribs ) { + if( ! $attrib->isa( "Bio::EnsEMBL::Attribute" )) { + throw( "Argument to add_Attribute must be a Bio::EnsEMBL::Attribute" ); + } + push( @{$self->{'attributes'}}, $attrib ); + $self->{seq}=undef; + } +} + + +=head2 get_all_SeqEdits + + Example : my @seqeds = @{$transcript->get_all_SeqEdits()}; + Description: Retrieves all post transcriptional sequence modifications for + this transcript. + Returntype : Bio::EnsEMBL::SeqEdit + Exceptions : none + Caller : spliced_seq() + Status : Stable + +=cut + +sub get_all_SeqEdits { + my $self = shift; + + my @seqeds; + + my $attribs; + + my @edits = ('initial_met', '_selenocysteine', 'amino_acid_sub'); + + + foreach my $edit(@edits){ + $attribs = $self->get_all_Attributes($edit); + + # convert attributes to SeqEdit objects + foreach my $a (@$attribs) { + push @seqeds, Bio::EnsEMBL::SeqEdit->new(-ATTRIB => $a); + } + } + return \@seqeds; +} + + +=head2 modify_translation + + Arg [1] : Bio::Seq $peptide + Example : my $seq = Bio::Seq->new(-SEQ => $dna)->translate(); + $translation->modify_translation($seq); + Description: Applies sequence edits such as selenocysteines to the Bio::Seq + peptide thats passed in + Returntype : Bio::Seq + Exceptions : none + Caller : Bio::EnsEMBL::Transcript->translate + Status : Stable + +=cut + +sub modify_translation { + my ( $self, $seq ) = @_; + + my @seqeds = @{ $self->get_all_SeqEdits() }; + + # Sort in reverse order to avoid complication of adjusting + # downstream edits. + # HACK: The translation ENSP00000420939 somehow makes the next line + # bomb out ($a or $b becomes undef) if the start() method + # is used. I haven't been able to find out why. It has 10 + # Selenocysteine seqedits that looks correct. + # /Andreas (release 59) + @seqeds = sort { $b->{'start'} <=> $a->{'start'} } @seqeds; + + # Apply all edits. + my $peptide = $seq->seq(); + foreach my $se (@seqeds) { + $se->apply_edit( \$peptide ); + } + + $seq->seq($peptide); + + return $seq; +} + +=head2 load + + Arg [1] : Boolean $load_xrefs + Load (or don't load) xrefs. Default is to load xrefs. + Example : $translation->load(); + Description : The Ensembl API makes extensive use of + lazy-loading. Under some circumstances (e.g., + when copying genes between databases), all data of + an object needs to be fully loaded. This method + loads the parts of the object that are usually + lazy-loaded. + Returns : none + +=cut + +sub load { + my ( $self, $load_xrefs ) = @_; + + if ( !defined($load_xrefs) ) { $load_xrefs = 1 } + + $self->seq(); + + $self->stable_id(); + $self->get_all_Attributes(); + $self->get_all_ProteinFeatures(); + + if ($load_xrefs) { + $self->get_all_DBEntries(); + } +} + +=head2 temporary_id + + Description: DEPRECATED This method should not be needed. Use dbID, + stable_id or something else. + +=cut + +sub temporary_id { + my $self = shift; + deprecate( "I cant see what a temporary_id is good for, please use " . + "dbID or stableID or\n try without an id." ); + $self->{'temporary_id'} = shift if( @_ ); + return $self->{'temporary_id'}; +} + + +=head2 get_all_DASFactories + + Function : Retrieves a listref of registered DAS objects + Returntype: Listref of DAS Objects + Exceptions: none + Caller : webcode + Example : $dasref = $prot->get_all_DASFactories; + Status : Stable + +=cut + +sub get_all_DASFactories { + my $self = shift; + return [ $self->adaptor()->db()->_each_DASFeatureFactory ]; +} + + +=head2 get_all_DAS_Features + + Example : $features = $prot->get_all_DAS_Features; + Description: Retreives a hash reference to a hash of DAS feature + sets, keyed by the DNS, NOTE the values of this hash + are an anonymous array containing: + (1) a pointer to an array of features; + (2) a pointer to the DAS stylesheet + Returntype : hashref of Bio::SeqFeatures + Exceptions : none + Caller : webcode + Status : Stable + +=cut + +sub get_all_DAS_Features{ + my $self = shift; + + my $db = $self->adaptor->db; + my $GeneAdaptor = $db->get_GeneAdaptor; + my $Gene = $GeneAdaptor->fetch_by_translation_stable_id($self->stable_id) || return; + my $slice = $Gene->feature_Slice; + + return $self->SUPER::get_all_DAS_Features($slice); +} + +=head2 summary_as_hash + + Example : $translation_summary = $translation->summary_as_hash(); + Description : Retrieves a textual summary of this Translation. + Not inherited from Feature. + Returns : hashref of arrays of descriptive strings + Status : Intended for internal use +=cut + +sub summary_as_hash { + my $self = shift; + my %summary; + $summary{'ID'} = $self->display_id; + $summary{'genomic_start'} = $self->genomic_start; + $summary{'genomic_end'} = $self->genomic_end; + my $transcript = $self->transcript; + $summary{'Parent'} = $transcript->display_id; + return \%summary; +} + +1;