11
|
1 #!/usr/bin/perl
|
|
2 #############################
|
|
3 ## DEEP COVERAGE GENOTYPER ##
|
|
4 #############################
|
|
5 # version : 0.0.1
|
|
6 # Principle:
|
|
7 # 1. get allele counts on all positions in specified targets (bed) using igvtools. Only SNPs !!
|
|
8 # 2. remove known dbsnp positions (bcf file)
|
|
9 # 3. Get distribution of background noise (pcr/sequencing errors), by modelling allele fractions as normal distributions.
|
|
10 # 4. Based on these distributions, check each position for significant change from the reference allele (based on allele fraction)
|
|
11 # 5. For abberant positions, check each alternate allele to see if it passes the background signal.
|
|
12 # 6. Generate VCF file.
|
|
13
|
|
14
|
|
15 ##################
|
|
16 ## LOAD MODULES ##
|
|
17 ##################
|
|
18 use threads;
|
|
19 use threads::shared;
|
|
20 use Thread::Queue;
|
|
21 use Getopt::Std;
|
|
22
|
|
23 ####################
|
|
24 ## get paramaters ##
|
|
25 ####################
|
|
26 # t: target file
|
|
27 # b: bam file
|
12
|
28 # R: reference genome files for twobit and IGV.
|
11
|
29 # p: number of threads.
|
|
30 # s: dbsnp file
|
|
31 # m: minimal coverage (defaults 400x)
|
|
32 # P: ploidy
|
|
33 # a: outfile for allele distributions
|
|
34 # v: vcf file output.
|
|
35 getopts('t:b:R:p:s:m:P:v:a:', \%opts) ;
|
|
36
|
|
37 ## variables
|
|
38 my $twobit :shared;
|
|
39 my $igvgenome :shared;
|
|
40 if (!defined($opts{'R'})) {
|
|
41 die("Reference Genomes not specified\n");
|
|
42 }
|
12
|
43 my @refgenomes = split(",",$opts{'R'});
|
11
|
44 if (!-e $refgenomes[0]) {
|
|
45 die("'$refgenomes[0]' is not a valid file path.");
|
|
46 }
|
|
47 else {
|
|
48 $twobit = $refgenomes[0];
|
|
49 }
|
|
50 if (!-e $refgenomes[1]) {
|
|
51 die("'$refgenomes[1]' is not a valid file path.");
|
|
52 }
|
|
53 else {
|
|
54 $igvgenome = $refgenomes[1];
|
|
55 }
|
|
56
|
|
57
|
|
58 my $mincov :shared;
|
|
59 $mincov = 320;
|
|
60 if (defined($opts{'m'})) {
|
|
61 $mincov = $opts{'m'};
|
|
62 }
|
|
63
|
|
64 my $ploidy :shared;
|
|
65 if (defined($opts{'P'}) && $opts{'P'} =~ m/^\d+$/) {
|
|
66 $ploidy = $opts{'P'};
|
|
67 }
|
|
68 else {
|
|
69 die("Ploidy (-P) was not specified or not an integer\n");
|
|
70 }
|
|
71
|
|
72
|
|
73 if (defined($opts{'v'})) {
|
|
74 $outfile = $opts{'v'};
|
|
75 }
|
|
76 else {
|
|
77 die("No output vcf-file specified.\n");
|
|
78 }
|
|
79 if (!defined($opts{'a'})) {
|
|
80 die("No output file specified for distribution details\n");
|
|
81 }
|
|
82 ## create working dir.
|
|
83 my $rand = int(rand(10000));
|
|
84 while (-d "/tmp/DC_Genotyper_$rand") {
|
|
85 $rand = int(rand(10000));
|
|
86 }
|
|
87 my $wd :shared;
|
|
88 $wd = "/tmp/DC_Genotyper_$rand";
|
|
89 system("mkdir '$wd'");
|
|
90
|
|
91
|
|
92 my $snpfile :shared;
|
|
93 my $hassnp :shared;
|
|
94 $hassnp = 'NoDbSNP';
|
|
95 $snpfile = '';
|
|
96 if (defined($opts{'s'})) {
|
|
97 $snpfile = $opts{'s'};
|
|
98 if (!-e $snpfile) {
|
|
99 die("'$snpfile' is not a valid file path.");
|
|
100 }
|
|
101
|
|
102 my $mime = `file $snpfile`;
|
|
103 if ($mime !~ m/compressed/) {
|
|
104 print "$snpfile is not in compressed format. compressing & indexing the file now.\n";
|
|
105 #print "... this takes a while\n";
|
|
106 system("bgzip -c $snpfile > $wd/dbSNP.vcf.bgz");
|
|
107 system("cd $wd/ && tabix -p vcf dbSNP.vcf.bgz");
|
|
108 $snpfile = "$wd/dbSNP.vcf.bgz";
|
|
109 }
|
|
110 elsif (!-e "$snpfile.tbi") {
|
|
111 print "tabix index file is missing for '$snpfile'. creating now.\n";
|
|
112 ## check if I can write it out for future use
|
|
113 $snpfile =~ m/(.*)([^\/]+)$/;
|
|
114 my $d = $1;
|
|
115 if (-w $d) {
|
|
116 open OUT, ">$d/lock";
|
|
117 flock(OUT,2);
|
|
118 system("cd $d && tabix -p vcf $snpfile");
|
|
119 close OUT;
|
|
120 system("rm $d/lock");
|
|
121 }
|
|
122 else {
|
|
123 system("cp $snpfile /$wd/dbSNP.vcf.bgz");
|
|
124 system("cd $wd/ && tabix -p vcf dbSNP.vcf.bgz");
|
|
125 $snpfile = "$wd/dbSNP.vcf.bgz";
|
|
126 }
|
|
127 }
|
|
128 $hassnp = 'WithDbSNP';
|
|
129 }
|
|
130
|
|
131
|
|
132 ## 1. Get FASTA and prepare output hashes:
|
|
133 my $targets_one = Thread::Queue->new();
|
|
134 my $targets_two = Thread::Queue->new();
|
|
135 my $targets_three = Thread::Queue->new();
|
|
136 open IN, $opts{'t'} or die("Could not open $opts{'t'} file for reading");
|
|
137 if (-d "$wd/Fasta/") {
|
|
138 system("rm $wd/Fasta/*");
|
|
139 }
|
|
140 else {
|
|
141 system("mkdir $wd/Fasta");
|
|
142 }
|
|
143 ## create the threads.
|
|
144 for (my $i = 1; $i<= $opts{'p'}; $i++) {
|
|
145 ${'thr'.$i} = threads->create('FetchFasta');
|
|
146 }
|
|
147
|
|
148 ## enqueue the targets.
|
|
149 my %thash;
|
|
150 while (<IN>) {
|
|
151 chomp;
|
|
152 my ($chr,$start,$stop,$name,$score,$strand) = split(/\t/,$_);
|
|
153 $targets_one->enqueue($_);
|
|
154 $targets_two->enqueue($_);
|
|
155 $targets_three->enqueue($_);
|
|
156 $thash{$chr}{$start} = $stop;
|
|
157 }
|
|
158 close IN;
|
|
159
|
|
160 ## end the threads.
|
|
161 for (my $i = 1; $i <= $opts{'p'}; $i++) {
|
|
162 $targets_one->enqueue(undef);
|
|
163 }
|
|
164
|
|
165 for (my $i = 1; $i <= $opts{'p'}; $i++) {
|
|
166 ${'thr'.$i}->join();
|
|
167 }
|
|
168
|
|
169 ## load dbSNP inside target regions into shared structure.
|
|
170 ##########################################################
|
|
171 my %dbsnp :shared;
|
|
172 if ($snpfile ne '') {
|
16
|
173 #my $bcf = `which bcftools`;
|
|
174 #chomp($bcf);
|
|
175 #if ($bcf ne '') {
|
|
176 # my $command = "bcftools query -f '\%CHROM\\t\%POS\\t\%REF\\t\%ALT\\t\%ID\\n' -R '".$opts{'t'}."' '$snpfile' > $wd/dbsnp.txt";
|
|
177 # system("$command");
|
|
178 # open IN, "$wd/dbsnp.txt";
|
|
179 # while (<IN>) {
|
|
180 # chomp;
|
|
181 # my @p = split(/\t/,$_);
|
|
182 # $dbsnp{$p[0].'-'.$p[1]} = $p[2].'-'.$p[3].'-'.$p[4];
|
|
183 # }
|
|
184 # close IN;
|
|
185 #}
|
|
186 #else {
|
|
187 # print "WARNING: BCFtools is not in the path. Skipping snp handling.\n";
|
|
188 # $snpfile = '';
|
|
189 # system("touch $wd/dbsnp.txt");
|
|
190 #}
|
|
191 system("tabix $snpfile -B $opts{'t'} | cut -f 1-5 > $wd/dbsnp.txt");
|
|
192 my $lc = `cat $wd/dbsnp.txt | wc -l`;
|
|
193 chomp($lc);
|
|
194 if ($lc eq '0') {
|
|
195 open SNP, ">$wd/dbsnp.txt";
|
|
196 ## dummy line on chr zero
|
|
197 print SNP "chr0\t1\t.\tA\tT\n";
|
|
198 close SNP;
|
11
|
199 }
|
|
200 else {
|
16
|
201 open SNP, ">$wd/dbsnp.txt";
|
|
202 ## dummy line on chr zero
|
|
203 print SNP "chr0\t1\t.\tA\tT\n";
|
|
204 close SNP;
|
11
|
205 }
|
|
206
|
|
207 ## now process the bam file.
|
|
208 mkdir "$wd/WIGS/";
|
|
209 my $bam :shared;
|
|
210 $bam = $opts{'b'};
|
|
211 my $bai = $bam.".bai";
|
|
212 if (!-e $bai) {
|
|
213 print "BAI ($bai) missing for $bam : creating\n";
|
|
214 system("samtools index $bam");
|
|
215 }
|
|
216
|
|
217 for (my $i = 1; $i <= $opts{'p'}; $i++) {
|
|
218 ${'thr'.$i} = threads->create('CountAlleles');
|
|
219 }
|
|
220 ## end the threads.
|
|
221 for (my $i = 1; $i <= $opts{'p'}; $i++) {
|
|
222 $targets_two->enqueue(undef);
|
|
223 }
|
|
224
|
|
225 for (my $i = 1; $i <= $opts{'p'}; $i++) {
|
|
226 ${'thr'.$i}->join();
|
|
227 }
|
|
228
|
|
229 ## generate the distributions.
|
|
230 ##############################
|
|
231 my $alleles = Thread::Queue->new();
|
|
232 my %all = ('A' => 1,'C' => 2,'G' => 3, 'T' => 4);
|
|
233 foreach(keys(%all)) {
|
|
234 $alleles->enqueue($_);
|
|
235 my $a = $_;
|
|
236 foreach(keys(%all)) {
|
|
237 if ($_ eq $a) {
|
|
238 next;
|
|
239 }
|
|
240 $alleles->enqueue($a.'-'.$_);
|
|
241 }
|
|
242 }
|
|
243 for (my $i = 1; $i <= $opts{'p'}; $i++) {
|
|
244 ${'thr'.$i} = threads->create('GetDistribution');
|
|
245 }
|
|
246 ## end the threads.
|
|
247 for (my $i = 1; $i <= $opts{'p'}; $i++) {
|
|
248 $alleles->enqueue(undef);
|
|
249 }
|
|
250
|
|
251 for (my $i = 1; $i <= $opts{'p'}; $i++) {
|
|
252 ${'thr'.$i}->join();
|
|
253 }
|
|
254
|
|
255 ## group distributions into one file
|
|
256 ####################################
|
|
257 my %map =('A' => 2,'C' => 3,'G' => 4, 'T' => 5);
|
|
258 open OUT, ">".$opts{'a'};
|
|
259 print OUT "allele\tavg\tsd\n";
|
|
260 foreach(keys(%map)) {
|
|
261 my $r = $_;
|
|
262 my $f = "$wd/model.$r.$mincov"."x.$hassnp.txt";
|
|
263 open IN, "$f";
|
|
264 my $a = <IN>;
|
|
265 chomp($a);
|
|
266 #$dists{$r}{'avg'} = $a;
|
|
267 my $s = <IN>;
|
|
268 chomp($s);
|
|
269 #$dists{$r}{'sd'} = $s;
|
|
270 close IN;
|
|
271 print OUT "$r\t$a\t$s\n";
|
|
272 foreach(keys(%map)) {
|
|
273 if ($_ eq $r) {
|
|
274 next;
|
|
275 }
|
|
276 my $f = "$wd/model.$r-$_.$mincov"."x.$hassnp.txt";
|
|
277 open IN, "$f";
|
|
278 my $a = <IN>;
|
|
279 chomp($a);
|
|
280 my $s = <IN>;
|
|
281 chomp($s);
|
|
282 close IN;
|
|
283 print OUT "$r-$_\t$a\t$s\n";
|
|
284 }
|
|
285 }
|
|
286 close OUT;
|
|
287
|
|
288 ## CALL SNPs
|
|
289 ############
|
|
290 # create the R script.
|
|
291 open R, ">$wd/CallSNPs.R";
|
16
|
292 print R "\n";
|
11
|
293 print R "args <- commandArgs(trailingOnly = TRUE)\n";
|
16
|
294 print R "counts <- read.table(file = args[1],header = FALSE, as.is = TRUE)\n";
|
11
|
295 print R "ploidy <- as.integer(args[3])\n";
|
|
296 print R "chr <- args[2]\n";
|
|
297 print R "snps <- read.table(file=args[5],header=FALSE,as.is=TRUE)\n";
|
16
|
298 print R "colnames(snps) <- c('chr','pos','id','ref','alt')\n";
|
11
|
299 print R "colnames(counts) <- c('pos','ref','A','C','G','T','TotalDepth')\n";
|
16
|
300 print R "dists <- read.table(file='".$opts{'a'}."',header=TRUE,as.is=TRUE)\n";
|
11
|
301 print R 'rownames(dists) = dists$allele'."\n";
|
|
302 print R 'dists <- dists[,-1]'."\n";
|
|
303 print R "vcf <- c()\n";
|
|
304 print R "lower <- c()\n";
|
|
305 print R "higher <- c()\n";
|
|
306 print R "for (i in 1:(ploidy)) {\n";
|
|
307 print R " lower[length(lower)+1] <- (2*i-1)/(2*ploidy)\n";
|
|
308 print R " higher[length(higher)+1] <- (2*i+1)/(2*ploidy)\n";
|
|
309 print R "}\n";
|
|
310 print R "for (i in 1:nrow(counts)) {\n";
|
|
311 print R " if (counts[i,'TotalDepth'] == 0) next\n";
|
|
312 print R " # significantly different from reference?\n";
|
|
313 print R " z <- ((counts[i,counts[i,'ref']]/counts[i,'TotalDepth']) - dists[counts[i,'ref'],'avg']) / dists[counts[i,'ref'],'sd']\n";
|
|
314 print R " if (abs(z) > 3) {\n";
|
|
315 print R " # test all alterate alleles to see which one is significant.\n";
|
|
316 print R " for (j in c('A','C','G','T')) {\n";
|
|
317 print R " if (j == counts[i,'ref']) next\n";
|
|
318 print R " z <- ((counts[i,j]/counts[i,'TotalDepth']) - dists[paste(counts[i,'ref'],'-',j,sep=''),'avg']) / dists[paste(counts[i,'ref'],'-',j,sep=''),'sd']\n";
|
|
319 print R " if (abs(z) > 3){\n";
|
|
320 print R " filter <- 'PASS'\n";
|
|
321 print R " phred <- round(-10*log(pnorm(-abs(z))),digits=0)\n";
|
|
322 print R " if (phred > 9999) phred <- 9999\n";
|
|
323 print R " frac <- counts[i,j]/counts[i,'TotalDepth']\n";
|
|
324 print R " for (k in 1:ploidy) {\n";
|
|
325 print R " if (frac >= lower[k] && frac < higher[k]) {\n";
|
|
326 print R " sample <- paste(paste(paste(rep(0,(ploidy-k)),sep='',collapse='/'),paste(rep(1,k),sep='',collapse='/'),sep='/',collapse=''),':',counts[i,counts[i,'ref']],',',counts[i,j],sep='',collapse='')\n";
|
|
327 print R " af <- k/ploidy\n";
|
|
328 print R " break\n";
|
|
329 print R " }\n";
|
|
330 print R " }\n";
|
|
331 print R " if (frac < lower[1]) {\n";
|
|
332 print R " sample <- paste(paste(paste(rep(0,(ploidy-1)),sep='',collapse='/'),paste(rep(1,1),sep='',collapse='/'),sep='/',collapse=''),':',counts[i,counts[i,'ref']],',',counts[i,j],sep='',collapse='')\n";
|
|
333 print R " af <- 1/ploidy\n";
|
|
334 print R " filter <- 'LowFraction'\n";
|
|
335 print R " }\n";
|
|
336 print R " if (counts[i,'TotalDepth'] < $mincov) {\n";
|
|
337 print R " filter <- 'LowCoverage'\n";
|
|
338 print R " }\n";
|
|
339 print R " info <- paste('DP=',counts[i,'TotalDepth'],';AF=',round(af,digits=5),';AR=',round(frac,digits=5),sep='')\n";
|
|
340 print R " snpids <- which(snps\$chr == chr & snps\$pos == counts[i,'pos'])\n";
|
|
341 print R " id <- '.'\n";
|
|
342 print R " if (length(snpids) > 0) id <- snps[snpids[1],'id']\n";
|
|
343 print R " vcf[length(vcf)+1] <- paste(chr,counts[i,'pos'],id,counts[i,'ref'],j,phred,filter,info,'GT:AD',sample,sep='\\t',collapse='')\n";
|
|
344 print R " }\n";
|
|
345 print R " }\n";
|
|
346 print R " }\n";
|
|
347 print R "}\n";
|
|
348 print R "if (length(vcf) > 0) {\n";
|
|
349 print R " write(file=args[4],paste(vcf,sep='\\n'))\n";
|
|
350 print R "}\n";
|
|
351 close R;
|
|
352 system("mkdir $wd/VCF/");
|
|
353 for (my $i = 1; $i <= $opts{'p'}; $i++) {
|
|
354 ${'thr'.$i} = threads->create('CallSNPs');
|
|
355 }
|
|
356 ## end the threads.
|
|
357 for (my $i = 1; $i <= $opts{'p'}; $i++) {
|
|
358 $targets_three->enqueue(undef);
|
|
359 }
|
|
360
|
|
361 for (my $i = 1; $i <= $opts{'p'}; $i++) {
|
|
362 ${'thr'.$i}->join();
|
|
363 }
|
|
364
|
|
365 ## BUILD FINAL VCF
|
|
366 open OUT, ">$outfile";
|
|
367 print OUT "##fileformat=VCFv4.1\n";
|
|
368 print OUT "##source=High_Ploidy_Genotyper_v.0.1\n";
|
|
369 print OUT "##genome_reference=$twobit\n";
|
|
370 if ($snpfile ne '') {
|
|
371 print OUT "##SNP_file=$snpfile\n";
|
|
372 }
|
|
373 foreach(keys(%thash)) {
|
|
374 print OUT "##contig=<ID=$_,assembly=hg19,species=\"Homo Sapiens\">\n";
|
|
375 }
|
|
376 print OUT "##INFO=<ID=DP,Number=1,Type=Integer,Description=\"Total Depth\">\n";
|
|
377 print OUT "##INFO=<ID=AF,Number=1,Type=Float,Description=\"Allele Frequency\">\n";
|
|
378 print OUT "##INFO=<ID=AR,Number=1,Type=Float,Description=\"Allelic Ratio\">\n";
|
|
379 print OUT "##FILTER=<ID=LowFraction,Description=\"Allelic Fraction under 1/2*$ploidy\">\n";
|
|
380 print OUT "##FILTER=<ID=LowCoverage,Description=\"Total Depth is lower than threshold of $mincov\">\n";
|
|
381 print OUT "##FORMAT=<ID=GT,Number=1,Type=String,Description=\"Genotype\">\n";
|
|
382 print OUT "##FORMAT=<ID=AD,Number=2,type=Integer,Description,\"Allelic Depth\">\n";
|
|
383 print OUT "#CHROM\tPOS\tID\tREF\tALT\tQUAL\tFILTER\tINFO\tFORMAT\tSAMPLE\n";
|
|
384 close OUT;
|
|
385 @i = ( 1 .. 22,'X','Y','M' );
|
|
386 foreach(@i) {
|
|
387 my $chr = "chr$_";
|
|
388 foreach(sort {$a <=> $b} keys(%{$thash{$chr}})) {
|
|
389 my $v = "$wd/VCF/$chr.$_-".$thash{$chr}{$_}.".vcf";
|
|
390 if (-e $v) {
|
|
391 system("cat '$v' >> '$outfile'");
|
|
392 }
|
|
393 }
|
|
394 }
|
|
395
|
|
396 ## clean up
|
|
397 system("rm -Rf '$wd'");
|
|
398
|
|
399 sub FetchFasta {
|
|
400 while(defined(my $line = $targets_one->dequeue())) {
|
|
401 my ($chr,$start,$stop,$name,$score,$strand) = split(/\t/,$line);
|
|
402 # 2bit is zero based, non-including => decrease start by one
|
|
403 $startposition = $start - 1;
|
|
404 my $command = "twoBitToFa -seq=$chr -start=$startposition -end=$stop -noMask $twobit $wd/Fasta/$chr-$start-$stop.fasta";
|
|
405 system($command);
|
|
406 }
|
|
407 }
|
|
408
|
|
409 sub CountAlleles {
|
|
410 # local version of hashes
|
|
411 my $snp = \%dbsnp;
|
|
412 my %counts;
|
|
413 $counts{'A'} = '';
|
|
414 $counts{'C'} = '';
|
|
415 $counts{'G'} = '';
|
|
416 $counts{'T'} = '';
|
|
417 my %map =('A' => 1,'C' => 2,'G' => 3, 'T' => 4);
|
|
418 my %options;
|
|
419 foreach(keys(%map)) {
|
|
420 my $r = $_;
|
|
421 foreach(keys(%map)) {
|
|
422 if ($_ eq $r) {
|
|
423 next;
|
|
424 }
|
|
425 $options{$r.'-'.$_} = '';
|
|
426 }
|
|
427 }
|
|
428 while (defined(my $line = $targets_two->dequeue())) {
|
|
429 $out = '';
|
|
430 my ($chr,$start,$stop,$name,$score,$strand) = split(/\t/,$line);
|
|
431 ## get reference alleles
|
|
432 my %ref_alleles;
|
|
433 open FASTA, "$wd/Fasta/$chr-$start-$stop.fasta";
|
|
434 my $head = <FASTA>;
|
|
435 my $seq = '';
|
|
436 while (<FASTA>) {
|
|
437 chomp;
|
|
438 $seq .= $_;
|
|
439 }
|
|
440 close FASTA;
|
|
441 # this generates a hash of the reference alleles once, instead of substr-calls in every bam, on every iteration.
|
|
442 for (my $pos = 0; $pos < length($seq); $pos++) {
|
|
443 $ref_alleles{($pos+$start)} = substr($seq,$pos,1);
|
|
444 }
|
|
445 ## get counts.
|
|
446 my $target = "$chr:$start-$stop";
|
|
447 my $command = "igvtools count -w 1 --bases --query '$target' '$bam' '$wd/WIGS/$chr-$start-$stop.wig' '$igvgenome' > /dev/null 2>&1";
|
|
448 system($command);
|
|
449 open WIG, "$wd/WIGS/$chr-$start-$stop.wig";
|
|
450 my $h = <WIG>;
|
|
451 $h = <WIG>;
|
|
452 $h = <WIG>;
|
|
453 my $target_counts = '';
|
|
454 while (<WIG>) {
|
|
455 chomp;
|
|
456 #my ($pos, $a, $c, $g, $t , $n) = split(/\t/,$_);
|
|
457 my @p = split(/\t/,$_);
|
|
458 my $s = $p[1] + $p[2] + $p[3] + $p[4];
|
|
459 $target_counts .= "$p[0]\t$ref_alleles{$p[0]}\t$p[1]\t$p[2]\t$p[3]\t$p[4]\t$s\n";
|
|
460 ## skip positions with coverage < minimal coverage, and positions in dbsnp if specified (if not specified, snp hash is empty).
|
|
461 if ($s > $mincov && !defined($snp->{$chr.'-'.$p[0]})) {
|
|
462 ## for model of 'non-reference'
|
|
463 my $frac = $p[$map{$ref_alleles{$p[0]}}] / $s;
|
|
464 $counts{$ref_alleles{$p[0]}} .= $frac.',';
|
|
465 $out .= "$target\t$p[0]\t$ref_alleles{$p[0]}\t$p[1]\t$p[2]\t$p[3]\t$p[4]\n";
|
|
466 ## for each of the options background models
|
|
467 foreach(keys(%map)) {
|
|
468 if ($_ eq $ref_alleles{$p[0]}) {
|
|
469 next;
|
|
470 }
|
|
471 $options{$ref_alleles{$p[0]}.'-'.$_} .= ($p[$map{$_}] / $s) .',';
|
|
472 }
|
|
473
|
|
474 }
|
|
475 }
|
|
476 close WIG;
|
|
477 open OUT, ">>$wd/allcounts.$mincov"."x.$hassnp.txt";
|
|
478 flock(OUT, 2);
|
|
479 print OUT $out;
|
|
480 close OUT;
|
|
481 open OUT, ">$wd/WIGS/$chr.$start-$stop.txt";
|
|
482 print OUT $target_counts;
|
|
483 close OUT;
|
|
484
|
|
485 }
|
|
486 foreach(keys(%counts)) {
|
|
487 open OUT, ">>$wd/counts_$_.$mincov"."x.$hassnp.txt";
|
|
488 flock(OUT,2);
|
|
489 print OUT $counts{$_};
|
|
490 close OUT;
|
|
491 }
|
|
492 foreach(keys(%options)) {
|
|
493 open OUT, ">>$wd/counts_$_.$mincov"."x.$hassnp.txt";
|
|
494 flock(OUT,2);
|
|
495 print OUT $options{$_};
|
|
496 close OUT;
|
|
497 }
|
|
498 }
|
|
499
|
|
500 sub GetDistribution {
|
|
501 while (defined(my $allele = $alleles->dequeue())) {
|
|
502 system("sed -i 's/.\$//' '$wd/counts_$allele.$mincov"."x.$hassnp.txt'");
|
|
503 open OUT, ">$wd/GetDistribution.$allele.R";
|
16
|
504 print OUT "\n";
|
11
|
505 print OUT "nt <- '$allele'\n";
|
|
506 #print OUT "pdf(file='$wd/Distribution.$allele.$mincov"."x.$hassnp.pdf',paper='a4')\n";
|
|
507 print OUT "data <- scan(file='$wd/counts_$allele.$mincov"."x.$hassnp.txt',sep=',')\n";
|
|
508 print OUT "nr <- length(data)\n";
|
|
509 print OUT "avg <- mean(data)\n";
|
|
510 print OUT "sdd <- sd(data)\n";
|
|
511 #print OUT "if (avg > 0.5) {\n";
|
|
512 #print OUT " x <- seq(0.8,1,length=1000)\n";
|
|
513 #print OUT " y <- dnorm(x,mean=avg,sd=sdd)\n";
|
|
514 #print OUT " plot(x,y,main='Distribution in sample $bam for nt $allele',xlab='Allelic Ratio',type='l',lwd=1)\n";
|
|
515 #print OUT " abline(v=(avg-3*sdd),col='red')\n";
|
|
516 #print OUT " text(0.81,max(y-0.5),paste(c('avg: ',avg,'\\nsd: ',sdd,'\\nnrDataPoints:', nr,'\\n$hassnp\\nMin.Cov:',$mincov),sep=' ',collapse=''),adj=c(0,1))\n";
|
|
517 #print OUT "} else {\n";
|
|
518 #print OUT " x <- seq(0,0.3,length=1000)\n";
|
|
519 #print OUT " y <- dnorm(x,mean=avg,sd=sdd)\n";
|
|
520 #print OUT " plot(x,y,main='Distribution in sample $bam for nt $allele',xlab='Allelic Ratio',type='l',lwd=1)\n";
|
|
521 #print OUT " abline(v=(avg+3*sdd),col='red')\n";
|
|
522 #print OUT " text(0.2,max(y-0.5),paste(c('avg: ',avg,'\\nsd: ',sdd,'\\nnrDataPoints:', nr,'\\n$hassnp\\nMin.Cov:',$mincov),sep=' ',collapse=''),adj=c(0,1))\n";
|
|
523 #print OUT "}\n";
|
|
524 #print OUT "dev.off()\n";
|
|
525 print OUT "write(c(avg,sdd),file='$wd/model.$allele.$mincov"."x.$hassnp.txt',ncolumns=1)\n";
|
|
526 close OUT;
|
|
527 system("cd $wd && Rscript GetDistribution.$allele.R >/dev/null 2>&1");
|
|
528 }
|
|
529 }
|
|
530
|
|
531
|
|
532 sub CallSNPs {
|
|
533 while (defined(my $line = $targets_three->dequeue())) {
|
|
534 # split.
|
|
535 my ($chr,$start,$stop,$name,$score,$strand) = split(/\t/,$line);
|
|
536 my $file = "$wd/WIGS/$chr.$start-$stop.txt";
|
|
537 my $ofile = "$wd/VCF/$chr.$start-$stop.vcf";
|
|
538 system("cd $wd && Rscript CallSNPs.R '$file' '$chr' '$ploidy' '$ofile' '$wd/dbsnp.txt'");
|
|
539 }
|
|
540
|
|
541 }
|
|
542
|