File Coverage

blib/lib/CracTools/GenomeMask.pm
Criterion Covered Total %
statement 94 99 94.9
branch 18 30 60.0
condition 2 3 66.6
subroutine 15 15 100.0
pod 10 10 100.0
total 139 157 88.5


line stmt bran cond sub pod time code
1             package CracTools::GenomeMask;
2              
3             {
4             $CracTools::GenomeMask::DIST = 'CracTools';
5             }
6             # ABSTRACT: A bit vector mask over the whole genome
7             $CracTools::GenomeMask::VERSION = '1.251';
8 1     1   14268 use strict;
  1         3  
  1         23  
9 1     1   5 use warnings;
  1         2  
  1         22  
10              
11 1     1   334 use CracTools::BitVector;
  1         3  
  1         42  
12 1     1   367 use CracTools::Utils;
  1         3  
  1         25  
13 1     1   6 use Carp;
  1         2  
  1         733  
14              
15             #You can also define is the genome should be consider as uniquely stranded or as double stranded
16             #with the C argument.
17              
18              
19             sub new {
20 3     3 1 1925 my $class = shift;
21              
22 3         9 my %args = @_;
23              
24             # the genome mask is not stranded by default
25             #my $is_stranded = defined $args{is_stranded}? $args{is_stranded} : 0;
26 3 50       10 my $verbose = defined $args{verbose}? $args{verbose} : 0;
27              
28 3         5 my %bit_vectors;
29              
30 3 100       14 if(defined $args{genome}) {
    100          
    50          
31              
32 1         2 foreach my $chr (keys %{$args{genome}}) {
  1         5  
33 2 50       5 if(!defined $bit_vectors{$chr}) {
34 2         10 $bit_vectors{$chr} = CracTools::BitVector->new($args{genome}->{$chr});
35             } else {
36 0         0 croak "Multiple definition of sequence $chr inf the genome lengths";
37             }
38             }
39             } elsif(defined $args{crac_index_conf}) {
40 1 50       5 print STDERR "Creating GenomeMask from crac index conf file : $args{crac_index_conf}\n" if $verbose;
41 1         6 my $conf_fh = CracTools::Utils::getReadingFileHandle($args{crac_index_conf});
42 1         8 my $nb_chr = <$conf_fh>;
43 1         2 my $nb_chr_found = 0;
44 1         4 while(<$conf_fh>) {
45 24         315 my $chr = $_;
46 24         36 chomp $chr;
47 24         39 my $chr_length = <$conf_fh>;
48 24         28 chomp $chr_length;
49 24 50       45 if(defined $chr_length) {
50 24 50       46 print STDERR "\tCreating bitvecor for chr $chr of length $chr_length\n" if $verbose;
51 24         58 $bit_vectors{$chr} = CracTools::BitVector->new($chr_length);
52 24         64 $nb_chr_found++;
53             } else {
54 0         0 croak "Missing genome length for chromosome $chr";
55             }
56             }
57 1 50       13 croak "There is less chromosome found ($nb_chr_found) in $args{crac_index_conf} than expected ($nb_chr)" if $nb_chr_found < $nb_chr;
58             } elsif(defined $args{sam_reader}) {
59 1         5 my $refseq_lengths = $args{sam_reader}->allRefSeqLengths();
60 1         3 foreach my $chr (keys %{$refseq_lengths}) {
  1         5  
61 24         61 $bit_vectors{$chr} = CracTools::BitVector->new($refseq_lengths->{$chr});
62             }
63             } else {
64 0         0 croak "There is no valid argument to extract the chromosomes names and length";
65             }
66              
67 3         15 my $self = bless {
68             bit_vectors => \%bit_vectors,
69             #is_stranded => $is_stranded,
70             }, $class;
71              
72 3         11 return $self;
73             }
74              
75             #=head2 isStranded
76             #
77             # Description : Return true is genomeMask is double stranded
78             #
79             #=cut
80             #
81             #sub isStranded {
82             # my $self = shift;
83             # return $self->{is_stranded};
84             #}
85              
86             #Arg [2] : Integer (1,-1) - strand
87              
88             sub getBitvector {
89 27     27 1 38 my $self = shift;
90 27         39 my $chr = shift;
91             #my $strand = shift;
92 27 50       57 if(defined $self->{bit_vectors}->{$chr}) {
93 27         66 return $self->{bit_vectors}->{$chr};
94             } else {
95 0         0 carp "There is no bitvector for sequence $chr in the genome mask";
96 0         0 return undef;
97             }
98             }
99              
100              
101             sub getChrLength {
102 3     3 1 56 my $self = shift;
103 3         4 my $chr = shift;
104 3         9 my $bv = $self->getBitvector($chr);
105 3 50       14 return defined $bv? $bv->length : undef;
106             }
107              
108              
109             sub setPos {
110 6     6 1 11 my ($self,$chr,$pos) = @_;
111 6         12 my $bv = $self->getBitvector($chr);
112 6 50       22 $bv->set($pos) if defined $bv;
113             }
114              
115              
116             sub setRegion {
117 1     1 1 4 my ($self,$chr,$start,$end) = @_;
118 1         4 for(my $i = $start; $i <= $end; $i++) {
119 4         11 $self->setPos($chr,$i);
120             }
121             }
122              
123            
124             sub getPos {
125 5     5 1 12 my ($self,$chr,$pos) = @_;
126 5         11 my $bv = $self->getBitvector($chr);
127 5 50       20 return $bv->get($pos) if defined $bv;
128             }
129              
130              
131             sub getPosSetInRegion {
132 2     2 1 5 my ($self,$chr,$start,$end) = @_;
133 2         5 my $bv = $self->getBitvector($chr);
134 2         4 my @pos;
135 2 50       6 if(defined $bv) {
136 2         6 for(my $i = $start; $i <= $end; $i++) {
137 13 100       28 push(@pos,$i) if $bv->get($i) == 1;
138             }
139             }
140 2         8 return \@pos;
141             }
142              
143              
144             sub getNbBitsSetInRegion {
145 1     1 1 2 my $self = shift;
146 1         2 return scalar @{$self->getPosSetInRegion(@_)};
  1         4  
147             }
148              
149              
150             sub rank {
151 2     2 1 1484 my ($self,$chr,$pos) = @_;
152 2         5 my $cumulated_bits = 0;
153 2         3 my $i = 0;
154 2         5 my @chr_sorted = sort keys %{$self->{bit_vectors}};
  2         10  
155 2         8 while($chr_sorted[$i] ne $chr) {
156 2         9 $cumulated_bits += $self->getBitvector($chr_sorted[$i])->nb_set;
157 2         6 $i++;
158             }
159 2         5 return $cumulated_bits + $self->getBitvector($chr_sorted[$i])->rank($pos);
160             }
161              
162              
163             sub select {
164 1     1 1 3 my $self = shift;
165 1         2 my $i = shift;
166 1         7 my $cumulated_bits = 0;
167 1         2 my @chr_sorted = sort keys %{$self->{bit_vectors}};
  1         6  
168 1         2 my $j = 0;
169 1   66     7 while($j < @chr_sorted && $cumulated_bits + $self->getBitvector($chr_sorted[$j])->nb_set < $i) {
170 2         4 my $chr = $chr_sorted[$j];
171 2         6 my $bv = $self->getBitvector($chr);
172 2         4 $cumulated_bits += $self->getBitvector($chr)->nb_set;
173 2         6 $j++;
174             }
175 1         3 my $chr = $chr_sorted[$j-1];
176 1         3 my $pos = $self->getBitvector($chr_sorted[$j-1])->select($i - $cumulated_bits + 1);
177 1         4 return ($chr,$pos);
178             }
179              
180             1;
181              
182             __END__