Compare commits

..
24 Commits
Author SHA1 Message Date
Heng Li 59f23f7579 Release minimap2-2.14 (r883) 2018-11-06 00:03:16 -05:00
Heng Li 5e55e397e9 r882: guard against -E0 (#263) 2018-11-05 23:36:12 -05:00
Heng Li 88c421e8de r881: a recent change reduces sr accuracy 2018-11-05 22:03:59 -05:00
Heng Li 3db5bfe6e5 r880: fixed false wrong FASTA/Q alert 2018-11-05 20:52:07 -05:00
Heng Li 83dfdd5f50 draft release note 2018-11-05 20:07:57 -05:00
Heng Li 8a2b1cd4c9 updated mappy for extra option max_sw_mat 2018-11-05 19:28:44 -05:00
Heng Li 1ede8ca170 r877: renamed cap-sw-mat to cap-sw-mem 2018-11-05 11:46:38 -05:00
Heng Li 13981404e2 r876: skip DP if taking too much RAM (#259) 2018-11-05 11:43:10 -05:00
Heng Li fd64dd26f6 r875: warn given incorrect FASTA/Q
resolves #252
resolves #255
2018-11-05 10:02:44 -05:00
Heng Li 24df95e4b8 r874: don't call x86_simd() so often
This takes a few percent of time in profiler.
2018-11-05 09:20:35 -05:00
Heng Li a8ee48c2ce r873: comforming to C99/C11; resolves #261 2018-11-05 08:25:07 -05:00
Heng Li 09e089c3dc r872: choose the longest isoform 2018-11-04 23:48:50 -05:00
Heng Li e46cbb7d84 r871: print erroneous genes 2018-11-04 20:37:06 -05:00
Heng Li 57ec73ec6c r870: separate <50% and <10% 2018-11-04 19:31:25 -05:00
Heng Li 9e27575387 r869: classify incomplete genes 2018-11-04 19:21:55 -05:00
Heng Li b4ad8d8bf0 added asmgene
improvements coming; not made public yet
2018-11-04 17:24:05 -05:00
Heng Li e315b9fada hidden options to control bp calculation 2018-11-04 16:36:04 -05:00
Heng Li 42baf287a4 r866: fixed a typo; resolves #262 2018-10-30 09:11:55 -04:00
Heng Li 2ceba22a7a fixed a typo in manpage 2018-10-28 11:51:02 -04:00
Heng Li 9ed56b4a25 r860: MD/cs not working with --eqx 2018-10-26 23:23:53 -04:00
Heng Li ecb6c5c36c Document --no-pairing (#256) 2018-10-23 10:00:21 -04:00
Heng Li 377c7099a8 r858: fixed a bug; resolves #254 2018-10-22 22:47:11 -04:00
Heng Li 51e2abfa60 clarify that minimap2 may miss small exons 2018-10-22 11:16:16 -04:00
Heng Li 7b0a49732e r856: wrongly reported for an unrecognized option
Resolved #250
2018-10-19 20:07:14 -04:00
23 changed files with 315 additions and 316 deletions
+26
View File
@@ -1,3 +1,29 @@
Release 2.14-r883 (5 November 2018)
-----------------------------------
Notable changes:
* Fixed two minor bugs caused by typos (#254 and #266).
* Fixed a bug that made minimap2 abort when --eqx was used together with --MD
or --cs (#257).
* Added --cap-sw-mem to cap the size of DP matrices (#259). Base alignment may
take a lot of memory in the splicing mode. This may lead to issues when we
run minimap2 on a cluster with a hard memory limit. The new option avoids
unlimited memory usage at the cost of missing a few long introns.
* Conforming to C99 and C11 when possible (#261).
* Warn about malformatted FASTA or FASTQ (#252 and #255).
This release occasionally produces base alignments different from v2.13. The
overall alignment accuracy remain similar.
(2.14: 5 November 2018, r883)
Release 2.13-r850 (11 October 2018) Release 2.13-r850 (11 October 2018)
----------------------------------- -----------------------------------
+4 -2
View File
@@ -71,8 +71,8 @@ Detailed evaluations are available from the [minimap2 paper][doi] or the
Minimap2 is optimized for x86-64 CPUs. You can acquire precompiled binaries from Minimap2 is optimized for x86-64 CPUs. You can acquire precompiled binaries from
the [release page][release] with: the [release page][release] with:
```sh ```sh
curl -L https://github.com/lh3/minimap2/releases/download/v2.13/minimap2-2.13_x64-linux.tar.bz2 | tar -jxvf - curl -L https://github.com/lh3/minimap2/releases/download/v2.14/minimap2-2.14_x64-linux.tar.bz2 | tar -jxvf -
./minimap2-2.13_x64-linux/minimap2 ./minimap2-2.14_x64-linux/minimap2
``` ```
If you want to compile from the source, you need to have a C compiler, GNU make If you want to compile from the source, you need to have a C compiler, GNU make
and zlib development files installed. Then type `make` in the source code and zlib development files installed. Then type `make` in the source code
@@ -355,6 +355,8 @@ mappy` or [from BioConda][mappyconda] via `conda install -c bioconda mappy`.
billion bases or longer (2,147,483,647 to be exact). The total length of all billion bases or longer (2,147,483,647 to be exact). The total length of all
sequences can well exceed this threshold. sequences can well exceed this threshold.
* Minimap2 often misses small exons.
[paf]: https://github.com/lh3/miniasm/blob/master/PAF.md [paf]: https://github.com/lh3/miniasm/blob/master/PAF.md
+22 -27
View File
@@ -88,14 +88,13 @@ static int mm_test_zdrop(void *km, const mm_mapopt_t *opt, const uint8_t *qseq,
return max_zdrop > opt->zdrop? 1 : 0; return max_zdrop > opt->zdrop? 1 : 0;
} }
static void mm_fix_cigar(mm_reg1_t *r, const uint8_t *qseq, const uint8_t *tseq, int *qshift, int *tshift, int left_aln) static void mm_fix_cigar(mm_reg1_t *r, const uint8_t *qseq, const uint8_t *tseq, int *qshift, int *tshift)
{ {
mm_extra_t *p = r->p; mm_extra_t *p = r->p;
int32_t toff = 0, qoff = 0, to_shrink = 0; int32_t toff = 0, qoff = 0, to_shrink = 0;
uint32_t k; uint32_t k;
*qshift = *tshift = 0; *qshift = *tshift = 0;
if (p->n_cigar <= 1) return; if (p->n_cigar <= 1) return;
if (!left_aln) goto end_left_aln;
for (k = 0; k < p->n_cigar; ++k) { // indel left alignment for (k = 0; k < p->n_cigar; ++k) { // indel left alignment
uint32_t op = p->cigar[k]&0xf, len = p->cigar[k]>>4; uint32_t op = p->cigar[k]&0xf, len = p->cigar[k]>>4;
if (len == 0) to_shrink = 1; if (len == 0) to_shrink = 1;
@@ -124,7 +123,6 @@ static void mm_fix_cigar(mm_reg1_t *r, const uint8_t *qseq, const uint8_t *tseq,
} }
} }
assert(qoff == r->qe - r->qs && toff == r->re - r->rs); assert(qoff == r->qe - r->qs && toff == r->re - r->rs);
end_left_aln:
if (to_shrink) { // squeeze out zero-length operations if (to_shrink) { // squeeze out zero-length operations
int32_t l = 0; int32_t l = 0;
for (k = 0; k < p->n_cigar; ++k) // squeeze out zero-length operations for (k = 0; k < p->n_cigar; ++k) // squeeze out zero-length operations
@@ -149,13 +147,13 @@ end_left_aln:
} }
} }
static void mm_update_extra(mm_reg1_t *r, const uint8_t *qseq, const uint8_t *tseq, const int8_t *mat, int8_t q, int8_t e, int left_aln) static void mm_update_extra(mm_reg1_t *r, const uint8_t *qseq, const uint8_t *tseq, const int8_t *mat, int8_t q, int8_t e)
{ {
uint32_t k, l; uint32_t k, l;
int32_t s = 0, max = 0, qshift, tshift, toff = 0, qoff = 0; int32_t s = 0, max = 0, qshift, tshift, toff = 0, qoff = 0;
mm_extra_t *p = r->p; mm_extra_t *p = r->p;
if (p == 0) return; if (p == 0) return;
mm_fix_cigar(r, qseq, tseq, &qshift, &tshift, left_aln); mm_fix_cigar(r, qseq, tseq, &qshift, &tshift);
qseq += qshift, tseq += tshift; // qseq and tseq may be shifted due to the removal of leading I/D qseq += qshift, tseq += tshift; // qseq and tseq may be shifted due to the removal of leading I/D
r->blen = r->mlen = 0; r->blen = r->mlen = 0;
for (k = 0; k < p->n_cigar; ++k) { for (k = 0; k < p->n_cigar; ++k) {
@@ -292,8 +290,7 @@ static void mm_update_cigar_eqx(mm_reg1_t *r, const uint8_t *qseq, const uint8_t
r->p = p; r->p = p;
} }
static void mm_align_pair(void *km, const mm_mapopt_t *opt, int qlen, const uint8_t *qseq, int tlen, const uint8_t *tseq, const int8_t *ob, const int8_t *mat, static void mm_align_pair(void *km, const mm_mapopt_t *opt, int qlen, const uint8_t *qseq, int tlen, const uint8_t *tseq, const int8_t *mat, int w, int end_bonus, int zdrop, int flag, ksw_extz_t *ez)
int w, int end_bonus, int zdrop, int flag, ksw_extz_t *ez)
{ {
if (mm_dbg_flag & MM_DBG_PRINT_ALN_SEQ) { if (mm_dbg_flag & MM_DBG_PRINT_ALN_SEQ) {
int i; int i;
@@ -303,12 +300,15 @@ static void mm_align_pair(void *km, const mm_mapopt_t *opt, int qlen, const uint
for (i = 0; i < qlen; ++i) fputc("ACGTN"[qseq[i]], stderr); for (i = 0; i < qlen; ++i) fputc("ACGTN"[qseq[i]], stderr);
fputc('\n', stderr); fputc('\n', stderr);
} }
if (opt->flag & MM_F_SPLICE) if (opt->max_sw_mat > 0 && (int64_t)tlen * qlen > opt->max_sw_mat) {
ksw_reset_extz(ez);
ez->zdropped = 1;
} else if (opt->flag & MM_F_SPLICE)
ksw_exts2_sse(km, qlen, qseq, tlen, tseq, 5, mat, opt->q, opt->e, opt->q2, opt->noncan, zdrop, flag, ez); ksw_exts2_sse(km, qlen, qseq, tlen, tseq, 5, mat, opt->q, opt->e, opt->q2, opt->noncan, zdrop, flag, ez);
else if (opt->q == opt->q2 && opt->e == opt->e2) else if (opt->q == opt->q2 && opt->e == opt->e2)
ksw_extz2_sse(km, qlen, qseq, tlen, tseq, 5, mat, opt->q, opt->e, w, zdrop, end_bonus, flag, ez); ksw_extz2_sse(km, qlen, qseq, tlen, tseq, 5, mat, opt->q, opt->e, w, zdrop, end_bonus, flag, ez);
else else
ksw_extd2_sse(km, qlen, qseq, tlen, tseq, 5, mat, opt->q, opt->e, opt->q2, opt->e2, w, zdrop, end_bonus, flag, ob, ez); ksw_extd2_sse(km, qlen, qseq, tlen, tseq, 5, mat, opt->q, opt->e, opt->q2, opt->e2, w, zdrop, end_bonus, flag, ez);
if (mm_dbg_flag & MM_DBG_PRINT_ALN_SEQ) { if (mm_dbg_flag & MM_DBG_PRINT_ALN_SEQ) {
int i; int i;
fprintf(stderr, "score=%d, cigar=", ez->score); fprintf(stderr, "score=%d, cigar=", ez->score);
@@ -417,7 +417,7 @@ static void mm_filter_bad_seeds_alt(void *km, int as1, int cnt1, mm128_t *a, int
gap2 = ((int32_t)a[as1 + j].y - (int32_t)a[as1 + j - 1].y) - (int32_t)(a[as1 + j].x - a[as1 + j - 1].x); gap2 = ((int32_t)a[as1 + j].y - (int32_t)a[as1 + j - 1].y) - (int32_t)(a[as1 + j].x - a[as1 + j - 1].x);
q_span_pre = a[as1 + j - 1].y >> 32 & 0xff; q_span_pre = a[as1 + j - 1].y >> 32 & 0xff;
rs2 = (int32_t)a[as1 + j - 1].x + q_span_pre; rs2 = (int32_t)a[as1 + j - 1].x + q_span_pre;
qs2 = (int32_t)a[as1 + j - 1].x + q_span_pre; qs2 = (int32_t)a[as1 + j - 1].y + q_span_pre;
m = rs2 - re1 < qs2 - qe1? rs2 - re1 : qs2 - qe1; m = rs2 - re1 < qs2 - qe1? rs2 - re1 : qs2 - qe1;
gap2 = gap2 > 0? gap2 : -gap2; gap2 = gap2 > 0? gap2 : -gap2;
if (m > gap1 + gap2) break; if (m > gap1 + gap2) break;
@@ -550,7 +550,7 @@ static void mm_align1(void *km, const mm_mapopt_t *opt, const mm_idx_t *mi, int
int32_t i, l, bw, dropped = 0, extra_flag = 0, rs0, re0, qs0, qe0; int32_t i, l, bw, dropped = 0, extra_flag = 0, rs0, re0, qs0, qe0;
int32_t rs, re, qs, qe; int32_t rs, re, qs, qe;
int32_t rs1, qs1, re1, qe1; int32_t rs1, qs1, re1, qe1;
int8_t mat[25], *ob; int8_t mat[25];
if (is_sr) assert(!(mi->flag & MM_I_HPC)); // HPC won't work with SR because with HPC we can't easily tell if there is a gap if (is_sr) assert(!(mi->flag & MM_I_HPC)); // HPC won't work with SR because with HPC we can't easily tell if there is a gap
@@ -594,11 +594,9 @@ static void mm_align1(void *km, const mm_mapopt_t *opt, const mm_idx_t *mi, int
qs0 = 0, qe0 = qlen; qs0 = 0, qe0 = qlen;
l = qs; l = qs;
l += l * opt->a + opt->end_bonus > opt->q? (l * opt->a + opt->end_bonus - opt->q) / opt->e : 0; l += l * opt->a + opt->end_bonus > opt->q? (l * opt->a + opt->end_bonus - opt->q) / opt->e : 0;
l = l < opt->bw? l : opt->bw;
rs0 = rs - l > 0? rs - l : 0; rs0 = rs - l > 0? rs - l : 0;
l = qlen - qe; l = qlen - qe;
l += l * opt->a + opt->end_bonus > opt->q? (l * opt->a + opt->end_bonus - opt->q) / opt->e : 0; l += l * opt->a + opt->end_bonus > opt->q? (l * opt->a + opt->end_bonus - opt->q) / opt->e : 0;
l = l < opt->bw? l : opt->bw;
re0 = re + l < (int32_t)mi->seq[rid].len? re + l : mi->seq[rid].len; re0 = re + l < (int32_t)mi->seq[rid].len? re + l : mi->seq[rid].len;
} else { } else {
// compute rs0 and qs0 // compute rs0 and qs0
@@ -665,14 +663,13 @@ static void mm_align1(void *km, const mm_mapopt_t *opt, const mm_idx_t *mi, int
assert(re0 > rs0); assert(re0 > rs0);
tseq = (uint8_t*)kmalloc(km, re0 - rs0); tseq = (uint8_t*)kmalloc(km, re0 - rs0);
ob = (int8_t*)kmalloc(km, re0 - rs0);
if (qs > 0 && rs > 0) { // left extension if (qs > 0 && rs > 0) { // left extension
qseq = &qseq0[rev][qs0]; qseq = &qseq0[rev][qs0];
mm_idx_getseq2(mi, rid, rs0, rs, tseq, ob); mm_idx_getseq(mi, rid, rs0, rs, tseq);
mm_seq_rev(qs - qs0, qseq); mm_seq_rev(qs - qs0, qseq);
mm_seq_rev(rs - rs0, tseq); mm_seq_rev(rs - rs0, tseq);
mm_align_pair(km, opt, qs - qs0, qseq, rs - rs0, tseq, ob, mat, bw, opt->end_bonus, r->split_inv? opt->zdrop_inv : opt->zdrop, extra_flag|KSW_EZ_EXTZ_ONLY|KSW_EZ_RIGHT|KSW_EZ_REV_CIGAR, ez); mm_align_pair(km, opt, qs - qs0, qseq, rs - rs0, tseq, mat, bw, opt->end_bonus, r->split_inv? opt->zdrop_inv : opt->zdrop, extra_flag|KSW_EZ_EXTZ_ONLY|KSW_EZ_RIGHT|KSW_EZ_REV_CIGAR, ez);
if (ez->n_cigar > 0) { if (ez->n_cigar > 0) {
mm_append_cigar(r, ez->n_cigar, ez->cigar); mm_append_cigar(r, ez->n_cigar, ez->cigar);
r->p->dp_score += ez->max; r->p->dp_score += ez->max;
@@ -697,7 +694,7 @@ static void mm_align1(void *km, const mm_mapopt_t *opt, const mm_idx_t *mi, int
bw1 = qe - qs > re - rs? qe - qs : re - rs; bw1 = qe - qs > re - rs? qe - qs : re - rs;
// perform alignment // perform alignment
qseq = &qseq0[rev][qs]; qseq = &qseq0[rev][qs];
mm_idx_getseq2(mi, rid, rs, re, tseq, ob); mm_idx_getseq(mi, rid, rs, re, tseq);
if (is_sr) { // perform ungapped alignment if (is_sr) { // perform ungapped alignment
assert(qe - qs == re - rs); assert(qe - qs == re - rs);
ksw_reset_extz(ez); ksw_reset_extz(ez);
@@ -707,11 +704,11 @@ static void mm_align1(void *km, const mm_mapopt_t *opt, const mm_idx_t *mi, int
} }
ez->cigar = ksw_push_cigar(km, &ez->n_cigar, &ez->m_cigar, ez->cigar, 0, qe - qs); ez->cigar = ksw_push_cigar(km, &ez->n_cigar, &ez->m_cigar, ez->cigar, 0, qe - qs);
} else { // perform normal gapped alignment } else { // perform normal gapped alignment
mm_align_pair(km, opt, qe - qs, qseq, re - rs, tseq, ob, mat, bw1, -1, opt->zdrop, extra_flag|KSW_EZ_APPROX_MAX, ez); // first pass: with approximate Z-drop mm_align_pair(km, opt, qe - qs, qseq, re - rs, tseq, mat, bw1, -1, opt->zdrop, extra_flag|KSW_EZ_APPROX_MAX, ez); // first pass: with approximate Z-drop
} }
// test Z-drop and inversion Z-drop // test Z-drop and inversion Z-drop
if ((zdrop_code = mm_test_zdrop(km, opt, qseq, tseq, ez->n_cigar, ez->cigar, mat)) != 0) if ((zdrop_code = mm_test_zdrop(km, opt, qseq, tseq, ez->n_cigar, ez->cigar, mat)) != 0)
mm_align_pair(km, opt, qe - qs, qseq, re - rs, tseq, ob, mat, bw1, -1, zdrop_code == 2? opt->zdrop_inv : opt->zdrop, extra_flag, ez); // second pass: lift approximate mm_align_pair(km, opt, qe - qs, qseq, re - rs, tseq, mat, bw1, -1, zdrop_code == 2? opt->zdrop_inv : opt->zdrop, extra_flag, ez); // second pass: lift approximate
// update CIGAR // update CIGAR
if (ez->n_cigar > 0) if (ez->n_cigar > 0)
mm_append_cigar(r, ez->n_cigar, ez->cigar); mm_append_cigar(r, ez->n_cigar, ez->cigar);
@@ -736,8 +733,8 @@ static void mm_align1(void *km, const mm_mapopt_t *opt, const mm_idx_t *mi, int
if (!dropped && qe < qe0 && re < re0) { // right extension if (!dropped && qe < qe0 && re < re0) { // right extension
qseq = &qseq0[rev][qe]; qseq = &qseq0[rev][qe];
mm_idx_getseq2(mi, rid, re, re0, tseq, ob); mm_idx_getseq(mi, rid, re, re0, tseq);
mm_align_pair(km, opt, qe0 - qe, qseq, re0 - re, tseq, ob, mat, bw, opt->end_bonus, opt->zdrop, extra_flag|KSW_EZ_EXTZ_ONLY, ez); mm_align_pair(km, opt, qe0 - qe, qseq, re0 - re, tseq, mat, bw, opt->end_bonus, opt->zdrop, extra_flag|KSW_EZ_EXTZ_ONLY, ez);
if (ez->n_cigar > 0) { if (ez->n_cigar > 0) {
mm_append_cigar(r, ez->n_cigar, ez->cigar); mm_append_cigar(r, ez->n_cigar, ez->cigar);
r->p->dp_score += ez->max; r->p->dp_score += ez->max;
@@ -753,16 +750,14 @@ static void mm_align1(void *km, const mm_mapopt_t *opt, const mm_idx_t *mi, int
assert(re1 - rs1 <= re0 - rs0); assert(re1 - rs1 <= re0 - rs0);
if (r->p) { if (r->p) {
int left_aln = (opt->flag & MM_F_SPLICE) || mi->n_R == 0? 1 : 0; mm_idx_getseq(mi, rid, rs1, re1, tseq);
mm_idx_getseq2(mi, rid, rs1, re1, tseq, ob); mm_update_extra(r, &qseq0[r->rev][qs1], tseq, mat, opt->q, opt->e);
mm_update_extra(r, &qseq0[r->rev][qs1], tseq, mat, opt->q, opt->e, left_aln);
if (opt->flag & MM_F_EQX) mm_update_cigar_eqx(r, &qseq0[r->rev][qs1], tseq); if (opt->flag & MM_F_EQX) mm_update_cigar_eqx(r, &qseq0[r->rev][qs1], tseq);
if (rev && r->p->trans_strand) if (rev && r->p->trans_strand)
r->p->trans_strand ^= 3; // flip to the read strand r->p->trans_strand ^= 3; // flip to the read strand
} }
kfree(km, tseq); kfree(km, tseq);
kfree(km, ob);
} }
static int mm_align1_inv(void *km, const mm_mapopt_t *opt, const mm_idx_t *mi, int qlen, uint8_t *qseq0[2], const mm_reg1_t *r1, const mm_reg1_t *r2, mm_reg1_t *r_inv, ksw_extz_t *ez) static int mm_align1_inv(void *km, const mm_mapopt_t *opt, const mm_idx_t *mi, int qlen, uint8_t *qseq0[2], const mm_reg1_t *r1, const mm_reg1_t *r2, mm_reg1_t *r_inv, ksw_extz_t *ez)
@@ -796,7 +791,7 @@ static int mm_align1_inv(void *km, const mm_mapopt_t *opt, const mm_idx_t *mi, i
mm_seq_rev(tl, tseq); mm_seq_rev(tl, tseq);
if (score < opt->min_dp_max) goto end_align1_inv; if (score < opt->min_dp_max) goto end_align1_inv;
q_off = ql - (q_off + 1), t_off = tl - (t_off + 1); q_off = ql - (q_off + 1), t_off = tl - (t_off + 1);
mm_align_pair(km, opt, ql - q_off, qseq + q_off, tl - t_off, tseq + t_off, 0, mat, (int)(opt->bw * 1.5), -1, opt->zdrop, KSW_EZ_EXTZ_ONLY, ez); mm_align_pair(km, opt, ql - q_off, qseq + q_off, tl - t_off, tseq + t_off, mat, (int)(opt->bw * 1.5), -1, opt->zdrop, KSW_EZ_EXTZ_ONLY, ez);
if (ez->n_cigar == 0) goto end_align1_inv; // should never be here if (ez->n_cigar == 0) goto end_align1_inv; // should never be here
mm_append_cigar(r_inv, ez->n_cigar, ez->cigar); mm_append_cigar(r_inv, ez->n_cigar, ez->cigar);
r_inv->p->dp_score = ez->max; r_inv->p->dp_score = ez->max;
@@ -815,7 +810,7 @@ static int mm_align1_inv(void *km, const mm_mapopt_t *opt, const mm_idx_t *mi, i
} }
r_inv->rs = r1->re + t_off; r_inv->rs = r1->re + t_off;
r_inv->re = r_inv->rs + ez->max_t + 1; r_inv->re = r_inv->rs + ez->max_t + 1;
mm_update_extra(r_inv, &qseq[q_off], &tseq[t_off], mat, opt->q, opt->e, 0); mm_update_extra(r_inv, &qseq[q_off], &tseq[t_off], mat, opt->q, opt->e);
if (opt->flag & MM_F_EQX) mm_update_cigar_eqx(r_inv, &qseq[q_off], &tseq[t_off]); if (opt->flag & MM_F_EQX) mm_update_cigar_eqx(r_inv, &qseq[q_off], &tseq[t_off]);
ret = 1; ret = 1;
end_align1_inv: end_align1_inv:
+7 -2
View File
@@ -39,7 +39,7 @@ mm_bseq_file_t *mm_bseq_open(const char *fn)
{ {
mm_bseq_file_t *fp; mm_bseq_file_t *fp;
gzFile f; gzFile f;
f = fn && strcmp(fn, "-")? gzopen(fn, "r") : gzdopen(fileno(stdin), "r"); f = fn && strcmp(fn, "-")? gzopen(fn, "r") : gzdopen(0, "r");
if (f == 0) return 0; if (f == 0) return 0;
fp = (mm_bseq_file_t*)calloc(1, sizeof(mm_bseq_file_t)); fp = (mm_bseq_file_t*)calloc(1, sizeof(mm_bseq_file_t));
fp->fp = f; fp->fp = f;
@@ -65,6 +65,8 @@ static inline char *kstrdup(const kstring_t *s)
static inline void kseq2bseq(kseq_t *ks, mm_bseq1_t *s, int with_qual, int with_comment) static inline void kseq2bseq(kseq_t *ks, mm_bseq1_t *s, int with_qual, int with_comment)
{ {
int i; int i;
if (ks->name.l == 0)
fprintf(stderr, "[WARNING]\033[1;31m empty sequence name in the input.\033[0m\n");
s->name = kstrdup(&ks->name); s->name = kstrdup(&ks->name);
s->seq = kstrdup(&ks->seq); s->seq = kstrdup(&ks->seq);
for (i = 0; i < (int)ks->seq.l; ++i) // convert U to T for (i = 0; i < (int)ks->seq.l; ++i) // convert U to T
@@ -78,6 +80,7 @@ static inline void kseq2bseq(kseq_t *ks, mm_bseq1_t *s, int with_qual, int with_
mm_bseq1_t *mm_bseq_read3(mm_bseq_file_t *fp, int chunk_size, int with_qual, int with_comment, int frag_mode, int *n_) mm_bseq1_t *mm_bseq_read3(mm_bseq_file_t *fp, int chunk_size, int with_qual, int with_comment, int frag_mode, int *n_)
{ {
int64_t size = 0; int64_t size = 0;
int ret;
kvec_t(mm_bseq1_t) a = {0,0,0}; kvec_t(mm_bseq1_t) a = {0,0,0};
kseq_t *ks = fp->ks; kseq_t *ks = fp->ks;
*n_ = 0; *n_ = 0;
@@ -87,7 +90,7 @@ mm_bseq1_t *mm_bseq_read3(mm_bseq_file_t *fp, int chunk_size, int with_qual, int
size = fp->s.l_seq; size = fp->s.l_seq;
memset(&fp->s, 0, sizeof(mm_bseq1_t)); memset(&fp->s, 0, sizeof(mm_bseq1_t));
} }
while (kseq_read(ks) >= 0) { while ((ret = kseq_read(ks)) >= 0) {
mm_bseq1_t *s; mm_bseq1_t *s;
assert(ks->seq.l <= INT32_MAX); assert(ks->seq.l <= INT32_MAX);
if (a.m == 0) kv_resize(mm_bseq1_t, 0, a, 256); if (a.m == 0) kv_resize(mm_bseq1_t, 0, a, 256);
@@ -107,6 +110,8 @@ mm_bseq1_t *mm_bseq_read3(mm_bseq_file_t *fp, int chunk_size, int with_qual, int
break; break;
} }
} }
if (ret < -1)
fprintf(stderr, "[WARNING]\033[1;31m wrong FASTA/FASTQ record. Continue anyway.\033[0m\n");
*n_ = a.n; *n_ = a.n;
return a.a; return a.a;
} }
+2 -2
View File
@@ -31,8 +31,8 @@ To acquire the data used in this cookbook and to install minimap2 and paftools,
please follow the command lines below: please follow the command lines below:
```sh ```sh
# install minimap2 executables # install minimap2 executables
curl -L https://github.com/lh3/minimap2/releases/download/v2.13/minimap2-2.13_x64-linux.tar.bz2 | tar jxf - curl -L https://github.com/lh3/minimap2/releases/download/v2.14/minimap2-2.14_x64-linux.tar.bz2 | tar jxf -
cp minimap2-2.13_x64-linux/{minimap2,k8,paftools.js} . # copy executables cp minimap2-2.14_x64-linux/{minimap2,k8,paftools.js} . # copy executables
export PATH="$PATH:"`pwd` # put the current directory on PATH export PATH="$PATH:"`pwd` # put the current directory on PATH
# download example datasets # download example datasets
curl -L https://github.com/lh3/minimap2/releases/download/v2.10/cookbook-data.tgz | tar zxf - curl -L https://github.com/lh3/minimap2/releases/download/v2.10/cookbook-data.tgz | tar zxf -
+6 -5
View File
@@ -92,7 +92,8 @@ static void sam_write_rg_line(kstring_t *str, const char *s)
if (mm_verbose >= 1) fprintf(stderr, "[ERROR] the read group line contained literal <tab> characters -- replace with escaped tabs: \\t\n"); if (mm_verbose >= 1) fprintf(stderr, "[ERROR] the read group line contained literal <tab> characters -- replace with escaped tabs: \\t\n");
goto err_set_rg; goto err_set_rg;
} }
rg_line = strdup(s); rg_line = (char*)malloc(strlen(s) + 1);
strcpy(rg_line, s);
mm_escape(rg_line); mm_escape(rg_line);
if ((p = strstr(rg_line, "\tID:")) == 0) { if ((p = strstr(rg_line, "\tID:")) == 0) {
if (mm_verbose >= 1) fprintf(stderr, "[ERROR] no ID within the read group line\n"); if (mm_verbose >= 1) fprintf(stderr, "[ERROR] no ID within the read group line\n");
@@ -139,8 +140,8 @@ static void write_cs_core(kstring_t *s, const uint8_t *tseq, const uint8_t *qseq
if (write_tag) mm_sprintf_lite(s, "\tcs:Z:"); if (write_tag) mm_sprintf_lite(s, "\tcs:Z:");
for (i = q_off = t_off = 0; i < (int)r->p->n_cigar; ++i) { for (i = q_off = t_off = 0; i < (int)r->p->n_cigar; ++i) {
int j, op = r->p->cigar[i]&0xf, len = r->p->cigar[i]>>4; int j, op = r->p->cigar[i]&0xf, len = r->p->cigar[i]>>4;
assert(op >= 0 && op <= 3); assert((op >= 0 && op <= 3) || op == 7 || op == 8);
if (op == 0) { // match if (op == 0 || op == 7 || op == 8) { // match
int l_tmp = 0; int l_tmp = 0;
for (j = 0; j < len; ++j) { for (j = 0; j < len; ++j) {
if (qseq[q_off + j] != tseq[t_off + j]) { if (qseq[q_off + j] != tseq[t_off + j]) {
@@ -187,8 +188,8 @@ static void write_MD_core(kstring_t *s, const uint8_t *tseq, const uint8_t *qseq
if (write_tag) mm_sprintf_lite(s, "\tMD:Z:"); if (write_tag) mm_sprintf_lite(s, "\tMD:Z:");
for (i = q_off = t_off = 0; i < (int)r->p->n_cigar; ++i) { for (i = q_off = t_off = 0; i < (int)r->p->n_cigar; ++i) {
int j, op = r->p->cigar[i]&0xf, len = r->p->cigar[i]>>4; int j, op = r->p->cigar[i]&0xf, len = r->p->cigar[i]>>4;
assert(op >= 0 && op <= 3); assert((op >= 0 && op <= 3) || op == 7 || op == 8);
if (op == 0) { // match if (op == 0 || op == 7 || op == 8) { // match
for (j = 0; j < len; ++j) { for (j = 0; j < len; ++j) {
if (qseq[q_off + j] != tseq[t_off + j]) { if (qseq[q_off + j] != tseq[t_off + j]) {
mm_sprintf_lite(s, "%d%c", l_MD, "ACGTN"[tseq[t_off + j]]); mm_sprintf_lite(s, "%d%c", l_MD, "ACGTN"[tseq[t_off + j]]);
+2 -105
View File
@@ -60,7 +60,7 @@ void mm_idx_destroy(mm_idx_t *mi)
free(mi->seq[i].name); free(mi->seq[i].name);
free(mi->seq); free(mi->seq);
} else km_destroy(mi->km); } else km_destroy(mi->km);
free(mi->R); free(mi->B); free(mi->S); free(mi); free(mi->B); free(mi->S); free(mi);
} }
const uint64_t *mm_idx_get(const mm_idx_t *mi, uint64_t minier, int *n) const uint64_t *mm_idx_get(const mm_idx_t *mi, uint64_t minier, int *n)
@@ -134,7 +134,7 @@ int mm_idx_name2id(const mm_idx_t *mi, const char *name)
return k == kh_end(h)? -1 : kh_val(h, k); return k == kh_end(h)? -1 : kh_val(h, k);
} }
int mm_idx_getseq2(const mm_idx_t *mi, uint32_t rid, uint32_t st, uint32_t en, uint8_t *seq, int8_t *b) int mm_idx_getseq(const mm_idx_t *mi, uint32_t rid, uint32_t st, uint32_t en, uint8_t *seq)
{ {
uint64_t i, st1, en1; uint64_t i, st1, en1;
if (rid >= mi->n_seq || st >= mi->seq[rid].len) return -1; if (rid >= mi->n_seq || st >= mi->seq[rid].len) return -1;
@@ -143,26 +143,9 @@ int mm_idx_getseq2(const mm_idx_t *mi, uint32_t rid, uint32_t st, uint32_t en, u
en1 = mi->seq[rid].offset + en; en1 = mi->seq[rid].offset + en;
for (i = st1; i < en1; ++i) for (i = st1; i < en1; ++i)
seq[i - st1] = mm_seq4_get(mi->S, i); seq[i - st1] = mm_seq4_get(mi->S, i);
if (b) memset(b, 0, en - st);
if (b && mi->R) {
uint32_t i, z;
memset(b, 0, en - st);
z = mm_idx_bed_query(mi, (uint64_t)rid << 32 | st);
for (i = z < 0? 0 : z; i < mi->n_R; ++i) {
uint32_t j, rr, rs, re;
rr = mi->R[i].x >> 32, rs = (uint32_t)mi->R[i].x, re = mi->R[i].end;
if (rr > rid || rs >= en) break;
if (rr < rid) continue;
re = re < en? re : en;
for (j = st > rs? st : rs; j < re; ++j)
b[j - st] = mi->R[i].score;
}
}
return en - st; return en - st;
} }
int mm_idx_getseq(const mm_idx_t *mi, uint32_t rid, uint32_t st, uint32_t en, uint8_t *seq) { return mm_idx_getseq2(mi, rid, st, en, seq, 0); }
int32_t mm_idx_cal_max_occ(const mm_idx_t *mi, float f) int32_t mm_idx_cal_max_occ(const mm_idx_t *mi, float f)
{ {
int i; int i;
@@ -602,89 +585,3 @@ int mm_idx_reader_eof(const mm_idx_reader_t *r) // TODO: in extremely rare cases
{ {
return r->is_idx? (feof(r->fp.idx) || ftell(r->fp.idx) == r->idx_size) : mm_bseq_eof(r->fp.seq); return r->is_idx? (feof(r->fp.idx) || ftell(r->fp.idx) == r->idx_size) : mm_bseq_eof(r->fp.seq);
} }
#include <ctype.h>
#include <zlib.h>
#include "ksort.h"
#include "kseq.h"
KSTREAM_DECLARE(gzFile, gzread)
#define sort_key_bed(a) ((a).x)
KRADIX_SORT_INIT(bed, mm_idx_bed_t, sort_key_bed, 8)
mm_idx_bed_t *mm_idx_bed_read_list(const mm_idx_t *mi, const char *fn, uint32_t *n_)
{
gzFile fp;
kstream_t *ks;
kstring_t str = {0,0,0};
uint32_t n = 0, m = 0;
mm_idx_bed_t *r = 0;
fp = fn && strcmp(fn, "-")? gzopen(fn, "r") : gzdopen(fileno(stdin), "r");
if (fp == 0) return 0;
ks = ks_init(fp);
while (ks_getuntil(ks, KS_SEP_LINE, &str, 0) >= 0) {
mm_idx_bed_t t;
char *p, *q;
int i, id = -1, st = -1, en = -1, sc = -1;
for (p = q = str.s, i = 0;; ++p) {
if (*p == 0 || isspace(*p)) {
int32_t c = *p;
*p = 0;
if (i == 0) { // chr
id = mm_idx_name2id(mi, q);
if (id < 0) break; // unknown name; TODO: throw a warning
} else if (i == 1) { // start
st = atoi(q);
if (st < 0) break;
} else if (i == 2) { // end
en = atoi(q);
if (en < 0) break;
} else if (i == 3) { // name; do nothing
} else if (i == 4) { // BED score
sc = atoi(q);
assert(sc >= 0 && sc <= 127);
} else break;
if (c == 0) break;
++i, q = p + 1;
}
}
if (en < 0) en = st + 1;
if (st < 0 || st >= en) continue;
if (m == n) EXPAND(r, m);
t.x = (uint64_t)id << 32 | st, t.end = en, t.score = sc >= 0? sc : 0, t.idx = -1;
r[n++] = t;
}
ks_destroy(ks);
gzclose(fp);
*n_ = n;
return r;
}
int mm_idx_bed_attach(mm_idx_t *mi, uint32_t n, mm_idx_bed_t *r) // TODO: check errors
{
radix_sort_bed(r, r + n);
mi->R = r, mi->n_R = n;
return 0;
}
int mm_idx_bed_read(mm_idx_t *mi, const char *fn)
{
mm_idx_bed_t *r;
uint32_t n;
if (mi->h == 0) mm_idx_index_name(mi);
r = mm_idx_bed_read_list(mi, fn, &n);
return mm_idx_bed_attach(mi, n, r);
}
int mm_idx_bed_query(const mm_idx_t *mi, uint64_t x)
{
int32_t left = -1, right = mi->n_R;
while (right - left > 1) {
int32_t mid = left + ((right - left) >> 1);
if (mi->R[mid].x > x) right = mid;
else if (mi->R[mid].x < x) left = mid;
else return mid;
}
return left;
}
+1 -9
View File
@@ -37,14 +37,6 @@
#define KS_SEP_LINE 2 // line separator: "\n" (Unix) or "\r\n" (Windows) #define KS_SEP_LINE 2 // line separator: "\n" (Unix) or "\r\n" (Windows)
#define KS_SEP_MAX 2 #define KS_SEP_MAX 2
#ifndef klib_unused
#if (defined __clang__ && __clang_major__ >= 3) || (defined __GNUC__ && __GNUC__ >= 3)
#define klib_unused __attribute__ ((__unused__))
#else
#define klib_unused
#endif
#endif /* klib_unused */
#define __KS_TYPE(type_t) \ #define __KS_TYPE(type_t) \
typedef struct __kstream_t { \ typedef struct __kstream_t { \
int begin, end; \ int begin, end; \
@@ -72,7 +64,7 @@
} }
#define __KS_INLINED(__read) \ #define __KS_INLINED(__read) \
static inline klib_unused int ks_getc(kstream_t *ks) \ static inline int ks_getc(kstream_t *ks) \
{ \ { \
if (ks->is_eof && ks->begin >= ks->end) return -1; \ if (ks->is_eof && ks->begin >= ks->end) return -1; \
if (ks->begin >= ks->end) { \ if (ks->begin >= ks->end) { \
+1 -1
View File
@@ -58,7 +58,7 @@ void ksw_extd(void *km, int qlen, const uint8_t *query, int tlen, const uint8_t
int8_t gapo, int8_t gape, int8_t gapo2, int8_t gape2, int w, int zdrop, int flag, ksw_extz_t *ez); int8_t gapo, int8_t gape, int8_t gapo2, int8_t gape2, int w, int zdrop, int flag, ksw_extz_t *ez);
void ksw_extd2_sse(void *km, int qlen, const uint8_t *query, int tlen, const uint8_t *target, int8_t m, const int8_t *mat, void ksw_extd2_sse(void *km, int qlen, const uint8_t *query, int tlen, const uint8_t *target, int8_t m, const int8_t *mat,
int8_t gapo, int8_t gape, int8_t gapo2, int8_t gape2, int w, int zdrop, int end_bonus, int flag, const int8_t *qd, ksw_extz_t *ez); int8_t gapo, int8_t gape, int8_t gapo2, int8_t gape2, int w, int zdrop, int end_bonus, int flag, ksw_extz_t *ez);
void ksw_exts2_sse(void *km, int qlen, const uint8_t *query, int tlen, const uint8_t *target, int8_t m, const int8_t *mat, void ksw_exts2_sse(void *km, int qlen, const uint8_t *query, int tlen, const uint8_t *target, int8_t m, const int8_t *mat,
int8_t gapo, int8_t gape, int8_t gapo2, int8_t noncan, int zdrop, int flag, ksw_extz_t *ez); int8_t gapo, int8_t gape, int8_t gapo2, int8_t noncan, int zdrop, int flag, ksw_extz_t *ez);
+19 -20
View File
@@ -17,18 +17,20 @@
void __cpuidex(int cpuid[4], int func_id, int subfunc_id) void __cpuidex(int cpuid[4], int func_id, int subfunc_id)
{ {
#if defined(__x86_64__) #if defined(__x86_64__)
asm volatile ("cpuid" __asm__ volatile ("cpuid"
: "=a" (cpuid[0]), "=b" (cpuid[1]), "=c" (cpuid[2]), "=d" (cpuid[3]) : "=a" (cpuid[0]), "=b" (cpuid[1]), "=c" (cpuid[2]), "=d" (cpuid[3])
: "0" (func_id), "2" (subfunc_id)); : "0" (func_id), "2" (subfunc_id));
#else // on 32bit, ebx can NOT be used as PIC code #else // on 32bit, ebx can NOT be used as PIC code
asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1" __asm__ volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1"
: "=a" (cpuid[0]), "=r" (cpuid[1]), "=c" (cpuid[2]), "=d" (cpuid[3]) : "=a" (cpuid[0]), "=r" (cpuid[1]), "=c" (cpuid[2]), "=d" (cpuid[3])
: "0" (func_id), "2" (subfunc_id)); : "0" (func_id), "2" (subfunc_id));
#endif #endif
} }
#endif #endif
int x86_simd(void) static int ksw_simd = -1;
static int x86_simd(void)
{ {
int flag = 0, cpuid[4], max_id; int flag = 0, cpuid[4], max_id;
__cpuidex(cpuid, 0, 0); __cpuidex(cpuid, 0, 0);
@@ -54,28 +56,26 @@ void ksw_extz2_sse(void *km, int qlen, const uint8_t *query, int tlen, const uin
{ {
extern void ksw_extz2_sse2(void *km, int qlen, const uint8_t *query, int tlen, const uint8_t *target, int8_t m, const int8_t *mat, int8_t q, int8_t e, int w, int zdrop, int end_bonus, int flag, ksw_extz_t *ez); extern void ksw_extz2_sse2(void *km, int qlen, const uint8_t *query, int tlen, const uint8_t *target, int8_t m, const int8_t *mat, int8_t q, int8_t e, int w, int zdrop, int end_bonus, int flag, ksw_extz_t *ez);
extern void ksw_extz2_sse41(void *km, int qlen, const uint8_t *query, int tlen, const uint8_t *target, int8_t m, const int8_t *mat, int8_t q, int8_t e, int w, int zdrop, int end_bonus, int flag, ksw_extz_t *ez); extern void ksw_extz2_sse41(void *km, int qlen, const uint8_t *query, int tlen, const uint8_t *target, int8_t m, const int8_t *mat, int8_t q, int8_t e, int w, int zdrop, int end_bonus, int flag, ksw_extz_t *ez);
unsigned simd; if (ksw_simd < 0) ksw_simd = x86_simd();
simd = x86_simd(); if (ksw_simd & SIMD_SSE4_1)
if (simd & SIMD_SSE4_1)
ksw_extz2_sse41(km, qlen, query, tlen, target, m, mat, q, e, w, zdrop, end_bonus, flag, ez); ksw_extz2_sse41(km, qlen, query, tlen, target, m, mat, q, e, w, zdrop, end_bonus, flag, ez);
else if (simd & SIMD_SSE2) else if (ksw_simd & SIMD_SSE2)
ksw_extz2_sse2(km, qlen, query, tlen, target, m, mat, q, e, w, zdrop, end_bonus, flag, ez); ksw_extz2_sse2(km, qlen, query, tlen, target, m, mat, q, e, w, zdrop, end_bonus, flag, ez);
else abort(); else abort();
} }
void ksw_extd2_sse(void *km, int qlen, const uint8_t *query, int tlen, const uint8_t *target, int8_t m, const int8_t *mat, void ksw_extd2_sse(void *km, int qlen, const uint8_t *query, int tlen, const uint8_t *target, int8_t m, const int8_t *mat,
int8_t q, int8_t e, int8_t q2, int8_t e2, int w, int zdrop, int end_bonus, int flag, const int8_t *qd, ksw_extz_t *ez) int8_t q, int8_t e, int8_t q2, int8_t e2, int w, int zdrop, int end_bonus, int flag, ksw_extz_t *ez)
{ {
extern void ksw_extd2_sse2(void *km, int qlen, const uint8_t *query, int tlen, const uint8_t *target, int8_t m, const int8_t *mat, extern void ksw_extd2_sse2(void *km, int qlen, const uint8_t *query, int tlen, const uint8_t *target, int8_t m, const int8_t *mat,
int8_t q, int8_t e, int8_t q2, int8_t e2, int w, int zdrop, int end_bonus, int flag, const int8_t *qd, ksw_extz_t *ez); int8_t q, int8_t e, int8_t q2, int8_t e2, int w, int zdrop, int end_bonus, int flag, ksw_extz_t *ez);
extern void ksw_extd2_sse41(void *km, int qlen, const uint8_t *query, int tlen, const uint8_t *target, int8_t m, const int8_t *mat, extern void ksw_extd2_sse41(void *km, int qlen, const uint8_t *query, int tlen, const uint8_t *target, int8_t m, const int8_t *mat,
int8_t q, int8_t e, int8_t q2, int8_t e2, int w, int zdrop, int end_bonus, int flag, const int8_t *qd, ksw_extz_t *ez); int8_t q, int8_t e, int8_t q2, int8_t e2, int w, int zdrop, int end_bonus, int flag, ksw_extz_t *ez);
unsigned simd; if (ksw_simd < 0) ksw_simd = x86_simd();
simd = x86_simd(); if (ksw_simd & SIMD_SSE4_1)
if (simd & SIMD_SSE4_1) ksw_extd2_sse41(km, qlen, query, tlen, target, m, mat, q, e, q2, e2, w, zdrop, end_bonus, flag, ez);
ksw_extd2_sse41(km, qlen, query, tlen, target, m, mat, q, e, q2, e2, w, zdrop, end_bonus, flag, qd, ez); else if (ksw_simd & SIMD_SSE2)
else if (simd & SIMD_SSE2) ksw_extd2_sse2(km, qlen, query, tlen, target, m, mat, q, e, q2, e2, w, zdrop, end_bonus, flag, ez);
ksw_extd2_sse2(km, qlen, query, tlen, target, m, mat, q, e, q2, e2, w, zdrop, end_bonus, flag, qd, ez);
else abort(); else abort();
} }
@@ -86,11 +86,10 @@ void ksw_exts2_sse(void *km, int qlen, const uint8_t *query, int tlen, const uin
int8_t q, int8_t e, int8_t q2, int8_t noncan, int zdrop, int flag, ksw_extz_t *ez); int8_t q, int8_t e, int8_t q2, int8_t noncan, int zdrop, int flag, ksw_extz_t *ez);
extern void ksw_exts2_sse41(void *km, int qlen, const uint8_t *query, int tlen, const uint8_t *target, int8_t m, const int8_t *mat, extern void ksw_exts2_sse41(void *km, int qlen, const uint8_t *query, int tlen, const uint8_t *target, int8_t m, const int8_t *mat,
int8_t q, int8_t e, int8_t q2, int8_t noncan, int zdrop, int flag, ksw_extz_t *ez); int8_t q, int8_t e, int8_t q2, int8_t noncan, int zdrop, int flag, ksw_extz_t *ez);
unsigned simd; if (ksw_simd < 0) ksw_simd = x86_simd();
simd = x86_simd(); if (ksw_simd & SIMD_SSE4_1)
if (simd & SIMD_SSE4_1)
ksw_exts2_sse41(km, qlen, query, tlen, target, m, mat, q, e, q2, noncan, zdrop, flag, ez); ksw_exts2_sse41(km, qlen, query, tlen, target, m, mat, q, e, q2, noncan, zdrop, flag, ez);
else if (simd & SIMD_SSE2) else if (ksw_simd & SIMD_SSE2)
ksw_exts2_sse2(km, qlen, query, tlen, target, m, mat, q, e, q2, noncan, zdrop, flag, ez); ksw_exts2_sse2(km, qlen, query, tlen, target, m, mat, q, e, q2, noncan, zdrop, flag, ez);
else abort(); else abort();
} }
+29 -40
View File
@@ -17,18 +17,17 @@
#ifdef KSW_CPU_DISPATCH #ifdef KSW_CPU_DISPATCH
#ifdef __SSE4_1__ #ifdef __SSE4_1__
void ksw_extd2_sse41(void *km, int qlen, const uint8_t *query, int tlen, const uint8_t *target, int8_t m, const int8_t *mat, void ksw_extd2_sse41(void *km, int qlen, const uint8_t *query, int tlen, const uint8_t *target, int8_t m, const int8_t *mat,
int8_t q, int8_t e, int8_t q2, int8_t e2, int w, int zdrop, int end_bonus, int flag, const int8_t *qd, ksw_extz_t *ez) int8_t q, int8_t e, int8_t q2, int8_t e2, int w, int zdrop, int end_bonus, int flag, ksw_extz_t *ez)
#else #else
void ksw_extd2_sse2(void *km, int qlen, const uint8_t *query, int tlen, const uint8_t *target, int8_t m, const int8_t *mat, void ksw_extd2_sse2(void *km, int qlen, const uint8_t *query, int tlen, const uint8_t *target, int8_t m, const int8_t *mat,
int8_t q, int8_t e, int8_t q2, int8_t e2, int w, int zdrop, int end_bonus, int flag, const int8_t *qd, ksw_extz_t *ez) int8_t q, int8_t e, int8_t q2, int8_t e2, int w, int zdrop, int end_bonus, int flag, ksw_extz_t *ez)
#endif #endif
#else #else
void ksw_extd2_sse(void *km, int qlen, const uint8_t *query, int tlen, const uint8_t *target, int8_t m, const int8_t *mat, void ksw_extd2_sse(void *km, int qlen, const uint8_t *query, int tlen, const uint8_t *target, int8_t m, const int8_t *mat,
int8_t q, int8_t e, int8_t q2, int8_t e2, int w, int zdrop, int end_bonus, int flag, const int8_t *qd, ksw_extz_t *ez) int8_t q, int8_t e, int8_t q2, int8_t e2, int w, int zdrop, int end_bonus, int flag, ksw_extz_t *ez)
#endif // ~KSW_CPU_DISPATCH #endif // ~KSW_CPU_DISPATCH
{ {
#define __dp_code_block1 \ #define __dp_code_block1 \
dt = _mm_load_si128(&dv[t]); \
z = _mm_load_si128(&s[t]); \ z = _mm_load_si128(&s[t]); \
xt1 = _mm_load_si128(&x[t]); /* xt1 <- x[r-1][t..t+15] */ \ xt1 = _mm_load_si128(&x[t]); /* xt1 <- x[r-1][t..t+15] */ \
tmp = _mm_srli_si128(xt1, 15); /* tmp <- x[r-1][t+15] */ \ tmp = _mm_srli_si128(xt1, 15); /* tmp <- x[r-1][t+15] */ \
@@ -51,10 +50,10 @@ void ksw_extd2_sse(void *km, int qlen, const uint8_t *query, int tlen, const uin
#define __dp_code_block2 \ #define __dp_code_block2 \
_mm_store_si128(&u[t], _mm_sub_epi8(z, vt1)); /* u[r][t..t+15] <- z - v[r-1][t-1..t+14] */ \ _mm_store_si128(&u[t], _mm_sub_epi8(z, vt1)); /* u[r][t..t+15] <- z - v[r-1][t-1..t+14] */ \
_mm_store_si128(&v[t], _mm_sub_epi8(z, ut)); /* v[r][t..t+15] <- z - u[r-1][t..t+15] */ \ _mm_store_si128(&v[t], _mm_sub_epi8(z, ut)); /* v[r][t..t+15] <- z - u[r-1][t..t+15] */ \
tmp = _mm_sub_epi8(z, _mm_add_epi8(dt, q_)); \ tmp = _mm_sub_epi8(z, q_); \
a = _mm_sub_epi8(a, tmp); \ a = _mm_sub_epi8(a, tmp); \
b = _mm_sub_epi8(b, tmp); \ b = _mm_sub_epi8(b, tmp); \
tmp = _mm_sub_epi8(z, _mm_add_epi8(dt, q2_)); \ tmp = _mm_sub_epi8(z, q2_); \
a2= _mm_sub_epi8(a2, tmp); \ a2= _mm_sub_epi8(a2, tmp); \
b2= _mm_sub_epi8(b2, tmp); b2= _mm_sub_epi8(b2, tmp);
@@ -62,8 +61,8 @@ void ksw_extd2_sse(void *km, int qlen, const uint8_t *query, int tlen, const uin
int with_cigar = !(flag&KSW_EZ_SCORE_ONLY), approx_max = !!(flag&KSW_EZ_APPROX_MAX); int with_cigar = !(flag&KSW_EZ_SCORE_ONLY), approx_max = !!(flag&KSW_EZ_APPROX_MAX);
int32_t *H = 0, H0 = 0, last_H0_t = 0; int32_t *H = 0, H0 = 0, last_H0_t = 0;
uint8_t *qr, *sf, *mem, *mem2 = 0; uint8_t *qr, *sf, *mem, *mem2 = 0;
__m128i q_, q2_, qe_, qe2_, e_, e2_, zero_, sc_mch_, sc_mis_, m1_, sc_N_; __m128i q_, q2_, qe_, qe2_, zero_, sc_mch_, sc_mis_, m1_, sc_N_;
__m128i *u, *v, *x, *y, *x2, *y2, *s, *p = 0, *dv; __m128i *u, *v, *x, *y, *x2, *y2, *s, *p = 0;
ksw_reset_extz(ez); ksw_reset_extz(ez);
if (m <= 1 || qlen <= 0 || tlen <= 0) return; if (m <= 1 || qlen <= 0 || tlen <= 0) return;
@@ -73,8 +72,6 @@ void ksw_extd2_sse(void *km, int qlen, const uint8_t *query, int tlen, const uin
zero_ = _mm_set1_epi8(0); zero_ = _mm_set1_epi8(0);
q_ = _mm_set1_epi8(q); q_ = _mm_set1_epi8(q);
q2_ = _mm_set1_epi8(q2); q2_ = _mm_set1_epi8(q2);
e_ = _mm_set1_epi8(e);
e2_ = _mm_set1_epi8(e2);
qe_ = _mm_set1_epi8(q + e); qe_ = _mm_set1_epi8(q + e);
qe2_ = _mm_set1_epi8(q2 + e2); qe2_ = _mm_set1_epi8(q2 + e2);
sc_mch_ = _mm_set1_epi8(mat[0]); sc_mch_ = _mm_set1_epi8(mat[0]);
@@ -99,23 +96,16 @@ void ksw_extd2_sse(void *km, int qlen, const uint8_t *query, int tlen, const uin
++long_thres; ++long_thres;
long_diff = long_thres * (e - e2) - (q2 - q) - e2; long_diff = long_thres * (e - e2) - (q2 - q) - e2;
mem = (uint8_t*)kcalloc(km, tlen_ * 9 + qlen_ + 1, 16); mem = (uint8_t*)kcalloc(km, tlen_ * 8 + qlen_ + 1, 16);
u = (__m128i*)(((size_t)mem + 15) >> 4 << 4); // 16-byte aligned u = (__m128i*)(((size_t)mem + 15) >> 4 << 4); // 16-byte aligned
v = u + tlen_, x = v + tlen_, y = x + tlen_, x2 = y + tlen_, y2 = x2 + tlen_, dv = y2 + tlen_; v = u + tlen_, x = v + tlen_, y = x + tlen_, x2 = y + tlen_, y2 = x2 + tlen_;
s = dv + tlen_, sf = (uint8_t*)(s + tlen_), qr = sf + tlen_ * 16; s = y2 + tlen_, sf = (uint8_t*)(s + tlen_), qr = sf + tlen_ * 16;
memset(u, -q - e, tlen_ * 16); memset(u, -q - e, tlen_ * 16);
memset(v, -q - e, tlen_ * 16); memset(v, -q - e, tlen_ * 16);
memset(x, -q - e, tlen_ * 16); memset(x, -q - e, tlen_ * 16);
memset(y, -q - e, tlen_ * 16); memset(y, -q - e, tlen_ * 16);
memset(x2, -q2 - e2, tlen_ * 16); memset(x2, -q2 - e2, tlen_ * 16);
memset(y2, -q2 - e2, tlen_ * 16); memset(y2, -q2 - e2, tlen_ * 16);
if (qd) {
int8_t *tmp = (int8_t*)dv;
for (t = 0; t < tlen; ++t) tmp[t] = -qd[t];
fprintf(stderr, "%d\t%d\t%x\n", tlen, qlen, flag&KSW_EZ_RIGHT);
for (t = 0; t < tlen; ++t) fputc("ACGTN"[target[t]], stderr); fputc('\n', stderr);
for (t = 0; t < tlen; ++t) fputc('0' + qd[t], stderr); fputc('\n', stderr);
}
if (!approx_max) { if (!approx_max) {
H = (int32_t*)kmalloc(km, tlen_ * 16 * 4); H = (int32_t*)kmalloc(km, tlen_ * 16 * 4);
for (t = 0; t < tlen_ * 16; ++t) H[t] = KSW_NEG_INF; for (t = 0; t < tlen_ * 16; ++t) H[t] = KSW_NEG_INF;
@@ -192,7 +182,7 @@ void ksw_extd2_sse(void *km, int qlen, const uint8_t *query, int tlen, const uin
assert(en_ - st_ + 1 <= n_col_); assert(en_ - st_ + 1 <= n_col_);
if (!with_cigar) { // score only if (!with_cigar) { // score only
for (t = st_; t <= en_; ++t) { for (t = st_; t <= en_; ++t) {
__m128i z, a, b, a2, b2, xt1, x2t1, vt1, ut, tmp, dt; __m128i z, a, b, a2, b2, xt1, x2t1, vt1, ut, tmp;
__dp_code_block1; __dp_code_block1;
#ifdef __SSE4_1__ #ifdef __SSE4_1__
z = _mm_max_epi8(z, a); z = _mm_max_epi8(z, a);
@@ -201,10 +191,10 @@ void ksw_extd2_sse(void *km, int qlen, const uint8_t *query, int tlen, const uin
z = _mm_max_epi8(z, b2); z = _mm_max_epi8(z, b2);
z = _mm_min_epi8(z, sc_mch_); z = _mm_min_epi8(z, sc_mch_);
__dp_code_block2; // save u[] and v[]; update a, b, a2 and b2 __dp_code_block2; // save u[] and v[]; update a, b, a2 and b2
_mm_store_si128(&x[t], _mm_sub_epi8(_mm_max_epi8(a, zero_), _mm_add_epi8(dt, qe_))); _mm_store_si128(&x[t], _mm_sub_epi8(_mm_max_epi8(a, zero_), qe_));
_mm_store_si128(&y[t], _mm_sub_epi8(_mm_max_epi8(b, zero_), _mm_add_epi8(dt, qe_))); _mm_store_si128(&y[t], _mm_sub_epi8(_mm_max_epi8(b, zero_), qe_));
_mm_store_si128(&x2[t], _mm_sub_epi8(_mm_max_epi8(a2, zero_), _mm_add_epi8(dt, qe2_))); _mm_store_si128(&x2[t], _mm_sub_epi8(_mm_max_epi8(a2, zero_), qe2_));
_mm_store_si128(&y2[t], _mm_sub_epi8(_mm_max_epi8(b2, zero_), _mm_add_epi8(dt, qe2_))); _mm_store_si128(&y2[t], _mm_sub_epi8(_mm_max_epi8(b2, zero_), qe2_));
#else #else
tmp = _mm_cmpgt_epi8(a, z); tmp = _mm_cmpgt_epi8(a, z);
z = _mm_or_si128(_mm_andnot_si128(tmp, z), _mm_and_si128(tmp, a)); z = _mm_or_si128(_mm_andnot_si128(tmp, z), _mm_and_si128(tmp, a));
@@ -218,20 +208,20 @@ void ksw_extd2_sse(void *km, int qlen, const uint8_t *query, int tlen, const uin
z = _mm_or_si128(_mm_and_si128(tmp, sc_mch_), _mm_andnot_si128(tmp, z)); z = _mm_or_si128(_mm_and_si128(tmp, sc_mch_), _mm_andnot_si128(tmp, z));
__dp_code_block2; __dp_code_block2;
tmp = _mm_cmpgt_epi8(a, zero_); tmp = _mm_cmpgt_epi8(a, zero_);
_mm_store_si128(&x[t], _mm_sub_epi8(_mm_and_si128(tmp, a), _mm_add_epi8(dt, qe_))); _mm_store_si128(&x[t], _mm_sub_epi8(_mm_and_si128(tmp, a), qe_));
tmp = _mm_cmpgt_epi8(b, zero_); tmp = _mm_cmpgt_epi8(b, zero_);
_mm_store_si128(&y[t], _mm_sub_epi8(_mm_and_si128(tmp, b), _mm_add_epi8(dt, qe_))); _mm_store_si128(&y[t], _mm_sub_epi8(_mm_and_si128(tmp, b), qe_));
tmp = _mm_cmpgt_epi8(a2, zero_); tmp = _mm_cmpgt_epi8(a2, zero_);
_mm_store_si128(&x2[t], _mm_sub_epi8(_mm_and_si128(tmp, a2), _mm_add_epi8(dt, qe2_))); _mm_store_si128(&x2[t], _mm_sub_epi8(_mm_and_si128(tmp, a2), qe2_));
tmp = _mm_cmpgt_epi8(b2, zero_); tmp = _mm_cmpgt_epi8(b2, zero_);
_mm_store_si128(&y2[t], _mm_sub_epi8(_mm_and_si128(tmp, b2), _mm_add_epi8(dt, qe2_))); _mm_store_si128(&y2[t], _mm_sub_epi8(_mm_and_si128(tmp, b2), qe2_));
#endif #endif
} }
} else if (!(flag&KSW_EZ_RIGHT)) { // gap left-alignment } else if (!(flag&KSW_EZ_RIGHT)) { // gap left-alignment
__m128i *pr = p + (size_t)r * n_col_ - st_; __m128i *pr = p + (size_t)r * n_col_ - st_;
off[r] = st, off_end[r] = en; off[r] = st, off_end[r] = en;
for (t = st_; t <= en_; ++t) { for (t = st_; t <= en_; ++t) {
__m128i d, z, a, b, a2, b2, xt1, x2t1, vt1, ut, tmp, dt; __m128i d, z, a, b, a2, b2, xt1, x2t1, vt1, ut, tmp;
__dp_code_block1; __dp_code_block1;
#ifdef __SSE4_1__ #ifdef __SSE4_1__
d = _mm_and_si128(_mm_cmpgt_epi8(a, z), _mm_set1_epi8(1)); // d = a > z? 1 : 0 d = _mm_and_si128(_mm_cmpgt_epi8(a, z), _mm_set1_epi8(1)); // d = a > z? 1 : 0
@@ -261,16 +251,16 @@ void ksw_extd2_sse(void *km, int qlen, const uint8_t *query, int tlen, const uin
#endif #endif
__dp_code_block2; __dp_code_block2;
tmp = _mm_cmpgt_epi8(a, zero_); tmp = _mm_cmpgt_epi8(a, zero_);
_mm_store_si128(&x[t], _mm_sub_epi8(_mm_and_si128(tmp, a), _mm_add_epi8(dt, qe_))); _mm_store_si128(&x[t], _mm_sub_epi8(_mm_and_si128(tmp, a), qe_));
d = _mm_or_si128(d, _mm_and_si128(tmp, _mm_set1_epi8(0x08))); // d = a > 0? 1<<3 : 0 d = _mm_or_si128(d, _mm_and_si128(tmp, _mm_set1_epi8(0x08))); // d = a > 0? 1<<3 : 0
tmp = _mm_cmpgt_epi8(b, zero_); tmp = _mm_cmpgt_epi8(b, zero_);
_mm_store_si128(&y[t], _mm_sub_epi8(_mm_and_si128(tmp, b), _mm_add_epi8(dt, qe_))); _mm_store_si128(&y[t], _mm_sub_epi8(_mm_and_si128(tmp, b), qe_));
d = _mm_or_si128(d, _mm_and_si128(tmp, _mm_set1_epi8(0x10))); // d = b > 0? 1<<4 : 0 d = _mm_or_si128(d, _mm_and_si128(tmp, _mm_set1_epi8(0x10))); // d = b > 0? 1<<4 : 0
tmp = _mm_cmpgt_epi8(a2, zero_); tmp = _mm_cmpgt_epi8(a2, zero_);
_mm_store_si128(&x2[t], _mm_sub_epi8(_mm_and_si128(tmp, a2), _mm_add_epi8(dt, qe2_))); _mm_store_si128(&x2[t], _mm_sub_epi8(_mm_and_si128(tmp, a2), qe2_));
d = _mm_or_si128(d, _mm_and_si128(tmp, _mm_set1_epi8(0x20))); // d = a > 0? 1<<5 : 0 d = _mm_or_si128(d, _mm_and_si128(tmp, _mm_set1_epi8(0x20))); // d = a > 0? 1<<5 : 0
tmp = _mm_cmpgt_epi8(b2, zero_); tmp = _mm_cmpgt_epi8(b2, zero_);
_mm_store_si128(&y2[t], _mm_sub_epi8(_mm_and_si128(tmp, b2), _mm_add_epi8(dt, qe2_))); _mm_store_si128(&y2[t], _mm_sub_epi8(_mm_and_si128(tmp, b2), qe2_));
d = _mm_or_si128(d, _mm_and_si128(tmp, _mm_set1_epi8(0x40))); // d = b > 0? 1<<6 : 0 d = _mm_or_si128(d, _mm_and_si128(tmp, _mm_set1_epi8(0x40))); // d = b > 0? 1<<6 : 0
_mm_store_si128(&pr[t], d); _mm_store_si128(&pr[t], d);
} }
@@ -278,7 +268,7 @@ void ksw_extd2_sse(void *km, int qlen, const uint8_t *query, int tlen, const uin
__m128i *pr = p + (size_t)r * n_col_ - st_; __m128i *pr = p + (size_t)r * n_col_ - st_;
off[r] = st, off_end[r] = en; off[r] = st, off_end[r] = en;
for (t = st_; t <= en_; ++t) { for (t = st_; t <= en_; ++t) {
__m128i d, z, a, b, a2, b2, xt1, x2t1, vt1, ut, tmp, dt; __m128i d, z, a, b, a2, b2, xt1, x2t1, vt1, ut, tmp;
__dp_code_block1; __dp_code_block1;
#ifdef __SSE4_1__ #ifdef __SSE4_1__
d = _mm_andnot_si128(_mm_cmpgt_epi8(z, a), _mm_set1_epi8(1)); // d = z > a? 0 : 1 d = _mm_andnot_si128(_mm_cmpgt_epi8(z, a), _mm_set1_epi8(1)); // d = z > a? 0 : 1
@@ -308,16 +298,16 @@ void ksw_extd2_sse(void *km, int qlen, const uint8_t *query, int tlen, const uin
#endif #endif
__dp_code_block2; __dp_code_block2;
tmp = _mm_cmpgt_epi8(zero_, a); tmp = _mm_cmpgt_epi8(zero_, a);
_mm_store_si128(&x[t], _mm_sub_epi8(_mm_andnot_si128(tmp, a), _mm_add_epi8(dt, qe_))); _mm_store_si128(&x[t], _mm_sub_epi8(_mm_andnot_si128(tmp, a), qe_));
d = _mm_or_si128(d, _mm_andnot_si128(tmp, _mm_set1_epi8(0x08))); // d = a > 0? 1<<3 : 0 d = _mm_or_si128(d, _mm_andnot_si128(tmp, _mm_set1_epi8(0x08))); // d = a > 0? 1<<3 : 0
tmp = _mm_cmpgt_epi8(zero_, b); tmp = _mm_cmpgt_epi8(zero_, b);
_mm_store_si128(&y[t], _mm_sub_epi8(_mm_andnot_si128(tmp, b), _mm_add_epi8(dt, qe_))); _mm_store_si128(&y[t], _mm_sub_epi8(_mm_andnot_si128(tmp, b), qe_));
d = _mm_or_si128(d, _mm_andnot_si128(tmp, _mm_set1_epi8(0x10))); // d = b > 0? 1<<4 : 0 d = _mm_or_si128(d, _mm_andnot_si128(tmp, _mm_set1_epi8(0x10))); // d = b > 0? 1<<4 : 0
tmp = _mm_cmpgt_epi8(zero_, a2); tmp = _mm_cmpgt_epi8(zero_, a2);
_mm_store_si128(&x2[t], _mm_sub_epi8(_mm_andnot_si128(tmp, a2), _mm_add_epi8(dt, qe2_))); _mm_store_si128(&x2[t], _mm_sub_epi8(_mm_andnot_si128(tmp, a2), qe2_));
d = _mm_or_si128(d, _mm_andnot_si128(tmp, _mm_set1_epi8(0x20))); // d = a > 0? 1<<5 : 0 d = _mm_or_si128(d, _mm_andnot_si128(tmp, _mm_set1_epi8(0x20))); // d = a > 0? 1<<5 : 0
tmp = _mm_cmpgt_epi8(zero_, b2); tmp = _mm_cmpgt_epi8(zero_, b2);
_mm_store_si128(&y2[t], _mm_sub_epi8(_mm_andnot_si128(tmp, b2), _mm_add_epi8(dt, qe2_))); _mm_store_si128(&y2[t], _mm_sub_epi8(_mm_andnot_si128(tmp, b2), qe2_));
d = _mm_or_si128(d, _mm_andnot_si128(tmp, _mm_set1_epi8(0x40))); // d = b > 0? 1<<6 : 0 d = _mm_or_si128(d, _mm_andnot_si128(tmp, _mm_set1_epi8(0x40))); // d = b > 0? 1<<6 : 0
_mm_store_si128(&pr[t], d); _mm_store_si128(&pr[t], d);
} }
@@ -386,7 +376,6 @@ void ksw_extd2_sse(void *km, int qlen, const uint8_t *query, int tlen, const uin
last_st = st, last_en = en; last_st = st, last_en = en;
//for (t = st0; t <= en0; ++t) printf("(%d,%d)\t(%d,%d,%d,%d)\t%d\n", r, t, ((int8_t*)u)[t], ((int8_t*)v)[t], ((int8_t*)x)[t], ((int8_t*)y)[t], H[t]); // for debugging //for (t = st0; t <= en0; ++t) printf("(%d,%d)\t(%d,%d,%d,%d)\t%d\n", r, t, ((int8_t*)u)[t], ((int8_t*)v)[t], ((int8_t*)x)[t], ((int8_t*)y)[t], H[t]); // for debugging
} }
fprintf(stderr, "score: %d\n", ez->score);
kfree(km, mem); kfree(km, mem);
if (!approx_max) kfree(km, H); if (!approx_max) kfree(km, H);
if (with_cigar) { // backtrack if (with_cigar) { // backtrack
+5 -6
View File
@@ -6,7 +6,7 @@
#include "mmpriv.h" #include "mmpriv.h"
#include "ketopt.h" #include "ketopt.h"
#define MM_VERSION "2.13-r852-dirty" #define MM_VERSION "2.14-r883"
#ifdef __linux__ #ifdef __linux__
#include <sys/resource.h> #include <sys/resource.h>
@@ -60,7 +60,7 @@ static ko_longopt_t long_options[] = {
{ "split-prefix", ko_required_argument, 334 }, { "split-prefix", ko_required_argument, 334 },
{ "no-end-flt", ko_no_argument, 335 }, { "no-end-flt", ko_no_argument, 335 },
{ "hard-mask-level",ko_no_argument, 336 }, { "hard-mask-level",ko_no_argument, 336 },
{ "bed", ko_required_argument, 337 }, { "cap-sw-mem", ko_required_argument, 337 },
{ "help", ko_no_argument, 'h' }, { "help", ko_no_argument, 'h' },
{ "max-intron-len", ko_required_argument, 'G' }, { "max-intron-len", ko_required_argument, 'G' },
{ "version", ko_no_argument, 'V' }, { "version", ko_no_argument, 'V' },
@@ -103,7 +103,7 @@ int main(int argc, char *argv[])
mm_mapopt_t opt; mm_mapopt_t opt;
mm_idxopt_t ipt; mm_idxopt_t ipt;
int i, c, n_threads = 3, n_parts, old_best_n = -1; int i, c, n_threads = 3, n_parts, old_best_n = -1;
char *fnw = 0, *fn_bed = 0, *rg = 0, *s; char *fnw = 0, *rg = 0, *s;
FILE *fp_help = stderr; FILE *fp_help = stderr;
mm_idx_reader_t *idx_rdr; mm_idx_reader_t *idx_rdr;
mm_idx_t *mi; mm_idx_t *mi;
@@ -123,7 +123,7 @@ int main(int argc, char *argv[])
fprintf(stderr, "[ERROR] missing option argument\n"); fprintf(stderr, "[ERROR] missing option argument\n");
return 1; return 1;
} else if (c == '?') { } else if (c == '?') {
fprintf(stderr, "[ERROR] unknown option in \"%s\"\n", argv[o.i]); fprintf(stderr, "[ERROR] unknown option in \"%s\"\n", argv[o.i - 1]);
return 1; return 1;
} }
} }
@@ -191,7 +191,7 @@ int main(int argc, char *argv[])
else if (c == 334) opt.split_prefix = o.arg; // --split-prefix else if (c == 334) opt.split_prefix = o.arg; // --split-prefix
else if (c == 335) opt.flag |= MM_F_NO_END_FLT; // --no-end-flt else if (c == 335) opt.flag |= MM_F_NO_END_FLT; // --no-end-flt
else if (c == 336) opt.flag |= MM_F_HARD_MLEVEL; // --hard-mask-level else if (c == 336) opt.flag |= MM_F_HARD_MLEVEL; // --hard-mask-level
else if (c == 337) fn_bed = o.arg; // --bed-prefer else if (c == 337) opt.max_sw_mat = mm_parse_num(o.arg); // --cap-sw-mat
else if (c == 314) { // --frag else if (c == 314) { // --frag
yes_or_no(&opt, MM_F_FRAG_MODE, o.longidx, o.arg, 1); yes_or_no(&opt, MM_F_FRAG_MODE, o.longidx, o.arg, 1);
} else if (c == 315) { // --secondary } else if (c == 315) { // --secondary
@@ -350,7 +350,6 @@ int main(int argc, char *argv[])
fprintf(stderr, "[M::%s::%.3f*%.2f] loaded/built the index for %d target sequence(s)\n", fprintf(stderr, "[M::%s::%.3f*%.2f] loaded/built the index for %d target sequence(s)\n",
__func__, realtime() - mm_realtime0, cputime() / (realtime() - mm_realtime0), mi->n_seq); __func__, realtime() - mm_realtime0, cputime() / (realtime() - mm_realtime0), mi->n_seq);
if (argc != o.ind + 1) mm_mapopt_update(&opt, mi); if (argc != o.ind + 1) mm_mapopt_update(&opt, mi);
if (fn_bed) mm_idx_bed_read(mi, fn_bed);
if (mm_verbose >= 3) mm_idx_stat(mi); if (mm_verbose >= 3) mm_idx_stat(mi);
if (!(opt.flag & MM_F_FRAG_MODE)) { if (!(opt.flag & MM_F_FRAG_MODE)) {
for (i = o.ind + 1; i < argc; ++i) for (i = o.ind + 1; i < argc; ++i)
+1 -13
View File
@@ -59,21 +59,13 @@ typedef struct {
uint32_t len; // length uint32_t len; // length
} mm_idx_seq_t; } mm_idx_seq_t;
typedef struct {
uint64_t x;
int32_t end, idx;
int32_t score; // NB: wasting 4 bytes due to memory alignment
} mm_idx_bed_t;
typedef struct { typedef struct {
int32_t b, w, k, flag; int32_t b, w, k, flag;
uint32_t n_seq; // number of reference sequences uint32_t n_seq; // number of reference sequences
int32_t index; int32_t index;
uint32_t n_R;
mm_idx_seq_t *seq; // sequence name, length and offset mm_idx_seq_t *seq; // sequence name, length and offset
uint32_t *S; // 4-bit packed sequence uint32_t *S; // 4-bit packed sequence
struct mm_idx_bucket_s *B; // index (hidden) struct mm_idx_bucket_s *B; // index (hidden)
mm_idx_bed_t *R;
void *km, *h; void *km, *h;
} mm_idx_t; } mm_idx_t;
@@ -147,6 +139,7 @@ typedef struct {
int32_t mid_occ; // ignore seeds with occurrences above this threshold int32_t mid_occ; // ignore seeds with occurrences above this threshold
int32_t max_occ; int32_t max_occ;
int mini_batch_size; // size of a batch of query bases to process in parallel int mini_batch_size; // size of a batch of query bases to process in parallel
int64_t max_sw_mat;
const char *split_prefix; const char *split_prefix;
} mm_mapopt_t; } mm_mapopt_t;
@@ -370,11 +363,6 @@ int mm_idx_index_name(mm_idx_t *mi);
int mm_idx_name2id(const mm_idx_t *mi, const char *name); int mm_idx_name2id(const mm_idx_t *mi, const char *name);
int mm_idx_getseq(const mm_idx_t *mi, uint32_t rid, uint32_t st, uint32_t en, uint8_t *seq); int mm_idx_getseq(const mm_idx_t *mi, uint32_t rid, uint32_t st, uint32_t en, uint8_t *seq);
// BED operations
int mm_idx_bed_read(mm_idx_t *mi, const char *fn);
int mm_idx_bed_attach(mm_idx_t *mi, uint32_t n, mm_idx_bed_t *r);
int mm_idx_bed_query(const mm_idx_t *mi, uint64_t x);
// deprecated APIs for backward compatibility // deprecated APIs for backward compatibility
void mm_mapopt_init(mm_mapopt_t *opt); void mm_mapopt_init(mm_mapopt_t *opt);
mm_idx_t *mm_idx_build(const char *fn, int w, int k, int flag, int n_threads); mm_idx_t *mm_idx_build(const char *fn, int w, int k, int flag, int n_threads);
+11 -2
View File
@@ -1,4 +1,4 @@
.TH minimap2 1 "11 October 2018" "minimap2-2.13 (r850)" "Bioinformatics tools" .TH minimap2 1 "5 November 2018" "minimap2-2.14 (r883)" "Bioinformatics tools"
.SH NAME .SH NAME
.PP .PP
minimap2 - mapping and alignment between collections of DNA sequences minimap2 - mapping and alignment between collections of DNA sequences
@@ -274,6 +274,10 @@ Only map to the reverse complement strand of the reference sequences.
.BR --heap-sort = no | yes .BR --heap-sort = no | yes
If yes, sort anchors with heap merge, instead of radix sort. Heap merge is If yes, sort anchors with heap merge, instead of radix sort. Heap merge is
faster for short reads, but slower for long reads. [no] faster for short reads, but slower for long reads. [no]
.TP
.B --no-pairing
Treat two reads in a pair as independent reads. The mate related fields in SAM
are still properly populated.
.SS Alignment options .SS Alignment options
.TP 10 .TP 10
.BI -A \ INT .BI -A \ INT
@@ -369,6 +373,11 @@ It helps to avoid tiny terminal exons. [6]
.B --no-end-flt .B --no-end-flt
Don't filter seeds towards the ends of chains before performing base-level Don't filter seeds towards the ends of chains before performing base-level
alignment. alignment.
.TP
.BI --cap-sw-mem \ NUM
Skip alignment if the DP matrix size is above
.IR NUM .
Set 0 to disable [0].
.SS Input/output options .SS Input/output options
.TP 10 .TP 10
.B -a .B -a
@@ -493,7 +502,7 @@ Up to 10% sequence divergence.
.B asm20 .B asm20
Long assembly to reference mapping Long assembly to reference mapping
.RB ( -k19 .RB ( -k19
.B -w10 -A1 -B6 -O6,26 -E2,1 -s200 -z200 .B -w10 -A1 -B4 -O6,26 -E2,1 -s200 -z200
.BR --min-occ-floor=100 ). .BR --min-occ-floor=100 ).
Up to 20% sequence divergence. Up to 20% sequence divergence.
.TP .TP
+1 -2
View File
@@ -116,8 +116,7 @@ long peakrss(void)
double realtime(void) double realtime(void)
{ {
struct timeval tp; struct timeval tp;
struct timezone tzp; gettimeofday(&tp, NULL);
gettimeofday(&tp, &tzp);
return tp.tv_sec + tp.tv_usec * 1e-6; return tp.tv_sec + tp.tv_usec * 1e-6;
} }
+168 -12
View File
@@ -1,6 +1,6 @@
#!/usr/bin/env k8 #!/usr/bin/env k8
var paftools_version = '2.13-r850'; var paftools_version = '2.14-r883';
/***************************** /*****************************
***** Library functions ***** ***** Library functions *****
@@ -564,10 +564,12 @@ function paf_call(args)
function paf_asmstat(args) function paf_asmstat(args)
{ {
var c, min_seg_len = 10000, max_diff = 0.01; var c, min_seg_len = 10000, max_diff = 0.01, bp_flank_len = 0, bp_gap_len = 0;
while ((c = getopt(args, "l:d:")) != null) { while ((c = getopt(args, "l:d:b:g:")) != null) {
if (c == 'l') min_seg_len = parseInt(getopt.arg); if (c == 'l') min_seg_len = parseInt(getopt.arg);
else if (c == 'd') max_diff = parseFloat(getopt.arg); else if (c == 'd') max_diff = parseFloat(getopt.arg);
else if (c == 'b') bp_flank_len = parseInt(getopt.arg);
else if (c == 'g') bp_gap_len = parseInt(getopt.arg);
} }
if (getopt.ind == args.length) { if (getopt.ind == args.length) {
print("Usage: paftools.js asmstat [options] <ref.fa.fai> <asm1.paf> [...]"); print("Usage: paftools.js asmstat [options] <ref.fa.fai> <asm1.paf> [...]");
@@ -587,7 +589,7 @@ function paf_asmstat(args)
} }
file.close(); file.close();
function process_query(qblocks, qblock_len, bp) { function process_query(qblocks, qblock_len, bp, qi) {
qblocks.sort(function(a,b) { return a[0]-b[0]; }); qblocks.sort(function(a,b) { return a[0]-b[0]; });
var last_k = null, last_blen = null, st = -1, en = -1, qcov = 0; var last_k = null, last_blen = null, st = -1, en = -1, qcov = 0;
for (var k = 0; k < qblocks.length; ++k) { for (var k = 0; k < qblocks.length; ++k) {
@@ -612,6 +614,7 @@ function paf_asmstat(args)
var min = blen < last_blen? blen : last_blen; var min = blen < last_blen? blen : last_blen;
var flank = k == 0? min : blen; var flank = k == 0? min : blen;
bp.push([flank, gap]); bp.push([flank, gap]);
qi.bp.push([flank, gap]);
} }
last_k = k, last_blen = blen; last_k = k, last_blen = blen;
} }
@@ -664,16 +667,22 @@ function paf_asmstat(args)
for (var i = 0; i < n_asm; ++i) { for (var i = 0; i < n_asm; ++i) {
var n_breaks = 0, qcov = 0; var n_breaks = 0, qcov = 0;
var fn = args[getopt.ind + 1 + i]; var fn = args[getopt.ind + 1 + i];
header.push(fn.replace(/.paf(.gz)?$/, "")); var label = fn.replace(/.paf(.gz)?$/, "");
header.push(label);
var ref_blocks = [], qblock_len = [], qblocks = [], bp = []; var ref_blocks = [], qblock_len = [], qblocks = [], bp = [];
var query = {}; var query = {}, qinfo = {};
var last_qname = null; var last_qname = null;
file = new File(fn); file = new File(fn);
while (file.readline(buf) >= 0) { while (file.readline(buf) >= 0) {
var m, line = buf.toString(); var m, line = buf.toString();
var t = line.split("\t"); var t = line.split("\t");
t[1] = parseInt(t[1]); t[1] = parseInt(t[1]);
if (t.length >= 2) query[t[0]] = t[1]; if (t.length >= 2) {
query[t[0]] = t[1];
if (qinfo[t[0]] == null) qinfo[t[0]] = {};
qinfo[t[0]].len = t[1];
qinfo[t[0]].bp = [];
}
if (t.length < 9) continue; if (t.length < 9) continue;
if (!/\ttp:A:[PI]/.test(line)) continue; if (!/\ttp:A:[PI]/.test(line)) continue;
if ((m = /\tcg:Z:(\S+)/.exec(line)) == null) continue; if ((m = /\tcg:Z:(\S+)/.exec(line)) == null) continue;
@@ -690,7 +699,7 @@ function paf_asmstat(args)
if (t[3] - t[2] < min_seg_len) continue; if (t[3] - t[2] < min_seg_len) continue;
if (t[0] != last_qname) { if (t[0] != last_qname) {
if (last_qname != null) if (last_qname != null)
qcov += process_query(qblocks, qblock_len, bp); qcov += process_query(qblocks, qblock_len, bp, qinfo[last_qname]);
qblocks = []; qblocks = [];
last_qname = t[0]; last_qname = t[0];
} }
@@ -698,7 +707,7 @@ function paf_asmstat(args)
qblocks.push([t[2], t[3], t[4], t[5], t[7], t[8]]); qblocks.push([t[2], t[3], t[4], t[5], t[7], t[8]]);
} }
if (last_qname != null) if (last_qname != null)
qcov += process_query(qblocks, qblock_len, bp); qcov += process_query(qblocks, qblock_len, bp, qinfo[last_qname]);
file.close(); file.close();
// compute NG50 // compute NG50
@@ -733,12 +742,157 @@ function paf_asmstat(args)
rst[5][i] = n_breaks; rst[5][i] = n_breaks;
rst[6][i] = count_bp(bp, 500, 0); rst[6][i] = count_bp(bp, 500, 0);
rst[7][i] = count_bp(bp, 500, 10000); rst[7][i] = count_bp(bp, 500, 10000);
// nb-plot
var qa = [];
for (var qn in qinfo)
qa.push([qinfo[qn].len, qinfo[qn].bp]);
qa = qa.sort(function(a, b) { return b[0] - a[0] });
var sum = 0, n_bp = 0, next_quantile = 0.1;
for (var j = 0; j < qa.length; ++j) {
sum += qa[j][0];
for (var k = 0; k < qa[j][1].length; ++k)
if (qa[j][1][k][0] >= bp_flank_len && qa[j][1][k][1] >= bp_gap_len)
++n_bp;
if (sum >= ref_len * next_quantile) {
print(label, Math.floor(next_quantile * 100 + .5), qa[j][0], (sum / n_bp).toFixed(0), n_bp);
next_quantile += 0.1;
if (next_quantile >= 1.0) break;
}
}
}
buf.destroy();
if (bp_flank_len <= 0) {
print(header.join("\t"));
for (var i = 0; i < labels.length; ++i)
print(labels[i], rst[i].join("\t"));
}
}
function paf_asmgene(args)
{
var c, opt = { min_cov:0.99, min_iden:0.99 }, print_err = false;
while ((c = getopt(args, "i:c:e")) != null)
if (c == 'i') opt.min_iden = parseFloat(getopt.arg);
else if (c == 'c') opt.min_cov = parseFloat(getopt.arg);
else if (c == 'e') print_err = true;
var n_fn = args.length - getopt.ind;
if (n_fn < 2) {
print("Usage: paftools.js asmgene [options] <ref-splice.paf> <asm-splice.paf> [...]");
print("Options:");
print(" -i FLOAT min identity [" + opt.min_iden + "]");
print(" -c FLOAT min coverage [" + opt.min_cov + "]");
print(" -e print fragmented/missing genes");
exit(1);
} }
print(header.join("\t")); function process_query(opt, a) {
for (var i = 0; i < labels.length; ++i) var b = [], cnt = [0, 0, 0];
print(labels[i], rst[i].join("\t")); for (var j = 0; j < a.length; ++j) {
if (a[j][4] < a[j][5] * opt.min_iden)
continue;
b.push(a[j].slice(0));
}
if (b.length == 0) return cnt;
// count full
var n_full = 0;
for (var j = 0; j < b.length; ++j)
if (b[j][3] - b[j][2] >= b[j][1] * opt.min_cov)
++n_full;
cnt[0] = n_full;
// compute coverage
b = b.sort(function(x, y) { return x[2] - y[2] });
var l_cov = 0, st = b[0][2], en = b[0][3];
for (var j = 1; j < b.length; ++j) {
if (b[j][2] <= en)
en = b[j][3] > en? b[j][3] : en;
else l_cov += en - st;
}
l_cov += en - st;
cnt[1] = l_cov / b[0][1];
cnt[2] = b.length;
return cnt;
}
var buf = new Bytes();
var gene = {}, header = [], refpos = {};
for (var i = getopt.ind; i < args.length; ++i) {
var fn = args[i];
var label = fn.replace(/.paf(.gz)?$/, "");
header.push(label);
var file = new File(fn), a = [];
while (file.readline(buf) >= 0) {
var t = buf.toString().split("\t");
var ql = parseInt(t[1]), qs = parseInt(t[2]), qe = parseInt(t[3]), mlen = parseInt(t[9]), blen = parseInt(t[10]), mapq = parseInt(t[11]);
if (i == getopt.ind) refpos[t[0]] = [t[0], t[1], t[5], t[7], t[8]];
if (gene[t[0]] == null) gene[t[0]] = [];
if (a.length && t[0] != a[0][0]) {
gene[t[0]][i - getopt.ind] = process_query(opt, a);
a = [];
}
a.push([t[0], ql, qs, qe, mlen, blen]);
}
if (a.length)
gene[t[0]][i - getopt.ind] = process_query(opt, a);
file.close();
}
// select the longest genes (not optimal, but should be good enough)
var gene_list = [], gene_nr = {};
for (var g in refpos)
gene_list.push(refpos[g]);
gene_list = gene_list.sort(function(a, b) { return a[2] < b[2]? -1 : a[2] > b[2]? 1 : a[3] - b[3] });
var last = 0;
for (var j = 1; j < gene_list.length; ++j) {
if (gene_list[j][2] != gene_list[last][2] || gene_list[j][3] >= gene_list[last][4]) {
gene_nr[gene_list[last][0]] = 1;
last = j;
} else if (gene_list[j][1] > gene_list[last][1]) {
last = j;
}
}
gene_nr[gene_list[last][0]] = 1;
// count and print
var col1 = ["full_sgl", "full_dup", "frag", "part50+", "part10+", "part10-"];
var rst = [];
for (var k = 0; k < col1.length; ++k) {
rst[k] = [];
for (var i = 0; i < n_fn; ++i)
rst[k][i] = 0;
}
for (var g in gene) {
if (gene[g][0] == null || gene[g][0][0] != 1) continue;
if (gene_nr[g] == null) continue;
for (var i = 0; i < n_fn; ++i) {
if (gene[g][i] == null) {
rst[4][i]++;
if (print_err) print('M', header[i], refpos[g].join("\t"));
} else if (gene[g][i][0] == 1) rst[0][i]++;
else if (gene[g][i][0] > 1) {
rst[1][i]++;
if (print_err) print('D', header[i], refpos[g].join("\t"));
} else if (gene[g][i][1] >= opt.min_cov) {
rst[2][i]++;
if (print_err) print('F', header[i], refpos[g].join("\t"));
} else if (gene[g][i][1] >= 0.5) {
rst[3][i]++;
if (print_err) print('5', header[i], refpos[g].join("\t"));
} else if (gene[g][i][1] >= 0.1) {
rst[4][i]++;
if (print_err) print('1', header[i], refpos[g].join("\t"));
} else {
rst[5][i]++;
if (print_err) print('0', header[i], refpos[g].join("\t")); // TODO: reduce code duplicates...
}
}
}
print('H', 'Metric', header.join("\t"));
for (var k = 0; k < rst.length; ++k) {
print('X', col1[k], rst[k].join("\t"));
}
buf.destroy(); buf.destroy();
} }
@@ -2189,6 +2343,7 @@ function main(args)
print(""); print("");
print(" stat collect basic mapping information in PAF/SAM"); print(" stat collect basic mapping information in PAF/SAM");
print(" asmstat collect basic assembly information"); print(" asmstat collect basic assembly information");
print(" asmgene evaluate gene completeness (EXPERIMENTAL)");
print(" liftover simplistic liftOver"); print(" liftover simplistic liftOver");
print(" call call variants from asm-to-ref alignment with the cs tag"); print(" call call variants from asm-to-ref alignment with the cs tag");
print(" bedcov compute the number of bases covered"); print(" bedcov compute the number of bases covered");
@@ -2210,6 +2365,7 @@ function main(args)
else if (cmd == 'gff2bed') paf_gff2bed(args); else if (cmd == 'gff2bed') paf_gff2bed(args);
else if (cmd == 'stat') paf_stat(args); else if (cmd == 'stat') paf_stat(args);
else if (cmd == 'asmstat') paf_asmstat(args); else if (cmd == 'asmstat') paf_asmstat(args);
else if (cmd == 'asmgene') paf_asmgene(args);
else if (cmd == 'liftover' || cmd == 'liftOver') paf_liftover(args); else if (cmd == 'liftover' || cmd == 'liftOver') paf_liftover(args);
else if (cmd == 'call') paf_call(args); else if (cmd == 'call') paf_call(args);
else if (cmd == 'mapeval') paf_mapeval(args); else if (cmd == 'mapeval') paf_mapeval(args);
-8
View File
@@ -31,13 +31,6 @@
#define MALLOC(type, len) ((type*)malloc((len) * sizeof(type))) #define MALLOC(type, len) ((type*)malloc((len) * sizeof(type)))
#define CALLOC(type, len) ((type*)calloc((len), sizeof(type))) #define CALLOC(type, len) ((type*)calloc((len), sizeof(type)))
#define REALLOC(ptr, len) ((ptr) = (__typeof__(ptr))realloc((ptr), (len) * sizeof(*(ptr))))
#define EXPAND(a, m) do { \
(m) = (m)? (m) + ((m)>>1) : 16; \
REALLOC((a), (m)); \
} while (0)
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@@ -74,7 +67,6 @@ void mm_write_sam2(kstring_t *s, const mm_idx_t *mi, const mm_bseq1_t *t, int se
void mm_idxopt_init(mm_idxopt_t *opt); void mm_idxopt_init(mm_idxopt_t *opt);
const uint64_t *mm_idx_get(const mm_idx_t *mi, uint64_t minier, int *n); 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); int32_t mm_idx_cal_max_occ(const mm_idx_t *mi, float f);
int mm_idx_getseq2(const mm_idx_t *mi, uint32_t rid, uint32_t st, uint32_t en, uint8_t *seq, int8_t *b);
mm128_t *mm_chain_dp(int max_dist_x, int max_dist_y, int bw, int max_skip, int min_cnt, int min_sc, int is_cdna, int n_segs, int64_t n, mm128_t *a, int *n_u_, uint64_t **_u, void *km); mm128_t *mm_chain_dp(int max_dist_x, int max_dist_y, int bw, int max_skip, int min_cnt, int min_sc, int is_cdna, int n_segs, int64_t n, mm128_t *a, int *n_u_, uint64_t **_u, void *km);
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_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);
+5
View File
@@ -159,6 +159,11 @@ int mm_check_opt(const mm_idxopt_t *io, const mm_mapopt_t *mo)
fprintf(stderr, "[ERROR]\033[1;31m --for-only and --rev-only can't be applied at the same time\033[0m\n"); fprintf(stderr, "[ERROR]\033[1;31m --for-only and --rev-only can't be applied at the same time\033[0m\n");
return -3; return -3;
} }
if (mo->e <= 0 || mo->q <= 0) {
if (mm_verbose >= 1)
fprintf(stderr, "[ERROR]\033[1;31m -O and -E must be positive\033[0m\n");
return -1;
}
if ((mo->q != mo->q2 || mo->e != mo->e2) && !(mo->e > mo->e2 && mo->q + mo->e < mo->q2 + mo->e2)) { if ((mo->q != mo->q2 || mo->e != mo->e2) && !(mo->e > mo->e2 && mo->q + mo->e < mo->q2 + mo->e2)) {
if (mm_verbose >= 1) if (mm_verbose >= 1)
fprintf(stderr, "[ERROR]\033[1;31m dual gap penalties violating E1>E2 and O1+E1<O2+E2\033[0m\n"); fprintf(stderr, "[ERROR]\033[1;31m dual gap penalties violating E1>E2 and O1+E1<O2+E2\033[0m\n");
+1 -1
View File
@@ -54,7 +54,7 @@ void mm_set_pe_thru(const int *qlens, int *n_regs, mm_reg1_t **regs)
if (n_pri[0] == 1 && n_pri[1] == 1) { if (n_pri[0] == 1 && n_pri[1] == 1) {
mm_reg1_t *p = &regs[0][pri[0]]; mm_reg1_t *p = &regs[0][pri[0]];
mm_reg1_t *q = &regs[1][pri[1]]; mm_reg1_t *q = &regs[1][pri[1]];
if (p->rid == q->rid && p->rev == q->rev && abs(p->rs - q->rs) < 3 && abs(p->re - p->re) < 3 if (p->rid == q->rid && p->rev == q->rev && abs(p->rs - q->rs) < 3 && abs(p->re - q->re) < 3
&& ((p->qs == 0 && qlens[1] - q->qe == 0) || (q->qs == 0 && qlens[0] - p->qe == 0))) && ((p->qs == 0 && qlens[1] - q->qe == 0) || (q->qs == 0 && qlens[0] - p->qe == 0)))
{ {
p->pe_thru = q->pe_thru = 1; p->pe_thru = q->pe_thru = 1;
-34
View File
@@ -20,11 +20,6 @@ typedef struct {
uint32_t *cigar32; uint32_t *cigar32;
} mm_hitpy_t; } mm_hitpy_t;
typedef struct {
int32_t n, m;
mm_idx_bed_t *r;
} mm_bedpy_t;
static inline void mm_reg2hitpy(const mm_idx_t *mi, mm_reg1_t *r, mm_hitpy_t *h) static inline void mm_reg2hitpy(const mm_idx_t *mi, mm_reg1_t *r, mm_hitpy_t *h)
{ {
h->ctg = mi->seq[r->rid].name; h->ctg = mi->seq[r->rid].name;
@@ -154,33 +149,4 @@ static mm_idx_t *mappy_idx_seq(int w, int k, int is_hpc, int bucket_bits, const
return mi; return mi;
} }
static mm_bedpy_t *mappy_bed_new(void)
{
return (mm_bedpy_t*)calloc(1, sizeof(mm_bedpy_t));
}
static int mappy_bed_add(mm_bedpy_t *bed, mm_idx_t *mi, const char *name, uint32_t st, uint32_t en)
{
mm_idx_bed_t *b;
int id;
if (mi->h == 0) mm_idx_index_name(mi);
if (bed->n == bed->m) {
bed->m = bed->m? bed->m + (bed->m>>1) : 16;
bed->r = (mm_idx_bed_t*)realloc(bed->r, sizeof(mm_idx_bed_t) * bed->m);
}
id = mm_idx_name2id(mi, name);
if (id < 0 || st >= en) return -1;
if (en > mi->seq[id].len) en = mi->seq[id].len;
b = &bed->r[bed->n++];
b->x = (uint64_t)id << 32 | st;
b->end = en, b->idx = -1;
return 0;
}
static void mappy_bed_finalize(mm_bedpy_t *bed, mm_idx_t *mi)
{
mm_idx_bed_attach(mi, bed->n, bed->r); // bed->r is now owned by mi and will be deallocated with it
free(bed);
}
#endif #endif
+1 -13
View File
@@ -40,6 +40,7 @@ cdef extern from "minimap.h":
int32_t mid_occ int32_t mid_occ
int32_t max_occ int32_t max_occ
int mini_batch_size int mini_batch_size
int64_t max_sw_mat
const char *split_prefix const char *split_prefix
int mm_set_opt(char *preset, mm_idxopt_t *io, mm_mapopt_t *mo) int mm_set_opt(char *preset, mm_idxopt_t *io, mm_mapopt_t *mo)
@@ -53,10 +54,6 @@ cdef extern from "minimap.h":
uint64_t offset uint64_t offset
uint32_t len uint32_t len
ctypedef struct mm_idx_bed_t:
uint64_t x
int32_t end, idx
ctypedef struct mm_idx_bucket_t: ctypedef struct mm_idx_bucket_t:
pass pass
@@ -66,7 +63,6 @@ cdef extern from "minimap.h":
mm_idx_seq_t *seq mm_idx_seq_t *seq
uint32_t *S uint32_t *S
mm_idx_bucket_t *B mm_idx_bucket_t *B
mm_idx_bed_t *R
void *km void *km
void *h void *h
@@ -117,14 +113,6 @@ cdef extern from "cmappy.h":
char *mappy_fetch_seq(const mm_idx_t *mi, const char *name, int st, int en, int *l) char *mappy_fetch_seq(const mm_idx_t *mi, const char *name, int st, int en, int *l)
mm_idx_t *mappy_idx_seq(int w, int k, int is_hpc, int bucket_bits, const char *seq, int l) mm_idx_t *mappy_idx_seq(int w, int k, int is_hpc, int bucket_bits, const char *seq, int l)
ctypedef struct mm_bedpy_t:
int32_t n, m
mm_idx_bed_t *r
mm_bedpy_t *mappy_bed_new()
int mappy_bed_add(mm_bedpy_t *bed, mm_idx_t *mi, const char *name, uint32_t st, uint32_t en)
void mappy_bed_finalize(mm_bedpy_t *bed, mm_idx_t *mi)
ctypedef struct kstring_t: ctypedef struct kstring_t:
unsigned l, m unsigned l, m
char *s char *s
+2 -11
View File
@@ -3,7 +3,7 @@ from libc.stdlib cimport free
cimport cmappy cimport cmappy
import sys import sys
__version__ = '2.13' __version__ = '2.14'
cmappy.mm_reset_timer() cmappy.mm_reset_timer()
@@ -112,7 +112,7 @@ cdef class Aligner:
cdef cmappy.mm_idxopt_t idx_opt cdef cmappy.mm_idxopt_t idx_opt
cdef cmappy.mm_mapopt_t map_opt cdef cmappy.mm_mapopt_t map_opt
def __cinit__(self, fn_idx_in=None, preset=None, k=None, w=None, min_cnt=None, min_chain_score=None, min_dp_score=None, bw=None, best_n=None, n_threads=3, fn_idx_out=None, max_frag_len=None, extra_flags=None, seq=None, scoring=None, bed=None): def __cinit__(self, fn_idx_in=None, preset=None, k=None, w=None, min_cnt=None, min_chain_score=None, min_dp_score=None, bw=None, best_n=None, n_threads=3, fn_idx_out=None, max_frag_len=None, extra_flags=None, seq=None, scoring=None):
cmappy.mm_set_opt(NULL, &self.idx_opt, &self.map_opt) # set the default options cmappy.mm_set_opt(NULL, &self.idx_opt, &self.map_opt) # set the default options
if preset is not None: if preset is not None:
cmappy.mm_set_opt(str.encode(preset), &self.idx_opt, &self.map_opt) # apply preset cmappy.mm_set_opt(str.encode(preset), &self.idx_opt, &self.map_opt) # apply preset
@@ -137,7 +137,6 @@ cdef class Aligner:
self.map_opt.sc_ambi = scoring[6] self.map_opt.sc_ambi = scoring[6]
cdef cmappy.mm_idx_reader_t *r; cdef cmappy.mm_idx_reader_t *r;
cdef cmappy.mm_bedpy_t *bed_agg;
if seq is None: if seq is None:
if fn_idx_out is None: if fn_idx_out is None:
@@ -154,14 +153,6 @@ cdef class Aligner:
cmappy.mm_mapopt_update(&self.map_opt, self._idx) cmappy.mm_mapopt_update(&self.map_opt, self._idx)
self.map_opt.mid_occ = 1000 # don't filter high-occ seeds self.map_opt.mid_occ = 1000 # don't filter high-occ seeds
if bed is not None:
bed_agg = cmappy.mappy_bed_new()
for b in bed:
if len(b) < 3: en = int(b[1]) + 1
else: en = int(b[2])
cmappy.mappy_bed_add(bed_agg, self._idx, str.encode(b[0]), int(b[1]), en)
cmappy.mappy_bed_finalize(bed_agg, self._idx)
def __dealloc__(self): def __dealloc__(self):
if self._idx is not NULL: if self._idx is not NULL:
cmappy.mm_idx_destroy(self._idx) cmappy.mm_idx_destroy(self._idx)
+1 -1
View File
@@ -33,7 +33,7 @@ def readme():
setup( setup(
name = 'mappy', name = 'mappy',
version = '2.13', version = '2.14',
url = 'https://github.com/lh3/minimap2', url = 'https://github.com/lh3/minimap2',
description = 'Minimap2 python binding', description = 'Minimap2 python binding',
long_description = readme(), long_description = readme(),