int bam_plbuf_push(const bam1_t *b, bam_plbuf_t *buf) { int ret, n_plp, tid, pos; const bam_pileup1_t *plp; ret = bam_plp_push(buf->iter, b); if (ret < 0) return ret; while ((plp = bam_plp_next(buf->iter, &tid, &pos, &n_plp)) != 0) buf->func(tid, pos, n_plp, plp, buf->data); return 0; }
const bam_pileup1_t *bam_plp_auto(bam_plp_t iter, int *_tid, int *_pos, int *_n_plp) { const bam_pileup1_t *plp; if (iter->func == 0 || iter->error) { *_n_plp = -1; return 0; } if ((plp = bam_plp_next(iter, _tid, _pos, _n_plp)) != 0) return plp; else { // no pileup line can be obtained; read alignments *_n_plp = 0; if (iter->is_eof) return 0; while (iter->func(iter->data, iter->b) >= 0) { if (bam_plp_push(iter, iter->b) < 0) { *_n_plp = -1; return 0; } if ((plp = bam_plp_next(iter, _tid, _pos, _n_plp)) != 0) return plp; // otherwise no pileup line can be returned; read the next alignment. } bam_plp_push(iter, 0); if ((plp = bam_plp_next(iter, _tid, _pos, _n_plp)) != 0) return plp; return 0; } }
loci_stats *bam_access_get_position_base_counts(char *chr, int posn){ char *region = NULL; hts_itr_t *iter = NULL; bam1_t* b = NULL; bam_plp_t buf; loci_stats *stats = malloc(sizeof(loci_stats *)); check_mem(stats); stats->base_counts = malloc(sizeof(int) * 4); check_mem(stats->base_counts); stats->base_counts[0] = 0; stats->base_counts[1] = 0; stats->base_counts[2] = 0; stats->base_counts[3] = 0; fholder->stats = stats; region = malloc((sizeof(char *) * (strlen(chr)+1))+sizeof(":")+sizeof("-")+(sizeof(char)*((no_of_digits(posn)*2)+1))); sprintf(region,"%s:%d-%d",chr,posn,posn); fholder->beg = posn; fholder->end = posn; // initialize pileup buf = bam_plp_init(pileup_func, (void *)fholder); bam_plp_set_maxcnt(buf,maxitercnt); /* sam_fetch(fholder->in, fholder->idx, ref, fholder->beg, fholder->end, buf, fetch_algo_func); */ //Replace fetch with iterator for htslib compatibility. b = bam_init1(); iter = sam_itr_querys(fholder->idx, fholder->head, region); int result; int count = 0; while ((result = sam_itr_next(fholder->in, iter, b)) >= 0) { if(b->core.qual < min_map_qual || (b->core.flag & BAM_FUNMAP) || !(b->core.flag & BAM_FPROPER_PAIR) || (b->core.flag & BAM_FMUNMAP)//Proper pair and mate unmapped || (b->core.flag & BAM_FDUP)//1024 is PCR/optical duplicate || (b->core.flag & BAM_FSECONDARY) || (b->core.flag & BAM_FQCFAIL)//Secondary alignment, quality fail || (b->core.flag & BAM_FSUPPLEMENTARY) ) continue; count++; bam_plp_push(buf, b); } sam_itr_destroy(iter); bam_plp_push(buf, 0); int tid, pos, n_plp = -1; const bam_pileup1_t *pil; while ( (pil=bam_plp_next(buf, &tid, &pos, &n_plp)) > 0) { if((pos+1) != posn) continue; int i=0; for(i=0;i<n_plp;i++){ const bam_pileup1_t *p = pil + i; int qual = bam_get_qual(p->b)[p->qpos]; uint8_t c = bam_seqi(bam_get_seq(p->b), p->qpos); if(!(p->is_del) && qual >= min_base_qual && p->b->core.qual >= min_map_qual){ //&& (c == 1 /*A*/|| c == 2 /*C*/|| c == 4 /*G*/|| c == 8 /*T*/)){ //Now we add a new read pos struct to the list since the read is valid. //char cbase = toupper(bam_nt16_rev_table[c]); switch(c){ case 1: fholder->stats->base_counts[0]++; break; case 2: fholder->stats->base_counts[1]++; break; case 4: fholder->stats->base_counts[2]++; break; case 8: fholder->stats->base_counts[3]++; break; default: break; }; // End of args switch statement */ } } } //End of iteration through pileup //bam_plp_push(buf, 0); // finalize pileup bam_plp_destroy(buf); free(region); return fholder->stats; error: //if(region) free(region); if(fholder->stats){ if(fholder->stats->base_counts) free(fholder->stats->base_counts); free(fholder->stats); } if(iter) sam_itr_destroy(iter); if(b) bam_destroy1(b); if(region) free(region); return NULL; }