Skip to content
Snippets Groups Projects
Commit 00c2dd8c authored by Andy Yates's avatar Andy Yates
Browse files

Adding an iterator for subseqs to the Slice object. Means a lot of our code...

Adding an iterator for subseqs to the Slice object. Means a lot of our code which deals with iteration of slices can delegate to this for its logic.
parent 2ffc9730
No related branches found
No related tags found
No related merge requests found
......@@ -68,6 +68,7 @@ use Bio::EnsEMBL::RepeatMaskedSlice;
use Bio::EnsEMBL::Utils::Sequence qw(reverse_comp);
use Bio::EnsEMBL::ProjectionSegment;
use Bio::EnsEMBL::Registry;
use Bio::EnsEMBL::Utils::Iterator;
use Bio::EnsEMBL::DBSQL::MergedAdaptor;
use Bio::EnsEMBL::StrainSlice;
......@@ -663,6 +664,37 @@ sub subseq {
return $subseq;
}
=head2 sub_Slice_Iterator
Arg[1] : int The chunk size to request
Example : my $i = $slice->sub_Slice_Iterator(60000);
while($i->has_next()) { warn $i->next()->name(); }
Description : Returns an iterator which batches subslices of this Slice
in the requested chunk size
Returntype : Bio::EnsEMBL::Utils::Iterator next() will return the next
chunk of Slice
Exceptions : None
=cut
sub sub_Slice_Iterator {
my ($self, $chunk_size) = @_;
throw "Need a chunk size to divide the slice by" if ! $chunk_size;
my $here = 1;
my $end = $self->length();
my $iterator_sub = sub {
while($here <= $end) {
my $there = $here + $chunk_size - 1;
$there = $end if($there > $end);
my $slice = $self->sub_Slice($here, $there);
$here = $there + 1;
return $slice;
}
return;
};
return Bio::EnsEMBL::Utils::Iterator->new($iterator_sub);
}
=head2 assembly_exception_type
Example : $self->assembly_exception_type();
......
use strict;
use warnings;
use Test::More tests => 64;
use Test::More;
use Bio::EnsEMBL::Test::TestUtils;
use IO::String;
......@@ -451,3 +451,39 @@ is($hap_slice->assembly_exception_type(), 'HAP', 'Ensuring haplotype regions are
my $chr_one_slice = $slice_adaptor->fetch_by_region('chromosome', '1', 1, 10);
is($chr_one_slice->assembly_exception_type(), 'REF', 'Ensuring reference regions are REF');
#Test slice iterator
{
my $large_slice = $slice_adaptor->fetch_by_region('chromosome', 1, 1, 21);
my $map = sub { $_->length() };
my $si = sub {
my ($chunk) = @_;
return $large_slice->sub_Slice_Iterator($chunk)->map($map)->to_arrayref();
};
is_deeply($si->(100), [21], 'Subslice larger than actual slice gives just 1 slice back');
is_deeply($si->(10), [10,10,1], 'Subslice smaller than actual slice gives 3 slices back');
is_deeply($si->(20), [20,1], 'Subslice just smaller than actual slice gives 2 slices back');
is_deeply($si->(21), [21], 'Subslice equal to slice size gives 1 slice back');
my $slice_count = $large_slice->sub_Slice_Iterator(1)->reduce(sub { $_[0]+1 }, 0);
is($slice_count, 21, 'Giving a subslice size of 1 means 21 slices');
{
my $fake_slice = Bio::EnsEMBL::Slice->new(-SEQ => 'AAACCCTTTGGGA',
-START => 1, -END => 13, -SEQ_REGION_NAME => 'fake',
-COORD_SYSTEM => $coord_system);
my $subseqs = $fake_slice->sub_Slice_Iterator(3)->map(sub { $_->seq() })->to_arrayref();
my $expected = ['AAA','CCC','TTT','GGG','A'];
is_deeply($subseqs, $expected, 'Calling seq on subslices returns only the sequence for the bounds');
}
{
my $one_bp_slice = Bio::EnsEMBL::Slice->new(-SEQ => 'A',
-START => 1, -END => 1, -SEQ_REGION_NAME => 'fake',
-COORD_SYSTEM => $coord_system);
my $subseqs = $one_bp_slice->sub_Slice_Iterator(1)->map(sub { $_->seq() })->to_arrayref();
my $expected = ['A'];
is_deeply($subseqs, $expected, 'Calling seq on subslices for 1bp slice returns only an A');
}
}
done_testing();
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment