File Coverage

blib/lib/Bio/Gonzales/Var/Util.pm
Criterion Covered Total %
statement 31 142 21.8
branch 3 42 7.1
condition 0 17 0.0
subroutine 8 22 36.3
pod 0 15 0.0
total 42 238 17.6


line stmt bran cond sub pod time code
1             package Bio::Gonzales::Var::Util;
2              
3 1     1   149657 use warnings;
  1         12  
  1         33  
4 1     1   6 use strict;
  1         2  
  1         20  
5 1     1   4 use Carp;
  1         2  
  1         49  
6              
7 1     1   20 use 5.010;
  1         5  
8              
9 1     1   7 use Exporter 'import';
  1         2  
  1         42  
10              
11 1     1   634 use List::MoreUtils qw/uniq/;
  1         13422  
  1         7  
12 1     1   1095 use List::Util qw/max/;
  1         3  
  1         1753  
13              
14             our $VERSION = 0.01_01;
15              
16             our %EXPORT_TAGS = (
17             'all' => [
18             qw/
19             get_allele_obs
20             parse_format
21             geno_count_gt
22             geno_hom_het_part
23             geno_is_poly
24             geno_major_alleles
25             geno_nhet
26             geno_nmissing
27             geno2haplo
28             renumber_genotypes
29             merge_alleles
30             geno_get_gt_simple
31             geno_get_gt
32             geno_get_field
33             geno_nuniq/
34             ]
35             );
36              
37             our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
38              
39             sub get_allele_obs {
40 0     0 0 0 my $fmt = shift;
41 0         0 my $call = shift;
42              
43 0         0 my @call = split /:/, $call;
44 0         0 my $ad_idx = $fmt->{'AD'};
45 0         0 my $ao_idx = $fmt->{'AO'};
46 0         0 my $ro_idx = $fmt->{'RO'};
47              
48 0 0 0     0 if ( defined($ad_idx) ) {
    0          
49              
50 0         0 my @dp = split /,/, $call[$ad_idx];
51 0         0 return \@dp;
52             } elsif ( defined($ao_idx) && defined($ro_idx) ) {
53 0         0 my @dp = ( $call[$ro_idx], split( /,/, $call[$ao_idx] ) );
54 0         0 return \@dp;
55              
56             } else {
57 0         0 return;
58             }
59             }
60              
61             sub geno2haplo {
62 0     0 0 0 my $genotypes = shift;
63 0         0 my $ploidy = shift;
64              
65 0 0       0 die "no ploidy defined for geno2haplo" unless ( defined($ploidy) );
66             # check if also coverage, etc. is part of the genotype then
67             # split the genotypes into haplotypes
68 0         0 my $phased = 1;
69 0         0 my @haplotypes;
70 0         0 for my $g_raw (@$genotypes) {
71 0 0       0 my $g = index( $g_raw, ':' ) >= 0 ? substr( $g_raw, 0, index( $g_raw, ':' ) ) : $g_raw;
72             # we need to find only one genotype of x/y to set phased to false
73 0   0     0 $phased &&= not index( $g, '|' ) < 0;
74 0         0 my @h = split /[|\/]/, $g;
75 0 0 0     0 @h = ('.') x $ploidy if ( @h == 1 && $h[0] eq '.' );
76 0 0       0 die "ploidy mismatch in geno2haplo" if ( @h != $ploidy );
77 0         0 push @haplotypes, @h;
78             }
79 0         0 return ( \@haplotypes, $phased );
80             }
81              
82             sub renumber_genotypes {
83 1     1 0 1096 my ( $map, $genotypes, ) = @_;
84 1         3 my @renumbered;
85 1         3 for my $g_raw (@$genotypes) {
86 3         8 my $idx = index( $g_raw, ':' );
87 3 50       70 my $g = $idx >= 0 ? substr( $g_raw, 0, $idx ) : $g_raw;
88 3         20 my @g_split = split /([|\/])/, $g;
89 3         11 for ( my $i = 0; $i < @g_split; $i += 2 ) {
90 6 50       22 $g_split[$i] = $map->[ $g_split[$i] ] if ( $g_split[$i] ne '.' );
91             }
92 3 50       9 if ( $idx < 0 ) {
93 0         0 $g_raw = join '', @g_split;
94             } else {
95 3         12 substr( $g_raw, 0, $idx, join( '', @g_split ) );
96             }
97             }
98 1         6 return $genotypes;
99             }
100              
101             sub merge_alleles {
102 0     0 0   my ( $ref_alleles, $alleles ) = @_;
103              
104 0           my $i = 0;
105 0           my %ra = map { $_ => $i++ } @$ref_alleles;
  0            
106              
107 0           my @map;
108 0           my @merged_alleles = @$ref_alleles;
109 0           my $allele_idx = @$ref_alleles;
110 0           for ( my $idx = 0; $idx < @$alleles; $idx++ ) {
111 0 0         if ( defined $ra{ $alleles->[$idx] } ) {
112 0           $map[$idx] = $ra{ $alleles->[$idx] };
113             } else {
114 0           $map[$idx] = $allele_idx++;
115 0           push @merged_alleles, $alleles->[$idx];
116             }
117             }
118 0           return ( \@merged_alleles, \@map );
119             }
120              
121             sub geno_get_gt_simple {
122 0     0 0   my $genotypes = shift;
123 0 0         my @res = map { index( $_, ':' ) >= 0 ? substr( $_, 0, index( $_, ':' ) ) : $_ } @$genotypes;
  0            
124 0           return \@res;
125             }
126              
127             sub geno_get_field {
128 0     0 0   my ( $gt, $smp_idcs, $field_idx ) = @_;
129              
130 0           my @gt;
131 0 0 0       $smp_idcs = [ 0 .. ( @$gt - 1 ) ] unless ($smp_idcs && @$smp_idcs);
132 0           for my $i (@$smp_idcs) {
133 0           my $call = $gt->[$i];
134              
135 0           my @fields = split /:/, $call;
136 0           push @gt, $fields[$field_idx];
137             }
138 0           return \@gt;
139             }
140              
141             sub geno_get_gt {
142 0     0 0   my ( $gt, $smp_idcs, $gt_idx ) = @_;
143 0   0       $gt_idx //= 0;
144              
145 0           my @gt;
146 0 0 0       $smp_idcs = [ 0 .. ( @$gt - 1 ) ] unless ($smp_idcs && @$smp_idcs);
147 0           for my $i (@$smp_idcs) {
148 0           my $call = $gt->[$i];
149              
150 0           my @fields = split /:/, $call;
151 0 0         if ( index( $fields[$gt_idx], '.' ) >= 0 ) {
152 0           push @gt, '.';
153             } else {
154 0           push @gt, $fields[$gt_idx];
155             }
156             }
157 0           return \@gt;
158             }
159              
160             sub geno_count_gt {
161 0     0 0   my $gt = shift;
162              
163 0           my %cnt;
164 0           map { $cnt{$_}++ } @$gt;
  0            
165 0           return \%cnt;
166             }
167              
168             sub geno_nhet {
169 0     0 0   my $gt = shift;
170              
171 0           my $nhet = 0;
172 0           for my $g (@$gt) {
173 0           my @called_alleles = split /[\/|]/, $g;
174 0 0         $nhet++ if ( uniq(@called_alleles) > 1 );
175              
176             }
177 0           return $nhet;
178             }
179              
180             sub geno_is_poly {
181 0     0 0   my $gt = shift;
182 0           my @valid_gt = grep { index( $_, '.' ) < 0 } @$gt;
  0            
183 0 0         return 0 unless (@valid_gt);
184 0 0         return uniq(@valid_gt) == 1 ? 0 : 1;
185             }
186              
187             sub geno_nuniq {
188 0     0 0   my $gt = shift;
189 0           my @valid_gt = grep { index( $_, '.' ) < 0 } @$gt;
  0            
190 0 0         return 0 unless (@valid_gt);
191 0           return scalar uniq(@valid_gt);
192             }
193              
194             sub geno_hom_het_part {
195 0     0 0   my $gt = shift;
196 0           my @hom;
197             my @het;
198 0           my $nmissing = 0;
199              
200 0           for my $g (@$gt) {
201 0 0         if ( index( $g, '.' ) >= 0 ) {
202 0           $nmissing++;
203 0           next;
204             }
205 0           my @called_alleles = split /[\/|]/, $g;
206 0 0         if ( uniq(@called_alleles) > 1 ) {
207 0           push @het, $g;
208             } else {
209 0           push @hom, $g;
210             }
211             }
212 0           return ( \@hom, \@het, $nmissing );
213             }
214              
215             sub parse_format {
216 0     0 0   my $v = shift;
217              
218 0           my $idx = 0;
219 0           my %format = map { $_ => $idx++ } split /:/, $v->{format};
  0            
220 0           return \%format;
221             }
222              
223             sub geno_nmissing {
224 0     0 0   my $gt = shift;
225 0           return scalar grep { index( $_, '.' ) >= 0 } @$gt;
  0            
226             }
227              
228             sub geno_major_alleles {
229 0     0 0   my $cnt = shift;
230              
231 0           my @valid = grep { index( $_, '.' ) < 0 } keys %$cnt;
  0            
232 0           my $cnt_major = max @{$cnt}{@valid};
  0            
233 0 0         my @major_alleles = grep { $cnt->{$_} == $cnt_major && index( $_, '.' ) < 0 } @valid;
  0            
234 0           return \@major_alleles;
235             }
236              
237             1;