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