void browse(int type, int nc, int nr, void *in) { WINDOW *pdlscr, *wmenu, *wscroll, *warray, *whlab, *wvlab, *wtmp; char s[CHBUF],echobuf[CHBUF],line[CHBUF]; chtype ch; int i,j,eps,ioff,joff,iecho; int ncols, nrows, mycols; extern int colwid, dcols, drows, width[]; pdlscr = initscr(); /* sets LINES, COLS (which aren't macro constants...) */ clear(); /* Clear the screen before we start drawing */ colwid = width[type]; ncols = (COLS-HLAB)/colwid; dcols = MIN(nc,ncols); mycols = dcols*colwid; nrows = LINES-3; drows = MIN(nr,nrows); cbreak(); noecho(); nonl(); intrflush(pdlscr,FALSE); keypad(pdlscr,TRUE); /* Menu bar */ wmenu = subwin(pdlscr,1,COLS,0,0); wvlab = subwin(pdlscr,1,mycols,1,HLAB); wscroll= subwin(pdlscr,drows,mycols+HLAB,2,0); warray = subwin(wscroll,drows,mycols,2,HLAB); whlab = subwin(wscroll,drows,HLAB,2,0); keypad(warray,TRUE); scrollok(pdlscr,TRUE); scrollok(wscroll,TRUE); wmenu = subwin(pdlscr,1,COLS,0,0); sprintf(s,"Perldl data browser: type %d, (%d,%d), type q to quit\n", type,nc,nr); mvwaddstr(wmenu,0,10,s); wrefresh(wmenu); for (i=0;i<dcols;i++) { update_vlab(wvlab,i,0); } wrefresh(wvlab); for (j=0;j<drows;j++) { update_hlab(whlab,j,0); } wrefresh(whlab); for (j=0;j<drows;j++) { update_row(warray,j,0,0,type,nc,in); } i = j = eps = 0; ioff = joff = 0; while (tolower(ch=mvwgetch(warray,j-joff,(i-ioff)*colwid+ MIN(eps,colwid-2))) != 'q') { /* #define ECHOCH */ #ifdef ECHOCH sprintf(echobuf,"%8o",ch); mvwaddstr(wmenu,0,iecho,echobuf); iecho = (iecho < 72) ? iecho+8 :0; wrefresh(wmenu); #endif switch (ch) { case KEY_LEFT: case KEY_RIGHT: case KEY_UP: case KEY_DOWN: case '\t': case '\015': if (eps) { line[eps] = '\0'; set_value(i,j,type,nc,in,line); } set_cell(warray,i,j,ioff,joff,type,nc,in); eps = 0; wrefresh(warray); break; case '\b': case KEY_DL: case 0177: if (eps) { eps--; mvwaddch(warray,j-joff,(i-ioff)*colwid+MIN(eps,colwid-2),' '); wrefresh(warray); } continue; default: if (!eps && ch >= 32 && ch <= 127) { clear_cell(warray,i-ioff,j-joff); wrefresh(warray); } mvwaddch(warray,j-joff,(i-ioff)*colwid+MIN(eps,colwid-2),ch|A_UNDERLINE); line[eps++]=ch; continue; } switch (ch) { case KEY_LEFT: i = (i<2)?0:i-1; if (i-ioff == -1) { ioff--; wtmp = newwin(1,mycols-colwid,1,HLAB); overwrite(wvlab,wtmp); mvwin(wtmp,1,HLAB+colwid); overwrite(wtmp,wvlab); delwin(wtmp); update_vlab(wvlab,0,ioff); wtmp = newwin(drows,mycols-colwid,2,HLAB); overwrite(warray,wtmp); mvwin(wtmp,2,HLAB+colwid); overwrite(wtmp,warray); delwin(wtmp); update_col(warray,0,ioff,joff,type,nc,in); wrefresh(warray); wrefresh(wvlab); } break; case KEY_RIGHT: case '\t': i = (i>nc-2)?nc-1:i+1; if (i-ioff == dcols) { ioff++; wtmp = newwin(1,mycols-colwid,1,HLAB+colwid); overwrite(wvlab,wtmp); mvwin(wtmp,1,HLAB); overwrite(wtmp,wvlab); delwin(wtmp); update_vlab(wvlab,dcols-1,ioff); wtmp = newwin(drows,mycols-colwid,2,HLAB+colwid); overwrite(warray,wtmp); mvwin(wtmp,2,HLAB); overwrite(wtmp,warray); delwin(wtmp); update_col(warray,dcols-1,ioff,joff,type,nc,in); wrefresh(warray); wrefresh(wvlab); } break; case KEY_UP: j = (j<2)?0:j-1; if (j-joff == -1) { joff--; wscrl(wscroll,-1); wrefresh(wscroll); update_hlab(whlab,0,joff); wrefresh(whlab); update_row(warray,0,ioff,joff,type,nc,in); wrefresh(warray); } break; case KEY_DOWN: case '\015': j = (j>nr-2)?nr-1:j+1; if (j-joff == drows) { joff++; wscrl(wscroll,1); wrefresh(wscroll); update_hlab(whlab,drows-1,joff); wrefresh(whlab); update_row(warray,drows-1,ioff,joff,type,nc,in); wrefresh(warray); } break; } } nl(); echo(); nocbreak(); endwin(); }
consensus_data * get_cns_from_align_tags( align_tags_t ** tag_seqs, unsigned n_tag_seqs, unsigned t_len, unsigned min_cov ) { seq_coor_t i, j; seq_coor_t t_pos = 0; unsigned int * coverage; unsigned int * local_nbase; consensus_data * consensus; //char * consensus; align_tag_t * c_tag; static msa_pos_t * msa_array = NULL; coverage = calloc( t_len, sizeof(unsigned int) ); local_nbase = calloc( t_len, sizeof(unsigned int) ); #ifndef STATIC_ALLOCATE msa_array = calloc(t_len, sizeof(msa_pos_t *)); for (i = 0; i < t_len; i++) { msa_array[i] = calloc(1, sizeof(msa_delta_group_t)); msa_array[i]->size = 8; allocate_delta_group(msa_array[i]); } #endif #ifdef STATIC_ALLOCATE if ( msa_array == NULL) { msa_array = get_msa_working_sapce( 100000 ); } assert(t_len < 100000); #endif // loop through every alignment //printf("XX %d\n", n_tag_seqs); for (i = 0; i < n_tag_seqs; i++) { // for each alignment position, insert the alignment tag to msa_array for (j = 0; j < tag_seqs[i]->len; j++) { c_tag = tag_seqs[i]->align_tags + j; unsigned int delta; delta = c_tag->delta; if (delta == 0) { t_pos = c_tag->t_pos; coverage[ t_pos ] ++; } // Assume t_pos was set on earlier iteration. // (Otherwise, use its initial value, which might be an error. ~cd) if (delta > msa_array[t_pos]->max_delta) { msa_array[t_pos]->max_delta = delta; if (msa_array[t_pos]->max_delta + 4 > msa_array[t_pos]->size ) { realloc_delta_group(msa_array[t_pos], msa_array[t_pos]->max_delta + 8); } } unsigned int base = -1; switch (c_tag->q_base) { case 'A': base = 0; break; case 'C': base = 1; break; case 'G': base = 2; break; case 'T': base = 3; break; case '-': base = 4; break; } // Note: On bad input, base may be -1. update_col( &(msa_array[t_pos]->delta[delta].base[base]), c_tag->p_t_pos, c_tag->p_delta, c_tag->p_q_base); local_nbase[ t_pos ] ++; } } // propogate score throught the alignment links, setup backtracking information align_tag_col_t * g_best_aln_col = 0; unsigned int g_best_ck = 0; seq_coor_t g_best_t_pos = 0; { int kk; int ck; // char base; int best_i; int best_j; int best_b; int best_ck = -1; double score; double best_score; double g_best_score; // char best_mark; align_tag_col_t * aln_col; g_best_score = -1; for (i = 0; i < t_len; i++) { //loop through every template base //printf("max delta: %d %d\n", i, msa_array[i]->max_delta); for (j = 0; j <= msa_array[i]->max_delta; j++) { // loop through every delta position for (kk = 0; kk < 5; kk++) { // loop through diff bases of the same delta posiiton /* switch (kk) { case 0: base = 'A'; break; case 1: base = 'C'; break; case 2: base = 'G'; break; case 3: base = 'T'; break; case 4: base = '-'; break; } */ aln_col = msa_array[i]->delta[j].base + kk; if (aln_col->count >= 0) { best_score = -1; best_i = -1; best_j = -1; best_b = -1; for (ck = 0; ck < aln_col->n_link; ck++) { // loop through differnt link to previous column int pi; int pj; int pkk; pi = aln_col->p_t_pos[ck]; pj = aln_col->p_delta[ck]; switch (aln_col->p_q_base[ck]) { case 'A': pkk = 0; break; case 'C': pkk = 1; break; case 'G': pkk = 2; break; case 'T': pkk = 3; break; case '-': pkk = 4; break; default: pkk = 4; } if (aln_col->p_t_pos[ck] == -1) { score = (double) aln_col->link_count[ck] - (double) coverage[i] * 0.5; } else { score = msa_array[pi]->delta[pj].base[pkk].score + (double) aln_col->link_count[ck] - (double) coverage[i] * 0.5; } // best_mark = ' '; if (score > best_score) { best_score = score; aln_col->best_p_t_pos = best_i = pi; aln_col->best_p_delta = best_j = pj; aln_col->best_p_q_base = best_b = pkk; best_ck = ck; // best_mark = '*'; } /* printf("X %d %d %d %c %d %d %d %c %d %lf %c\n", coverage[i], i, j, base, aln_col->count, aln_col->p_t_pos[ck], aln_col->p_delta[ck], aln_col->p_q_base[ck], aln_col->link_count[ck], score, best_mark); */ } aln_col->score = best_score; if (best_score > g_best_score) { g_best_score = best_score; g_best_aln_col = aln_col; g_best_ck = best_ck; g_best_t_pos = i; //printf("GB %d %d %d %d\n", i, j, ck, g_best_aln_col); } } } } } assert(g_best_score != -1); } // reconstruct the sequences unsigned int index; char bb = '$'; int ck; char * cns_str; int * eqv; double score0; consensus = calloc( 1, sizeof(consensus_data) ); consensus->sequence = calloc( t_len * 2 + 1, sizeof(char) ); consensus->eqv = calloc( t_len * 2 + 1, sizeof(unsigned int) ); cns_str = consensus->sequence; eqv = consensus->eqv; index = 0; ck = g_best_ck; i = g_best_t_pos; while (1) { if (coverage[i] > min_cov) { switch (ck) { case 0: bb = 'A'; break; case 1: bb = 'C'; break; case 2: bb = 'G'; break; case 3: bb = 'T'; break; case 4: bb = '-'; break; } } else { switch (ck) { case 0: bb = 'a'; break; case 1: bb = 'c'; break; case 2: bb = 'g'; break; case 3: bb = 't'; break; case 4: bb = '-'; break; } } // Note: On bad input, bb will keep previous value, possibly '$'. score0 = g_best_aln_col->score; i = g_best_aln_col->best_p_t_pos; if (i == -1 || index >= t_len * 2) break; j = g_best_aln_col->best_p_delta; ck = g_best_aln_col->best_p_q_base; g_best_aln_col = msa_array[i]->delta[j].base + ck; if (bb != '-') { cns_str[index] = bb; eqv[index] = (int) score0 - (int) g_best_aln_col->score; //printf("C %d %d %c %lf %d %d\n", i, index, bb, g_best_aln_col->score, coverage[i], eqv[index] ); index ++; } } // reverse the sequence for (i = 0; i < index/2; i++) { cns_str[i] = cns_str[i] ^ cns_str[index-i-1]; cns_str[index-i-1] = cns_str[i] ^ cns_str[index-i-1]; cns_str[i] = cns_str[i] ^ cns_str[index-i-1]; eqv[i] = eqv[i] ^ eqv[index-i-1]; eqv[index-i-1] = eqv[i] ^ eqv[index-i-1]; eqv[i] = eqv[i] ^ eqv[index-i-1]; } cns_str[index] = 0; //printf("%s\n", cns_str); #ifndef STATIC_ALLOCATE for (i = 0; i < t_len; i++) { free_delta_group(msa_array[i]); free(msa_array[i]); } free(msa_array); #endif #ifdef STATIC_ALLOCATE clean_msa_working_space(msa_array, t_len+1); #endif free(coverage); free(local_nbase); return consensus; }