0
|
1 #include <unistd.h>
|
|
2 #include <assert.h>
|
|
3 #include "bam.h"
|
|
4
|
|
5 typedef struct {
|
|
6 long long n_reads[2], n_mapped[2], n_pair_all[2], n_pair_map[2], n_pair_good[2];
|
|
7 long long n_sgltn[2], n_read1[2], n_read2[2];
|
|
8 long long n_dup[2];
|
|
9 long long n_diffchr[2], n_diffhigh[2];
|
|
10 } bam_flagstat_t;
|
|
11
|
|
12 #define flagstat_loop(s, c) do { \
|
|
13 int w = ((c)->flag & BAM_FQCFAIL)? 1 : 0; \
|
|
14 ++(s)->n_reads[w]; \
|
|
15 if ((c)->flag & BAM_FPAIRED) { \
|
|
16 ++(s)->n_pair_all[w]; \
|
|
17 if ((c)->flag & BAM_FPROPER_PAIR) ++(s)->n_pair_good[w]; \
|
|
18 if ((c)->flag & BAM_FREAD1) ++(s)->n_read1[w]; \
|
|
19 if ((c)->flag & BAM_FREAD2) ++(s)->n_read2[w]; \
|
|
20 if (((c)->flag & BAM_FMUNMAP) && !((c)->flag & BAM_FUNMAP)) ++(s)->n_sgltn[w]; \
|
|
21 if (!((c)->flag & BAM_FUNMAP) && !((c)->flag & BAM_FMUNMAP)) { \
|
|
22 ++(s)->n_pair_map[w]; \
|
|
23 if ((c)->mtid != (c)->tid) { \
|
|
24 ++(s)->n_diffchr[w]; \
|
|
25 if ((c)->qual >= 5) ++(s)->n_diffhigh[w]; \
|
|
26 } \
|
|
27 } \
|
|
28 } \
|
|
29 if (!((c)->flag & BAM_FUNMAP)) ++(s)->n_mapped[w]; \
|
|
30 if ((c)->flag & BAM_FDUP) ++(s)->n_dup[w]; \
|
|
31 } while (0)
|
|
32
|
|
33 bam_flagstat_t *bam_flagstat_core(bamFile fp)
|
|
34 {
|
|
35 bam_flagstat_t *s;
|
|
36 bam1_t *b;
|
|
37 bam1_core_t *c;
|
|
38 int ret;
|
|
39 s = (bam_flagstat_t*)calloc(1, sizeof(bam_flagstat_t));
|
|
40 b = bam_init1();
|
|
41 c = &b->core;
|
|
42 while ((ret = bam_read1(fp, b)) >= 0)
|
|
43 flagstat_loop(s, c);
|
|
44 bam_destroy1(b);
|
|
45 if (ret != -1)
|
|
46 fprintf(stderr, "[bam_flagstat_core] Truncated file? Continue anyway.\n");
|
|
47 return s;
|
|
48 }
|
|
49 int bam_flagstat(int argc, char *argv[])
|
|
50 {
|
|
51 bamFile fp;
|
|
52 bam_header_t *header;
|
|
53 bam_flagstat_t *s;
|
|
54 if (argc == optind) {
|
|
55 fprintf(stderr, "Usage: samtools flagstat <in.bam>\n");
|
|
56 return 1;
|
|
57 }
|
|
58 fp = strcmp(argv[optind], "-")? bam_open(argv[optind], "r") : bam_dopen(fileno(stdin), "r");
|
|
59 assert(fp);
|
|
60 header = bam_header_read(fp);
|
|
61 s = bam_flagstat_core(fp);
|
|
62 printf("%lld + %lld in total (QC-passed reads + QC-failed reads)\n", s->n_reads[0], s->n_reads[1]);
|
|
63 printf("%lld + %lld duplicates\n", s->n_dup[0], s->n_dup[1]);
|
|
64 printf("%lld + %lld mapped (%.2f%%:%.2f%%)\n", s->n_mapped[0], s->n_mapped[1], (float)s->n_mapped[0] / s->n_reads[0] * 100.0, (float)s->n_mapped[1] / s->n_reads[1] * 100.0);
|
|
65 printf("%lld + %lld paired in sequencing\n", s->n_pair_all[0], s->n_pair_all[1]);
|
|
66 printf("%lld + %lld read1\n", s->n_read1[0], s->n_read1[1]);
|
|
67 printf("%lld + %lld read2\n", s->n_read2[0], s->n_read2[1]);
|
|
68 printf("%lld + %lld properly paired (%.2f%%:%.2f%%)\n", s->n_pair_good[0], s->n_pair_good[1], (float)s->n_pair_good[0] / s->n_pair_all[0] * 100.0, (float)s->n_pair_good[1] / s->n_pair_all[1] * 100.0);
|
|
69 printf("%lld + %lld with itself and mate mapped\n", s->n_pair_map[0], s->n_pair_map[1]);
|
|
70 printf("%lld + %lld singletons (%.2f%%:%.2f%%)\n", s->n_sgltn[0], s->n_sgltn[1], (float)s->n_sgltn[0] / s->n_pair_all[0] * 100.0, (float)s->n_sgltn[1] / s->n_pair_all[1] * 100.0);
|
|
71 printf("%lld + %lld with mate mapped to a different chr\n", s->n_diffchr[0], s->n_diffchr[1]);
|
|
72 printf("%lld + %lld with mate mapped to a different chr (mapQ>=5)\n", s->n_diffhigh[0], s->n_diffhigh[1]);
|
|
73 free(s);
|
|
74 bam_header_destroy(header);
|
|
75 bam_close(fp);
|
|
76 return 0;
|
|
77 }
|