Gene.pm 41.8 KB
Newer Older
1
2
=head1 LICENSE

3
  Copyright (c) 1999-2011 The European Bioinformatics Institute and
4
5
6
7
8
9
10
11
12
13
  Genome Research Limited.  All rights reserved.

  This software is distributed under a modified Apache license.
  For license details, please see

    http://www.ensembl.org/info/about/code_licence.html

=head1 CONTACT

  Please email comments or questions to the public Ensembl
14
  developers list at <dev@ensembl.org>.
15
16
17
18
19

  Questions may also be sent to the Ensembl help desk at
  <helpdesk@ensembl.org>.

=cut
Ewan Birney's avatar
Ewan Birney committed
20
21
22

=head1 NAME

23
Bio::EnsEMBL::Gene - Object representing a genes
Ewan Birney's avatar
Ewan Birney committed
24
25
26

=head1 SYNOPSIS

27
  my $gene = Bio::EnsEMBL::Gene->new(
28
29
30
31
    -START  => 123,
    -END    => 1045,
    -STRAND => 1,
    -SLICE  => $slice
32
33
34
  );

  # print gene information
35
36
37
  print("gene start:end:strand is "
      . join( ":", map { $gene->$_ } qw(start end strand) )
      . "\n" );
38
39
40
41

  # set some additional attributes
  $gene->stable_id('ENSG000001');
  $gene->description('This is the gene description');
Ewan Birney's avatar
Ewan Birney committed
42
43
44

=head1 DESCRIPTION

45
46
47
A representation of a Gene within the Ensembl system. A gene is a set of one or
more alternative transcripts.

48
=head1 METHODS
Ewan Birney's avatar
Ewan Birney committed
49
50
51

=cut

52
53
package Bio::EnsEMBL::Gene;

Ewan Birney's avatar
Ewan Birney committed
54
55
use strict;

Glenn Proctor's avatar
Glenn Proctor committed
56
use POSIX;
57
58
59
use Bio::EnsEMBL::Feature;
use Bio::EnsEMBL::Utils::Argument qw(rearrange);
use Bio::EnsEMBL::Utils::Exception qw(throw warning deprecate);
60
use Bio::EnsEMBL::Utils::Scalar qw(assert_ref);
Ewan Birney's avatar
Ewan Birney committed
61

62
use vars qw(@ISA);
63
@ISA = qw(Bio::EnsEMBL::Feature);
Ewan Birney's avatar
Ewan Birney committed
64

65
66
67

=head2 new

68
69
70
71
72
  Arg [-START]  : 
       int - start postion of the gene
  Arg [-END]    : 
       int - end position of the gene
  Arg [-STRAND] : 
73
       int - 1,-1 tehe strand the gene is on
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
  Arg [-SLICE]  : 
       Bio::EnsEMBL::Slice - the slice the gene is on
  Arg [-STABLE_ID] :
        string - the stable identifier of this gene
  Arg [-VERSION] :
        int - the version of the stable identifier of this gene
  Arg [-EXTERNAL_NAME] :
        string - the external database name associated with this gene
  Arg [-EXTERNAL_DB] :
        string - the name of the database the external name is from
  Arg [-EXTERNAL_STATUS]:
        string - the status of the external identifier
  Arg [-DISPLAY_XREF]:
        Bio::EnsEMBL::DBEntry - The external database entry that is used
        to label this gene when it is displayed.
89
90
  Arg [-TRANSCRIPTS]:
        Listref of Bio::EnsEMBL::Transcripts - this gene's transcripts
91
92
93
94
95
96
97
98
  Arg [-CREATED_DATE]:
        string - the date the gene was created
  Arg [-MODIFIED_DATE]:
        string - the date the gene was last modified
  Arg [-DESCRIPTION]:
        string - the genes description
  Arg [-BIOTYPE]:
        string - the biotype e.g. "protein_coding"
99
100
  Arg [-STATUS]:
        string - the gene status i.e. "KNOWN","NOVEL"
101
102
103
104
  Arg [-SOURCE]:
        string - the genes source, e.g. "ensembl"
  Arg [-IS_CURRENT]:
        Boolean - specifies if this is the current version of the gene
105
106
107
108
109
110
111
112
  Arg [-CANONICAL_TRANSCRIPT]:
        Bio::EnsEMBL::Transcript - the canonical transcript of this gene
  Arg [-CANONICAL_TRANSCRIPT_ID]:
        integer - the canonical transcript dbID of this gene, if the
        transcript object itself is not available.
  Arg [-CANONICAL_ANNOTATION]:
        string - canonical annotation

113
  Example    : $gene = Bio::EnsEMBL::Gene->new(...);
114
115
116
117
  Description: Creates a new gene object
  Returntype : Bio::EnsEMBL::Gene
  Exceptions : none
  Caller     : general
118
  Status     : Stable
119
120

=cut
Ewan Birney's avatar
Ewan Birney committed
121

Arne Stabenau's avatar
Arne Stabenau committed
122
sub new {
123
  my $caller = shift;
124

125
126
  my $class = ref($caller) || $caller;
  my $self = $class->SUPER::new(@_);
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
  my (
    $stable_id,               $version,
    $external_name,           $type,
    $external_db,             $external_status,
    $display_xref,            $description,
    $transcripts,             $created_date,
    $modified_date,           $confidence,
    $biotype,                 $source,
    $status,                  $is_current,
    $canonical_transcript_id, $canonical_transcript,
    $canonical_annotation
    )
    = rearrange( [
      'STABLE_ID',               'VERSION',
      'EXTERNAL_NAME',           'TYPE',
      'EXTERNAL_DB',             'EXTERNAL_STATUS',
      'DISPLAY_XREF',            'DESCRIPTION',
      'TRANSCRIPTS',             'CREATED_DATE',
      'MODIFIED_DATE',           'CONFIDENCE',
      'BIOTYPE',                 'SOURCE',
      'STATUS',                  'IS_CURRENT',
      'CANONICAL_TRANSCRIPT_ID', 'CANONICAL_TRANSCRIPT',
      'CANONICAL_ANNOTATION'
    ],
    @_
    );
153

154

155
156
157
158
  if ($transcripts) {
    $self->{'_transcript_array'} = $transcripts;
    $self->recalculate_coordinates();
  }
159

160
161
162
  $self->stable_id($stable_id);
  $self->version($version);
  $self->{'created_date'}  = $created_date;
163
164
  $self->{'modified_date'} = $modified_date;

165
166
167
168
169
170
171
  $self->external_name($external_name) if ( defined $external_name );
  $self->external_db($external_db)     if ( defined $external_db );
  $self->external_status($external_status)
    if ( defined $external_status );
  $self->display_xref($display_xref) if ( defined $display_xref );
  $self->biotype($type)              if ( defined $type );
  $self->biotype($biotype)           if ( defined $biotype );
172
  $self->description($description);
173
174
175
176
  $self->status($confidence);    # incase old naming is used.
      # kept to ensure routine is backwards compatible.
  $self->status($status);    # add new naming
  $self->source($source);
177
178
179
180

  # default to is_current
  $is_current = 1 unless (defined($is_current));
  $self->{'is_current'} = $is_current;
181

182
183
184
185
186
187
188
189
190
191
192
  # Add the canonical transcript if we were given one, otherwise add the
  # canonical transcript internal ID if we were given one.
  if ( defined($canonical_transcript) ) {
    $self->canonical_transcript($canonical_transcript);
  } elsif ( defined($canonical_transcript_id) ) {
    $self->{'canonical_transcript_id'} = $canonical_transcript_id;
  }

  $self->canonical_annotation($canonical_annotation)
    if ( defined $canonical_annotation );

193
  return $self;
194
195
196
}


197
198
=head2 is_known

199
200
201
  Example    : print "Gene ".$gene->stable_id." is KNOWN\n" if $gene->is_known;
  Description: Returns TRUE if this gene has a status of 'KNOWN'
  Returntype : TRUE if known, FALSE otherwise
Arne Stabenau's avatar
Arne Stabenau committed
202
203
  Exceptions : none
  Caller     : general
204
  Status     : Stable
205
206
207

=cut

Arne Stabenau's avatar
Arne Stabenau committed
208

209
sub is_known{
210
  my $self = shift;
211
  return ( $self->{'status'} eq "KNOWN" );
212
213
214
}


215
216
=head2 external_name

217
218
219
220
  Arg [1]    : (optional) String - the external name to set
  Example    : $gene->external_name('BRCA2');
  Description: Getter/setter for attribute external_name.
  Returntype : String or undef
Arne Stabenau's avatar
Arne Stabenau committed
221
  Exceptions : none
222
  Caller     : general
223
  Status     : Stable
224
225
226
227

=cut

sub external_name {
228
  my  $self  = shift;
229

230
  $self->{'external_name'} = shift if (@_);
231

232
  if (defined $self->{'external_name'}) {
233
    return $self->{'external_name'};
234
235
  }

236
  my $display_xref = $self->display_xref();
237

238
239
  if (defined $display_xref) {
    return $display_xref->display_id();
240
241
242
  } else {
    return undef;
  }
243
244
}

Arne Stabenau's avatar
Arne Stabenau committed
245

246
247
=head2 status

248
249
250
251
  Arg [1]    : (optional) String - status to set
  Example    : $gene->status('KNOWN');
  Description: Getter/setter for attribute status
  Returntype : String
252
253
254
255
256
257
258
259
260
261
262
263
  Exceptions : none
  Caller     : general
  Status     : Medium Risk

=cut

sub status {
   my $self = shift;
  $self->{'status'} = shift if( @_ );
  return $self->{'status'};
}

264
265
266

=head2 source

267
268
269
270
  Arg [1]    : (optional) String - the source to set
  Example    : $gene->source('ensembl');
  Description: Getter/setter for attribute source
  Returntype : String
271
272
  Exceptions : none
  Caller     : general
273
  Status     : Stable
274
275
276
277
278
279
280
281
282
283

=cut

sub source {
  my $self = shift;
  $self->{'source'} = shift if( @_ );
  return ( $self->{'source'} || "ensembl" );
}


Arne Stabenau's avatar
Arne Stabenau committed
284
285
=head2 external_db	

286
287
288
  Arg [1]    : (optional) String - name of external db to set
  Example    : $gene->external_db('HGNC');
  Description: Getter/setter for attribute external_db. The db is the one that 
289
               belongs to the external_name.  
290
  Returntype : String
Arne Stabenau's avatar
Arne Stabenau committed
291
292
  Exceptions : none
  Caller     : general
293
  Status     : Stable
Arne Stabenau's avatar
Arne Stabenau committed
294
295
296

=cut

297
sub external_db {
298
  my $self = shift;
299

300
  $self->{'external_db'} = shift if( @_ );
301

302
303
  if( exists $self->{'external_db'} ) {
    return $self->{'external_db'};
304
305
  }

306
  my $display_xref = $self->display_xref();
307

308
309
310
311
312
  if( defined $display_xref ) {
    return $display_xref->dbname()
  } else {
    return undef;
  }
313
}
Graham McVicker's avatar
Graham McVicker committed
314

315

316
317
=head2 external_status

318
319
320
  Arg [1]    : (optional) String - status of the external db
  Example    : $gene->external_status('KNOWNXREF');
  Description: Getter/setter for attribute external_status. The status of
321
               the external db of the one that belongs to the external_name.
322
  Returntype : String
323
324
  Exceptions : none
  Caller     : general
325
  Status     : Stable
326
327
328
329

=cut

sub external_status {
330
  my $self = shift;
331

332
  $self->{'_ext_status'} = shift if ( @_ );
333
334
335
336
337
338
339
340
341
342
343
344
  return $self->{'_ext_status'} if exists $self->{'_ext_status'};

  my $display_xref = $self->display_xref();

  if( defined $display_xref ) {
    return $display_xref->status()
  } else {
    return undef;
  }
}


Philip Lijnzaad's avatar
Philip Lijnzaad committed
345
=head2 description
346

347
348
349
350
  Arg [1]    : (optional) String - the description to set
  Example    : $gene->description('This is the gene\'s description');
  Description: Getter/setter for gene description
  Returntype : String
351
  Exceptions : none
Arne Stabenau's avatar
Arne Stabenau committed
352
  Caller     : general
353
  Status     : Stable
354
355
356

=cut

Philip Lijnzaad's avatar
Philip Lijnzaad committed
357
sub description {
358
359
360
    my $self = shift;
    $self->{'description'} = shift if( @_ );
    return $self->{'description'};
361
362
}

363

364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
=head2 equals

  Arg [1]       : Bio::EnsEMBL::Gene gene
  Example       : if ($geneA->equals($geneB)) { ... }
  Description   : Compares two genes for equality.
                  The test for eqality goes through the following list
                  and terminates at the first true match:

                  1. If Bio::EnsEMBL::Feature::equals() returns false,
                     then the genes are *not* equal.
                  2. If the biotypes differ, then the genes are *not*
                     equal.
                  3. If both genes have stable IDs: if these are the
                     same, the genes are equal, otherwise not.
                  4. If both genes have the same number of transcripts
                     and if these are (when compared pair-wise sorted by
                     start-position and length) the same, then they are
                     equal, otherwise not.

  Return type   : Boolean (0, 1)

  Exceptions    : Thrown if a non-gene is passed as the argument.

=cut

sub equals {
  my ( $self, $gene ) = @_;

392
  if ( $self eq $gene ) { return 1 }
Andy Yates's avatar
Andy Yates committed
393
  if ( ! defined $gene ) { return 0 }
394

395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
  assert_ref( $gene, 'Bio::EnsEMBL::Gene' );

  my $feature_equals = $self->SUPER::equals($gene);
  if ( defined($feature_equals) && $feature_equals == 0 ) {
    return 0;
  }

  if ( $self->biotype() ne $gene->biotype() ) {
    return 0;
  }

  if ( defined( $self->stable_id() ) && defined( $gene->stable_id() ) )
  {
    if ( $self->stable_id() eq $gene->stable_id() ) {
      return 1;
    } else {
      return 0;
    }
  }

  my @self_transcripts = sort {
         $a->start() <=> $b->start()
      || $a->length() <=> $b->length()
  } @{ $self->get_all_Transcripts() };
  my @gene_transcripts = sort {
         $a->start() <=> $b->start()
      || $a->length() <=> $b->length()
  } @{ $gene->get_all_Transcripts() };

  if ( scalar(@self_transcripts) != scalar(@gene_transcripts) ) {
    return 0;
  }

  while (@self_transcripts) {
    my $self_transcript = shift(@self_transcripts);
    my $gene_transcript = shift(@gene_transcripts);

    if ( !$self_transcript->equals($gene_transcript) ) {
      return 0;
    }
  }

  return 1;
} ## end sub equals

440
441
442
443
444
445
=head2 canonical_transcript

  Arg [1]    : (optional) Bio::EnsEMBL::Transcipt - canonical_transcript object
  Example    : $gene->canonical_transcript($canonical_transcript);
  Description: Getter/setter for the canonical_transcript
  Returntype : Bio::EnsEMBL::Transcript
446
  Exceptions : Throws if argument is not a transcript object.
447
448
449
450
451
452
  Caller     : general
  Status     : Stable

=cut

sub canonical_transcript {
453
454
455
456
457
  my ( $self, $transcript ) = @_;

  if ( defined($transcript) ) {
    # We're attaching a new canonical transcript.

458
    assert_ref( $transcript, 'Bio::EnsEMBL::Transcript' );
459

460
461
462
463
464
465
    # If there's already a canonical transcript, make sure it doesn't
    # think it's still canonical.
    if ( defined( $self->{'canonical_transcript'} ) ) {
      $self->{'canonical_transcript'}->is_canonical(0);
    }

466
467
    $self->{'canonical_transcript'}    = $transcript;
    $self->{'canonical_transcript_id'} = $transcript->dbID();
468

469
    $transcript->is_canonical(1);
470

471
  } elsif (   !defined( $self->{'canonical_transcript'} )
472
473
            && defined( $self->{'canonical_transcript_id'} )
            && $self->{'canonical_transcript_id'} != 0 )
474
475
476
477
  {
    # We have not attached a canoncical transcript, but we have the dbID
    # of one.

478
479
480
481
    if ( defined( $self->adaptor() ) ) {
      my $transcript_adaptor =
        $self->adaptor()->db()->get_TranscriptAdaptor();

482
      my $canonical_transcript =
483
        $transcript_adaptor->fetch_by_dbID(
484
                                   $self->{'canonical_transcript_id'} );
485

486
487
488
489
      if ( defined($canonical_transcript) ) {
        # Recusive call...
        $self->canonical_transcript($canonical_transcript);
      }
490

491
    } else {
492
493
      warning(   "Gene has no adaptor "
               . "when trying to fetch canonical transcript." );
494
    }
495

496
  } ## end elsif ( !defined( $self->...))
497
498
499

  return $self->{'canonical_transcript'};
} ## end sub canonical_transcript
500
501
502
503
504


=head2 canonical_annotation

  Arg [1]    : (optional) String - canonical_annotation
505
  Example    : $gene->canonical_annotation('This is the canonical_annotation');
506
507
508
509
510
511
512
513
514
515
  Description: Getter/setter for the canonical_annotation
  Returntype : String
  Exceptions : none
  Caller     : general
  Status     : Stable

=cut

sub canonical_annotation {
    my $self = shift;
Daniel Rios's avatar
Daniel Rios committed
516
    $self->{'canonical_annotation'} = shift if( @_ );
517
518
519
    return $self->{'canonical_annotation'};
}

Patrick Meidl's avatar
Patrick Meidl committed
520
521
=head2 get_all_Attributes

522
523
  Arg [1]    : (optional) String $attrib_code
               The code of the attribute type to retrieve values for
Patrick Meidl's avatar
Patrick Meidl committed
524
  Example    : my ($author) = @{ $gene->get_all_Attributes('author') };
525
               my @gene_attributes = @{ $gene->get_all_Attributes };
Patrick Meidl's avatar
Patrick Meidl committed
526
  Description: Gets a list of Attributes of this gene.
527
528
               Optionally just get Attributes for given code.
  Returntype : Listref of Bio::EnsEMBL::Attribute
Patrick Meidl's avatar
Patrick Meidl committed
529
530
531
532
533
534
535
536
537
538
539
  Exceptions : warning if gene does not have attached adaptor and attempts lazy
               load.
  Caller     : general
  Status     : Stable

=cut

sub get_all_Attributes {
  my $self = shift;
  my $attrib_code = shift;

540
541
  if ( ! exists $self->{'attributes' } ) {
    if (!$self->adaptor() ) {
Patrick Meidl's avatar
Patrick Meidl committed
542
543
544
545
546
547
548
      return [];
    }

    my $attribute_adaptor = $self->adaptor->db->get_AttributeAdaptor();
    $self->{'attributes'} = $attribute_adaptor->fetch_all_by_Gene($self);
  }

549
  if ( defined $attrib_code ) {
Patrick Meidl's avatar
Patrick Meidl committed
550
551
552
553
554
555
556
557
558
559
560
    my @results = grep { uc($_->code()) eq uc($attrib_code) }
    @{$self->{'attributes'}};
    return \@results;
  } else {
    return $self->{'attributes'};
  }
}


=head2 add_Attributes

561
562
563
564
  Arg [1-N]  : list of Bio::EnsEMBL::Attribute's @attribs
               Attribute(s) to add
  Example    : my $attrib = Bio::EnsEMBL::Attribute->new(...);
               $gene->add_Attributes($attrib);
Patrick Meidl's avatar
Patrick Meidl committed
565
  Description: Adds an Attribute to the Gene. If you add an attribute before
566
               you retrieve any from database, lazy loading will be disabled.
Patrick Meidl's avatar
Patrick Meidl committed
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
  Returntype : none
  Exceptions : throw on incorrect arguments
  Caller     : general
  Status     : Stable

=cut

sub add_Attributes {
  my $self = shift;
  my @attribs = @_;

  if( ! exists $self->{'attributes'} ) {
    $self->{'attributes'} = [];
  }

  for my $attrib ( @attribs ) {
    if( ! $attrib->isa( "Bio::EnsEMBL::Attribute" )) {
     throw( "Argument to add_Attribute has to be an Bio::EnsEMBL::Attribute" );
    }
    push( @{$self->{'attributes'}}, $attrib );
  }

  return;
}

592

593
594
595
596
=head2 add_DBEntry

  Arg [1]    : Bio::EnsEMBL::DBEntry $dbe
               The dbEntry to be added
597
598
  Example    : my $dbe = Bio::EnsEMBL::DBEntery->new(...);
               $gene->add_DBEntry($dbe);
599
600
601
602
603
604
  Description: Associates a DBEntry with this gene. Note that adding DBEntries
               will prevent future lazy-loading of DBEntries for this gene
               (see get_all_DBEntries).
  Returntype : none
  Exceptions : thrown on incorrect argument type
  Caller     : general
605
  Status     : Stable
606
607
608
609
610
611
612
613

=cut

sub add_DBEntry {
  my $self = shift;
  my $dbe = shift;

  unless($dbe && ref($dbe) && $dbe->isa('Bio::EnsEMBL::DBEntry')) {
614
    throw('Expected DBEntry argument');
615
616
617
618
619
620
621
622
  }

  $self->{'dbentries'} ||= [];
  push @{$self->{'dbentries'}}, $dbe;
}


=head2 get_all_DBEntries
623

624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
  Arg [1]    : (optional) String, external database name

  Arg [2]    : (optional) String, external_db type

  Example    : @dbentries = @{ $gene->get_all_DBEntries() };

  Description: Retrieves DBEntries (xrefs) for this gene.  This does
               *not* include DBEntries that are associated with the
               transcripts and corresponding translations of this
               gene (see get_all_DBLinks()).

               This method will attempt to lazy-load DBEntries
               from a database if an adaptor is available and no
               DBEntries are present on the gene (i.e. they have not
               already been added or loaded).

  Return type: Listref of Bio::EnsEMBL::DBEntry objects
641
  Exceptions : none
642
  Caller     : get_all_DBLinks, GeneAdaptor::store
643
  Status     : Stable
644
645
646

=cut

647
sub get_all_DBEntries {
648
649
  my ( $self, $db_name_exp, $ex_db_type ) = @_;

650
  my $cache_name = 'dbentries';
651

652
  if ( defined($db_name_exp) ) {
653
654
    $cache_name .= $db_name_exp;
  }
655
656

  if ( defined($ex_db_type) ) {
Ian Longden's avatar
Ian Longden committed
657
    $cache_name .= $ex_db_type;
658
  }
659

660
  # if not cached, retrieve all of the xrefs for this gene
661
662
663
  if ( !defined( $self->{$cache_name} ) && defined( $self->adaptor() ) )
  {
    $self->{$cache_name} =
664
665
      $self->adaptor()->db()->get_DBEntryAdaptor()
      ->fetch_all_by_Gene( $self, $db_name_exp, $ex_db_type );
666
  }
667

668
  $self->{$cache_name} ||= [];
669

670
  return $self->{$cache_name};
671
} ## end sub get_all_DBEntries
672

673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
=head2 get_all_object_xrefs

  Arg [1]    : (optional) String, external database name

  Arg [2]    : (optional) String, external_db type

  Example    : @oxrefs = @{ $gene->get_all_object_xrefs() };

  Description: Retrieves xrefs for this gene.  This does *not*
               include xrefs that are associated with the
               transcripts or corresponding translations of this
               gene (see get_all_xrefs()).

               This method will attempt to lazy-load xrefs from a
               database if an adaptor is available and no xrefs are
               present on the gene (i.e. they have not already been
               added or loaded).

691
692
                NB: This method is an alias for the
                    get_all_DBentries() method.
693
694
695
696
697
698
699

  Return type: Listref of Bio::EnsEMBL::DBEntry objects

  Status     : Stable

=cut

700
701
702
703
sub get_all_object_xrefs {
  my $self = shift;
  return $self->get_all_DBEntries(@_);
}
704

705
=head2 get_all_DBLinks
706

707
708
  Arg [1]    : String database name (optional)
               SQL wildcard characters (_ and %) can be used to
Glenn Proctor's avatar
Glenn Proctor committed
709
               specify patterns.
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730

  Example    : @dblinks = @{ $gene->get_all_DBLinks() };
               @dblinks = @{ $gene->get_all_DBLinks('Uniprot%') };

  Description: Retrieves *all* related DBEntries for this gene. This
               includes all DBEntries that are associated with the
               transcripts and corresponding translations of this
               gene.

               If you only want to retrieve the DBEntries
               associated with the gene (and not the transcript
               and translations) then you should use the
               get_all_DBEntries() call instead.

               Note: Each entry may be listed more than once.  No
               uniqueness checks are done.  Also if you put in an
               incorrect external database name no checks are done
               to see if this exists, you will just get an empty
               list.

  Return type: Listref of Bio::EnsEMBL::DBEntry objects
Arne Stabenau's avatar
Arne Stabenau committed
731
732
  Exceptions : none
  Caller     : general
733
  Status     : Stable
734
735
736

=cut

737
sub get_all_DBLinks {
738
  my ( $self, $db_name_exp, $ex_db_type ) = @_;
739

740
741
  my @links =
    @{ $self->get_all_DBEntries( $db_name_exp, $ex_db_type ) };
742

743
744
745
746
747
748
  # Add all of the transcript and translation xrefs to the return list.
  foreach my $transcript ( @{ $self->get_all_Transcripts() } ) {
    push( @links,
          @{$transcript->get_all_DBLinks( $db_name_exp, $ex_db_type ) }
    );
  }
749

750
  return \@links;
751
}
752

753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
=head2 get_all_xrefs

  Arg [1]    : String database name (optional)
               SQL wildcard characters (_ and %) can be used to
               specify patterns.

  Example    : @xrefs = @{ $gene->get_all_xrefs() };
               @xrefs = @{ $gene->get_all_xrefs('Uniprot%') };

  Description: Retrieves *all* related xrefs for this gene.  This
               includes all xrefs that are associated with the
               transcripts and corresponding translations of this
               gene.

               If you want to retrieve the xrefs associated
               with only the gene (and not the transcript
               or translations) then you should use the
               get_all_object_xrefs() method instead.

               Note: Each entry may be listed more than once.  No
               uniqueness checks are done.  Also if you put in an
               incorrect external database name no checks are done
               to see if this exists, you will just get an empty
               list.

                NB: This method is an alias for the
                    get_all_DBLinks() method.

  Return type: Listref of Bio::EnsEMBL::DBEntry objects

  Status     : Stable

=cut

787
788
789
790
sub get_all_xrefs {
  my $self = shift;
  return $self->get_all_DBLinks(@_);
}
791

792
793
=head2 get_all_Exons

794
795
796
  Example    : my @exons = @{ $gene->get_all_Exons };
  Description: Returns a set of all the exons associated with this gene.
  Returntype : Listref of Bio::EnsEMBL::Exon objects
Arne Stabenau's avatar
Arne Stabenau committed
797
798
  Exceptions : none
  Caller     : general
799
  Status     : Stable
800
801
802

=cut

Arne Stabenau's avatar
Arne Stabenau committed
803

804
sub get_all_Exons {
805
  my $self = shift;
806

807
808
  my %h;
  my @out = ();
Graham McVicker's avatar
Graham McVicker committed
809

810
811
812
813
814
  foreach my $trans ( @{$self->get_all_Transcripts} ) {
    foreach my $e ( @{$trans->get_all_Exons} ) {
      $h{$e->start()."-".$e->end()."-".$e->strand()."-".$e->phase()."-".$e->end_phase()} = $e;
    }
  }
815

816
  push @out, values %h;
817

818
  return \@out;
Graham McVicker's avatar
Graham McVicker committed
819
}
820

821

Will Spooner's avatar
Will Spooner committed
822
=head2 get_all_homologous_Genes
823

824
825
  Description: Queries the Ensembl Compara database and retrieves all
               Genes from other species that are orthologous.
826
827
828
               REQUIRES properly setup Registry conf file. Meaning that
               one of the aliases for each core db has to be "Genus species"
               e.g. "Homo sapiens" (as in the name column in genome_db table
829
               in the compara database).
830
831
832
  Returntype : listref [
                        Bio::EnsEMBL::Gene,
                        Bio::EnsEMBL::Compara::Homology,
833
                        string $species # needed as cannot get spp from Gene 
834
835
836
                       ]
  Exceptions : none
  Caller     : general
837
  Status     : Stable
838
839
840

=cut

841
sub get_all_homologous_Genes {
842
843
844
845
846
847
848
849
850
851
  my $self = shift;

  if( exists( $self->{'homologues'} ) ){
    return $self->{'homologues'};
  }
  $self->{'homologues'} = [];

  # TODO: Find a robust way of retrieving compara dba directly.
  # For now look through all DBAs
  my $compara_dba;
852
  foreach my $dba( @{Bio::EnsEMBL::Registry->get_all_DBAdaptors} ){
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
    if( $dba->isa('Bio::EnsEMBL::Compara::DBSQL::DBAdaptor') ){
      $compara_dba = $dba;
      last;
    }
  }
  unless( $compara_dba ){
    warning("No compara in Bio::EnsEMBL::Registry");
    return $self->{'homologues'};
  }

  # Get the compara 'member' corresponding to self
  my $member_adaptor   = $compara_dba->get_adaptor('Member');
  my $query_member = $member_adaptor->fetch_by_source_stable_id
      ("ENSEMBLGENE",$self->stable_id);
  unless( $query_member ){ return $self->{'homologues'} };

  # Get the compara 'homologies' corresponding to 'member'
  my $homology_adaptor = $compara_dba->get_adaptor('Homology');
871
  my @homolos = @{$homology_adaptor->fetch_all_by_Member($query_member)};
872
873
874
875
876
877
878
879
  unless( scalar(@homolos) ){ return $self->{'homologues'} };

  # Get the ensembl 'genes' corresponding to 'homologies'
  foreach my $homolo( @homolos ){
    foreach my $member_attrib( @{$homolo->get_all_Member_Attribute} ){
      my ($member, $attrib) = @{$member_attrib};
      my $hstable_id = $member->stable_id;
      next if ($hstable_id eq $query_member->stable_id); # Ignore self     
880
881
      my $hgene = undef;
      eval { $hgene = $member->get_Gene;} ;
882
883
884
885
      unless( $hgene ){
        # Something up with DB. Create a new gene is best we can do
        $hgene = Bio::EnsEMBL::Gene->new
            ( -stable_id=>$hstable_id,
Will Spooner's avatar
Will Spooner committed
886
              -description=>$member->description, );
887
888
889
890
891
892
893
      }
      my $hspecies = $member->genome_db->name;
      push @{$self->{'homologues'}}, [$hgene,$homolo,$hspecies];
    }
  }
  return $self->{'homologues'};
}
Arne Stabenau's avatar
Arne Stabenau committed
894

895
896
897

=head2 biotype

898
899
900
901
  Arg [1]    : (optional) String - the biotype to set
  Example    : $gene->biotype("protein_coding");
  Description: Getter/setter for the attribute biotype
  Returntype : String
902
903
  Exceptions : none
  Caller     : general
904
  Status     : Stable
905
906

=cut
907

908
909
sub biotype {
  my $self = shift;
910

911
912
  $self->{'biotype'} = shift if( @_ );
  return ( $self->{'biotype'} || "protein_coding" );
Arne Stabenau's avatar
Arne Stabenau committed
913
914
}

915

Arne Stabenau's avatar
Arne Stabenau committed
916
=head2 add_Transcript
Ewan Birney's avatar
Ewan Birney committed
917

918
919
920
921
922
923
924
  Arg [1]    : Bio::EnsEMBL::Transcript $trans
               The transcript to add to the gene
  Example    : my $transcript = Bio::EnsEMBL::Transcript->new(...);
               $gene->add_Transcript($transcript);
  Description: Adds another Transcript to the set of alternatively
               spliced Transcripts of this gene. If it shares exons 
               with another Transcript, these should be object-identical.
Arne Stabenau's avatar
Arne Stabenau committed
925
926
927
  Returntype : none
  Exceptions : none
  Caller     : general
928
  Status     : Stable
Ewan Birney's avatar
Ewan Birney committed
929
930
931

=cut

932
sub add_Transcript {
933
   my ($self, $trans) = @_;
Ewan Birney's avatar
Ewan Birney committed
934

935
936
937
938
939
   if( !ref $trans || ! $trans->isa("Bio::EnsEMBL::Transcript") ) {
       throw("$trans is not a Bio::EnsEMBL::Transcript!");
   }

   $self->{'_transcript_array'} ||= [];
940
   push(@{$self->{'_transcript_array'}},$trans);
941

942
   $self->recalculate_coordinates();
Ewan Birney's avatar
Ewan Birney committed
943
944
945
}


946
947
=head2 get_all_Transcripts

948
949
950
  Example    : my @transcripts = @{ $gene->get_all_Transcripts };
  Description: Returns the Transcripts in this gene.
  Returntype : Listref of Bio::EnsEMBL::Transcript objects
Arne Stabenau's avatar
Arne Stabenau committed
951
952
  Exceptions : none
  Caller     : general
953
  Status     : Stable
Ewan Birney's avatar
Ewan Birney committed
954
955
956

=cut

957
sub get_all_Transcripts {
958
  my $self = shift;
Ewan Birney's avatar
Ewan Birney committed
959

960
961
962
963
964
965
966
  if( ! exists $self->{'_transcript_array'} ) {
    if( defined $self->adaptor() ) {
      my $ta = $self->adaptor()->db()->get_TranscriptAdaptor();
      my $transcripts = $ta->fetch_all_by_Gene( $self );
      $self->{'_transcript_array'} = $transcripts;
    }
  }
Graham McVicker's avatar
Graham McVicker committed
967
  return $self->{'_transcript_array'};
Ewan Birney's avatar
Ewan Birney committed
968
969
}

970

971
=head2 get_all_alt_alleles
972

973
974
975
976
977
  Example    : my @alt_genes = @{ $gene->get_all_alt_alleles };
               foreach my $alt_gene (@alt_genes) {
                 print "Alternate allele: " . $alt_gene->stable_id() . "\n";
               }
  Description: Returns a listref of Gene objects that represent this Gene on
978
               an alternative haplotype. Empty list if there is no such
979
980
               Gene (eg there is no overlapping haplotype).
  Returntype : listref of Bio::EnsEMBL::Gene objects
Arne Stabenau's avatar
Arne Stabenau committed
981
982
  Exceptions : none
  Caller     : general
983
  Status     : Stable
984
985
986

=cut

987
988
989
990
991
sub get_all_alt_alleles {
  my $self = shift;
  my $result = $self->adaptor()->fetch_all_alt_alleles( $self );
  return $result;
}
Arne Stabenau's avatar
Arne Stabenau committed
992

993

994
=head2 version
995

996
  Arg [1]    : (optional) Int
997
               A version number for the stable_id
998
999
1000
  Example    : $gene->version(2);
  Description: Getter/setter for version number
  Returntype : Int
1001
1002
  Exceptions : none
  Caller     : general
1003
  Status     : Stable
1004

1005
=cut
1006

1007
sub version {
1008
1009
1010
  my $self = shift;
  $self->{'version'} = shift if(@_);
  return $self->{'version'};
1011
1012
1013
}


1014
=head2 stable_id
1015

1016
1017
1018
1019
  Arg [1]    : (optional) String - the stable ID to set
  Example    : $gene->stable_id("ENSG0000000001");
  Description: Getter/setter for stable id for this gene.
  Returntype : String
Arne Stabenau's avatar
Arne Stabenau committed
1020
1021
  Exceptions : none
  Caller     : general
1022
  Status     : Stable
1023
1024
1025

=cut

1026
sub stable_id {
1027
1028
1029
  my $self = shift;
  $self->{'stable_id'} = shift if(@_);
  return $self->{'stable_id'};
1030
1031
}

1032

1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
=head2 is_current

  Arg [1]    : Boolean $is_current
  Example    : $gene->is_current(1)
  Description: Getter/setter for is_current state of this gene.
  Returntype : Int
  Exceptions : none
  Caller     : general
  Status     : Stable

=cut

sub is_current {
  my $self = shift;
  $self->{'is_current'} = shift if (@_);
  return $self->{'is_current'};
}


1052
1053
=head2 created_date

1054
1055
  Arg [1]    : (optional) String - created date to set (as a UNIX time int)
  Example    : $gene->created_date('1141948800');
1056
1057
  Description: Getter/setter for attribute created_date
  Returntype : String
1058
1059
1060
1061
1062
1063
  Exceptions : none
  Caller     : general
  Status     : Stable

=cut

1064
1065
1066
1067
1068
1069
sub created_date {
  my $self = shift;
  $self->{'created_date'} = shift if ( @_ );
  return $self->{'created_date'};
}

1070

1071
1072
=head2 modified_date

1073
1074
  Arg [1]    : (optional) String - modified date to set (as a UNIX time int)
  Example    : $gene->modified_date('1141948800');
1075
1076
  Description: Getter/setter for attribute modified_date
  Returntype : String
1077
1078
1079
1080
1081
1082
  Exceptions : none
  Caller     : general
  Status     : Stable

=cut

1083
1084
1085
1086
1087
1088
1089
sub modified_date {
  my $self = shift;
  $self->{'modified_date'} = shift if ( @_ );
  return $self->{'modified_date'};
}


1090
=head2 transform
Arne Stabenau's avatar
Arne Stabenau committed
1091

1092
1093
1094
1095
1096
  Arg [1]    : String - coordinate system name to transform to
  Arg [2]    : String - coordinate system version
  Example    : my $new_gene = $gene->transform('supercontig');
  Description: Moves this gene to the given coordinate system. If this gene has
               Transcripts attached, they move as well.
1097
  Returntype : Bio::EnsEMBL::Gene
1098
  Exceptions : throw on wrong parameters
Arne Stabenau's avatar
Arne Stabenau committed
1099
  Caller     : general
1100
  Status     : Stable
1101
1102
1103

=cut

1104
1105
sub transform {
  my $self = shift;
1106

1107
  # catch for old style transform calls
Ian Longden's avatar
Ian Longden committed
1108
  if( !@_  || ( ref $_[0] && ($_[0]->isa( "Bio::EnsEMBL::Slice" ) or $_[0]->isa( "Bio::EnsEMBL::LRGSlice" )) )) {
1109
1110
1111
    deprecate('Calling transform without a coord system name is deprecated.');
    return $self->_deprecated_transform(@_);
  }
1112

1113
1114
1115
1116
  my $new_gene = $self->SUPER::transform(@_);

  if ( !defined($new_gene) ) {
    # check if this gene projects at all to requested coord system,
1117
    #  if not we are done.
1118
1119
    my @segments = @{ $self->project(@_) };
    if ( !@segments ) {
1120
1121
      return undef;
    }
1122
1123
1124
1125