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