static void flush_buffer(args_t *args, int n) { int i, j; for (i=0; i<n; i++) { int k = rbuf_shift(&args->rbuf); bcf1_t *rec = args->rbuf_lines[k]; int pass = 1; if ( !args->soft_filter ) { for (j=0; j<rec->d.n_flt; j++) { if ( args->indel_gap && rec->d.flt[j]==args->IndelGap_id ) { pass = 0; break; } if ( args->snp_gap && rec->d.flt[j]==args->SnpGap_id ) { pass = 0; break; } } } if ( pass ) bcf_write1(args->out_fh, args->hdr, rec); } }
bcf1_t *vcfbuf_flush(vcfbuf_t *buf, int flush_all) { int i,j; if ( buf->rbuf.n==0 ) return NULL; if ( flush_all ) goto ret; i = rbuf_kth(&buf->rbuf, 0); // first j = rbuf_last(&buf->rbuf); // last if ( buf->vcf[i].rec->rid != buf->vcf[j].rec->rid ) goto ret; if ( buf->overlap.active ) { int ret = _overlap_can_flush(buf, flush_all); //printf("can_flush: %d %d - %d\n", ret, buf->vcf[i].rec->pos+1, buf->vcf[j].rec->pos+1); if ( ret ) goto ret; } //if ( buf->overlap.active && _overlap_can_flush(buf, flush_all) ) goto ret; if ( buf->win > 0 ) { if ( buf->rbuf.n <= buf->win ) return NULL; goto ret; } else if ( buf->win < 0 ) { if ( buf->vcf[i].rec->pos - buf->vcf[j].rec->pos > buf->win ) return NULL; } else return NULL; ret: if ( buf->prune.max_sites && buf->prune.max_sites < buf->rbuf.n ) _prune_sites(buf, flush_all); i = rbuf_shift(&buf->rbuf); return buf->vcf[i].rec; }
static void consensus(args_t *args) { htsFile *fasta = hts_open(args->ref_fname, "rb"); if ( !fasta ) error("Error reading %s\n", args->ref_fname); kstring_t str = {0,0,0}; while ( hts_getline(fasta, KS_SEP_LINE, &str) > 0 ) { if ( str.s[0]=='>' ) { // new sequence encountered, apply all chached variants while ( args->vcf_rbuf.n ) { if (args->chain) { print_chain(args); destroy_chain(args); } bcf1_t *rec = args->vcf_buf[args->vcf_rbuf.f]; if ( rec->rid!=args->rid || ( args->fa_end_pos && rec->pos > args->fa_end_pos ) ) break; int i = rbuf_shift(&args->vcf_rbuf); apply_variant(args, args->vcf_buf[i]); } flush_fa_buffer(args, 0); init_region(args, str.s+1); continue; } args->fa_length += str.l; args->fa_src_pos += str.l; // determine if uppercase or lowercase is used in this fasta file if ( args->fa_case==-1 ) args->fa_case = toupper(str.s[0])==str.s[0] ? 1 : 0; if ( args->mask && args->rid>=0) mask_region(args, str.s, str.l); kputs(str.s, &args->fa_buf); bcf1_t **rec_ptr = NULL; while ( args->rid>=0 && (rec_ptr = next_vcf_line(args)) ) { bcf1_t *rec = *rec_ptr; // still the same chr and the same region? if not, fasta buf can be flushed if ( rec->rid!=args->rid || ( args->fa_end_pos && rec->pos > args->fa_end_pos ) ) { // save the vcf record until next time and flush unread_vcf_line(args, rec_ptr); rec_ptr = NULL; break; } // is the vcf record well beyond cached fasta buffer? if yes, the buf can be flushed if ( args->fa_ori_pos + args->fa_buf.l - args->fa_mod_off <= rec->pos ) { unread_vcf_line(args, rec_ptr); rec_ptr = NULL; break; } // is the cached fasta buffer full enough? if not, read more fasta, no flushing if ( args->fa_ori_pos + args->fa_buf.l - args->fa_mod_off < rec->pos + rec->rlen ) { unread_vcf_line(args, rec_ptr); break; } apply_variant(args, rec); } if ( !rec_ptr ) flush_fa_buffer(args, 60); } if (args->chain) { print_chain(args); destroy_chain(args); } flush_fa_buffer(args, 0); hts_close(fasta); free(str.s); }