Bio-EnsEMBL
view release on metacpan or search on metacpan
lib/Bio/EnsEMBL/Feature.pm view on Meta::CPAN
=cut
=head1 NAME
Bio::EnsEMBL::Feature - Ensembl specific sequence feature.
=head1 SYNOPSIS
my $feat = new Bio::EnsEMBL::Feature(
-start => 100,
-end => 220,
-strand => -1,
-slice => $slice,
-analysis => $analysis
);
my $start = $feat->start();
my $end = $feat->end();
my $strand = $feat->strand();
# Move the feature to the chromosomal coordinate system
$feature = $feature->transform('chromosome');
# Move the feature to a different slice (possibly on another coord
# system)
$feature = $feature->transfer($new_slice);
# Project the feature onto another coordinate system possibly across
# boundaries:
@projection = @{ $feature->project('contig') };
# Change the start, end, and strand of the feature in place
$feature->move( $new_start, $new_end, $new_strand );
=head1 DESCRIPTION
This is the Base feature class from which all Ensembl features inherit.
It provides a bare minimum functionality that all features require. It
basically describes a location on a sequence in an arbitrary coordinate
system.
=head1 METHODS
=cut
package Bio::EnsEMBL::Feature;
$Bio::EnsEMBL::Feature::VERSION = '114.0.0';
use strict;
use warnings;
use Bio::EnsEMBL::Storable;
use Bio::EnsEMBL::Utils::Argument qw(rearrange);
use Bio::EnsEMBL::Utils::Exception qw(throw warning);
use Bio::EnsEMBL::Utils::Scalar qw(check_ref assert_ref);
use Bio::EnsEMBL::Slice;
use vars qw(@ISA);
use Scalar::Util qw(weaken);
@ISA = qw(Bio::EnsEMBL::Storable);
=head2 new
Arg [-SLICE]: Bio::EnsEMBL::SLice - Represents the sequence that this
feature is on. The coordinates of the created feature are
relative to the start of the slice.
Arg [-START]: The start coordinate of this feature relative to the start
of the slice it is sitting on. Coordinates start at 1 and
are inclusive.
Arg [-END] : The end coordinate of this feature relative to the start of
the slice it is sitting on. Coordinates start at 1 and are
inclusive.
Arg [-STRAND]: The orientation of this feature. Valid values are 1,-1,0.
Arg [-SEQNAME] : A seqname to be used instead of the default name of the
of the slice. Useful for features that do not have an
attached slice such as protein features.
Arg [-dbID] : (optional) internal database id
Arg [-ADAPTOR]: (optional) Bio::EnsEMBL::DBSQL::BaseAdaptor
Example : $feature = Bio::EnsEMBL::Feature->new(-start => 1,
-end => 100,
-strand => 1,
-slice => $slice,
-analysis => $analysis);
Description: Constructs a new Bio::EnsEMBL::Feature. Generally subclasses
of this method are instantiated, rather than this class itself.
Returntype : Bio::EnsEMBL::Feature
Exceptions : Thrown on invalid -SLICE, -ANALYSIS, -STRAND ,-ADAPTOR arguments
Caller : general, subclass constructors
Status : Stable
=cut
sub new {
my $caller = shift;
my $class = ref($caller) || $caller;
my ( $start, $end, $strand, $slice, $analysis,$seqname, $dbID, $adaptor ) =
rearrange(['START','END','STRAND','SLICE','ANALYSIS', 'SEQNAME',
'DBID', 'ADAPTOR'], @_);
if($slice) {
if(!ref($slice) || !($slice->isa('Bio::EnsEMBL::Slice') or $slice->isa('Bio::EnsEMBL::LRGSlice')) ) {
throw('-SLICE argument must be a Bio::EnsEMBL::Slice not '.$slice);
}
}
if($analysis) {
if(!ref($analysis) || !$analysis->isa('Bio::EnsEMBL::Analysis')) {
throw('-ANALYSIS argument must be a Bio::EnsEMBL::Analysis not '.
$analysis);
}
}
if(defined($strand)) {
if(!($strand == 1) && !($strand == -1) && !($strand == 0)) {
throw('-STRAND argument must be 1, -1, or 0');
}
lib/Bio/EnsEMBL/Feature.pm view on Meta::CPAN
$slice = $slice_adaptor->fetch_by_region($p_slice->coord_system()->name(),
$p_slice->seq_region_name(),
undef, #start
undef, #end
1, #strand
$p_slice->coord_system()->version);
my $new_feature;
%$new_feature = %$self;
bless $new_feature, ref $self;
$new_feature->{'start'} = $p_slice->start();
$new_feature->{'end'} = $p_slice->end();
$new_feature->{'strand'} =
($self->{'strand'} == 0) ? 0 : $p_slice->strand();
$new_feature->{'slice'} = $slice;
return $new_feature;
}
=head2 transfer
Arg [1] : Bio::EnsEMBL::Slice $slice
The slice to transfer this feature to
Example : $feature = $feature->transfer($slice);
next if(!defined($feature));
Description: Returns a copy of this feature which has been shifted onto
another slice.
If the new slice is in a different coordinate system the
feature is transformed first and then placed on the slice.
If the feature would be split across a coordinate system
boundary or mapped to a gap undef is returned instead.
If the feature cannot be placed on the provided slice because
it maps to an entirely different location, undef is returned
instead.
Returntype : Bio::EnsEMBL::Feature (or undef)
Exceptions : throw on incorrect argument
throw if feature does not have attached slice
Caller : general, transform()
Status : Stable
=cut
sub transfer {
my $self = shift;
my $slice = shift;
if(!$slice || !ref($slice) || (!$slice->isa('Bio::EnsEMBL::Slice') && !$slice->isa('Bio::EnsEMBL::LRGSlice'))) {
throw('Slice argument is required');
}
#make a shallow copy of the feature to be transfered
my $feature;
%{$feature} = %{$self};
bless $feature, ref($self);
weaken $feature->{adaptor};
my $current_slice = $self->{'slice'};
if(!$current_slice) {
warning("Feature cannot be transfered without attached slice.");
return undef;
}
my $cur_cs = $current_slice->coord_system();
my $dest_cs = $slice->coord_system();
#if we are not in the same coord system a transformation step is needed first
if(!$dest_cs->equals($cur_cs)) {
$feature = $feature->transform($dest_cs->name, $dest_cs->version, $slice);
return undef if(!defined($feature));
$current_slice = $feature->{'slice'};
}
# feature went to entirely different seq_region
if($current_slice->seq_region_name() ne $slice->seq_region_name()) {
return undef;
}
#if the current feature positions are not relative to the start of the
#seq region, convert them so they are
my $cur_slice_start = $current_slice->start();
my $cur_slice_strand = $current_slice->strand();
if($cur_slice_start != 1 || $cur_slice_strand != 1) {
my $fstart = $feature->{'start'};
my $fend = $feature->{'end'};
if($cur_slice_strand == 1) {
$feature->{'start'} = $fstart + $cur_slice_start - 1;
$feature->{'end'} = $fend + $cur_slice_start - 1;
} else {
my $cur_slice_end = $current_slice->end();
$feature->{'start'} = $cur_slice_end - $fend + 1;
$feature->{'end'} = $cur_slice_end - $fstart + 1;
$feature->{'strand'} *= -1;
}
}
my $fstart = $feature->{'start'};
my $fend = $feature->{'end'};
#convert to destination slice coords
if($slice->strand == 1) {
$feature->{'start'} = $fstart - $slice->start() + 1;
$feature->{'end'} = $fend - $slice->start() + 1;
} else {
$feature->{'start'} = $slice->end() - $fend + 1;
$feature->{'end'} = $slice->end() - $fstart + 1;
$feature->{'strand'} *= -1;
}
$feature->{'slice'} = $slice;
return $feature;
}
( run in 0.958 second using v1.01-cache-2.11-cpan-600a1bdf6e4 )