3 See the NOTICE file distributed with
this work
for additional information
4 regarding copyright ownership.
6 Licensed under the Apache License, Version 2.0 (the
"License");
7 you may not use
this file except in compliance with the License.
8 You may obtain a copy of the License at
12 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an
"AS IS" BASIS,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 See the License
for the specific language governing permissions and
16 limitations under the License.
23 Please email comments or questions to the
public Ensembl
24 developers list at <http:
26 Questions may also be sent to the Ensembl help desk at
37 # get a reference slice
39 $slice_adaptor->fetch_by_region(
'chromosome', 14, 900000, 950000 );
41 # create MappedSliceContainer based on the reference slice
44 # set the adaptor for fetching AssemblySlices
46 $msc->set_AssemblySliceAdaptor($asa);
48 # add an AssemblySlice to your MappedSliceContainer
49 $msc->attach_AssemblySlice(
'NCBIM36');
51 foreach my $mapped_slice ( @{ $msc->get_all_MappedSlices } ) {
52 print $mapped_slice->name,
"\n";
54 foreach my $sf ( @{ $mapped_slice->get_all_SimpleFeatures } ) {
55 print
" ", &to_string($sf),
"\n";
61 NOTE:
this code is under development and not fully functional nor tested
62 yet. Use only
for development.
64 This
object represents a mapped slice, i.e. a slice that
's attached
65 to a reference slice and a mapper to convert coordinates to/from the
66 reference. The attachment is done via a MappedSliceContainer which
67 has the reference slice and the "container slice" defining the common
68 coordinate system for all MappedSlices.
70 A MappedSlice is supposed to behave as close to a Bio::EnsEMBL::Slice
71 as possible. Most Slice methods are implemented in MappedSlice and will
72 return an equivalent value to what Slice does. There are some exceptions
73 of unimplemented methods, either because there is no useful equivalent
74 for a MappedSlice to do, or they are too complicated.
76 Not supported Bio::EnsEMBL::Slice methods:
78 All Bio::PrimarySeqI compliance methods
84 Not currently supported but maybe should/could:
93 Internally, a MappedSlice is a collection of Bio::EnsEMBL::Slices and
94 associated Bio::EnsEMBL::Mappers which map the slices to the common
95 container coordinate system.
97 MappedSlices are usually created and attached to a MappedSliceContainer
98 by an adaptor/factory.
103 add_Slice_Mapper_pair
104 get_all_Slice_Mapper_pairs
118 seq (not implemented yet)
119 subseq (not implemented yet)
120 get_repeatmasked_seq (not implemented yet)
121 sub_MappedSlice (not implemented yet)
122 project (not implemented yet)
124 =head1 RELATED MODULES
126 Bio::EnsEMBL::MappedSlice
127 Bio::EnsEMBL::DBSQL::AssemblySliceAdaptor
128 Bio::EnsEMBL::Compara::AlignSlice
129 Bio::EnsEMBL::Compara::AlignSlice::Slice
130 Bio::EnsEMBL::StrainSlice
134 package Bio::EnsEMBL::MappedSlice;
138 no warnings 'uninitialized
';
140 use Bio::EnsEMBL::Utils::Argument qw(rearrange);
141 use Bio::EnsEMBL::Utils::Exception qw(throw warning);
142 use Bio::EnsEMBL::Mapper;
143 use Scalar::Util qw(weaken);
145 use vars qw($AUTOLOAD);
150 Arg [ADAPTOR] : Adaptor $adaptor - an adaptor of the appropriate type
151 Arg [CONTAINER] : Bio::EnsEMBL::MappedSliceContainer $container - the
152 container this MappedSlice is attached to
153 Arg [NAME] : String $name - name
154 Example : my $mapped_slice = Bio::EnsEMBL::MappedSlice->new(
155 -ADAPTOR => $adaptor,
156 -CONTAINER => $container,
159 Description : Constructor. Usually you won't call
this method manually, but
160 the
MappedSlice will be constructed by an adaptor/factory.
162 Exceptions : thrown on wrong or missing arguments
171 my $class = ref($caller) || $caller;
173 my ($adaptor, $container, $name) =
174 rearrange([qw(ADAPTOR CONTAINER NAME)], @_);
177 unless ($container and ref($container) and
178 $container->isa(
'Bio::EnsEMBL::MappedSliceContainer')) {
179 throw(
"Need a MappedSliceContainer.");
183 bless ($self, $class);
189 # need to weaken reference to prevent circular reference
190 weaken($self->{
'container'} = $container);
192 $self->adaptor($adaptor)
if (defined($adaptor));
193 $self->{
'name'} = $name
if (defined($name));
195 $self->{
'slice_mapper_pairs'} = [];
201 =head2 add_Slice_Mapper_pair
205 Example : $mapped_slice->add_Slice_Mapper_pair($slice, $mapper);
206 Description : Adds a native slice and a corresponding mapper to
map to/from
207 the artificial container coord system.
209 Exceptions : thrown on wrong or missing arguments
210 Caller : general, MappedSlice adaptors
216 sub add_Slice_Mapper_pair {
222 unless ($slice and ref($slice) and ($slice->isa(
'Bio::EnsEMBL::Slice') or $slice->isa(
'Bio::EnsEMBL::LRGSlice')) ) {
223 throw(
"You must provide a slice.");
226 unless ($mapper and ref($mapper) and $mapper->isa(
'Bio::EnsEMBL::Mapper')) {
227 throw(
"You must provide a mapper.");
230 push @{ $self->{
'slice_mapper_pairs'} }, [ $slice, $mapper ];
232 return $self->{
'slice_mapper_pairs'};
236 =head2 get_all_Slice_Mapper_pairs
238 Example :
foreach my $pair (@{ $self->get_all_Slice_Mapper_pairs }) {
239 my ($slice, $mapper) = @$pair;
241 # get container coordinates
242 my @coords = $mapper->map_coordinates(
243 $slice->seq_region_name,
252 Description : Gets all Slice/Mapper pairs
this MappedSlice is composed of.
253 Each slice (and features on it) can be mapped onto the
254 artificial container coord system
using the mapper.
264 sub get_all_Slice_Mapper_pairs {
266 return $self->{
'slice_mapper_pairs'};
272 Arg[1] : (optional) Adaptor $adaptor - the adaptor/factory
for this
274 Example : $mapped_slice->adaptor($assembly_slice_adaptor);
275 Description : Getter/setter
for the adaptor/factory
for this object.
276 Return type : Adaptor of appropriate type
286 weaken($self->{
'adaptor'} = shift)
if (@_);
287 return $self->{
'adaptor'};
294 this object is attached to
295 Example : my $container = $mapped_slice->container;
297 Description : Getter/setter
for the container
this object is attached to. The
298 container will give you access to the reference slice, a common
299 artificial container slice, and a mapper to
map to it from the
300 container coord system.
302 The implementation uses a weak reference to attach the container
303 since the container holds a list of MappedSlices itself.
314 weaken($self->{
'container'} = shift)
if (@_);
315 return $self->{
'container'};
321 Arg[1] : String - the name of
this object
322 Example : my $name = $mapped_slice->container->
ref_slice->
name .
323 ":mapped_" . $ident_string;
324 $mapped_slice->name($name);
325 Description : Getter/setter
for this object's name
336 $self->{'name
'} = shift if (@_);
337 return $self->{'name
'};
341 =head2 seq_region_name
343 Example : my $sr_name = $mapped_slice->seq_region_name;
344 Description : Returns the seq_region name of the reference slice.
353 sub seq_region_name {
355 return $self->container->ref_slice->seq_region_name;
361 Example : my $start = $mapped_slice->start;
362 Description : Returns the start of the container slice.
373 return $self->container->container_slice->start;
379 Example : my $end = $mapped_slice->end;
380 Description : Returns the end of the container slice.
391 return $self->container->container_slice->end;
397 Example : my $strand = $mapped_slice->strand;
398 Description : Returns the strand of the container slice.
409 return $self->container->container_slice->strand;
415 Example : my $length = $mapped_slice->length;
416 Description : Returns the length of the container slice
427 return $self->container->container_slice->length;
431 =head2 seq_region_length
433 Example : my $sr_length = $mapped_slice->seq_region_length;
434 Description : Returns the seq_region length of the reference slice.
443 sub seq_region_length {
445 return $self->container->ref_slice->seq_region_length;
451 Example : my $centrepoint = $mapped_slice->centrepoint;
452 Description : Returns the centrepoint of the container slice.
463 return $self->container->container_slice->centrepoint;
469 Example : my $cs = $mapped_slice->coord_system;
470 Description : Returns the coord system of the container slice.
471 Return type : Bio::EnsEMBL::CoordSystem
481 return $self->container->container_slice->coord_system;
484 =head2 coord_system_name
486 Example : my $cs_name = $mapped_slice->coord_system_name;
487 Description : Returns the coord system name of the container slice.
496 sub coord_system_name {
498 return $self->container->container_slice->coord_system_name;
503 Example : my $toplevel_flag = $mapped_slice->is_toplevel;
504 Description : Returns weather the container slice is toplevel.
515 return $self->container->container_slice->is_toplevel;
521 Example : my $seq = $mapped_slice->seq()
522 Description : Retrieves the expanded sequence of this mapped slice,
523 including "-" characters where there are inserts in any other
524 mapped slices. This will align with the sequence returned by
525 the container's seq() method.
537 # create an empty string
540 # this coord represents the current position in the MS sequence
543 # get slice/mapper pairs from mapped slice (usually only one anyway)
544 foreach my $pair(@{$self->get_all_Slice_Mapper_pairs()}) {
545 my ($s, $m) = @$pair;
547 # make sure to send extra args
548 # eg strain slices might need read coverage filtering
549 my $seq = $s->seq(@_);
551 # project from mapped slice to reference slice using the mapper
552 foreach my $ref_coord($m->map_coordinates(
'mapped_slice', 1, CORE::length($seq), $s->strand,
'mapped_slice')) {
555 if(!$ref_coord->isa(
'Bio::EnsEMBL::Mapper::IndelCoordinate') && !$ref_coord->isa(
'Bio::EnsEMBL::Mapper::Gap')) {
557 # project from reference slice to container slice using the container's mapper
558 foreach my $ms_coord($self->container->mapper->map_coordinates($self->container->ref_slice->seq_region_name, $ref_coord->start, $ref_coord->end, $ref_coord->strand,
'ref_slice')) {
561 if(!$ms_coord->isa(
'Bio::EnsEMBL::Mapper::IndelCoordinate') && !$ms_coord->isa(
'Bio::EnsEMBL::Mapper::Gap')) {
562 $ms_seq .= substr($seq, $start, $ms_coord->length);
564 $start += $ms_coord->length();
569 $ms_seq .=
'-' x $ms_coord->length();
576 if($ref_coord->isa(
'Bio::EnsEMBL::Mapper::IndelCoordinate')) {
577 if($ref_coord->gap_length > 0) {
578 $ms_seq .= substr($seq, $start, $ref_coord->gap_length);
579 $start += $ref_coord->gap_length;
581 $ms_seq .=
'-' x ($ref_coord->length() - $ref_coord->gap_length());
583 $ms_seq .=
'-' x $ref_coord->length();
595 sub get_repeatmasked_seq {
598 sub sub_MappedSlice {
607 Arg[1..N] : Arguments passed on to the calls on the underlying slices.
608 Example : my @simple_features = @{ $mapped_slice->get_all_SimpleFeatures };
609 Description : Aggregate data gathered from composing Slices.
610 This will call Slice->get_all_* and combine the results.
611 Coordinates will be transformed to be on the container slice
614 Calls involving DAS features are skipped since the DAS adaptor
615 handles coordinate conversions natively.
616 Return type : listref of features (same type as corresponding Slice method)
627 my $method = $AUTOLOAD;
630 # AUTOLOAD should only deal with get_all_* methods
631 return unless ($method =~ /^get_all_/);
634 return if ($method =~ /DAS/);
636 my @mapped_features = ();
638 foreach my $pair (@{ $self->get_all_Slice_Mapper_pairs }) {
639 my ($slice, $mapper) = @$pair;
642 # call $method on each native slice composing the MappedSlice
643 my @features = @{ $slice->$method(@_) };
645 # map features onto the artificial container coordinate system
646 foreach my $f (@features) {
648 my @coords = $mapper->map_coordinates(
649 $f->slice->seq_region_name,
657 if (scalar(@coords) > 1) {
658 warning(
"Got more than one Coordinate returned, expected only one!\n");
661 $f->start($coords[0]->start);
662 $f->end($coords[0]->end);
663 $f->strand($coords[0]->strand);
664 $f->slice($self->container->container_slice);
666 push @mapped_features, $f;
671 return \@mapped_features;