mirror of
https://github.com/lh3/minimap2.git
synced 2026-09-15 13:07:55 +08:00
backup
This commit is contained in:
10
align.c
10
align.c
@@ -300,9 +300,8 @@ static void mm_update_extra(mm_reg1_t *r, const uint8_t *qseq, const uint8_t *ts
|
||||
if (is_eqx) mm_update_cigar_eqx(r, qseq, tseq); // NB: it has to be called here as changes to qseq and tseq are not returned
|
||||
}
|
||||
|
||||
static void mm_append_cigar(mm_reg1_t *r, uint32_t n_cigar, uint32_t *cigar) // TODO: this calls the libc realloc()
|
||||
void mm_enlarge_cigar(mm_reg1_t *r, uint32_t n_cigar) // TODO: this calls the libc realloc()
|
||||
{
|
||||
mm_extra_t *p;
|
||||
if (n_cigar == 0) return;
|
||||
if (r->p == 0) {
|
||||
uint32_t capacity = n_cigar + sizeof(mm_extra_t)/4;
|
||||
@@ -314,6 +313,13 @@ static void mm_append_cigar(mm_reg1_t *r, uint32_t n_cigar, uint32_t *cigar) //
|
||||
kroundup32(r->p->capacity);
|
||||
r->p = (mm_extra_t*)realloc(r->p, r->p->capacity * 4);
|
||||
}
|
||||
}
|
||||
|
||||
static void mm_append_cigar(mm_reg1_t *r, uint32_t n_cigar, const uint32_t *cigar)
|
||||
{
|
||||
mm_extra_t *p;
|
||||
if (n_cigar == 0) return;
|
||||
mm_enlarge_cigar(r, n_cigar);
|
||||
p = r->p;
|
||||
if (p->n_cigar > 0 && (p->cigar[p->n_cigar-1]&0xf) == (cigar[0]&0xf)) { // same CIGAR op at the boundary
|
||||
p->cigar[p->n_cigar-1] += cigar[0]>>4<<4;
|
||||
|
||||
167
hit.c
167
hit.c
@@ -464,3 +464,170 @@ void mm_set_mapq(void *km, int n_regs, mm_reg1_t *regs, int min_chain_sc, int ma
|
||||
}
|
||||
mm_set_inv_mapq(km, n_regs, regs);
|
||||
}
|
||||
|
||||
/******************************
|
||||
* Instructed split alignment *
|
||||
******************************/
|
||||
|
||||
#define MM_MIN_EXON_LEN 20
|
||||
|
||||
static int32_t mm_jump_check(void *km, const mm_idx_t *mi, int32_t qlen, const uint8_t *qseq0, const mm_reg1_t *r, int32_t ext, int32_t is_left) // TODO: check close N
|
||||
{
|
||||
int32_t clip, clen, e = !r->rev ^ !is_left; // 0 for left of the alignment; 1 for right
|
||||
uint32_t cigar;
|
||||
if (!r->p || r->p->n_cigar <= 0) return -1; // only working with CIGAR
|
||||
clip = e == 0? r->qs : qlen - r->qe;
|
||||
cigar = r->p->cigar[e == 0? 0 : r->p->n_cigar - 1];
|
||||
clen = (cigar&0xf) == MM_CIGAR_MATCH? cigar>>4 : 0;
|
||||
if (clen <= ext) return -1;
|
||||
if (is_left) {
|
||||
if (clip >= r->rs) return -1; // no space to jump
|
||||
} else {
|
||||
if (clip >= mi->seq[r->rid].len - r->re) return -1; // no space to jump
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint8_t *mm_jump_get_qseq_seq(void *km, int32_t qlen, const uint8_t *qseq0, const mm_reg1_t *r, int32_t is_left, int32_t ql0, uint8_t *qseq)
|
||||
{
|
||||
int32_t i, k;
|
||||
if (!r->rev) {
|
||||
if (is_left) memcpy(qseq, qseq0, ql0);
|
||||
else memcpy(qseq, &qseq0[qlen - ql0], ql0);
|
||||
} else {
|
||||
if (is_left)
|
||||
for (i = qlen - 1, k = 0; i >= qlen - ql0; --i)
|
||||
qseq[k++] = qseq0[i] >= 4? qseq0[i] : 3 - qseq0[i];
|
||||
else
|
||||
for (i = ql0 - 1, k = 0; i >= 0; --i)
|
||||
qseq[k++] = qseq0[i] >= 4? qseq0[i] : 3 - qseq0[i];
|
||||
}
|
||||
return qseq;
|
||||
}
|
||||
|
||||
static void mm_jump_split_left(void *km, const mm_idx_t *mi, const mm_mapopt_t *opt, int32_t qlen, const uint8_t *qseq0, mm_reg1_t *r, int32_t ts_strand)
|
||||
{
|
||||
uint8_t *tseq = 0, *qseq = 0;
|
||||
int32_t i, n, i0 = -1, m = 0, l;
|
||||
int32_t ext = 1 + (opt->b + opt->a - 1) / opt->a + 1;
|
||||
int32_t clip = !r->rev? r->qs : qlen - r->qe;
|
||||
int32_t extt = clip < ext? clip : ext;
|
||||
const mm_idx_jjump1_t *a;
|
||||
|
||||
if (mm_jump_check(km, mi, qlen, qseq0, r, ext + MM_MIN_EXON_LEN, 1) < 0) return;
|
||||
a = mm_idx_jump_get(mi, r->rid, r->rs - extt, r->rs + ext, &n);
|
||||
if (n == 0) return;
|
||||
|
||||
for (i = 0; i < n; ++i) { // traverse possible jumps
|
||||
const mm_idx_jjump1_t *ai = &a[i];
|
||||
int32_t tlen, tl1, j, mm1, mm2;
|
||||
assert(ai->off >= r->rs - extt && ai->off < r->rs + ext);
|
||||
if (ts_strand * ai->strand < 0) continue; // wrong strand
|
||||
if (ai->off2 >= ai->off) continue; // wrong direction
|
||||
if (ai->off2 < clip + ext) continue; // not long enough
|
||||
if (tseq == 0) {
|
||||
tseq = Kcalloc(km, uint8_t, (clip + ext) * 2); // tseq and qseq are allocated together
|
||||
qseq = tseq + clip + ext;
|
||||
mm_jump_get_qseq_seq(km, qlen, qseq0, r, 1, clip + ext, qseq);
|
||||
}
|
||||
tl1 = clip + (ai->off - r->rs);
|
||||
tlen = mm_idx_getseq2(mi, 0, r->rid, ai->off, r->rs + ext, &tseq[tl1]);
|
||||
assert(tlen == r->rs + ext - ai->off);
|
||||
tlen = mm_idx_getseq2(mi, 0, r->rid, ai->off2 - tl1, ai->off2, tseq);
|
||||
assert(tlen == tl1);
|
||||
for (j = 0, mm1 = 0; j < tl1; ++j)
|
||||
if (qseq[j] != tseq[j] || qseq[j] > 3 || tseq[j] > 3)
|
||||
++mm1;
|
||||
for (mm2 = 0; j < clip + ext; ++j)
|
||||
if (qseq[j] != tseq[j] || qseq[j] > 3 || tseq[j] > 3)
|
||||
++mm2;
|
||||
if (mm1 == 0 && mm2 == 1)
|
||||
i0 = i, ++m; // i0 points to the rightmost i
|
||||
}
|
||||
kfree(km, tseq);
|
||||
|
||||
l = m > 0? a[i0].off - r->rs : 0; // may be negative
|
||||
if (m == 1 && clip + l >= opt->jump_min_alen) { // add one more exon
|
||||
mm_enlarge_cigar(r, 2);
|
||||
memmove(r->p->cigar + 2, r->p->cigar, r->p->n_cigar * 4);
|
||||
r->p->cigar[0] = (clip + l) << 4 | MM_CIGAR_MATCH;
|
||||
r->p->cigar[1] = (a[i0].off - a[i0].off2) << 4 | MM_CIGAR_N_SKIP;
|
||||
r->p->cigar[2] = ((r->p->cigar[2]>>4) - l) << 4 | MM_CIGAR_MATCH;
|
||||
r->p->n_cigar += 2;
|
||||
r->rs = a[i0].off2 - (clip + l);
|
||||
if (!r->rev) r->qs = 0;
|
||||
else r->qe = qlen;
|
||||
} else if (m > 0 && a[i0].off > r->rs) { // trim by l; l is always positive
|
||||
r->p->cigar[0] -= l << 4 | MM_CIGAR_MATCH;
|
||||
r->rs += l;
|
||||
if (!r->rev) r->qs += l;
|
||||
else r->qe -= l;
|
||||
}
|
||||
}
|
||||
|
||||
static void mm_jump_split_right(void *km, const mm_idx_t *mi, const mm_mapopt_t *opt, int32_t qlen, const uint8_t *qseq0, mm_reg1_t *r, int32_t ts_strand)
|
||||
{
|
||||
uint8_t *tseq = 0, *qseq = 0;
|
||||
int32_t i, n, i0 = -1, m = 0, l;
|
||||
int32_t ext = 1 + (opt->b + opt->a - 1) / opt->a + 1;
|
||||
int32_t clip = !r->rev? qlen - r->qe : r->qs;
|
||||
int32_t extt = clip < ext? clip : ext;
|
||||
const mm_idx_jjump1_t *a;
|
||||
|
||||
if (mm_jump_check(km, mi, qlen, qseq0, r, ext + MM_MIN_EXON_LEN, 1) < 0) return;
|
||||
a = mm_idx_jump_get(mi, r->rid, r->re - ext, r->re + extt, &n);
|
||||
if (n == 0) return;
|
||||
|
||||
for (i = 0; i < n; ++i) { // traverse possible jumps
|
||||
const mm_idx_jjump1_t *ai = &a[i];
|
||||
int32_t tlen, tl1, j, mm1, mm2;
|
||||
assert(ai->off >= r->rs - extt && ai->off < r->rs + ext);
|
||||
if (ts_strand * ai->strand < 0) continue; // wrong strand
|
||||
if (ai->off2 <= ai->off) continue; // wrong direction
|
||||
if (ai->off2 + clip + ext > mi->seq[r->rid].len) continue; // not long enough
|
||||
if (tseq == 0) {
|
||||
tseq = Kcalloc(km, uint8_t, (clip + ext) * 2); // tseq and qseq are allocated together
|
||||
qseq = tseq + clip + ext;
|
||||
mm_jump_get_qseq_seq(km, qlen, qseq0, r, 0, clip + ext, qseq);
|
||||
}
|
||||
tl1 = clip + (r->re - ai->off);
|
||||
tlen = mm_idx_getseq2(mi, 0, r->rid, r->re - ext, ai->off, tseq);
|
||||
assert(tlen == ai->off - (r->re - ext));
|
||||
tlen = mm_idx_getseq2(mi, 0, r->rid, ai->off2, ai->off2 + tl1, &tseq[clip + ext - tl1]);
|
||||
assert(tlen == tl1);
|
||||
for (j = 0, mm2 = 0; j < clip + ext - tl1; ++j)
|
||||
if (qseq[j] != tseq[j] || qseq[j] > 3 || tseq[j] > 3)
|
||||
++mm2;
|
||||
for (mm1 = 0; j < clip + ext; ++j)
|
||||
if (qseq[j] != tseq[j] || qseq[j] > 3 || tseq[j] > 3)
|
||||
++mm1;
|
||||
if (mm1 == 0 && mm2 == 1)
|
||||
i0 = i0 >= 0? i0 : i, ++m; // i0 points to the leftmost i
|
||||
}
|
||||
kfree(km, tseq);
|
||||
|
||||
l = m > 0? r->re - a[i0].off : 0; // may be negative
|
||||
if (m == 1 && clip + l >= opt->jump_min_alen) { // add one more exon
|
||||
mm_enlarge_cigar(r, 2);
|
||||
memmove(r->p->cigar + 2, r->p->cigar, r->p->n_cigar * 4);
|
||||
r->p->cigar[r->p->n_cigar - 1] = ((r->p->cigar[r->p->n_cigar - 1]>>4) - l) << 4 | MM_CIGAR_MATCH;
|
||||
r->p->cigar[r->p->n_cigar] = (a[i0].off2 - a[i0].off) << 4 | MM_CIGAR_N_SKIP;
|
||||
r->p->cigar[r->p->n_cigar + 1] = (clip + l) << 4 | MM_CIGAR_MATCH;
|
||||
r->p->n_cigar += 2;
|
||||
r->re = a[i0].off2 + (clip + l);
|
||||
if (!r->rev) r->qe = qlen;
|
||||
else r->qs = 0;
|
||||
} else if (m > 0 && r->re > a[i0].off) { // trim by l; l is always positive
|
||||
r->p->cigar[r->p->n_cigar - 1] -= l << 4 | MM_CIGAR_MATCH;
|
||||
r->re -= l;
|
||||
if (!r->rev) r->qe -= l;
|
||||
else r->qs += l;
|
||||
}
|
||||
}
|
||||
|
||||
void mm_jump_split(void *km, const mm_idx_t *mi, const mm_mapopt_t *opt, int32_t qlen, const uint8_t *qseq, mm_reg1_t *r, int32_t ts_strand)
|
||||
{
|
||||
assert((opt->flag & MM_F_EQX) == 0);
|
||||
mm_jump_split_left(km, mi, opt, qlen, qseq, r, ts_strand);
|
||||
mm_jump_split_right(km, mi, opt, qlen, qseq, r, ts_strand);
|
||||
}
|
||||
|
||||
29
index.c
29
index.c
@@ -855,6 +855,35 @@ int mm_idx_bed_junc(const mm_idx_t *mi, int32_t ctg, int32_t st, int32_t en, uin
|
||||
return left;
|
||||
}
|
||||
|
||||
static int32_t mm_idx_jump_get_core(int32_t n, const mm_idx_jjump1_t *a, int32_t x) // similar to mm_idx_find_intv()
|
||||
{
|
||||
int32_t s = 0, e = n;
|
||||
if (n == 0) return -1;
|
||||
if (x < a[0].off) return -1;
|
||||
while (s < e) {
|
||||
int32_t mid = s + (e - s) / 2;
|
||||
if (x >= a[mid].off && (mid + 1 >= n || x < a[mid+1].off)) return mid;
|
||||
else if (x < a[mid].off) e = mid;
|
||||
else s = mid + 1;
|
||||
}
|
||||
assert(0);
|
||||
}
|
||||
|
||||
const mm_idx_jjump1_t *mm_idx_jump_get(const mm_idx_t *db, int32_t cid, int32_t st, int32_t en, int32_t *n)
|
||||
{
|
||||
mm_idx_jjump_t *s;
|
||||
int32_t l, r;
|
||||
*n = 0;
|
||||
if (cid >= db->n_seq || cid < 0 || db->J == 0) return 0;
|
||||
if (en < 0 || en > db->seq[cid].len) en = db->seq[cid].len;
|
||||
s = &db->J[cid];
|
||||
if (s->n == 0) return 0;
|
||||
l = mm_idx_jump_get_core(s->n, s->a, st);
|
||||
r = mm_idx_jump_get_core(s->n, s->a, en);
|
||||
*n = r - l;
|
||||
return &s->a[l + 1];
|
||||
}
|
||||
|
||||
/****************
|
||||
* splice score *
|
||||
****************/
|
||||
|
||||
@@ -174,6 +174,8 @@ typedef struct {
|
||||
|
||||
int pe_ori, pe_bonus;
|
||||
|
||||
int32_t jump_min_alen;
|
||||
|
||||
float mid_occ_frac; // only used by mm_mapopt_update(); see below
|
||||
float q_occ_frac;
|
||||
int32_t min_mid_occ, max_mid_occ;
|
||||
|
||||
6
mmpriv.h
6
mmpriv.h
@@ -83,8 +83,8 @@ void mm_idxopt_init(mm_idxopt_t *opt);
|
||||
const uint64_t *mm_idx_get(const mm_idx_t *mi, uint64_t minier, int *n);
|
||||
int32_t mm_idx_cal_max_occ(const mm_idx_t *mi, float f);
|
||||
int mm_idx_getseq2(const mm_idx_t *mi, int is_rev, uint32_t rid, uint32_t st, uint32_t en, uint8_t *seq);
|
||||
mm_reg1_t *mm_align_skeleton(void *km, const mm_mapopt_t *opt, const mm_idx_t *mi, int qlen, const char *qstr, int *n_regs_, mm_reg1_t *regs, mm128_t *a);
|
||||
mm_reg1_t *mm_gen_regs(void *km, uint32_t hash, int qlen, int n_u, uint64_t *u, mm128_t *a, int is_qstrand);
|
||||
const mm_idx_jjump1_t *mm_idx_jump_get(const mm_idx_t *db, int32_t cid, int32_t st, int32_t en, int32_t *n);
|
||||
|
||||
mm128_t *mg_lchain_dp(int max_dist_x, int max_dist_y, int bw, int max_skip, int max_iter, int min_cnt, int min_sc, float chn_pen_gap, float chn_pen_skip,
|
||||
int is_cdna, int n_segs, int64_t n, mm128_t *a, int *n_u_, uint64_t **_u, void *km);
|
||||
@@ -104,6 +104,10 @@ void mm_filter_regs(const mm_mapopt_t *opt, int qlen, int *n_regs, mm_reg1_t *re
|
||||
void mm_hit_sort(void *km, int *n_regs, mm_reg1_t *r, float alt_diff_frac);
|
||||
void mm_set_mapq(void *km, int n_regs, mm_reg1_t *regs, int min_chain_sc, int match_sc, int rep_len, int is_sr);
|
||||
void mm_update_dp_max(int qlen, int n_regs, mm_reg1_t *regs, float frac, int a, int b);
|
||||
void mm_jump_split(void *km, const mm_idx_t *mi, const mm_mapopt_t *opt, int32_t qlen, const uint8_t *qseq, mm_reg1_t *r, int32_t ts_strand);
|
||||
|
||||
mm_reg1_t *mm_align_skeleton(void *km, const mm_mapopt_t *opt, const mm_idx_t *mi, int qlen, const char *qstr, int *n_regs_, mm_reg1_t *regs, mm128_t *a);
|
||||
void mm_enlarge_cigar(mm_reg1_t *r, uint32_t n_cigar);
|
||||
|
||||
void mm_est_err(const mm_idx_t *mi, int qlen, int n_regs, mm_reg1_t *regs, const mm128_t *a, int32_t n, const uint64_t *mini_pos);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user