Compare commits

...
34 Commits
Author SHA1 Message Date
Heng Li 0517972d02 Release minimap2-2.11 (r797) 2018-06-21 00:04:08 -04:00
Heng Li d46e68e6ad r796: don't use ssize_t 2018-06-20 12:45:27 -04:00
Heng Li 2584a4149a r295: use -r2000 for ava-ont, NOT for ava-pb 2018-06-20 12:24:43 -04:00
Heng Li 66674afd09 r794: fixed a bug in seed filtering 2018-06-20 10:26:29 -04:00
Heng Li e9ca0c9dab added __version__; resolved #165
Not sure if this is the right way. Apparently working.
2018-06-19 15:40:26 -04:00
Heng Li 7e6e8ca73f r792: fixed -Wextra warnings and resolved #184 2018-06-19 15:26:58 -04:00
Ilya Kolpakov 408e098859 fix deserialization of zero-length reference names 2018-06-19 14:46:05 -04:00
Ilya Kolpakov 57f37551f8 expose mm_idx_is_idx, mm_idx_load and mm_idx_dump 2018-06-19 14:46:05 -04:00
Ilya Kolpakov 4c66b689c3 fix serialization of empty names in mm_idx_dump 2018-06-19 14:46:05 -04:00
mvdbeek 1bde2cf076 Allow setting max_frag_len on a per alignment level 2018-06-19 14:39:30 -04:00
mvdbeek 31fc0f218a Allow setting max_frag_len parameter in Aligner class 2018-06-19 14:39:30 -04:00
Aaron Wenger 3d3bcc29a8 Fix CIGAR reallocation with --eqx
Fix the logic that calculates the number of CIGAR entries when
match "M" entries are expanded into "=" and "X".  The number
of entries depends not on the number of mismatches but rather
on the number of transitions between "=" to "X".
2018-06-19 14:37:41 -04:00
Hasindu Gamaarachchi 99dcd75f64 added support for 64 bit ARM architectures 2018-06-19 14:28:45 -04:00
Heng Li 154d2caf5b r784: support the =/X CIGAR operators (#156) 2018-05-30 16:11:22 -04:00
Heng Li a3afeec0b2 r783: reverted to r781 (#155) 2018-05-30 15:25:34 -04:00
Heng Li 3573784b4d r782: no mask a chain having long ref ovlp (#155) 2018-05-30 13:53:45 -04:00
Heng Li 872f300955 r781: fixed the buggy heapmerge (resolves #166) 2018-05-30 11:55:14 -04:00
Heng Li d7b61a039e updated citation 2018-05-30 11:11:55 -04:00
Heng Li 248158a3e1 Resolved #168: citing the manpage for cs 2018-05-30 11:03:16 -04:00
Heng Li 9f4309c376 r777: avoid skipping too many seeds 2018-05-11 10:25:18 -04:00
Heng Li 463f9309f9 Merge branch 'hot-fix' into fix-long-gap 2018-05-11 10:13:19 -04:00
Heng Li abe989e355 the previous fix on int overflow is incomplete 2018-05-11 10:12:57 -04:00
Heng Li 881b4ca3a2 r774: Merge branch 'hot-fix' into fix-long-gap 2018-05-11 10:02:17 -04:00
Heng Li 10c6dd2551 r773: fixed an integer overflow 2018-05-11 10:01:23 -04:00
Heng Li 7ec6721c44 r772: option -Y not working 2018-05-11 10:00:11 -04:00
Heng Li e61812ee55 reduced gap len to trigger bad seed filtering 2018-05-01 16:17:21 -04:00
Heng Li 734ac379bb r770: matching N bases not working properly (#155) 2018-04-30 19:55:23 -04:00
Heng Li 759f8e4ac9 r769: filter out seeds breaking long gaps 2018-04-24 15:37:37 -04:00
Heng Li aef7b0744c r768: shortened preset; added dv tag (#25)
Also added asm20 to command line help (#151)
2018-04-24 12:48:54 -04:00
Heng Li 39f836eac8 r767: don't crash when there is no "cg" (#153) 2018-04-24 12:32:37 -04:00
Heng Li cbeb86dad6 Merge remote-tracking branch 'origin/master' 2018-04-10 09:12:26 -04:00
Heng Li 372c90ceb5 r764: fixed incorrect inversion mapq (#148) 2018-04-10 09:11:49 -04:00
apregier 2e2e69107c Small bugfix for paftools.js
The bug resulted in the wrong coverage being printed in some cases.
2018-04-04 16:29:54 -04:00
Heng Li ee4cd089f7 r763: fine control long join flank len (#128) 2018-03-29 14:16:58 -04:00
26 changed files with 413 additions and 150 deletions
+8 -4
View File
@@ -1,4 +1,4 @@
CFLAGS= -g -Wall -O2 -Wc++-compat CFLAGS= -g -Wall -O2 -Wc++-compat #-Wextra
CPPFLAGS= -DHAVE_KALLOC CPPFLAGS= -DHAVE_KALLOC
INCLUDES= INCLUDES=
OBJS= kthread.o kalloc.o misc.o bseq.o sketch.o sdust.o options.o index.o chain.o align.o hit.o map.o format.o pe.o esterr.o ksw2_ll_sse.o OBJS= kthread.o kalloc.o misc.o bseq.o sketch.o sdust.o options.o index.o chain.o align.o hit.o map.o format.o pe.o esterr.o ksw2_ll_sse.o
@@ -12,10 +12,14 @@ ifeq ($(sse2only),) # if sse2only is not defined
else # if sse2only is defined else # if sse2only is defined
OBJS+=ksw2_extz2_sse.o ksw2_extd2_sse.o ksw2_exts2_sse.o OBJS+=ksw2_extz2_sse.o ksw2_extd2_sse.o ksw2_exts2_sse.o
endif endif
else # if arm_neon is defined else # if arm_neon is defined
OBJS+=ksw2_extz2_neon.o ksw2_extd2_neon.o ksw2_exts2_neon.o OBJS+=ksw2_extz2_neon.o ksw2_extd2_neon.o ksw2_exts2_neon.o
CFLAGS+=-D_FILE_OFFSET_BITS=64 -mfpu=neon -fsigned-char
INCLUDES+=-Isse2neon INCLUDES+=-Isse2neon
ifeq ($(aarch64),) #if aarch64 is not defined
CFLAGS+=-D_FILE_OFFSET_BITS=64 -mfpu=neon -fsigned-char
else #if aarch64 is defined
CFLAGS+=-D_FILE_OFFSET_BITS=64 -fsigned-char
endif
endif endif
.PHONY:all extra clean depend .PHONY:all extra clean depend
+55
View File
@@ -1,3 +1,58 @@
Release 2.11-r797 (20 June 2018)
--------------------------------
Changes to minimap2:
* Improved alignment accuracy in low-complexity regions for SV calling. Thank
@armintoepfer for multiple offline examples.
* Added option --eqx to encode sequence match/mismatch with the =/X CIGAR
operators (#156, #157 and #175).
* When compiled with VC++, minimap2 generated wrong alignments due to a
comparison between a signed integer and an unsigned integer (#184). Also
fixed warnings reported by "clang -Wextra".
* Fixed incorrect anchor filtering due to a missing 64- to 32-bit cast.
* Fixed incorrect mapping quality for inversions (#148).
* Fixed incorrect alignment involving ambiguous bases (#155).
* Fixed incorrect presets: option `-r 2000` is intended to be used with
ava-ont, not ava-pb. The bug was introduced in 2.10.
* Fixed a bug when --for-only/--rev-only is used together with --sr or
--heap-sort=yes (#166).
* Fixed option -Y that was not working in the previous releases.
* Added option --lj-min-ratio to fine control the alignment of long gaps
found by the "long-join" heuristic (#128).
* Exposed `mm_idx_is_idx`, `mm_idx_load` and `mm_idx_dump` C APIs (#177).
Also fixed a bug when indexing without reference names (this feature is not
exposed to the command line).
Changes to mappy:
* Added `__version__` (#165).
* Exposed the maximum fragment length parameter to mappy (#174).
Changes to paftools:
* Don't crash when there is no "cg" tag (#153).
* Fixed wrong coverage report by "paftools.js call" (#145).
This version may produce slightly different base-level alignment. The overall
alignment statistics should remain similar.
(2.11: 20 June 2018, r797)
Release 2.10-r761 (27 March 2018) Release 2.10-r761 (27 March 2018)
--------------------------------- ---------------------------------
+13 -7
View File
@@ -61,15 +61,16 @@ mainstream long-read mappers such as BLASR, BWA-MEM, NGMLR and GMAP. It is more
accurate on simulated long reads and produces biologically meaningful alignment accurate on simulated long reads and produces biologically meaningful alignment
ready for downstream analyses. For >100bp Illumina short reads, minimap2 is ready for downstream analyses. For >100bp Illumina short reads, minimap2 is
three times as fast as BWA-MEM and Bowtie2, and as accurate on simulated data. three times as fast as BWA-MEM and Bowtie2, and as accurate on simulated data.
Detailed evaluations are available from the [minimap2 preprint][preprint]. Detailed evaluations are available from the [minimap2 paper][doi] or the
[preprint][preprint].
### <a name="install"></a>Installation ### <a name="install"></a>Installation
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.10/minimap2-2.10_x64-linux.tar.bz2 | tar -jxvf - curl -L https://github.com/lh3/minimap2/releases/download/v2.11/minimap2-2.11_x64-linux.tar.bz2 | tar -jxvf -
./minimap2-2.10_x64-linux/minimap2 ./minimap2-2.11_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
@@ -77,7 +78,7 @@ directory to compile. If you see compilation errors, try `make sse2only=1`
to disable SSE4 code, which will make minimap2 slightly slower. to disable SSE4 code, which will make minimap2 slightly slower.
Minimap2 also works with ARM CPUs supporting the NEON instruction sets. To Minimap2 also works with ARM CPUs supporting the NEON instruction sets. To
compile, use `make arm_neon=1`. compile for 32 bit ARM architectures (such as ARMv7), use `make arm_neon=1`. To compile for for 64 bit ARM architectures (such as ARMv8), use `make arm_neon=1 aarch64=1`.
### <a name="general"></a>General usage ### <a name="general"></a>General usage
@@ -253,7 +254,9 @@ similar to the `MD` SAM tag but is standalone and easier to parse.
If `--cs=long` is used, the `cs` string also contains identical sequences in If `--cs=long` is used, the `cs` string also contains identical sequences in
the alignment. The above example will become the alignment. The above example will become
`=CGATCG-ata=AATAGAGTAG+gtc=GAAT*at=GCA`. The long form of `cs` encodes both `=CGATCG-ata=AATAGAGTAG+gtc=GAAT*at=GCA`. The long form of `cs` encodes both
reference and query sequences in one string. reference and query sequences in one string. The `cs` tag also encodes intron
positions and splicing signals (see the [minimap2 manpage][manpage-cs] for
details).
#### <a name="paftools"></a>Working with the PAF format #### <a name="paftools"></a>Working with the PAF format
@@ -316,9 +319,10 @@ There is not a specific mailing list for the time being.
### <a name="cite"></a>Citing minimap2 ### <a name="cite"></a>Citing minimap2
If you use minimap2 in your work, please consider to cite: If you use minimap2 in your work, please cite:
> Li, H. (2017). Minimap2: fast pairwise alignment for long nucleotide sequences. [arXiv:1708.01492][preprint] > Li, H. (2018). Minimap2: pairwise alignment for nucleotide sequences.
> Bioinformatics. [doi:10.1093/bioinformatics/bty191][doi]
## <a name="dguide"></a>Developers' Guide ## <a name="dguide"></a>Developers' Guide
@@ -365,3 +369,5 @@ mappy` or [from BioConda][mappyconda] via `conda install -c bioconda mappy`.
[issue]: https://github.com/lh3/minimap2/issues [issue]: https://github.com/lh3/minimap2/issues
[k8]: https://github.com/attractivechaos/k8 [k8]: https://github.com/attractivechaos/k8
[manpage]: https://lh3.github.io/minimap2/minimap2.html [manpage]: https://lh3.github.io/minimap2/minimap2.html
[manpage-cs]: https://lh3.github.io/minimap2/minimap2.html#10
[doi]: https://doi.org/10.1093/bioinformatics/bty191
+143 -21
View File
@@ -6,18 +6,19 @@
#include "mmpriv.h" #include "mmpriv.h"
#include "ksw2.h" #include "ksw2.h"
static void ksw_gen_simple_mat(int m, int8_t *mat, int8_t a, int8_t b) static void ksw_gen_simple_mat(int m, int8_t *mat, int8_t a, int8_t b, int8_t sc_ambi)
{ {
int i, j; int i, j;
a = a < 0? -a : a; a = a < 0? -a : a;
b = b > 0? -b : b; b = b > 0? -b : b;
sc_ambi = sc_ambi > 0? -sc_ambi : sc_ambi;
for (i = 0; i < m - 1; ++i) { for (i = 0; i < m - 1; ++i) {
for (j = 0; j < m - 1; ++j) for (j = 0; j < m - 1; ++j)
mat[i * m + j] = i == j? a : b; mat[i * m + j] = i == j? a : b;
mat[i * m + m - 1] = 0; mat[i * m + m - 1] = sc_ambi;
} }
for (j = 0; j < m; ++j) for (j = 0; j < m; ++j)
mat[(m - 1) * m + j] = 0; mat[(m - 1) * m + j] = sc_ambi;
} }
static inline void mm_seq_rev(uint32_t len, uint8_t *seq) static inline void mm_seq_rev(uint32_t len, uint8_t *seq)
@@ -90,7 +91,8 @@ static int mm_test_zdrop(void *km, const mm_mapopt_t *opt, const uint8_t *qseq,
static void mm_fix_cigar(mm_reg1_t *r, const uint8_t *qseq, const uint8_t *tseq, int *qshift, int *tshift) 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 k, toff = 0, qoff = 0, to_shrink = 0; int32_t toff = 0, qoff = 0, to_shrink = 0;
uint32_t k;
*qshift = *tshift = 0; *qshift = *tshift = 0;
if (p->n_cigar <= 1) return; if (p->n_cigar <= 1) return;
for (k = 0; k < p->n_cigar; ++k) { // indel left alignment for (k = 0; k < p->n_cigar; ++k) { // indel left alignment
@@ -147,8 +149,8 @@ static void mm_fix_cigar(mm_reg1_t *r, const uint8_t *qseq, const uint8_t *tseq,
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) 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, toff = 0, qoff = 0; uint32_t k, l;
int32_t s = 0, max = 0, qshift, tshift; 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); mm_fix_cigar(r, qseq, tseq, &qshift, &tshift);
@@ -197,7 +199,7 @@ static void mm_append_cigar(mm_reg1_t *r, uint32_t n_cigar, uint32_t *cigar) //
mm_extra_t *p; mm_extra_t *p;
if (n_cigar == 0) return; if (n_cigar == 0) return;
if (r->p == 0) { if (r->p == 0) {
uint32_t capacity = n_cigar + sizeof(mm_extra_t); uint32_t capacity = n_cigar + sizeof(mm_extra_t); // TODO: should this be "n_cigar + sizeof(mm_extra_t)/4" instead?
kroundup32(capacity); kroundup32(capacity);
r->p = (mm_extra_t*)calloc(capacity, 4); r->p = (mm_extra_t*)calloc(capacity, 4);
r->p->capacity = capacity; r->p->capacity = capacity;
@@ -217,6 +219,77 @@ static void mm_append_cigar(mm_reg1_t *r, uint32_t n_cigar, uint32_t *cigar) //
} }
} }
static void mm_update_cigar_eqx(mm_reg1_t *r, const uint8_t *qseq, const uint8_t *tseq) // written by @armintoepfer
{
uint32_t n_EQX = 0;
uint32_t k, l, m, cap, toff = 0, qoff = 0, n_M = 0;
mm_extra_t *p;
if (r->p == 0) return;
for (k = 0; k < r->p->n_cigar; ++k) {
uint32_t op = r->p->cigar[k]&0xf, len = r->p->cigar[k]>>4;
if (op == 0) {
while (len > 0) {
for (l = 0; l < len && qseq[qoff + l] == tseq[toff + l]; ++l) {} // run of "="; TODO: N<=>N is converted to "="
if (l > 0) { ++n_EQX; len -= l; toff += l; qoff += l; }
for (l = 0; l < len && qseq[qoff + l] != tseq[toff + l]; ++l) {} // run of "X"
if (l > 0) { ++n_EQX; len -= l; toff += l; qoff += l; }
}
++n_M;
} else if (op == 1) { // insertion
qoff += len;
} else if (op == 2) { // deletion
toff += len;
} else if (op == 3) { // intron
toff += len;
}
}
// update in-place if we can
if (n_EQX == n_M) {
for (k = 0; k < r->p->n_cigar; ++k) {
uint32_t op = r->p->cigar[k]&0xf, len = r->p->cigar[k]>>4;
if (op == 0) r->p->cigar[k] = len << 4 | 7;
}
return;
}
// allocate new storage
cap = r->p->n_cigar + (n_EQX - n_M) + sizeof(mm_extra_t);
kroundup32(cap);
p = (mm_extra_t*)calloc(cap, 4);
memcpy(p, r->p, sizeof(mm_extra_t));
p->capacity = cap;
// update cigar while copying
toff = qoff = m = 0;
for (k = 0; k < r->p->n_cigar; ++k) {
uint32_t op = r->p->cigar[k]&0xf, len = r->p->cigar[k]>>4;
if (op == 0) { // match/mismatch
while (len > 0) {
// match
for (l = 0; l < len && qseq[qoff + l] == tseq[toff + l]; ++l) {}
if (l > 0) p->cigar[m++] = l << 4 | 7;
len -= l;
toff += l, qoff += l;
// mismatch
for (l = 0; l < len && qseq[qoff + l] != tseq[toff + l]; ++l) {}
if (l > 0) p->cigar[m++] = l << 4 | 8;
len -= l;
toff += l, qoff += l;
}
continue;
} else if (op == 1) { // insertion
qoff += len;
} else if (op == 2) { // deletion
toff += len;
} else if (op == 3) { // intron
toff += len;
}
p->cigar[m++] = r->p->cigar[k];
}
p->n_cigar = m;
free(r->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 *mat, int w, int end_bonus, int zdrop, int flag, ksw_extz_t *ez) 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)
{ {
if (mm_dbg_flag & MM_DBG_PRINT_ALN_SEQ) { if (mm_dbg_flag & MM_DBG_PRINT_ALN_SEQ) {
@@ -268,20 +341,30 @@ static inline void mm_adjust_minier(const mm_idx_t *mi, uint8_t *const qseq0[2],
} }
} }
static void mm_filter_bad_seeds(void *km, int as1, int cnt1, mm128_t *a, int min_gap, int diff_thres, int max_ext_len, int max_ext_cnt) static int *collect_long_gaps(void *km, int as1, int cnt1, mm128_t *a, int min_gap, int *n_)
{ {
int max_st, max_en, n, i, k, max, *K; int i, n, *K;
*n_ = 0;
for (i = 1, n = 0; i < cnt1; ++i) { // count the number of gaps longer than min_gap for (i = 1, n = 0; i < cnt1; ++i) { // count the number of gaps longer than min_gap
int gap = ((int32_t)a[as1 + i].y - a[as1 + i - 1].y) - ((int32_t)a[as1 + i].x - a[as1 + i - 1].x); int gap = ((int32_t)a[as1 + i].y - a[as1 + i - 1].y) - ((int32_t)a[as1 + i].x - a[as1 + i - 1].x);
if (gap < -min_gap || gap > min_gap) ++n; if (gap < -min_gap || gap > min_gap) ++n;
} }
if (n <= 1) return; if (n <= 1) return 0;
K = (int*)kmalloc(km, n * sizeof(int)); K = (int*)kmalloc(km, n * sizeof(int));
for (i = 1, n = 0; i < cnt1; ++i) { // store the positions of long gaps for (i = 1, n = 0; i < cnt1; ++i) { // store the positions of long gaps
int gap = ((int32_t)a[as1 + i].y - a[as1 + i - 1].y) - ((int32_t)a[as1 + i].x - a[as1 + i - 1].x); int gap = ((int32_t)a[as1 + i].y - a[as1 + i - 1].y) - ((int32_t)a[as1 + i].x - a[as1 + i - 1].x);
if (gap < -min_gap || gap > min_gap) if (gap < -min_gap || gap > min_gap)
K[n++] = i; K[n++] = i;
} }
*n_ = n;
return K;
}
static void mm_filter_bad_seeds(void *km, int as1, int cnt1, mm128_t *a, int min_gap, int diff_thres, int max_ext_len, int max_ext_cnt)
{
int max_st, max_en, n, i, k, max, *K;
K = collect_long_gaps(km, as1, cnt1, a, min_gap, &n);
if (K == 0) return;
max = 0, max_st = max_en = -1; max = 0, max_st = max_en = -1;
for (k = 0;; ++k) { // traverse long gaps for (k = 0;; ++k) { // traverse long gaps
int gap, l, n_ins = 0, n_del = 0, qs, rs, max_diff = 0, max_diff_l = -1; int gap, l, n_ins = 0, n_del = 0, qs, rs, max_diff = 0, max_diff_l = -1;
@@ -293,7 +376,7 @@ static void mm_filter_bad_seeds(void *km, int as1, int cnt1, mm128_t *a, int min
if (k == n) break; if (k == n) break;
} }
i = K[k]; i = K[k];
gap = ((int32_t)a[as1 + i].y - a[as1 + i - 1].y) - ((int32_t)a[as1 + i].x - a[as1 + i - 1].x); gap = ((int32_t)a[as1 + i].y - (int32_t)a[as1 + i - 1].y) - (int32_t)(a[as1 + i].x - a[as1 + i - 1].x);
if (gap > 0) n_ins += gap; if (gap > 0) n_ins += gap;
else n_del += -gap; else n_del += -gap;
qs = (int32_t)a[as1 + i - 1].y; qs = (int32_t)a[as1 + i - 1].y;
@@ -301,7 +384,7 @@ static void mm_filter_bad_seeds(void *km, int as1, int cnt1, mm128_t *a, int min
for (l = k + 1; l < n && l <= k + max_ext_cnt; ++l) { for (l = k + 1; l < n && l <= k + max_ext_cnt; ++l) {
int j = K[l], diff; int j = K[l], diff;
if ((int32_t)a[as1 + j].y - qs > max_ext_len || (int32_t)a[as1 + j].x - rs > max_ext_len) break; if ((int32_t)a[as1 + j].y - qs > max_ext_len || (int32_t)a[as1 + j].x - rs > max_ext_len) break;
gap = ((int32_t)a[as1 + j].y - (int32_t)a[as1 + j - 1].y) - (a[as1 + j].x - a[as1 + j - 1].x); gap = ((int32_t)a[as1 + j].y - (int32_t)a[as1 + j - 1].y) - (int32_t)(a[as1 + j].x - a[as1 + j - 1].x);
if (gap > 0) n_ins += gap; if (gap > 0) n_ins += gap;
else n_del += -gap; else n_del += -gap;
diff = n_ins + n_del - abs(n_ins - n_del); diff = n_ins + n_del - abs(n_ins - n_del);
@@ -314,6 +397,42 @@ static void mm_filter_bad_seeds(void *km, int as1, int cnt1, mm128_t *a, int min
kfree(km, K); kfree(km, K);
} }
static void mm_filter_bad_seeds_alt(void *km, int as1, int cnt1, mm128_t *a, int min_gap, int max_ext)
{
int n, k, *K;
K = collect_long_gaps(km, as1, cnt1, a, min_gap, &n);
if (K == 0) return;
for (k = 0; k < n;) {
int i = K[k], l;
int gap1 = ((int32_t)a[as1 + i].y - (int32_t)a[as1 + i - 1].y) - ((int32_t)a[as1 + i].x - (int32_t)a[as1 + i - 1].x);
int re1 = (int32_t)a[as1 + i].x;
int qe1 = (int32_t)a[as1 + i].y;
gap1 = gap1 > 0? gap1 : -gap1;
for (l = k + 1; l < n; ++l) {
int j = K[l], gap2, q_span_pre, rs2, qs2, m;
if ((int32_t)a[as1 + j].y - qe1 > max_ext || (int32_t)a[as1 + j].x - re1 > max_ext) break;
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;
rs2 = (int32_t)a[as1 + j - 1].x + q_span_pre;
qs2 = (int32_t)a[as1 + j - 1].x + q_span_pre;
m = rs2 - re1 < qs2 - qe1? rs2 - re1 : qs2 - qe1;
gap2 = gap2 > 0? gap2 : -gap2;
if (m > gap1 + gap2) break;
re1 = (int32_t)a[as1 + j].x;
qe1 = (int32_t)a[as1 + j].y;
gap1 = gap2;
}
if (l > k + 1) {
int j, end = K[l - 1];
for (j = K[k]; j < end; ++j)
a[as1 + j].y |= MM_SEED_IGNORE;
a[as1 + end].y |= MM_SEED_LONG_JOIN;
}
k = l;
}
kfree(km, K);
}
static void mm_fix_bad_ends(const mm_reg1_t *r, const mm128_t *a, int bw, int min_match, int32_t *as, int32_t *cnt) static void mm_fix_bad_ends(const mm_reg1_t *r, const mm128_t *a, int bw, int min_match, int32_t *as, int32_t *cnt)
{ {
int32_t i, l, m; int32_t i, l, m;
@@ -350,7 +469,7 @@ static void mm_fix_bad_ends(const mm_reg1_t *r, const mm128_t *a, int bw, int mi
} }
} }
static void mm_max_stretch(const mm_mapopt_t *opt, const mm_reg1_t *r, const mm128_t *a, int32_t *as, int32_t *cnt) static void mm_max_stretch(const mm_reg1_t *r, const mm128_t *a, int32_t *as, int32_t *cnt)
{ {
int32_t i, score, max_score, len, max_i, max_len; int32_t i, score, max_score, len, max_i, max_len;
@@ -388,7 +507,7 @@ static int mm_seed_ext_score(void *km, const mm_mapopt_t *opt, const mm_idx_t *m
qe = (uint32_t)a->y + 1, qs = qe - q_span; qe = (uint32_t)a->y + 1, qs = qe - q_span;
rs = rs - ext_len > 0? rs - ext_len : 0; rs = rs - ext_len > 0? rs - ext_len : 0;
qs = qs - ext_len > 0? qs - ext_len : 0; qs = qs - ext_len > 0? qs - ext_len : 0;
re = re + ext_len < mi->seq[rid].len? re + ext_len : mi->seq[rid].len; re = re + ext_len < (int32_t)mi->seq[rid].len? re + ext_len : mi->seq[rid].len;
qe = qe + ext_len < qlen? qe + ext_len : qlen; qe = qe + ext_len < qlen? qe + ext_len : qlen;
tseq = (uint8_t*)kmalloc(km, re - rs); tseq = (uint8_t*)kmalloc(km, re - rs);
mm_idx_getseq(mi, rid, rs, re, tseq); mm_idx_getseq(mi, rid, rs, re, tseq);
@@ -434,11 +553,11 @@ static void mm_align1(void *km, const mm_mapopt_t *opt, const mm_idx_t *mi, int
r2->cnt = 0; r2->cnt = 0;
if (r->cnt == 0) return; if (r->cnt == 0) return;
ksw_gen_simple_mat(5, mat, opt->a, opt->b); ksw_gen_simple_mat(5, mat, opt->a, opt->b, opt->sc_ambi);
bw = (int)(opt->bw * 1.5 + 1.); bw = (int)(opt->bw * 1.5 + 1.);
if (is_sr && !(mi->flag & MM_I_HPC)) { if (is_sr && !(mi->flag & MM_I_HPC)) {
mm_max_stretch(opt, r, a, &as1, &cnt1); mm_max_stretch(r, a, &as1, &cnt1);
rs = (int32_t)a[as1].x + 1 - (int32_t)(a[as1].y>>32&0xff); rs = (int32_t)a[as1].x + 1 - (int32_t)(a[as1].y>>32&0xff);
qs = (int32_t)a[as1].y + 1 - (int32_t)(a[as1].y>>32&0xff); qs = (int32_t)a[as1].y + 1 - (int32_t)(a[as1].y>>32&0xff);
re = (int32_t)a[as1+cnt1-1].x + 1; re = (int32_t)a[as1+cnt1-1].x + 1;
@@ -450,6 +569,7 @@ static void mm_align1(void *km, const mm_mapopt_t *opt, const mm_idx_t *mi, int
mm_fix_bad_ends(r, a, opt->bw, opt->min_chain_score * 2, &as1, &cnt1); mm_fix_bad_ends(r, a, opt->bw, opt->min_chain_score * 2, &as1, &cnt1);
} }
mm_filter_bad_seeds(km, as1, cnt1, a, 10, 40, opt->max_gap>>1, 10); mm_filter_bad_seeds(km, as1, cnt1, a, 10, 40, opt->max_gap>>1, 10);
mm_filter_bad_seeds_alt(km, as1, cnt1, a, 30, opt->max_gap>>1);
mm_adjust_minier(mi, qseq0, &a[as1], &rs, &qs); mm_adjust_minier(mi, qseq0, &a[as1], &rs, &qs);
mm_adjust_minier(mi, qseq0, &a[as1 + cnt1 - 1], &re, &qe); mm_adjust_minier(mi, qseq0, &a[as1 + cnt1 - 1], &re, &qe);
} }
@@ -473,7 +593,7 @@ static void mm_align1(void *km, const mm_mapopt_t *opt, const mm_idx_t *mi, int
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;
re0 = re + l < 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
rs0 = (int32_t)a[r->as].x + 1 - (int32_t)(a[r->as].y>>32&0xff); rs0 = (int32_t)a[r->as].x + 1 - (int32_t)(a[r->as].y>>32&0xff);
@@ -517,13 +637,13 @@ static void mm_align1(void *km, const mm_mapopt_t *opt, const mm_idx_t *mi, int
} }
} }
} }
if (qe < qlen && re < mi->seq[rid].len) { if (qe < qlen && re < (int32_t)mi->seq[rid].len) {
l = qlen - qe < opt->max_gap? qlen - qe : opt->max_gap; l = qlen - qe < opt->max_gap? qlen - qe : opt->max_gap;
qe1 = qe1 < qe + l? qe1 : qe + l; qe1 = qe1 < qe + l? qe1 : qe + l;
qe0 = qe0 > qe1? qe0 : qe1; // at least include qe0 qe0 = qe0 > qe1? qe0 : qe1; // at least include qe0
l += l * opt->a > opt->q? (l * opt->a - opt->q) / opt->e : 0; l += l * opt->a > opt->q? (l * opt->a - opt->q) / opt->e : 0;
l = l < opt->max_gap? l : opt->max_gap; l = l < opt->max_gap? l : opt->max_gap;
l = l < mi->seq[rid].len - re? l : mi->seq[rid].len - re; l = l < (int32_t)mi->seq[rid].len - re? l : mi->seq[rid].len - re;
re1 = re1 < re + l? re1 : re + l; re1 = re1 < re + l? re1 : re + l;
re0 = re0 > re1? re0 : re1; re0 = re0 > re1? re0 : re1;
} else re0 = re, qe0 = qe; } else re0 = re, qe0 = qe;
@@ -628,6 +748,7 @@ static void mm_align1(void *km, const mm_mapopt_t *opt, const mm_idx_t *mi, int
if (r->p) { if (r->p) {
mm_idx_getseq(mi, rid, rs1, re1, tseq); mm_idx_getseq(mi, rid, rs1, re1, tseq);
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);
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
} }
@@ -652,7 +773,7 @@ static int mm_align1_inv(void *km, const mm_mapopt_t *opt, const mm_idx_t *mi, i
if (ql < opt->min_chain_score || ql > opt->max_gap) return 0; if (ql < opt->min_chain_score || ql > opt->max_gap) return 0;
if (tl < opt->min_chain_score || tl > opt->max_gap) return 0; if (tl < opt->min_chain_score || tl > opt->max_gap) return 0;
ksw_gen_simple_mat(5, mat, opt->a, opt->b); ksw_gen_simple_mat(5, mat, opt->a, opt->b, opt->sc_ambi);
tseq = (uint8_t*)kmalloc(km, tl); tseq = (uint8_t*)kmalloc(km, tl);
mm_idx_getseq(mi, r1->rid, r1->re, r2->rs, tseq); mm_idx_getseq(mi, r1->rid, r1->re, r2->rs, tseq);
qseq = r1->rev? &qseq0[0][r2->qe] : &qseq0[1][qlen - r2->qs]; qseq = r1->rev? &qseq0[0][r2->qe] : &qseq0[1][qlen - r2->qs];
@@ -686,6 +807,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); 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]);
ret = 1; ret = 1;
end_align1_inv: end_align1_inv:
kfree(km, tseq); kfree(km, tseq);
@@ -755,7 +877,7 @@ mm_reg1_t *mm_align_skeleton(void *km, const mm_mapopt_t *opt, const mm_idx_t *m
*n_regs_ = n_regs; *n_regs_ = n_regs;
kfree(km, qseq0[0]); kfree(km, qseq0[0]);
kfree(km, ez.cigar); kfree(km, ez.cigar);
mm_filter_regs(km, opt, qlen, n_regs_, regs); mm_filter_regs(opt, qlen, n_regs_, regs);
mm_hit_sort_by_dp(km, n_regs_, regs); mm_hit_sort_by_dp(km, n_regs_, regs);
return regs; return regs;
} }
+1 -1
View File
@@ -67,7 +67,7 @@ static inline void kseq2bseq(kseq_t *ks, mm_bseq1_t *s, int with_qual, int with_
int i; int i;
s->name = kstrdup(&ks->name); s->name = kstrdup(&ks->name);
s->seq = kstrdup(&ks->seq); s->seq = kstrdup(&ks->seq);
for (i = 0; i < ks->seq.l; ++i) // convert U to T for (i = 0; i < (int)ks->seq.l; ++i) // convert U to T
if (s->seq[i] == 'u' || s->seq[i] == 'U') if (s->seq[i] == 'u' || s->seq[i] == 'U')
--s->seq[i]; --s->seq[i];
s->qual = with_qual && ks->qual.l? kstrdup(&ks->qual) : 0; s->qual = with_qual && ks->qual.l? kstrdup(&ks->qual) : 0;
+1 -1
View File
@@ -44,7 +44,7 @@ mm128_t *mm_chain_dp(int max_dist_x, int max_dist_y, int bw, int max_skip, int m
int32_t qi = (int32_t)a[i].y, q_span = a[i].y>>32&0xff; // NB: only 8 bits of span is used!!! int32_t qi = (int32_t)a[i].y, q_span = a[i].y>>32&0xff; // NB: only 8 bits of span is used!!!
int32_t max_f = q_span, n_skip = 0, min_d; int32_t max_f = q_span, n_skip = 0, min_d;
int32_t sidi = (a[i].y & MM_SEED_SEG_MASK) >> MM_SEED_SEG_SHIFT; int32_t sidi = (a[i].y & MM_SEED_SEG_MASK) >> MM_SEED_SEG_SHIFT;
while (st < i && ri - a[st].x > max_dist_x) ++st; while (st < i && ri > a[st].x + max_dist_x) ++st;
for (j = i - 1; j >= st; --j) { for (j = i - 1; j >= st; --j) {
int64_t dr = ri - a[j].x; int64_t dr = ri - a[j].x;
int32_t dq = qi - (int32_t)a[j].y, dd, sc, log_dd; int32_t dq = qi - (int32_t)a[j].y, dd, sc, log_dd;
+6 -6
View File
@@ -24,18 +24,18 @@
This cookbook walks you through a variety of applications of minimap2 and its This cookbook walks you through a variety of applications of minimap2 and its
companion script `paftools.js`. All data here are freely available from the companion script `paftools.js`. All data here are freely available from the
minimap2 release page at version tag [v2.10][v2.10]. Some examples only work minimap2 release page at version tag [v2.11][v2.11]. Some examples only work
with v2.10 or later. with v2.11 or later.
To acquire the data used in this cookbook and to install minimap2 and paftools, 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.10/minimap2-2.10_x64-linux.tar.bz2 | tar jxf - curl -L https://github.com/lh3/minimap2/releases/download/v2.11/minimap2-2.11_x64-linux.tar.bz2 | tar jxf -
cp minimap2-2.10_x64-linux/{minimap2,k8,paftools.js} . # copy executables cp minimap2-2.11_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.11/cookbook-data.tgz | tar zxf -
``` ```
## <a name="map-reads"></a>Mapping Genomic Reads ## <a name="map-reads"></a>Mapping Genomic Reads
@@ -240,4 +240,4 @@ with `-x ava-pb` (99% vs 93% with `-x ava-ont`).
[pbsim]: https://github.com/pfaucon/PBSIM-PacBio-Simulator [pbsim]: https://github.com/pfaucon/PBSIM-PacBio-Simulator
[mason2]: https://github.com/seqan/seqan/tree/master/apps/mason2 [mason2]: https://github.com/seqan/seqan/tree/master/apps/mason2
[paf]: https://github.com/lh3/miniasm/blob/master/PAF.md [paf]: https://github.com/lh3/miniasm/blob/master/PAF.md
[v2.10]: https://github.com/lh3/minimap2/releases/tag/v2.10 [v2.11]: https://github.com/lh3/minimap2/releases/tag/v2.11
+4 -4
View File
@@ -137,7 +137,7 @@ static void write_cs_core(kstring_t *s, const uint8_t *tseq, const uint8_t *qseq
{ {
int i, q_off, t_off; int i, q_off, t_off;
mm_sprintf_lite(s, "\tcs:Z:"); mm_sprintf_lite(s, "\tcs:Z:");
for (i = q_off = t_off = 0; i < 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);
if (op == 0) { // match if (op == 0) { // match
@@ -185,7 +185,7 @@ static void write_MD_core(kstring_t *s, const uint8_t *tseq, const uint8_t *qseq
{ {
int i, q_off, t_off, l_MD = 0; int i, q_off, t_off, l_MD = 0;
mm_sprintf_lite(s, "\tMD:Z:"); mm_sprintf_lite(s, "\tMD:Z:");
for (i = q_off = t_off = 0; i < 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 <= 2); // introns (aka reference skips) are not supported assert(op >= 0 && op <= 2); // introns (aka reference skips) are not supported
if (op == 0) { // match if (op == 0) { // match
@@ -270,7 +270,7 @@ void mm_write_paf(kstring_t *s, const mm_idx_t *mi, const mm_bseq1_t *t, const m
uint32_t k; uint32_t k;
mm_sprintf_lite(s, "\tcg:Z:"); mm_sprintf_lite(s, "\tcg:Z:");
for (k = 0; k < r->p->n_cigar; ++k) for (k = 0; k < r->p->n_cigar; ++k)
mm_sprintf_lite(s, "%d%c", r->p->cigar[k]>>4, "MIDN"[r->p->cigar[k]&0xf]); mm_sprintf_lite(s, "%d%c", r->p->cigar[k]>>4, "MIDNSHP=XB"[r->p->cigar[k]&0xf]);
} }
if (r->p && (opt_flag & (MM_F_OUT_CS|MM_F_OUT_MD))) if (r->p && (opt_flag & (MM_F_OUT_CS|MM_F_OUT_MD)))
write_cs_or_MD(km, s, mi, t, r, !(opt_flag&MM_F_OUT_CS_LONG), opt_flag&MM_F_OUT_MD); write_cs_or_MD(km, s, mi, t, r, !(opt_flag&MM_F_OUT_CS_LONG), opt_flag&MM_F_OUT_MD);
@@ -321,7 +321,7 @@ static void write_sam_cigar(kstring_t *s, int sam_flag, int in_tag, int qlen, co
int clip_char = (sam_flag&0x800) && !(opt_flag&MM_F_SOFTCLIP)? 'H' : 'S'; int clip_char = (sam_flag&0x800) && !(opt_flag&MM_F_SOFTCLIP)? 'H' : 'S';
if (clip_len[0]) mm_sprintf_lite(s, "%d%c", clip_len[0], clip_char); if (clip_len[0]) mm_sprintf_lite(s, "%d%c", clip_len[0], clip_char);
for (k = 0; k < r->p->n_cigar; ++k) for (k = 0; k < r->p->n_cigar; ++k)
mm_sprintf_lite(s, "%d%c", r->p->cigar[k]>>4, "MIDN"[r->p->cigar[k]&0xf]); mm_sprintf_lite(s, "%d%c", r->p->cigar[k]>>4, "MIDNSHP=XB"[r->p->cigar[k]&0xf]);
if (clip_len[1]) mm_sprintf_lite(s, "%d%c", clip_len[1], clip_char); if (clip_len[1]) mm_sprintf_lite(s, "%d%c", clip_len[1], clip_char);
} }
} }
+17 -16
View File
@@ -132,7 +132,7 @@ void mm_set_parent(void *km, float mask_level, int n, mm_reg1_t *r, int sub_diff
int j, x = si; int j, x = si;
radix_sort_64(cov, cov + n_cov); radix_sort_64(cov, cov + n_cov);
for (j = 0; j < n_cov; ++j) { for (j = 0; j < n_cov; ++j) {
if (cov[j]>>32 > x) uncov_len += (cov[j]>>32) - x; if ((int)(cov[j]>>32) > x) uncov_len += (cov[j]>>32) - x;
x = (int32_t)cov[j] > x? (int32_t)cov[j] : x; x = (int32_t)cov[j] > x? (int32_t)cov[j] : x;
} }
if (ei > x) uncov_len += ei - x; if (ei > x) uncov_len += ei - x;
@@ -143,7 +143,7 @@ void mm_set_parent(void *km, float mask_level, int n, mm_reg1_t *r, int sub_diff
if (ej <= si || sj >= ei) continue; // no overlap if (ej <= si || sj >= ei) continue; // no overlap
min = ej - sj < ei - si? ej - sj : ei - si; min = ej - sj < ei - si? ej - sj : ei - si;
max = ej - sj > ei - si? ej - sj : ei - si; max = ej - sj > ei - si? ej - sj : ei - si;
ol = si < sj? (ei < sj? 0 : ei < ej? ei - sj : ej - sj) : (ej < si? 0 : ej < ei? ej - si : ei - si); // overlap length ol = si < sj? (ei < sj? 0 : ei < ej? ei - sj : ej - sj) : (ej < si? 0 : ej < ei? ej - si : ei - si); // overlap length; TODO: this can be simplified
if ((float)ol / min - (float)uncov_len / max > mask_level) { if ((float)ol / min - (float)uncov_len / max > mask_level) {
int cnt_sub = 0; int cnt_sub = 0;
ri->parent = rp->parent; ri->parent = rp->parent;
@@ -246,7 +246,7 @@ void mm_select_sub(void *km, float pri_ratio, int min_diff, int best_n, int *n_,
} }
} }
void mm_filter_regs(void *km, const mm_mapopt_t *opt, int qlen, int *n_regs, mm_reg1_t *regs) void mm_filter_regs(const mm_mapopt_t *opt, int qlen, int *n_regs, mm_reg1_t *regs)
{ // NB: after this call, mm_reg1_t::parent can be -1 if its parent filtered out { // NB: after this call, mm_reg1_t::parent can be -1 if its parent filtered out
int i, k; int i, k;
for (i = k = 0; i < *n_regs; ++i) { for (i = k = 0; i < *n_regs; ++i) {
@@ -304,7 +304,7 @@ void mm_join_long(void *km, const mm_mapopt_t *opt, int qlen, int *n_regs_, mm_r
for (i = n_aux - 1; i >= 1; --i) { for (i = n_aux - 1; i >= 1; --i) {
mm_reg1_t *r0 = &regs[(int32_t)aux[i-1]], *r1 = &regs[(int32_t)aux[i]]; mm_reg1_t *r0 = &regs[(int32_t)aux[i-1]], *r1 = &regs[(int32_t)aux[i]];
mm128_t *a0e, *a1s; mm128_t *a0e, *a1s;
int max_gap, min_gap, sc_thres; int max_gap, min_gap, sc_thres, min_flank_len;
// test // test
if (r0->as + r0->cnt != r1->as) continue; // not adjacent in a[] if (r0->as + r0->cnt != r1->as) continue; // not adjacent in a[]
@@ -313,13 +313,14 @@ void mm_join_long(void *km, const mm_mapopt_t *opt, int qlen, int *n_regs_, mm_r
a1s = &a[r1->as]; a1s = &a[r1->as];
if (a1s->x <= a0e->x || (int32_t)a1s->y <= (int32_t)a0e->y) continue; // keep colinearity if (a1s->x <= a0e->x || (int32_t)a1s->y <= (int32_t)a0e->y) continue; // keep colinearity
max_gap = min_gap = (int32_t)a1s->y - (int32_t)a0e->y; max_gap = min_gap = (int32_t)a1s->y - (int32_t)a0e->y;
max_gap = max_gap > a1s->x - a0e->x? max_gap : a1s->x - a0e->x; max_gap = a0e->x + max_gap > a1s->x? max_gap : a1s->x - a0e->x;
min_gap = min_gap < a1s->x - a0e->x? min_gap : a1s->x - a0e->x; min_gap = a0e->x + min_gap < a1s->x? min_gap : a1s->x - a0e->x;
if (max_gap > opt->max_join_long || min_gap > opt->max_join_short) continue; if (max_gap > opt->max_join_long || min_gap > opt->max_join_short) continue;
sc_thres = (int)((float)opt->min_join_flank_sc / opt->max_join_long * max_gap + .499); sc_thres = (int)((float)opt->min_join_flank_sc / opt->max_join_long * max_gap + .499);
if (r0->score < sc_thres || r1->score < sc_thres) continue; // require good flanking chains if (r0->score < sc_thres || r1->score < sc_thres) continue; // require good flanking chains
if (r0->re - r0->rs < max_gap>>1 || r0->qe - r0->qs < max_gap>>1) continue; // require enough flanking length min_flank_len = (int)(max_gap * opt->min_join_flank_ratio);
if (r1->re - r1->rs < max_gap>>1 || r1->qe - r1->qs < max_gap>>1) continue; if (r0->re - r0->rs < min_flank_len || r0->qe - r0->qs < min_flank_len) continue; // require enough flanking length
if (r1->re - r1->rs < min_flank_len || r1->qe - r1->qs < min_flank_len) continue;
// all conditions satisfied; join // all conditions satisfied; join
a[r1->as].y |= MM_SEED_LONG_JOIN; a[r1->as].y |= MM_SEED_LONG_JOIN;
@@ -339,7 +340,7 @@ void mm_join_long(void *km, const mm_mapopt_t *opt, int qlen, int *n_regs_, mm_r
r->parent = regs[r->parent].parent; r->parent = regs[r->parent].parent;
} }
} }
mm_filter_regs(km, opt, qlen, n_regs_, regs); mm_filter_regs(opt, qlen, n_regs_, regs);
mm_sync_regs(km, *n_regs_, regs); mm_sync_regs(km, *n_regs_, regs);
} }
} }
@@ -411,23 +412,23 @@ void mm_seg_free(void *km, int n_segs, mm_seg_t *segs)
static void mm_set_inv_mapq(void *km, int n_regs, mm_reg1_t *regs) static void mm_set_inv_mapq(void *km, int n_regs, mm_reg1_t *regs)
{ {
int i, n_aux; int i, n_aux;
uint64_t *aux; mm128_t *aux;
if (n_regs < 3) return; if (n_regs < 3) return;
for (i = 0; i < n_regs; ++i) for (i = 0; i < n_regs; ++i)
if (regs[i].inv) break; if (regs[i].inv) break;
if (i == n_regs) return; // no inversion hits if (i == n_regs) return; // no inversion hits
aux = (uint64_t*)kmalloc(km, n_regs * 8); aux = (mm128_t*)kmalloc(km, n_regs * 16);
for (i = n_aux = 0; i < n_regs; ++i) for (i = n_aux = 0; i < n_regs; ++i)
if (regs[i].parent == i || regs[i].parent < 0) if (regs[i].parent == i || regs[i].parent < 0)
aux[n_aux++] = (uint64_t)regs[i].as << 32 | i; aux[n_aux].y = i, aux[n_aux++].x = (uint64_t)regs[i].rid << 32 | regs[i].rs;
radix_sort_64(aux, aux + n_aux); radix_sort_128x(aux, aux + n_aux);
for (i = 1; i < n_aux - 1; ++i) { for (i = 1; i < n_aux - 1; ++i) {
mm_reg1_t *inv = &regs[(int32_t)aux[i]]; mm_reg1_t *inv = &regs[aux[i].y];
if (inv->inv) { if (inv->inv) {
mm_reg1_t *l = &regs[(int32_t)aux[i-1]]; mm_reg1_t *l = &regs[aux[i-1].y];
mm_reg1_t *r = &regs[(int32_t)aux[i+1]]; mm_reg1_t *r = &regs[aux[i+1].y];
inv->mapq = l->mapq < r->mapq? l->mapq : r->mapq; inv->mapq = l->mapq < r->mapq? l->mapq : r->mapq;
} }
} }
+26 -20
View File
@@ -45,10 +45,10 @@ mm_idx_t *mm_idx_init(int w, int k, int b, int flag)
void mm_idx_destroy(mm_idx_t *mi) void mm_idx_destroy(mm_idx_t *mi)
{ {
int i; uint32_t i;
if (mi == 0) return; if (mi == 0) return;
if (mi->h) kh_destroy(str, (khash_t(str)*)mi->h); if (mi->h) kh_destroy(str, (khash_t(str)*)mi->h);
for (i = 0; i < 1<<mi->b; ++i) { for (i = 0; i < 1U<<mi->b; ++i) {
free(mi->B[i].p); free(mi->B[i].p);
free(mi->B[i].a.a); free(mi->B[i].a.a);
kh_destroy(idx, (idxhash_t*)mi->B[i].h); kh_destroy(idx, (idxhash_t*)mi->B[i].h);
@@ -82,14 +82,15 @@ const uint64_t *mm_idx_get(const mm_idx_t *mi, uint64_t minier, int *n)
void mm_idx_stat(const mm_idx_t *mi) void mm_idx_stat(const mm_idx_t *mi)
{ {
int i, n = 0, n1 = 0; int n = 0, n1 = 0;
uint32_t i;
uint64_t sum = 0, len = 0; uint64_t sum = 0, len = 0;
fprintf(stderr, "[M::%s] kmer size: %d; skip: %d; is_hpc: %d; #seq: %d\n", __func__, mi->k, mi->w, mi->flag&MM_I_HPC, mi->n_seq); fprintf(stderr, "[M::%s] kmer size: %d; skip: %d; is_hpc: %d; #seq: %d\n", __func__, mi->k, mi->w, mi->flag&MM_I_HPC, mi->n_seq);
for (i = 0; i < mi->n_seq; ++i) for (i = 0; i < mi->n_seq; ++i)
len += mi->seq[i].len; len += mi->seq[i].len;
for (i = 0; i < 1<<mi->b; ++i) for (i = 0; i < 1U<<mi->b; ++i)
if (mi->B[i].h) n += kh_size((idxhash_t*)mi->B[i].h); if (mi->B[i].h) n += kh_size((idxhash_t*)mi->B[i].h);
for (i = 0; i < 1<<mi->b; ++i) { for (i = 0; i < 1U<<mi->b; ++i) {
idxhash_t *h = (idxhash_t*)mi->B[i].h; idxhash_t *h = (idxhash_t*)mi->B[i].h;
khint_t k; khint_t k;
if (h == 0) continue; if (h == 0) continue;
@@ -172,7 +173,8 @@ int32_t mm_idx_cal_max_occ(const mm_idx_t *mi, float f)
static void worker_post(void *g, long i, int tid) static void worker_post(void *g, long i, int tid)
{ {
int j, start_a, start_p, n, n_keys; int n, n_keys;
size_t j, start_a, start_p;
idxhash_t *h; idxhash_t *h;
mm_idx_t *mi = (mm_idx_t*)g; mm_idx_t *mi = (mm_idx_t*)g;
mm_idx_bucket_t *b = &mi->B[i]; mm_idx_bucket_t *b = &mi->B[i];
@@ -200,7 +202,7 @@ static void worker_post(void *g, long i, int tid)
int absent; int absent;
mm128_t *p = &b->a.a[j-1]; mm128_t *p = &b->a.a[j-1];
itr = kh_put(idx, h, p->x>>8>>mi->b<<1, &absent); itr = kh_put(idx, h, p->x>>8>>mi->b<<1, &absent);
assert(absent && j - start_a == n); assert(absent && j == start_a + n);
if (n == 1) { if (n == 1) {
kh_key(h, itr) |= 1; kh_key(h, itr) |= 1;
kh_val(h, itr) = p->y; kh_val(h, itr) = p->y;
@@ -216,7 +218,7 @@ static void worker_post(void *g, long i, int tid)
} else ++n; } else ++n;
} }
b->h = h; b->h = h;
assert(b->n == start_p); assert(b->n == (int32_t)start_p);
// deallocate and clear b->a // deallocate and clear b->a
kfree(0, b->a.a); kfree(0, b->a.a);
@@ -336,7 +338,7 @@ mm_idx_t *mm_idx_gen(mm_bseq_file_t *fp, int w, int k, int b, int flag, int mini
pipeline_t pl; pipeline_t pl;
if (fp == 0 || mm_bseq_eof(fp)) return 0; if (fp == 0 || mm_bseq_eof(fp)) return 0;
memset(&pl, 0, sizeof(pipeline_t)); memset(&pl, 0, sizeof(pipeline_t));
pl.mini_batch_size = mini_batch_size < batch_size? mini_batch_size : batch_size; pl.mini_batch_size = (uint64_t)mini_batch_size < batch_size? mini_batch_size : batch_size;
pl.batch_size = batch_size; pl.batch_size = batch_size;
pl.fp = fp; pl.fp = fp;
pl.mi = mm_idx_init(w, k, b, flag); pl.mi = mm_idx_init(w, k, b, flag);
@@ -413,17 +415,20 @@ mm_idx_t *mm_idx_str(int w, int k, int is_hpc, int bucket_bits, int n, const cha
void mm_idx_dump(FILE *fp, const mm_idx_t *mi) void mm_idx_dump(FILE *fp, const mm_idx_t *mi)
{ {
uint64_t sum_len = 0; uint64_t sum_len = 0;
uint32_t x[5]; uint32_t x[5], i;
int i;
x[0] = mi->w, x[1] = mi->k, x[2] = mi->b, x[3] = mi->n_seq, x[4] = mi->flag; x[0] = mi->w, x[1] = mi->k, x[2] = mi->b, x[3] = mi->n_seq, x[4] = mi->flag;
fwrite(MM_IDX_MAGIC, 1, 4, fp); fwrite(MM_IDX_MAGIC, 1, 4, fp);
fwrite(x, 4, 5, fp); fwrite(x, 4, 5, fp);
for (i = 0; i < mi->n_seq; ++i) { for (i = 0; i < mi->n_seq; ++i) {
uint8_t l; if (mi->seq[i].name) {
l = strlen(mi->seq[i].name); uint8_t l = strlen(mi->seq[i].name);
fwrite(&l, 1, 1, fp); fwrite(&l, 1, 1, fp);
fwrite(mi->seq[i].name, 1, l, fp); fwrite(mi->seq[i].name, 1, l, fp);
} else {
uint8_t l = 0;
fwrite(&l, 1, 1, fp);
}
fwrite(&mi->seq[i].len, 4, 1, fp); fwrite(&mi->seq[i].len, 4, 1, fp);
sum_len += mi->seq[i].len; sum_len += mi->seq[i].len;
} }
@@ -450,9 +455,8 @@ void mm_idx_dump(FILE *fp, const mm_idx_t *mi)
mm_idx_t *mm_idx_load(FILE *fp) mm_idx_t *mm_idx_load(FILE *fp)
{ {
int i;
char magic[4]; char magic[4];
uint32_t x[5]; uint32_t x[5], i;
uint64_t sum_len = 0; uint64_t sum_len = 0;
mm_idx_t *mi; mm_idx_t *mi;
@@ -466,9 +470,11 @@ mm_idx_t *mm_idx_load(FILE *fp)
uint8_t l; uint8_t l;
mm_idx_seq_t *s = &mi->seq[i]; mm_idx_seq_t *s = &mi->seq[i];
fread(&l, 1, 1, fp); fread(&l, 1, 1, fp);
s->name = (char*)kmalloc(mi->km, l + 1); if (l) {
fread(s->name, 1, l, fp); s->name = (char*)kmalloc(mi->km, l + 1);
s->name[l] = 0; fread(s->name, 1, l, fp);
s->name[l] = 0;
}
fread(&s->len, 4, 1, fp); fread(&s->len, 4, 1, fp);
s->offset = sum_len; s->offset = sum_len;
sum_len += s->len; sum_len += s->len;
+2 -2
View File
@@ -127,11 +127,11 @@ static inline void ksw_backtrack(void *km, int is_rot, int is_rev, int min_intro
r = i + j; r = i + j;
if (i < off[r]) force_state = 2; if (i < off[r]) force_state = 2;
if (off_end && i > off_end[r]) force_state = 1; if (off_end && i > off_end[r]) force_state = 1;
tmp = force_state < 0? p[r * n_col + i - off[r]] : 0; tmp = force_state < 0? p[(size_t)r * n_col + i - off[r]] : 0;
} else { } else {
if (j < off[i]) force_state = 2; if (j < off[i]) force_state = 2;
if (off_end && j > off_end[i]) force_state = 1; if (off_end && j > off_end[i]) force_state = 1;
tmp = force_state < 0? p[i * n_col + j - off[i]] : 0; tmp = force_state < 0? p[(size_t)i * n_col + j - off[i]] : 0;
} }
if (state == 0) state = tmp & 7; // if requesting the H state, find state one maximizes it. if (state == 0) state = tmp & 7; // if requesting the H state, find state one maximizes it.
else if (!(tmp >> (state + 2) & 1)) state = 0; // if requesting other states, _state_ stays the same if it is a continuation; otherwise, set to H else if (!(tmp >> (state + 2) & 1)) state = 0; // if requesting other states, _state_ stays the same if it is a continuation; otherwise, set to H
+5 -5
View File
@@ -76,7 +76,7 @@ void ksw_extd2_sse(void *km, int qlen, const uint8_t *query, int tlen, const uin
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]);
sc_mis_ = _mm_set1_epi8(mat[1]); sc_mis_ = _mm_set1_epi8(mat[1]);
sc_N_ = _mm_set1_epi8(-e2); sc_N_ = mat[m*m-1] == 0? _mm_set1_epi8(-e2) : _mm_set1_epi8(mat[m*m-1]);
m1_ = _mm_set1_epi8(m - 1); // wildcard m1_ = _mm_set1_epi8(m - 1); // wildcard
if (w < 0) w = tlen > qlen? tlen : qlen; if (w < 0) w = tlen > qlen? tlen : qlen;
@@ -111,7 +111,7 @@ void ksw_extd2_sse(void *km, int qlen, const uint8_t *query, int tlen, const uin
for (t = 0; t < tlen_ * 16; ++t) H[t] = KSW_NEG_INF; for (t = 0; t < tlen_ * 16; ++t) H[t] = KSW_NEG_INF;
} }
if (with_cigar) { if (with_cigar) {
mem2 = (uint8_t*)kmalloc(km, ((qlen + tlen - 1) * n_col_ + 1) * 16); mem2 = (uint8_t*)kmalloc(km, ((size_t)(qlen + tlen - 1) * n_col_ + 1) * 16);
p = (__m128i*)(((size_t)mem2 + 15) >> 4 << 4); p = (__m128i*)(((size_t)mem2 + 15) >> 4 << 4);
off = (int*)kmalloc(km, (qlen + tlen - 1) * sizeof(int) * 2); off = (int*)kmalloc(km, (qlen + tlen - 1) * sizeof(int) * 2);
off_end = off + qlen + tlen - 1; off_end = off + qlen + tlen - 1;
@@ -218,7 +218,7 @@ void ksw_extd2_sse(void *km, int qlen, const uint8_t *query, int tlen, const uin
#endif #endif
} }
} else if (!(flag&KSW_EZ_RIGHT)) { // gap left-alignment } else if (!(flag&KSW_EZ_RIGHT)) { // gap left-alignment
__m128i *pr = p + 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; __m128i d, z, a, b, a2, b2, xt1, x2t1, vt1, ut, tmp;
@@ -265,7 +265,7 @@ void ksw_extd2_sse(void *km, int qlen, const uint8_t *query, int tlen, const uin
_mm_store_si128(&pr[t], d); _mm_store_si128(&pr[t], d);
} }
} else { // gap right-alignment } else { // gap right-alignment
__m128i *pr = p + 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; __m128i d, z, a, b, a2, b2, xt1, x2t1, vt1, ut, tmp;
@@ -382,7 +382,7 @@ void ksw_extd2_sse(void *km, int qlen, const uint8_t *query, int tlen, const uin
int rev_cigar = !!(flag & KSW_EZ_REV_CIGAR); int rev_cigar = !!(flag & KSW_EZ_REV_CIGAR);
if (!ez->zdropped && !(flag&KSW_EZ_EXTZ_ONLY)) { if (!ez->zdropped && !(flag&KSW_EZ_EXTZ_ONLY)) {
ksw_backtrack(km, 1, rev_cigar, 0, (uint8_t*)p, off, off_end, n_col_*16, tlen-1, qlen-1, &ez->m_cigar, &ez->n_cigar, &ez->cigar); ksw_backtrack(km, 1, rev_cigar, 0, (uint8_t*)p, off, off_end, n_col_*16, tlen-1, qlen-1, &ez->m_cigar, &ez->n_cigar, &ez->cigar);
} else if (!ez->zdropped && (flag&KSW_EZ_EXTZ_ONLY) && ez->mqe + end_bonus > ez->max) { } else if (!ez->zdropped && (flag&KSW_EZ_EXTZ_ONLY) && ez->mqe + end_bonus > (int)ez->max) {
ez->reach_end = 1; ez->reach_end = 1;
ksw_backtrack(km, 1, rev_cigar, 0, (uint8_t*)p, off, off_end, n_col_*16, ez->mqe_t, qlen-1, &ez->m_cigar, &ez->n_cigar, &ez->cigar); ksw_backtrack(km, 1, rev_cigar, 0, (uint8_t*)p, off, off_end, n_col_*16, ez->mqe_t, qlen-1, &ez->m_cigar, &ez->n_cigar, &ez->cigar);
} else if (ez->max_t >= 0 && ez->max_q >= 0) { } else if (ez->max_t >= 0 && ez->max_q >= 0) {
+1 -1
View File
@@ -71,7 +71,7 @@ void ksw_exts2_sse(void *km, int qlen, const uint8_t *query, int tlen, const uin
qe_ = _mm_set1_epi8(q + e); qe_ = _mm_set1_epi8(q + e);
sc_mch_ = _mm_set1_epi8(mat[0]); sc_mch_ = _mm_set1_epi8(mat[0]);
sc_mis_ = _mm_set1_epi8(mat[1]); sc_mis_ = _mm_set1_epi8(mat[1]);
sc_N_ = _mm_set1_epi8(-e); sc_N_ = mat[m*m-1] == 0? _mm_set1_epi8(-e) : _mm_set1_epi8(mat[m*m-1]);
m1_ = _mm_set1_epi8(m - 1); // wildcard m1_ = _mm_set1_epi8(m - 1); // wildcard
tlen_ = (tlen + 15) / 16; tlen_ = (tlen + 15) / 16;
+5 -5
View File
@@ -65,7 +65,7 @@ void ksw_extz2_sse(void *km, int qlen, const uint8_t *query, int tlen, const uin
flag16_ = _mm_set1_epi8(0x10); flag16_ = _mm_set1_epi8(0x10);
sc_mch_ = _mm_set1_epi8(mat[0]); sc_mch_ = _mm_set1_epi8(mat[0]);
sc_mis_ = _mm_set1_epi8(mat[1]); sc_mis_ = _mm_set1_epi8(mat[1]);
sc_N_ = _mm_set1_epi8(-e); sc_N_ = mat[m*m-1] == 0? _mm_set1_epi8(-e) : _mm_set1_epi8(mat[m*m-1]);
m1_ = _mm_set1_epi8(m - 1); // wildcard m1_ = _mm_set1_epi8(m - 1); // wildcard
max_sc_ = _mm_set1_epi8(mat[0] + (q + e) * 2); max_sc_ = _mm_set1_epi8(mat[0] + (q + e) * 2);
@@ -89,7 +89,7 @@ void ksw_extz2_sse(void *km, int qlen, const uint8_t *query, int tlen, const uin
for (t = 0; t < tlen_ * 16; ++t) H[t] = KSW_NEG_INF; for (t = 0; t < tlen_ * 16; ++t) H[t] = KSW_NEG_INF;
} }
if (with_cigar) { if (with_cigar) {
mem2 = (uint8_t*)kmalloc(km, ((qlen + tlen - 1) * n_col_ + 1) * 16); mem2 = (uint8_t*)kmalloc(km, ((size_t)(qlen + tlen - 1) * n_col_ + 1) * 16);
p = (__m128i*)(((size_t)mem2 + 15) >> 4 << 4); p = (__m128i*)(((size_t)mem2 + 15) >> 4 << 4);
off = (int*)kmalloc(km, (qlen + tlen - 1) * sizeof(int) * 2); off = (int*)kmalloc(km, (qlen + tlen - 1) * sizeof(int) * 2);
off_end = off + qlen + tlen - 1; off_end = off + qlen + tlen - 1;
@@ -169,7 +169,7 @@ void ksw_extz2_sse(void *km, int qlen, const uint8_t *query, int tlen, const uin
#endif #endif
} }
} else if (!(flag&KSW_EZ_RIGHT)) { // gap left-alignment } else if (!(flag&KSW_EZ_RIGHT)) { // gap left-alignment
__m128i *pr = p + 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, xt1, vt1, ut, tmp; __m128i d, z, a, b, xt1, vt1, ut, tmp;
@@ -195,7 +195,7 @@ void ksw_extz2_sse(void *km, int qlen, const uint8_t *query, int tlen, const uin
_mm_store_si128(&pr[t], d); _mm_store_si128(&pr[t], d);
} }
} else { // gap right-alignment } else { // gap right-alignment
__m128i *pr = p + 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, xt1, vt1, ut, tmp; __m128i d, z, a, b, xt1, vt1, ut, tmp;
@@ -293,7 +293,7 @@ void ksw_extz2_sse(void *km, int qlen, const uint8_t *query, int tlen, const uin
int rev_cigar = !!(flag & KSW_EZ_REV_CIGAR); int rev_cigar = !!(flag & KSW_EZ_REV_CIGAR);
if (!ez->zdropped && !(flag&KSW_EZ_EXTZ_ONLY)) { if (!ez->zdropped && !(flag&KSW_EZ_EXTZ_ONLY)) {
ksw_backtrack(km, 1, rev_cigar, 0, (uint8_t*)p, off, off_end, n_col_*16, tlen-1, qlen-1, &ez->m_cigar, &ez->n_cigar, &ez->cigar); ksw_backtrack(km, 1, rev_cigar, 0, (uint8_t*)p, off, off_end, n_col_*16, tlen-1, qlen-1, &ez->m_cigar, &ez->n_cigar, &ez->cigar);
} else if (!ez->zdropped && (flag&KSW_EZ_EXTZ_ONLY) && ez->mqe + end_bonus > ez->max) { } else if (!ez->zdropped && (flag&KSW_EZ_EXTZ_ONLY) && ez->mqe + end_bonus > (int)ez->max) {
ez->reach_end = 1; ez->reach_end = 1;
ksw_backtrack(km, 1, rev_cigar, 0, (uint8_t*)p, off, off_end, n_col_*16, ez->mqe_t, qlen-1, &ez->m_cigar, &ez->n_cigar, &ez->cigar); ksw_backtrack(km, 1, rev_cigar, 0, (uint8_t*)p, off, off_end, n_col_*16, ez->mqe_t, qlen-1, &ez->m_cigar, &ez->n_cigar, &ez->cigar);
} else if (ez->max_t >= 0 && ez->max_q >= 0) { } else if (ez->max_t >= 0 && ez->max_q >= 0) {
+17 -13
View File
@@ -10,7 +10,7 @@
#include "getopt.h" #include "getopt.h"
#endif #endif
#define MM_VERSION "2.10-r761" #define MM_VERSION "2.11-r797"
#ifdef __linux__ #ifdef __linux__
#include <sys/resource.h> #include <sys/resource.h>
@@ -57,6 +57,9 @@ static struct option long_options[] = {
{ "max-clip-ratio", required_argument, 0, 0 }, // 27 { "max-clip-ratio", required_argument, 0, 0 }, // 27
{ "min-occ-floor", required_argument, 0, 0 }, // 28 { "min-occ-floor", required_argument, 0, 0 }, // 28
{ "MD", no_argument, 0, 0 }, // 29 { "MD", no_argument, 0, 0 }, // 29
{ "lj-min-ratio", required_argument, 0, 0 }, // 30
{ "score-N", required_argument, 0, 0 }, // 31
{ "eqx", no_argument, 0, 0 }, // 32
{ "help", no_argument, 0, 'h' }, { "help", no_argument, 0, 'h' },
{ "max-intron-len", required_argument, 0, 'G' }, { "max-intron-len", required_argument, 0, 'G' },
{ "version", no_argument, 0, 'V' }, { "version", no_argument, 0, 'V' },
@@ -72,7 +75,7 @@ static inline int64_t mm_parse_num(const char *str)
{ {
double x; double x;
char *p; char *p;
x = strtod(optarg, &p); x = strtod(str, &p);
if (*p == 'G' || *p == 'g') x *= 1e9; if (*p == 'G' || *p == 'g') x *= 1e9;
else if (*p == 'M' || *p == 'm') x *= 1e6; else if (*p == 'M' || *p == 'm') x *= 1e6;
else if (*p == 'K' || *p == 'k') x *= 1e3; else if (*p == 'K' || *p == 'k') x *= 1e3;
@@ -94,7 +97,7 @@ static inline void yes_or_no(mm_mapopt_t *opt, int flag, int long_idx, const cha
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
const char *opt_str = "2aSDw:k:K:t:r:f:Vv:g:G:I:d:XT:s:x:Hcp:M:n:z:A:B:O:E:m:N:Qu:R:hF:LC:y"; const char *opt_str = "2aSDw:k:K:t:r:f:Vv:g:G:I:d:XT:s:x:Hcp:M:n:z:A:B:O:E:m:N:Qu:R:hF:LC:yY";
mm_mapopt_t opt; mm_mapopt_t opt;
mm_idxopt_t ipt; mm_idxopt_t ipt;
int i, c, n_threads = 3, long_idx; int i, c, n_threads = 3, long_idx;
@@ -173,6 +176,9 @@ int main(int argc, char *argv[])
else if (c == 0 && long_idx ==27) opt.max_clip_ratio = atof(optarg); // --max-clip-ratio else if (c == 0 && long_idx ==27) opt.max_clip_ratio = atof(optarg); // --max-clip-ratio
else if (c == 0 && long_idx ==28) opt.min_mid_occ = atoi(optarg); // --min-occ-floor else if (c == 0 && long_idx ==28) opt.min_mid_occ = atoi(optarg); // --min-occ-floor
else if (c == 0 && long_idx ==29) opt.flag |= MM_F_OUT_MD; // --MD else if (c == 0 && long_idx ==29) opt.flag |= MM_F_OUT_MD; // --MD
else if (c == 0 && long_idx ==30) opt.min_join_flank_ratio = atof(optarg); // --lj-min-ratio
else if (c == 0 && long_idx ==31) opt.sc_ambi = atoi(optarg); // --score-N
else if (c == 0 && long_idx ==32) opt.flag |= MM_F_EQX; // --eqx
else if (c == 0 && long_idx == 14) { // --frag else if (c == 0 && long_idx == 14) { // --frag
yes_or_no(&opt, MM_F_FRAG_MODE, long_idx, optarg, 1); yes_or_no(&opt, MM_F_FRAG_MODE, long_idx, optarg, 1);
} else if (c == 0 && long_idx == 15) { // --secondary } else if (c == 0 && long_idx == 15) { // --secondary
@@ -241,7 +247,7 @@ int main(int argc, char *argv[])
fprintf(fp_help, "Usage: minimap2 [options] <target.fa>|<target.idx> [query.fa] [...]\n"); fprintf(fp_help, "Usage: minimap2 [options] <target.fa>|<target.idx> [query.fa] [...]\n");
fprintf(fp_help, "Options:\n"); fprintf(fp_help, "Options:\n");
fprintf(fp_help, " Indexing:\n"); fprintf(fp_help, " Indexing:\n");
fprintf(fp_help, " -H use homopolymer-compressed k-mer\n"); fprintf(fp_help, " -H use homopolymer-compressed k-mer (preferrable for PacBio)\n");
fprintf(fp_help, " -k INT k-mer size (no larger than 28) [%d]\n", ipt.k); fprintf(fp_help, " -k INT k-mer size (no larger than 28) [%d]\n", ipt.k);
fprintf(fp_help, " -w INT minizer window size [%d]\n", ipt.w); fprintf(fp_help, " -w INT minizer window size [%d]\n", ipt.w);
fprintf(fp_help, " -I NUM split index for every ~NUM input bases [4G]\n"); fprintf(fp_help, " -I NUM split index for every ~NUM input bases [4G]\n");
@@ -274,21 +280,19 @@ int main(int argc, char *argv[])
fprintf(fp_help, " -c output CIGAR in PAF\n"); fprintf(fp_help, " -c output CIGAR in PAF\n");
fprintf(fp_help, " --cs[=STR] output the cs tag; STR is 'short' (if absent) or 'long' [none]\n"); fprintf(fp_help, " --cs[=STR] output the cs tag; STR is 'short' (if absent) or 'long' [none]\n");
fprintf(fp_help, " --MD output the MD tag\n"); fprintf(fp_help, " --MD output the MD tag\n");
fprintf(fp_help, " --eqx write =/X CIGAR operators\n");
fprintf(fp_help, " -Y use soft clipping for supplementary alignments\n"); fprintf(fp_help, " -Y use soft clipping for supplementary alignments\n");
fprintf(fp_help, " -t INT number of threads [%d]\n", n_threads); fprintf(fp_help, " -t INT number of threads [%d]\n", n_threads);
fprintf(fp_help, " -K NUM minibatch size for mapping [500M]\n"); fprintf(fp_help, " -K NUM minibatch size for mapping [500M]\n");
// fprintf(fp_help, " -v INT verbose level [%d]\n", mm_verbose); // fprintf(fp_help, " -v INT verbose level [%d]\n", mm_verbose);
fprintf(fp_help, " --version show version number\n"); fprintf(fp_help, " --version show version number\n");
fprintf(fp_help, " Preset:\n"); fprintf(fp_help, " Preset:\n");
fprintf(fp_help, " -x STR preset (always applied before other options) []\n"); fprintf(fp_help, " -x STR preset (always applied before other options; see minimap2.1 for details) []\n");
fprintf(fp_help, " map-pb: -Hk19 (PacBio vs reference mapping)\n"); fprintf(fp_help, " - map-pb/map-ont: PacBio/Nanopore vs reference mapping\n");
fprintf(fp_help, " map-ont: -k15 (Oxford Nanopore vs reference mapping)\n"); fprintf(fp_help, " - ava-pb/ava-ont: PacBio/Nanopore read overlap\n");
fprintf(fp_help, " asm5: -k19 -w19 -A1 -B19 -O39,81 -E3,1 -s200 -z200 (asm to ref mapping; break at 5%% div.)\n"); fprintf(fp_help, " - asm5/asm10/asm20: asm-to-ref mapping, for ~0.1/1/5%% sequence divergence\n");
fprintf(fp_help, " asm10: -k19 -w19 -A1 -B9 -O16,41 -E2,1 -s200 -z200 (asm to ref mapping; break at 10%% div.)\n"); fprintf(fp_help, " - splice: long-read spliced alignment\n");
fprintf(fp_help, " ava-pb: -Hk19 -Xw5 -m100 -g10000 --max-chain-skip 25 (PacBio read overlap)\n"); fprintf(fp_help, " - sr: genomic short-read mapping\n");
fprintf(fp_help, " ava-ont: -k15 -Xw5 -m100 -g10000 -r2000 --max-chain-skip 25 (ONT read overlap)\n");
fprintf(fp_help, " splice: long-read spliced alignment (see minimap2.1 for details)\n");
fprintf(fp_help, " sr: short single-end reads without splicing (see minimap2.1 for details)\n");
fprintf(fp_help, "\nSee `man ./minimap2.1' for detailed description of command-line options.\n"); fprintf(fp_help, "\nSee `man ./minimap2.1' for detailed description of command-line options.\n");
return fp_help == stdout? 0 : 1; return fp_help == stdout? 0 : 1;
} }
+28 -24
View File
@@ -39,12 +39,12 @@ static int mm_dust_minier(void *km, int n, mm128_t *a, int l_seq, const char *se
for (j = k = 0; j < n; ++j) { // squeeze out minimizers that significantly overlap with LCRs for (j = k = 0; j < n; ++j) { // squeeze out minimizers that significantly overlap with LCRs
int32_t qpos = (uint32_t)a[j].y>>1, span = a[j].x&0xff; int32_t qpos = (uint32_t)a[j].y>>1, span = a[j].x&0xff;
int32_t s = qpos - (span - 1), e = s + span; int32_t s = qpos - (span - 1), e = s + span;
while (u < n_dreg && (uint32_t)dreg[u] <= s) ++u; while (u < n_dreg && (int32_t)dreg[u] <= s) ++u;
if (u < n_dreg && dreg[u]>>32 < e) { if (u < n_dreg && (int32_t)(dreg[u]>>32) < e) {
int v, l = 0; int v, l = 0;
for (v = u; v < n_dreg && dreg[v]>>32 < e; ++v) { // iterate over LCRs overlapping this minimizer for (v = u; v < n_dreg && (int32_t)(dreg[v]>>32) < e; ++v) { // iterate over LCRs overlapping this minimizer
int ss = s > dreg[v]>>32? s : dreg[v]>>32; int ss = s > (int32_t)(dreg[v]>>32)? s : dreg[v]>>32;
int ee = e < (uint32_t)dreg[v]? e : (uint32_t)dreg[v]; int ee = e < (int32_t)dreg[v]? e : (uint32_t)dreg[v];
l += ee - ss; l += ee - ss;
} }
if (l <= span>>1) a[k++] = a[j]; // keep the minimizer if less than half of it falls in masked region if (l <= span>>1) a[k++] = a[j]; // keep the minimizer if less than half of it falls in masked region
@@ -56,9 +56,10 @@ static int mm_dust_minier(void *km, int n, mm128_t *a, int l_seq, const char *se
static void collect_minimizers(void *km, const mm_mapopt_t *opt, const mm_idx_t *mi, int n_segs, const int *qlens, const char **seqs, mm128_v *mv) static void collect_minimizers(void *km, const mm_mapopt_t *opt, const mm_idx_t *mi, int n_segs, const int *qlens, const char **seqs, mm128_v *mv)
{ {
int i, j, n, sum = 0; int i, n, sum = 0;
mv->n = 0; mv->n = 0;
for (i = n = 0; i < n_segs; ++i) { for (i = n = 0; i < n_segs; ++i) {
size_t j;
mm_sketch(km, seqs[i], qlens[i], mi->w, mi->k, i, mi->flag&MM_I_HPC, mv); mm_sketch(km, seqs[i], qlens[i], mi->w, mi->k, i, mi->flag&MM_I_HPC, mv);
for (j = n; j < mv->n; ++j) for (j = n; j < mv->n; ++j)
mv->a[j].y += sum << 1; mv->a[j].y += sum << 1;
@@ -81,12 +82,13 @@ typedef struct {
static mm_match_t *collect_matches(void *km, int *_n_m, int max_occ, const mm_idx_t *mi, const mm128_v *mv, int64_t *n_a, int *rep_len, int *n_mini_pos, uint64_t **mini_pos) static mm_match_t *collect_matches(void *km, int *_n_m, int max_occ, const mm_idx_t *mi, const mm128_v *mv, int64_t *n_a, int *rep_len, int *n_mini_pos, uint64_t **mini_pos)
{ {
int i, rep_st = 0, rep_en = 0, n_m; int rep_st = 0, rep_en = 0, n_m;
size_t i;
mm_match_t *m; mm_match_t *m;
*n_mini_pos = 0; *n_mini_pos = 0;
*mini_pos = (uint64_t*)kmalloc(km, mv->n * sizeof(uint64_t)); *mini_pos = (uint64_t*)kmalloc(km, mv->n * sizeof(uint64_t));
m = (mm_match_t*)kmalloc(km, mv->n * sizeof(mm_match_t)); m = (mm_match_t*)kmalloc(km, mv->n * sizeof(mm_match_t));
for (i = n_m = 0, *rep_len = 0, *n_a = 0; i < mv->n; ++i) { for (i = 0, n_m = 0, *rep_len = 0, *n_a = 0; i < mv->n; ++i) {
const uint64_t *cr; const uint64_t *cr;
mm128_t *p = &mv->a[i]; mm128_t *p = &mv->a[i];
uint32_t q_pos = (uint32_t)p->y, q_span = p->x & 0xff; uint32_t q_pos = (uint32_t)p->y, q_span = p->x & 0xff;
@@ -120,7 +122,7 @@ static inline int skip_seed(int flag, uint64_t r, const mm_match_t *q, const cha
const mm_idx_seq_t *s = &mi->seq[r>>32]; const mm_idx_seq_t *s = &mi->seq[r>>32];
int cmp; int cmp;
cmp = strcmp(qname, s->name); cmp = strcmp(qname, s->name);
if ((flag&MM_F_NO_DIAG) && cmp == 0 && s->len == qlen) { if ((flag&MM_F_NO_DIAG) && cmp == 0 && (int)s->len == qlen) {
if ((uint32_t)r>>1 == (q->q_pos>>1)) return 1; // avoid the diagnonal anchors if ((uint32_t)r>>1 == (q->q_pos>>1)) return 1; // avoid the diagnonal anchors
if ((r&1) == (q->q_pos&1)) *is_self = 1; // this flag is used to avoid spurious extension on self chain if ((r&1) == (q->q_pos&1)) *is_self = 1; // this flag is used to avoid spurious extension on self chain
} }
@@ -163,19 +165,20 @@ static mm128_t *collect_seed_hits_heap(void *km, const mm_mapopt_t *opt, int max
mm128_t *p; mm128_t *p;
uint64_t r = heap->x; uint64_t r = heap->x;
int32_t is_self, rpos = (uint32_t)r >> 1; int32_t is_self, rpos = (uint32_t)r >> 1;
if (skip_seed(opt->flag, r, q, qname, qlen, mi, &is_self)) continue; if (!skip_seed(opt->flag, r, q, qname, qlen, mi, &is_self)) {
if ((r&1) == (q->q_pos&1)) { // forward strand if ((r&1) == (q->q_pos&1)) { // forward strand
p = &a[n_for++]; p = &a[n_for++];
p->x = (r&0xffffffff00000000ULL) | rpos; p->x = (r&0xffffffff00000000ULL) | rpos;
p->y = (uint64_t)q->q_span << 32 | q->q_pos >> 1; p->y = (uint64_t)q->q_span << 32 | q->q_pos >> 1;
} else { // reverse strand } else { // reverse strand
p = &a[(*n_a) - (++n_rev)]; p = &a[(*n_a) - (++n_rev)];
p->x = 1ULL<<63 | (r&0xffffffff00000000ULL) | rpos; p->x = 1ULL<<63 | (r&0xffffffff00000000ULL) | rpos;
p->y = (uint64_t)q->q_span << 32 | (qlen - ((q->q_pos>>1) + 1 - q->q_span) - 1); p->y = (uint64_t)q->q_span << 32 | (qlen - ((q->q_pos>>1) + 1 - q->q_span) - 1);
}
p->y |= (uint64_t)q->seg_id << MM_SEED_SEG_SHIFT;
if (q->is_tandem) p->y |= MM_SEED_TANDEM;
if (is_self) p->y |= MM_SEED_SELF;
} }
p->y |= (uint64_t)q->seg_id << MM_SEED_SEG_SHIFT;
if (q->is_tandem) p->y |= MM_SEED_TANDEM;
if (is_self) p->y |= MM_SEED_SELF;
// update the heap // update the heap
if ((uint32_t)heap->y < q->n - 1) { if ((uint32_t)heap->y < q->n - 1) {
++heap[0].y; ++heap[0].y;
@@ -205,7 +208,7 @@ static mm128_t *collect_seed_hits_heap(void *km, const mm_mapopt_t *opt, int max
static mm128_t *collect_seed_hits(void *km, const mm_mapopt_t *opt, int max_occ, const mm_idx_t *mi, const char *qname, const mm128_v *mv, int qlen, int64_t *n_a, int *rep_len, static mm128_t *collect_seed_hits(void *km, const mm_mapopt_t *opt, int max_occ, const mm_idx_t *mi, const char *qname, const mm128_v *mv, int qlen, int64_t *n_a, int *rep_len,
int *n_mini_pos, uint64_t **mini_pos) int *n_mini_pos, uint64_t **mini_pos)
{ {
int i, k, n_m; int i, n_m;
mm_match_t *m; mm_match_t *m;
mm128_t *a; mm128_t *a;
m = collect_matches(km, &n_m, max_occ, mi, mv, n_a, rep_len, n_mini_pos, mini_pos); m = collect_matches(km, &n_m, max_occ, mi, mv, n_a, rep_len, n_mini_pos, mini_pos);
@@ -213,6 +216,7 @@ static mm128_t *collect_seed_hits(void *km, const mm_mapopt_t *opt, int max_occ,
for (i = 0, *n_a = 0; i < n_m; ++i) { for (i = 0, *n_a = 0; i < n_m; ++i) {
mm_match_t *q = &m[i]; mm_match_t *q = &m[i];
const uint64_t *r = q->cr; const uint64_t *r = q->cr;
uint32_t k;
for (k = 0; k < q->n; ++k) { for (k = 0; k < q->n; ++k) {
int32_t is_self, rpos = (uint32_t)r[k] >> 1; int32_t is_self, rpos = (uint32_t)r[k] >> 1;
mm128_t *p; mm128_t *p;
@@ -308,10 +312,10 @@ void mm_map_frag(const mm_idx_t *mi, int n_segs, const int *qlens, const char **
if (n_regs0 > 0) { // test if the best chain has all the segments if (n_regs0 > 0) { // test if the best chain has all the segments
int n_chained_segs = 1, max = 0, max_i = -1, max_off = -1, off = 0; int n_chained_segs = 1, max = 0, max_i = -1, max_off = -1, off = 0;
for (i = 0; i < n_regs0; ++i) { // find the best chain for (i = 0; i < n_regs0; ++i) { // find the best chain
if (max < u[i]>>32) max = u[i]>>32, max_i = i, max_off = off; if (max < (int)(u[i]>>32)) max = u[i]>>32, max_i = i, max_off = off;
off += (uint32_t)u[i]; off += (uint32_t)u[i];
} }
for (i = 1; i < (uint32_t)u[max_i]; ++i) // count the number of segments in the best chain for (i = 1; i < (int32_t)u[max_i]; ++i) // count the number of segments in the best chain
if ((a[max_off+i].y&MM_SEED_SEG_MASK) != (a[max_off+i-1].y&MM_SEED_SEG_MASK)) if ((a[max_off+i].y&MM_SEED_SEG_MASK) != (a[max_off+i-1].y&MM_SEED_SEG_MASK))
++n_chained_segs; ++n_chained_segs;
if (n_chained_segs < n_segs) if (n_chained_segs < n_segs)
+33
View File
@@ -31,6 +31,7 @@
#define MM_F_ALL_CHAINS 0x800000 #define MM_F_ALL_CHAINS 0x800000
#define MM_F_OUT_MD 0x1000000 #define MM_F_OUT_MD 0x1000000
#define MM_F_COPY_COMMENT 0x2000000 #define MM_F_COPY_COMMENT 0x2000000
#define MM_F_EQX 0x4000000 // use =/X instead of M
#define MM_I_HPC 0x1 #define MM_I_HPC 0x1
#define MM_I_NO_SEQ 0x2 #define MM_I_NO_SEQ 0x2
@@ -115,8 +116,10 @@ typedef struct {
int max_join_long, max_join_short; int max_join_long, max_join_short;
int min_join_flank_sc; int min_join_flank_sc;
float min_join_flank_ratio;
int a, b, q, e, q2, e2; // matching score, mismatch, gap-open and gap-ext penalties int a, b, q, e, q2, e2; // matching score, mismatch, gap-open and gap-ext penalties
int sc_ambi; // score when one or both bases are "N"
int noncan; // cost of non-canonical splicing sites int noncan; // cost of non-canonical splicing sites
int zdrop, zdrop_inv; // break alignment if alignment score drops too fast along the diagonal int zdrop, zdrop_inv; // break alignment if alignment score drops too fast along the diagonal
int end_bonus; int end_bonus;
@@ -216,6 +219,36 @@ void mm_idx_reader_close(mm_idx_reader_t *r);
int mm_idx_reader_eof(const mm_idx_reader_t *r); int mm_idx_reader_eof(const mm_idx_reader_t *r);
/**
* Check whether the file contains a minimap2 index
*
* @param fn file name
*
* @return the file size if fn is an index file; 0 if fn is not.
*/
int64_t mm_idx_is_idx(const char *fn);
/**
* Load a part of an index
*
* Given a uni-part index, this function loads the entire index into memory.
* Given a multi-part index, it loads one part only and places the file pointer
* at the end of that part.
*
* @param fp pointer to FILE object
*
* @return minimap2 index read from fp
*/
mm_idx_t *mm_idx_load(FILE *fp);
/**
* Append an index (or one part of a full index) to file
*
* @param fp pointer to FILE object
* @param mi minimap2 index
*/
void mm_idx_dump(FILE *fp, const mm_idx_t *mi);
/** /**
* Create an index from strings in memory * Create an index from strings in memory
* *
+12 -1
View File
@@ -1,4 +1,4 @@
.TH minimap2 1 "27 March 2018" "minimap2-2.10 (r761)" "Bioinformatics tools" .TH minimap2 1 "20 June 2018" "minimap2-2.11 (r797)" "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
@@ -239,6 +239,10 @@ Disable the long gap patching heuristic. When this option is applied, the
maximum alignment gap is mostly controlled by maximum alignment gap is mostly controlled by
.BR -r . .BR -r .
.TP .TP
.B --lj-min-ratio \ FLOAT
Fraction of query sequence length required to bridge a long gap [0.5]. A
smaller value helps to recover longer gaps, at the cost of more false gaps.
.TP
.B --splice .B --splice
Enable the splice alignment mode. Enable the splice alignment mode.
.TP .TP
@@ -322,6 +326,9 @@ no attempt to match GT-AG [n]
.BI --end-bonus \ INT .BI --end-bonus \ INT
Score bonus when alignment extends to the end of the query sequence [0]. Score bonus when alignment extends to the end of the query sequence [0].
.TP .TP
.BI --score-N \ INT
Score of a mismatch involving ambiguous bases [1].
.TP
.BR --splice-flank = yes | no .BR --splice-flank = yes | no
Assume the next base to a Assume the next base to a
.B GT .B GT
@@ -394,6 +401,9 @@ is assumed. [none]
.B --MD .B --MD
Output the MD tag (see the SAM spec). Output the MD tag (see the SAM spec).
.TP .TP
.B --eqx
Output =/X CIGAR operators for sequence match/mismatch.
.TP
.B -Y .B -Y
In SAM output, use soft clipping for supplementary alignments. In SAM output, use soft clipping for supplementary alignments.
.TP .TP
@@ -572,6 +582,7 @@ nn i Number of ambiguous bases in the alignment
ts A Transcript strand (splice mode only) ts A Transcript strand (splice mode only)
cg Z CIGAR string (only in PAF) cg Z CIGAR string (only in PAF)
cs Z Difference string cs Z Difference string
dv f Approximate per-base sequence divergence
.TE .TE
.PP .PP
+7 -5
View File
@@ -1,6 +1,6 @@
#!/usr/bin/env k8 #!/usr/bin/env k8
var paftools_version = 'r755'; var paftools_version = 'r767';
/***************************** /*****************************
***** Library functions ***** ***** Library functions *****
@@ -484,7 +484,7 @@ function paf_call(args)
// drop alignments that don't overlap with the current one // drop alignments that don't overlap with the current one
var k = 0; var k = 0;
for (var i = 0; i < a.length; ++i) for (var i = 0; i < a.length; ++i)
if (a[0][0] == ctg && a[0][2] > x) if (a[i][0] == ctg && a[i][2] > x)
a[k++] = a[i]; a[k++] = a[i];
a.length = k; a.length = k;
// core loop // core loop
@@ -496,7 +496,7 @@ function paf_call(args)
var cov = 1; var cov = 1;
if (m[1] == '*' || m[1] == '+' || m[1] == '-') if (m[1] == '*' || m[1] == '+' || m[1] == '-')
for (var i = 0; i < a.length; ++i) for (var i = 0; i < a.length; ++i)
if (a[0][2] > x) ++cov; if (a[i][2] > x) ++cov;
var qs, qe; var qs, qe;
if (m[1] == '=' || m[1] == ':') { if (m[1] == '=' || m[1] == ':') {
var l = m[1] == '='? m[2].length : parseInt(m[2]); var l = m[1] == '='? m[2].length : parseInt(m[2]);
@@ -676,8 +676,10 @@ function paf_stat(args)
last_qlen = ori_qlen; last_qlen = ori_qlen;
} }
} }
l_tot += last_qlen; if (regs.length) {
l_cov += cov_len(regs); l_tot += last_qlen;
l_cov += cov_len(regs);
}
file.close(); file.close();
buf.destroy(); buf.destroy();
+1 -1
View File
@@ -75,7 +75,7 @@ int mm_set_sam_pri(int n, mm_reg1_t *r);
void mm_set_parent(void *km, float mask_level, int n, mm_reg1_t *r, int sub_diff); void mm_set_parent(void *km, float mask_level, int n, mm_reg1_t *r, int sub_diff);
void mm_select_sub(void *km, float pri_ratio, int min_diff, int best_n, int *n_, mm_reg1_t *r); void mm_select_sub(void *km, float pri_ratio, int min_diff, int best_n, int *n_, mm_reg1_t *r);
void mm_select_sub_multi(void *km, float pri_ratio, float pri1, float pri2, int max_gap_ref, int min_diff, int best_n, int n_segs, const int *qlens, int *n_, mm_reg1_t *r); void mm_select_sub_multi(void *km, float pri_ratio, float pri1, float pri2, int max_gap_ref, int min_diff, int best_n, int n_segs, const int *qlens, int *n_, mm_reg1_t *r);
void mm_filter_regs(void *km, const mm_mapopt_t *opt, int qlen, int *n_regs, mm_reg1_t *regs); void mm_filter_regs(const mm_mapopt_t *opt, int qlen, int *n_regs, mm_reg1_t *regs);
void mm_join_long(void *km, const mm_mapopt_t *opt, int qlen, int *n_regs, mm_reg1_t *regs, mm128_t *a); void mm_join_long(void *km, const mm_mapopt_t *opt, int qlen, int *n_regs, mm_reg1_t *regs, mm128_t *a);
void mm_hit_sort_by_dp(void *km, int *n_regs, mm_reg1_t *r); void mm_hit_sort_by_dp(void *km, int *n_regs, mm_reg1_t *r);
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_set_mapq(void *km, int n_regs, mm_reg1_t *regs, int min_chain_sc, int match_sc, int rep_len, int is_sr);
+8 -1
View File
@@ -31,8 +31,10 @@ void mm_mapopt_init(mm_mapopt_t *opt)
opt->max_join_long = 20000; opt->max_join_long = 20000;
opt->max_join_short = 2000; opt->max_join_short = 2000;
opt->min_join_flank_sc = 1000; opt->min_join_flank_sc = 1000;
opt->min_join_flank_ratio = 0.5f;
opt->a = 2, opt->b = 4, opt->q = 4, opt->e = 2, opt->q2 = 24, opt->e2 = 1; opt->a = 2, opt->b = 4, opt->q = 4, opt->e = 2, opt->q2 = 24, opt->e2 = 1;
opt->sc_ambi = 1;
opt->zdrop = 400, opt->zdrop_inv = 200; opt->zdrop = 400, opt->zdrop_inv = 200;
opt->end_bonus = -1; opt->end_bonus = -1;
opt->min_dp_max = opt->min_chain_score * opt->a; opt->min_dp_max = opt->min_chain_score * opt->a;
@@ -72,11 +74,11 @@ int mm_set_opt(const char *preset, mm_idxopt_t *io, mm_mapopt_t *mo)
io->flag = 0, io->k = 15, io->w = 5; io->flag = 0, io->k = 15, io->w = 5;
mo->flag |= MM_F_ALL_CHAINS | MM_F_NO_DIAG | MM_F_NO_DUAL | MM_F_NO_LJOIN; mo->flag |= MM_F_ALL_CHAINS | MM_F_NO_DIAG | MM_F_NO_DUAL | MM_F_NO_LJOIN;
mo->min_chain_score = 100, mo->pri_ratio = 0.0f, mo->max_gap = 10000, mo->max_chain_skip = 25; mo->min_chain_score = 100, mo->pri_ratio = 0.0f, mo->max_gap = 10000, mo->max_chain_skip = 25;
mo->bw = 2000;
} else if (strcmp(preset, "ava-pb") == 0) { } else if (strcmp(preset, "ava-pb") == 0) {
io->flag |= MM_I_HPC, io->k = 19, io->w = 5; io->flag |= MM_I_HPC, io->k = 19, io->w = 5;
mo->flag |= MM_F_ALL_CHAINS | MM_F_NO_DIAG | MM_F_NO_DUAL | MM_F_NO_LJOIN; mo->flag |= MM_F_ALL_CHAINS | MM_F_NO_DIAG | MM_F_NO_DUAL | MM_F_NO_LJOIN;
mo->min_chain_score = 100, mo->pri_ratio = 0.0f, mo->max_gap = 10000, mo->max_chain_skip = 25; mo->min_chain_score = 100, mo->pri_ratio = 0.0f, mo->max_gap = 10000, mo->max_chain_skip = 25;
mo->bw = 2000;
} else if (strcmp(preset, "map10k") == 0 || strcmp(preset, "map-pb") == 0) { } else if (strcmp(preset, "map10k") == 0 || strcmp(preset, "map-pb") == 0) {
io->flag |= MM_I_HPC, io->k = 19; io->flag |= MM_I_HPC, io->k = 19;
} else if (strcmp(preset, "map-ont") == 0) { } else if (strcmp(preset, "map-ont") == 0) {
@@ -130,6 +132,11 @@ int mm_set_opt(const char *preset, mm_idxopt_t *io, mm_mapopt_t *mo)
int mm_check_opt(const mm_idxopt_t *io, const mm_mapopt_t *mo) int mm_check_opt(const mm_idxopt_t *io, const mm_mapopt_t *mo)
{ {
if (io->k <= 0 || io->w <= 0) {
if (mm_verbose >= 1)
fprintf(stderr, "[ERROR]\033[1;31m -k and -w must be positive\033[0m\n");
return -5;
}
if (mo->best_n < 0) { if (mo->best_n < 0) {
if (mm_verbose >= 1) if (mm_verbose >= 1)
fprintf(stderr, "[ERROR]\033[1;31m -N must be no less than 0\033[0m\n"); fprintf(stderr, "[ERROR]\033[1;31m -N must be no less than 0\033[0m\n");
+4 -4
View File
@@ -105,7 +105,7 @@ void mm_pair(void *km, int max_gap_ref, int pe_bonus, int sub_diff, int match_sc
max = -1; max = -1;
max_idx[0] = max_idx[1] = -1; max_idx[0] = max_idx[1] = -1;
last[0] = last[1] = -1; last[0] = last[1] = -1;
kv_resize(uint64_t, km, sc, n); kv_resize(uint64_t, km, sc, (size_t)n);
for (i = 0; i < n; ++i) { for (i = 0; i < n; ++i) {
if (a[i].key & 1) { // reverse first read or forward second read if (a[i].key & 1) { // reverse first read or forward second read
mm_reg1_t *q, *r; mm_reg1_t *q, *r;
@@ -151,8 +151,8 @@ void mm_pair(void *km, int max_gap_ref, int pe_bonus, int sub_diff, int match_sc
} }
} }
mapq_pe = r[0]->mapq > r[1]->mapq? r[0]->mapq : r[1]->mapq; mapq_pe = r[0]->mapq > r[1]->mapq? r[0]->mapq : r[1]->mapq;
for (i = 0; i < sc.n; ++i) for (i = 0; i < (int)sc.n; ++i)
if ((sc.a[i]>>32) + sub_diff >= max>>32) if ((sc.a[i]>>32) + sub_diff >= (uint64_t)max>>32)
++n_sub; ++n_sub;
if (sc.n > 1) { if (sc.n > 1) {
int mapq_pe_alt; int mapq_pe_alt;
@@ -164,7 +164,7 @@ void mm_pair(void *km, int max_gap_ref, int pe_bonus, int sub_diff, int match_sc
if (sc.n == 1) { if (sc.n == 1) {
if (r[0]->mapq < 2) r[0]->mapq = 2; if (r[0]->mapq < 2) r[0]->mapq = 2;
if (r[1]->mapq < 2) r[1]->mapq = 2; if (r[1]->mapq < 2) r[1]->mapq = 2;
} else if (max>>32 > sc.a[sc.n - 2]>>32) { } else if ((uint64_t)max>>32 > sc.a[sc.n - 2]>>32) {
if (r[0]->mapq < 1) r[0]->mapq = 1; if (r[0]->mapq < 1) r[0]->mapq = 1;
if (r[1]->mapq < 1) r[1]->mapq = 1; if (r[1]->mapq < 1) r[1]->mapq = 1;
} }
+2
View File
@@ -24,7 +24,9 @@ cdef extern from "minimap.h":
int best_n int best_n
int max_join_long, max_join_short int max_join_long, max_join_short
int min_join_flank_sc int min_join_flank_sc
float min_join_flank_ratio;
int a, b, q, e, q2, e2 int a, b, q, e, q2, e2
int sc_ambi
int noncan int noncan
int zdrop, zdrop_inv int zdrop, zdrop_inv
int end_bonus int end_bonus
+10 -4
View File
@@ -3,6 +3,8 @@ from libc.stdlib cimport free
cimport cmappy cimport cmappy
import sys import sys
__version__ = '2.11'
cmappy.mm_reset_timer() cmappy.mm_reset_timer()
cdef class Alignment: cdef class Alignment:
@@ -100,7 +102,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, 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): def __cinit__(self, fn_idx_in, 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):
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
@@ -113,6 +115,7 @@ cdef class Aligner:
if min_dp_score is not None: self.map_opt.min_dp_max = min_dp_score if min_dp_score is not None: self.map_opt.min_dp_max = min_dp_score
if bw is not None: self.map_opt.bw = bw if bw is not None: self.map_opt.bw = bw
if best_n is not None: self.map_opt.best_n = best_n if best_n is not None: self.map_opt.best_n = best_n
if max_frag_len is not None: self.map_opt.max_frag_len = max_frag_len
cdef cmappy.mm_idx_reader_t *r; cdef cmappy.mm_idx_reader_t *r;
if fn_idx_out is None: if fn_idx_out is None:
@@ -132,11 +135,14 @@ cdef class Aligner:
def __bool__(self): def __bool__(self):
return (self._idx != NULL) return (self._idx != NULL)
def map(self, seq, seq2=None, buf=None): def map(self, seq, seq2=None, buf=None, max_frag_len=None):
cdef cmappy.mm_reg1_t *regs cdef cmappy.mm_reg1_t *regs
cdef cmappy.mm_hitpy_t h cdef cmappy.mm_hitpy_t h
cdef ThreadBuffer b cdef ThreadBuffer b
cdef int n_regs cdef int n_regs
cdef cmappy.mm_mapopt_t map_opt
map_opt = self.map_opt
if max_frag_len is not None: map_opt.max_frag_len = max_frag_len
if self._idx is NULL: return None if self._idx is NULL: return None
if buf is None: b = ThreadBuffer() if buf is None: b = ThreadBuffer()
@@ -144,10 +150,10 @@ cdef class Aligner:
_seq = seq if isinstance(seq, bytes) else seq.encode() _seq = seq if isinstance(seq, bytes) else seq.encode()
if seq2 is None: if seq2 is None:
regs = cmappy.mm_map_aux(self._idx, _seq, NULL, &n_regs, b._b, &self.map_opt) regs = cmappy.mm_map_aux(self._idx, _seq, NULL, &n_regs, b._b, &map_opt)
else: else:
_seq2 = seq2 if isinstance(seq2, bytes) else seq2.encode() _seq2 = seq2 if isinstance(seq2, bytes) else seq2.encode()
regs = cmappy.mm_map_aux(self._idx, _seq, _seq2, &n_regs, b._b, &self.map_opt) regs = cmappy.mm_map_aux(self._idx, _seq, _seq2, &n_regs, b._b, &map_opt)
for i in range(n_regs): for i in range(n_regs):
cmappy.mm_reg2hitpy(self._idx, &regs[i], &h) cmappy.mm_reg2hitpy(self._idx, &regs[i], &h)
+3 -3
View File
@@ -70,10 +70,10 @@ void sdust_buf_destroy(sdust_buf_t *buf)
static inline void shift_window(int t, kdq_t(int) *w, int T, int W, int *L, int *rw, int *rv, int *cw, int *cv) static inline void shift_window(int t, kdq_t(int) *w, int T, int W, int *L, int *rw, int *rv, int *cw, int *cv)
{ {
int s; int s;
if (kdq_size(w) >= W - SD_WLEN + 1) { // TODO: is this right for SD_WLEN!=3? if ((int)kdq_size(w) >= W - SD_WLEN + 1) { // TODO: is this right for SD_WLEN!=3?
s = *kdq_shift(int, w); s = *kdq_shift(int, w);
*rw -= --cw[s]; *rw -= --cw[s];
if (*L > kdq_size(w)) if (*L > (int)kdq_size(w))
--*L, *rv -= --cv[s]; --*L, *rv -= --cv[s];
} }
kdq_push(int, w, t); kdq_push(int, w, t);
@@ -114,7 +114,7 @@ static void find_perfect(void *km, perf_intv_v *P, const kdq_t(int) *w, int T, i
r += c[t]++; r += c[t]++;
new_r = r, new_l = kdq_size(w) - i - 1; new_r = r, new_l = kdq_size(w) - i - 1;
if (new_r * 10 > T * new_l) { if (new_r * 10 > T * new_l) {
for (j = 0; j < P->n && P->a[j].start >= i + start; ++j) { // find insertion position for (j = 0; j < (int)P->n && P->a[j].start >= i + start; ++j) { // find insertion position
perf_intv_t *p = &P->a[j]; perf_intv_t *p = &P->a[j];
if (max_r == 0 || p->r * max_l > max_r * p->l) if (max_r == 0 || p->r * max_l > max_r * p->l)
max_r = p->r, max_l = p->l; max_r = p->r, max_l = p->l;
+1 -1
View File
@@ -23,7 +23,7 @@ def readme():
setup( setup(
name = 'mappy', name = 'mappy',
version = '2.10', version = '2.11',
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(),