comparison variant_effect_predictor/Bio/EnsEMBL/DBSQL/ExonAdaptor.pm @ 0:1f6dce3d34e0

Uploaded
author mahtabm
date Thu, 11 Apr 2013 02:01:53 -0400
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:1f6dce3d34e0
1 =head1 LICENSE
2
3 Copyright (c) 1999-2012 The European Bioinformatics Institute and
4 Genome Research Limited. All rights reserved.
5
6 This software is distributed under a modified Apache license.
7 For license details, please see
8
9 http://www.ensembl.org/info/about/code_licence.html
10
11 =head1 CONTACT
12
13 Please email comments or questions to the public Ensembl
14 developers list at <dev@ensembl.org>.
15
16 Questions may also be sent to the Ensembl help desk at
17 <helpdesk@ensembl.org>.
18
19 =cut
20
21 =head1 NAME
22
23 Bio::EnsEMBL::DBSQL::ExonAdaptor - An adaptor responsible for the retrieval and
24 storage of exon objects
25
26 =head1 SYNOPSIS
27
28 my $exon_adaptor = $registry->get_adaptor( 'Human', 'Core', 'Exon' );
29
30 my $exon = $exon_adaptor->fetch_by_dbID($dbID);
31
32 =head1 DESCRIPTION
33
34 The ExonAdaptor is responsible for retrieving and storing Exon objects
35 from an Ensembl database. Most of the ExonAdaptor functionality is
36 inherited from the B<Bio::EnsEMBL::DBSQL::BaseFeatureAdaptor> class.
37
38 =head1 METHODS
39
40 =cut
41
42 package Bio::EnsEMBL::DBSQL::ExonAdaptor;
43
44 use strict;
45
46 use Bio::EnsEMBL::DBSQL::BaseFeatureAdaptor;
47 use Bio::EnsEMBL::Exon;
48 use Bio::EnsEMBL::Utils::Exception qw( warning throw deprecate );
49
50 use vars qw( @ISA );
51 @ISA = qw( Bio::EnsEMBL::DBSQL::BaseFeatureAdaptor );
52
53
54 #_tables
55 #
56 # Arg [1] : none
57 # Example : none
58 # Description: PROTECTED implementation of superclass abstract method
59 # returns the names, aliases of the tables to use for queries
60 # Returntype : list of listrefs of strings
61 # Exceptions : none
62 # Caller : internal
63
64 sub _tables {
65 my $self = shift;
66
67 # Allow the table definition to be overridden by certain methods.
68 if ( defined( $self->{'tables'} ) ) {
69 return @{ $self->{'tables'} };
70 }
71
72 return ( [ 'exon', 'e' ] );
73 }
74
75
76 # _columns
77 #
78 # Arg [1] : none
79 # Example : none
80 # Description: PROTECTED implementation of superclass abstract method
81 # returns a list of columns to use for queries
82 # Returntype : list of strings
83 # Exceptions : none
84 # Caller : internal
85
86 sub _columns {
87 my $self = shift;
88
89 my $created_date =
90 $self->db->dbc->from_date_to_seconds("created_date");
91 my $modified_date =
92 $self->db->dbc->from_date_to_seconds("modified_date");
93
94 return (
95 'e.exon_id', 'e.seq_region_id', 'e.seq_region_start',
96 'e.seq_region_end', 'e.seq_region_strand', 'e.phase',
97 'e.end_phase', 'e.is_current', 'e.is_constitutive',
98 'e.stable_id', 'e.version', $created_date,
99 $modified_date
100 );
101 }
102
103
104
105 # _final_clause
106 #
107 # Arg [1] : none
108 # Example : none
109 # Description: PROTECTED implementation of superclass abstract method
110 # returns a default end for the SQL-query (ORDER BY)
111 # Returntype : string
112 # Exceptions : none
113 # Caller : internal
114
115 sub _final_clause {
116 my $self = shift;
117 return $self->{'final_clause'} || '';
118 }
119
120
121 sub fetch_all {
122 my ($self) = @_;
123
124 my $constraint = 'e.is_current = 1';
125 my @exons = @{ $self->generic_fetch($constraint) };
126 return \@exons ;
127 }
128
129 =head2 fetch_by_stable_id
130
131 Arg [1] : string $stable_id
132 the stable id of the exon to retrieve
133 Example : $exon = $exon_adaptor->fetch_by_stable_id('ENSE0000988221');
134 Description: Retrieves an Exon from the database via its stable id
135 Returntype : Bio::EnsEMBL::Exon in native coordinates.
136 Exceptions : none
137 Caller : general
138 Status : Stable
139
140 =cut
141
142 sub fetch_by_stable_id {
143 my ($self, $stable_id) = @_;
144
145 my $constraint = "e.stable_id = ? AND e.is_current = 1";
146
147 $self->bind_param_generic_fetch($stable_id,SQL_VARCHAR);
148 my ($exon) = @{ $self->generic_fetch($constraint) };
149
150 return $exon;
151 }
152
153
154 =head2 fetch_all_versions_by_stable_id
155
156 Arg [1] : String $stable_id
157 The stable ID of the exon to retrieve
158 Example : my $exon = $exon_adaptor->fetch_all_version_by_stable_id
159 ('ENSE00000309301');
160 Description : Similar to fetch_by_stable_id, but retrieves all versions of an
161 exon stored in the database.
162 Returntype : listref of Bio::EnsEMBL::Exon objects
163 Exceptions : if we cant get the gene in given coord system
164 Caller : general
165 Status : At Risk
166
167 =cut
168
169 sub fetch_all_versions_by_stable_id {
170 my ($self, $stable_id) = @_;
171
172 my $constraint = "e.stable_id = ?";
173
174 $self->bind_param_generic_fetch($stable_id,SQL_VARCHAR);
175
176 return $self->generic_fetch($constraint);
177 }
178
179
180 =head2 fetch_all_by_Transcript
181
182 Arg [1] : Bio::EnsEMBL::Transcript $transcript
183 Example : none
184 Description: Retrieves all Exons for the Transcript in 5-3 order
185 Returntype : listref Bio::EnsEMBL::Exon on Transcript slice
186 Exceptions : throws if transcript has no slice
187 Caller : Transcript->get_all_Exons()
188 Status : Stable
189
190 =cut
191
192 sub fetch_all_by_Transcript {
193 my ( $self, $transcript ) = @_;
194
195 my $tslice = $transcript->slice();
196 my $slice;
197
198 if ( !defined($tslice) ) {
199 throw("Transcript must have attached slice to retrieve exons.");
200 }
201
202 # use a small slice the same size as the transcript
203 if ( !$tslice->is_circular() ) {
204 $slice =
205 $self->db()->get_SliceAdaptor()->fetch_by_Feature($transcript);
206 } else {
207 # Circular.
208 $slice = $tslice;
209 }
210
211 # Override the tables definition to provide an additional join to the
212 # exon_transcript table. For efficiency we cannot afford to have this
213 # in as a left join every time.
214 my @tables = $self->_tables();
215
216 # Be extra cautious so that we do not add 'exon_transcript' twice.
217 my $found = 0;
218 foreach my $table (@tables) {
219 if ( $table->[0] eq 'exon_transcript' ) {
220 $found = 1;
221 last;
222 }
223 }
224 if ( !$found ) {
225 push @tables, [ 'exon_transcript', 'et' ];
226 }
227
228 $self->{'tables'} = \@tables;
229 $self->{'final_clause'} = "ORDER BY et.transcript_id, et.rank";
230
231 my $constraint =
232 "et.transcript_id = "
233 . $transcript->dbID()
234 . " AND e.exon_id = et.exon_id";
235
236 # fetch all of the exons
237 my $exons = $self->fetch_all_by_Slice_constraint($slice, $constraint);
238
239 # un-override the table definition
240 delete( $self->{'tables'} );
241 delete( $self->{'final_clause'} );
242
243 # remap exon coordinates if necessary
244 if($slice->name() ne $tslice->name()) {
245 my @out;
246 foreach my $ex (@$exons) {
247 push @out, $ex->transfer($tslice);
248 }
249 $exons = \@out;
250 }
251
252 return $exons;
253 }
254
255
256 =head2 store
257
258 Arg [1] : Bio::EnsEMBL::Exon $exon
259 the exon to store in this database
260 Example : $exon_adaptor->store($exon);
261 Description: Stores an exon in the database
262 Returntype : none
263 Exceptions : thrown if exon (or component exons) do not have a contig_id
264 or if $exon->start, $exon->end, $exon->strand, or $exon->phase
265 are not defined or if $exon is not a Bio::EnsEMBL::Exon
266 Caller : general
267 Status : Stable
268
269 =cut
270
271 sub store {
272 my ($self, $exon) = @_;
273
274 if( ! $exon->isa('Bio::EnsEMBL::Exon') ) {
275 throw("$exon is not a EnsEMBL exon - not storing.");
276 }
277
278 my $db = $self->db();
279
280 if($exon->is_stored($db)) {
281 return $exon->dbID();
282 }
283
284 if( ! $exon->start || ! $exon->end ||
285 ! $exon->strand || ! defined $exon->phase ) {
286 throw("Exon does not have all attributes to store");
287 }
288
289 # Default to is_current = 1 if this attribute is not set
290 my $is_current = $exon->is_current();
291 if ( !defined($is_current) ) { $is_current = 1 }
292
293 # Default to is_constitutive = 0 if this attribute is not set
294 my $is_constitutive = $exon->is_constitutive();
295 if ( !defined($is_constitutive) ) { $is_constitutive = 0 }
296
297 my $exon_sql = q{
298 INSERT into exon ( seq_region_id, seq_region_start,
299 seq_region_end, seq_region_strand, phase,
300 end_phase, is_current, is_constitutive
301 };
302 if ( defined($exon->stable_id) ) {
303 my $created = $self->db->dbc->from_seconds_to_date($exon->created_date());
304 my $modified = $self->db->dbc->from_seconds_to_date($exon->modified_date());
305 $exon_sql .= ", stable_id, version, created_date, modified_date) VALUES ( ?,?,?,?,?,?,?,?,?,?,". $created . ",". $modified ." )";
306
307 } else {
308 $exon_sql .= q{
309 ) VALUES ( ?,?,?,?,?,?,?,?)
310 };
311 }
312
313
314 my $exonst = $self->prepare($exon_sql);
315
316 my $exonId = undef;
317
318 my $original = $exon;
319 my $seq_region_id;
320 ($exon, $seq_region_id) = $self->_pre_store($exon);
321
322 #store the exon
323 $exonst->bind_param( 1, $seq_region_id, SQL_INTEGER );
324 $exonst->bind_param( 2, $exon->start, SQL_INTEGER );
325 $exonst->bind_param( 3, $exon->end, SQL_INTEGER );
326 $exonst->bind_param( 4, $exon->strand, SQL_TINYINT );
327 $exonst->bind_param( 5, $exon->phase, SQL_TINYINT );
328 $exonst->bind_param( 6, $exon->end_phase, SQL_TINYINT );
329 $exonst->bind_param( 7, $is_current, SQL_TINYINT );
330 $exonst->bind_param( 8, $is_constitutive, SQL_TINYINT );
331
332 if ( defined($exon->stable_id) ) {
333
334 $exonst->bind_param( 9, $exon->stable_id, SQL_VARCHAR );
335 my $version = ($exon->version()) ? $exon->version() : 1;
336 $exonst->bind_param( 10, $version, SQL_INTEGER );
337 }
338
339 $exonst->execute();
340 $exonId = $exonst->{'mysql_insertid'};
341
342 # Now the supporting evidence
343 my $esf_adaptor = $db->get_SupportingFeatureAdaptor;
344 $esf_adaptor->store($exonId, $exon->get_all_supporting_features);
345
346 #
347 # Finally, update the dbID and adaptor of the exon (and any component exons)
348 # to point to the new database
349 #
350
351 $original->adaptor($self);
352 $original->dbID($exonId);
353
354 return $exonId;
355 }
356
357
358 =head2 remove
359
360 Arg [1] : Bio::EnsEMBL::Exon $exon
361 the exon to remove from the database
362 Example : $exon_adaptor->remove($exon);
363 Description: Removes an exon from the database. This method is generally
364 called by the TranscriptAdaptor::store method. Database
365 integrity will not be maintained if this method is simply
366 called on its own without taking into account transcripts which
367 may refer to the exon being removed.
368 Returntype : none
369 Exceptions : none
370 Caller : general
371 Status : Stable
372
373 =cut
374
375 sub remove {
376 my $self = shift;
377 my $exon = shift;
378
379 if(!ref($exon) || !$exon->isa('Bio::EnsEMBL::Exon')) {
380 throw('Bio::EnsEMBL::Exon argument expected.');
381 }
382
383 if(!$exon->is_stored($self->db())) {
384 warning("Cannot remove exon " .$exon->dbID.
385 "Is not stored in this database.");
386 return;
387 }
388
389 # sanity check: make sure nobdody tries to slip past a prediction exon
390 # which inherits from exon but actually uses different tables
391 if($exon->isa('Bio::EnsEMBL::PredictionExon')) {
392 throw("ExonAdaptor can only remove Exons not PredictionExons.");
393 }
394
395 # Remove the supporting features of this exon
396
397 my $prot_adp = $self->db->get_ProteinAlignFeatureAdaptor;
398 my $dna_adp = $self->db->get_DnaAlignFeatureAdaptor;
399
400 my $sth = $self->prepare("SELECT feature_type, feature_id " .
401 "FROM supporting_feature " .
402 "WHERE exon_id = ?");
403 $sth->bind_param(1, $exon->dbID, SQL_INTEGER);
404 $sth->execute();
405
406 # statements to check for shared align_features
407 my $sth1 = $self->prepare("SELECT count(*) FROM supporting_feature " .
408 "WHERE feature_type = ? AND feature_id = ?");
409 my $sth2 = $self->prepare("SELECT count(*) " .
410 "FROM transcript_supporting_feature " .
411 "WHERE feature_type = ? AND feature_id = ?");
412
413 SUPPORTING_FEATURE:
414 while(my ($type, $feature_id) = $sth->fetchrow()){
415
416 # only remove align_feature if this is the last reference to it
417 $sth1->bind_param(1, $type, SQL_VARCHAR);
418 $sth1->bind_param(2, $feature_id, SQL_INTEGER);
419 $sth1->execute;
420 $sth2->bind_param(1, $type, SQL_VARCHAR);
421 $sth2->bind_param(2, $feature_id, SQL_INTEGER);
422 $sth2->execute;
423 my ($count1) = $sth1->fetchrow;
424 my ($count2) = $sth2->fetchrow;
425 if ($count1 + $count2 > 1) {
426 #warn "shared feature, not removing $type|$feature_id\n";
427 next SUPPORTING_FEATURE;
428 }
429
430 #warn "removing $type|$feature_id\n";
431
432 if($type eq 'protein_align_feature'){
433 my $f = $prot_adp->fetch_by_dbID($feature_id);
434 $prot_adp->remove($f);
435 }
436 elsif($type eq 'dna_align_feature'){
437 my $f = $dna_adp->fetch_by_dbID($feature_id);
438 $dna_adp->remove($f);
439 }
440 else {
441 warning("Unknown supporting feature type $type. Not removing feature.");
442 }
443 }
444 $sth->finish();
445 $sth1->finish();
446 $sth2->finish();
447
448 # delete the association to supporting features
449
450 $sth = $self->prepare("DELETE FROM supporting_feature WHERE exon_id = ?");
451 $sth->bind_param(1, $exon->dbID, SQL_INTEGER);
452 $sth->execute();
453 $sth->finish();
454
455
456 # delete the exon
457
458 $sth = $self->prepare( "DELETE FROM exon WHERE exon_id = ?" );
459 $sth->bind_param(1, $exon->dbID, SQL_INTEGER);
460 $sth->execute();
461 $sth->finish();
462
463 $exon->dbID(undef);
464 $exon->adaptor(undef);
465
466 return;
467 }
468
469
470 =head2 list_dbIDs
471
472 Arg [1] : none
473 Example : @exon_ids = @{$exon_adaptor->list_dbIDs()};
474 Description: Gets an array of internal ids for all exons in the current db
475 Arg[1] : <optional> int. not 0 for the ids to be sorted by the seq_region.
476 Returntype : list of ints
477 Exceptions : none
478 Caller : ?
479 Status : Stable
480
481 =cut
482
483 sub list_dbIDs {
484 my ($self, $ordered) = @_;
485
486 return $self->_list_dbIDs("exon",undef, $ordered);
487 }
488
489
490 =head2 list_stable_ids
491
492 Arg [1] : none
493 Example : @stable_exon_ids = @{$exon_adaptor->list_stable_dbIDs()};
494 Description: Gets an array of stable ids for all exons in the current db
495 Returntype : list of ints
496 Exceptions : none
497 Caller : ?
498 Status : Stable
499
500 =cut
501
502 sub list_stable_ids {
503 my ($self) = @_;
504
505 return $self->_list_dbIDs("exon", "stable_id");
506 }
507
508 #_objs_from_sth
509 #
510 # Arg [1] : StatementHandle $sth
511 # Example : none
512 # Description: PROTECTED implementation of abstract superclass method.
513 # responsible for the creation of Exons
514 # Returntype : listref of Bio::EnsEMBL::Exons in target coordinate system
515 # Exceptions : none
516 # Caller : internal
517
518 sub _objs_from_sth {
519 my ( $self, $sth, $mapper, $dest_slice ) = @_;
520
521 #
522 # This code is ugly because an attempt has been made to remove as many
523 # function calls as possible for speed purposes. Thus many caches and
524 # a fair bit of gymnastics is used.
525 #
526
527 my $sa = $self->db()->get_SliceAdaptor();
528
529 my @exons;
530 my %slice_hash;
531 my %sr_name_hash;
532 my %sr_cs_hash;
533
534 my ( $exon_id, $seq_region_id, $seq_region_start,
535 $seq_region_end, $seq_region_strand, $phase,
536 $end_phase, $is_current, $is_constitutive,
537 $stable_id, $version, $created_date,
538 $modified_date );
539
540 $sth->bind_columns( \( $exon_id, $seq_region_id, $seq_region_start,
541 $seq_region_end, $seq_region_strand, $phase,
542 $end_phase, $is_current, $is_constitutive,
543 $stable_id, $version, $created_date,
544 $modified_date ) );
545
546 my $asm_cs;
547 my $cmp_cs;
548 my $asm_cs_vers;
549 my $asm_cs_name;
550 my $cmp_cs_vers;
551 my $cmp_cs_name;
552
553 if ($mapper) {
554 $asm_cs = $mapper->assembled_CoordSystem();
555 $cmp_cs = $mapper->component_CoordSystem();
556 $asm_cs_name = $asm_cs->name();
557 $asm_cs_vers = $asm_cs->version();
558 $cmp_cs_name = $cmp_cs->name();
559 $cmp_cs_vers = $cmp_cs->version();
560 }
561
562 my $dest_slice_start;
563 my $dest_slice_end;
564 my $dest_slice_strand;
565 my $dest_slice_length;
566 my $dest_slice_cs;
567 my $dest_slice_sr_name;
568 my $dest_slice_sr_id;
569 my $asma;
570
571 if ($dest_slice) {
572 $dest_slice_start = $dest_slice->start();
573 $dest_slice_end = $dest_slice->end();
574 $dest_slice_strand = $dest_slice->strand();
575 $dest_slice_length = $dest_slice->length();
576 $dest_slice_cs = $dest_slice->coord_system();
577 $dest_slice_sr_name = $dest_slice->seq_region_name();
578 $dest_slice_sr_id = $dest_slice->get_seq_region_id();
579 $asma = $self->db->get_AssemblyMapperAdaptor();
580 }
581
582 FEATURE: while ( $sth->fetch() ) {
583 #need to get the internal_seq_region, if present
584 $seq_region_id = $self->get_seq_region_id_internal($seq_region_id);
585
586 my $slice = $slice_hash{ "ID:" . $seq_region_id };
587 my $dest_mapper = $mapper;
588
589 if ( !$slice ) {
590 $slice = $sa->fetch_by_seq_region_id($seq_region_id);
591 $slice_hash{ "ID:" . $seq_region_id } = $slice;
592 $sr_name_hash{$seq_region_id} = $slice->seq_region_name();
593 $sr_cs_hash{$seq_region_id} = $slice->coord_system();
594 }
595
596 #obtain a mapper if none was defined, but a dest_seq_region was
597 if ( !$dest_mapper
598 && $dest_slice
599 && !$dest_slice_cs->equals( $slice->coord_system ) )
600 {
601 $dest_mapper =
602 $asma->fetch_by_CoordSystems( $dest_slice_cs,
603 $slice->coord_system );
604 $asm_cs = $dest_mapper->assembled_CoordSystem();
605 $cmp_cs = $dest_mapper->component_CoordSystem();
606 $asm_cs_name = $asm_cs->name();
607 $asm_cs_vers = $asm_cs->version();
608 $cmp_cs_name = $cmp_cs->name();
609 $cmp_cs_vers = $cmp_cs->version();
610 }
611
612 my $sr_name = $sr_name_hash{$seq_region_id};
613 my $sr_cs = $sr_cs_hash{$seq_region_id};
614
615 #
616 # Remap the feature coordinates to another coord system if a mapper
617 # was provided.
618 #
619 if ( defined($dest_mapper) ) {
620
621 if (defined $dest_slice && $dest_mapper->isa('Bio::EnsEMBL::ChainedAssemblyMapper') ) {
622 ( $seq_region_id, $seq_region_start,
623 $seq_region_end, $seq_region_strand )
624 =
625 $dest_mapper->map( $sr_name, $seq_region_start, $seq_region_end,
626 $seq_region_strand, $sr_cs, 1, $dest_slice);
627
628 } else {
629
630 ( $seq_region_id, $seq_region_start,
631 $seq_region_end, $seq_region_strand )
632 = $dest_mapper->fastmap( $sr_name, $seq_region_start,
633 $seq_region_end, $seq_region_strand,
634 $sr_cs );
635 }
636
637 # Skip features that map to gaps or coord system boundaries.
638 if ( !defined($seq_region_id) ) { next FEATURE }
639
640 # Get a slice in the coord system we just mapped to
641 $slice = $slice_hash{ "ID:" . $seq_region_id } ||=
642 $sa->fetch_by_seq_region_id($seq_region_id);
643 }
644
645 #
646 # If a destination slice was provided convert the coords.
647 #
648 if ( defined($dest_slice) ) {
649 if ( $dest_slice_strand == 1 ) {
650 # On the positive strand.
651
652 $seq_region_start = $seq_region_start - $dest_slice_start + 1;
653 $seq_region_end = $seq_region_end - $dest_slice_start + 1;
654
655 if ( ( $seq_region_end > $dest_slice_start || $seq_region_end < 0 || ( $dest_slice_start > $dest_slice_end
656 && $seq_region_end < 0 ) ) && $dest_slice->is_circular() ) {
657 # Handle circular chromosomes.
658
659 if ( $seq_region_start > $seq_region_end ) {
660 # Looking at a feature overlapping the chromsome origin.
661
662 if ( $seq_region_end > $dest_slice_start ) {
663 # Looking at the region in the beginning of the
664 # chromosome.
665 $seq_region_start -= $dest_slice->seq_region_length();
666 }
667
668 if ( $seq_region_end < 0 ) {
669 $seq_region_end += $dest_slice->seq_region_length();
670 }
671
672 } else {
673 if ( $dest_slice_start > $dest_slice_end
674 && $seq_region_end < 0 )
675 {
676 # Looking at the region overlapping the chromosome
677 # origin and a feature which is at the beginning of the
678 # chromosome.
679 $seq_region_start += $dest_slice->seq_region_length();
680 $seq_region_end += $dest_slice->seq_region_length();
681 }
682 }
683 }
684
685 } else {
686 # On the negative strand.
687
688 if ( $seq_region_start > $seq_region_end && $dest_slice->is_circular() )
689 {
690 # Handle circular chromosomes.
691
692 if ( $dest_slice_start > $dest_slice_end ) {
693 my $tmp_seq_region_start = $seq_region_start;
694 $seq_region_start = $dest_slice_end - $seq_region_end + 1;
695 $seq_region_end =
696 $dest_slice_end +
697 $dest_slice->seq_region_length() -
698 $tmp_seq_region_start + 1;
699 } else {
700
701 if ( $seq_region_end > $dest_slice_start ) {
702 # Looking at the region in the beginning of the
703 # chromosome.
704 $seq_region_start = $dest_slice_end - $seq_region_end + 1;
705 $seq_region_end =
706 $seq_region_end -
707 $dest_slice->seq_region_length() -
708 $dest_slice_start + 1;
709 } else {
710 my $tmp_seq_region_start = $seq_region_start;
711 $seq_region_start =
712 $dest_slice_end -
713 $seq_region_end -
714 $dest_slice->seq_region_length() + 1;
715 $seq_region_end =
716 $dest_slice_end - $tmp_seq_region_start + 1;
717 }
718
719 }
720
721 } else {
722 # Non-circular chromosome.
723
724 my $tmp_seq_region_start = $seq_region_start;
725 $seq_region_start = $dest_slice_end - $seq_region_end + 1;
726 $seq_region_end = $dest_slice_end - $tmp_seq_region_start + 1;
727 }
728
729 $seq_region_strand = -$seq_region_strand;
730
731 } ## end else [ if ( $dest_slice_strand...)]
732
733 # Throw away features off the end of the requested slice.
734 if ( $seq_region_end < 1
735 || $seq_region_start > $dest_slice_length
736 || ( $dest_slice_sr_id != $seq_region_id ) )
737 {
738 next FEATURE;
739 }
740
741 $slice = $dest_slice;
742 } ## end if ( defined($dest_slice...))
743
744 # Finally, create the new exon.
745 push( @exons,
746 $self->_create_feature_fast(
747 'Bio::EnsEMBL::Exon', {
748 'start' => $seq_region_start,
749 'end' => $seq_region_end,
750 'strand' => $seq_region_strand,
751 'adaptor' => $self,
752 'slice' => $slice,
753 'dbID' => $exon_id,
754 'stable_id' => $stable_id,
755 'version' => $version,
756 'created_date' => $created_date || undef,
757 'modified_date' => $modified_date || undef,
758 'phase' => $phase,
759 'end_phase' => $end_phase,
760 'is_current' => $is_current,
761 'is_constitutive' => $is_constitutive } )
762 );
763
764 } ## end while ( $sth->fetch() )
765
766 return \@exons;
767 } ## end sub _objs_from_sth
768
769 =head1 DEPRECATED METHODS
770
771 =cut
772
773
774 =head2 get_stable_entry_info
775
776 Description: DEPRECATED. This method is no longer necessary. Exons are
777 always fetched with their stable identifiers (if they exist) and
778 no lazy loading is necessary.
779
780 =cut
781
782 sub get_stable_entry_info {
783 my ($self,$exon) = @_;
784
785 deprecated( "This method call shouldnt be necessary" );
786
787 if( !$exon || !ref $exon || !$exon->isa('Bio::EnsEMBL::Exon') ) {
788 $self->throw("Needs a exon object, not a $exon");
789 }
790 if(!$exon->dbID){
791 #$self->throw("can't fetch stable info with no dbID");
792 return;
793 }
794
795 my $created_date = $self->db->dbc->from_date_to_seconds("created_date");
796 my $modified_date = $self->db->dbc->from_date_to_seconds("modified_date");
797 my $sth = $self->prepare("SELECT stable_id, " . $created_date . ",
798 " . $modified_date . ", version
799 FROM exon
800 WHERE exon_id = ");
801
802 $sth->bind_param(1, $exon->dbID, SQL_INTEGER);
803 $sth->execute();
804
805 # my @array = $sth->fetchrow_array();
806 if( my $aref = $sth->fetchrow_arrayref() ) {
807 $exon->{'_stable_id'} = $aref->[0];
808 $exon->{'_created'} = $aref->[1];
809 $exon->{'_modified'} = $aref->[2];
810 $exon->{'_version'} = $aref->[3];
811 }
812
813 return 1;
814 }
815
816
817 =head2 fetch_all_by_gene_id
818
819 Description: DEPRECATED. This method should not be needed - Exons can
820 be fetched by Transcript.
821
822 =cut
823
824 sub fetch_all_by_gene_id {
825 my ( $self, $gene_id ) = @_;
826 my %exons;
827 my $hashRef;
828 my ( $currentId, $currentTranscript );
829
830 deprecated( "Hopefully this method is not needed any more. Exons should be fetched by Transcript" );
831
832 if( !$gene_id ) {
833 $self->throw("Gene dbID not defined");
834 }
835
836 $self->{rchash} = {};
837
838 my $query = qq {
839 SELECT
840 STRAIGHT_JOIN
841 e.exon_id
842 , e.contig_id
843 , e.contig_start
844 , e.contig_end
845 , e.contig_strand
846 , e.phase
847 , e.end_phase
848 , e.sticky_rank
849 FROM transcript t
850 , exon_transcript et
851 , exon e
852 WHERE t.gene_id = ?
853 AND et.transcript_id = t.transcript_id
854 AND e.exon_id = et.exon_id
855 ORDER BY t.transcript_id,e.exon_id
856 , e.sticky_rank DESC
857 };
858
859 my $sth = $self->prepare( $query );
860 $sth->bind_param(1,$gene_id,SQL_INTEGER);
861 $sth->execute();
862
863 while( $hashRef = $sth->fetchrow_hashref() ) {
864 if( ! exists $exons{ $hashRef->{exon_id} } ) {
865
866 my $exon = $self->_exon_from_sth( $sth, $hashRef );
867
868 $exons{$exon->dbID} = $exon;
869 }
870 }
871 delete $self->{rchash};
872
873 my @out = ();
874
875 push @out, values %exons;
876
877 return \@out;
878 }
879
880
881 1;
882
883