my($self) = @_;
#print STDERR "transforming ".$self." to raw contig coords\n";
$self->throw("can't transform coordinates of $self without a contig defined")
unless $self->contig;
my $slice = $self->contig;
unless($slice->adaptor) {
$self->throw("can't transform coordinates of $self without an adaptor " .
"attached to the feature's slice");
}
my $dbh = $slice->adaptor->db;
my $mapper =
$dbh->get_AssemblyMapperAdaptor->fetch_by_type($slice->assembly_type);
my $rca = $dbh->get_RawContigAdaptor;
#first convert the features coordinates to assembly coordinates
my($start, $end, $strand);
if($slice->strand == 1) {
$start = $slice->chr_start + $self->start - 1;
$end = $slice->chr_start + $self->end - 1;
$strand = $self->strand;
} else {
$start = $slice->chr_end - $self->end + 1;
$end = $slice->chr_end - $self->start + 1;
$strand = $self->strand * -1;
}
#convert the assembly coordinates to RawContig coordinates
my @mapped = $mapper->map_coordinates_to_rawcontig(
$slice->chr_name,
$start,
$end,
$strand
);
unless (@mapped) {
$self->throw("couldn't map $self");
return $self;
}
if (@mapped == 1) {
if ($mapped[0]->isa("Bio::EnsEMBL::Mapper::Gap")) {
$self->warn("feature lies on gap\n");
return;
}
my $rc = $rca->fetch_by_dbID($mapped[0]->id);
$self->start ($mapped[0]->
start);
$self->end ($mapped[0]->
end);
$self->strand ($mapped[0]->
strand);
$self->seqname ($mapped[0]->id);
#print STDERR "setting contig to be ".$mapped[0]->id."\n";
$self->contig($rca->fetch_by_dbID($mapped[0]->id));
return $self;
}
else {
# more than one object returned from mapper
# possibly more than one RawContig in region
my (@gaps, @coords);
foreach my $m (@mapped) {
if ($m->isa("Bio::EnsEMBL::Mapper::Gap")) {
push @gaps, $m;
}
elsif ($m->isa("Bio::EnsEMBL::Mapper::Coordinate")) {
push @coords, $m;
}
}
# case where only one RawContig maps
if (@coords == 1) {
$self->start ($coords[0]->
start);
$self->end ($coords[0]->
end);
$self->strand ($coords[0]->
strand);
$self->seqname($coords[0]->id);
#print STDERR "2 setting contig to be ".$coords[0]->id."\n";
$self->contig ($rca->fetch_by_dbID($coords[0]->id));
$self->warn("Feature [$self] truncated as lies partially on a gap");
return $self;
}
unless ($self->is_splittable) {
$self->warn("Feature spans >1 raw contig - can't split\n");
return;
}
my @out;
my $obj = ref $self;
SPLIT: foreach my $map (@mapped) {
if ($map->isa("Bio::EnsEMBL::Mapper::Gap")) {
$self->warn("piece of evidence lies on gap\n");
next SPLIT;
}
my $feat = $obj->new;
$feat->start ($map->start);
$feat->end ($map->end);
$feat->strand ($map->strand);
#print STDERR "3 setting contig to be ".$mapped[0]->id."\n";
$feat->contig ($rca->fetch_by_dbID($map->id));
$feat->adaptor($self->adaptor) if $self->adaptor();
$feat->display_label($self->display_label) if($self->can('display_label'));
$feat->analysis($self->analysis);
push @out, $feat;
}
return @out;
}
}