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.
24 Please email comments or questions to the
public Ensembl
25 developers list at <http:
27 Questions may also be sent to the Ensembl help desk at
41 $operon_transcript_adaptor->store($operon_transcript);
42 my $operon_transcript2 = $operon_transcript_adaptor->fetch_by_dbID( $operon->dbID() );
43 my $operon_transcripts = $operon_transcript_adaptor->fetch_all_by_gene( $gene );
47 This is a database aware adaptor
for the retrieval and storage of operon
54 package Bio::EnsEMBL::DBSQL::OperonTranscriptAdaptor;
72 # Description: PROTECTED implementation of superclass abstract method.
73 # Returns the names, aliases of the tables to use for queries.
74 # Returntype : list of listrefs of strings
80 return ( [
'operon_transcript',
'o' ] );
86 # Description: PROTECTED implementation of superclass abstract method.
87 # Returns a list of columns to use for queries.
88 # Returntype : list of strings
97 $self->db()->dbc()->from_date_to_seconds(
"o.created_date");
99 $self->db()->dbc()->from_date_to_seconds(
"o.modified_date");
101 return (
'o.operon_transcript_id',
'o.seq_region_id',
102 'o.seq_region_start',
'o.seq_region_end',
103 'o.seq_region_strand',
'o.display_label',
104 'o.analysis_id',
'o.stable_id',
105 'o.version', $created_date,
111 Example : @ot_ids = @{$ot_adaptor->list_dbIDs()};
112 Description: Gets an array of
internal ids
for all operon_transcripts in the current db
113 Arg[1] : <optional>
int. not 0
for the ids to be sorted by the seq_region.
114 Returntype : Listref of Ints
122 my ( $self, $ordered ) = @_;
124 return $self->_list_dbIDs(
"operon_transcript", undef, $ordered );
127 =head2 list_stable_ids
129 Example : @stable_ot_ids = @{$ot_adaptor->list_stable_ids()};
130 Description: Gets an listref of stable ids
for all operon_transcripts in the current db
131 Returntype : reference to a list of strings
138 sub list_stable_ids {
141 return $self->_list_dbIDs(
"operon_transcript",
"stable_id" );
144 sub list_seq_region_ids {
147 return $self->_list_seq_region_ids(
'operon');
150 =head2 fetch_by_stable_id
153 The stable ID of the operon_transcript to retrieve
154 Example : $operon_transcript = $operon_transcript_adaptor->fetch_by_stable_id(
'T16152-16153-4840');
155 Description: Retrieves a operon_transcript
object from the database via its stable
id.
156 The operon_transcript will be retrieved in its native coordinate system (i.e.
157 in the coordinate system it is stored in the database). It may
158 be converted to a different coordinate system through a call to
159 transform() or transfer(). If the operon_transcript is not found
160 undef is returned instead.
162 Exceptions :
if we cant get the operon_transcript in given coord system
168 sub fetch_by_stable_id {
169 my ( $self, $stable_id ) = @_;
171 my $constraint =
"o.stable_id = ?";
172 $self->bind_param_generic_fetch( $stable_id, SQL_VARCHAR );
173 my ($operon_transcript) = @{ $self->generic_fetch($constraint) };
175 # If we didn't get anything back, desperately try to see if there's
176 # a version number in the stable_id
177 if(!defined($operon_transcript) && (my $vindex = rindex($stable_id,
'.'))) {
178 $operon_transcript = $self->fetch_by_stable_id_version(substr($stable_id,0,$vindex),
179 substr($stable_id,$vindex+1));
182 return $operon_transcript;
185 =head2 fetch_by_stable_id_version
188 The stable ID of the operon_transcript to retrieve
189 Arg [2] : Integer $version
190 The version of the stable_id to retrieve
191 Example : $operon_transcript = $operon_transcript_adaptor->fetch_by_stable_id(
'T16152-16153-4840', 2);
192 Description: Retrieves an operon_transcript
object from the database via its stable
id and version.
193 The operon_transcript will be retrieved in its native coordinate system (i.e.
194 in the coordinate system it is stored in the database). It may
195 be converted to a different coordinate system through a call to
196 transform() or transfer(). If the operon_transcript is not found
197 undef is returned instead.
199 Exceptions :
if we cant get the operon_transcript in given coord system
205 sub fetch_by_stable_id_version {
206 my ($self, $stable_id, $version) = @_;
208 # Enforce that version be numeric
209 return unless($version =~ /^\d+$/);
211 my $constraint =
"o.stable_id = ? AND o.version = ?";
212 $self->bind_param_generic_fetch($stable_id, SQL_VARCHAR);
213 $self->bind_param_generic_fetch($version, SQL_INTEGER);
214 my ($operon_transcript) = @{$self->generic_fetch($constraint)};
216 return $operon_transcript;
221 Arg [1] : String $label - name of operon
transcript to fetch
222 Example : my $operon_transcript = $operonAdaptor->fetch_by_name(
"ECK0012121342");
223 Description: Returns the operon
transcript which has the given display label or undef
if
224 there is none. If there are more than 1, only the first is
237 my $constraint =
"o.display_label = ?";
238 $self->bind_param_generic_fetch( $label, SQL_VARCHAR );
239 my ($operon) = @{ $self->generic_fetch($constraint) };
246 Example : $operon_transcripts = $operon_adaptor->fetch_all();
247 Description : Retrieves all operon transcripts stored in the database.
258 my @operon_transcripts = @{ $self->generic_fetch($constraint) };
259 return \@operon_transcripts;
262 =head2 fetch_all_versions_by_stable_id
264 Arg [1] : String $stable_id
265 The stable ID of the operon_transcript to retrieve
266 Example : $operon_transcript = $operon_transcript_adaptor->fetch_all_versions_by_stable_id
268 Description : Similar to fetch_by_stable_id, but retrieves all versions of a
269 operon_transcript stored in the database.
271 Exceptions :
if we cant get the operon_transcript in given coord system
277 sub fetch_all_versions_by_stable_id {
278 my ( $self, $stable_id ) = @_;
280 my $constraint =
"o.stable_id = ?";
281 $self->bind_param_generic_fetch( $stable_id, SQL_VARCHAR );
282 return $self->generic_fetch($constraint);
285 =head2 fetch_all_by_Slice
288 The slice to fetch operon_transcripts on.
289 Arg [2] : (optional)
string $logic_name
290 the logic name of the type of features to obtain
291 Arg [3] : (optional)
boolean $load_transcripts
292 if true, transcripts will be loaded immediately rather than
294 Arg [4] : (optional)
string $source
295 the source name of the features to obtain.
296 Arg [5] : (optional)
string biotype
297 the biotype of the features to obtain.
298 Example : @operon_transcripts = @{$operon_transcript_adaptor->fetch_all_by_Slice()};
299 Description: Overrides superclass method to optionally load transcripts
300 immediately rather than lazy-loading them later. This
301 is more efficient when there are a lot of operon_transcripts whose
302 transcripts are going to be used.
303 Returntype : reference to list of operon_transcripts
305 Caller : Slice::get_all_OperonTranscripts
310 sub fetch_all_by_Slice {
311 my ( $self, $slice, $logic_name, $load_transcripts ) = @_;
316 $self->SUPER::fetch_all_by_Slice_constraint( $slice, $constraint,
319 # If there are less than two operons, still do lazy-loading.
320 if ( !$load_transcripts || @$operons < 2 ) {
324 # Preload all of the transcripts now, instead of lazy loading later,
325 # faster than one query per transcript.
327 # First check if transcripts are already preloaded.
328 # FIXME: Should check all transcripts.
329 if ( exists( $operons->[0]->{
'_operon_transcript_array'} ) ) {
333 # Get extent of region spanned by transcripts.
334 my ($min_start, $max_end);
337 unless ($slice->is_circular()) {
338 foreach my $o (@$operons) {
339 if (!defined($min_start) || $o->seq_region_start() < $min_start) {
340 $min_start = $o->seq_region_start();
342 if (!defined($max_end) || $o->seq_region_end() > $max_end) {
343 $max_end = $o->seq_region_end();
347 if ($min_start >= $slice->start() && $max_end <= $slice->end()) {
350 my $sa = $self->db()->get_SliceAdaptor();
351 $ext_slice = $sa->fetch_by_region($slice->coord_system->name(), $slice->seq_region_name(), $min_start, $max_end, $slice->strand(), $slice->coord_system->version());
355 # feature might be crossing the origin of replication (i.e. seq_region_start > seq_region_end)
356 # the computation of min_start|end based on seq_region_start|end is not safe
357 # use feature start/end relative to the slice instead
358 my ($min_start_feature, $max_end_feature);
359 foreach my $o (@$operons) {
360 if (!defined($min_start) || ($o->start() >= 0 && $o->start() < $min_start)) {
361 $min_start = $o->start();
362 $min_start_feature = $o;
364 if (!defined($max_end) || ($o->end() >= 0 && $o->end() > $max_end)) {
365 $max_end = $o->end();
366 $max_end_feature = $o;
370 # now we can reassign min_start|end to seq_region_start|end of
371 # the feature which spans the largest region
372 $min_start = $min_start_feature->seq_region_start();
373 $max_end = $max_end_feature->seq_region_end();
375 my $sa = $self->db()->get_SliceAdaptor();
377 $sa->fetch_by_region($slice->coord_system->name(),
378 $slice->seq_region_name(),
382 $slice->coord_system->version());
386 # Associate transcript identifiers with operon_transcripts.
388 my %o_hash =
map { $_->dbID => $_ } @{$operons};
390 my $o_id_str = join(
',', keys(%o_hash) );
393 $self->prepare(
"SELECT operon_id, operon_transcript_id "
394 .
"FROM operon_transcript "
395 .
"WHERE operon_id IN ($o_id_str)" );
399 my ( $o_id, $tr_id );
400 $sth->bind_columns( \( $o_id, $tr_id ) );
404 while ( $sth->fetch() ) {
405 $tr_o_hash{$tr_id} = $o_hash{$o_id};
408 my $ta = $self->db()->get_OperonTranscriptAdaptor();
410 $ta->fetch_all_by_Slice( $ext_slice,
412 sprintf(
"ot.operon_transcript_id IN (%s)",
415 keys(%tr_o_hash) ) ) );
417 # Move transcripts onto operon_transcript slice, and add them to operon_transcripts.
418 foreach my $tr ( @{$transcripts} ) {
419 if ( !exists( $tr_o_hash{ $tr->dbID() } ) ) {
424 if ( $slice != $ext_slice ) {
425 $new_tr = $tr->transfer($slice);
426 if ( !defined($new_tr) ) {
428 .
"Transcript could not be transfered onto OperonTranscript slice."
435 $tr_o_hash{ $tr->dbID() }->add_OperonTranscript($new_tr);
439 } ## end sub fetch_all_by_Slice
441 =head2 fetch_by_Operon
444 Example : $ot = $ot_adaptor->fetch_by_Operon($operon);
445 Description: Retrieves all operon transcripts belonging to an operon
453 sub fetch_all_by_Operon {
454 my ( $self, $operon ) = @_;
455 return $self->fetch_by_operon_id( $operon->dbID() );
458 =head2 fetch_by_operon_id
461 Example : $ot = $ot_adaptor->fetch_by_operon_transcript($operon);
462 Description: Retrieves all operon transcripts belonging to an operon
470 sub fetch_by_operon_id {
471 my ( $self, $operon_id ) = @_;
473 my $constraint =
"o.operon_id = ?";
474 $self->bind_param_generic_fetch( $operon_id, SQL_INTEGER );
475 return $self->generic_fetch($constraint);
478 =head2 fetch_genes_by_operon_transcript
481 Example : $ot = $ot_adaptor->fetch_genes_by_operon_transcript($operon_transcript);
482 Description: Retrieves all genes attached to an operon
transcript
490 sub fetch_genes_by_operon_transcript {
491 my ( $self, $operon_transcript ) = @_;
492 assert_ref( $operon_transcript,
'Bio::EnsEMBL::OperonTranscript' );
493 return $self->fetch_genes_by_operon_transcript_id(
494 $operon_transcript->dbID() );
497 =head2 fetch_genes_by_operon_transcript_id
500 Example : $ot = $ot_adaptor->fetch_genes_by_operon_transcript($operon_transcript_id);
501 Description: Retrieves all genes attached to an operon
transcript
509 sub fetch_genes_by_operon_transcript_id {
510 my ( $self, $operon_transcript_id ) = @_;
515 $helper->execute_simple(
517 'SELECT gene_id FROM operon_transcript_gene tr WHERE operon_transcript_id =?',
518 -PARAMS => [$operon_transcript_id] );
521 my $gene_adaptor = $self->db()->get_GeneAdaptor();
522 for my $gene_id (@$gene_ids) {
523 push @$genes, $gene_adaptor->fetch_by_dbID($gene_id);
528 =head2 fetch_all_by_gene
531 Example : $ots = $ot_adaptor->fetch_all_by_gene($gene);
532 Description: Retrieves all operon transcripts attached to a given gene
540 sub fetch_all_by_gene {
541 my ( $self, $gene ) = @_;
542 assert_ref( $gene,
'Bio::EnsEMBL::Gene' );
543 return $self->fetch_all_by_gene_id( $gene->dbID() );
546 =head2 fetch_all_by_gene_id
549 Example : $ots = $ot_adaptor->fetch_all_by_gene($gene);
550 Description: Retrieves all operon transcripts attached to a given gene
558 sub fetch_all_by_gene_id {
559 my ( $self, $gene_id ) = @_;
563 my $ot_ids = $helper->execute_simple(
565 'SELECT operon_transcript_id FROM operon_transcript_gene tr WHERE gene_id =?',
566 -PARAMS => [$gene_id] );
569 for my $ot_id (@$ot_ids) {
570 push @$ots, $self->fetch_by_dbID($ot_id);
578 The gene to store in the database
579 Arg [2] : ignore_release in xrefs [
default 1] set to 0 to use release
info
580 in external database references
581 Example : $gene_adaptor->store($gene);
582 Description: Stores a gene in the database.
583 Returntype : the database identifier (dbID) of the newly stored gene
585 $gene does not have an analysis
object
592 my ( $self, $operon_transcript, $operon_id ) = @_;
594 assert_ref( $operon_transcript,
'Bio::EnsEMBL::OperonTranscript' );
596 my $db = $self->db();
598 if ( $operon_transcript->is_stored($db) ) {
599 return $operon_transcript->dbID();
602 # ensure coords are correct before storing
603 #$operon->recalculate_coordinates();
607 ( $operon_transcript, $seq_region_id ) =
608 $self->_pre_store($operon_transcript);
609 my $analysis = $operon_transcript->analysis();
610 throw(
"OperonTranscripts must have an analysis object.")
611 if ( !defined($analysis) );
613 if ( $analysis->is_stored($db) ) {
614 $analysis_id = $analysis->dbID();
616 $analysis_id = $db->get_AnalysisAdaptor->store($analysis);
629 if ( defined($operon_transcript->stable_id()) ) {
634 my $created = $self->db->dbc->from_seconds_to_date($operon_transcript->created_date());
635 my $modified = $self->db->dbc->from_seconds_to_date($operon_transcript->modified_date());
638 push @canned_columns,
'created_date';
639 push @canned_values, $created;
642 push @canned_columns,
'modified_date';
643 push @canned_values, $modified;
646 my $i_columns = join(
', ', @columns, @canned_columns);
647 my $i_values = join(
', ', ((
'?') x scalar(@columns)), @canned_values);
648 my $store_operon_transcript_sql = qq(
649 INSERT INTO operon_transcript ( ${i_columns} ) VALUES ( $i_values )
652 my $sth = $self->prepare($store_operon_transcript_sql);
653 $sth->bind_param( 1, $seq_region_id, SQL_INTEGER );
654 $sth->bind_param( 2, $operon_transcript->start(), SQL_INTEGER );
655 $sth->bind_param( 3, $operon_transcript->end(), SQL_INTEGER );
656 $sth->bind_param( 4, $operon_transcript->strand(), SQL_TINYINT );
657 $sth->bind_param( 5, $operon_transcript->display_label(), SQL_VARCHAR );
658 $sth->bind_param( 6, $operon_id, SQL_INTEGER );
659 $sth->bind_param( 7, $analysis_id, SQL_INTEGER );
661 if ( defined($operon_transcript->stable_id()) ) {
662 $sth->bind_param( 8, $operon_transcript->stable_id(), SQL_VARCHAR );
663 my $version = ($operon_transcript->version()) ? $operon_transcript->version() : 1;
664 $sth->bind_param( 9, $version, SQL_INTEGER );
670 my $operon_transcript_dbID = $self->last_insert_id(
'operon_transcript_id', undef,
'operon_transcript');
672 # store the dbentries associated with this gene
673 my $dbEntryAdaptor = $db->get_DBEntryAdaptor();
675 foreach my $dbe ( @{ $operon_transcript->get_all_DBEntries } ) {
676 $dbEntryAdaptor->store( $dbe, $operon_transcript_dbID,
677 "OperonTranscript" );
680 # store operon attributes if there are any
681 my $attrs = $operon_transcript->get_all_Attributes();
682 if ( $attrs && scalar @$attrs ) {
683 my $attr_adaptor = $db->get_AttributeAdaptor();
684 $attr_adaptor->store_on_OperonTranscript( $operon_transcript, $attrs );
687 # set the adaptor and dbID on the original passed in gene not the
689 $operon_transcript->adaptor($self);
690 $operon_transcript->dbID($operon_transcript_dbID);
692 if ( defined $operon_transcript->{_gene_array} ) {
693 $self->store_genes_on_OperonTranscript( $operon_transcript,
694 $operon_transcript->{_gene_array} );
697 return $operon_transcript_dbID;
700 =head2 store_genes_on_OperonTranscript
703 the operon_transcript to store genes on
706 Example : $ot_adaptor->store_genes_on_OperonTranscript(\@genes);
707 Description: Associates genes with operon
transcript
709 Exceptions :
throw on incorrect arguments
710 warning
if operon_transcript is not stored in
this database
711 Caller : general, store
716 sub store_genes_on_OperonTranscript {
717 my ( $self, $operon_transcript, $genes ) = @_;
718 assert_ref( $operon_transcript,
"Bio::EnsEMBL::OperonTranscript" );
719 my $sth = $self->prepare(
720 'insert into operon_transcript_gene(operon_transcript_id,gene_id) values('
721 . $operon_transcript->dbID()
723 for my $gene ( @{$genes} ) {
724 assert_ref( $gene,
"Bio::EnsEMBL::Gene" );
725 $sth->bind_param( 1, $gene->dbID(), SQL_INTEGER );
735 the operon_transcript to remove from the database
736 Example : $ot_adaptor->remove($ot);
737 Description: Removes a operon
transcript completely from the database.
739 Exceptions :
throw on incorrect arguments
740 warning
if operon_transcript is not stored in
this database
748 my $operon_transcript = shift;
750 assert_ref( $operon_transcript,
'Bio::EnsEMBL::OperonTranscript' );
752 if ( !$operon_transcript->is_stored( $self->db() ) ) {
753 warning(
"Cannot remove operon transcript "
754 . $operon_transcript->dbID()
755 .
". Is not stored in "
756 .
"this database." );
760 # remove all object xrefs associated with this gene
762 my $dbe_adaptor = $self->db()->get_DBEntryAdaptor();
763 foreach my $dbe ( @{ $operon_transcript->get_all_DBEntries() } ) {
764 $dbe_adaptor->remove_from_object( $dbe, $operon_transcript,
765 'OperonTranscript' );
768 # # remove the attributes associated with this transcript
769 # my $attrib_adaptor = $self->db->get_AttributeAdaptor;
770 # $attrib_adaptor->remove_from_OperonTranscript($operon_transcript);
772 # remove from the database
773 my $sth = $self->prepare(
774 "DELETE FROM operon_transcript WHERE operon_transcript_id = ? ");
775 $sth->bind_param( 1, $operon_transcript->dbID, SQL_INTEGER );
779 # unset the gene identifier and adaptor thereby flagging it as unstored
781 $operon_transcript->dbID(undef);
782 $operon_transcript->adaptor(undef);
789 # Arg [1] : StatementHandle $sth
790 # Arg [2] : Bio::EnsEMBL::AssemblyMapper $mapper
791 # Arg [3] : Bio::EnsEMBL::Slice $dest_slice
792 # Description: PROTECTED implementation of abstract superclass method.
793 # responsible for the creation of OperonTranscripts
794 # Returntype : listref of Bio::EnsEMBL::OperonTranscripts in target coordinate system
800 my ($self, $sth, $mapper, $dest_slice) = @_;
803 # This code is ugly because an attempt has been made to remove as many
804 # function calls as possible for speed purposes. Thus many caches and
805 # a fair bit of gymnastics is used.
808 my $sa = $self->db()->get_SliceAdaptor();
809 my $aa = $self->db()->get_AnalysisAdaptor();
818 $operon_transcript_id, $seq_region_id, $seq_region_start,
819 $seq_region_end, $seq_region_strand, $display_label,
820 $analysis_id, $stable_id, $version,
821 $created_date, $modified_date );
823 $sth->bind_columns( \(
824 $operon_transcript_id, $seq_region_id, $seq_region_start,
825 $seq_region_end, $seq_region_strand, $display_label,
826 $analysis_id, $stable_id, $version,
827 $created_date, $modified_date ));
829 my $dest_slice_start;
831 my $dest_slice_strand;
832 my $dest_slice_length;
834 my $dest_slice_sr_name;
835 my $dest_slice_sr_id;
839 $dest_slice_start = $dest_slice->start();
840 $dest_slice_end = $dest_slice->end();
841 $dest_slice_strand = $dest_slice->strand();
842 $dest_slice_length = $dest_slice->length();
843 $dest_slice_cs = $dest_slice->coord_system();
844 $dest_slice_sr_name = $dest_slice->seq_region_name();
845 $dest_slice_sr_id = $dest_slice->get_seq_region_id();
846 $asma = $self->db->get_AssemblyMapperAdaptor();
849 OPERON:
while ( $sth->fetch() ) {
851 #get the analysis object
852 my $analysis = $analysis_hash{$analysis_id} ||= $aa->fetch_by_dbID($analysis_id);
853 $analysis_hash{$analysis_id} = $analysis;
855 #need to get the internal_seq_region, if present
856 $seq_region_id = $self->get_seq_region_id_internal($seq_region_id);
857 my $slice = $slice_hash{
"ID:".$seq_region_id};
860 $slice = $sa->fetch_by_seq_region_id($seq_region_id);
861 $slice_hash{
"ID:".$seq_region_id} = $slice;
862 $sr_name_hash{$seq_region_id} = $slice->seq_region_name();
863 $sr_cs_hash{$seq_region_id} = $slice->coord_system();
866 #obtain a mapper if none was defined, but a dest_seq_region was
867 if(!$mapper && $dest_slice && !$dest_slice_cs->equals($slice->coord_system)) {
868 $mapper = $asma->fetch_by_CoordSystems($dest_slice_cs, $slice->coord_system);
871 my $sr_name = $sr_name_hash{$seq_region_id};
872 my $sr_cs = $sr_cs_hash{$seq_region_id};
875 # remap the feature coordinates to another coord system
876 # if a mapper was provided
881 if (defined $dest_slice && $mapper->isa(
'Bio::EnsEMBL::ChainedAssemblyMapper') ) {
882 ($seq_region_id, $seq_region_start, $seq_region_end, $seq_region_strand) =
883 $mapper->map($sr_name, $seq_region_start, $seq_region_end, $seq_region_strand, $sr_cs, 1, $dest_slice);
886 ($seq_region_id, $seq_region_start, $seq_region_end, $seq_region_strand) =
887 $mapper->fastmap($sr_name, $seq_region_start, $seq_region_end, $seq_region_strand, $sr_cs);
890 #skip features that map to gaps or coord system boundaries
891 next OPERON
if ( !defined($seq_region_id) );
893 #get a slice in the coord system we just mapped to
894 $slice = $slice_hash{
"ID:".$seq_region_id} ||= $sa->fetch_by_seq_region_id($seq_region_id);
898 # If a destination slice was provided convert the coords.
900 if (defined($dest_slice)) {
901 my $seq_region_len = $dest_slice->seq_region_length();
903 if ( $dest_slice_strand == 1 ) {
904 $seq_region_start = $seq_region_start - $dest_slice_start + 1;
905 $seq_region_end = $seq_region_end - $dest_slice_start + 1;
907 if ( $dest_slice->is_circular ) {
908 # Handle circular chromosomes.
910 if ( $seq_region_start > $seq_region_end ) {
911 # Looking at a feature overlapping the chromosome origin.
913 if ( $seq_region_end > $dest_slice_start ) {
914 # Looking at the region in the beginning of the chromosome
915 $seq_region_start -= $seq_region_len;
917 if ( $seq_region_end < 0 ) {
918 $seq_region_end += $seq_region_len;
921 if ($dest_slice_start > $dest_slice_end && $seq_region_end < 0) {
922 # Looking at the region overlapping the chromosome
923 # origin and a feature which is at the beginning of the
925 $seq_region_start += $seq_region_len;
926 $seq_region_end += $seq_region_len;
932 my $start = $dest_slice_end - $seq_region_end + 1;
933 my $end = $dest_slice_end - $seq_region_start + 1;
935 if ($dest_slice->is_circular()) {
937 if ($dest_slice_start > $dest_slice_end) {
938 # slice spans origin or replication
940 if ($seq_region_start >= $dest_slice_start) {
941 $end += $seq_region_len;
942 $start += $seq_region_len
if $seq_region_end > $dest_slice_start;
944 } elsif ($seq_region_start <= $dest_slice_end) {
946 } elsif ($seq_region_end >= $dest_slice_start) {
947 $start += $seq_region_len;
948 $end += $seq_region_len;
950 } elsif ($seq_region_end <= $dest_slice_end) {
951 $end += $seq_region_len
if $end < 0;
953 } elsif ($seq_region_start > $seq_region_end) {
954 $end += $seq_region_len;
959 if ($seq_region_start <= $dest_slice_end and $seq_region_end >= $dest_slice_start) {
961 } elsif ($seq_region_start > $seq_region_end) {
962 if ($seq_region_start <= $dest_slice_end) {
963 $start -= $seq_region_len;
964 } elsif ($seq_region_end >= $dest_slice_start) {
965 $end += $seq_region_len;
971 $seq_region_start = $start;
972 $seq_region_end = $end;
973 $seq_region_strand *= -1;
975 } ## end
else [
if ( $dest_slice_strand...)]
977 # Throw away features off the end of the requested slice or on
978 # different seq_region.
979 if ($seq_region_end < 1
980 || $seq_region_start > $dest_slice_length
981 || ($dest_slice_sr_id != $seq_region_id)) {
984 $slice = $dest_slice;
989 -START => $seq_region_start,
990 -END => $seq_region_end,
991 -STRAND => $seq_region_strand,
993 -DISPLAY_LABEL => $display_label,
995 -DBID => $operon_transcript_id,
996 -STABLE_ID => $stable_id,
997 -VERSION => $version,
998 -CREATED_DATE => $created_date || undef,
999 -MODIFIED_DATE => $modified_date || undef,
1000 -ANALYSIS => $analysis ) );
1002 } ## end
while ( $sth->fetch() )
1005 } ## end sub _objs_from_sth