Bio-Das
view release on metacpan or search on metacpan
Das/Feature.pm view on Meta::CPAN
return shift->strand eq '-';
}
sub seq {
my $self = shift;
my $seg = $self->segment or return;
my $das = $seg->das or return;
my $newseg = $das->segment($self->seq_id,$self->start,$self->end);
my $dna = $newseg->dna;
if ($self->strand < 0) {
$dna =~ tr/gatcGATC/ctagCTAG/;
$dna = reverse $dna;
}
$dna;
}
sub get_SeqFeatures {
my $self = shift;
my $type = shift;
my $subfeat = $self->{subfeatures} or return;
$self->sort_features;
my @a;
if ($type) {
my $features = $subfeat->{lc $type} or return;
@a = @{$features};
} else {
@a = map {@{$_}} values %{$subfeat};
}
return @a;
}
sub add_subfeature {
my $self = shift;
my $feature = shift;
my $type = $feature->method;
my $subfeat = $self->{subfeatures}{lc $type} ||= [];
push @{$subfeat},$feature;
}
# adjust a feature so that its boundaries are synched with its subparts' boundaries.
# this works recursively, so subfeatures can contain other features
sub adjust_bounds {
my $self = shift;
my $t = $self->{target};
if (my $subfeat = $self->{subfeatures}) {
for my $list (values %$subfeat) {
for my $feat (@$list) {
# fix up our bounds to hold largest subfeature
my($start,$stop,$strand) = $feat->adjust_bounds;
$self->{fstrand} = $strand unless defined $self->{fstrand};
if ($start <= $stop) {
$self->{start} = $start if !defined($self->{start}) || $start < $self->{start};
$self->{stop} = $stop if !defined($self->{stop}) || $stop > $self->{stop};
} else {
$self->{start} = $start if !defined($self->{start}) || $start > $self->{start};
$self->{stop} = $stop if !defined($self->{stop}) || $stop < $self->{stop};
}
# fix up endpoints of targets too
my $st = $feat->{target};
next unless $t && $st;
($start,$stop) = (@{$st}[1,2]);
if ($start < $stop) {
$t->[1] = $start if !defined($t->[1]) || $start < $t->[1]; # start
$t->[2] = $stop if !defined($t->[2]) || $stop > $t->[2]; # stop
} else {
$t->[1] = $start if !defined($t->[1]) || $start > $t->[1]; # start
$t->[2] = $stop if !defined($t->[2]) || $stop < $t->[2];
}
}
}
}
($self->{start},$self->{stop},$self->strand);
}
# sort features
sub sort_features {
my $self = shift;
return if $self->{sorted}++;
my $strand = $self->strand or return;
my $subfeat = $self->{subfeatures} or return;
for my $type (keys %$subfeat) {
$subfeat->{$type} = [map { $_->[0] }
sort {$a->[1] <=> $b->[1] }
map { [$_,$_->start] }
@{$subfeat->{$type}}] if $strand > 0;
$subfeat->{$type} = [map { $_->[0] }
sort {$b->[1] <=> $a->[1]}
map { [$_,$_->start] }
@{$subfeat->{$type}}] if $strand < 0;
}
}
sub compound {
my $self = shift;
my $d = $self->{compound};
$self->{compound} = shift if @_;
$d;
}
sub primary_tag { shift->type }
sub class { shift->method }
sub source_tag { shift->method }
sub source {
my $type = shift->type;
my ($method,$source) = split ':',$type;
return $source;
}
sub gff_string {
my $self = shift;
return join "\t",(
$self->refseq,
$self->method,
$self->type,
$self->start,
$self->end,
$self->score,
$self->{orientation},
( run in 1.448 second using v1.01-cache-2.11-cpan-63c85eba8c4 )