my $self = shift;
my $return_all = shift || 0;
my $slice = $self->{'slice'} or return [];
my $sa = $slice->adaptor() or return [];
# get slice of entire region
$slice = $sa->fetch_by_seq_region_id($slice->get_seq_region_id);
my $axfa = $sa->db->get_AssemblyExceptionFeatureAdaptor();
my $axfs = $axfa->fetch_all_by_Slice($slice);
my (@haps, @alt);
foreach my $axf (@$axfs) {
if(uc($axf->type()) eq 'HAP') {
push @haps, $axf;
} elsif(uc($axf->type()) =~ 'PAR') {
push @alt, $axf;
} elsif( $axf->type() eq "PATCH_FIX"){
push @haps, $axf;
} elsif( $axf->type() eq "PATCH_FIX REF"){
push @haps, $axf if $return_all > 0 ;
} elsif( $axf->type() eq "HAP REF" ) {
push @haps, $axf if $return_all > 0 ;
# do nothing when you are on REF
} elsif( $axf->type() eq "PATCH_NOVEL"){
push @haps, $axf;
}elsif( $axf->type() eq "PATCH_NOVEL REF"){
push @haps, $axf if $return_all > 0 ;
} else {
warning("Unknown exception feature type ". $axf->type()."- ignoring.");
}
}
# regions surrounding hap are those of interest, not hap itself
# convert hap alt. exc. features to regions around haps instead
foreach my $h (@haps) {
my $haslice = $h->alternate_slice();
my $hacs = $haslice->coord_system();
if($h->start() > 1 && $haslice->start() > 1) {
my $aslice = $sa->fetch_by_region($hacs->name(),
$haslice->seq_region_name(),
1,
$haslice->start()-1,
$haslice->strand(),
$hacs->version());
-alternate_slice => $aslice);
}
if($h->end() < $slice->seq_region_length() &&
$haslice->end < $haslice->seq_region_length()) {
my $aslice = $sa->fetch_by_region($hacs->name(),
$haslice->seq_region_name(),
$haslice->end()+1,
$haslice->seq_region_length(),
$haslice->strand(),
$hacs->version());
(-
start => $h->end() + 1,
-
end => $slice->seq_region_length(),
-alternate_slice => $aslice);
}
}
# check if exception regions contain our feature
my @features;
foreach my $axf (@alt) {
# ignore other region if feature is not entirely on it
next if($self->seq_region_start() < $axf->start() ||
$self->seq_region_end() > $axf->end());
# quick shallow copy of the feature
my $f;
%$f = %$self;
bless $f, ref($self);
my $aslice = $axf->alternate_slice();
# position feature on entire slice of other region
# Cache seq_region_* to prevent contamination when changing feature coordinates.
my $seq_region_start = $f->seq_region_start();
my $seq_region_end = $f->seq_region_end();
$f->{'start'} = $seq_region_start - $axf->start() + $aslice->start();
$f->{'end'} = $seq_region_end - $axf->start() + $aslice->start();
$f->{'strand'} *= $aslice->strand();
$f->{'slice'} = $sa->fetch_by_seq_region_id($aslice->get_seq_region_id());
push @features, $f;
}
return \@features;
}