]> git.donarmstrong.com Git - samtools.git/blob - misc/bamcheck.c
742ed761b419424a49de1aaec01a7924dcb5a933
[samtools.git] / misc / bamcheck.c
1 /* 
2     Author: petr.danecek@sanger
3     gcc -Wall -Winline -g -O2 -I ~/git/samtools bamcheck.c -o bamcheck -lm -lz -L ~/git/samtools -lbam
4
5     Assumptions, approximations and other issues:
6         - GC-depth graph does not split reads, the starting position determines which bin is incremented.
7             There are small overlaps between bins (max readlen-1). However, the bins are big (20k).
8         - coverage distribution ignores softclips and deletions
9         - some stats require sorted BAMs
10         - GC content graph can have an untidy, step-like pattern when BAM contains multiple read lengths.
11         - The whole reads are used with -t, no splicing is done, no indels or soft clips are 
12             considered, even small overlap is good enough to include the read in the stats.
13 */
14
15 #define BAMCHECK_VERSION "2012-04-04"
16
17 #define _ISOC99_SOURCE
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <stdarg.h>
21 #include <string.h>
22 #include <math.h>
23 #include <ctype.h>
24 #include <getopt.h>
25 #include <errno.h>
26 #include "faidx.h"
27 #include "khash.h"
28 #include "sam.h"
29 #include "razf.h"
30
31 #define BWA_MIN_RDLEN 35
32 #define IS_PAIRED(bam) ((bam)->core.flag&BAM_FPAIRED && !((bam)->core.flag&BAM_FUNMAP) && !((bam)->core.flag&BAM_FMUNMAP))
33 #define IS_UNMAPPED(bam) ((bam)->core.flag&BAM_FUNMAP)
34 #define IS_REVERSE(bam) ((bam)->core.flag&BAM_FREVERSE)
35 #define IS_MATE_REVERSE(bam) ((bam)->core.flag&BAM_FMREVERSE)
36 #define IS_READ1(bam) ((bam)->core.flag&BAM_FREAD1)
37 #define IS_READ2(bam) ((bam)->core.flag&BAM_FREAD2)
38 #define IS_DUP(bam) ((bam)->core.flag&BAM_FDUP)
39
40 typedef struct 
41 {
42     int32_t line_len, line_blen;
43     int64_t len;
44     uint64_t offset;
45
46 faidx1_t;
47 KHASH_MAP_INIT_STR(s, faidx1_t)
48 KHASH_MAP_INIT_STR(str, int)
49 struct __faidx_t {
50     RAZF *rz;
51     int n, m;
52     char **name;
53     khash_t(s) *hash;
54 };
55
56 typedef struct
57 {
58     float gc;
59     uint32_t depth;
60 }
61 gc_depth_t;
62
63 // For coverage distribution, a simple pileup
64 typedef struct 
65 {
66     int64_t pos;
67     int size, start;
68     int *buffer;
69
70 round_buffer_t;
71
72 typedef struct { uint32_t from, to; } pos_t;
73 typedef struct
74 {
75     int npos,mpos,cpos;
76     pos_t *pos;
77 }
78 regions_t;
79
80 typedef struct
81 {
82     // Parameters
83     int trim_qual;      // bwa trim quality
84     int rmdup;          // Exclude reads marked as duplicates from the stats
85
86     // Dimensions of the quality histogram holder (quals_1st,quals_2nd), GC content holder (gc_1st,gc_2nd),
87     //  insert size histogram holder
88     int nquals;         // The number of quality bins 
89     int nbases;         // The maximum sequence length the allocated array can hold
90     int nisize;         // The maximum insert size that the allocated array can hold
91     int ngc;            // The size of gc_1st and gc_2nd
92     int nindels;        // The maximum indel length for indel distribution
93
94     // Arrays for the histogram data
95     uint64_t *quals_1st, *quals_2nd;
96     uint64_t *gc_1st, *gc_2nd;
97     uint64_t *isize_inward, *isize_outward, *isize_other;
98     uint64_t *acgt_cycles;
99     uint64_t *read_lengths;
100     uint64_t *insertions, *deletions;
101     uint64_t *ins_cycles, *del_cycles;
102
103     // The extremes encountered
104     int max_len;            // Maximum read length
105     int max_qual;           // Maximum quality
106     float isize_main_bulk;  // There are always some unrealistically big insert sizes, report only the main part
107     int is_sorted;
108
109     // Summary numbers
110     uint64_t total_len;
111     uint64_t total_len_dup;
112     uint64_t nreads_1st;
113     uint64_t nreads_2nd;
114     uint64_t nreads_dup;
115     uint64_t nreads_unmapped;
116     uint64_t nreads_unpaired;
117     uint64_t nreads_paired;
118     uint64_t nreads_mq0;
119     uint64_t nbases_mapped;
120     uint64_t nbases_mapped_cigar;
121     uint64_t nbases_trimmed;  // bwa trimmed bases
122     uint64_t nmismatches;
123
124     // GC-depth related data
125     uint32_t ngcd, igcd;        // The maximum number of GC depth bins and index of the current bin
126     gc_depth_t *gcd;            // The GC-depth bins holder
127     int gcd_bin_size;           // The size of GC-depth bin
128     int32_t tid, gcd_pos;       // Position of the current bin
129     int32_t pos;                // Position of the last read
130
131     // Coverage distribution related data
132     int ncov;                       // The number of coverage bins
133     uint64_t *cov;                  // The coverage frequencies
134     int cov_min,cov_max,cov_step;   // Minimum, maximum coverage and size of the coverage bins
135     round_buffer_t cov_rbuf;        // Pileup round buffer
136
137     // Mismatches by read cycle 
138     uint8_t *rseq_buf;             // A buffer for reference sequence to check the mismatches against
139     int nref_seq;               // The size of the buffer
140     int32_t rseq_pos;           // The coordinate of the first base in the buffer
141     int32_t rseq_len;           // The used part of the buffer
142     uint64_t *mpc_buf;          // Mismatches per cycle
143
144     // Filters
145     int filter_readlen;
146
147     // Target regions
148     int nregions;
149     regions_t *regions;
150
151     // Auxiliary data
152     double sum_qual;            // For calculating average quality value 
153     samfile_t *sam;             // Unused
154     faidx_t *fai;               // Reference sequence for GC-depth graph
155     int argc;                   // Command line arguments to be printed on the output
156     char **argv;
157 }
158 stats_t;
159
160 void error(const char *format, ...);
161
162 // Coverage distribution methods
163 inline int coverage_idx(int min, int max, int n, int step, int depth)
164 {
165     if ( depth < min )
166         return 0;
167
168     if ( depth > max )
169         return n-1;
170
171     return 1 + (depth - min) / step;
172 }
173
174 inline int round_buffer_lidx2ridx(int offset, int size, int64_t refpos, int64_t pos)
175 {
176     return (offset + (pos-refpos) % size) % size;
177 }
178
179 void round_buffer_flush(stats_t *stats, int64_t pos)
180 {
181     int ibuf,idp;
182
183     if ( pos==stats->cov_rbuf.pos ) 
184         return;
185
186     int64_t new_pos = pos;
187     if ( pos==-1 || pos - stats->cov_rbuf.pos >= stats->cov_rbuf.size )
188     {
189         // Flush the whole buffer, but in sequential order, 
190         pos = stats->cov_rbuf.pos + stats->cov_rbuf.size - 1;
191     }
192
193     if ( pos < stats->cov_rbuf.pos ) 
194         error("Expected coordinates in ascending order, got %ld after %ld\n", pos,stats->cov_rbuf.pos);
195
196     int ifrom = stats->cov_rbuf.start;
197     int ito = round_buffer_lidx2ridx(stats->cov_rbuf.start,stats->cov_rbuf.size,stats->cov_rbuf.pos,pos-1);
198     if ( ifrom>ito )
199     {
200         for (ibuf=ifrom; ibuf<stats->cov_rbuf.size; ibuf++)
201         {
202             if ( !stats->cov_rbuf.buffer[ibuf] )
203                 continue;
204             idp = coverage_idx(stats->cov_min,stats->cov_max,stats->ncov,stats->cov_step,stats->cov_rbuf.buffer[ibuf]);
205             stats->cov[idp]++;
206             stats->cov_rbuf.buffer[ibuf] = 0;
207         }
208         ifrom = 0;
209     }
210     for (ibuf=ifrom; ibuf<=ito; ibuf++)
211     {
212         if ( !stats->cov_rbuf.buffer[ibuf] )
213             continue;
214         idp = coverage_idx(stats->cov_min,stats->cov_max,stats->ncov,stats->cov_step,stats->cov_rbuf.buffer[ibuf]);
215         stats->cov[idp]++;
216         stats->cov_rbuf.buffer[ibuf] = 0;
217     }
218     stats->cov_rbuf.start = (new_pos==-1) ? 0 : round_buffer_lidx2ridx(stats->cov_rbuf.start,stats->cov_rbuf.size,stats->cov_rbuf.pos,pos);
219     stats->cov_rbuf.pos   = new_pos;
220 }
221
222 void round_buffer_insert_read(round_buffer_t *rbuf, int64_t from, int64_t to)
223 {
224     if ( to-from >= rbuf->size )
225         error("The read length too big (%d), please increase the buffer length (currently %d)\n", to-from+1,rbuf->size);
226     if ( from < rbuf->pos )
227         error("The reads are not sorted (%ld comes after %ld).\n", from,rbuf->pos);
228
229     int ifrom,ito,ibuf;
230     ifrom = round_buffer_lidx2ridx(rbuf->start,rbuf->size,rbuf->pos,from);
231     ito   = round_buffer_lidx2ridx(rbuf->start,rbuf->size,rbuf->pos,to);
232     if ( ifrom>ito )
233     {
234         for (ibuf=ifrom; ibuf<rbuf->size; ibuf++)
235             rbuf->buffer[ibuf]++;
236         ifrom = 0;
237     }
238     for (ibuf=ifrom; ibuf<=ito; ibuf++)
239         rbuf->buffer[ibuf]++;
240 }
241
242 // Calculate the number of bases in the read trimmed by BWA
243 int bwa_trim_read(int trim_qual, uint8_t *quals, int len, int reverse) 
244 {
245     if ( len<BWA_MIN_RDLEN ) return 0;
246
247     // Although the name implies that the read cannot be trimmed to more than BWA_MIN_RDLEN,
248     //  the calculation can in fact trim it to (BWA_MIN_RDLEN-1). (bwa_trim_read in bwa/bwaseqio.c).
249     int max_trimmed = len - BWA_MIN_RDLEN + 1;
250     int l, sum=0, max_sum=0, max_l=0;
251
252     for (l=0; l<max_trimmed; l++)
253     {
254         sum += trim_qual - quals[ reverse ? l : len-1-l ];
255         if ( sum<0 ) break;
256         if ( sum>max_sum )
257         {
258             max_sum = sum;
259             // This is the correct way, but bwa clips from some reason one base less
260             // max_l   = l+1;
261             max_l   = l;
262         }
263     }
264     return max_l;
265 }
266
267
268 void count_indels(stats_t *stats,bam1_t *bam_line) 
269 {
270     int is_fwd = IS_REVERSE(bam_line) ? 0 : 1;
271     int icig;
272     int icycle = 0;
273     int read_len = bam_line->core.l_qseq;
274     for (icig=0; icig<bam_line->core.n_cigar; icig++) 
275     {
276         // Conversion from uint32_t to MIDNSHP
277         //  0123456
278         //  MIDNSHP
279         int cig  = bam1_cigar(bam_line)[icig] & BAM_CIGAR_MASK;
280         int ncig = bam1_cigar(bam_line)[icig] >> BAM_CIGAR_SHIFT;
281
282         if ( cig==1 )
283         {
284             int idx = is_fwd ? icycle : read_len-icycle;
285             if ( idx<0 ) error("FIXME: read_len=%d vs icycle=%d\n", read_len,icycle);
286             if ( idx >= stats->nbases || idx<0 ) error("FIXME: %d vs %d\n", idx,stats->nbases);
287             stats->ins_cycles[idx]++;
288             icycle += ncig;
289             if ( ncig<=stats->nindels )
290                 stats->insertions[ncig-1]++;
291             continue;
292         }
293         if ( cig==2 )
294         {
295             int idx = is_fwd ? icycle-1 : read_len-icycle-1;
296             if ( idx<0 ) continue;  // discard meaningless deletions
297             if ( idx >= stats->nbases ) error("FIXME: %d vs %d\n", idx,stats->nbases);
298             stats->del_cycles[idx]++;
299             if ( ncig<=stats->nindels )
300                 stats->deletions[ncig-1]++;
301             continue;
302         }
303         icycle += ncig;
304     }
305 }
306
307 void count_mismatches_per_cycle(stats_t *stats,bam1_t *bam_line) 
308 {
309     int is_fwd = IS_REVERSE(bam_line) ? 0 : 1;
310     int icig,iread=0,icycle=0;
311     int iref = bam_line->core.pos - stats->rseq_pos;
312     int read_len   = bam_line->core.l_qseq;
313     uint8_t *read  = bam1_seq(bam_line);
314     uint8_t *quals = bam1_qual(bam_line);
315     uint64_t *mpc_buf = stats->mpc_buf;
316     for (icig=0; icig<bam_line->core.n_cigar; icig++) 
317     {
318         // Conversion from uint32_t to MIDNSHP
319         //  0123456
320         //  MIDNSHP
321         int cig  = bam1_cigar(bam_line)[icig] & BAM_CIGAR_MASK;
322         int ncig = bam1_cigar(bam_line)[icig] >> BAM_CIGAR_SHIFT;
323         if ( cig==1 )
324         {
325             iread  += ncig;
326             icycle += ncig;
327             continue;
328         }
329         if ( cig==2 )
330         {
331             iref += ncig;
332             continue;
333         }
334         if ( cig==4 )
335         {
336             icycle += ncig;
337             // Soft-clips are present in the sequence, but the position of the read marks a start of non-clipped sequence
338             //   iref += ncig;
339             iread  += ncig;
340             continue;
341         }
342         if ( cig==5 )
343         {
344             icycle += ncig;
345             continue;
346         }
347         if ( cig!=0 )
348             error("TODO: cigar %d, %s\n", cig,bam1_qname(bam_line));
349        
350         if ( ncig+iref > stats->rseq_len )
351             error("FIXME: %d+%d > %d, %s, %s:%d\n",ncig,iref,stats->rseq_len, bam1_qname(bam_line),stats->sam->header->target_name[bam_line->core.tid],bam_line->core.pos+1);
352
353         int im;
354         for (im=0; im<ncig; im++)
355         {
356             uint8_t cread = bam1_seqi(read,iread);
357             uint8_t cref  = stats->rseq_buf[iref];
358
359             // ---------------15
360             // =ACMGRSVTWYHKDBN
361             if ( cread==15 )
362             {
363                 int idx = is_fwd ? icycle : read_len-icycle-1;
364                 if ( idx>stats->max_len )
365                     error("mpc: %d>%d\n",idx,stats->max_len);
366                 idx = idx*stats->nquals;
367                 if ( idx>=stats->nquals*stats->nbases )
368                     error("FIXME: mpc_buf overflow\n");
369                 mpc_buf[idx]++;
370             }
371             else if ( cref && cread && cref!=cread )
372             {
373                 uint8_t qual = quals[iread] + 1;
374                 if ( qual>=stats->nquals )
375                     error("TODO: quality too high %d>=%d\n", quals[iread],stats->nquals);
376
377                 int idx = is_fwd ? icycle : read_len-icycle-1;
378                 if ( idx>stats->max_len )
379                     error("mpc: %d>%d\n",idx,stats->max_len);
380
381                 idx = idx*stats->nquals + qual;
382                 if ( idx>=stats->nquals*stats->nbases )
383                     error("FIXME: mpc_buf overflow\n");
384                 mpc_buf[idx]++;
385             }
386
387             iref++;
388             iread++;
389             icycle++;
390         }
391     }
392 }
393
394 void read_ref_seq(stats_t *stats,int32_t tid,int32_t pos)
395 {
396     khash_t(s) *h;
397     khiter_t iter;
398     faidx1_t val;
399     char *chr, c;
400     faidx_t *fai = stats->fai;
401
402     h = fai->hash;
403     chr = stats->sam->header->target_name[tid];
404
405     // ID of the sequence name
406     iter = kh_get(s, h, chr);
407     if (iter == kh_end(h)) 
408         error("No such reference sequence [%s]?\n", chr);
409     val = kh_value(h, iter);
410
411     // Check the boundaries
412     if (pos >= val.len)
413         error("Was the bam file mapped with the reference sequence supplied?"
414               " A read mapped beyond the end of the chromosome (%s:%d, chromosome length %d).\n", chr,pos,val.len);
415     int size = stats->nref_seq;
416     // The buffer extends beyond the chromosome end. Later the rest will be filled with N's.
417     if (size+pos > val.len) size = val.len-pos;
418
419     // Position the razf reader
420     razf_seek(fai->rz, val.offset + pos / val.line_blen * val.line_len + pos % val.line_blen, SEEK_SET);
421
422     uint8_t *ptr = stats->rseq_buf;
423     int nread = 0;
424     while ( nread<size && razf_read(fai->rz,&c,1) && !fai->rz->z_err )
425     {
426         if ( !isgraph(c) )
427             continue;
428
429         // Conversion between uint8_t coding and ACGT
430         //      -12-4---8-------
431         //      =ACMGRSVTWYHKDBN
432         if ( c=='A' || c=='a' )
433             *ptr = 1;
434         else if ( c=='C' || c=='c' )
435             *ptr = 2;
436         else if ( c=='G' || c=='g' )
437             *ptr = 4;
438         else if ( c=='T' || c=='t' )
439             *ptr = 8;
440         else
441             *ptr = 0;
442         ptr++;
443         nread++;
444     }
445     if ( nread < stats->nref_seq )
446     {
447         memset(ptr,0, stats->nref_seq - nread);
448         nread = stats->nref_seq;
449     }
450     stats->rseq_len = nread;
451     stats->rseq_pos = pos;
452     stats->tid      = tid;
453 }
454
455 float fai_gc_content(stats_t *stats)
456 {
457     uint32_t gc,count,c;
458     int i,size = stats->rseq_len;
459
460     // Count GC content
461     gc = count = 0;
462     for (i=0; i<size; i++)
463     {
464         c = stats->rseq_buf[i];
465         if ( c==2 || c==4 )
466         {
467             gc++;
468             count++;
469         }
470         else if ( c==1 || c==8 )
471             count++;
472     }
473     return count ? (float)gc/count : 0;
474 }
475
476
477 void realloc_buffers(stats_t *stats, int seq_len)
478 {
479     int n = 2*(1 + seq_len - stats->nbases) + stats->nbases;
480
481     stats->quals_1st = realloc(stats->quals_1st, n*stats->nquals*sizeof(uint64_t));
482     if ( !stats->quals_1st )
483         error("Could not realloc buffers, the sequence too long: %d (%ld)\n", seq_len,n*stats->nquals*sizeof(uint64_t));
484     memset(stats->quals_1st + stats->nbases*stats->nquals, 0, (n-stats->nbases)*stats->nquals*sizeof(uint64_t));
485
486     stats->quals_2nd = realloc(stats->quals_2nd, n*stats->nquals*sizeof(uint64_t));
487     if ( !stats->quals_2nd )
488         error("Could not realloc buffers, the sequence too long: %d (2x%ld)\n", seq_len,n*stats->nquals*sizeof(uint64_t));
489     memset(stats->quals_2nd + stats->nbases*stats->nquals, 0, (n-stats->nbases)*stats->nquals*sizeof(uint64_t));
490
491     if ( stats->mpc_buf )
492     {
493         stats->mpc_buf = realloc(stats->mpc_buf, n*stats->nquals*sizeof(uint64_t));
494         if ( !stats->mpc_buf )
495             error("Could not realloc buffers, the sequence too long: %d (%ld)\n", seq_len,n*stats->nquals*sizeof(uint64_t));
496         memset(stats->mpc_buf + stats->nbases*stats->nquals, 0, (n-stats->nbases)*stats->nquals*sizeof(uint64_t));
497     }
498
499     stats->acgt_cycles = realloc(stats->acgt_cycles, n*4*sizeof(uint64_t));
500     if ( !stats->acgt_cycles )
501         error("Could not realloc buffers, the sequence too long: %d (%ld)\n", seq_len,n*4*sizeof(uint64_t));
502     memset(stats->acgt_cycles + stats->nbases*4, 0, (n-stats->nbases)*4*sizeof(uint64_t));
503
504     stats->read_lengths = realloc(stats->read_lengths, n*sizeof(uint64_t));
505     if ( !stats->read_lengths )
506         error("Could not realloc buffers, the sequence too long: %d (%ld)\n", seq_len,n*sizeof(uint64_t));
507     memset(stats->read_lengths + stats->nbases, 0, (n-stats->nbases)*sizeof(uint64_t));
508
509     stats->insertions = realloc(stats->insertions, n*sizeof(uint64_t));
510     if ( !stats->insertions )
511         error("Could not realloc buffers, the sequence too long: %d (%ld)\n", seq_len,n*sizeof(uint64_t));
512     memset(stats->insertions + stats->nbases, 0, (n-stats->nbases)*sizeof(uint64_t));
513
514     stats->deletions = realloc(stats->deletions, n*sizeof(uint64_t));
515     if ( !stats->deletions )
516         error("Could not realloc buffers, the sequence too long: %d (%ld)\n", seq_len,n*sizeof(uint64_t));
517     memset(stats->deletions + stats->nbases, 0, (n-stats->nbases)*sizeof(uint64_t));
518
519     stats->ins_cycles = realloc(stats->ins_cycles, (n+1)*sizeof(uint64_t));
520     if ( !stats->ins_cycles )
521         error("Could not realloc buffers, the sequence too long: %d (%ld)\n", seq_len,(n+1)*sizeof(uint64_t));
522     memset(stats->ins_cycles + stats->nbases + 1, 0, (n+1-stats->nbases)*sizeof(uint64_t));
523
524     stats->del_cycles = realloc(stats->del_cycles, (n+1)*sizeof(uint64_t));
525     if ( !stats->del_cycles )
526         error("Could not realloc buffers, the sequence too long: %d (%ld)\n", seq_len,(n+1)*sizeof(uint64_t));
527     memset(stats->del_cycles + stats->nbases + 1, 0, (n+1-stats->nbases)*sizeof(uint64_t));
528
529     stats->nbases = n;
530
531     // Realloc the coverage distribution buffer
532     int *rbuffer = calloc(sizeof(int),seq_len*5);
533     n = stats->cov_rbuf.size-stats->cov_rbuf.start;
534     memcpy(rbuffer,stats->cov_rbuf.buffer+stats->cov_rbuf.start,n);
535     if ( stats->cov_rbuf.start>1 )
536         memcpy(rbuffer+n,stats->cov_rbuf.buffer,stats->cov_rbuf.start);
537     stats->cov_rbuf.start = 0;
538     free(stats->cov_rbuf.buffer);
539     stats->cov_rbuf.buffer = rbuffer;
540     stats->cov_rbuf.size = seq_len*5;
541 }
542
543 void collect_stats(bam1_t *bam_line, stats_t *stats)
544 {
545     if ( stats->rmdup && IS_DUP(bam_line) )
546         return;
547
548     int seq_len = bam_line->core.l_qseq;
549     if ( !seq_len ) return;
550     if ( stats->filter_readlen!=-1 && seq_len!=stats->filter_readlen ) return;
551     if ( seq_len >= stats->nbases )
552         realloc_buffers(stats,seq_len);
553     if ( stats->max_len<seq_len )
554         stats->max_len = seq_len;
555
556     stats->read_lengths[seq_len]++;
557
558     // Count GC and ACGT per cycle
559     uint8_t base, *seq  = bam1_seq(bam_line);
560     int gc_count  = 0;
561     int i;
562     int reverse = IS_REVERSE(bam_line);
563     for (i=0; i<seq_len; i++)
564     {
565         // Conversion from uint8_t coding to ACGT
566         //      -12-4---8-------
567         //      =ACMGRSVTWYHKDBN
568         //       01 2   3
569         base = bam1_seqi(seq,i);
570         base /= 2;
571         if ( base==1 || base==2 ) gc_count++;
572         else if ( base>2 ) base=3;
573         if ( 4*(reverse ? seq_len-i-1 : i) + base >= stats->nbases*4 ) 
574             error("FIXME: acgt_cycles\n");
575         stats->acgt_cycles[ 4*(reverse ? seq_len-i-1 : i) + base ]++;
576     }
577     int gc_idx_min = gc_count*(stats->ngc-1)/seq_len;
578     int gc_idx_max = (gc_count+1)*(stats->ngc-1)/seq_len;
579     if ( gc_idx_max >= stats->ngc ) gc_idx_max = stats->ngc - 1;
580
581     // Determine which array (1st or 2nd read) will these stats go to,
582     //  trim low quality bases from end the same way BWA does, 
583     //  fill GC histogram
584     uint64_t *quals;
585     uint8_t *bam_quals = bam1_qual(bam_line);
586     if ( bam_line->core.flag&BAM_FREAD2 )
587     {
588         quals  = stats->quals_2nd;
589         stats->nreads_2nd++;
590         for (i=gc_idx_min; i<gc_idx_max; i++)
591             stats->gc_2nd[i]++;
592     }
593     else
594     {
595         quals = stats->quals_1st;
596         stats->nreads_1st++;
597         for (i=gc_idx_min; i<gc_idx_max; i++)
598             stats->gc_1st[i]++;
599     }
600     if ( stats->trim_qual>0 ) 
601         stats->nbases_trimmed += bwa_trim_read(stats->trim_qual, bam_quals, seq_len, reverse);
602
603     // Quality histogram and average quality
604     for (i=0; i<seq_len; i++)
605     {
606         uint8_t qual = bam_quals[ reverse ? seq_len-i-1 : i];
607         if ( qual>=stats->nquals )
608             error("TODO: quality too high %d>=%d\n", quals[i],stats->nquals);
609         if ( qual>stats->max_qual )
610             stats->max_qual = qual;
611
612         quals[ i*stats->nquals+qual ]++;
613         stats->sum_qual += qual;
614     }
615
616     // Look at the flags and increment appropriate counters (mapped, paired, etc)
617     if ( IS_UNMAPPED(bam_line) )
618         stats->nreads_unmapped++;
619     else
620     {
621         if ( !bam_line->core.qual )
622             stats->nreads_mq0++;
623
624         count_indels(stats,bam_line);
625
626         // The insert size is tricky, because for long inserts the libraries are
627         // prepared differently and the pairs point in other direction. BWA does
628         // not set the paired flag for them.  Similar thing is true also for 454
629         // reads. Therefore, do the insert size stats for all mapped reads.
630         int32_t isize = bam_line->core.isize;
631         if ( isize<0 ) isize = -isize;
632         if ( IS_PAIRED(bam_line) && isize!=0 )
633         {
634             stats->nreads_paired++;
635             if ( isize >= stats->nisize )
636                 isize=stats->nisize-1;
637
638             int pos_fst = bam_line->core.mpos - bam_line->core.pos;
639             int is_fst  = IS_READ1(bam_line) ? 1 : -1;
640             int is_fwd  = IS_REVERSE(bam_line) ? -1 : 1;
641             int is_mfwd = IS_MATE_REVERSE(bam_line) ? -1 : 1;
642
643             if ( is_fwd*is_mfwd>0 )
644                 stats->isize_other[isize]++;
645             else if ( is_fst*pos_fst>0 )
646             {
647                 if ( is_fst*is_fwd>0 )
648                     stats->isize_inward[isize]++;
649                 else
650                     stats->isize_outward[isize]++;
651             }
652             else if ( is_fst*pos_fst<0 )
653             {
654                 if ( is_fst*is_fwd>0 )
655                     stats->isize_outward[isize]++;
656                 else
657                     stats->isize_inward[isize]++;
658             }
659         }
660         else
661             stats->nreads_unpaired++;
662
663         // Number of mismatches 
664         uint8_t *nm = bam_aux_get(bam_line,"NM");
665         if (nm) 
666             stats->nmismatches += bam_aux2i(nm);
667
668         // Number of mapped bases from cigar 
669         if ( bam_line->core.n_cigar == 0) 
670             error("FIXME: mapped read with no cigar?\n");
671         int readlen = seq_len;
672         for (i=0; i<bam_line->core.n_cigar; i++) 
673         {
674             // Conversion from uint32_t to MIDNSHP
675             //  01--4--
676             //  MIDNSHP
677             if ( (bam1_cigar(bam_line)[i]&BAM_CIGAR_MASK)==0 || (bam1_cigar(bam_line)[i]&BAM_CIGAR_MASK)==1 )
678                 stats->nbases_mapped_cigar += bam1_cigar(bam_line)[i]>>BAM_CIGAR_SHIFT;
679
680             if ( (bam1_cigar(bam_line)[i]&BAM_CIGAR_MASK)==2 )
681                 readlen += bam1_cigar(bam_line)[i]>>BAM_CIGAR_SHIFT;
682         }
683         stats->nbases_mapped += seq_len;
684
685         if ( stats->tid==bam_line->core.tid && bam_line->core.pos<stats->pos )
686             stats->is_sorted = 0;
687         stats->pos = bam_line->core.pos;
688
689         if ( stats->is_sorted )
690         {
691             if ( stats->tid==-1 || stats->tid!=bam_line->core.tid )
692                 round_buffer_flush(stats,-1);
693
694             // Mismatches per cycle and GC-depth graph
695             if ( stats->fai )
696             {
697                 // First pass, new chromosome or sequence spanning beyond the end of the buffer 
698                 if ( stats->rseq_pos==-1 || stats->tid != bam_line->core.tid || stats->rseq_pos+stats->rseq_len < bam_line->core.pos+readlen )
699                 {
700                     read_ref_seq(stats,bam_line->core.tid,bam_line->core.pos);
701
702                     // Get the reference GC content for this bin. Note that in the current implementation
703                     //  the GCD bins overlap by seq_len-1. Because the bin size is by default 20k and the 
704                     //  expected read length only ~100bp, it shouldn't really matter.
705                     stats->gcd_pos = bam_line->core.pos;
706                     stats->igcd++;
707
708                     if ( stats->igcd >= stats->ngcd )
709                         error("The genome too long or the GCD bin overlaps too big [%ud]\n", stats->igcd);
710
711                     stats->gcd[ stats->igcd ].gc = fai_gc_content(stats);
712                 }
713                 count_mismatches_per_cycle(stats,bam_line);
714             }
715             else if ( stats->gcd_pos==-1 || stats->tid != bam_line->core.tid || bam_line->core.pos - stats->gcd_pos > stats->gcd_bin_size )
716             {
717                 // First pass or a new chromosome
718                 stats->tid     = bam_line->core.tid;
719                 stats->gcd_pos = bam_line->core.pos;
720                 stats->igcd++;
721
722                 if ( stats->igcd >= stats->ngcd )
723                 {
724                     uint32_t n = 2*(1 + stats->ngcd);
725                     stats->gcd = realloc(stats->gcd, n*sizeof(gc_depth_t));
726                     if ( !stats->gcd )
727                         error("Could not realloc GCD buffer, too many chromosomes or the genome too long?? [%u %u]\n", stats->ngcd,n);
728                     memset(&(stats->gcd[stats->ngcd]),0,(n-stats->ngcd)*sizeof(gc_depth_t));
729                 }
730             }
731
732             stats->gcd[ stats->igcd ].depth++;
733             // When no reference sequence is given, approximate the GC from the read (much shorter window, but otherwise OK)
734             if ( !stats->fai )
735                 stats->gcd[ stats->igcd ].gc += (float) gc_count / seq_len;
736
737             // Coverage distribution graph
738             round_buffer_flush(stats,bam_line->core.pos);
739             round_buffer_insert_read(&(stats->cov_rbuf),bam_line->core.pos,bam_line->core.pos+seq_len-1);
740         }
741     }
742
743     stats->total_len += seq_len;
744     if ( IS_DUP(bam_line) )
745     {
746         stats->total_len_dup += seq_len;
747         stats->nreads_dup++;
748     }
749 }
750
751 // Sort by GC and depth
752 #define GCD_t(x) ((gc_depth_t *)x)
753 static int gcd_cmp(const void *a, const void *b)
754 {
755     if ( GCD_t(a)->gc < GCD_t(b)->gc ) return -1;
756     if ( GCD_t(a)->gc > GCD_t(b)->gc ) return 1;
757     if ( GCD_t(a)->depth < GCD_t(b)->depth ) return -1;
758     if ( GCD_t(a)->depth > GCD_t(b)->depth ) return 1;
759     return 0;
760 }
761 #undef GCD_t
762
763 float gcd_percentile(gc_depth_t *gcd, int N, int p)
764 {
765     float n,d;
766     int k;
767
768     n = p*(N+1)/100;
769     k = n;
770     if ( k<=0 ) 
771         return gcd[0].depth;
772     if ( k>=N ) 
773         return gcd[N-1].depth;
774
775     d = n - k;
776     return gcd[k-1].depth + d*(gcd[k].depth - gcd[k-1].depth);
777 }
778
779 void output_stats(stats_t *stats)
780 {
781     // Calculate average insert size and standard deviation (from the main bulk data only)
782     int isize, ibulk=0;
783     uint64_t nisize=0, nisize_inward=0, nisize_outward=0, nisize_other=0;
784     for (isize=1; isize<stats->nisize; isize++)
785     {
786         // Each pair was counted twice
787         stats->isize_inward[isize] *= 0.5;
788         stats->isize_outward[isize] *= 0.5;
789         stats->isize_other[isize] *= 0.5;
790
791         nisize_inward += stats->isize_inward[isize];
792         nisize_outward += stats->isize_outward[isize];
793         nisize_other += stats->isize_other[isize];
794         nisize += stats->isize_inward[isize] + stats->isize_outward[isize] + stats->isize_other[isize];
795     }
796
797     double bulk=0, avg_isize=0, sd_isize=0;
798     for (isize=1; isize<stats->nisize; isize++)
799     {
800         bulk += stats->isize_inward[isize] + stats->isize_outward[isize] + stats->isize_other[isize];
801         avg_isize += isize * (stats->isize_inward[isize] + stats->isize_outward[isize] + stats->isize_other[isize]);
802
803         if ( bulk/nisize > stats->isize_main_bulk )
804         {
805             ibulk  = isize+1;
806             nisize = bulk;
807             break;
808         }
809     }
810     avg_isize /= nisize ? nisize : 1;
811     for (isize=1; isize<ibulk; isize++)
812         sd_isize += (stats->isize_inward[isize] + stats->isize_outward[isize] + stats->isize_other[isize]) * (isize-avg_isize)*(isize-avg_isize) / nisize;
813     sd_isize = sqrt(sd_isize);
814
815
816     printf("# This file was produced by bamcheck (%s)\n",BAMCHECK_VERSION);
817     printf("# The command line was:  %s",stats->argv[0]);
818     int i;
819     for (i=1; i<stats->argc; i++)
820         printf(" %s",stats->argv[i]);
821     printf("\n");
822     printf("# Summary Numbers. Use `grep ^SN | cut -f 2-` to extract this part.\n");
823     printf("SN\tsequences:\t%ld\n", (long)(stats->nreads_1st+stats->nreads_2nd));
824     printf("SN\tis paired:\t%d\n", stats->nreads_1st&&stats->nreads_2nd ? 1 : 0);
825     printf("SN\tis sorted:\t%d\n", stats->is_sorted ? 1 : 0);
826     printf("SN\t1st fragments:\t%ld\n", (long)stats->nreads_1st);
827     printf("SN\tlast fragments:\t%ld\n", (long)stats->nreads_2nd);
828     printf("SN\treads mapped:\t%ld\n", (long)(stats->nreads_paired+stats->nreads_unpaired));
829     printf("SN\treads unmapped:\t%ld\n", (long)stats->nreads_unmapped);
830     printf("SN\treads unpaired:\t%ld\n", (long)stats->nreads_unpaired);
831     printf("SN\treads paired:\t%ld\n", (long)stats->nreads_paired);
832     printf("SN\treads duplicated:\t%ld\n", (long)stats->nreads_dup);
833     printf("SN\treads MQ0:\t%ld\n", (long)stats->nreads_mq0);
834     printf("SN\ttotal length:\t%ld\n", (long)stats->total_len);
835     printf("SN\tbases mapped:\t%ld\n", (long)stats->nbases_mapped);
836     printf("SN\tbases mapped (cigar):\t%ld\n", (long)stats->nbases_mapped_cigar);
837     printf("SN\tbases trimmed:\t%ld\n", (long)stats->nbases_trimmed);
838     printf("SN\tbases duplicated:\t%ld\n", (long)stats->total_len_dup);
839     printf("SN\tmismatches:\t%ld\n", (long)stats->nmismatches);
840     printf("SN\terror rate:\t%e\n", (float)stats->nmismatches/stats->nbases_mapped_cigar);
841     float avg_read_length = (stats->nreads_1st+stats->nreads_2nd)?stats->total_len/(stats->nreads_1st+stats->nreads_2nd):0;
842     printf("SN\taverage length:\t%.0f\n", avg_read_length);
843     printf("SN\tmaximum length:\t%d\n", stats->max_len);
844     printf("SN\taverage quality:\t%.1f\n", stats->total_len?stats->sum_qual/stats->total_len:0);
845     printf("SN\tinsert size average:\t%.1f\n", avg_isize);
846     printf("SN\tinsert size standard deviation:\t%.1f\n", sd_isize);
847     printf("SN\tinward oriented pairs:\t%ld\n", (long)nisize_inward);
848     printf("SN\toutward oriented pairs:\t%ld\n", (long)nisize_outward);
849     printf("SN\tpairs with other orientation:\t%ld\n", (long)nisize_other);
850
851     int ibase,iqual;
852     if ( stats->max_len<stats->nbases ) stats->max_len++;
853     if ( stats->max_qual+1<stats->nquals ) stats->max_qual++;
854     printf("# First Fragment Qualitites. Use `grep ^FFQ | cut -f 2-` to extract this part.\n");
855     printf("# Columns correspond to qualities and rows to cycles. First column is the cycle number.\n");
856     for (ibase=0; ibase<stats->max_len; ibase++)
857     {
858         printf("FFQ\t%d",ibase+1);
859         for (iqual=0; iqual<=stats->max_qual; iqual++)
860         {
861             printf("\t%ld", (long)stats->quals_1st[ibase*stats->nquals+iqual]);
862         }
863         printf("\n");
864     }
865     printf("# Last Fragment Qualitites. Use `grep ^LFQ | cut -f 2-` to extract this part.\n");
866     printf("# Columns correspond to qualities and rows to cycles. First column is the cycle number.\n");
867     for (ibase=0; ibase<stats->max_len; ibase++)
868     {
869         printf("LFQ\t%d",ibase+1);
870         for (iqual=0; iqual<=stats->max_qual; iqual++)
871         {
872             printf("\t%ld", (long)stats->quals_2nd[ibase*stats->nquals+iqual]);
873         }
874         printf("\n");
875     }
876     if ( stats->mpc_buf )
877     {
878         printf("# Mismatches per cycle and quality. Use `grep ^MPC | cut -f 2-` to extract this part.\n");
879         printf("# Columns correspond to qualities, rows to cycles. First column is the cycle number, second\n");
880         printf("# is the number of N's and the rest is the number of mismatches\n");
881         for (ibase=0; ibase<stats->max_len; ibase++)
882         {
883             printf("MPC\t%d",ibase+1);
884             for (iqual=0; iqual<=stats->max_qual; iqual++)
885             {
886                 printf("\t%ld", (long)stats->mpc_buf[ibase*stats->nquals+iqual]);
887             }
888             printf("\n");
889         }
890     }
891     printf("# GC Content of first fragments. Use `grep ^GCF | cut -f 2-` to extract this part.\n");
892     int ibase_prev = 0;
893     for (ibase=0; ibase<stats->ngc; ibase++)
894     {
895         if ( stats->gc_1st[ibase]==stats->gc_1st[ibase_prev] ) continue;
896         printf("GCF\t%.2f\t%ld\n", (ibase+ibase_prev)*0.5*100./(stats->ngc-1), (long)stats->gc_1st[ibase_prev]);
897         ibase_prev = ibase;
898     }
899     printf("# GC Content of last fragments. Use `grep ^GCL | cut -f 2-` to extract this part.\n");
900     ibase_prev = 0;
901     for (ibase=0; ibase<stats->ngc; ibase++)
902     {
903         if ( stats->gc_2nd[ibase]==stats->gc_2nd[ibase_prev] ) continue;
904         printf("GCL\t%.2f\t%ld\n", (ibase+ibase_prev)*0.5*100./(stats->ngc-1), (long)stats->gc_2nd[ibase_prev]);
905         ibase_prev = ibase;
906     }
907     printf("# ACGT content per cycle. Use `grep ^GCC | cut -f 2-` to extract this part. The columns are: cycle, and A,C,G,T counts [%%]\n");
908     for (ibase=0; ibase<stats->max_len; ibase++)
909     {
910         uint64_t *ptr = &(stats->acgt_cycles[ibase*4]);
911         uint64_t  sum = ptr[0]+ptr[1]+ptr[2]+ptr[3];
912         if ( ! sum ) continue;
913         printf("GCC\t%d\t%.2f\t%.2f\t%.2f\t%.2f\n", ibase,100.*ptr[0]/sum,100.*ptr[1]/sum,100.*ptr[2]/sum,100.*ptr[3]/sum);
914     }
915     printf("# Insert sizes. Use `grep ^IS | cut -f 2-` to extract this part. The columns are: pairs total, inward oriented pairs, outward oriented pairs, other pairs\n");
916     for (isize=1; isize<ibulk; isize++)
917         printf("IS\t%d\t%ld\t%ld\t%ld\t%ld\n", isize, (long)(stats->isize_inward[isize]+stats->isize_outward[isize]+stats->isize_other[isize]),
918             (long)stats->isize_inward[isize], (long)stats->isize_outward[isize], (long)stats->isize_other[isize]);
919
920     printf("# Read lengths. Use `grep ^RL | cut -f 2-` to extract this part. The columns are: read length, count\n");
921     int ilen;
922     for (ilen=0; ilen<stats->max_len; ilen++)
923     {
924         if ( stats->read_lengths[ilen]>0 )
925             printf("RL\t%d\t%ld\n", ilen, (long)stats->read_lengths[ilen]);
926     }
927
928     printf("# Indel distribution. Use `grep ^ID | cut -f 2-` to extract this part. The columns are: length, number of insertions, number of deletions\n");
929     for (ilen=0; ilen<stats->nindels; ilen++)
930     {
931         if ( stats->insertions[ilen]>0 || stats->deletions[ilen]>0 )
932             printf("ID\t%d\t%ld\t%ld\n", ilen+1, (long)stats->insertions[ilen], (long)stats->deletions[ilen]);
933     }
934
935     printf("# Indels per cycle. Use `grep ^IC | cut -f 2-` to extract this part. The columns are: cycle, number of insertions, number of deletions\n");
936     for (ilen=0; ilen<=stats->nbases; ilen++)
937     {
938         if ( stats->ins_cycles[ilen]>0 || stats->del_cycles[ilen]>0 )
939             printf("IC\t%d\t%ld\t%ld\n", ilen+1, (long)stats->ins_cycles[ilen], (long)stats->del_cycles[ilen]);
940     }
941
942     printf("# Coverage distribution. Use `grep ^COV | cut -f 2-` to extract this part.\n");
943     printf("COV\t[<%d]\t%d\t%ld\n",stats->cov_min,stats->cov_min-1, (long)stats->cov[0]);
944     int icov;
945     for (icov=1; icov<stats->ncov-1; icov++)
946         printf("COV\t[%d-%d]\t%d\t%ld\n",stats->cov_min + (icov-1)*stats->cov_step, stats->cov_min + icov*stats->cov_step-1,stats->cov_min + icov*stats->cov_step-1, (long)stats->cov[icov]);
947     printf("COV\t[%d<]\t%d\t%ld\n",stats->cov_min + (stats->ncov-2)*stats->cov_step-1,stats->cov_min + (stats->ncov-2)*stats->cov_step-1, (long)stats->cov[stats->ncov-1]);
948
949
950     // Calculate average GC content, then sort by GC and depth
951     printf("# GC-depth. Use `grep ^GCD | cut -f 2-` to extract this part. The columns are: GC%%, unique sequence percentiles, 10th, 25th, 50th, 75th and 90th depth percentile\n");
952     uint32_t igcd;
953     for (igcd=0; igcd<stats->igcd; igcd++)
954     {
955         if ( stats->fai )
956             stats->gcd[igcd].gc = round(100. * stats->gcd[igcd].gc);
957         else
958             if ( stats->gcd[igcd].depth ) 
959                 stats->gcd[igcd].gc = round(100. * stats->gcd[igcd].gc / stats->gcd[igcd].depth);
960     }
961     qsort(stats->gcd, stats->igcd+1, sizeof(gc_depth_t), gcd_cmp);
962     igcd = 0;
963     while ( igcd < stats->igcd )
964     {
965         // Calculate percentiles (10,25,50,75,90th) for the current GC content and print
966         uint32_t nbins=0, itmp=igcd;
967         float gc = stats->gcd[igcd].gc;
968         while ( itmp<stats->igcd && fabs(stats->gcd[itmp].gc-gc)<0.1 )
969         {
970             nbins++;
971             itmp++;
972         }
973         printf("GCD\t%.1f\t%.3f\t%.3f\t%.3f\t%.3f\t%.3f\t%.3f\n", gc, (igcd+nbins+1)*100./(stats->igcd+1),
974                 gcd_percentile(&(stats->gcd[igcd]),nbins,10) *avg_read_length/stats->gcd_bin_size,
975                 gcd_percentile(&(stats->gcd[igcd]),nbins,25) *avg_read_length/stats->gcd_bin_size, 
976                 gcd_percentile(&(stats->gcd[igcd]),nbins,50) *avg_read_length/stats->gcd_bin_size, 
977                 gcd_percentile(&(stats->gcd[igcd]),nbins,75) *avg_read_length/stats->gcd_bin_size, 
978                 gcd_percentile(&(stats->gcd[igcd]),nbins,90) *avg_read_length/stats->gcd_bin_size 
979               );
980         igcd += nbins;
981     }
982 }
983
984 void bam_init_header_hash(bam_header_t *header);
985
986 size_t getline(char **line, size_t *n, FILE *fp)
987 {
988     if (line == NULL || n == NULL || fp == NULL)
989     {
990         errno = EINVAL;
991         return -1;
992     }
993     if (*n==0 || !*line)
994     {
995         *line = NULL;
996         *n = 0;
997     }
998
999     size_t nread=0;
1000     int c;
1001     while ((c=getc(fp))!= EOF && c!='\n')
1002     {
1003         if ( ++nread>=*n )
1004         {
1005             *n += 255;
1006             *line = realloc(*line, sizeof(char)*(*n));
1007         }
1008         (*line)[nread-1] = c;
1009     }
1010     if ( nread>=*n )
1011     {
1012         *n += 255;
1013         *line = realloc(*line, sizeof(char)*(*n));
1014     }
1015     (*line)[nread] = 0;
1016     return nread>0 ? nread : -1;
1017
1018 }
1019
1020 void init_regions(stats_t *stats, char *file)
1021 {
1022     khiter_t iter;
1023     khash_t(str) *header_hash;
1024
1025     bam_init_header_hash(stats->sam->header);
1026     header_hash = (khash_t(str)*)stats->sam->header->hash;
1027
1028     FILE *fp = fopen(file,"r");
1029     if ( !fp ) error("%s: %s\n",file,strerror(errno));
1030
1031     char *line = NULL;
1032     size_t len = 0;
1033     ssize_t nread;
1034     int warned = 0;
1035     int prev_tid=-1, prev_pos=-1;
1036     while ((nread = getline(&line, &len, fp)) != -1) 
1037     {
1038         if ( line[0] == '#' ) continue;
1039
1040         int i = 0;
1041         while ( i<nread && !isspace(line[i]) ) i++;
1042         if ( i>=nread ) error("Could not parse the file: %s [%s]\n", file,line);
1043         line[i] = 0;
1044
1045         iter = kh_get(str, header_hash, line);
1046         int tid = kh_val(header_hash, iter);
1047         if ( iter == kh_end(header_hash) )
1048         {
1049             if ( !warned )
1050                 fprintf(stderr,"Warning: Some sequences not present in the BAM (%s)\n", line);
1051             warned = 1;
1052             continue;
1053         }
1054
1055         if ( tid >= stats->nregions )
1056         {
1057             stats->regions = realloc(stats->regions,sizeof(regions_t)*(stats->nregions+100));
1058             int j;
1059             for (j=stats->nregions; j<stats->nregions+100; j++)
1060             {
1061                 stats->regions[j].npos = stats->regions[j].mpos = stats->regions[j].cpos = 0;
1062                 stats->regions[j].pos = NULL;
1063             }
1064             stats->nregions += 100;
1065         }
1066         int npos = stats->regions[tid].npos;
1067         if ( npos >= stats->regions[tid].mpos )
1068         {
1069             stats->regions[tid].mpos += 1000;
1070             stats->regions[tid].pos = realloc(stats->regions[tid].pos,sizeof(pos_t)*stats->regions[tid].mpos);
1071         }
1072
1073         if ( (sscanf(line+i+1,"%d %d",&stats->regions[tid].pos[npos].from,&stats->regions[tid].pos[npos].to))!=2 ) error("Could not parse the region [%s]\n");
1074         if ( prev_tid==-1 || prev_tid!=tid )
1075         {
1076             prev_tid = tid;
1077             prev_pos = stats->regions[tid].pos[npos].from;
1078         }
1079         if ( prev_pos>stats->regions[tid].pos[npos].from )
1080             error("The positions are not in chromosomal order (%s:%d comes after %d)\n", line,stats->regions[tid].pos[npos].from,prev_pos);
1081         stats->regions[tid].npos++;
1082     }
1083     if (line) free(line);
1084     fclose(fp);
1085 }
1086
1087 void destroy_regions(stats_t *stats)
1088 {
1089     int i;
1090     for (i=0; i<stats->nregions; i++)
1091     {
1092         if ( !stats->regions[i].mpos ) continue;
1093         free(stats->regions[i].pos);
1094     }
1095     if ( stats->regions ) free(stats->regions);
1096 }
1097
1098 static int fetch_read(const bam1_t *bam_line, void *data)
1099 {
1100     collect_stats((bam1_t*)bam_line,(stats_t*)data);
1101     return 1;
1102 }
1103
1104
1105 void error(const char *format, ...)
1106 {
1107     if ( !format )
1108     {
1109         printf("Version: %s\n", BAMCHECK_VERSION);
1110         printf("About: The program collects statistics from BAM files. The output can be visualized using plot-bamcheck.\n");
1111         printf("Usage: bamcheck [OPTIONS] file.bam\n");
1112         printf("       bamcheck [OPTIONS] file.bam chr:from-to\n");
1113         printf("Options:\n");
1114         printf("    -c, --coverage <int>,<int>,<int>    Coverage distribution min,max,step [1,1000,1]\n");
1115         printf("    -d, --remove-dups                   Exlude from statistics reads marked as duplicates\n");
1116         printf("    -h, --help                          This help message\n");
1117         printf("    -i, --insert-size <int>             Maximum insert size [8000]\n");
1118         printf("    -l, --read-length <int>             Include in the statistics only reads with the given read length []\n");
1119         printf("    -m, --most-inserts <float>          Report only the main part of inserts [0.99]\n");
1120         printf("    -q, --trim-quality <int>            The BWA trimming parameter [0]\n");
1121         printf("    -r, --ref-seq <file>                Reference sequence (required for GC-depth calculation).\n");
1122         printf("    -t, --target-regions <file>         Do stats in these regions only. Tab-delimited file chr,from,to, 1-based, inclusive.\n");
1123         printf("    -s, --sam                           Input is SAM\n");
1124         printf("\n");
1125     }
1126     else
1127     {
1128         va_list ap;
1129         va_start(ap, format);
1130         vfprintf(stderr, format, ap);
1131         va_end(ap);
1132     }
1133     exit(-1);
1134 }
1135
1136 int main(int argc, char *argv[])
1137 {
1138     char *targets = NULL;
1139     char *bam_fname = NULL;
1140     samfile_t *sam = NULL;
1141     char in_mode[5];
1142
1143     stats_t *stats = calloc(1,sizeof(stats_t));
1144     stats->ngc    = 200;
1145     stats->nquals = 95;
1146     stats->nbases = 300;
1147     stats->nisize = 8000;
1148     stats->max_len   = 30;
1149     stats->max_qual  = 40;
1150     stats->isize_main_bulk = 0.99;   // There are always outliers at the far end
1151     stats->gcd_bin_size = 20000;
1152     stats->ngcd         = 3e5;     // 300k of 20k bins is enough to hold a genome 6Gbp big
1153     stats->nref_seq     = stats->gcd_bin_size;
1154     stats->rseq_pos     = -1;
1155     stats->tid = stats->gcd_pos = -1;
1156     stats->is_sorted = 1;
1157     stats->cov_min  = 1;
1158     stats->cov_max  = 1000;
1159     stats->cov_step = 1;
1160     stats->argc = argc;
1161     stats->argv = argv;
1162     stats->filter_readlen = -1;
1163     stats->nindels = stats->nbases;
1164
1165     strcpy(in_mode, "rb");
1166
1167     static struct option loptions[] = 
1168     {
1169         {"help",0,0,'h'},
1170         {"remove-dups",0,0,'d'},
1171         {"sam",0,0,'s'},
1172         {"ref-seq",0,0,'r'},
1173         {"coverage",0,0,'c'},
1174         {"read-length",0,0,'l'},
1175         {"insert-size",0,0,'i'},
1176         {"most-inserts",0,0,'m'},
1177         {"trim-quality",0,0,'q'},
1178         {"target-regions",0,0,'t'},
1179         {0,0,0,0}
1180     };
1181     int opt;
1182     while ( (opt=getopt_long(argc,argv,"?hdsr:c:l:i:t:m:q:",loptions,NULL))>0 )
1183     {
1184         switch (opt)
1185         {
1186             case 'd': stats->rmdup=1; break;
1187             case 's': strcpy(in_mode, "r"); break;
1188             case 'r': stats->fai = fai_load(optarg); 
1189                       if (stats->fai==0) 
1190                           error("Could not load faidx: %s\n", optarg); 
1191                       break;
1192             case 'c': if ( sscanf(optarg,"%d,%d,%d",&stats->cov_min,&stats->cov_max,&stats->cov_step)!= 3 ) 
1193                           error("Unable to parse -c %s\n", optarg); 
1194                       break;
1195             case 'l': stats->filter_readlen = atoi(optarg); break;
1196             case 'i': stats->nisize = atoi(optarg); break;
1197             case 'm': stats->isize_main_bulk = atof(optarg); break;
1198             case 'q': stats->trim_qual = atoi(optarg); break;
1199             case 't': targets = optarg; break;
1200             case '?': 
1201             case 'h': error(NULL);
1202             default: error("Unknown argument: %s\n", optarg);
1203         }
1204     }
1205     if ( optind<argc )
1206         bam_fname = argv[optind++];
1207
1208     if ( !bam_fname )
1209     {
1210         if ( isatty(fileno((FILE *)stdin)) )
1211             error(NULL);
1212         bam_fname = "-";
1213     }
1214
1215     // Init structures
1216     //  .. coverage bins and round buffer
1217     if ( stats->cov_step > stats->cov_max - stats->cov_min + 1 )
1218     {
1219         stats->cov_step = stats->cov_max - stats->cov_min;
1220         if ( stats->cov_step <= 0 )
1221             stats->cov_step = 1;
1222     }
1223     stats->ncov = 3 + (stats->cov_max-stats->cov_min) / stats->cov_step;
1224     stats->cov_max = stats->cov_min + ((stats->cov_max-stats->cov_min)/stats->cov_step +1)*stats->cov_step - 1;
1225     stats->cov = calloc(sizeof(uint64_t),stats->ncov);
1226     stats->cov_rbuf.size = stats->nbases*5;
1227     stats->cov_rbuf.buffer = calloc(sizeof(int32_t),stats->cov_rbuf.size);
1228     // .. bam
1229     if ((sam = samopen(bam_fname, in_mode, NULL)) == 0) 
1230         error("Failed to open: %s\n", bam_fname);
1231     stats->sam = sam;
1232     bam1_t *bam_line = bam_init1();
1233     // .. arrays
1234     stats->quals_1st     = calloc(stats->nquals*stats->nbases,sizeof(uint64_t));
1235     stats->quals_2nd     = calloc(stats->nquals*stats->nbases,sizeof(uint64_t));
1236     stats->gc_1st        = calloc(stats->ngc,sizeof(uint64_t));
1237     stats->gc_2nd        = calloc(stats->ngc,sizeof(uint64_t));
1238     stats->isize_inward  = calloc(stats->nisize,sizeof(uint64_t));
1239     stats->isize_outward = calloc(stats->nisize,sizeof(uint64_t));
1240     stats->isize_other   = calloc(stats->nisize,sizeof(uint64_t));
1241     stats->gcd           = calloc(stats->ngcd,sizeof(gc_depth_t));
1242     stats->rseq_buf      = calloc(stats->nref_seq,sizeof(uint8_t));
1243     stats->mpc_buf       = stats->fai ? calloc(stats->nquals*stats->nbases,sizeof(uint64_t)) : NULL;
1244     stats->acgt_cycles   = calloc(4*stats->nbases,sizeof(uint64_t));
1245     stats->read_lengths  = calloc(stats->nbases,sizeof(uint64_t));
1246     stats->insertions    = calloc(stats->nbases,sizeof(uint64_t));
1247     stats->deletions     = calloc(stats->nbases,sizeof(uint64_t));
1248     stats->ins_cycles    = calloc(stats->nbases+1,sizeof(uint64_t));
1249     stats->del_cycles    = calloc(stats->nbases+1,sizeof(uint64_t));
1250     if ( targets )
1251         init_regions(stats, targets);
1252
1253     // Collect statistics
1254     if ( optind<argc )
1255     {
1256         // Collect stats in selected regions only
1257         bam_index_t *bam_idx = bam_index_load(bam_fname);
1258         if (bam_idx == 0)
1259             error("Random alignment retrieval only works for indexed BAM files.\n");
1260
1261         int i;
1262         for (i=optind; i<argc; i++) 
1263         {
1264             int tid, beg, end;
1265             bam_parse_region(stats->sam->header, argv[i], &tid, &beg, &end);
1266             if ( tid < 0 ) continue;
1267             bam_fetch(stats->sam->x.bam, bam_idx, tid, beg, end, stats, fetch_read);
1268         }
1269         bam_index_destroy(bam_idx);
1270     }
1271     else
1272     {
1273         // Stream through the entire BAM ignoring off-target regions if -t is given
1274         while (samread(sam,bam_line) >= 0) 
1275         {
1276             if ( stats->regions )
1277             {
1278                 if ( bam_line->core.tid >= stats->nregions || bam_line->core.tid<0 ) continue;
1279                 if ( !stats->is_sorted ) error("The BAM must be sorted in order for -t to work.\n");
1280
1281                 regions_t *reg = &stats->regions[bam_line->core.tid];
1282                 if ( reg->cpos==reg->npos ) continue;       // done for this chr
1283
1284                 // Find a matching interval or skip this read. No splicing of reads is done, no indels or soft clips considered, 
1285                 //  even small overlap is enough to include the read in the stats.
1286                 int i = reg->cpos;
1287                 while ( i<reg->npos && reg->pos[i].to<=bam_line->core.pos ) i++;
1288                 if ( i>=reg->npos ) { reg->cpos = reg->npos; continue; }
1289                 if ( bam_line->core.pos + bam_line->core.l_qseq + 1 < reg->pos[i].from ) continue;
1290                 reg->cpos = i;
1291             }
1292             collect_stats(bam_line,stats);
1293         }
1294     }
1295     round_buffer_flush(stats,-1);
1296
1297     output_stats(stats);
1298
1299     bam_destroy1(bam_line);
1300     samclose(stats->sam);
1301     if (stats->fai) fai_destroy(stats->fai);
1302     free(stats->cov_rbuf.buffer); free(stats->cov);
1303     free(stats->quals_1st); free(stats->quals_2nd); 
1304     free(stats->gc_1st); free(stats->gc_2nd);
1305     free(stats->isize_inward); free(stats->isize_outward); free(stats->isize_other);
1306     free(stats->gcd);
1307     free(stats->rseq_buf);
1308     free(stats->mpc_buf);
1309     free(stats->acgt_cycles);
1310     free(stats->read_lengths);
1311     free(stats->insertions);
1312     free(stats->deletions);
1313     free(stats->ins_cycles);
1314     free(stats->del_cycles);
1315     destroy_regions(stats);
1316     free(stats);
1317
1318         return 0;
1319 }
1320
1321
1322