bam_rmdup.o bam_rmdupse.o bam_mate.o bam_stat.o bam_color.o \
bamtk.o kaln.o bam2bcf.o bam2bcf_indel.o errmod.o sample.o \
cut_target.o phase.o bam2depth.o padding.o bedcov.o bamshuf.o \
- bam_tview_curses.o
+ bam_tview_curses.o bam_tview_html.o
PROG= samtools
INCLUDES= -I.
SUBDIRS= . bcftools misc
bam_index.o:bam.h khash.h ksort.h razf.h bam_endian.h
bam_lpileup.o:bam.h ksort.h
bam_tview.o:bam.h faidx.h bam_tview.h
-bam_tview_curses.o:bam.h faidx.h bam_tview.h bam_tview_curses.h
+bam_tview_curses.o:bam.h faidx.h bam_tview.h
+bam_tview_html.o:bam.h faidx.h bam_tview.h
bam_sort.o:bam.h ksort.h razf.h
bam_md.o:bam.h faidx.h
sam_header.o:sam_header.h khash.h
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 = BAM_TVIEW_UNDERLINE;
+ attr = tv->my_underline(tv);
c = ",ACMGRSVTWYHKDBN"[call>>16&0xf];
i = (call&0xffff)/10+1;
if (i > 4) i = 4;
int x;
attr = 0;
if (((p->b->core.flag&BAM_FPAIRED) && !(p->b->core.flag&BAM_FPROPER_PAIR))
- || (p->b->core.flag & BAM_FSECONDARY)) attr |= BAM_TVIEW_UNDERLINE;
+ || (p->b->core.flag & BAM_FSECONDARY)) attr |= tv->my_underline(tv);
if (tv->color_for == TV_COLOR_BASEQ) {
x = bam1_qual(p->b)[p->qpos]/10 + 1;
if (x > 4) x = 4;
- attr |= COLOR_PAIR(x);
+ attr |= tv->my_colorpair(tv,x);
} else if (tv->color_for == TV_COLOR_MAPQ) {
x = p->b->core.qual/10 + 1;
if (x > 4) x = 4;
- attr |= COLOR_PAIR(x);
+ attr |= tv->my_colorpair(tv,x);
} else if (tv->color_for == TV_COLOR_NUCL) {
x = bam_nt16_nt4_table[bam1_seqi(bam1_seq(p->b), p->qpos)] + 5;
- attr |= COLOR_PAIR(x);
+ attr |= tv->my_colorpair(tv,x);
} else if(tv->color_for == TV_COLOR_COL) {
x = 0;
switch(bam_aux_getCSi(p->b, p->qpos)) {
default: x = bam_nt16_nt4_table[bam1_seqi(bam1_seq(p->b), p->qpos)]; break;
}
x+=5;
- attr |= COLOR_PAIR(x);
+ attr |= tv->my_colorpair(tv,x);
} else if(tv->color_for == TV_COLOR_COLQ) {
x = bam_aux_getCQi(p->b, p->qpos);
if(0 == x) x = bam1_qual(p->b)[p->qpos];
x = x/10 + 1;
if (x > 4) x = 4;
- attr |= COLOR_PAIR(x);
+ attr |= tv->my_colorpair(tv,x);
}
tv->my_attron(tv,attr);
tv->my_mvaddch(tv,row, tv->ccol, bam1_strand(p->b)? tolower(c) : toupper(c));
}
c = j? '*' : rb;
if (c == '*') {
- attr = COLOR_PAIR(8);
+ attr = tv->my_colorpair(tv,8);
tv->my_attron(tv,attr);
tv->my_mvaddch(tv,1, tv->ccol++, c);
tv->my_attroff(tv,attr);
return 0;
}
-int tv_draw_aln(tview_t *tv, int tid, int pos)
+int base_draw_aln(tview_t *tv, int tid, int pos)
{
assert(tv!=NULL);
// reset
return 0;
}
+
+
+
+static 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 group\n");
+ fprintf(stderr, " -d display (H)tml or (C)urses or (T)ext \n");
+ fprintf(stderr, "\n\n");
+ }
+ else
+ {
+ va_list ap;
+ va_start(ap, format);
+ vfprintf(stderr, format, ap);
+ va_end(ap);
+ }
+ exit(-1);
+}
+
+enum dipsay_mode {display_ncurses,display_html,display_text};
+extern tview_t* curses_tv_init(const char *fn, const char *fn_fa, const char *samples);
+extern tview_t* html_tv_init(const char *fn, const char *fn_fa, const char *samples);
+int bam_tview_main(int argc, char *argv[])
+ {
+ int view_mode=display_ncurses;
+ tview_t* tv=NULL;
+ char *samples=NULL, *position=NULL;
+ int c;
+ while ((c = getopt(argc, argv, "s:p:d:")) >= 0) {
+ switch (c) {
+ case 's': samples=optarg; break;
+ case 'p': position=optarg; break;
+ case 'd':
+ {
+ switch(optarg[0])
+ {
+ case 'H': case 'h': view_mode=display_html;break;
+ case 'T': case 't': view_mode=display_text;break;
+ case 'C': case 'c': view_mode=display_ncurses;break;
+ default: view_mode=display_ncurses;break;
+ }
+ break;
+ }
+ default: error(NULL);
+ }
+ }
+ if (argc==optind) error(NULL);
+
+ switch(view_mode)
+ {
+ case display_ncurses:
+ {
+ tv = curses_tv_init(argv[optind], (optind+1>=argc)? 0 : argv[optind+1], samples);
+ break;
+ }
+ case display_text:
+ case display_html:
+ {
+ tv = html_tv_init(argv[optind], (optind+1>=argc)? 0 : argv[optind+1], samples);
+ break;
+ }
+ }
+ if(tv==NULL)
+ {
+ error("cannot create view");
+ return EXIT_FAILURE;
+ }
+
+ 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->my_drawaln(tv, tv->curr_tid, tv->left_pos);
+ tv->my_loop(tv);
+ tv->my_destroy(tv);
+
+ return EXIT_SUCCESS;
+ }
#include <string.h>
#include <math.h>
#include <unistd.h>
+#include <stdarg.h>
#include "bam.h"
#include "faidx.h"
#include "bam2bcf.h"
void (*my_attroff)(struct AbstractTview*,int);
void (*my_clear)(struct AbstractTview*);
int (*my_colorpair)(struct AbstractTview*,int);
+ int (*my_drawaln)(struct AbstractTview*,int,int);
+ int (*my_loop)(struct AbstractTview*);
+ int (*my_underline)(struct AbstractTview*);
} tview_t;
int tv_pl_func(uint32_t tid, uint32_t pos, int n, const bam_pileup1_t *pl, void *data);
int base_tv_init(tview_t*,const char *fn, const char *fn_fa, const char *samples);
void base_tv_destroy(tview_t*);
+int base_draw_aln(tview_t *tv, int tid, int pos);
-int tv_draw_aln(tview_t *tv, int tid, int pos);
-
-
-enum {
- BAM_TVIEW_UNDERLINE
- };
+typedef struct Tixel
+ {
+ int ch;
+ int attributes;
+ }tixel_t;
#endif
-#include "bam_tview_curses.h"
+#include <curses.h>
+#include "bam_tview.h"
+
+typedef struct CursesTview {
+ tview_t view;
+ WINDOW *wgoto, *whelp;
+ } curses_tview_t;
+
+
#define FROM_TV(ptr) ((curses_tview_t*)ptr)
{
unsigned int size=tv->mcol+2;
char* str=malloc(size);
+ if(str==0) exit(EXIT_FAILURE);
va_list argptr;
va_start(argptr, fmt);
vsnprintf(str,size, fmt, argptr);
return COLOR_PAIR(flag);
}
-
-#define SET_CALLBACK(fun) base->my_##fun=curses_##fun;
+static int curses_drawaln(struct AbstractTview* tv, int tid, int pos)
+ {
+ return base_draw_aln(tv, tid, pos);
+ }
-curses_tview_t* curses_tv_init(const char *fn, const char *fn_fa, const char *samples)
- {
- curses_tview_t *tv = (curses_tview_t*)calloc(1, sizeof(curses_tview_t));
- tview_t* base=(tview_t*)tv;
- if(tv==0)
- {
- fprintf(stderr,"Calloc failed\n");
- return 0;
- }
-
- base_tv_init(base,fn,fn_fa,samples);
- /* initialize callbacks */
- SET_CALLBACK(destroy);
- SET_CALLBACK(mvprintw);
- SET_CALLBACK(mvaddch);
- SET_CALLBACK(attron);
- SET_CALLBACK(attroff);
- SET_CALLBACK(clear);
- SET_CALLBACK(colorpair);
-
- initscr();
- keypad(stdscr, TRUE);
- clear();
- noecho();
- cbreak();
-
- getmaxyx(stdscr, base->mrow, base->mcol);
- tv->wgoto = newwin(3, TV_MAX_GOTO + 10, 10, 5);
- tv->whelp = newwin(29, 40, 5, 5);
-
- start_color();
- init_pair(1, COLOR_BLUE, COLOR_BLACK);
- init_pair(2, COLOR_GREEN, COLOR_BLACK);
- init_pair(3, COLOR_YELLOW, COLOR_BLACK);
- init_pair(4, COLOR_WHITE, COLOR_BLACK);
- init_pair(5, COLOR_GREEN, COLOR_BLACK);
- init_pair(6, COLOR_CYAN, COLOR_BLACK);
- init_pair(7, COLOR_YELLOW, COLOR_BLACK);
- init_pair(8, COLOR_RED, COLOR_BLACK);
- init_pair(9, COLOR_BLUE, COLOR_BLACK);
- return tv;
- }
-
-
static void tv_win_goto(curses_tview_t *tv, int *tid, int *pos)
{
char str[256], *p;
wgetch(win);
}
-void tv_loop(curses_tview_t *CTV)
-{
+static int curses_underline(tview_t* tv)
+ {
+ return A_UNDERLINE;
+ }
+
+static int curses_loop(tview_t* tv)
+ {
int tid, pos;
- tview_t* tv=(tview_t*)CTV;
+ curses_tview_t *CTV=(curses_tview_t *)tv;
tid = tv->curr_tid; pos = tv->left_pos;
while (1) {
int c = getch();
}
if (pos < 0) pos = 0;
if (tv->row_shift < 0) tv->row_shift = 0;
- tv_draw_aln(tv, tid, pos);
+ tv->my_drawaln(tv, tid, pos);
}
end_loop:
- return;
+ return 0;
}
-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[])
-{
- curses_tview_t *CTV;
- tview_t* tv=NULL;
- 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);
- CTV = curses_tv_init(argv[optind], (optind+1>=argc)? 0 : argv[optind+1], samples);
- tv=(tview_t*)CTV;
- 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(CTV);
- tv->my_destroy(tv);
+
+tview_t* curses_tv_init(const char *fn, const char *fn_fa, const char *samples)
+ {
+ curses_tview_t *tv = (curses_tview_t*)calloc(1, sizeof(curses_tview_t));
+ tview_t* base=(tview_t*)tv;
+ if(tv==0)
+ {
+ fprintf(stderr,"Calloc failed\n");
+ return 0;
+ }
+
+ base_tv_init(base,fn,fn_fa,samples);
+ /* initialize callbacks */
+#define SET_CALLBACK(fun) base->my_##fun=curses_##fun;
+ SET_CALLBACK(destroy);
+ SET_CALLBACK(mvprintw);
+ SET_CALLBACK(mvaddch);
+ SET_CALLBACK(attron);
+ SET_CALLBACK(attroff);
+ SET_CALLBACK(clear);
+ SET_CALLBACK(colorpair);
+ SET_CALLBACK(drawaln);
+ SET_CALLBACK(loop);
+ SET_CALLBACK(underline);
+#undef SET_CALLBACK
+
+ initscr();
+ keypad(stdscr, TRUE);
+ clear();
+ noecho();
+ cbreak();
+
+ getmaxyx(stdscr, base->mrow, base->mcol);
+ tv->wgoto = newwin(3, TV_MAX_GOTO + 10, 10, 5);
+ tv->whelp = newwin(29, 40, 5, 5);
+
+ start_color();
+ init_pair(1, COLOR_BLUE, COLOR_BLACK);
+ init_pair(2, COLOR_GREEN, COLOR_BLACK);
+ init_pair(3, COLOR_YELLOW, COLOR_BLACK);
+ init_pair(4, COLOR_WHITE, COLOR_BLACK);
+ init_pair(5, COLOR_GREEN, COLOR_BLACK);
+ init_pair(6, COLOR_CYAN, COLOR_BLACK);
+ init_pair(7, COLOR_YELLOW, COLOR_BLACK);
+ init_pair(8, COLOR_RED, COLOR_BLACK);
+ init_pair(9, COLOR_BLUE, COLOR_BLACK);
+ return base;
+ }
+
+
+
- return 0;
-}
+++ /dev/null
-#ifndef BAM_TVIEW_CURSES_H
-#define BAM_TVIEW_CURSES_H
-
-#include <curses.h>
-#include "bam_tview.h"
-
-typedef struct CursesTview {
- tview_t view;
- WINDOW *wgoto, *whelp;
- } curses_tview_t;
-
-
-curses_tview_t* curses_tv_init(const char *fn, const char *fn_fa,const char *samples);
-
-#endif
-
--- /dev/null
+#include "bam_tview.h"
+
+typedef struct HtmlTview {
+ tview_t view;
+ int row_count;
+ tixel_t** screen;
+ FILE* out;
+ int attributes;/* color... */
+ } html_tview_t;
+
+#define FROM_TV(ptr) ((html_tview_t*)ptr)
+
+static void html_destroy(tview_t* base)
+ {
+ int i;
+ html_tview_t* tv=(html_tview_t*)base;
+ if(tv->screen!=NULL)
+ {
+ for(i=0;i< tv->row_count;++i) free(tv->screen[i]);
+ free(tv->screen);
+ }
+ base_tv_destroy(base);
+ free(tv);
+ }
+
+/*
+ void (*my_mvprintw)(struct AbstractTview* ,int,int,const char*,...);
+ void (*my_)(struct AbstractTview*,int,int,int);
+ void (*my_attron)(struct AbstractTview*,int);
+ void (*my_attroff)(struct AbstractTview*,int);
+ void (*my_clear)(struct AbstractTview*);
+ int (*my_colorpair)(struct AbstractTview*,int);
+*/
+
+static void html_mvprintw(struct AbstractTview* tv,int y ,int x,const char* fmt,...)
+ {
+ int i,nchars=0;
+ unsigned int size=tv->mcol+2;
+ char* str=malloc(size);
+ if(str==0) exit(EXIT_FAILURE);
+ va_list argptr;
+ va_start(argptr, fmt);
+ nchars=vsnprintf(str,size, fmt, argptr);
+ va_end(argptr);
+
+ for(i=0;i< nchars;++i)
+ {
+ tv->my_mvaddch(tv,y,x+i,str[i]);
+ }
+ free(str);
+ }
+
+static void html_mvaddch(struct AbstractTview* tv,int y,int x,int ch)
+ {
+ tixel_t* row=NULL;
+ html_tview_t* ptr=FROM_TV(tv);
+ if( x >= tv->mcol ) return; //out of screen
+ while(ptr->row_count<=y)
+ {
+ int x;
+ row=(tixel_t*)calloc(tv->mcol,sizeof(tixel_t));
+ if(row==0) exit(EXIT_FAILURE);
+ for(x=0;x<tv->mcol;++x) {row[x].ch=' ';row[x].attributes=0;}
+ ptr->screen=(tixel_t**)realloc(ptr->screen,sizeof(tixel_t*)*(ptr->row_count+1));
+ ptr->screen[ptr->row_count++]=row;
+ }
+ row=ptr->screen[y];
+ row[x].ch=ch;
+ row[x].attributes=ptr->attributes;
+ }
+
+static void html_attron(struct AbstractTview* tv,int flag)
+ {
+ html_tview_t* ptr=FROM_TV(tv);
+ ptr->attributes |= 1 << flag;
+ }
+
+static void html_attroff(struct AbstractTview* tv,int flag)
+ {
+ html_tview_t* ptr=FROM_TV(tv);
+ ptr->attributes &= ~(1 << flag);
+ }
+
+static void html_clear(struct AbstractTview* tv)
+ {
+ html_tview_t* ptr=FROM_TV(tv);
+ if(ptr->screen!=NULL)
+ {
+ int i;
+ for(i=0;i< ptr->row_count;++i) free(ptr->screen[i]);
+ free(ptr->screen);
+ ptr->screen=NULL;
+ }
+ ptr->row_count=0;
+ ptr->attributes=0;
+ }
+
+static int html_colorpair(struct AbstractTview* tv,int flag)
+ {
+ return flag;
+ }
+
+static int html_drawaln(struct AbstractTview* tv, int tid, int pos)
+ {
+ int y,x;
+ html_tview_t* ptr=FROM_TV(tv);
+ html_clear(tv);
+ base_draw_aln(tv, tid, pos);
+ fputs("<html><head>",ptr->out);
+
+ //style
+ fputs("<style type='text/css'>",ptr->out);
+ #define CSS(id,col) fprintf(ptr->out,".tviewc%d {color:%s;}\n.tviewcu%d {color:%s;text-decoration:underline;}\n",id,col,id,col);
+ CSS(0, "black");
+ CSS(1, "blue");
+ CSS(2, "green");
+ CSS(3, "yellow");
+ CSS(4, "black");
+ CSS(5, "green");
+ CSS(6, "cyan");
+ CSS(7, "yellow");
+ CSS(8, "red");
+ CSS(9, "blue");
+ #undef CSS
+ fputs("</style>",ptr->out);
+
+ fputs("</head><body>",ptr->out);
+ fputs("<pre class='tview'>\n",ptr->out);
+ for(y=0;y< ptr->row_count;++y)
+ {
+
+ for(x=0;x< tv->mcol;++x)
+ {
+
+
+ if(x== 0 || ptr->screen[y][x].attributes!=ptr->screen[y][x-1].attributes)
+ {
+ int css=0;
+ fputs("<span class='",ptr->out);
+ while(css<10)
+ {
+ if((ptr->screen[y][x].attributes & (1 << css))!=0)
+ {
+ break;
+ }
+ ++css;
+ }
+ if(css>=10) css=0;
+ fprintf(ptr->out,"tviewc%d",css);
+ fputs("'>",ptr->out);
+ }
+
+ int ch=ptr->screen[y][x].ch;
+ switch(ch)
+ {
+ case '<': fputs("<",ptr->out);break;
+ case '>': fputs(">",ptr->out);break;
+ case '&': fputs("&",ptr->out);break;
+ default: fputc(ch,ptr->out); break;
+ }
+
+
+ if(x+1 == tv->mcol || ptr->screen[y][x].attributes!=ptr->screen[y][x+1].attributes)
+ {
+ fputs("</span>",ptr->out);
+ }
+ }
+ if(y+1 < ptr->row_count) fputs("<br/>",ptr->out);
+ }
+ fputs("</pre></body></html>",ptr->out);
+ return 0;
+ }
+
+static int text_drawaln(struct AbstractTview* tv, int tid, int pos)
+ {
+ int y,x;
+ html_tview_t* ptr=FROM_TV(tv);
+ html_clear(tv);
+ base_draw_aln(tv, tid, pos);
+ for(y=0;y< ptr->row_count;++y)
+ {
+ for(x=0;x< tv->mcol;++x)
+ {
+ int ch=ptr->screen[y][x].ch;
+
+ fputc(ch,ptr->out);
+ }
+ fputc('\n',ptr->out);
+ }
+ return 0;
+ }
+
+
+static int html_loop(tview_t* tv)
+ {
+ //tv->my_drawaln(tv, tv->curr_tid, tv->left_pos);
+ return 0;
+ }
+
+static int html_underline(tview_t* tv)
+ {
+ return 11;
+ }
+
+/*
+static void init_pair(html_tview_t *tv,int id_ge_1, const char* pen, const char* paper)
+ {
+
+ }
+*/
+
+tview_t* html_tv_init(const char *fn, const char *fn_fa, const char *samples)
+ {
+ char* colstr=getenv("COLUMNS");
+ html_tview_t *tv = (html_tview_t*)calloc(1, sizeof(html_tview_t));
+ tview_t* base=(tview_t*)tv;
+ if(tv==0)
+ {
+ fprintf(stderr,"Calloc failed\n");
+ return 0;
+ }
+ tv->row_count=0;
+ tv->screen=NULL;
+ tv->out=stdout;
+ tv->attributes=0;
+ base_tv_init(base,fn,fn_fa,samples);
+ /* initialize callbacks */
+#define SET_CALLBACK(fun) base->my_##fun=html_##fun;
+ SET_CALLBACK(destroy);
+ SET_CALLBACK(mvprintw);
+ SET_CALLBACK(mvaddch);
+ SET_CALLBACK(attron);
+ SET_CALLBACK(attroff);
+ SET_CALLBACK(clear);
+ SET_CALLBACK(colorpair);
+ SET_CALLBACK(drawaln);
+ SET_CALLBACK(loop);
+ SET_CALLBACK(underline);
+#undef SET_CALLBACK
+
+
+ if(colstr!=0)
+ {
+ base->mcol=atoi(colstr);
+ if(base->mcol<10) base->mcol=80;
+ }
+ base->mrow=99999;
+
+/*
+ init_pair(tv,1, "blue", "white");
+ init_pair(tv,2, "green", "white");
+ init_pair(tv,3, "yellow", "white");
+ init_pair(tv,4, "white", "white");
+ init_pair(tv,5, "green", "white");
+ init_pair(tv,6, "cyan", "white");
+ init_pair(tv,7, "yellow", "white");
+ init_pair(tv,8, "red", "white");
+ init_pair(tv,9, "blue", "white");
+ */
+ return base;
+ }
+
+
+tview_t* text_tv_init(const char *fn, const char *fn_fa, const char *samples)
+ {
+ tview_t* tv=html_tv_init(fn,fn_fa,samples);
+ tv->my_drawaln=text_drawaln;
+ return tv;
+ }
+