int bns_intv2rid(const bntseq_t *bns, int64_t rb, int64_t re) { int is_rev, rid_b, rid_e; if (rb < bns->l_pac && re > bns->l_pac) return -2; rid_b = bns_pos2rid(bns, bns_depos(bns, rb, &is_rev)); rid_e = bns_pos2rid(bns, bns_depos(bns, re, &is_rev) - 1); return rid_b == rid_e? rid_b : -1; }
int bns_intv2rid(const bntseq_t *bns, int64_t rb, int64_t re) { int is_rev, rid_b, rid_e; if (rb < bns->l_pac && re > bns->l_pac) return -2; assert(rb <= re); rid_b = bns_pos2rid(bns, bns_depos(bns, rb, &is_rev)); rid_e = rb < re? bns_pos2rid(bns, bns_depos(bns, re - 1, &is_rev)) : rid_b; return rid_b == rid_e? rid_b : -1; }
uint8_t *bns_fetch_seq(const bntseq_t *bns, const uint8_t *pac, int64_t *beg, int64_t mid, int64_t *end, int *rid) { int64_t far_beg, far_end, len; int is_rev; uint8_t *seq; if (*end < *beg) *end ^= *beg, *beg ^= *end, *end ^= *beg; // if end is smaller, swap assert(*beg <= mid && mid < *end); *rid = bns_pos2rid(bns, bns_depos(bns, mid, &is_rev)); far_beg = bns->anns[*rid].offset; far_end = far_beg + bns->anns[*rid].len; if (is_rev) { // flip to the reverse strand int64_t tmp = far_beg; far_beg = (bns->l_pac<<1) - far_end; far_end = (bns->l_pac<<1) - tmp; } *beg = *beg > far_beg? *beg : far_beg; *end = *end < far_end? *end : far_end; seq = bns_get_seq(bns->l_pac, pac, *beg, *end, &len); if (seq == 0 || *end - *beg != len) { fprintf(stderr, "[E::%s] begin=%ld, mid=%ld, end=%ld, len=%ld, seq=%p, rid=%d, far_beg=%ld, far_end=%ld\n", __func__, (long)*beg, (long)mid, (long)*end, (long)len, seq, *rid, (long)far_beg, (long)far_end); } assert(seq && *end - *beg == len); // assertion failure should never happen return seq; }
int bns_cnt_ambi(const bntseq_t *bns, int64_t pos_f, int len, int *ref_id) { int left, mid, right, nn; if (ref_id) *ref_id = bns_pos2rid(bns, pos_f); left = 0; right = bns->n_holes; nn = 0; while (left < right) { mid = (left + right) >> 1; if (pos_f >= bns->ambs[mid].offset + bns->ambs[mid].len) left = mid + 1; else if (pos_f + len <= bns->ambs[mid].offset) right = mid; else { // overlap if (pos_f >= bns->ambs[mid].offset) { nn += bns->ambs[mid].offset + bns->ambs[mid].len < pos_f + len? bns->ambs[mid].offset + bns->ambs[mid].len - pos_f : len; } else { nn += bns->ambs[mid].offset + bns->ambs[mid].len < pos_f + len? bns->ambs[mid].len : len - (bns->ambs[mid].offset - pos_f); } break; } } return nn; }
void mem_reg2ovlp(const mem_opt_t *opt, const bntseq_t *bns, const uint8_t *pac, bseq1_t *s, mem_alnreg_v *a) { int i; kstring_t str = {0,0,0}; for (i = 0; i < a->n; ++i) { const mem_alnreg_t *p = &a->a[i]; int is_rev, rid, qb = p->qb, qe = p->qe; int64_t pos, rb = p->rb, re = p->re; pos = bns_depos(bns, rb < bns->l_pac? rb : re - 1, &is_rev); rid = bns_pos2rid(bns, pos); assert(rid == p->rid); pos -= bns->anns[rid].offset; kputs(s->name, &str); kputc('\t', &str); kputw(s->l_seq, &str); kputc('\t', &str); if (is_rev) qb ^= qe, qe ^= qb, qb ^= qe; // swap kputw(qb, &str); kputc('\t', &str); kputw(qe, &str); kputc('\t', &str); kputs(bns->anns[rid].name, &str); kputc('\t', &str); kputw(bns->anns[rid].len, &str); kputc('\t', &str); kputw(pos, &str); kputc('\t', &str); kputw(pos + (re - rb), &str); kputc('\t', &str); ksprintf(&str, "%.3f", (double)p->truesc / opt->a / (qe - qb > re - rb? qe - qb : re - rb)); kputc('\n', &str); } s->sam = str.s; }