]> git.donarmstrong.com Git - samtools.git/blob - misc/wgsim_eval.pl
412243f9a5485a1962473fe4ce4dd3559a4e3597
[samtools.git] / misc / wgsim_eval.pl
1 #!/usr/bin/perl -w
2
3 # Contact: lh3
4 # Version: 0.1.5
5
6 use strict;
7 use warnings;
8 use Getopt::Std;
9
10 &wgsim_eval;
11 exit;
12
13 sub wgsim_eval {
14   my %opts = (g=>5);
15   getopts('pcg:', \%opts);
16   die("Usage: wgsim_eval.pl [-pc] [-g $opts{g}] <in.sam>\n") if (@ARGV == 0 && -t STDIN);
17   my (@c0, @c1);
18   my ($max_q, $flag) = (0, 0);
19   my $gap = $opts{g};
20   $flag |= 1 if (defined $opts{p});
21   $flag |= 2 if (defined $opts{c});
22   while (<>) {
23         next if (/^\@/);
24         my @t = split("\t");
25         next if (@t < 11);
26         my $line = $_;
27         my ($q, $is_correct, $chr, $left, $rght) = (int($t[4]/10), 1, $t[2], $t[3], $t[3]);
28         $max_q = $q if ($q > $max_q);
29         # right coordinate
30         $_ = $t[5]; s/(\d+)[MDN]/$rght+=$1,'x'/eg;
31         --$rght;
32         # correct for soft clipping
33         $left -= $1 if (/^(\d+)[SH]/);
34         $rght += $1 if (/(\d+)[SH]$/);
35         # skip unmapped reads
36         next if (($t[1]&0x4) || $chr eq '*');
37         # parse read name and check
38         if ($t[0] =~ /^(\S+)_(\d+)_(\d+)_/) {
39           if ($1 ne $chr) { # different chr
40                 $is_correct = 0;
41           } else {
42                 if ($flag & 2) {
43                   if (($t[1]&0x40) && !($t[1]&0x10)) { # F3, forward
44                         $is_correct = 0 if (abs($2 - $left) > $gap);
45                   } elsif (($t[1]&0x40) && ($t[1]&0x10)) { # F3, reverse
46                         $is_correct = 0 if (abs($3 - $rght) > $gap);
47                   } elsif (($t[1]&0x80) && !($t[1]&0x10)) { # R3, forward
48                         $is_correct = 0 if (abs($3 - $left) > $gap);
49                   } else { # R3, reverse
50                         $is_correct = 0 if (abs($2 - $rght) > $gap);
51                   }
52                 } else {
53                   if ($t[1] & 0x10) { # reverse
54                         $is_correct = 0 if (abs($3 - $rght) > $gap); # in case of indels that are close to the end of a reads
55                   } else {
56                         $is_correct = 0 if (abs($2 - $left) > $gap);
57                   }
58                 }
59           }
60         } else {
61           warn("[wgsim_eval] read '$t[0]' was not generated by wgsim?\n");
62           next;
63         }
64         ++$c0[$q];
65         ++$c1[$q] unless ($is_correct);
66         print STDERR $line if (($flag&1) && !$is_correct && $q > 0);
67   }
68   # print
69   my ($cc0, $cc1) = (0, 0);
70   for (my $i = $max_q; $i >= 0; --$i) {
71         $c0[$i] = 0 unless (defined $c0[$i]);
72         $c1[$i] = 0 unless (defined $c1[$i]);
73         $cc0 += $c0[$i]; $cc1 += $c1[$i];
74         printf("%.2dx %12d / %-12d  %12d  %.3e\n", $i, $c1[$i], $c0[$i], $cc0, $cc1/$cc0);
75   }
76 }