ensembl-hive  2.8.1
Translation.pm
Go to the documentation of this file.
1 =head1 LICENSE
2 
3 See the NOTICE file distributed with this work for additional information
4 regarding copyright ownership.
5 
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
9 
10  http://www.apache.org/licenses/LICENSE-2.0
11 
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.
17 
18 =cut
19 
20 
21 =head1 CONTACT
22 
23  Please email comments or questions to the public Ensembl
24  developers list at <http://lists.ensembl.org/mailman/listinfo/dev>.
25 
26  Questions may also be sent to the Ensembl help desk at
27  <http://www.ensembl.org/Help/Contact>.
28 
29 =cut
30 
31 =head1 NAME
32 
33 Bio::EnsEMBL::Translation - A class representing the translation of a
35 
36 =head1 SYNOPSIS
37 
38  my $translation = Bio::EnsEMBL::Translation->new(
39  -START_EXON => $exon1,
40  -END_EXON => $exon2,
41  -SEQ_START => 98,
42  -SEQ_END => 39
43  );
44 
45  # stable ID setter
46  $translation->stable_id('ENSP00053458');
47 
48  # get start and end position in start/end exons
49  my $start = $translation->start;
50  my $end = $translation->end;
51 
52 =head1 DESCRIPTION
53 
54 A Translation object defines the CDS and UTR regions of a Transcript
55 through the use of start_Exon/end_Exon, and start/end attributes.
56 
57 =cut
58 
59 
60 package Bio::EnsEMBL::Translation;
61 
62 use vars qw($AUTOLOAD @ISA);
63 use strict;
64 
65 use Bio::EnsEMBL::Utils::Exception qw(throw warning );
66 use Bio::EnsEMBL::Utils::Argument qw( rearrange );
67 use Bio::EnsEMBL::Utils::Scalar qw( assert_ref wrap_array );
68 use Scalar::Util qw(weaken);
69 
71 
72 @ISA = qw(Bio::EnsEMBL::Storable);
73 
74 
75 =head2 new
76 
77  Arg [-START_EXON] : The Exon object in which the translation (CDS) starts
78  Arg [-END_EXON] : The Exon object in which the translation (CDS) ends
79  Arg [-SEQ_START] : The offset in the start_Exon indicating the start
80  position of the CDS.
81  Arg [-SEQ_END] : The offset in the end_Exon indicating the end
82  position of the CDS.
83  Arg [-STABLE_ID] : The stable identifier for this Translation
84  Arg [-VERSION] : The version of the stable identifier
85  Arg [-DBID] : The internal identifier of this Translation
86  Arg [-ADAPTOR] : The TranslationAdaptor for this Translation
87  Arg [-SEQ] : Manually sets the peptide sequence of this translation.
88  May be useful if this translation is not stored in
89  a database.
90  Arg [-CREATED_DATE]: the date the translation was created
91  Arg [-MODIFIED_DATE]: the date the translation was modified
92  Example : my $tl = Bio::EnsEMBL::Translation->new
93  (-START_EXON => $ex1,
94  -END_EXON => $ex2,
95  -SEQ_START => 98,
96  -SEQ_END => 39);
97  Description: Constructor. Creates a new Translation object
98  Returntype : Bio::EnsEMBL::Translation
99  Exceptions : none
100  Caller : general
101  Status : Stable
102 
103 =cut
104 
105 sub new {
106  my $caller = shift;
107 
108  my $class = ref($caller) || $caller;
109 
110  my ( $start_exon, $end_exon, $seq_start, $seq_end,
111  $stable_id, $version, $dbID, $adaptor, $seq,
112  $created_date, $modified_date ) =
113  rearrange( [ "START_EXON", "END_EXON", "SEQ_START", "SEQ_END",
114  "STABLE_ID", "VERSION", "DBID", "ADAPTOR",
115  "SEQ", "CREATED_DATE", "MODIFIED_DATE" ], @_ );
116 
117  # Default version
118  if ( !defined($version) ) { $version = 1 }
119 
120  my $self = bless {
121  'start_exon' => $start_exon,
122  'end_exon' => $end_exon,
123  'dbID' => $dbID,
124  'start' => $seq_start,
125  'end' => $seq_end,
126  'stable_id' => $stable_id,
127  'version' => $version,
128  'created_date' => $created_date,
129  'modified_date' => $modified_date,
130  'seq' => $seq
131  }, $class;
132 
133  $self->adaptor($adaptor);
134 
135  return $self;
136 }
137 
138 
139 
140 =head2 transcript
141 
142  Arg [1] : Transcript object (optional)
143  Description : Sets or retrieves the transcript object associated
144  with this translation object.
145  Exceptions : Throws if there is no adaptor or no dbID defined for
146  the translation object.
147  Returntype : Bio::EnsEMBL::Transcript
148 =cut
149 
150 sub transcript {
151  my ( $self, $transcript ) = @_;
152 
153  if ( defined($transcript) ) {
154  assert_ref( $transcript, 'Bio::EnsEMBL::Transcript' );
155 
156  $self->{'transcript'} = $transcript;
157 
158  weaken( $self->{'transcript'} ); # Avoid circular references.
159 
160  } elsif ( @_ > 1 ) {
161  # Break connection to transcript.
162  delete( $self->{'transcript'} );
163  } elsif ( !defined( $self->{'transcript'} ) ) {
164  my $adaptor = $self->adaptor;
165  if ( !defined($adaptor) ) {
166  throw( "Adaptor is not set for translation, "
167  . "can not fetch its transcript." );
168  }
169 
170  my $dbID = $self->{'dbID'};
171  if ( !defined($dbID) ) {
172  throw( "dbID is not set for translation, "
173  . " can not fetch its transcript." );
174  }
175 
176  $self->{'transcript'} =
177  $adaptor->db()->get_TranscriptAdaptor()
178  ->fetch_by_translation_id($dbID);
179 
180  # Do not weaken the reference if we had to get the transcript from the
181  # database. The user is probably working on translations directly,
182  # not going through transcripts.
183  #weaken( $self->{'transcript'} ); # Avoid circular references.
184  }
185 
186  return $self->{'transcript'};
187 } ## end sub transcript
188 
189 
190 =head2 start
191 
192  Arg [1] : (optional) int $start - start position to set
193  Example : $translation->start(17);
194  Description: Getter/setter for the value of start, which is a position within
195  the exon given by start_Exon.
196 
197  If you need genomic coordinates, use the genomic_start()
198  method.
199  Returntype : int
200  Exceptions : none
201  Caller : general
202  Status : Stable
203 
204 =cut
205 
206 sub start{
207  my $obj = shift;
208  if( @_ ) {
209  my $value = shift;
210 
211  $obj->{'start'} = $value;
212  }
213  return $obj->{'start'};
214 
215 }
216 
217 
218 =head2 end
219 
220  Arg [1] : (optional) int $end - end position to set
221  Example : $translation->end(8);
222  Description: Getter/setter for the value of end, which is a position within
223  the exon given by end_Exon.
224 
225  If you need genomic coordinates, use the genomic_end()
226  method.
227  Returntype : int
228  Exceptions : none
229  Caller : general
230  Status : Stable
231 
232 =cut
233 
234 sub end {
235  my $self = shift;
236  if( @_ ) {
237  my $value = shift;
238 
239  $self->{'end'} = $value;
240  }
241  return $self->{'end'};
242 
243 }
244 
245 
246 =head2 start_Exon
247 
248  Arg [1] : (optional) Bio::EnsEMBL::Exon - start exon to assign
249  Example : $translation->start_Exon($exon1);
250  Description: Getter/setter for the value of start_Exon, which denotes the
251  exon at which translation starts (and within this exon, at the
252  position indicated by start, see above).
253  Returntype : Bio::EnsEMBL::Exon
254  Exceptions : thrown on wrong argument type
255  Caller : general
256  Status : Stable
257 
258 =cut
259 
260 sub start_Exon {
261  my $self = shift;
262 
263  if( @_ ) {
264  my $value = shift;
265  if( !ref $value || !$value->isa('Bio::EnsEMBL::Exon') ) {
266  throw("Got to have an Exon object, not a $value");
267  }
268  $self->{'start_exon'} = $value;
269  }
270  return $self->{'start_exon'};
271 }
272 
273 
274 =head2 end_Exon
275 
276  Arg [1] : (optional) Bio::EnsEMBL::Exon - start exon to assign
277  Example : $translation->start_Exon($exon1);
278  Description: Getter/setter for the value of end_Exon, which denotes the
279  exon at which translation ends (and within this exon, at the
280  position indicated by end, see above).
281  Returntype : Bio::EnsEMBL::Exon
282  Exceptions : thrown on wrong argument type
283  Caller : general
284  Status : Stable
285 
286 =cut
287 
288 sub end_Exon {
289  my $self = shift;
290  if( @_ ) {
291  my $value = shift;
292  if( !ref $value || !$value->isa('Bio::EnsEMBL::Exon') ) {
293  throw("Got to have an Exon object, not a $value");
294  }
295  $self->{'end_exon'} = $value;
296  }
297 
298  return $self->{'end_exon'};
299 }
300 
301 =head2 cdna_start
302 
303  Arg [1] : (optional) Bio::EnsEMBL::Transcript $transcript
304  The transcript which this is a translation of.
305  Example : $translation_cdna_start = $translation->cdna_start();
306  Description : Returns the start position of the translation in cDNA
307  coordinates.
308  If no transcript is given, the method will use
309  TranscriptAdaptor->fetch_by_translation_id() to locate
310  the correct transcript.
311  Return type : Integer
312  Exceptions : Throws if the given (optional) argument is not a
313  transcript.
314  Caller : General
315  Status : At Risk (Under Development)
316 
317 =cut
318 
319 sub cdna_start {
320  my ( $self, $transcript ) = @_;
321 
322  if ( defined($transcript)
323  && ( !ref($transcript)
324  || !$transcript->isa('Bio::EnsEMBL::Transcript') ) )
325  {
326  throw("Argument is not a transcript");
327  }
328 
329  if ( !exists( $self->{'cdna_start'} ) ) {
330  if ( !defined($transcript) ) {
331  # We were not given a transcript, get the transcript out of
332  # the database.
333  $transcript = $self->transcript();
334  }
335 
336  $self->{'cdna_start'} =
337  $self->start_Exon()->cdna_coding_start($transcript);
338  }
339 
340  return $self->{'cdna_start'};
341 }
342 
343 =head2 cdna_end
344 
345  Arg [1] : (optional) Bio::EnsEMBL::Transcript $transcript
346  The transcript which this is a translation of.
347  Example : $translation_cdna_end = $translation->cdna_end();
348  Description : Returns the end position of the translation in cDNA
349  coordinates.
350  If no transcript is given, the method will use
351  TranscriptAdaptor->fetch_by_translation_id() to locate
352  the correct transcript.
353  Return type : Integer
354  Exceptions : Throws if the given (optional) argument is not a
355  transcript.
356  Caller : General
357  Status : At Risk (Under Development)
358 
359 =cut
360 
361 sub cdna_end {
362  my ( $self, $transcript ) = @_;
363 
364  if ( defined($transcript)
365  && ( !ref($transcript)
366  || !$transcript->isa('Bio::EnsEMBL::Transcript') ) )
367  {
368  throw("Argument is not a transcript");
369  }
370 
371  if ( !exists( $self->{'cdna_end'} ) ) {
372  if ( !defined($transcript) ) {
373  # We were not given a transcript, get the transcript out of
374  # the database.
375  $transcript = $self->transcript();
376  }
377 
378  $self->{'cdna_end'} =
379  $self->end_Exon()->cdna_coding_end($transcript);
380  }
381 
382  return $self->{'cdna_end'};
383 }
384 
385 =head2 genomic_start
386 
387  Args : None
388  Example : $translation_genomic_start =
389  $translation->genomic_start();
390  Description : Returns the start position of the translation in
391  genomic coordinates on the forward strand.
392  Return type : Integer
393  Exceptions : None
394  Caller : General
395  Status : At Risk (Under Development)
396 
397 =cut
398 
399 sub genomic_start {
400  my $self = shift;
401 
402  if ( !exists $self->{'genomic_start'} ) {
403  if ( $self->start_Exon()->strand() >= 0 ) {
404  $self->{'genomic_start'} =
405  $self->start_Exon()->start() + ( $self->start() - 1 );
406  } else {
407  $self->{'genomic_start'} =
408  $self->end_Exon()->end() - ( $self->end() - 1 );
409  }
410  }
411 
412  return $self->{'genomic_start'};
413 }
414 
415 =head2 genomic_end
416 
417  Args : None
418  Example : $translation_genomic_end = $translation->genomic_end();
419  Description : Returns the end position of the translation in genomic
420  coordinates on the forward strand.
421  Return type : Integer
422  Exceptions : None
423  Caller : General
424  Status : At Risk (Under Development)
425 
426 =cut
427 
428 sub genomic_end {
429  my $self = shift;
430 
431  if ( !exists $self->{'genomic_end'} ) {
432  if ( $self->end_Exon()->strand() >= 0 ) {
433  $self->{'genomic_end'} =
434  $self->end_Exon()->start() + ( $self->end() - 1 );
435  } else {
436  $self->{'genomic_end'} =
437  $self->start_Exon()->end() - ( $self->start() - 1 );
438  }
439  }
440 
441  return $self->{'genomic_end'};
442 }
443 
444 =head2 version
445 
446  Arg [1] : (optional) string $version - version to set
447  Example : $translation->version(2);
448  Description: Getter/setter for attribute version
449  Returntype : string
450  Exceptions : none
451  Caller : general
452  Status : Stable
453 
454 =cut
455 
456 sub version {
457  my $self = shift;
458  $self->{'version'} = shift if( @_ );
459  return $self->{'version'};
460 }
461 
462 
463 =head2 stable_id
464 
465  Arg [1] : (optional) string $stable_id - stable ID to set
466  Example : $translation->stable_id('ENSP0059890');
467  Description: Getter/setter for attribute stable_id
468  Returntype : string
469  Exceptions : none
470  Caller : general
471  Status : Stable
472 
473 =cut
474 
475 sub stable_id {
476  my $self = shift;
477  $self->{'stable_id'} = shift if( @_ );
478  return $self->{'stable_id'};
479 }
480 
481 =head2 stable_id_version
482 
483  Arg [1] : (optional) String - the stable ID with version to set
484  Example : $translation->stable_id("ENSP0059890.3");
485  Description: Getter/setter for stable id with version for this translation.
486  Returntype : String
487  Exceptions : none
488  Caller : general
489  Status : Stable
490 
491 =cut
492 
493 sub stable_id_version {
494  my $self = shift;
495  if(my $stable_id = shift) {
496  # See if there's an embedded period, assume that's a
497  # version, might not work for some species but you
498  # should use ->stable_id() and version() if you're worried
499  # about ambiguity
500  my $vindex = rindex($stable_id, '.');
501  # Set the stable_id and version pair depending on if
502  # we found a version delimiter in the stable_id
503  ($self->{stable_id}, $self->{version}) = ($vindex > 0 ?
504  (substr($stable_id,0,$vindex), substr($stable_id,$vindex+1)) :
505  $stable_id, undef);
506  }
507  return $self->{stable_id} . ($self->{version} ? ".$self->{version}" : '');
508 }
509 
510 =head2 created_date
511 
512  Arg [1] : (optional) string $created_date - created date to set
513  Example : $translation->created_date('2007-01-10 20:52:00');
514  Description: Getter/setter for attribute created date
515  Returntype : string
516  Exceptions : none
517  Caller : general
518  Status : Stable
519 
520 =cut
521 
522 sub created_date {
523  my $self = shift;
524  $self->{'created_date'} = shift if ( @_ );
525  return $self->{'created_date'};
526 }
527 
528 
529 =head2 modified_date
530 
531  Arg [1] : (optional) string $modified_date - modification date to set
532  Example : $translation->modified_date('2007-01-10 20:52:00');
533  Description: Getter/setter for attribute modified date
534  Returntype : string
535  Exceptions : none
536  Caller : general
537  Status : Stable
538 
539 =cut
540 
541 sub modified_date {
542  my $self = shift;
543  $self->{'modified_date'} = shift if ( @_ );
544  return $self->{'modified_date'};
545 }
546 
547 
548 
549 =head2 transform
550 
551  Arg [1] : hashref $old_new_exon_map
552  a hash that maps old to new exons for a whole gene
553  Description: maps start end end exon according to mapping table.
554  If an exon is not mapped, just keep the old one.
555  Returntype : none
556  Exceptions : none
557  Caller : Transcript->transform()
558  Status : Stable
559 
560 =cut
561 
562 sub transform {
563  my $self = shift;
564  my $href_exons = shift;
565 
566  my $start_exon = $self->start_Exon();
567  my $end_exon = $self->end_Exon();
568 
569  if ( exists $href_exons->{$start_exon} ) {
570  $self->start_Exon($href_exons->{$start_exon});
571  } else {
572  # do nothing, the start exon wasnt mapped
573  }
574 
575  if ( exists $href_exons->{$end_exon} ) {
576  $self->end_Exon($href_exons->{$end_exon});
577  } else {
578  # do nothing, the end exon wasnt mapped
579  }
580 }
581 
582 
583 =head2 get_all_DBEntries
584 
585  Arg [1] : (optional) String, external database name,
586  SQL wildcard characters (_ and %) can be used to
587  specify patterns.
588 
589  Arg [2] : (optional) String, external_db type,
590  ('ARRAY','ALT_TRANS','ALT_GENE','MISC','LIT','PRIMARY_DB_SYNONYM','ENSEMBL'),
591  SQL wildcard characters (_ and %) can be used to
592  specify patterns.
593 
594  Example : my @dbentries = @{ $translation->get_all_DBEntries() };
595  @dbentries = @{ $translation->get_all_DBEntries('Uniprot%') };
596  @dbentries = @{ $translation->get_all_DBEntries('%', 'ENSEMBL') };
597 
598  Description: Retrieves DBEntries (xrefs) for this translation.
599 
600  This method will attempt to lazy-load DBEntries
601  from a database if an adaptor is available and no
602  DBEntries are present on the translation (i.e. they
603  have not already been added or loaded).
604 
605  Returntype : Listref to Bio::EnsEMBL::DBEntry objects
606  Exceptions : none
607  Caller : TranslationAdaptor::store
608  Status : Stable
609 
610 =cut
611 
612 sub get_all_DBEntries {
613  my ( $self, $ex_db_exp, $ex_db_type ) = @_;
614 
615  my $cache_name = 'dbentries';
616 
617  if ( defined($ex_db_exp) ) {
618  $cache_name .= $ex_db_exp;
619  }
620 
621  if ( defined($ex_db_type) ) {
622  $cache_name .= $ex_db_type;
623  }
624 
625  # if not cached, retrieve all of the xrefs for this translation
626  if ( !defined( $self->{$cache_name} ) && defined( $self->adaptor() ) )
627  {
628  $self->{$cache_name} =
629  $self->adaptor()->db()->get_DBEntryAdaptor()
630  ->fetch_all_by_Translation( $self, $ex_db_exp, $ex_db_type );
631  }
632 
633  $self->{$cache_name} ||= [];
634 
635  return $self->{$cache_name};
636 } ## end sub get_all_DBEntries
637 
638 =head2 get_all_object_xrefs
639 
640  Arg [1] : (optional) String, external database name
641 
642  Arg [2] : (optional) String, external_db type
643 
644  Example : @oxrefs = @{ $translation->get_all_object_xrefs() };
645 
646  Description: Retrieves xrefs for this translation.
647 
648  This method will attempt to lazy-load xrefs from a
649  database if an adaptor is available and no xrefs
650  are present on the translation (i.e. they have not
651  already been added or loaded).
652 
653  NB: This method is an alias for the
654  get_all_DBentries() method.
655 
656  Return type: Listref of Bio::EnsEMBL::DBEntry objects
657 
658  Status : Stable
659 
660 =cut
661 
662 sub get_all_object_xrefs {
663  my $self = shift;
664  return $self->get_all_DBEntries(@_);
665 }
666 
667 =head2 add_DBEntry
668 
669  Arg [1] : Bio::EnsEMBL::DBEntry $dbe
670  The dbEntry to be added
671  Example : $translation->add_DBEntry($xref);
672  Description: Associates a DBEntry with this translation. Note that adding
673  DBEntries will prevent future lazy-loading of DBEntries for this
674  translation (see get_all_DBEntries).
675  Returntype : none
676  Exceptions : thrown on incorrect argument type
677  Caller : general
678  Status : Stable
679 
680 =cut
681 
682 sub add_DBEntry {
683  my $self = shift;
684  my $dbe = shift;
685 
686  unless($dbe && ref($dbe) && $dbe->isa('Bio::EnsEMBL::DBEntry')) {
687  throw('Expected DBEntry argument');
688  }
689 
690  $self->{'dbentries'} ||= [];
691  push @{$self->{'dbentries'}}, $dbe;
692 }
693 
694 
695 =head2 get_all_DBLinks
696 
697  Arg [1] : String database name (optional)
698  SQL wildcard characters (_ and %) can be used to
699  specify patterns.
700 
701  Arg [2] : (optional) String, external database type, can be one of
702  ('ARRAY','ALT_TRANS','ALT_GENE','MISC','LIT','PRIMARY_DB_SYNONYM','ENSEMBL'),
703  SQL wildcard characters (_ and %) can be used to
704  specify patterns.
705 
706  Example : my @dblinks = @{ $translation->get_all_DBLinks() };
707  @dblinks = @{ $translation->get_all_DBLinks('Uniprot%') };
708  @dblinks = @{ $translation->get_all_DBLinks('%', 'ENSEMBL') };
709 
710  Description: This is here for consistancy with the Transcript
711  and Gene classes. It is a synonym for the
712  get_all_DBEntries() method.
713 
714  Return type: Listref to Bio::EnsEMBL::DBEntry objects
715  Exceptions : none
716  Caller : general
717  Status : Stable
718 
719 =cut
720 
721 sub get_all_DBLinks {
722  my $self = shift;
723  return $self->get_all_DBEntries(@_);
724 }
725 
726 =head2 get_all_xrefs
727 
728  Arg [1] : String database name (optional)
729  SQL wildcard characters (_ and %) can be used to
730  specify patterns.
731 
732  Example : @xrefs = @{ $translation->get_all_xrefs() };
733  @xrefs = @{ $translation->get_all_xrefs('Uniprot%') };
734 
735  Description: This method is here for consistancy with the Gene
736  and Transcript classes. It is an alias for the
737  get_all_DBLinks() method, which in turn directly
738  calls get_all_DBEntries().
739 
740  Return type: Listref of Bio::EnsEMBL::DBEntry objects
741 
742  Status : Stable
743 
744 =cut
745 
746 sub get_all_xrefs {
747  my $self = shift;
748  return $self->get_all_DBLinks(@_);
749 }
750 
751 =head2 get_all_ProteinFeatures
752 
753  Arg [1] : (optional) string $logic_name
754  The analysis logic_name of the features to retrieve. If not
755  specified, all features are retrieved instead.
756  If no logic_name is found, looking for analysis db name instead.
757  Example : $features = $self->get_all_ProteinFeatures('PFam');
758  Description: Retrieves all ProteinFeatures associated with this
759  Translation. If a logic_name is specified, only features with
760  that logic_name are returned. If no logic_name is provided all
761  associated protein_features are returned.
762 
763  ProteinFeatures are lazy-loaded from the database unless they
764  added manually to the Translation or had already been loaded.
765  Returntype : Listref of Bio::EnsEMBL::ProteinFeature
766  Exceptions : none
767  Caller : general
768  Status : Stable
769 
770 =cut
771 
772 sub get_all_ProteinFeatures {
773  my $self = shift;
774  my $logic_name = shift;
775 
776  my (%hash, %db_hash);
777  my $no_pf = 0;
778 
779  if(!$self->{'protein_features'}) {
780  $no_pf = 1;
781  my $adaptor = $self->adaptor();
782  my $dbID = $self->dbID();
783 
784  return [] if (!$adaptor || !$dbID);
785 
786  $self->{'protein_features'} = \%hash;
787 
788  my $pfa = $adaptor->db()->get_ProteinFeatureAdaptor();
789  my ($name, $ana_db);
790  foreach my $f (@{$pfa->fetch_all_by_translation_id($dbID)}) {
791  my $analysis = $f->analysis();
792  if($analysis) {
793  $name = lc($f->analysis->logic_name());
794  $ana_db = lc($f->analysis->db());
795  $db_hash{$ana_db} = $name;
796  } else {
797  warning("ProteinFeature has no attached analysis\n");
798  $name = '';
799  }
800  $hash{$name} ||= [];
801  push @{$hash{$name}}, $f;
802  }
803  }
804 
805  # a specific type of protein feature was requested
806  if(defined($logic_name)) {
807  $logic_name = lc($logic_name);
808  if (!$hash{$logic_name} && $no_pf) {
809  $logic_name = $db_hash{$logic_name};
810  }
811  return $self->{'protein_features'}->{$logic_name} || [];
812  }
813 
814  my @features = ();
815 
816  # all protein features were requested
817  foreach my $type (keys %{$self->{'protein_features'}}) {
818  push @features, @{$self->{'protein_features'}->{$type}};
819  }
820 
821  return \@features;
822 }
823 
824 
825 =head2 get_all_DomainFeatures
826 
827  Example : @domain_feats = @{$translation->get_all_DomainFeatures};
828  Description: A convenience method which retrieves all protein features
829  that are considered to be 'Domain' features. Features which
830  are 'domain' features are those with analysis logic names:
831  'pfscan', 'scanprosite', 'superfamily', 'pfam', 'prints',
832  'smart', 'pirsf', 'tigrfam'.
833  Returntype : listref of Bio::EnsEMBL::ProteinFeature
834  Exceptions : none
835  Caller : webcode (protview)
836  Status : Stable
837 
838 =cut
839 
840 sub get_all_DomainFeatures{
841  my ($self) = @_;
842 
843  my @features;
844 
845  my @types = ('pfscan', #profile (prosite or pfam motifs)
846  'scanprosite', #prosite
847  'superfamily',
848  'pfam',
849  'smart',
850  'tigrfam',
851  'pirsf',
852  'prints');
853 
854  foreach my $type (@types) {
855  push @features, @{$self->get_all_ProteinFeatures($type)};
856  }
857 
858  return \@features;
859 }
860 
861 
862 =head2 add_ProteinFeature
863 
864  Arg [1] : Bio::EnsEMBL::ProteinFeature $pf
865  The ProteinFeature to be added
866  Example : $translation->add_ProteinFeature($pf);
867  Description: Associates a ProteinFeature with this translation. Note that
868  adding ProteinFeatures will prevent future lazy-loading of
869  ProteinFeatures for this translation (see
870  get_all_ProteinFeatures).
871  Returntype : none
872  Exceptions : thrown on incorrect argument type
873  Caller : general
874  Status : Stable
875 
876 =cut
877 
878 sub add_ProteinFeature {
879  my $self = shift;
880  my $pf = shift;
881 
882  unless ($pf && ref($pf) && $pf->isa('Bio::EnsEMBL::ProteinFeature')) {
883  throw('Expected ProteinFeature argument');
884  }
885 
886  my $analysis = $pf->analysis;
887  throw("ProteinFeature has no attached Analysis.") unless $analysis;
888 
889  push @{ $self->{'protein_features'}->{$analysis->logic_name} }, $pf;
890 }
891 
892 
893 =head2 display_id
894 
895  Example : print $translation->display_id();
896  Description: This method returns a string that is considered to be
897  the 'display' identifier. For translations this is (depending on
898  availability and in this order) the stable Id, the dbID or an
899  empty string.
900  Returntype : string
901  Exceptions : none
902  Caller : web drawing code
903  Status : Stable
904 
905 =cut
906 
907 sub display_id {
908  my $self = shift;
909  return $self->{'stable_id'} || $self->dbID || '';
910 }
911 
912 
913 =head2 length
914 
915  Example : print "Peptide length =", $translation->length();
916  Description: Retrieves the length of the peptide sequence (i.e. number of
917  amino acids) represented by this Translation object.
918  Returntype : int
919  Exceptions : none
920  Caller : webcode (protview etc.)
921  Status : Stable
922 
923 =cut
924 
925 sub length {
926  my $self = shift;
927  my $seq = $self->seq();
928 
929  return ($seq) ? CORE::length($seq) : 0;
930 }
931 
932 
933 =head2 seq
934 
935  Example : print $translation->seq();
936  Description: Retrieves a string representation of the peptide sequence
937  of this Translation. This retrieves the transcript from the
938  database and gets its sequence, or retrieves the sequence which
939  was set via the constructor.
940  Returntype : string
941  Exceptions : warning if the sequence is not set and cannot be retrieved from
942  the database.
943  Caller : webcode (protview etc.)
944  Status : Stable
945 
946 =cut
947 
948 sub seq {
949  my ( $self, $sequence ) = @_;
950 
951  if ( defined($sequence) ) {
952 
953  $self->{'seq'} = $sequence;
954 
955  } elsif ( !defined( $self->{'seq'} ) ) {
956 
957  my $transcript = $self->transcript();
958 
959  my $canonical_translation = $transcript->translation();
960  my $is_alternative;
961  if(!$canonical_translation) {
962  throw "Transcript does not have a canonical translation";
963  }
964  if ( defined( $canonical_translation->stable_id() )
965  && defined( $self->stable_id() ) )
966  {
967  # Try stable ID.
968  $is_alternative =
969  ( $canonical_translation->stable_id() ne $self->stable_id() );
970  } elsif ( defined( $canonical_translation->dbID() )
971  && defined( $self->dbID() ) )
972  {
973  # Try dbID.
974  $is_alternative =
975  ( $canonical_translation->dbID() != $self->dbID() );
976  } else {
977  # Resort to using geomic start/end coordinates.
978  $is_alternative = ( ($canonical_translation->genomic_start() !=
979  $self->genomic_start() )
980  || ( $canonical_translation->genomic_end() !=
981  $self->genomic_end() ) );
982  }
983 
984  if ($is_alternative) {
985  # To deal with non-canonical (alternative) translations, subsitute
986  # the canonical translation in the transcript with $self for a
987  # while.
988 
989  $transcript->translation($self);
990  }
991 
992  my $seq = $transcript->translate();
993  if ( defined($seq) ) {
994  $self->{'seq'} = $seq->seq();
995  }
996 
997  if ($is_alternative) {
998  # Reinstate the real canonical translation.
999 
1000  $transcript->translation($canonical_translation);
1001  }
1002 
1003  } ## end elsif ( !defined( $self->...))
1004 
1005  if ( !defined( $self->{'seq'} ) ) {
1006  return ''; # Empty string
1007  }
1008 
1009  return $self->{'seq'};
1010 
1011 } ## end sub seq
1012 
1013 
1014 =head2 get_all_Attributes
1015 
1016  Arg [1] : optional string $attrib_code
1017  The code of the attribute type to retrieve values for.
1018  Example : ($sc_attr) = @{$tl->get_all_Attributes('_selenocysteine')};
1019  @tl_attributes = @{$translation->get_all_Attributes()};
1020  Description: Gets a list of Attributes of this translation.
1021  Optionally just get Attrubutes for given code.
1022  Recognized attribute "_selenocysteine"
1023  Returntype : listref Bio::EnsEMBL::Attribute
1024  Exceptions : warning if translation does not have attached adaptor and
1025  attempts lazy load.
1026  Caller : general, modify_translation
1027  Status : Stable
1028 
1029 =cut
1030 
1031 sub get_all_Attributes {
1032  my $self = shift;
1033  my $attrib_code = shift;
1034 
1035  if( ! exists $self->{'attributes' } ) {
1036  if(!$self->adaptor() ) {
1037 # warning('Cannot get attributes without an adaptor.');
1038  return [];
1039  }
1040 
1041  my $aa = $self->adaptor->db->get_AttributeAdaptor();
1042  $self->{'attributes'} = $aa->fetch_all_by_Translation( $self );
1043  }
1044 
1045  if( defined $attrib_code ) {
1046  my @results = grep { uc($_->code()) eq uc($attrib_code) }
1047  @{$self->{'attributes'}};
1048  return \@results;
1049  } else {
1050  return $self->{'attributes'};
1051  }
1052 }
1053 
1054 
1055 =head2 add_Attributes
1056 
1057  Arg [1..N] : Bio::EnsEMBL::Attribute $attribute
1058  Attributes to add.
1059  Example : $translation->add_Attributes($selenocysteine_attribute);
1060  Description: Adds an Attribute to the Translation. Usefull to
1061  do _selenocysteine.
1062  If you add an attribute before you retrieve any from database,
1063  lazy load will be disabled.
1064  Returntype : none
1065  Exceptions : throw on incorrect arguments
1066  Caller : general
1067  Status : Stable
1068 
1069 =cut
1070 
1071 sub add_Attributes {
1072  my $self = shift;
1073  my @attribs = @_;
1074 
1075  if( ! exists $self->{'attributes'} ) {
1076  $self->{'attributes'} = [];
1077  }
1078 
1079  for my $attrib ( @attribs ) {
1080  if( ! $attrib->isa( "Bio::EnsEMBL::Attribute" )) {
1081  throw( "Argument to add_Attribute must be a Bio::EnsEMBL::Attribute" );
1082  }
1083  push( @{$self->{'attributes'}}, $attrib );
1084  $self->{seq}=undef;
1085  }
1086 }
1087 
1088 
1089 =head2 get_all_SeqEdits
1090 
1091  Arg [1] : ArrayRef $edits. Specify the name of the edits to fetch
1092  Example : my @seqeds = @{$translation->get_all_SeqEdits()};
1093  my @seqeds = @{$translation->get_all_SeqEdits('_selenocysteine')};
1094  Description: Retrieves all post transcriptional sequence modifications for
1095  this translation.
1096  Returntype : Bio::EnsEMBL::SeqEdit
1097  Exceptions : none
1098  Caller : spliced_seq()
1099  Status : Stable
1100 
1101 =cut
1102 
1103 sub get_all_SeqEdits {
1104  my $self = shift;
1105  my $edits = shift;
1106 
1107  my @seqeds;
1108 
1109  my $attribs;
1110 
1111  $edits ||= ['initial_met', '_selenocysteine', 'amino_acid_sub', '_stop_codon_rt'];
1112 
1113 
1114  foreach my $edit(@{wrap_array($edits)}){
1115  $attribs = $self->get_all_Attributes($edit);
1116 
1117  # convert attributes to SeqEdit objects
1118  foreach my $a (@$attribs) {
1119  push @seqeds, Bio::EnsEMBL::SeqEdit->new(-ATTRIB => $a);
1120  }
1121  }
1122  return \@seqeds;
1123 }
1124 
1125 =head2 get_all_selenocysteine_SeqEdits
1126 
1127  Example : my @edits = @{$translation->get_all_selenocysteine_SeqEdits()};
1128  Description: Retrieves all post transcriptional sequence modifications related
1129  to selenocysteine PTMs
1130  Returntype : Bio::EnsEMBL::SeqEdit
1131  Exceptions : none
1132 
1133 =cut
1134 
1135 sub get_all_selenocysteine_SeqEdits {
1136  my ($self) = @_;
1137  return $self->get_all_SeqEdits(['_selenocysteine']);
1138 }
1139 
1140 =head2 get_all_stop_codon_SeqEdits
1141 
1142  Example : my @edits = @{$translation->get_all_stop_codon_SeqEdits()};
1143  Description: Retrieves all post transcriptional sequence modifications related
1144  to stop codon readthrough
1145  Returntype : Bio::EnsEMBL::SeqEdit
1146  Exceptions : none
1147 
1148 =cut
1149 
1150 sub get_all_stop_codon_SeqEdits {
1151  my ($self) = @_;
1152  return $self->get_all_SeqEdits(['_stop_codon_rt']);
1153 }
1154 
1155 =head2 modify_translation
1156 
1157  Arg [1] : Bio::Seq $peptide
1158  Example : my $seq = Bio::Seq->new(-SEQ => $dna)->translate();
1159  $translation->modify_translation($seq);
1160  Description: Applies sequence edits such as selenocysteines to the Bio::Seq
1161  peptide thats passed in
1162  Returntype : Bio::Seq
1163  Exceptions : none
1165  Status : Stable
1166 
1167 =cut
1168 
1169 sub modify_translation {
1170  my ( $self, $seq ) = @_;
1171 
1172  my @seqeds = @{ $self->get_all_SeqEdits() };
1173 
1174  # Sort in reverse order to avoid complication of adjusting
1175  # downstream edits.
1176  # HACK: The translation ENSP00000420939 somehow makes the next line
1177  # bomb out ($a or $b becomes undef) if the start() method
1178  # is used. I haven't been able to find out why. It has 10
1179  # Selenocysteine seqedits that looks correct.
1180  # /Andreas (release 59)
1181  @seqeds = sort { $b->{'start'} <=> $a->{'start'} } @seqeds;
1182 
1183  # Apply all edits.
1184  my $peptide = $seq->seq();
1185  foreach my $se (@seqeds) {
1186  $se->apply_edit( \$peptide );
1187  }
1188 
1189  $seq->seq($peptide);
1190 
1191  return $seq;
1192 }
1193 
1194 =head2 load
1195 
1196  Arg [1] : Boolean $load_xrefs
1197  Load (or don't load) xrefs. Default is to load xrefs.
1198  Example : $translation->load();
1199  Description : The Ensembl API makes extensive use of
1200  lazy-loading. Under some circumstances (e.g.,
1201  when copying genes between databases), all data of
1202  an object needs to be fully loaded. This method
1203  loads the parts of the object that are usually
1204  lazy-loaded.
1205  Returns : none
1206 
1207 =cut
1208 
1209 sub load {
1210  my ( $self, $load_xrefs ) = @_;
1211 
1212  if ( !defined($load_xrefs) ) { $load_xrefs = 1 }
1213 
1214  $self->seq();
1215 
1216  $self->stable_id();
1217  $self->get_all_Attributes();
1218  $self->get_all_ProteinFeatures();
1219 
1220  if ($load_xrefs) {
1221  $self->get_all_DBEntries();
1222  }
1223 }
1224 
1225 
1226 =head2 get_all_DASFactories
1227 
1228  Function : Retrieves a listref of registered DAS objects
1229  Returntype: Listref of DAS Objects
1230  Exceptions: none
1231  Caller : webcode
1232  Example : $dasref = $prot->get_all_DASFactories;
1233  Status : Stable
1234 
1235 =cut
1236 
1237 sub get_all_DASFactories {
1238  my $self = shift;
1239  return [ $self->adaptor()->db()->_each_DASFeatureFactory ];
1240 }
1241 
1242 
1243 =head2 get_all_DAS_Features
1244 
1245  Example : $features = $prot->get_all_DAS_Features;
1246  Description: Retrieves a hash reference to a hash of DAS feature
1247  sets, keyed by the DNS, NOTE the values of this hash
1248  are an anonymous array containing:
1249  (1) a pointer to an array of features;
1250  (2) a pointer to the DAS stylesheet
1251  Returntype : hashref of Bio::SeqFeatures
1252  Exceptions : none
1253  Caller : webcode
1254  Status : Stable
1255 
1256 =cut
1257 
1258 sub get_all_DAS_Features{
1259  my $self = shift;
1260 
1261  my $db = $self->adaptor->db;
1262  my $GeneAdaptor = $db->get_GeneAdaptor;
1263  my $Gene = $GeneAdaptor->fetch_by_translation_stable_id($self->stable_id) || return;
1264  my $slice = $Gene->feature_Slice;
1265 
1266  return $self->SUPER::get_all_DAS_Features($slice);
1267 }
1268 
1269 =head2 summary_as_hash
1270 
1271  Example : $translation_summary = $translation->summary_as_hash();
1272  Description : Retrieves a textual summary of this Translation.
1273  Not inherited from Feature.
1274  Returns : hashref of arrays of descriptive strings
1275  Status : Intended for internal use
1276 =cut
1277 
1278 sub summary_as_hash {
1279  my $self = shift;
1280  my %summary;
1281  my $id = $self->display_id;
1282  if ($self->version) { $id .= "." . $self->version; }
1283  $summary{'id'} = $id;
1284  $summary{'protein_id'} = $id;
1285  $summary{'genomic_start'} = $self->genomic_start;
1286  $summary{'genomic_end'} = $self->genomic_end;
1287  $summary{'length'} = $self->length;
1288  my $transcript = $self->transcript;
1289  $summary{'Parent'} = $transcript->display_id;
1290  return \%summary;
1291 }
1292 
1293 1;
transcript
public transcript()
Bio::EnsEMBL::Transcript::translate
public Bio::Seq translate()
Bio::EnsEMBL::Analysis::logic_name
public String logic_name()
Bio::EnsEMBL::Translation
Definition: Translation.pm:32
EnsEMBL
Definition: Filter.pm:1
Bio::EnsEMBL::SeqEdit::new
public Bio::EnsEMBL::SeqEdit new()
Bio::EnsEMBL::Feature::analysis
public Bio::EnsEMBL::Analysis analysis()
Bio::EnsEMBL::Translation::stable_id
public String stable_id()
Bio::EnsEMBL::Storable
Definition: Storable.pm:23
Bio::EnsEMBL::ProteinFeature
Definition: ProteinFeature.pm:24
Bio::EnsEMBL::SeqEdit
Definition: SeqEdit.pm:55
exon
public exon()
Bio::EnsEMBL::Exon
Definition: Exon.pm:42
Bio::EnsEMBL::CDS
Definition: CDS.pm:28
Bio::EnsEMBL::Transcript
Definition: Transcript.pm:44
Bio::EnsEMBL::Utils::Scalar
Definition: Scalar.pm:66
Bio::EnsEMBL::DBSQL::BaseAdaptor::db
public Bio::EnsEMBL::DBSQL::DBAdaptor db()
Bio::EnsEMBL::Attribute
Definition: Attribute.pm:34
Bio::EnsEMBL::Translation::new
public Bio::EnsEMBL::Translation new()
Bio::EnsEMBL::DBEntry
Definition: DBEntry.pm:12
Bio::EnsEMBL::UTR
Definition: UTR.pm:28
Bio
Definition: AltAlleleGroup.pm:4
Bio::EnsEMBL::Utils::Argument
Definition: Argument.pm:34
Bio::EnsEMBL::Utils::Exception
Definition: Exception.pm:68
Bio::EnsEMBL::Storable::adaptor
public Bio::EnsEMBL::DBSQL::BaseAdaptor adaptor()