]> git.donarmstrong.com Git - samtools.git/blob - phase.c
* 0.1.12-r924:126
[samtools.git] / phase.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <stdint.h>
5 #include <math.h>
6 #include <zlib.h>
7 #include "bam.h"
8 #include "errmod.h"
9
10 #include "kseq.h"
11 KSTREAM_INIT(gzFile, gzread, 16384)
12
13 #define MAX_VARS 256
14 #define FLIP_PENALTY 2
15 #define FLIP_THRES 4
16 #define MASK_THRES 3
17
18 #define FLAG_FIX_CHIMERA 0x1
19 #define FLAG_LIST_EXCL   0x4
20
21 typedef struct {
22         // configurations, initialized in the main function
23         int flag, k, min_baseQ, min_varLOD, max_depth;
24         // other global variables
25         int vpos_shift;
26         bamFile fp;
27         char *pre;
28         bamFile out[3];
29         // alignment queue
30         int n, m;
31         bam1_t **b;
32 } phaseg_t;
33
34 typedef struct {
35         int8_t seq[MAX_VARS]; // TODO: change to dynamic memory allocation!
36         int vpos, beg, end;
37         uint32_t vlen:16, single:1, flip:1, phase:1, phased:1, ambig:1;
38         uint32_t in:16, out:16; // in-phase and out-phase
39 } frag_t, *frag_p;
40
41 #define rseq_lt(a,b) ((a)->vpos < (b)->vpos)
42
43 #include "khash.h"
44 KHASH_SET_INIT_INT64(set64)
45 KHASH_MAP_INIT_INT64(64, frag_t)
46
47 typedef khash_t(64) nseq_t;
48
49 #include "ksort.h"
50 KSORT_INIT(rseq, frag_p, rseq_lt)
51
52 static char nt16_nt4_table[] = { 4, 0, 1, 4, 2, 4, 4, 4, 3, 4, 4, 4, 4, 4, 4, 4 };
53
54 static inline uint64_t X31_hash_string(const char *s)
55 {
56         uint64_t h = *s;
57         if (h) for (++s ; *s; ++s) h = (h << 5) - h + *s;
58         return h;
59 }
60
61 static void count1(int l, const uint8_t *seq, int *cnt)
62 {
63         int i, j, n_ambi;
64         uint32_t z, x;
65         if (seq[l-1] == 0) return; // do nothing is the last base is ambiguous
66         for (i = n_ambi = 0; i < l; ++i) // collect ambiguous bases
67                 if (seq[i] == 0) ++n_ambi;
68         if (l - n_ambi <= 1) return; // only one SNP
69         for (x = 0; x < 1u<<n_ambi; ++x) { // count
70                 for (i = j = 0, z = 0; i < l; ++i) {
71                         int c;
72                         if (seq[i]) c = seq[i] - 1;
73                         else {
74                                 c = x>>j&1;
75                                 ++j;
76                         }
77                         z = z<<1 | c;
78                 }
79                 ++cnt[z];
80         }
81 }
82
83 static int **count_all(int l, int vpos, nseq_t *hash)
84 {
85         khint_t k;
86         int i, j, **cnt;
87         uint8_t *seq;
88         seq = calloc(l, 1);
89         cnt = calloc(vpos, sizeof(void*));
90         for (i = 0; i < vpos; ++i) cnt[i] = calloc(1<<l, sizeof(int));
91         for (k = 0; k < kh_end(hash); ++k) {
92                 if (kh_exist(hash, k)) {
93                         frag_t *f = &kh_val(hash, k);
94                         if (f->vpos >= vpos || f->single) continue; // out of region; or singleton
95                         if (f->vlen == 1) { // such reads should be flagged as deleted previously if everything is right
96                                 f->single = 1;
97                                 continue;
98                         }
99                         for (j = 1; j < f->vlen; ++j) {
100                                 for (i = 0; i < l; ++i)
101                                         seq[i] = j < l - 1 - i? 0 : f->seq[j - (l - 1 - i)];
102                                 count1(l, seq, cnt[f->vpos + j]);
103                         }
104                 }
105         }
106         free(seq);
107         return cnt;
108 }
109
110 // phasing
111 static int8_t *dynaprog(int l, int vpos, int **w)
112 {
113         int *f[2], *curr, *prev, max, i;
114         int8_t **b, *h = 0;
115         uint32_t x, z = 1u<<(l-1), mask = (1u<<l) - 1;
116         f[0] = calloc(z, sizeof(int));
117         f[1] = calloc(z, sizeof(int));
118         b = calloc(vpos, sizeof(void*));
119         prev = f[0]; curr = f[1];
120         // fill the backtrack matrix
121         for (i = 0; i < vpos; ++i) {
122                 int *wi = w[i], *tmp;
123                 int8_t *bi;
124                 bi = b[i] = calloc(z, 1);
125                 /* In the following, x is the current state, which is the
126                  * lexicographically smaller local haplotype. xc is the complement of
127                  * x, or the larger local haplotype; y0 and y1 are the two predecessors
128                  * of x. */
129                 for (x = 0; x < z; ++x) { // x0 is the smaller 
130                         uint32_t y0, y1, xc;
131                         int c0, c1;
132                         xc = ~x&mask; y0 = x>>1; y1 = xc>>1;
133                         c0 = prev[y0] + wi[x] + wi[xc];
134                         c1 = prev[y1] + wi[x] + wi[xc];
135                         if (c0 > c1) bi[x] = 0, curr[x] = c0;
136                         else bi[x] = 1, curr[x] = c1;
137                 }
138                 tmp = prev; prev = curr; curr = tmp; // swap
139         }
140         { // backtrack
141                 uint32_t max_x = 0;
142                 int which = 0;
143                 h = calloc(vpos, 1);
144                 for (x = 0, max = 0, max_x = 0; x < z; ++x)
145                         if (prev[x] > max) max = prev[x], max_x = x;
146                 for (i = vpos - 1, x = max_x; i >= 0; --i) {
147                         h[i] = which? (~x&1) : (x&1);
148                         which = b[i][x]? !which : which;
149                         x = b[i][x]? (~x&mask)>>1 : x>>1;
150                 }
151         }
152         // free
153         for (i = 0; i < vpos; ++i) free(b[i]);
154         free(f[0]); free(f[1]); free(b);
155         return h;
156 }
157
158 // phase each fragment
159 static uint64_t *fragphase(int vpos, const int8_t *path, nseq_t *hash, int flip)
160 {
161         khint_t k;
162         uint64_t *pcnt;
163         uint32_t *left, *rght, max;
164         left = rght = 0; max = 0;
165         pcnt = calloc(vpos, 8);
166         for (k = 0; k < kh_end(hash); ++k) {
167                 if (kh_exist(hash, k)) {
168                         int i, c[2];
169                         frag_t *f = &kh_val(hash, k);
170                         if (f->vpos >= vpos) continue;
171                         // get the phase
172                         c[0] = c[1] = 0;
173                         for (i = 0; i < f->vlen; ++i) {
174                                 if (f->seq[i] == 0) continue;
175                                 ++c[f->seq[i] == path[f->vpos + i] + 1? 0 : 1];
176                         }
177                         f->phase = c[0] > c[1]? 0 : 1;
178                         f->in = c[f->phase]; f->out = c[1 - f->phase];
179                         f->phased = f->in == f->out? 0 : 1;
180                         f->ambig = (f->in && f->out && f->in <= f->out + 1)? 1 : 0;
181                         // fix chimera
182                         f->flip = 0;
183                         if (flip && c[0] >= 3 && c[1] >= 3) {
184                                 int sum[2], m, mi, md;
185                                 if (f->vlen > max) { // enlarge the array
186                                         max = f->vlen;
187                                         kroundup32(max);
188                                         left = realloc(left, max * 4);
189                                         rght = realloc(rght, max * 4);
190                                 }
191                                 for (i = 0, sum[0] = sum[1] = 0; i < f->vlen; ++i) { // get left counts
192                                         if (f->seq[i]) {
193                                                 int c = f->phase? 2 - f->seq[i] : f->seq[i] - 1;
194                                                 ++sum[c == path[f->vpos + i]? 0 : 1];
195                                         }
196                                         left[i] = sum[1]<<16 | sum[0];
197                                 }
198                                 for (i = f->vlen - 1, sum[0] = sum[1] = 0; i >= 0; --i) { // get right counts
199                                         if (f->seq[i]) {
200                                                 int c = f->phase? 2 - f->seq[i] : f->seq[i] - 1;
201                                                 ++sum[c == path[f->vpos + i]? 0 : 1];
202                                         }
203                                         rght[i] = sum[1]<<16 | sum[0];
204                                 }
205                                 // find the best flip point
206                                 for (i = m = 0, mi = -1, md = -1; i < f->vlen - 1; ++i) {
207                                         int a[2];
208                                         a[0] = (left[i]&0xffff) + (rght[i+1]>>16&0xffff) - (rght[i+1]&0xffff) * FLIP_PENALTY;
209                                         a[1] = (left[i]>>16&0xffff) + (rght[i+1]&0xffff) - (rght[i+1]>>16&0xffff) * FLIP_PENALTY;
210                                         if (a[0] > a[1]) {
211                                                 if (a[0] > m) m = a[0], md = 0, mi = i;
212                                         } else {
213                                                 if (a[1] > m) m = a[1], md = 1, mi = i;
214                                         }
215                                 }
216                                 if (m - c[0] >= FLIP_THRES && m - c[1] >= FLIP_THRES) { // then flip
217                                         f->flip = 1;
218                                         if (md == 0) { // flip the tail
219                                                 for (i = mi + 1; i < f->vlen; ++i)
220                                                         if (f->seq[i] == 1) f->seq[i] = 2;
221                                                         else if (f->seq[i] == 2) f->seq[i] = 1;
222                                         } else { // flip the head
223                                                 for (i = 0; i <= mi; ++i)
224                                                         if (f->seq[i] == 1) f->seq[i] = 2;
225                                                         else if (f->seq[i] == 2) f->seq[i] = 1;
226                                         }
227                                 }
228                         }
229                         // update pcnt[]
230                         if (!f->single) {
231                                 for (i = 0; i < f->vlen; ++i) {
232                                         int c;
233                                         if (f->seq[i] == 0) continue;
234                                         c = f->phase? 2 - f->seq[i] : f->seq[i] - 1;
235                                         if (c == path[f->vpos + i]) {
236                                                 if (f->phase == 0) ++pcnt[f->vpos + i];
237                                                 else pcnt[f->vpos + i] += 1ull<<32;
238                                         } else {
239                                                 if (f->phase == 0) pcnt[f->vpos + i] += 1<<16;
240                                                 else pcnt[f->vpos + i] += 1ull<<48;
241                                         }
242                                 }
243                         }
244                 }
245         }
246         free(left); free(rght);
247         return pcnt;
248 }
249
250 static uint64_t *genmask(int vpos, const uint64_t *pcnt, int *_n)
251 {
252         int i, max = 0, max_i = -1, m = 0, n = 0, beg = 0, score = 0;
253         uint64_t *list = 0;
254         for (i = 0; i < vpos; ++i) {
255                 uint64_t x = pcnt[i];
256                 int c[4], pre = score, s;
257                 c[0] = x&0xffff; c[1] = x>>16&0xffff; c[2] = x>>32&0xffff; c[3] = x>>48&0xffff;
258                 s = (c[1] + c[3] == 0)? -(c[0] + c[2]) : (c[1] + c[3] - 1);
259                 if (c[3] > c[2]) s += c[3] - c[2];
260                 if (c[1] > c[0]) s += c[1] - c[0];
261                 score += s;
262                 if (score < 0) score = 0;
263                 if (pre == 0 && score > 0) beg = i; // change from zero to non-zero
264                 if ((i == vpos - 1 || score == 0) && max >= MASK_THRES) {
265                         if (n == m) {
266                                 m = m? m<<1 : 4;
267                                 list = realloc(list, m * 8);
268                         }
269                         list[n++] = (uint64_t)beg<<32 | max_i;
270                         i = max_i; // reset i to max_i
271                         score = 0;
272                 } else if (score > max) max = score, max_i = i;
273                 if (score == 0) max = 0;
274         }
275         *_n = n;
276         return list;
277 }
278
279 // trim heading and tailing ambiguous bases; mark deleted and remove sequence
280 static int clean_seqs(int vpos, nseq_t *hash)
281 {
282         khint_t k;
283         int ret = 0;
284         for (k = 0; k < kh_end(hash); ++k) {
285                 if (kh_exist(hash, k)) {
286                         frag_t *f = &kh_val(hash, k);
287                         int beg, end, i;
288                         if (f->vpos >= vpos) {
289                                 ret = 1;
290                                 continue;
291                         }
292                         for (i = 0; i < f->vlen; ++i)
293                                 if (f->seq[i] != 0) break;
294                         beg = i;
295                         for (i = f->vlen - 1; i >= 0; --i)
296                                 if (f->seq[i] != 0) break;
297                         end = i + 1;
298                         if (end - beg <= 0) kh_del(64, hash, k);
299                         else {
300                                 if (beg != 0) memmove(f->seq, f->seq + beg, end - beg);
301                                 f->vpos += beg; f->vlen = end - beg;
302                                 f->single = f->vlen == 1? 1 : 0;
303                         }
304                 }
305         }
306         return ret;
307 }
308
309 static void dump_aln(phaseg_t *g, int min_pos, const nseq_t *hash)
310 {
311         int i, is_flip;
312         is_flip = (drand48() < 0.5);
313         for (i = 0; i < g->n; ++i) {
314                 int end, which;
315                 uint64_t key;
316                 khint_t k;
317                 bam1_t *b = g->b[i];
318                 key = X31_hash_string(bam1_qname(b));
319                 end = bam_calend(&b->core, bam1_cigar(b));
320                 if (end > min_pos) break;
321                 k = kh_get(64, hash, key);
322                 if (k == kh_end(hash)) which = 3;
323                 else {
324                         frag_t *f = &kh_val(hash, k);
325                         if (f->ambig) which = 2;
326                         else if (f->phased && f->flip) which = 2;
327                         else if (f->phased == 0) which = 3;
328                         else { // phased and not flipped
329                                 char c = 'Y';
330                                 which = f->phase;
331                                 bam_aux_append(b, "ZP", 'A', 1, (uint8_t*)&c);
332                         }
333                         if (which < 2 && is_flip) which = 1 - which; // increase the randomness
334                 }
335                 if (which == 3) which = (drand48() < 0.5);
336                 bam_write1(g->out[which], b);
337                 bam_destroy1(b);
338                 g->b[i] = 0;
339         }
340         memmove(g->b, g->b + i, (g->n - i) * sizeof(void*));
341         g->n -= i;
342 }
343
344 static int phase(phaseg_t *g, const char *chr, int vpos, uint64_t *cns, nseq_t *hash)
345 {
346         int i, j, n_seqs = kh_size(hash), n_masked = 0, min_pos;
347         khint_t k;
348         frag_t **seqs;
349         int8_t *path, *sitemask;
350         uint64_t *pcnt, *regmask;
351
352         if (vpos == 0) return 0;
353         i = clean_seqs(vpos, hash); // i is true if hash has an element with its vpos >= vpos
354         min_pos = i? cns[vpos]>>32 : 0x7fffffff;
355         if (vpos == 1) {
356                 printf("PS\t%s\t%d\t%d\n", chr, (int)(cns[0]>>32) + 1, (int)(cns[0]>>32) + 1);
357                 printf("M0\t%s\t%d\t%d\t%c\t%c\t%d\t0\t0\t0\t0\n//\n", chr, (int)(cns[0]>>32) + 1, (int)(cns[0]>>32) + 1,
358                         "ACGTX"[cns[0]&3], "ACGTX"[cns[0]>>16&3], g->vpos_shift + 1);
359                 for (k = 0; k < kh_end(hash); ++k) {
360                         if (kh_exist(hash, k)) {
361                                 frag_t *f = &kh_val(hash, k);
362                                 if (f->vpos) continue;
363                                 f->flip = 0;
364                                 if (f->seq[0] == 0) f->phased = 0;
365                                 else f->phased = 1, f->phase = f->seq[0] - 1;
366                         }
367                 }
368                 dump_aln(g, min_pos, hash);
369                 ++g->vpos_shift;
370                 return 1;
371         }
372         { // phase
373                 int **cnt;
374                 uint64_t *mask;
375                 printf("PS\t%s\t%d\t%d\n", chr, (int)(cns[0]>>32) + 1, (int)(cns[vpos-1]>>32) + 1);
376                 sitemask = calloc(vpos, 1);
377                 cnt = count_all(g->k, vpos, hash);
378                 path = dynaprog(g->k, vpos, cnt);
379                 for (i = 0; i < vpos; ++i) free(cnt[i]);
380                 free(cnt);
381                 pcnt = fragphase(vpos, path, hash, 0); // do not fix chimeras when masking
382                 mask = genmask(vpos, pcnt, &n_masked);
383                 regmask = calloc(n_masked, 8);
384                 for (i = 0; i < n_masked; ++i) {
385                         regmask[i] = cns[mask[i]>>32]>>32<<32 | cns[(uint32_t)mask[i]]>>32;
386                         for (j = mask[i]>>32; j <= (int32_t)mask[i]; ++j)
387                                 sitemask[j] = 1;
388                 }
389                 free(mask);
390                 if (g->flag & FLAG_FIX_CHIMERA) {
391                         free(pcnt);
392                         pcnt = fragphase(vpos, path, hash, 1);
393                 }
394         }
395         for (i = 0; i < n_masked; ++i)
396                 printf("FL\t%s\t%d\t%d\n", chr, (int)(regmask[i]>>32) + 1, (int)regmask[i] + 1);
397         for (i = 0; i < vpos; ++i) {
398                 uint64_t x = pcnt[i];
399                 int8_t c[2];
400                 c[0] = (cns[i]&0xffff)>>2 == 0? 4 : (cns[i]&3);
401                 c[1] = (cns[i]>>16&0xffff)>>2 == 0? 4 : (cns[i]>>16&3);
402                 printf("M%d\t%s\t%d\t%d\t%c\t%c\t%d\t%d\t%d\t%d\t%d\n", sitemask[i]+1, chr, (int)(cns[0]>>32) + 1, (int)(cns[i]>>32) + 1, "ACGTX"[c[path[i]]], "ACGTX"[c[1-path[i]]],
403                         i + g->vpos_shift + 1, (int)(x&0xffff), (int)(x>>16&0xffff), (int)(x>>32&0xffff), (int)(x>>48&0xffff));
404         }
405         free(path); free(pcnt); free(regmask); free(sitemask);
406         seqs = calloc(n_seqs, sizeof(void*));
407         for (k = 0, i = 0; k < kh_end(hash); ++k) 
408                 if (kh_exist(hash, k) && kh_val(hash, k).vpos < vpos && !kh_val(hash, k).single)
409                         seqs[i++] = &kh_val(hash, k);
410         n_seqs = i;
411         ks_introsort_rseq(n_seqs, seqs);
412         for (i = 0; i < n_seqs; ++i) {
413                 frag_t *f = seqs[i];
414                 printf("EV\t0\t%s\t%d\t40\t%dM\t*\t0\t0\t", chr, f->vpos + 1 + g->vpos_shift, f->vlen);
415                 for (j = 0; j < f->vlen; ++j) {
416                         uint32_t c = cns[f->vpos + j];
417                         if (f->seq[j] == 0) putchar('N');
418                         else putchar("ACGT"[f->seq[j] == 1? (c&3) : (c>>16&3)]);
419                 }
420                 printf("\t*\tYP:i:%d\tYF:i:%d\tYI:i:%d\tYO:i:%d\tYS:i:%d\n", f->phase, f->flip, f->in, f->out, f->beg+1);
421         }
422         free(seqs);
423         printf("//\n");
424         fflush(stdout);
425         g->vpos_shift += vpos;
426         dump_aln(g, min_pos, hash);
427         return vpos;
428 }
429
430 static void update_vpos(int vpos, nseq_t *hash)
431 {
432         khint_t k;
433         for (k = 0; k < kh_end(hash); ++k) {
434                 if (kh_exist(hash, k)) {
435                         frag_t *f = &kh_val(hash, k);
436                         if (f->vpos < vpos) kh_del(64, hash, k); // TODO: if frag_t::seq is allocated dynamically, free it
437                         else f->vpos -= vpos;
438                 }
439         }
440 }
441
442 static nseq_t *shrink_hash(nseq_t *hash) // TODO: to implement
443 {
444         return hash;
445 }
446
447 static int readaln(void *data, bam1_t *b)
448 {
449         phaseg_t *g = (phaseg_t*)data;
450         int ret;
451         ret = bam_read1(g->fp, b);
452         if (ret < 0) return ret;
453         if (!(b->core.flag & (BAM_FUNMAP|BAM_FSECONDARY|BAM_FQCFAIL|BAM_FDUP)) && g->pre) {
454                 if (g->n == g->m) {
455                         g->m = g->m? g->m<<1 : 16;
456                         g->b = realloc(g->b, g->m * sizeof(void*));
457                 }
458                 g->b[g->n++] = bam_dup1(b);
459         }
460         return ret;
461 }
462
463 static khash_t(set64) *loadpos(const char *fn, bam_header_t *h)
464 {
465         gzFile fp;
466         kstream_t *ks;
467         int ret, dret;
468         kstring_t *str;
469         khash_t(set64) *hash;
470
471         hash = kh_init(set64);
472         str = calloc(1, sizeof(kstring_t));
473         fp = strcmp(fn, "-")? gzopen(fn, "r") : gzdopen(fileno(stdin), "r");
474         ks = ks_init(fp);
475         while (ks_getuntil(ks, 0, str, &dret) >= 0) {
476                 int tid = bam_get_tid(h, str->s);
477                 if (tid >= 0 && dret != '\n') {
478                         if (ks_getuntil(ks, 0, str, &dret) >= 0) {
479                                 uint64_t x = (uint64_t)tid<<32 | (atoi(str->s) - 1);
480                                 kh_put(set64, hash, x, &ret);
481                         } else break;
482                 }
483                 if (dret != '\n') while ((dret = ks_getc(ks)) > 0 && dret != '\n');
484                 if (dret < 0) break;
485         }
486         ks_destroy(ks);
487         gzclose(fp);
488         free(str->s); free(str);
489         return hash;
490 }
491
492 static int gl2cns(float q[16])
493 {
494         int i, j, min_ij;
495         float min, min2;
496         min = min2 = 1e30; min_ij = -1;
497         for (i = 0; i < 4; ++i) {
498                 for (j = i; j < 4; ++j) {
499                         if (q[i<<2|j] < min) min_ij = i<<2|j, min2 = min, min = q[i<<2|j];
500                         else if (q[i<<2|j] < min2) min2 = q[i<<2|j];
501                 }
502         }
503         return (min_ij>>2&3) == (min_ij&3)? 0 : 1<<18 | (min_ij>>2&3)<<16 | (min_ij&3) | (int)(min2 - min + .499) << 2;
504 }
505
506 int main_phase(int argc, char *argv[])
507 {
508         extern void bam_init_header_hash(bam_header_t *header);
509         int c, tid, pos, vpos = 0, n, lasttid = -1, max_vpos = 0;
510         const bam_pileup1_t *plp;
511         bam_plp_t iter;
512         bam_header_t *h;
513         nseq_t *seqs;
514         uint64_t *cns = 0;
515         phaseg_t g;
516         char *fn_list = 0;
517         khash_t(set64) *set = 0;
518         errmod_t *em;
519         uint16_t *bases;
520
521         memset(&g, 0, sizeof(phaseg_t));
522         g.flag = FLAG_FIX_CHIMERA;
523         g.min_varLOD = 37; g.k = 13; g.min_baseQ = 13; g.max_depth = 256;
524         while ((c = getopt(argc, argv, "Q:eFq:k:b:l:D:")) >= 0) {
525                 switch (c) {
526                         case 'D': g.max_depth = atoi(optarg); break;
527                         case 'q': g.min_varLOD = atoi(optarg); break;
528                         case 'Q': g.min_baseQ = atoi(optarg); break;
529                         case 'k': g.k = atoi(optarg); break;
530                         case 'F': g.flag &= ~FLAG_FIX_CHIMERA; break;
531                         case 'e': g.flag |= FLAG_LIST_EXCL; break;
532                         case 'b': g.pre = strdup(optarg); break;
533                         case 'l': fn_list = strdup(optarg); break;
534                 }
535         }
536         if (argc == optind) {
537                 fprintf(stderr, "\n");
538                 fprintf(stderr, "Usage:   samtools phase [options] <in.bam>\n\n");
539                 fprintf(stderr, "Options: -k INT    block length [%d]\n", g.k);
540                 fprintf(stderr, "         -b STR    prefix of BAMs to output [null]\n");
541                 fprintf(stderr, "         -q INT    min het phred-LOD [%d]\n", g.min_varLOD);
542                 fprintf(stderr, "         -Q INT    min base quality in het calling [%d]\n", g.min_baseQ);
543                 fprintf(stderr, "         -D INT    max read depth [%d]\n", g.max_depth);
544 //              fprintf(stderr, "         -l FILE   list of sites to phase [null]\n");
545                 fprintf(stderr, "         -F        do not attempt to fix chimeras\n");
546 //              fprintf(stderr, "         -e        do not discover SNPs (effective with -l)\n");
547                 fprintf(stderr, "\n");
548                 return 1;
549         }
550         g.fp = strcmp(argv[optind], "-")? bam_open(argv[optind], "r") : bam_dopen(fileno(stdin), "r");
551         h = bam_header_read(g.fp);
552         if (fn_list) { // read the list of sites to phase
553                 bam_init_header_hash(h);
554                 set = loadpos(fn_list, h);
555                 free(fn_list);
556         } else g.flag &= ~FLAG_LIST_EXCL;
557         if (g.pre) { // open BAMs to write
558                 char *s = malloc(strlen(g.pre) + 20);
559                 strcpy(s, g.pre); strcat(s, ".0.bam"); g.out[0] = bam_open(s, "w");
560                 strcpy(s, g.pre); strcat(s, ".1.bam"); g.out[1] = bam_open(s, "w");
561                 strcpy(s, g.pre); strcat(s, ".chimera.bam"); g.out[2] = bam_open(s, "w");
562                 for (c = 0; c <= 2; ++c) bam_header_write(g.out[c], h);
563                 free(s);
564         }
565
566         iter = bam_plp_init(readaln, &g);
567         g.vpos_shift = 0;
568         seqs = kh_init(64);
569         em = errmod_init(1. - 0.83);
570         bases = calloc(g.max_depth, 2);
571         printf("CC\n");
572         printf("CC\tDescriptions:\nCC\n");
573         printf("CC\t  CC      comments\n");
574         printf("CC\t  PS      start of a phase set\n");
575         printf("CC\t  FL      filtered region\n");
576         printf("CC\t  M[012]  markers; 0 for singletons, 1 for phased and 2 for filtered\n");
577         printf("CC\t  EV      supporting reads; SAM format\n");
578         printf("CC\t  //      end of a phase set\nCC\n");
579         printf("CC\tFormats of PS, FL and M[012] lines (1-based coordinates):\nCC\n");
580         printf("CC\t  PS  chr  phaseSetStart  phaseSetEnd\n");
581         printf("CC\t  FL  chr  filterStart    filterEnd\n");
582         printf("CC\t  M?  chr  PS  pos  allele0  allele1  hetIndex  #supports0  #errors0  #supp1  #err1\n");
583         printf("CC\nCC\n");
584         fflush(stdout);
585         while ((plp = bam_plp_auto(iter, &tid, &pos, &n)) != 0) {
586                 int i, k, c, tmp, dophase = 1, in_set = 0;
587                 float q[16];
588                 if (tid < 0) break;
589                 if (tid != lasttid) { // change of chromosome
590                         g.vpos_shift = 0;
591                         if (lasttid >= 0) {
592                                 seqs = shrink_hash(seqs);
593                                 phase(&g, h->target_name[lasttid], vpos, cns, seqs);
594                                 update_vpos(0x7fffffff, seqs);
595                         }
596                         lasttid = tid;
597                         vpos = 0;
598                 }
599                 if (set && kh_get(set64, set, (uint64_t)tid<<32 | pos) != kh_end(set)) in_set = 1;
600                 if (n > g.max_depth) continue; // do not proceed if the depth is too high
601                 // fill the bases array and check if there is a variant
602                 for (i = k = 0; i < n; ++i) {
603                         const bam_pileup1_t *p = plp + i;
604                         uint8_t *seq;
605                         int q, baseQ, b;
606                         if (p->is_del || p->is_refskip) continue;
607                         baseQ = bam1_qual(p->b)[p->qpos];
608                         if (baseQ < g.min_baseQ) continue;
609                         seq = bam1_seq(p->b);
610                         b = bam_nt16_nt4_table[bam1_seqi(seq, p->qpos)];
611                         if (b > 3) continue;
612                         q = baseQ < p->b->core.qual? baseQ : p->b->core.qual;
613                         if (q < 4) q = 4;
614                         if (q > 63) q = 63;
615                         bases[k++] = q<<5 | (int)bam1_strand(p->b)<<4 | b;
616                 }
617                 if (k == 0) continue;
618                 errmod_cal(em, k, 4, bases, q); // compute genotype likelihood
619                 c = gl2cns(q); // get the consensus
620                 // tell if to proceed
621                 if (set && (g.flag&FLAG_LIST_EXCL) && !in_set) continue; // not in the list
622                 if (!in_set && (c&0xffff)>>2 < g.min_varLOD) continue; // not a variant
623                 // add the variant
624                 if (vpos == max_vpos) {
625                         max_vpos = max_vpos? max_vpos<<1 : 128;
626                         cns = realloc(cns, max_vpos * 8);
627                 }
628                 cns[vpos] = (uint64_t)pos<<32 | c;
629                 for (i = 0; i < n; ++i) {
630                         const bam_pileup1_t *p = plp + i;
631                         uint64_t key;
632                         khint_t k;
633                         uint8_t *seq = bam1_seq(p->b);
634                         frag_t *f;
635                         if (p->is_del || p->is_refskip) continue;
636                         if (p->b->core.qual == 0) continue;
637                         // get the base code
638                         c = nt16_nt4_table[(int)bam1_seqi(seq, p->qpos)];
639                         if (c == (cns[vpos]&3)) c = 1;
640                         else if (c == (cns[vpos]>>16&3)) c = 2;
641                         else c = 0;
642                         // write to seqs
643                         key = X31_hash_string(bam1_qname(p->b));
644                         k = kh_put(64, seqs, key, &tmp);
645                         f = &kh_val(seqs, k);
646                         if (tmp == 0) { // present in the hash table
647                                 if (vpos - f->vpos + 1 < MAX_VARS) {
648                                         f->vlen = vpos - f->vpos + 1;
649                                         f->seq[f->vlen-1] = c;
650                                         f->end = bam_calend(&p->b->core, bam1_cigar(p->b));
651                                 }
652                                 dophase = 0;
653                         } else { // absent
654                                 memset(f->seq, 0, MAX_VARS);
655                                 f->beg = p->b->core.pos;
656                                 f->end = bam_calend(&p->b->core, bam1_cigar(p->b));
657                                 f->vpos = vpos, f->vlen = 1, f->seq[0] = c, f->single = f->phased = f->flip = f->ambig = 0;
658                         }
659                 }
660                 if (dophase) {
661                         seqs = shrink_hash(seqs);
662                         phase(&g, h->target_name[tid], vpos, cns, seqs);
663                         update_vpos(vpos, seqs);
664                         cns[0] = cns[vpos];
665                         vpos = 0;
666                 }
667                 ++vpos;
668         }
669         if (tid >= 0) phase(&g, h->target_name[tid], vpos, cns, seqs);
670         bam_header_destroy(h);
671         bam_plp_destroy(iter);
672         bam_close(g.fp);
673         kh_destroy(64, seqs);
674         kh_destroy(set64, set);
675         free(cns);
676         errmod_destroy(em);
677         free(bases);
678         if (g.pre) {
679                 for (c = 0; c <= 2; ++c) bam_close(g.out[c]);
680                 free(g.pre); free(g.b);
681         }
682         return 0;
683 }