X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=bam_tview.c;h=f8a1f2c3c1eeeef25542316d37af98f9819903fa;hb=70c740facc966321754c6bfcc6d61ea056480638;hp=4eea955ce05574051c60591dac6a44b5a1ad5edc;hpb=c350a570e955d5b4c2c13f607b7442df6d332c67;p=samtools.git diff --git a/bam_tview.c b/bam_tview.c index 4eea955..f8a1f2c 100644 --- a/bam_tview.c +++ b/bam_tview.c @@ -20,9 +20,14 @@ #include #include #include +#include #include "bam.h" #include "faidx.h" #include "bam2bcf.h" +#include "sam_header.h" +#include "khash.h" + +KHASH_MAP_INIT_STR(kh_rg, const char *) char bam_aux_getCEi(bam1_t *b, int i); char bam_aux_getCSi(bam1_t *b, int i); @@ -55,6 +60,7 @@ typedef struct { int ccol, last_pos, row_shift, base_for, color_for, is_dot, l_ref, ins, no_skip, show_name; char *ref; + khash_t(kh_rg) *rg_hash; } tview_t; int tv_pl_func(uint32_t tid, uint32_t pos, int n, const bam_pileup1_t *pl, void *data) @@ -114,7 +120,6 @@ int tv_pl_func(uint32_t tid, uint32_t pos, int n, const bam_pileup1_t *pl, void if (!p->is_del) { if (tv->base_for == TV_BASE_COLOR_SPACE && (c = bam_aux_getCSi(p->b, p->qpos))) { - c = bam_aux_getCSi(p->b, p->qpos); // assume that if we found one color, we will be able to get the color error if (tv->is_dot && '-' == bam_aux_getCEi(p->b, p->qpos)) c = bam1_strand(p->b)? ',' : '.'; } else { @@ -196,7 +201,7 @@ int tv_pl_func(uint32_t tid, uint32_t pos, int n, const bam_pileup1_t *pl, void return 0; } -tview_t *tv_init(const char *fn, const char *fn_fa) +tview_t *tv_init(const char *fn, const char *fn_fa, char *samples) { tview_t *tv = (tview_t*)calloc(1, sizeof(tview_t)); tv->is_dot = 1; @@ -211,6 +216,32 @@ tview_t *tv_init(const char *fn, const char *fn_fa) tv->bca = bcf_call_init(0.83, 13); tv->ins = 1; + if ( samples ) + { + if ( !tv->header->dict ) tv->header->dict = sam_header_parse2(tv->header->text); + void *iter = tv->header->dict; + const char *key, *val; + int n = 0; + tv->rg_hash = kh_init(kh_rg); + while ( (iter = sam_header2key_val(iter, "RG","ID","SM", &key, &val)) ) + { + if ( !strcmp(samples,key) || (val && !strcmp(samples,val)) ) + { + khiter_t k = kh_get(kh_rg, tv->rg_hash, key); + if ( k != kh_end(tv->rg_hash) ) continue; + int ret; + k = kh_put(kh_rg, tv->rg_hash, key, &ret); + kh_value(tv->rg_hash, k) = val; + n++; + } + } + if ( !n ) + { + fprintf(stderr,"The sample or read group \"%s\" not present.\n", samples); + exit(-1); + } + } + initscr(); keypad(stdscr, TRUE); clear(); @@ -252,6 +283,13 @@ void tv_destroy(tview_t *tv) int tv_fetch_func(const bam1_t *b, void *data) { tview_t *tv = (tview_t*)data; + if ( tv->rg_hash ) + { + const uint8_t *rg = bam_aux_get(b, "RG"); + if ( !rg ) return 0; + khiter_t k = kh_get(kh_rg, tv->rg_hash, (const char*)(rg + 1)); + if ( k == kh_end(tv->rg_hash) ) return 0; + } if (tv->no_skip) { uint32_t *cigar = bam1_cigar(b); // this is cheating... int i; @@ -304,7 +342,7 @@ static void tv_win_goto(tview_t *tv, int *tid, int *pos) int c = wgetch(tv->wgoto); wrefresh(tv->wgoto); if (c == KEY_BACKSPACE || c == '\010' || c == '\177') { - --l; + if(l > 0) --l; } else if (c == KEY_ENTER || c == '\012' || c == '\015') { int _tid = -1, _beg, _end; if (str[0] == '=') { @@ -416,15 +454,49 @@ end_loop: return; } +void error(const char *format, ...) +{ + if ( !format ) + { + fprintf(stderr, "\n"); + fprintf(stderr, "Usage: bamtk tview [options] [ref.fasta]\n"); + fprintf(stderr, "Options:\n"); + fprintf(stderr, " -p chr:pos go directly to this position\n"); + fprintf(stderr, " -s STR display only reads from this sample or grou\n"); + fprintf(stderr, "\n\n"); + } + else + { + va_list ap; + va_start(ap, format); + vfprintf(stderr, format, ap); + va_end(ap); + } + exit(-1); +} + + int bam_tview_main(int argc, char *argv[]) { tview_t *tv; - if (argc == 1) { - fprintf(stderr, "Usage: bamtk tview [ref.fasta]\n"); - return 1; - } - tv = tv_init(argv[1], (argc == 2)? 0 : argv[2]); - tv_draw_aln(tv, 0, 0); + char *samples=NULL, *position=NULL; + int c; + while ((c = getopt(argc, argv, "s:p:")) >= 0) { + switch (c) { + case 's': samples=optarg; break; + case 'p': position=optarg; break; + default: error(NULL); + } + } + if (argc==optind) error(NULL); + tv = tv_init(argv[optind], (optind+1>=argc)? 0 : argv[optind+1], samples); + if ( position ) + { + int _tid = -1, _beg, _end; + bam_parse_region(tv->header, position, &_tid, &_beg, &_end); + if (_tid >= 0) { tv->curr_tid = _tid; tv->left_pos = _beg; } + } + tv_draw_aln(tv, tv->curr_tid, tv->left_pos); tv_loop(tv); tv_destroy(tv); return 0;