3 See the NOTICE file distributed with
this work
for additional information
4 regarding copyright ownership.
6 Licensed under the Apache License, Version 2.0 (the
"License");
7 you may not use
this file except in compliance with the License.
8 You may obtain a copy of the License at
12 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an
"AS IS" BASIS,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 See the License
for the specific language governing permissions and
16 limitations under the License.
23 Please email comments or questions to the
public Ensembl
24 developers list at <http:
26 Questions may also be sent to the Ensembl help desk at
34 Translation objects from a database.
38 This adaptor provides a means to retrieve and store
41 Translation objects only truly make sense in the context of their
42 transcripts so the recommended means to retrieve Translations is
43 by retrieving the Transcript
object first, and then fetching the
51 -host =>
'ensembldb.ensembl.org',
59 $translation_adaptor =
63 my $transcript = $transcript_adaptor->fetch_by_dbID(131243);
65 $translation_adaptor->fetch_by_Transcript($transcript);
67 print(
"Translation Start Site: "
68 . $translation->start_Exon()->stable_id() .
" "
69 . $translation->start()
71 print(
"Translation Stop: "
72 . $translation->end_Exon()->stable_id() .
" "
73 . $translation->end() );
79 package Bio::EnsEMBL::DBSQL::TranslationAdaptor;
92 =head2 fetch_all_alternative_by_Transcript
98 $translation_adaptor->fetch_all_alternative_by_Transcript(
102 Description: Retrieves all alternative translations associated with a
103 particular
transcript. If no alternative translation is
104 found, a reference to an empty list is returned.
107 Exceptions :
throw on incorrect argument
113 sub fetch_all_alternative_by_Transcript {
114 my ( $self, $transcript ) = @_;
116 assert_ref($transcript,
'Bio::EnsEMBL::Transcript');
118 my $tl_created_date =
119 $self->db()->dbc()->from_date_to_seconds(
'tl.created_date');
120 my $tl_modified_date =
121 $self->db()->dbc()->from_date_to_seconds(
'tl.modified_date');
124 sprintf(
"SELECT tl.translation_id, tl.start_exon_id, "
125 .
"tl.end_exon_id, tl.seq_start, tl.seq_end, "
126 .
"tl.stable_id, tl.version, %s, %s "
127 .
"FROM translation tl "
128 .
"JOIN transcript t "
129 .
"ON (t.transcript_id = tl.transcript_id) "
130 .
"WHERE tl.transcript_id = ? "
131 .
"AND tl.translation_id != t.canonical_translation_id",
132 $tl_created_date, $tl_modified_date );
134 my $transcript_id = $transcript->dbID();
135 my $sth = $self->prepare($sql);
136 $sth->bind_param( 1, $transcript_id, SQL_INTEGER );
141 $translation_id, $start_exon_id, $end_exon_id,
142 $seq_start, $seq_end, $stable_id,
143 $version, $created_date, $modified_date
148 $translation_id, $start_exon_id, $end_exon_id,
149 $seq_start, $seq_end, $stable_id,
150 $version, $created_date, $modified_date
153 # Get all alternative translations.
154 my $translations = [];
155 while ( $sth->fetch() ) {
156 if ( !defined($translation_id) ) { next }
158 my ( $start_exon, $end_exon );
160 # this will load all the exons whenever we load the translation
161 # but I guess thats ok ....
163 foreach my $exon ( @{ $transcript->get_all_Exons() } ) {
164 if ( $exon->dbID() == $start_exon_id ) { $start_exon = $exon }
165 if ( $exon->dbID() == $end_exon_id ) { $end_exon = $exon }
168 if ( !( defined($start_exon) && defined($end_exon) ) ) {
171 "Could not find start or end exon in transcript_id=%d\n",
172 $transcript->dbID() ) );
177 'dbID' => $translation_id,
179 'start' => $seq_start,
181 'start_exon' => $start_exon,
182 'end_exon' => $end_exon,
183 'stable_id' => $stable_id,
184 'version' => $version,
185 'created_date' => $created_date || undef,
186 'modified_date' => $modified_date || undef,
189 $translation->transcript($transcript);
191 push( @{$translations}, $translation );
193 } ## end
while ( $sth->fetch() )
195 return $translations;
196 } ## end sub fetch_all_by_Transcript
198 =head2 fetch_by_Transcript
201 Example : $tl = $translation_adaptor->fetch_by_Transcript($transcript);
202 Description: Retrieves a Translation via its associated
transcript.
203 If the Translation is not found, undef is returned.
205 Exceptions :
throw on incorrect argument
211 sub fetch_by_Transcript {
212 my ( $self, $transcript ) = @_;
214 assert_ref( $transcript,
'Bio::EnsEMBL::Transcript' );
216 my $tl_created_date =
217 $self->db()->dbc()->from_date_to_seconds(
'tl.created_date');
218 my $tl_modified_date =
219 $self->db()->dbc()->from_date_to_seconds(
'tl.modified_date');
222 sprintf(
"SELECT tl.translation_id, tl.start_exon_id, "
223 .
"tl.end_exon_id, tl.seq_start, tl.seq_end, "
224 .
"tl.stable_id, tl.version, %s, %s "
225 .
"FROM translation tl "
226 .
"JOIN transcript tr "
227 .
"ON (tl.translation_id = tr.canonical_translation_id) "
228 .
"WHERE tr.transcript_id = ?",
229 $tl_created_date, $tl_modified_date );
231 my $transcript_id = $transcript->dbID();
232 my $sth = $self->prepare($sql);
233 $sth->bind_param( 1, $transcript_id, SQL_INTEGER );
238 $translation_id, $start_exon_id, $end_exon_id,
239 $seq_start, $seq_end, $stable_id,
240 $version, $created_date, $modified_date
241 ) = $sth->fetchrow_array();
244 if ( !defined($translation_id) ) {
return undef }
246 my ( $start_exon, $end_exon );
248 # this will load all the exons whenever we load the translation
249 # but I guess thats ok ....
251 foreach my $exon ( @{ $transcript->get_all_Exons() } ) {
252 if ( $exon->dbID() == $start_exon_id ) { $start_exon = $exon }
253 if ( $exon->dbID() == $end_exon_id ) { $end_exon = $exon }
256 if ( !( defined($start_exon) && defined($end_exon) ) ) {
258 sprintf(
"Could not find start or end exon in transcript_id=%d\n",
259 $transcript->dbID() ) );
264 'dbID' => $translation_id,
266 'start' => $seq_start,
268 'start_exon' => $start_exon,
269 'end_exon' => $end_exon,
270 'stable_id' => $stable_id,
271 'version' => $version,
272 'created_date' => $created_date || undef,
273 'modified_date' => $modified_date || undef,
276 $translation->transcript($transcript);
279 } ## end sub fetch_by_Transcript
283 =head2 fetch_all_by_external_name
285 Arg [1] :
string $external_name
286 The external identifier
for the translation(s) to be
288 Arg [2] : (optional)
string $external_db_name
289 The name of the external database from which the
290 identifier originates.
291 Arg [3] : Boolean
override. Force SQL regex matching
for users
292 who really
do want to find all
'NM%'
293 Example : my @translations =
294 @{ $trl_adaptor->fetch_all_by_external_name(
'BRCA2') };
295 my @many_translations =
296 @{ $trl_adaptor->fetch_all_by_external_name(
'BRCA%') };
297 Description: Retrieves a list of translations fetched via an
298 external identifier. Note that
this may not be a
299 particularly useful method, because translations
300 do not make much sense out of the context of
302 TranscriptAdaptor::fetch_all_by_external_name instead.
303 SQL wildcards % and _ are supported in the $external_name
304 but their use is somewhat restricted
for performance reasons.
305 Users that really
do want % and _ in the first three characters
306 should use argument 3 to prevent optimisations
307 Returntype : reference to a list of Translations
314 sub fetch_all_by_external_name {
315 my ( $self, $external_name, $external_db_name, $override ) = @_;
317 my $entry_adaptor = $self->db->get_DBEntryAdaptor();
319 my @ids = $entry_adaptor->list_translation_ids_by_extids(
320 $external_name, $external_db_name, $override );
322 my $transcript_adaptor = $self->db()->get_TranscriptAdaptor();
326 foreach my $id (@ids) {
327 my $transcript = $transcript_adaptor->fetch_by_translation_id($id);
329 if ( defined($transcript) ) {
330 my $translation = $self->fetch_by_Transcript($transcript);
331 if($transcript->slice()->is_reference()) {
332 push(@reference, $translation);
335 push(@non_reference, $translation);
340 return [@reference, @non_reference];
343 =head2 fetch_all_by_GOTerm
346 The GO term
for which translations should be fetched.
348 Example: @translations = @{
349 $translation_adaptor->fetch_all_by_GOTerm(
350 $go_adaptor->fetch_by_accession(
'GO:0030326') ) };
352 Description : Retrieves a list of translations that are
353 associated with the given GO term, or with any of
354 its descendent GO terms.
357 Exceptions : Throws of argument is not a GO term
363 sub fetch_all_by_GOTerm {
364 my ( $self, $term ) = @_;
366 assert_ref( $term,
'Bio::EnsEMBL::OntologyTerm' );
367 if ( $term->ontology() ne
'GO' ) {
368 throw(
'Argument is not a GO term');
371 my $entryAdaptor = $self->db->get_DBEntryAdaptor();
374 foreach my $accession (
map { $_->accession() }
375 ( $term, @{ $term->descendants() } ) )
378 $entryAdaptor->list_translation_ids_by_extids( $accession,
'GO' );
379 foreach my $dbID (@ids) { $unique_dbIDs{$dbID} = 1 }
383 if ( scalar( keys(%unique_dbIDs) ) > 0 ) {
384 my $transcript_adaptor = $self->db()->get_TranscriptAdaptor();
386 foreach my $dbID ( sort { $a <=> $b } keys(%unique_dbIDs) ) {
388 $transcript_adaptor->fetch_by_translation_id($dbID);
389 if ( defined($transcript) ) {
390 push( @result, $self->fetch_by_Transcript($transcript) );
396 } ## end sub fetch_all_by_GOTerm
398 =head2 fetch_all_by_GOTerm_accession
401 The GO term
accession for which genes should be
407 @{ $gene_adaptor->fetch_all_by_GOTerm_accession(
'GO:0030326') };
409 Description : Retrieves a list of genes that are associated with
410 the given GO term, or with any of its descendent
411 GO terms. The genes returned are in their native
412 coordinate system, i.e. in the coordinate system
413 in which they are stored in the database. If
414 another coordinate system is required then the
415 Gene::transfer or Gene::transform method can be
419 Exceptions : Throws of argument is not a GO term
accession
425 sub fetch_all_by_GOTerm_accession {
426 my ( $self, $accession ) = @_;
428 if ( $accession !~ /^GO:/ ) {
429 throw(
'Argument is not a GO term accession');
436 my $term = $goAdaptor->fetch_by_accession($accession);
438 return $self->fetch_all_by_GOTerm($term);
444 The translation
object to be stored in the database
445 Example : $transl_id = $translation_adaptor->store($translation);
446 Description: Stores a translation
object in the database
447 Returntype :
int - the
new dbID of the stored translation
448 Exceptions : thrown
if the dbID of the start_Exon or end_Exon is not
450 thrown
if only partial stable
id information is present (e.g.
451 identifier but not version number)
452 Caller : Transcript::store
458 my ( $self, $translation, $transcript_id ) = @_;
461 my $end_exon = $translation->end_Exon();
464 throw(
"Translation must define a start_Exon to be stored.");
468 throw(
"Translation must define an end_Exon to be stored.");
471 if(!$start_exon->dbID) {
472 throw(
"start_Exon must have a dbID for Translation to be stored.");
475 if(!$end_exon->dbID) {
476 throw(
"end_Exon must have a dbID for Translation to be stored.");
490 if (defined($translation->stable_id)) {
491 push @columns,
'stable_id',
'version';
493 my $created = $self->db->dbc->from_seconds_to_date($translation->created_date());
494 my $modified = $self->db->dbc->from_seconds_to_date($translation->modified_date());
497 push @canned_columns,
'created_date';
498 push @canned_values, $created;
501 push @canned_columns,
'modified_date';
502 push @canned_values, $modified;
506 my $columns = join(
', ', @columns, @canned_columns);
507 my $values = join(
', ', (
'?') x @columns, @canned_values);
508 my $store_translation_sql = qq(
509 INSERT INTO translation ( $columns ) VALUES ( $values )
512 my $sth = $self->prepare($store_translation_sql);
513 $sth->bind_param(1,$translation->start,SQL_INTEGER);
514 $sth->bind_param(2,$translation->start_Exon->dbID,SQL_INTEGER);
515 $sth->bind_param(3,$translation->end,SQL_INTEGER);
516 $sth->bind_param(4,$translation->end_Exon->dbID,SQL_INTEGER);
517 $sth->bind_param(5,$transcript_id,SQL_INTEGER);
520 if (defined($translation->stable_id)) {
522 $sth->bind_param(6, $translation->stable_id,SQL_VARCHAR);
523 $sth->bind_param(7, $translation->version,SQL_VARCHAR);
528 my $transl_dbID = $self->last_insert_id(
'translation_id', undef,
'translation');
531 # store object xref mappings to translations
534 my $dbEntryAdaptor = $self->db()->get_DBEntryAdaptor();
535 # store each of the xrefs for this translation
536 foreach my $dbl ( @{$translation->get_all_DBEntries} ) {
537 $dbEntryAdaptor->store( $dbl, $transl_dbID,
"Translation", 1 );
540 #storing the protein features associated with the translation
541 my $pfadaptor = $self->db->get_ProteinFeatureAdaptor();
542 foreach my $pf(@{$translation->get_all_ProteinFeatures}){
543 $pfadaptor->store($pf, $transl_dbID);
546 $translation->get_all_Attributes();
548 # store any translation attributes that are defined
549 my $attr_adaptor = $self->db->get_AttributeAdaptor();
550 $attr_adaptor->store_on_Translation($transl_dbID,
551 $translation->get_all_Attributes());
553 $translation->dbID($transl_dbID);
554 $translation->adaptor($self);
564 Example : $translation_adaptor->remove($translation);
565 Description: Removes a translation completely from the database, and all
566 associated information including protein features etc.
568 Exceptions :
throw on incorrect arguments
569 warning
if translation is not in
this database
570 Caller : TranscriptAdaptor::remove
577 my $translation = shift;
579 if(!ref($translation) || !$translation->isa(
'Bio::EnsEMBL::Translation')) {
580 throw(
"Bio::EnsEMBL::Translation argument expected.");
583 if( !$translation->is_stored($self->db()) ) {
584 warning(
"Cannot remove translation " . $translation->dbID() .
585 ". Is not stored in this database.");
589 # remove athe attributes associated with this translation
590 my $attrib_adp = $self->db->get_AttributeAdaptor;
591 $attrib_adp->remove_from_Translation($translation);
593 #remove all transcripts links to translation
594 my $sth = $self->prepare
595 (
"UPDATE transcript SET canonical_translation_id = NULL WHERE canonical_translation_id = ?");
596 $sth->bind_param(1,$translation->dbID,SQL_INTEGER);
600 # remove all xref associations to this translation
601 my $dbe_adaptor = $self->db()->get_DBEntryAdaptor();
602 foreach my $dbe (@{$translation->get_all_DBEntries()}) {
603 $dbe_adaptor->remove_from_object($dbe, $translation,
'Translation');
606 # remove all protein_features on this translation
607 $sth = $self->prepare
608 (
"DELETE FROM protein_feature WHERE translation_id = ?");
609 $sth->bind_param(1,$translation->dbID,SQL_INTEGER);
613 # remove the translation itself
615 $sth = $self->prepare(
"DELETE FROM translation WHERE translation_id = ?" );
616 $sth->bind_param(1,$translation->dbID,SQL_INTEGER);
620 $translation->dbID( undef );
621 $translation->adaptor(undef);
630 Example : @translation_ids = @{$translation_adaptor->list_dbIDs()};
631 Description: Gets an array of
internal ids
for all translations in the current db
632 Returntype : list of ints
642 return $self->_list_dbIDs(
"translation");
646 =head2 list_stable_ids
649 Example : @transl_stable_ids = @{$transl_adaptor->list_stable_dbIDs()};
650 Description: Gets an array of stable ids
for all translations in the current
652 Returntype : reference to a list of strings
659 sub list_stable_ids {
662 return $self->_list_dbIDs(
"translation",
"stable_id");
667 Arg[1] : String $table
668 Arg[2] : String $column
669 Example : $transl_adaptor->_list_dbIDs(
'translation',
'translation_id');
670 Description : Local reimplementation to ensure multi-species translations
671 are limited to their species alone
672 Returntype : ArrayRef of specified IDs
678 my ($self, $table, $column) = @_;
680 if($self->is_multispecies()) {
681 $column ||=
"${table}_id";
683 select `tr`.`${column}`
686 join seq_region sr
using (seq_region_id)
687 join coord_system cs
using (coord_system_id)
688 where cs.species_id =?
690 return $self->dbc()->sql_helper()->execute_simple(-SQL => $sql, -PARAMS => [$self->species_id()]);
693 $ids = $self->SUPER::_list_dbIDs($table, $column);
703 The
internal identifier of the Translation to obtain
704 Example : $translation = $translation_adaptor->fetch_by_dbID(1234);
705 Description: This fetches a Translation
object via its
internal id.
706 This is only debatably useful since translations
do
707 not make much sense outside of the context of their
708 Transcript. Consider
using fetch_by_Transcript instead.
711 Exceptions : warning
if an additional (old style) Transcript argument is
719 my ( $self, $dbID, $transcript ) = @_;
721 if ( !defined($dbID) ) {
722 throw(
"dbID argument is required");
725 my $transcript_adaptor = $self->db()->get_TranscriptAdaptor();
726 $transcript = $transcript_adaptor->fetch_by_translation_id($dbID);
728 if ( defined($transcript) ) {
729 my $translation = $self->fetch_by_Transcript($transcript);
731 if ( defined($translation) && $translation->dbID()==$dbID ) {
735 my @alt_translations =
736 @{ $self->fetch_all_alternative_by_Transcript($transcript) };
738 foreach my $alt_translation (@alt_translations) {
739 if ( $alt_translation->dbID() == $dbID ) {
740 return $alt_translation;
746 } ## end sub fetch_by_dbID
749 =head2 fetch_by_stable_id
751 Arg [1] :
string $stable_id
752 The stable identifier of the Translation to obtain
753 Example : $translation = $translation_adaptor->fetch_by_stable_id(
"ENSP00001");
754 Description: This fetches a Translation
object via its stable
id.
755 This is only debatably useful since translations
do
756 not make much sense outside of the context of their
757 Transcript. Consider
using fetch_by_Transcript instead.
760 Exceptions : warning
if an additional (old style) Transcript argument is
767 sub fetch_by_stable_id {
768 my ($self,$stable_id) = @_;
771 throw(
"stable id argument is required");
774 my $transcript_adaptor = $self->db()->get_TranscriptAdaptor();
776 $transcript_adaptor->fetch_by_translation_stable_id($stable_id);
778 return undef
if(!$transcript);
780 return $self->fetch_by_Transcript($transcript);
783 =head2 fetch_by_stable_id_version
786 The stable ID of the gene to retrieve
787 Arg [2] : Integer $version
788 The version of the stable_id to retrieve
789 Example : $gene = $gene_adaptor->fetch_by_stable_id(
'ENSG00000148944', 14);
790 Description: Retrieves a gene
object from the database via its stable
id and version.
791 The gene will be retrieved in its native coordinate system (i.e.
792 in the coordinate system it is stored in the database). It may
793 be converted to a different coordinate system through a call to
794 transform() or transfer(). If the gene or
exon is not found
795 undef is returned instead.
797 Exceptions : if we cant get the gene in given coord system
803 sub fetch_by_stable_id_version {
804 my ($self,$stable_id, $version) = @_;
807 throw(
"stable id argument is required");
810 # Enforce that version be numeric
811 return unless($version =~ /^\d+$/);
813 my $transcript_adaptor = $self->db()->get_TranscriptAdaptor();
815 $transcript_adaptor->fetch_by_translation_stable_id_version($stable_id, $version);
817 return if(!$transcript);
819 return $self->fetch_by_Transcript($transcript);
822 =head2 fetch_all_by_Transcript_list
824 Arg [1] : reference to list of Bio::EnsEMBL::Transcripts $transcripts
825 The list of $transcripts to obtain Translation
object for.
826 Example : @translations = @{$tla->fetch_all_by_Transcript_list([$t1,$t2]);
827 Description: Fetches all translations associated with the list of transcripts
828 passed to
this method. The passed transcripts will also have
829 their translation set by
this method.
830 Returntype : Reference to list of Bio::EnsEMBL::Translations
837 sub fetch_all_by_Transcript_list {
838 my ($self,$transcripts) = @_;
840 if(!defined($transcripts) || ref($transcripts) ne
'ARRAY') {
841 throw(
"reference to list of Transcripts argument is required");
844 return []
if(!@$transcripts);
846 my %trans_hash =
map {$_->dbID() => $_} @$transcripts;
847 my @id_list = keys %trans_hash;
851 # mysql is faster and we ensure that we do not exceed the max query size by
852 # splitting large queries into smaller queries of 200 ids
855 my ( $transcript_id, $translation_id, $start_exon_id, $end_exon_id,
856 $seq_start, $seq_end, $stable_id, $version,
857 $created_date, $modified_date );
863 if(@id_list > $max_size) {
864 @ids = splice(@id_list, 0, $max_size);
866 @ids = splice(@id_list, 0);
871 $id_str =
" IN (" . join(
',', @ids).
")";
873 $id_str =
" = " . $ids[0];
876 my $canonical_lookup = $self->dbc()->sql_helper()->execute_into_hash(
877 -SQL =>
'SELECT transcript_id, canonical_translation_id FROM transcript WHERE transcript_id '.$id_str
880 my $created_date = $self->db->dbc->from_date_to_seconds(
"tl.created_date");
881 my $modified_date = $self->db->dbc->from_date_to_seconds(
"tl.modified_date");
883 my $sth = $self->prepare
884 (
"SELECT tl.transcript_id, tl.translation_id, tl.start_exon_id,
885 tl.end_exon_id, tl.seq_start, tl.seq_end,
886 tl.stable_id, tl.version, " . $created_date .
"," .
888 " FROM translation tl
889 WHERE tl.transcript_id $id_str");
893 $sth->bind_columns( \$transcript_id, \$translation_id, \$start_exon_id, \$end_exon_id,
894 \$seq_start, \$seq_end, \$stable_id, \$version,
895 \$created_date, \$modified_date );
897 while($sth->fetch()) {
898 my ($start_exon, $end_exon);
900 # this will load all the exons whenever we load the translation
901 # but I guess thats ok ....
903 my $tr = $trans_hash{$transcript_id};
905 foreach my $exon (@{$tr->get_all_Exons()}) {
906 if(!$start_exon && $exon->dbID() == $start_exon_id ) {
911 if(!$end_exon && $exon->dbID() == $end_exon_id ) {
913 last
if($start_exon);
917 unless($start_exon && $end_exon) {
918 throw(
"Could not find start or end exon in transcript\n");
922 (-dbID => $translation_id,
923 -seq_start => $seq_start,
924 -seq_end => $seq_end,
925 -start_exon => $start_exon,
926 -end_exon => $end_exon,
927 -stable_id => $stable_id,
928 -version => $version,
929 -created_date => $created_date || undef,
930 -modified_date => $modified_date || undef);
932 # Calling the new method will set $tl->version to '1' if $version is not defined.
933 # But if the version in the database is NULL, $version will be undef; and so we
934 # need to override the default version of '1', and set it back to undef.
935 $tl->{version} = undef unless defined $version;
938 my $canonical_translation_id = $canonical_lookup->{$transcript_id};
939 $tr->translation($tl)
if $translation_id == $canonical_translation_id;
951 Example : $translations = $translation_adaptor->
fetch_all();
952 Description : Retrieves all canonical and alternative translations
953 stored in the database.
962 my $transcript_adaptor = $self->db()->get_TranscriptAdaptor();
965 foreach my $transcript (@{$transcript_adaptor->fetch_all}) {
966 my $translation = $self->fetch_by_Transcript($transcript);
968 push @translations, $translation;
970 foreach my $alt_translation (@{$self->fetch_all_alternative_by_Transcript($transcript)}) {
971 push @translations, $alt_translation;
974 return \@translations;
980 # Description: PROTECTED implementation of superclass abstract method.
981 # Returns the names, aliases of the tables to use for queries.
982 # Returntype : list of listrefs of strings
988 return ([
'translation',
'tl']);