diff --git a/modules/Bio/EnsEMBL/DBSQL/ExonAdaptor.pm b/modules/Bio/EnsEMBL/DBSQL/ExonAdaptor.pm index 65bb56a4f0baedf1b2cb1ca383610972050b6c78..c7a437e8e4e903d98978e4d200b93954223b3b2f 100644 --- a/modules/Bio/EnsEMBL/DBSQL/ExonAdaptor.pm +++ b/modules/Bio/EnsEMBL/DBSQL/ExonAdaptor.pm @@ -515,7 +515,7 @@ sub list_stable_ids { # Caller : internal sub _objs_from_sth { - my ($self, $sth, $mapper, $dest_slice) = @_; + my ( $self, $sth, $mapper, $dest_slice ) = @_; # # This code is ugly because an attempt has been made to remove as many @@ -530,21 +530,17 @@ sub _objs_from_sth { my %sr_name_hash; my %sr_cs_hash; - my ( - $exon_id, $seq_region_id, $seq_region_start, - $seq_region_end, $seq_region_strand, $phase, - $end_phase, $is_current, $is_constitutive, - $stable_id, $version, $created_date, - $modified_date - ); + my ( $exon_id, $seq_region_id, $seq_region_start, + $seq_region_end, $seq_region_strand, $phase, + $end_phase, $is_current, $is_constitutive, + $stable_id, $version, $created_date, + $modified_date ); - $sth->bind_columns( - \$exon_id, \$seq_region_id, \$seq_region_start, - \$seq_region_end, \$seq_region_strand, \$phase, - \$end_phase, \$is_current, \$is_constitutive, - \$stable_id, \$version, \$created_date, - \$modified_date - ); + $sth->bind_columns( \( $exon_id, $seq_region_id, $seq_region_start, + $seq_region_end, $seq_region_strand, $phase, + $end_phase, $is_current, $is_constitutive, + $stable_id, $version, $created_date, + $modified_date ) ); my $asm_cs; my $cmp_cs; @@ -552,9 +548,10 @@ sub _objs_from_sth { my $asm_cs_name; my $cmp_cs_vers; my $cmp_cs_name; - if($mapper) { - $asm_cs = $mapper->assembled_CoordSystem(); - $cmp_cs = $mapper->component_CoordSystem(); + + if ($mapper) { + $asm_cs = $mapper->assembled_CoordSystem(); + $cmp_cs = $mapper->component_CoordSystem(); $asm_cs_name = $asm_cs->name(); $asm_cs_vers = $asm_cs->version(); $cmp_cs_name = $cmp_cs->name(); @@ -569,38 +566,42 @@ sub _objs_from_sth { my $dest_slice_sr_name; my $dest_slice_sr_id; my $asma; - if($dest_slice) { - $dest_slice_start = $dest_slice->start(); - $dest_slice_end = $dest_slice->end(); - $dest_slice_strand = $dest_slice->strand(); - $dest_slice_length = $dest_slice->length(); - $dest_slice_cs = $dest_slice->coord_system(); + + if ($dest_slice) { + $dest_slice_start = $dest_slice->start(); + $dest_slice_end = $dest_slice->end(); + $dest_slice_strand = $dest_slice->strand(); + $dest_slice_length = $dest_slice->length(); + $dest_slice_cs = $dest_slice->coord_system(); $dest_slice_sr_name = $dest_slice->seq_region_name(); - $dest_slice_sr_id = $dest_slice->get_seq_region_id(); - $asma = $self->db->get_AssemblyMapperAdaptor(); + $dest_slice_sr_id = $dest_slice->get_seq_region_id(); + $asma = $self->db->get_AssemblyMapperAdaptor(); } - FEATURE: while($sth->fetch()) { +FEATURE: while ( $sth->fetch() ) { #need to get the internal_seq_region, if present $seq_region_id = $self->get_seq_region_id_internal($seq_region_id); - my $slice = $slice_hash{"ID:".$seq_region_id}; + my $slice = $slice_hash{ "ID:" . $seq_region_id }; my $dest_mapper = $mapper; - if(!$slice) { + if ( !$slice ) { $slice = $sa->fetch_by_seq_region_id($seq_region_id); - $slice_hash{"ID:".$seq_region_id} = $slice; - $sr_name_hash{$seq_region_id} = $slice->seq_region_name(); - $sr_cs_hash{$seq_region_id} = $slice->coord_system(); + $slice_hash{ "ID:" . $seq_region_id } = $slice; + $sr_name_hash{$seq_region_id} = $slice->seq_region_name(); + $sr_cs_hash{$seq_region_id} = $slice->coord_system(); } #obtain a mapper if none was defined, but a dest_seq_region was - if(!$dest_mapper && $dest_slice && - !$dest_slice_cs->equals($slice->coord_system)) { - $dest_mapper = $asma->fetch_by_CoordSystems($dest_slice_cs, - $slice->coord_system); - $asm_cs = $dest_mapper->assembled_CoordSystem(); - $cmp_cs = $dest_mapper->component_CoordSystem(); + if ( !$dest_mapper + && $dest_slice + && !$dest_slice_cs->equals( $slice->coord_system ) ) + { + $dest_mapper = + $asma->fetch_by_CoordSystems( $dest_slice_cs, + $slice->coord_system ); + $asm_cs = $dest_mapper->assembled_CoordSystem(); + $cmp_cs = $dest_mapper->component_CoordSystem(); $asm_cs_name = $asm_cs->name(); $asm_cs_vers = $asm_cs->version(); $cmp_cs_name = $cmp_cs->name(); @@ -630,57 +631,126 @@ sub _objs_from_sth { } # - # If a destination slice was provided convert the coords - # If the dest_slice starts at 1 and is foward strand, nothing needs doing + # If a destination slice was provided convert the coords. If the + # dest_slice starts at 1 and is foward strand, nothing needs doing. # - if($dest_slice) { - if($dest_slice_start != 1 || $dest_slice_strand != 1) { - if($dest_slice_strand == 1) { - $seq_region_start = $seq_region_start - $dest_slice_start + 1; - $seq_region_end = $seq_region_end - $dest_slice_start + 1; - } else { - my $tmp_seq_region_start = $seq_region_start; - $seq_region_start = $dest_slice_end - $seq_region_end + 1; - $seq_region_end = $dest_slice_end - $tmp_seq_region_start + 1; - $seq_region_strand *= -1; - } - } - - #throw away features off the end of the requested slice - if($seq_region_end < 1 || $seq_region_start > $dest_slice_length || - ( $dest_slice_sr_id != $seq_region_id )) { - next FEATURE; + if ( defined($dest_slice) ) { + if ( $dest_slice_strand == 1 ) { + # On the positive strand. + + $seq_region_start = $seq_region_start - $dest_slice_start + 1; + $seq_region_end = $seq_region_end - $dest_slice_start + 1; + + # Handle circular chromosomes. + if ( $dest_slice->is_circular() ) { + if ( $seq_region_start > $seq_region_end ) { + # Looking at a feature overlapping the chromsome origin. + + if ( $seq_region_end > $dest_slice_start ) { + # Looking at the region in the beginning of the + # chromosome. + $seq_region_start -= $dest_slice->seq_region_length(); + } + + if ( $seq_region_end < 0 ) { + $seq_region_end += $dest_slice->seq_region_length(); + } + + } elsif ( $dest_slice_start > $dest_slice_end + && $seq_region_end < 0 ) + { + # Looking at the region overlapping the chromosome + # origin and a feature which is at the beginning of the + # chromosome. + $seq_region_start += $dest_slice->seq_region_length(); + $seq_region_end += $dest_slice->seq_region_length(); + } + } + + } else { + # On the negative strand. + + # Handle circular chromosomes. + if ( $dest_slice->is_circular() ) { + if ( $seq_region_start > $seq_region_end ) { + + if ( $dest_slice_start > $dest_slice_end ) { + my $tmp_seq_region_start = $seq_region_start; + $seq_region_start = $dest_slice_end - $seq_region_end + 1; + $seq_region_end = + $dest_slice_end + + $dest_slice->seq_region_length - + $tmp_seq_region_start + 1; + } else { + + if ( $seq_region_end > $dest_slice_start ) { + # Looking at the region in the beginning of the + # chromosome. + $seq_region_start = + $dest_slice_end - $seq_region_end + 1; + $seq_region_end = + $seq_region_end - + $dest_slice->seq_region_length - + $dest_slice_start + 1; + } else { + my $tmp_seq_region_start = $seq_region_start; + $seq_region_start = + $dest_slice_end - + $seq_region_end - + $dest_slice->seq_region_length + 1; + $seq_region_end = + $dest_slice_end - $tmp_seq_region_start + 1; + } + + } + + } ## end if ( $seq_region_start...) + } else { + # Non-circular chromosome. + my $tmp_seq_region_start = $seq_region_start; + $seq_region_start = $dest_slice_end - $seq_region_end + 1; + $seq_region_end = $dest_slice_end - $tmp_seq_region_start + 1; + } + + $seq_region_strand = -$seq_region_strand; + + } ## end else [ if ( $dest_slice_strand...)] + + # Throw away features off the end of the requested slice. + if ( $seq_region_end < 1 + || $seq_region_start > $dest_slice_length + || ( $dest_slice_sr_id != $seq_region_id ) ) + { + next FEATURE; } $slice = $dest_slice; - } + } ## end if ( defined($dest_slice...)) # Finally, create the new exon. - push( - @exons, - $self->_create_feature_fast( - 'Bio::EnsEMBL::Exon', - { - 'start' => $seq_region_start, - 'end' => $seq_region_end, - 'strand' => $seq_region_strand, - 'adaptor' => $self, - 'slice' => $slice, - 'dbID' => $exon_id, - 'stable_id' => $stable_id, - 'version' => $version, - 'created_date' => $created_date || undef, - 'modified_date' => $modified_date || undef, - 'phase' => $phase, - 'end_phase' => $end_phase, - 'is_current' => $is_current, - 'is_constitutive' => $is_constitutive - } ) ); - - } + push( @exons, + $self->_create_feature_fast( + 'Bio::EnsEMBL::Exon', { + 'start' => $seq_region_start, + 'end' => $seq_region_end, + 'strand' => $seq_region_strand, + 'adaptor' => $self, + 'slice' => $slice, + 'dbID' => $exon_id, + 'stable_id' => $stable_id, + 'version' => $version, + 'created_date' => $created_date || undef, + 'modified_date' => $modified_date || undef, + 'phase' => $phase, + 'end_phase' => $end_phase, + 'is_current' => $is_current, + 'is_constitutive' => $is_constitutive } ) + ); + + } ## end while ( $sth->fetch() ) return \@exons; -} +} ## end sub _objs_from_sth =head1 DEPRECATED METHODS