Archive Ensembl HomeArchive Ensembl Home
TranslationAdaptor.pm
Go to the documentation of this file.
00001 =head1 LICENSE
00002 
00003   Copyright (c) 1999-2012 The European Bioinformatics Institute and
00004   Genome Research Limited.  All rights reserved.
00005 
00006   This software is distributed under a modified Apache license.
00007   For license details, please see
00008 
00009     http://www.ensembl.org/info/about/code_licence.html
00010 
00011 =head1 CONTACT
00012 
00013   Please email comments or questions to the public Ensembl
00014   developers list at <dev@ensembl.org>.
00015 
00016   Questions may also be sent to the Ensembl help desk at
00017   <helpdesk@ensembl.org>.
00018 
00019 =cut
00020 
00021 =head1 NAME
00022 
00023 Bio::EnsEMBL::DBSQL::TranslationAdaptor - Provides a means to fetch and store
00024 Translation objects from a database.
00025 
00026 =head1 DESCRIPTION
00027 
00028 This adaptor provides a means to retrieve and store
00029 Bio::EnsEMBL::Translation objects from/in a database.
00030 
00031 Translation objects only truly make sense in the context of their
00032 transcripts so the recommended means to retrieve Translations is
00033 by retrieving the Transcript object first, and then fetching the
00034 Translation.
00035 
00036 =head1 SYNOPSIS
00037 
00038   use Bio::EnsEMBL::Registry;
00039 
00040   Bio::EnsEMBL::Registry->load_registry_from_db(
00041     -host => 'ensembldb.ensembl.org',
00042     -user => 'anonymous'
00043   );
00044 
00045   $transcript_adaptor =
00046     Bio::EnsEMBL::Registry->get_adaptor( "human", "core",
00047     "transcript" );
00048 
00049   $translation_adaptor =
00050     Bio::EnsEMBL::Registry->get_adaptor( "human", "core",
00051     "translation" );
00052 
00053   my $transcript = $transcript_adaptor->fetch_by_dbID(131243);
00054   my $translation =
00055     $translation_adaptor->fetch_by_Transcript($transcript);
00056 
00057   print("Translation Start Site: "
00058       . $translation->start_Exon()->stable_id() . " "
00059       . $translation->start()
00060       . "\n" );
00061   print("Translation Stop: "
00062       . $translation->end_Exon()->stable_id() . " "
00063       . $translation->end() );
00064 
00065 =head1 METHODS
00066 
00067 =cut
00068 
00069 package Bio::EnsEMBL::DBSQL::TranslationAdaptor;
00070 
00071 use vars qw(@ISA);
00072 use strict;
00073 
00074 use Bio::EnsEMBL::DBSQL::BaseAdaptor;
00075 use Bio::EnsEMBL::Translation;
00076 use Bio::EnsEMBL::Utils::Exception qw( throw warning deprecate );
00077 use Bio::EnsEMBL::Utils::Scalar qw( assert_ref );
00078 
00079 
00080 @ISA = qw( Bio::EnsEMBL::DBSQL::BaseAdaptor );
00081 
00082 =head2 fetch_all_alternative_by_Transcript
00083 
00084   Arg [1]    : Bio::EnsEMBL::Transcript $transcript
00085   Example    :
00086 
00087     @tl = @{
00088       $translation_adaptor->fetch_all_alternative_by_Transcript(
00089                                                             $transcript)
00090       };
00091 
00092   Description: Retrieves all alternative translations associated with a
00093                particular transcript.  If no alternative translation is
00094                found, a reference to an empty list is returned.
00095 
00096   Returntype : listref of Bio::EnsEMBL::Translation
00097   Exceptions : throw on incorrect argument
00098   Caller     : Transcript
00099   Status     : Stable
00100 
00101 =cut
00102 
00103 sub fetch_all_alternative_by_Transcript {
00104   my ( $self, $transcript ) = @_;
00105 
00106   assert_ref($transcript, 'Bio::EnsEMBL::Transcript');
00107 
00108   my $tl_created_date =
00109     $self->db()->dbc()->from_date_to_seconds('tl.created_date');
00110   my $tl_modified_date =
00111     $self->db()->dbc()->from_date_to_seconds('tl.modified_date');
00112 
00113   my $sql =
00114     sprintf( "SELECT tl.translation_id, tl.start_exon_id, "
00115       . "tl.end_exon_id, tl.seq_start, tl.seq_end, "
00116       . "tl.stable_id, tl.version, %s, %s "
00117       . "FROM translation tl "
00118       . "JOIN transcript t "
00119       . "ON (t.transcript_id = tl.transcript_id) "
00120       . "WHERE tl.transcript_id = ? "
00121       . "AND tl.translation_id != t.canonical_translation_id",
00122     $tl_created_date, $tl_modified_date );
00123 
00124   my $transcript_id = $transcript->dbID();
00125   my $sth           = $self->prepare($sql);
00126   $sth->bind_param( 1, $transcript_id, SQL_INTEGER );
00127 
00128   $sth->execute();
00129 
00130   my (
00131     $translation_id, $start_exon_id, $end_exon_id,
00132     $seq_start,      $seq_end,       $stable_id,
00133     $version,        $created_date,  $modified_date
00134   );
00135 
00136   $sth->bind_columns(
00137     \(
00138       $translation_id, $start_exon_id, $end_exon_id,
00139       $seq_start,      $seq_end,       $stable_id,
00140       $version,        $created_date,  $modified_date
00141     ) );
00142 
00143   # Get all alternative translations.
00144   my $translations = [];
00145   while ( $sth->fetch() ) {
00146     if ( !defined($translation_id) ) { next }
00147 
00148     my ( $start_exon, $end_exon );
00149 
00150     # this will load all the exons whenever we load the translation
00151     # but I guess thats ok ....
00152 
00153     foreach my $exon ( @{ $transcript->get_all_Exons() } ) {
00154       if ( $exon->dbID() == $start_exon_id ) { $start_exon = $exon }
00155       if ( $exon->dbID() == $end_exon_id )   { $end_exon   = $exon }
00156     }
00157 
00158     if ( !( defined($start_exon) && defined($end_exon) ) ) {
00159       throw(
00160         sprintf(
00161           "Could not find start or end exon in transcript_id=%d\n",
00162           $transcript->dbID() ) );
00163     }
00164 
00165     my $translation =
00166       Bio::EnsEMBL::Translation->new_fast( {
00167                              'dbID'          => $translation_id,
00168                              'adaptor'       => $self,
00169                              'start'         => $seq_start,
00170                              'end'           => $seq_end,
00171                              'start_exon'    => $start_exon,
00172                              'end_exon'      => $end_exon,
00173                              'stable_id'     => $stable_id,
00174                              'version'       => $version,
00175                              'created_date'  => $created_date || undef,
00176                              'modified_date' => $modified_date || undef,
00177                            } );
00178 
00179     $translation->transcript($transcript);
00180 
00181     push( @{$translations}, $translation );
00182 
00183   } ## end while ( $sth->fetch() )
00184 
00185   return $translations;
00186 } ## end sub fetch_all_by_Transcript
00187 
00188 =head2 fetch_by_Transcript
00189 
00190   Arg [1]    : Bio::EnsEMBL::Transcript $transcript
00191   Example    : $tl = $translation_adaptor->fetch_by_Transcript($transcript);
00192   Description: Retrieves a Translation via its associated transcript.
00193                If the Translation is not found, undef is returned.
00194   Returntype : Bio::EnsEMBL::Translation
00195   Exceptions : throw on incorrect argument
00196   Caller     : Transcript
00197   Status     : Stable
00198 
00199 =cut
00200 
00201 sub fetch_by_Transcript {
00202   my ( $self, $transcript ) = @_;
00203 
00204   assert_ref( $transcript, 'Bio::EnsEMBL::Transcript' );
00205 
00206   my $tl_created_date =
00207     $self->db()->dbc()->from_date_to_seconds('tl.created_date');
00208   my $tl_modified_date =
00209     $self->db()->dbc()->from_date_to_seconds('tl.modified_date');
00210 
00211   my $sql =
00212     sprintf( "SELECT tl.translation_id, tl.start_exon_id, "
00213       . "tl.end_exon_id, tl.seq_start, tl.seq_end, "
00214       . "tl.stable_id, tl.version, %s, %s "
00215       . "FROM translation tl "
00216       . "JOIN transcript tr "
00217       . "ON (tl.translation_id = tr.canonical_translation_id) "
00218       . "WHERE tr.transcript_id = ?",
00219     $tl_created_date, $tl_modified_date );
00220 
00221   my $transcript_id = $transcript->dbID();
00222   my $sth           = $self->prepare($sql);
00223   $sth->bind_param( 1, $transcript_id, SQL_INTEGER );
00224 
00225   $sth->execute();
00226 
00227   my (
00228     $translation_id, $start_exon_id, $end_exon_id,
00229     $seq_start,      $seq_end,       $stable_id,
00230     $version,        $created_date,  $modified_date
00231   ) = $sth->fetchrow_array();
00232   $sth->finish();
00233 
00234   if ( !defined($translation_id) ) { return undef }
00235 
00236   my ( $start_exon, $end_exon );
00237 
00238   # this will load all the exons whenever we load the translation
00239   # but I guess thats ok ....
00240 
00241   foreach my $exon ( @{ $transcript->get_all_Exons() } ) {
00242     if ( $exon->dbID() == $start_exon_id ) { $start_exon = $exon }
00243     if ( $exon->dbID() == $end_exon_id )   { $end_exon   = $exon }
00244   }
00245 
00246   if ( !( defined($start_exon) && defined($end_exon) ) ) {
00247     throw(
00248       sprintf( "Could not find start or end exon in transcript_id=%d\n",
00249         $transcript->dbID() ) );
00250   }
00251 
00252   my $translation =
00253     Bio::EnsEMBL::Translation->new_fast( {
00254                              'dbID'          => $translation_id,
00255                              'adaptor'       => $self,
00256                              'start'         => $seq_start,
00257                              'end'           => $seq_end,
00258                              'start_exon'    => $start_exon,
00259                              'end_exon'      => $end_exon,
00260                              'stable_id'     => $stable_id,
00261                              'version'       => $version,
00262                              'created_date'  => $created_date || undef,
00263                              'modified_date' => $modified_date || undef,
00264                            } );
00265 
00266   $translation->transcript($transcript);
00267 
00268   return $translation;
00269 } ## end sub fetch_by_Transcript
00270 
00271 
00272 
00273 =head2 fetch_all_by_external_name
00274 
00275   Arg [1]    : string $external_name
00276                The external identifier for the translation(s) to be
00277                obtained.
00278   Arg [2]    : (optional) string $external_db_name
00279                The name of the external database from which the
00280                identifier originates.
00281   Example    : my @translations =
00282                   @{ $trl_adaptor->fetch_all_by_external_name('BRCA2') };
00283                my @many_translations = 
00284                   @{ $trl_adaptor->fetch_all_by_external_name('BRCA%') };
00285   Description: Retrieves a list of translations fetched via an
00286                external identifier.  Note that this may not be a
00287                particularly useful method, because translations
00288                do not make much sense out of the context of
00289                their transcript.  It may be better to use the
00290                TranscriptAdaptor::fetch_all_by_external_name instead.
00291                SQL wildcards % and _ are supported in the $external_name
00292   Returntype : reference to a list of Translations
00293   Exceptions : none
00294   Caller     : general
00295   Status     : Medium Risk
00296              :   At some time may be deprecated to instead use 
00297              :   TranscriptAdaptor::fetch_all_by_external_name 
00298 
00299 =cut
00300 
00301 sub fetch_all_by_external_name {
00302   my ( $self, $external_name, $external_db_name ) = @_;
00303 
00304   my $entry_adaptor = $self->db->get_DBEntryAdaptor();
00305 
00306   my @ids =
00307     $entry_adaptor->list_translation_ids_by_extids( $external_name,
00308                                                     $external_db_name );
00309 
00310   my $transcript_adaptor = $self->db()->get_TranscriptAdaptor();
00311 
00312   my @out;
00313   foreach my $id (@ids) {
00314     my $transcript = $transcript_adaptor->fetch_by_translation_id($id);
00315 
00316     if ( defined($transcript) ) {
00317       push @out, $self->fetch_by_Transcript($transcript);
00318     }
00319   }
00320 
00321   return \@out;
00322 }
00323 
00324 =head2 fetch_all_by_GOTerm
00325 
00326   Arg [1]   : Bio::EnsEMBL::OntologyTerm
00327               The GO term for which translations should be fetched.
00328 
00329   Example:  @translations = @{
00330               $translation_adaptor->fetch_all_by_GOTerm(
00331                 $go_adaptor->fetch_by_accession('GO:0030326') ) };
00332 
00333   Description   : Retrieves a list of translations that are
00334                   associated with the given GO term, or with any of
00335                   its descendent GO terms.
00336 
00337   Return type   : listref of Bio::EnsEMBL::Translation
00338   Exceptions    : Throws of argument is not a GO term
00339   Caller        : general
00340   Status        : Stable
00341 
00342 =cut
00343 
00344 sub fetch_all_by_GOTerm {
00345   my ( $self, $term ) = @_;
00346 
00347   assert_ref( $term, 'Bio::EnsEMBL::OntologyTerm' );
00348   if ( $term->ontology() ne 'GO' ) {
00349     throw('Argument is not a GO term');
00350   }
00351 
00352   my $entryAdaptor = $self->db->get_DBEntryAdaptor();
00353 
00354   my %unique_dbIDs;
00355   foreach my $accession ( map { $_->accession() }
00356                           ( $term, @{ $term->descendants() } ) )
00357   {
00358     my @ids =
00359       $entryAdaptor->list_translation_ids_by_extids( $accession, 'GO' );
00360     foreach my $dbID (@ids) { $unique_dbIDs{$dbID} = 1 }
00361   }
00362 
00363   my @result;
00364   if ( scalar( keys(%unique_dbIDs) ) > 0 ) {
00365     my $transcript_adaptor = $self->db()->get_TranscriptAdaptor();
00366 
00367     foreach my $dbID ( sort { $a <=> $b } keys(%unique_dbIDs) ) {
00368       my $transcript =
00369         $transcript_adaptor->fetch_by_translation_id($dbID);
00370       if ( defined($transcript) ) {
00371         push( @result, $self->fetch_by_Transcript($transcript) );
00372       }
00373     }
00374   }
00375 
00376   return \@result;
00377 } ## end sub fetch_all_by_GOTerm
00378 
00379 =head2 fetch_all_by_GOTerm_accession
00380 
00381   Arg [1]   : String
00382               The GO term accession for which genes should be
00383               fetched.
00384 
00385   Example   :
00386 
00387     @genes =
00388       @{ $gene_adaptor->fetch_all_by_GOTerm_accession('GO:0030326') };
00389 
00390   Description   : Retrieves a list of genes that are associated with
00391                   the given GO term, or with any of its descendent
00392                   GO terms.  The genes returned are in their native
00393                   coordinate system, i.e. in the coordinate system
00394                   in which they are stored in the database.  If
00395                   another coordinate system is required then the
00396                   Gene::transfer or Gene::transform method can be
00397                   used.
00398 
00399   Return type   : listref of Bio::EnsEMBL::Gene
00400   Exceptions    : Throws of argument is not a GO term accession
00401   Caller        : general
00402   Status        : Stable
00403 
00404 =cut
00405 
00406 sub fetch_all_by_GOTerm_accession {
00407   my ( $self, $accession ) = @_;
00408 
00409   if ( $accession !~ /^GO:/ ) {
00410     throw('Argument is not a GO term accession');
00411   }
00412 
00413   my $goAdaptor =
00414     Bio::EnsEMBL::Registry->get_adaptor( 'Multi', 'Ontology',
00415                                          'OntologyTerm' );
00416 
00417   my $term = $goAdaptor->fetch_by_accession($accession);
00418 
00419   return $self->fetch_all_by_GOTerm($term);
00420 }
00421 
00422 =head2 store
00423 
00424   Arg [1]    : Bio::EnsEMBL::Translation $translation
00425                The translation object to be stored in the database 
00426   Example    : $transl_id = $translation_adaptor->store($translation);
00427   Description: Stores a translation object in the database
00428   Returntype : int - the new dbID of the stored translation
00429   Exceptions : thrown if the dbID of the start_Exon or end_Exon is not 
00430                defined.
00431                thrown if only partial stable id information is present (e.g.
00432                identifier but not version number)
00433   Caller     : Transcript::store
00434   Status     : Stable
00435 
00436 =cut
00437 
00438 sub store {
00439   my ( $self, $translation, $transcript_id )  = @_;
00440   
00441   my $start_exon = $translation->start_Exon();
00442   my $end_exon   = $translation->end_Exon();
00443  
00444   if(!$start_exon) {
00445     throw("Translation must define a start_Exon to be stored.");
00446   }
00447  
00448   if(!$end_exon) {
00449     throw("Translation must define an end_Exon to be stored.");
00450   }
00451  
00452   if(!$start_exon->dbID) {
00453     throw("start_Exon must have a dbID for Translation to be stored.");
00454   }
00455 
00456   if(!$end_exon->dbID) {
00457     throw("end_Exon must have a dbID for Translation to be stored.");
00458   }
00459 
00460   my $store_translation_sql = qq(
00461          INSERT INTO translation 
00462              SET seq_start = ?, 
00463                  start_exon_id = ?,
00464                  seq_end = ?, 
00465                  end_exon_id = ?, 
00466                  transcript_id = ?
00467   );
00468 
00469   if (defined($translation->stable_id)) {
00470       my $created = $self->db->dbc->from_seconds_to_date($translation->created_date());
00471       my $modified = $self->db->dbc->from_seconds_to_date($translation->modified_date());
00472       $store_translation_sql .= ", stable_id = ?, version = ?, created_date = " . $created . " , modified_date = " . $modified;
00473 
00474   }
00475 
00476   my $sth = $self->prepare($store_translation_sql);
00477   $sth->bind_param(1,$translation->start,SQL_INTEGER);
00478   $sth->bind_param(2,$translation->start_Exon->dbID,SQL_INTEGER);
00479   $sth->bind_param(3,$translation->end,SQL_INTEGER);
00480   $sth->bind_param(4,$translation->end_Exon->dbID,SQL_INTEGER);
00481   $sth->bind_param(5,$transcript_id,SQL_INTEGER);
00482 
00483 
00484   if (defined($translation->stable_id)) {
00485  
00486     $sth->bind_param(6, $translation->stable_id,SQL_VARCHAR);
00487     my $version = ($translation->version()) ? $translation->version() : 1;
00488     $sth->bind_param(7, $version,SQL_VARCHAR);
00489   }
00490 
00491   $sth->execute();
00492  
00493   my $transl_dbID = $sth->{'mysql_insertid'};
00494 
00495   #
00496   # store object xref mappings to translations
00497   #
00498  
00499   my $dbEntryAdaptor = $self->db()->get_DBEntryAdaptor();
00500   # store each of the xrefs for this translation
00501   foreach my $dbl ( @{$translation->get_all_DBEntries} ) {
00502      $dbEntryAdaptor->store( $dbl, $transl_dbID, "Translation", 1 );
00503   }
00504 
00505   #storing the protein features associated with the translation
00506   my $pfadaptor = $self->db->get_ProteinFeatureAdaptor();
00507   foreach my $pf(@{$translation->get_all_ProteinFeatures}){
00508     $pfadaptor->store($pf, $transl_dbID);
00509   }
00510 
00511   $translation->get_all_Attributes();
00512 
00513   # store any translation attributes that are defined
00514   my $attr_adaptor = $self->db->get_AttributeAdaptor();
00515   $attr_adaptor->store_on_Translation($transl_dbID,
00516                                       $translation->get_all_Attributes());
00517 
00518   $translation->dbID($transl_dbID);
00519   $translation->adaptor($self);
00520 
00521   return $transl_dbID;
00522 }
00523 
00524 
00525 
00526 =head2 remove
00527 
00528   Arg [1]    : Bio::EnsEMBL::Translation $translation
00529   Example    : $translation_adaptor->remove($translation);
00530   Description: Removes a translation completely from the database, and all
00531                associated information including protein features etc.
00532   Returntype : none
00533   Exceptions : throw on incorrect arguments
00534                warning if translation is not in this database
00535   Caller     : TranscriptAdaptor::remove
00536   Status     : Stable
00537 
00538 =cut
00539 
00540 sub remove {
00541   my $self = shift;
00542   my $translation = shift;
00543 
00544   if(!ref($translation) || !$translation->isa('Bio::EnsEMBL::Translation')) {
00545     throw("Bio::EnsEMBL::Translation argument expected.");
00546   }
00547 
00548   if( !$translation->is_stored($self->db()) ) {
00549     warning("Cannot remove translation " . $translation->dbID() . 
00550             ". Is not stored in this database.");
00551     return;
00552   }
00553 
00554   # remove athe attributes associated with this translation
00555   my $attrib_adp = $self->db->get_AttributeAdaptor;
00556   $attrib_adp->remove_from_Translation($translation);
00557 
00558   # remove all xref associations to this translation
00559   my $dbe_adaptor = $self->db()->get_DBEntryAdaptor();
00560   foreach my $dbe (@{$translation->get_all_DBEntries()}) {
00561     $dbe_adaptor->remove_from_object($dbe, $translation, 'Translation');
00562   }
00563 
00564   # remove all protein_features on this translation
00565   my $sth = $self->prepare
00566     ("DELETE FROM protein_feature WHERE translation_id = ?");
00567   $sth->bind_param(1,$translation->dbID,SQL_INTEGER);
00568   $sth->execute();
00569   $sth->finish();
00570 
00571   # remove the translation itself
00572 
00573   $sth = $self->prepare("DELETE FROM translation WHERE translation_id = ?" );
00574   $sth->bind_param(1,$translation->dbID,SQL_INTEGER);
00575   $sth->execute();
00576   $sth->finish();
00577 
00578   $translation->dbID( undef );
00579   $translation->adaptor(undef);
00580 
00581   return
00582 }
00583 
00584 
00585 =head2 list_dbIDs
00586 
00587   Arg [1]    : none
00588   Example    : @translation_ids = @{$translation_adaptor->list_dbIDs()};
00589   Description: Gets an array of internal ids for all translations in the current db
00590   Returntype : list of ints
00591   Exceptions : none
00592   Caller     : ?
00593   Status     : Stable
00594 
00595 =cut
00596 
00597 sub list_dbIDs {
00598    my ($self) = @_;
00599 
00600    return $self->_list_dbIDs("translation");
00601 }
00602 
00603 
00604 =head2 list_stable_ids
00605 
00606   Arg [1]    : none
00607   Example    : @transl_stable_ids = @{$transl_adaptor->list_stable_dbIDs()};
00608   Description: Gets an array of stable ids for all translations in the current 
00609                db
00610   Returntype : reference to a list of strings
00611   Exceptions : none
00612   Caller     : general
00613   Status     : Stable
00614 
00615 =cut
00616 
00617 sub list_stable_ids {
00618    my ($self) = @_;
00619 
00620    return $self->_list_dbIDs("translation", "stable_id");
00621 }
00622 
00623 
00624 
00625 =head2 fetch_by_dbID
00626 
00627   Arg [1]    : int $dbID
00628                The internal identifier of the Translation to obtain
00629   Example    : $translation = $translation_adaptor->fetch_by_dbID(1234);
00630   Description: This fetches a Translation object via its internal id.
00631                This is only debatably useful since translations do
00632                not make much sense outside of the context of their
00633                Transcript.  Consider using fetch_by_Transcript instead.
00634   Returntype : Bio::EnsEMBL::Translation, or undef if the translation is not
00635                found.
00636   Exceptions : warning if an additional (old style) Transcript argument is
00637                provided
00638   Caller     : ?
00639   Status     : Stable
00640 
00641 =cut
00642 
00643 sub fetch_by_dbID {
00644   my ( $self, $dbID, $transcript ) = @_;
00645 
00646   if ($transcript) {
00647     deprecate(   "Use of fetch_by_dbID "
00648                . "with a Transcript argument is deprecated."
00649                . "Use fetch_by_Transcript instead." );
00650   }
00651 
00652   if ( !defined($dbID) ) {
00653     throw("dbID argument is required");
00654   }
00655 
00656   my $transcript_adaptor = $self->db()->get_TranscriptAdaptor();
00657   $transcript = $transcript_adaptor->fetch_by_translation_id($dbID);
00658 
00659   if ( defined($transcript) ) {
00660     my $translation = $self->fetch_by_Transcript($transcript);
00661 
00662     if ( defined($translation) ) {
00663       return $translation;
00664     }
00665 
00666     my @alt_translations =
00667       @{ $self->fetch_all_by_Transcript($transcript) };
00668 
00669     foreach my $alt_translation (@alt_translations) {
00670       if ( $alt_translation->dbID() == $dbID ) {
00671         return $alt_translation;
00672       }
00673     }
00674   }
00675 
00676   return undef;
00677 } ## end sub fetch_by_dbID
00678 
00679 
00680 =head2 fetch_by_stable_id
00681 
00682   Arg [1]    : string $stable_id
00683                The stable identifier of the Translation to obtain
00684   Example    : $translation = $translation_adaptor->fetch_by_stable_id("ENSP00001");
00685   Description: This fetches a Translation object via its stable id.
00686                This is only debatably useful since translations do
00687                not make much sense outside of the context of their
00688                Transcript.  Consider using fetch_by_Transcript instead.
00689   Returntype : Bio::EnsEMBL::Translation or undef if the translation is not
00690                found.
00691   Exceptions : warning if an additional (old style) Transcript argument is
00692                provided
00693   Caller     : ?
00694   Status     : Stable
00695 
00696 =cut
00697 
00698 sub fetch_by_stable_id {
00699    my ($self,$stable_id) = @_;
00700 
00701    if(!$stable_id) {
00702      throw("stable id argument is required");
00703    }
00704 
00705    my $transcript_adaptor = $self->db()->get_TranscriptAdaptor();
00706    my $transcript = 
00707      $transcript_adaptor->fetch_by_translation_stable_id($stable_id);
00708 
00709    return undef if(!$transcript);
00710 
00711    return $self->fetch_by_Transcript($transcript);
00712 }
00713 
00714 
00715 =head2 fetch_all_by_Transcript_list
00716 
00717   Arg [1]    : reference to list of Bio::EnsEMBL::Transcripts $transcripts
00718                The list of $transcripts to obtain Translation object for.
00719   Example    : @translations = @{$tla->fetch_all_by_Transcript_list([$t1,$t2]);
00720   Description: Fetches all translations associated with the list of transcripts
00721                passed to this method.  The passed transcripts will also have
00722                their translation set by this method.
00723   Returntype : Reference to list of Bio::EnsEMBL::Translations
00724   Exceptions : None
00725   Caller     : general
00726   Status     : Stable
00727 
00728 =cut
00729 
00730 sub fetch_all_by_Transcript_list {
00731   my ($self,$transcripts) = @_;
00732 
00733   if(!defined($transcripts) || ref($transcripts) ne 'ARRAY') {
00734     throw("reference to list of Transcripts argument is required");
00735   }
00736 
00737   return [] if(!@$transcripts);
00738 
00739   my %trans_hash = map {$_->dbID() => $_} @$transcripts;
00740   my @id_list = keys %trans_hash;
00741 
00742   my @out;
00743 
00744   # mysql is faster and we ensure that we do not exceed the max query size by
00745   # splitting large queries into smaller queries of 200 ids
00746   my $max_size = 200;
00747 
00748   my ( $transcript_id, $translation_id, $start_exon_id, $end_exon_id,
00749        $seq_start, $seq_end, $stable_id, $version, 
00750        $created_date, $modified_date );
00751 
00752   my %ex_hash;
00753 
00754   while(@id_list) {
00755     my @ids;
00756     if(@id_list > $max_size) {
00757       @ids = splice(@id_list, 0, $max_size);
00758     } else {
00759       @ids = splice(@id_list, 0);
00760     }
00761 
00762     my $id_str;
00763     if(@ids > 1)  {
00764       $id_str = " IN (" . join(',', @ids). ")";
00765     } else {
00766       $id_str = " = " . $ids[0];
00767     }
00768     
00769     my $canonical_lookup = $self->dbc()->sql_helper()->execute_into_hash(
00770       -SQL => 'SELECT transcript_id, canonical_translation_id FROM transcript WHERE transcript_id '.$id_str
00771     );
00772 
00773     my $created_date = $self->db->dbc->from_date_to_seconds("tl.created_date");
00774     my $modified_date = $self->db->dbc->from_date_to_seconds("tl.modified_date");
00775 
00776     my $sth = $self->prepare
00777       ("SELECT tl.transcript_id, tl.translation_id, tl.start_exon_id,
00778            tl.end_exon_id, tl.seq_start, tl.seq_end,
00779            tl.stable_id, tl.version, " . $created_date . "," .
00780        $modified_date . 
00781        " FROM translation tl
00782          WHERE tl.transcript_id $id_str");
00783 
00784     $sth->execute();
00785 
00786     $sth->bind_columns( \$transcript_id, \$translation_id, \$start_exon_id, \$end_exon_id,
00787                         \$seq_start, \$seq_end, \$stable_id, \$version,
00788             \$created_date, \$modified_date );
00789 
00790     while($sth->fetch()) {
00791       my ($start_exon, $end_exon);
00792 
00793       # this will load all the exons whenever we load the translation
00794       # but I guess thats ok ....
00795 
00796       my $tr = $trans_hash{$transcript_id};
00797 
00798       foreach my $exon (@{$tr->get_all_Exons()}) {
00799         if(!$start_exon && $exon->dbID() == $start_exon_id ) {
00800           $start_exon = $exon;
00801           last if($end_exon);
00802         }
00803 
00804         if(!$end_exon && $exon->dbID() == $end_exon_id ) {
00805           $end_exon = $exon;
00806           last if($start_exon);
00807         }
00808       }
00809 
00810       unless($start_exon && $end_exon) {
00811         throw("Could not find start or end exon in transcript\n");
00812       }
00813 
00814       my $tl =  Bio::EnsEMBL::Translation->new
00815         (-dbID => $translation_id,
00816          -seq_start => $seq_start,
00817          -seq_end => $seq_end,
00818          -start_exon => $start_exon,
00819          -end_exon => $end_exon,
00820          -stable_id => $stable_id,
00821          -version => $version,
00822      -created_date => $created_date || undef,
00823      -modified_date => $modified_date || undef);
00824       
00825       $tl->adaptor($self);
00826       my $canonical_translation_id = $canonical_lookup->{$transcript_id};
00827       $tr->translation($tl) if $translation_id == $canonical_translation_id;
00828 
00829       push @out, $tl;
00830     }
00831   }
00832 
00833   return \@out;
00834 }
00835 
00836 
00837 
00838 =head2 fetch_all_by_DBEntry
00839 
00840   Description: DEPRECATED, this has been renames fetch_all_by_external_name
00841 
00842 =cut
00843 
00844 sub fetch_all_by_DBEntry {
00845   my $self = shift;
00846   deprecate("Use fetch_all_by_external_name instead.");
00847   return $self->fetch_all_by_external_name(@_);
00848 }
00849 
00850 =head2 get_stable_entry_info
00851 
00852  Description: DEPRECATED - This method should no longer be needed. Stable
00853               id info is fetched when the transcript is.
00854 
00855 =cut
00856 
00857 sub get_stable_entry_info {
00858   my ($self,$translation) = @_;
00859 
00860   deprecate( "This method shouldnt be necessary any more" );
00861 
00862   unless(defined $translation && ref $translation && 
00863      $translation->isa('Bio::EnsEMBL::Translation') ) {
00864     throw("Needs a Translation object, not a [$translation]");
00865   }
00866 
00867   my $sth = $self->prepare("SELECT stable_id, version 
00868                             FROM   translation
00869                             WHERE  translation_id = ?");
00870   $sth->bind_param(1,$translation->dbID,SQL_INTEGER);
00871   $sth->execute();
00872 
00873   my @array = $sth->fetchrow_array();
00874   $translation->{'_stable_id'} = $array[0];
00875   $translation->{'_version'}   = $array[1];
00876 
00877   return 1;
00878 }
00879 
00880 =head2 fetch_all
00881 
00882   Example     : $translations = $translation_adaptor->fetch_all();
00883   Description : Retrieves all canonical and alternative translations 
00884                 stored in the database.
00885   Returntype  : listref of Bio::EnsEMBL::Translation
00886   Caller      : general
00887   Status      : At Risk
00888 
00889 =cut
00890 
00891 sub fetch_all {
00892   my ($self) = @_;
00893   my $transcript_adaptor = $self->db()->get_TranscriptAdaptor();
00894 
00895   my @translations;
00896   foreach my $transcript (@{$transcript_adaptor->fetch_all}) {
00897      my $translation = $self->fetch_by_Transcript($transcript);
00898      if ($translation) {
00899      push @translations, $translation;
00900      }
00901      foreach my $alt_translation (@{$self->fetch_all_alternative_by_Transcript($transcript)}) {
00902      push @translations, $alt_translation;
00903      }
00904   }
00905   return \@translations;
00906 }
00907 
00908 1;