bcftools.1 and samtools.1 were merged in upstream release 0.1.17.
[samtools.git] / bam_tview.c
index 4c121e7cbfa012ac0c3fa61d574f03c893e6d271..4eea955ce05574051c60591dac6a44b5a1ad5edc 100644 (file)
 #include <ctype.h>
 #include <assert.h>
 #include <string.h>
+#include <math.h>
 #include "bam.h"
 #include "faidx.h"
-#include "bam_maqcns.h"
+#include "bam2bcf.h"
 
 char bam_aux_getCEi(bam1_t *b, int i);
 char bam_aux_getCSi(bam1_t *b, int i);
@@ -50,7 +51,7 @@ typedef struct {
        bamFile fp;
        int curr_tid, left_pos;
        faidx_t *fai;
-       bam_maqcns_t *bmc;
+       bcf_callaux_t *bca;
 
        int ccol, last_pos, row_shift, base_for, color_for, is_dot, l_ref, ins, no_skip, show_name;
        char *ref;
@@ -58,6 +59,7 @@ typedef struct {
 
 int tv_pl_func(uint32_t tid, uint32_t pos, int n, const bam_pileup1_t *pl, void *data)
 {
+       extern unsigned char bam_nt16_table[256];
        tview_t *tv = (tview_t*)data;
        int i, j, c, rb, attr, max_ins = 0;
        uint32_t call = 0;
@@ -70,11 +72,26 @@ int tv_pl_func(uint32_t tid, uint32_t pos, int n, const bam_pileup1_t *pl, void
                mvaddch(1, tv->ccol++, c);
        }
        if (pos%10 == 0 && tv->mcol - tv->ccol >= 10) mvprintw(0, tv->ccol, "%-d", pos+1);
-       // print consensus
-       call = bam_maqcns_call(n, pl, tv->bmc);
+       { // call consensus
+               bcf_callret1_t bcr;
+               int qsum[4], a1, a2, tmp;
+               double p[3], prior = 30;
+               bcf_call_glfgen(n, pl, bam_nt16_table[rb], tv->bca, &bcr);
+               for (i = 0; i < 4; ++i) qsum[i] = bcr.qsum[i]<<2 | i;
+               for (i = 1; i < 4; ++i) // insertion sort
+                       for (j = i; j > 0 && qsum[j] > qsum[j-1]; --j)
+                               tmp = qsum[j], qsum[j] = qsum[j-1], qsum[j-1] = tmp;
+               a1 = qsum[0]&3; a2 = qsum[1]&3;
+               p[0] = bcr.p[a1*5+a1]; p[1] = bcr.p[a1*5+a2] + prior; p[2] = bcr.p[a2*5+a2];
+               if ("ACGT"[a1] != toupper(rb)) p[0] += prior + 3;
+               if ("ACGT"[a2] != toupper(rb)) p[2] += prior + 3;
+               if (p[0] < p[1] && p[0] < p[2]) call = (1<<a1)<<16 | (int)((p[1]<p[2]?p[1]:p[2]) - p[0] + .499);
+               else if (p[2] < p[1] && p[2] < p[0]) call = (1<<a2)<<16 | (int)((p[0]<p[1]?p[0]:p[1]) - p[2] + .499);
+               else call = (1<<a1|1<<a2)<<16 | (int)((p[0]<p[2]?p[0]:p[2]) - p[1] + .499);
+       }
        attr = A_UNDERLINE;
-       c = ",ACMGRSVTWYHKDBN"[call>>28&0xf];
-       i = (call>>8&0xff)/10+1;
+       c = ",ACMGRSVTWYHKDBN"[call>>16&0xf];
+       i = (call&0xffff)/10+1;
        if (i > 4) i = 4;
        attr |= COLOR_PAIR(i);
        if (c == toupper(rb)) c = '.';
@@ -109,7 +126,7 @@ int tv_pl_func(uint32_t tid, uint32_t pos, int n, const bam_pileup1_t *pl, void
                                                        if (tv->is_dot && toupper(c) == toupper(rb)) c = bam1_strand(p->b)? ',' : '.';
                                                }
                                        }
-                               } else c = '*';
+                               } else c = p->is_refskip? (bam1_strand(p->b)? '<' : '>') : '*';
                        } else { // padding
                                if (j > p->indel) c = '*';
                                else { // insertion
@@ -183,17 +200,16 @@ tview_t *tv_init(const char *fn, const char *fn_fa)
 {
        tview_t *tv = (tview_t*)calloc(1, sizeof(tview_t));
        tv->is_dot = 1;
-       tv->idx = bam_index_load(fn);
-       if (tv->idx == 0) exit(1);
        tv->fp = bam_open(fn, "r");
        bgzf_set_cache_size(tv->fp, 8 * 1024 *1024);
        assert(tv->fp);
        tv->header = bam_header_read(tv->fp);
+       tv->idx = bam_index_load(fn);
+       if (tv->idx == 0) exit(1);
        tv->lplbuf = bam_lplbuf_init(tv_pl_func, tv);
        if (fn_fa) tv->fai = fai_load(fn_fa);
-       tv->bmc = bam_maqcns_init();
+       tv->bca = bcf_call_init(0.83, 13);
        tv->ins = 1;
-       bam_maqcns_prepare(tv->bmc);
 
        initscr();
        keypad(stdscr, TRUE);
@@ -224,7 +240,7 @@ void tv_destroy(tview_t *tv)
        endwin();
 
        bam_lplbuf_destroy(tv->lplbuf);
-       bam_maqcns_destroy(tv->bmc);
+       bcf_call_destroy(tv->bca);
        bam_index_destroy(tv->idx);
        if (tv->fai) fai_destroy(tv->fai);
        free(tv->ref);
@@ -280,7 +296,7 @@ int tv_draw_aln(tview_t *tv, int tid, int pos)
 
 static void tv_win_goto(tview_t *tv, int *tid, int *pos)
 {
-       char str[256];
+       char str[256], *p;
        int i, l = 0;
        wborder(tv->wgoto, '|', '|', '-', '-', '+', '+', '+', '+');
        mvwprintw(tv->wgoto, 1, 2, "Goto: ");
@@ -291,10 +307,18 @@ static void tv_win_goto(tview_t *tv, int *tid, int *pos)
                        --l;
                } else if (c == KEY_ENTER || c == '\012' || c == '\015') {
                        int _tid = -1, _beg, _end;
-                       bam_parse_region(tv->header, str, &_tid, &_beg, &_end);
-                       if (_tid >= 0) {
-                               *tid = _tid; *pos = _beg;
-                               return;
+                       if (str[0] == '=') {
+                               _beg = strtol(str+1, &p, 10) - 1;
+                               if (_beg > 0) {
+                                       *pos = _beg;
+                                       return;
+                               }
+                       } else {
+                               bam_parse_region(tv->header, str, &_tid, &_beg, &_end);
+                               if (_tid >= 0) {
+                                       *tid = _tid; *pos = _beg;
+                                       return;
+                               }
                        }
                } else if (isgraph(c)) {
                        if (l < TV_MAX_GOTO) str[l++] = c;
@@ -351,6 +375,7 @@ void tv_loop(tview_t *tv)
                        case '?': tv_win_help(tv); break;
                        case '\033':
                        case 'q': goto end_loop;
+                       case '/': 
                        case 'g': tv_win_goto(tv, &tid, &pos); break;
                        case 'm': tv->color_for = TV_COLOR_MAPQ; break;
                        case 'b': tv->color_for = TV_COLOR_BASEQ; break;