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
38 Objects of
this class represent mature RNA products of
39 transcripts. Examples of such products include
MicroRNA (miRNA),
40 circular RNA (circRNA) or piwi-interacting RNA (piRNA), and they
41 commonly play a role in gene expression.
53 # Get start and end position in the precursor transcript
54 my $start = $rnaproduct->start();
55 my $end = $rnaproduct->end();
60 package Bio::EnsEMBL::RNAProduct;
62 use vars qw($AUTOLOAD);
70 use Scalar::Util qw(weaken);
79 Arg [-SEQ_START] : The offset in the
Transcript indicating the start
80 position of the product sequence.
81 Arg [-SEQ_END] : The offset in the
Transcript indicating the end
82 position of the product sequence.
85 Arg [-STABLE_ID] : The stable identifier
for this RNAPRoduct
86 Arg [-VERSION] : The version of the stable identifier
87 Arg [-DBID] : The
internal identifier of
this RNAProduct
88 Arg [-ADAPTOR] : The RNAProductAdaptor
for this RNAProduct
89 Arg [-SEQ] : Manually sets the nucleotide sequence of
this
92 Arg [-CREATED_DATE] : the date the
RNAProduct was created
93 Arg [-MODIFIED_DATE]: the date the
RNAProduct was modified
98 Description: Constructor. Creates a
new RNAProduct object
102 Status : In Development
106 # perlcritic doesn't know about rearrange(), silence it
107 sub
new { ## no critic (Subroutines::RequireArgUnpacking)
110 my $class = ref($caller) || $caller;
115 my ($seq_start, $seq_end, $start_exon, $end_exon, $stable_id, $version, $dbID,
116 $adaptor, $seq, $created_date, $modified_date ) =
117 rearrange([
"SEQ_START",
"SEQ_END",
"START_EXON",
"END_EXON",
118 "STABLE_ID",
"VERSION",
"DBID",
"ADAPTOR",
"SEQ",
119 "CREATED_DATE",
"MODIFIED_DATE"], @_);
121 # For consistency between stable_id() and stable_id_version()
128 'start' => $seq_start,
130 'start_exon' => $start_exon,
131 'end_exon' => $end_exon,
132 'stable_id' => $stable_id,
133 'version' => $version,
136 'created_date' => $created_date,
137 'modified_date' => $modified_date,
138 'type_code' => $type_code,
141 $self->adaptor($adaptor);
147 =head2 add_Attributes
151 Example : $rnaproduct->add_Attributes($selenocysteine_attribute);
153 If you add an attribute before you retrieve any from database,
154 lazy load will be disabled.
156 Exceptions :
throw on incorrect arguments
163 my ($self, @attribs) = @_;
165 if (! exists $self->{
'attributes'}) {
166 $self->{
'attributes'} = [];
169 for my $attrib (@attribs) {
170 if (! $attrib->isa(
"Bio::EnsEMBL::Attribute")) {
171 throw(
"Argument to add_Attribute must be a Bio::EnsEMBL::Attribute");
173 push (@{$self->{
'attributes'}}, $attrib);
175 # Invalidate the current sequence string in case the new attribute is a SeqEdit
176 $self->{seq} = undef;
186 The dbEntry to be added
187 Example : $rnaproduct->add_DBEntry($xref);
188 Description: Associates a DBEntry with
this RNAProduct. Note that adding
189 DBEntries will prevent future lazy-loading of DBEntries
for this
190 RNAProduct (see get_all_DBEntries).
192 Exceptions : thrown on incorrect argument type
199 my ($self, $dbe) = @_;
201 if (!$dbe || !ref($dbe) || !$dbe->isa(
'Bio::EnsEMBL::DBEntry')) {
202 throw(
'Expected DBEntry argument');
205 $self->{
'dbentries'} ||= [];
206 push @{$self->{
'dbentries'}}, $dbe;
214 Example : $rnaproduct_cdna_end = $rnaproduct->cdna_end();
215 Description : Returns the end position of the RNAProduct in cDNA
217 Since RNAProducts
do not span multiple exons,
this is
218 simply an alias
for end().
219 Return type : Integer
234 Example : $rnaproduct_cdna_start = $rnaproduct->cdna_start();
235 Description : Returns the start position of the RNAProduct in cDNA
237 Since RNAProducts
do not span multiple exons,
this is
238 simply an alias
for start().
239 Return type : Integer
248 return $self->start();
254 Arg [1] : (optional)
string $created_date - created date to set
255 Example : $rnaproduct->created_date(
'2007-01-10 20:52:00');
256 Description: Getter/setter
for attribute created_date
267 $self->{
'created_date'} = shift;
269 return $self->{
'created_date'};
276 Description: This method returns a
string that is considered to be
277 the
'display' identifier. For RNAProducts
this is (depending on
278 availability and in
this order) the stable ID, the dbID or an
282 Caller : web drawing code
289 return $self->stable_id() || $self->dbID() ||
'';
295 Arg [1] : (optional)
int $end - end position to set
296 Example : $rnaproduct->end(39);
297 Description: Getter/setter
for the value of end, which is a position within
298 the precursor Transcript.
309 $self->{
'end'} = shift;
311 return $self->{
'end'};
318 Example : $rnaproduct->end_Exon($exon1);
319 Description: Getter/setter
for the value of end_Exon, which denotes the
320 exon at which RNAProduct ends.
322 Exceptions : thrown on wrong argument type
329 my ($self, $exon) = @_;
331 if (defined($exon)) {
334 assert_ref($exon,
'Bio::EnsEMBL::Exon');
335 $self->{
'end_exon'} = $exon;
339 # User has explicitly passed undef. Break connection to exon.
340 delete( $self->{
'end_exon'} );
343 return $self->{
'end_exon'};
350 Example : $rnaproduct_genomic_end = $rnaproduct->genomic_end();
351 Description : Returns the end position of the RNAProduct in genomic
352 coordinates on the forward strand.
353 Return type : Integer
363 if (!exists $self->{
'genomic_end'}) {
364 my $transcript = $self->transcript();
366 if ($transcript->strand() >= 0) {
367 $self->{
'genomic_end'} =
368 $transcript->start() + ($self->end() - 1);
370 $self->{
'genomic_end'} =
371 $transcript->end() - ($self->start() - 1);
375 return $self->{
'genomic_end'};
382 Example : $rnaproduct_genomic_start = $rnaproduct->genomic_start();
383 Description : Returns the start position of the RNAProduct in
384 genomic coordinates on the forward strand.
385 Return type : Integer
395 if (!exists $self->{
'genomic_start'}) {
396 my $transcript = $self->transcript();
398 if ($transcript->strand() >= 0) {
399 $self->{
'genomic_start'} =
400 $transcript->start() + ($self->start() - 1);
402 $self->{
'genomic_start'} =
403 $transcript->end() - ($self->end() - 1);
407 return $self->{
'genomic_start'};
411 =head2 get_all_Attributes
413 Arg [1] : optional
string $attrib_code
414 The code of the attribute type to retrieve values
for.
415 Example : ($n_attr) = @{$tl->get_all_Attributes(
'note')};
416 @rp_attributes = @{$rnaproduct->get_all_Attributes()};
417 Description: Gets a list of Attributes of
this RNAProduct.
418 Optionally just get Attributes
for given code.
426 sub get_all_Attributes {
427 my ($self, $attrib_code) = @_;
429 # If not cached, retrieve all of the attributes for this RNAProduct
430 if (!defined($self->{
'attributes'}) && defined($self->adaptor())) {
431 my $aa = $self->adaptor->db->get_AttributeAdaptor();
432 $self->{
'attributes'} = $aa->fetch_all_by_RNAProduct($self);
435 if (defined $attrib_code) {
436 my @results = grep { uc($_->code()) eq uc($attrib_code) }
437 @{$self->{
'attributes'}};
440 return $self->{
'attributes'};
445 =head2 get_all_DBEntries
447 Arg [1] : (optional) String, external database name,
448 SQL wildcard characters (_ and %) can be used to
451 Arg [2] : (optional) String, external_db type,
452 (
'ARRAY',
'ALT_TRANS',
'ALT_GENE',
'MISC',
'LIT',
'PRIMARY_DB_SYNONYM',
'ENSEMBL'),
453 SQL wildcard characters (_ and %) can be used to
456 Example : my @dbentries = @{ $rnaproduct->get_all_DBEntries() };
457 @dbentries = @{ $rnaproduct->get_all_DBEntries(
'Uniprot%') };
458 @dbentries = @{ $rnaproduct->get_all_DBEntries(
'%',
'ENSEMBL') };
460 Description: Retrieves DBEntries (xrefs)
for this RNAProduct.
462 This method will attempt to lazy-load DBEntries
463 from a database
if an adaptor is available and no
464 DBEntries are present on the RNAProduct (i.e. they
465 have not already been added or loaded).
474 sub get_all_DBEntries {
475 my ($self, $ex_db_exp, $ex_db_type) = @_;
477 my $cache_name =
'dbentries';
479 if (defined($ex_db_exp)) {
480 $cache_name .= $ex_db_exp;
483 if (defined($ex_db_type)) {
484 $cache_name .= $ex_db_type;
487 # If not cached, retrieve all of the xrefs for this RNAProduct
488 if (!defined($self->{$cache_name}) && defined($self->adaptor())) {
489 $self->{$cache_name} = $self->
adaptor()->
db()->get_DBEntryAdaptor()->
490 fetch_all_by_RNAProduct( $self, $ex_db_exp, $ex_db_type );
493 $self->{$cache_name} ||= [];
495 return $self->{$cache_name};
502 =head2 get_all_DBLinks
504 Arg [1] : (optional) String, database name
505 SQL wildcard characters (_ and %) can be used to
508 Arg [2] : (optional) String, external database type, can be one of
509 (
'ARRAY',
'ALT_TRANS',
'ALT_GENE',
'MISC',
'LIT',
'PRIMARY_DB_SYNONYM',
'ENSEMBL'),
510 SQL wildcard characters (_ and %) can be used to
513 Example : my @dblinks = @{ $rnaproduct->get_all_DBLinks() };
514 @dblinks = @{ $rnaproduct->get_all_DBLinks(
'mirbase%') };
515 @dblinks = @{ $rnaproduct->get_all_DBLinks(
'%',
'ENSEMBL') };
517 Description: This is here
for consistancy with the Transcript
518 and Gene classes. It is a synonym
for the
519 get_all_DBEntries() method.
521 Return type: Listref to
Bio::
EnsEMBL::DBEntry objects
528 # this is an alias, we do NOT want to unpack @_
529 sub get_all_DBLinks { ## no critic (Subroutines::RequireArgUnpacking)
531 return $self->get_all_DBEntries(@_);
535 =head2 get_all_object_xrefs
537 Arg [1] : (optional) String, external database name
539 Arg [2] : (optional) String, external_db type
541 Example : @oxrefs = @{ $rnaproduct->get_all_object_xrefs() };
543 Description: Retrieves xrefs
for this RNAProduct.
545 This method will attempt to lazy-load xrefs from a
546 database
if an adaptor is available and no xrefs
547 are present on the RNAProduct (i.e. they have not
548 already been added or loaded).
550 NB: This method is an alias
for the
551 get_all_DBentries() method.
553 Return type: Listref of
Bio::
EnsEMBL::DBEntry objects
559 # this is an alias, we do NOT want to unpack @_
560 sub get_all_object_xrefs { ## no critic (Subroutines::RequireArgUnpacking)
562 return $self->get_all_DBEntries(@_);
568 Arg [1] : String database name (optional)
569 SQL wildcard characters (_ and %) can be used to
572 Example : @xrefs = @{ $rnaproduct->get_all_xrefs() };
573 @xrefs = @{ $rnaproduct->get_all_xrefs(
'mirbase%') };
575 Description: This method is here
for consistancy with the Gene
576 and Transcript classes. It is an alias
for the
577 get_all_DBLinks() method, which in turn directly
578 calls get_all_DBEntries().
580 Return type: Listref of
Bio::
EnsEMBL::DBEntry objects
586 # this is an alias, we do NOT want to unpack @_
587 sub get_all_xrefs { ## no critic (Subroutines::RequireArgUnpacking)
589 return $self->get_all_DBLinks(@_);
595 Arg [1] : (optional)
string $modified_date - modification date to set
596 Example : $rnaproduct->modified_date(
'2007-01-10 20:52:00');
597 Description: Getter/setter
for attribute modified_date
608 $self->{
'modified_date'} = shift;
610 return $self->{
'modified_date'};
616 Example : print
"RNA length =", $rnaproduct->length();
617 Description: Retrieves the length of the nucleotide sequence represented
618 by
this RNAProduct
object.
621 Caller : webcode (protview etc.)
626 # PBP do allow homonyms as methods but perlcritic cannot, tell these
627 # apart from the forbidden ones, as stated in the documentation of the
629 sub length { ## no critic (Subroutines::ProhibitBuiltinHomonyms)
631 my $seq = $self->seq();
633 return ($seq) ? CORE::length($seq) : 0;
639 Arg [1] : Boolean $load_xrefs
640 Load (or don
't load) xrefs. Default is to load xrefs.
641 Example : $rnaproduct->load();
642 Description : The Ensembl API makes extensive use of
643 lazy-loading. Under some circumstances (e.g.,
644 when copying genes between databases), all data of
645 an object needs to be fully loaded. This method
646 loads the parts of the object that are usually
653 my ($self, $load_xrefs) = @_;
655 if ( !defined $load_xrefs ) {
662 $self->get_all_Attributes();
665 $self->get_all_DBEntries();
674 Example : print $rnaproduct->seq();
675 Description: Retrieves a string representation of the nucleotide sequence
676 of this RNAProduct. This retrieves the transcript from the
677 database and gets its sequence, or retrieves the sequence which
678 was set via the constructor/setter.
680 Exceptions : warning if the sequence is not set and cannot be retrieved from
682 Caller : webcode (protview etc.)
688 my ($self, $sequence) = @_;
690 if (defined($sequence)) {
692 $self->{'seq
'} = $sequence;
694 } elsif (!defined($self->{'seq
'})) {
696 my $tr_seq = $self->transcript()->seq();
697 if ($tr_seq->length() <= 0) {
698 throw('Got no or empty sequence from the database
');
700 $self->{'seq
'} = $tr_seq->subseq($self->{'start
'}, $self->{'end
'});
704 return ( $self->{'seq
'} // q{} );
710 Arg [1] : (optional) string $stable_id - stable ID to set
711 Example : $rnaproduct->stable_id('ENSS00090210
');
712 Description: Getter/setter for attribute stable_id.
713 Unlike stable_id_version(), setting a new stable ID does NOT
714 reset the version number.
725 $self->{'stable_id
'} = shift;
727 return $self->{'stable_id
'};
731 =head2 stable_id_version
733 Arg [1] : (optional) String - the stable ID with version to set
734 Example : $rnaproduct->stable_id("ENSS0059890.3");
735 Description: Getter/setter for stable id with version for this RNAProduct.
736 If the input string omits the version part, the version gets reset
737 to undef; use stable_id() if you want to avoid this.
745 sub stable_id_version {
748 if (my $stable_id = shift) {
749 # If there is at least one embedded period assume everything
750 # beyond the last one is the version number. This may not work for
751 # some species, if you are worried about ambiguity use stable_id() +
752 # version() explicitly.
753 my $vindex = rindex($stable_id, '.
');
755 $self->{version}) = ($vindex > 0 ?
756 (substr($stable_id, 0, $vindex),
757 substr($stable_id, $vindex + 1)) :
762 return $self->{stable_id} . ($self->{version} ? ".$self->{version}" : '');
768 Arg [1] : (optional) int $start - start position to set
769 Example : $rnaproduct->start(17);
770 Description: Getter/setter for the value of start, which is a position within
771 the precursor Transcript.
782 $self->{'start
'} = shift;
784 return $self->{'start
'};
790 Arg [1] : (optional) Bio::EnsEMBL::Exon || undef - start exon to assign
791 Example : $rnaproduct->start_Exon($exon1);
792 Description: Getter/setter for the value of start_Exon, which denotes the
793 exon at which RNAProduct starts.
794 Returntype : Bio::EnsEMBL::Exon
795 Exceptions : thrown on wrong argument type
802 my ($self, $exon) = @_;
804 if (defined($exon)) {
808 $self->{'start_exon
'} = $exon;
812 # User has explicitly passed undef. Break connection to exon.
813 delete( $self->{'start_exon
'} );
816 return $self->{'start_exon
'};
820 =head2 summary_as_hash
822 Example : $rnaproduct_summary = $rnaproduct->summary_as_hash();
823 Description : Retrieves a textual summary of this RNAProduct.
824 Not inherited from Feature.
825 Returns : hashref of arrays of descriptive strings
826 Status : Intended for internal use
830 sub summary_as_hash {
833 my $id = $self->display_id;
834 if ($self->version) {
835 $id .= "." . $self->version;
837 $summary{'id'} = $id;
838 $summary{'rnaproduct_id
'} = $id;
839 $summary{'genomic_start
'} = $self->genomic_start;
840 $summary{'genomic_end
'} = $self->genomic_end;
841 $summary{'length
'} = $self->length;
842 my $transcript = $self->transcript;
843 $summary{'Parent
'} = $transcript->display_id;
848 =head2 synchronise_attributes
850 Example : $rnaproduct->synchronise_attributes();
851 Description : Some RNAProduct attributes, e.g. stem-loop arm in case
852 of MicroRNA, use a local cache of their value for
853 convenience. Unless the corresponding setters update both
854 the cache value and the attribute (which would defeat
855 the convenience thing), we have to make sure the former
856 get propagated to the latter before storing the object
858 - if no corresponding attribute exists, create one;
859 - if there is one, update its value.
860 Class-specific maps of attributes to synchronise are
862 RNAProductTypeMapper::class_attribute_cache_map() .
864 Exceptions : throws if the object contains multiple attributes with the
865 given code and the choice which one to update is
867 Caller : RNAProductAdaptor
868 Status : At Risk (In Development)
872 sub synchronise_attributes {
875 my $attribute_cache_map = Bio::EnsEMBL::Utils::RNAProductTypeMapper::mapper()
876 ->class_attribute_cache_map(ref($self));
878 while (my ($cache_key, $attr_code) = each %{$attribute_cache_map}) {
879 my $existing_attributes = $self->get_all_Attributes($attr_code);
880 my $n_existing_attrs = scalar @{$existing_attributes};
881 if ($n_existing_attrs > 0) {
882 # At the moment we do not support multiple occurrences of target
884 if ($n_existing_attrs > 1) {
885 throw("Object has multiple '$attr_code
' attributes and we do not know"
886 . " which one to update");
889 $existing_attributes->[0]->value($self->{$cache_key});
893 # No corresponding attribute exists, most likely because we are
894 # dealing with a newly created object which has never been pushed
896 $self->add_Attributes(Bio::EnsEMBL::Attribute->new(
898 -VALUE => $self->{$cache_key},
909 Arg [1] : Transcript object (optional)
910 Description : Sets or retrieves the transcript object associated
911 with this RNAProduct object.
912 Exceptions : Throws if there is no adaptor or no dbID defined for
913 the RNAProduct object.
914 Returntype : Bio::EnsEMBL::Transcript
919 my ($self, $transcript) = @_;
921 if (defined($transcript)) {
926 weaken($self->{'transcript'}); # Avoid circular references.
930 # User has explicitly passed undef. Break connection to transcript.
934 my $adaptor = $self->{'adaptor
'};
935 if (!defined($adaptor)) {
936 throw("Adaptor not set for RNAProduct, cannot fetch its transcript");
939 my $dbID = $self->{'dbID
'};
940 if (!defined($dbID)) {
941 throw("dbID not set for RNAProduct, cannot fetch its transcript.");
945 $adaptor->db()->get_TranscriptAdaptor()
946 ->fetch_by_rnaproduct_id($dbID);
948 # Do not weaken the reference if we had to get the transcript from the
949 # database. The user is probably working on RNA products directly,
950 # not going through transcripts.
959 Example : my $rp_type_code = $rnaproduct->type_code();
960 Description: Getter for the RNAProduct type (e.g. miRNA, circRNA, ...).
961 The type is expressed as human-readable code.
962 This is somewhat redundant because similar information can
963 be obtained simply by looking at the class of the object,
964 indeed type_code is not meant to be modified independently
965 of the class. However, there are certain use cases when the
966 latter are more convenient than the former.
970 Status : In Development
976 return $self->{'type_code
'};
982 Arg [1] : (optional) string $version - version to set
983 Example : $rnaproduct->version(2);
984 Description: Getter/setter for attribute version
995 $self->{'version
'} = shift;
997 return $self->{'version
'};