#include <assert.h>
#include <string.h>
#include <math.h>
+#include <unistd.h>
#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);
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)
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;
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();
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;
return;
}
+void error(const char *format, ...)
+{
+ if ( !format )
+ {
+ fprintf(stderr, "\n");
+ fprintf(stderr, "Usage: bamtk tview [options] <aln.bam> [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 <aln.bam> [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;