minimap2 0.0.4 → 0.2.23.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +113 -98
  3. data/ext/Rakefile +41 -0
  4. data/ext/cmappy/cmappy.c +129 -0
  5. data/ext/cmappy/cmappy.h +44 -0
  6. data/ext/minimap2/FAQ.md +46 -0
  7. data/ext/minimap2/LICENSE.txt +24 -0
  8. data/ext/minimap2/MANIFEST.in +10 -0
  9. data/ext/minimap2/Makefile +132 -0
  10. data/ext/minimap2/Makefile.simde +97 -0
  11. data/ext/minimap2/NEWS.md +807 -0
  12. data/ext/minimap2/README.md +403 -0
  13. data/ext/minimap2/align.c +1020 -0
  14. data/ext/minimap2/bseq.c +169 -0
  15. data/ext/minimap2/bseq.h +64 -0
  16. data/ext/minimap2/code_of_conduct.md +30 -0
  17. data/ext/minimap2/cookbook.md +243 -0
  18. data/ext/minimap2/esterr.c +64 -0
  19. data/ext/minimap2/example.c +63 -0
  20. data/ext/minimap2/format.c +559 -0
  21. data/ext/minimap2/hit.c +466 -0
  22. data/ext/minimap2/index.c +775 -0
  23. data/ext/minimap2/kalloc.c +205 -0
  24. data/ext/minimap2/kalloc.h +76 -0
  25. data/ext/minimap2/kdq.h +132 -0
  26. data/ext/minimap2/ketopt.h +120 -0
  27. data/ext/minimap2/khash.h +615 -0
  28. data/ext/minimap2/krmq.h +474 -0
  29. data/ext/minimap2/kseq.h +256 -0
  30. data/ext/minimap2/ksort.h +153 -0
  31. data/ext/minimap2/ksw2.h +184 -0
  32. data/ext/minimap2/ksw2_dispatch.c +96 -0
  33. data/ext/minimap2/ksw2_extd2_sse.c +402 -0
  34. data/ext/minimap2/ksw2_exts2_sse.c +416 -0
  35. data/ext/minimap2/ksw2_extz2_sse.c +313 -0
  36. data/ext/minimap2/ksw2_ll_sse.c +152 -0
  37. data/ext/minimap2/kthread.c +159 -0
  38. data/ext/minimap2/kthread.h +15 -0
  39. data/ext/minimap2/kvec.h +105 -0
  40. data/ext/minimap2/lchain.c +344 -0
  41. data/ext/minimap2/main.c +455 -0
  42. data/ext/minimap2/map.c +714 -0
  43. data/ext/minimap2/minimap.h +409 -0
  44. data/ext/minimap2/minimap2.1 +722 -0
  45. data/ext/minimap2/misc/README.md +179 -0
  46. data/ext/minimap2/misc/mmphase.js +335 -0
  47. data/ext/minimap2/misc/paftools.js +3149 -0
  48. data/ext/minimap2/misc.c +162 -0
  49. data/ext/minimap2/mmpriv.h +131 -0
  50. data/ext/minimap2/options.c +233 -0
  51. data/ext/minimap2/pe.c +177 -0
  52. data/ext/minimap2/python/README.rst +196 -0
  53. data/ext/minimap2/python/cmappy.h +152 -0
  54. data/ext/minimap2/python/cmappy.pxd +153 -0
  55. data/ext/minimap2/python/mappy.pyx +273 -0
  56. data/ext/minimap2/python/minimap2.py +39 -0
  57. data/ext/minimap2/sdust.c +213 -0
  58. data/ext/minimap2/sdust.h +25 -0
  59. data/ext/minimap2/seed.c +131 -0
  60. data/ext/minimap2/setup.py +55 -0
  61. data/ext/minimap2/sketch.c +143 -0
  62. data/ext/minimap2/splitidx.c +84 -0
  63. data/ext/minimap2/sse2neon/emmintrin.h +1689 -0
  64. data/ext/minimap2/test/MT-human.fa +278 -0
  65. data/ext/minimap2/test/MT-orang.fa +276 -0
  66. data/ext/minimap2/test/q-inv.fa +4 -0
  67. data/ext/minimap2/test/q2.fa +2 -0
  68. data/ext/minimap2/test/t-inv.fa +127 -0
  69. data/ext/minimap2/test/t2.fa +2 -0
  70. data/ext/minimap2/tex/Makefile +21 -0
  71. data/ext/minimap2/tex/bioinfo.cls +930 -0
  72. data/ext/minimap2/tex/blasr-mc.eval +17 -0
  73. data/ext/minimap2/tex/bowtie2-s3.sam.eval +28 -0
  74. data/ext/minimap2/tex/bwa-s3.sam.eval +52 -0
  75. data/ext/minimap2/tex/bwa.eval +55 -0
  76. data/ext/minimap2/tex/eval2roc.pl +33 -0
  77. data/ext/minimap2/tex/graphmap.eval +4 -0
  78. data/ext/minimap2/tex/hs38-simu.sh +10 -0
  79. data/ext/minimap2/tex/minialign.eval +49 -0
  80. data/ext/minimap2/tex/minimap2.bib +460 -0
  81. data/ext/minimap2/tex/minimap2.tex +724 -0
  82. data/ext/minimap2/tex/mm2-s3.sam.eval +62 -0
  83. data/ext/minimap2/tex/mm2-update.tex +240 -0
  84. data/ext/minimap2/tex/mm2.approx.eval +12 -0
  85. data/ext/minimap2/tex/mm2.eval +13 -0
  86. data/ext/minimap2/tex/natbib.bst +1288 -0
  87. data/ext/minimap2/tex/natbib.sty +803 -0
  88. data/ext/minimap2/tex/ngmlr.eval +38 -0
  89. data/ext/minimap2/tex/roc.gp +60 -0
  90. data/ext/minimap2/tex/snap-s3.sam.eval +62 -0
  91. data/ext/minimap2.patch +19 -0
  92. data/ext/vendor/libminimap2.so +0 -0
  93. data/lib/minimap2/aligner.rb +16 -5
  94. data/lib/minimap2/alignment.rb +6 -2
  95. data/lib/minimap2/ffi/constants.rb +74 -53
  96. data/lib/minimap2/ffi/functions.rb +5 -0
  97. data/lib/minimap2/ffi.rb +1 -2
  98. data/lib/minimap2/version.rb +2 -1
  99. data/lib/minimap2.rb +67 -22
  100. metadata +98 -64
  101. data/lib/minimap2/ffi_helper.rb +0 -53
@@ -0,0 +1,105 @@
1
+ /* The MIT License
2
+
3
+ Copyright (c) 2008, by Attractive Chaos <attractor@live.co.uk>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
20
+ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21
+ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ SOFTWARE.
24
+ */
25
+
26
+ /*
27
+ An example:
28
+
29
+ #include "kvec.h"
30
+ int main() {
31
+ kvec_t(int) array;
32
+ kv_init(array);
33
+ kv_push(int, array, 10); // append
34
+ kv_a(int, array, 20) = 5; // dynamic
35
+ kv_A(array, 20) = 4; // static
36
+ kv_destroy(array);
37
+ return 0;
38
+ }
39
+ */
40
+
41
+ /*
42
+ 2008-09-22 (0.1.0):
43
+
44
+ * The initial version.
45
+
46
+ */
47
+
48
+ #ifndef AC_KVEC_H
49
+ #define AC_KVEC_H
50
+
51
+ #include <stdlib.h>
52
+ #include "kalloc.h"
53
+
54
+ #define kv_roundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x))
55
+
56
+ #define kvec_t(type) struct { size_t n, m; type *a; }
57
+ #define kv_init(v) ((v).n = (v).m = 0, (v).a = 0)
58
+ #define kv_destroy(v) free((v).a)
59
+ #define kv_A(v, i) ((v).a[(i)])
60
+ #define kv_pop(v) ((v).a[--(v).n])
61
+ #define kv_size(v) ((v).n)
62
+ #define kv_max(v) ((v).m)
63
+
64
+ #define kv_resize(type, km, v, s) do { \
65
+ if ((v).m < (s)) { \
66
+ (v).m = (s); \
67
+ kv_roundup32((v).m); \
68
+ (v).a = (type*)krealloc((km), (v).a, sizeof(type) * (v).m); \
69
+ } \
70
+ } while (0)
71
+
72
+ #define kv_copy(type, km, v1, v0) do { \
73
+ if ((v1).m < (v0).n) kv_resize(type, (km), (v1), (v0).n); \
74
+ (v1).n = (v0).n; \
75
+ memcpy((v1).a, (v0).a, sizeof(type) * (v0).n); \
76
+ } while (0) \
77
+
78
+ #define kv_push(type, km, v, x) do { \
79
+ if ((v).n == (v).m) { \
80
+ (v).m = (v).m? (v).m<<1 : 2; \
81
+ (v).a = (type*)krealloc((km), (v).a, sizeof(type) * (v).m); \
82
+ } \
83
+ (v).a[(v).n++] = (x); \
84
+ } while (0)
85
+
86
+ #define kv_pushp(type, km, v, p) do { \
87
+ if ((v).n == (v).m) { \
88
+ (v).m = (v).m? (v).m<<1 : 2; \
89
+ (v).a = (type*)krealloc((km), (v).a, sizeof(type) * (v).m); \
90
+ } \
91
+ *(p) = &(v).a[(v).n++]; \
92
+ } while (0)
93
+
94
+ #define kv_reverse(type, v, start) do { \
95
+ if ((v).m > 0 && (v).n > (start)) { \
96
+ size_t __i, __end = (v).n - (start); \
97
+ type *__a = (v).a + (start); \
98
+ for (__i = 0; __i < __end>>1; ++__i) { \
99
+ type __t = __a[__end - 1 - __i]; \
100
+ __a[__end - 1 - __i] = __a[__i]; __a[__i] = __t; \
101
+ } \
102
+ } \
103
+ } while (0)
104
+
105
+ #endif
@@ -0,0 +1,344 @@
1
+ #include <stdint.h>
2
+ #include <string.h>
3
+ #include <stdio.h>
4
+ #include <assert.h>
5
+ #include "mmpriv.h"
6
+ #include "kalloc.h"
7
+ #include "krmq.h"
8
+
9
+ uint64_t *mg_chain_backtrack(void *km, int64_t n, const int32_t *f, const int64_t *p, int32_t *v, int32_t *t, int32_t min_cnt, int32_t min_sc, int32_t *n_u_, int32_t *n_v_)
10
+ {
11
+ mm128_t *z;
12
+ uint64_t *u;
13
+ int64_t i, k, n_z, n_v;
14
+ int32_t n_u;
15
+
16
+ *n_u_ = *n_v_ = 0;
17
+ for (i = 0, n_z = 0; i < n; ++i) // precompute n_z
18
+ if (f[i] >= min_sc) ++n_z;
19
+ if (n_z == 0) return 0;
20
+ KMALLOC(km, z, n_z);
21
+ for (i = 0, k = 0; i < n; ++i) // populate z[]
22
+ if (f[i] >= min_sc) z[k].x = f[i], z[k++].y = i;
23
+ radix_sort_128x(z, z + n_z);
24
+
25
+ memset(t, 0, n * 4);
26
+ for (k = n_z - 1, n_v = n_u = 0; k >= 0; --k) { // precompute n_u
27
+ int64_t n_v0 = n_v;
28
+ int32_t sc;
29
+ for (i = z[k].y; i >= 0 && t[i] == 0; i = p[i])
30
+ ++n_v, t[i] = 1;
31
+ sc = i < 0? z[k].x : (int32_t)z[k].x - f[i];
32
+ if (sc >= min_sc && n_v > n_v0 && n_v - n_v0 >= min_cnt)
33
+ ++n_u;
34
+ else n_v = n_v0;
35
+ }
36
+ KMALLOC(km, u, n_u);
37
+ memset(t, 0, n * 4);
38
+ for (k = n_z - 1, n_v = n_u = 0; k >= 0; --k) { // populate u[]
39
+ int64_t n_v0 = n_v;
40
+ int32_t sc;
41
+ for (i = z[k].y; i >= 0 && t[i] == 0; i = p[i])
42
+ v[n_v++] = i, t[i] = 1;
43
+ sc = i < 0? z[k].x : (int32_t)z[k].x - f[i];
44
+ if (sc >= min_sc && n_v > n_v0 && n_v - n_v0 >= min_cnt)
45
+ u[n_u++] = (uint64_t)sc << 32 | (n_v - n_v0);
46
+ else n_v = n_v0;
47
+ }
48
+ kfree(km, z);
49
+ assert(n_v < INT32_MAX);
50
+ *n_u_ = n_u, *n_v_ = n_v;
51
+ return u;
52
+ }
53
+
54
+ static mm128_t *compact_a(void *km, int32_t n_u, uint64_t *u, int32_t n_v, int32_t *v, mm128_t *a)
55
+ {
56
+ mm128_t *b, *w;
57
+ uint64_t *u2;
58
+ int64_t i, j, k;
59
+
60
+ // write the result to b[]
61
+ KMALLOC(km, b, n_v);
62
+ for (i = 0, k = 0; i < n_u; ++i) {
63
+ int32_t k0 = k, ni = (int32_t)u[i];
64
+ for (j = 0; j < ni; ++j)
65
+ b[k++] = a[v[k0 + (ni - j - 1)]];
66
+ }
67
+ kfree(km, v);
68
+
69
+ // sort u[] and a[] by the target position, such that adjacent chains may be joined
70
+ KMALLOC(km, w, n_u);
71
+ for (i = k = 0; i < n_u; ++i) {
72
+ w[i].x = b[k].x, w[i].y = (uint64_t)k<<32|i;
73
+ k += (int32_t)u[i];
74
+ }
75
+ radix_sort_128x(w, w + n_u);
76
+ KMALLOC(km, u2, n_u);
77
+ for (i = k = 0; i < n_u; ++i) {
78
+ int32_t j = (int32_t)w[i].y, n = (int32_t)u[j];
79
+ u2[i] = u[j];
80
+ memcpy(&a[k], &b[w[i].y>>32], n * sizeof(mm128_t));
81
+ k += n;
82
+ }
83
+ memcpy(u, u2, n_u * 8);
84
+ memcpy(b, a, k * sizeof(mm128_t)); // write _a_ to _b_ and deallocate _a_ because _a_ is oversized, sometimes a lot
85
+ kfree(km, a); kfree(km, w); kfree(km, u2);
86
+ return b;
87
+ }
88
+
89
+ static inline int32_t comput_sc(const mm128_t *ai, const mm128_t *aj, int32_t max_dist_x, int32_t max_dist_y, int32_t bw, float chn_pen_gap, float chn_pen_skip, int is_cdna, int n_seg)
90
+ {
91
+ int32_t dq = (int32_t)ai->y - (int32_t)aj->y, dr, dd, dg, q_span, sc;
92
+ int32_t sidi = (ai->y & MM_SEED_SEG_MASK) >> MM_SEED_SEG_SHIFT;
93
+ int32_t sidj = (aj->y & MM_SEED_SEG_MASK) >> MM_SEED_SEG_SHIFT;
94
+ if (dq <= 0 || dq > max_dist_x) return INT32_MIN;
95
+ dr = (int32_t)(ai->x - aj->x);
96
+ if (sidi == sidj && (dr == 0 || dq > max_dist_y)) return INT32_MIN;
97
+ dd = dr > dq? dr - dq : dq - dr;
98
+ if (sidi == sidj && dd > bw) return INT32_MIN;
99
+ if (n_seg > 1 && !is_cdna && sidi == sidj && dr > max_dist_y) return INT32_MIN;
100
+ dg = dr < dq? dr : dq;
101
+ q_span = aj->y>>32&0xff;
102
+ sc = q_span < dg? q_span : dg;
103
+ if (dd || dg > q_span) {
104
+ float lin_pen, log_pen;
105
+ lin_pen = chn_pen_gap * (float)dd + chn_pen_skip * (float)dg;
106
+ log_pen = dd >= 1? mg_log2(dd + 1) : 0.0f; // mg_log2() only works for dd>=2
107
+ if (is_cdna || sidi != sidj) {
108
+ if (sidi != sidj && dr == 0) ++sc; // possibly due to overlapping paired ends; give a minor bonus
109
+ else if (dr > dq || sidi != sidj) sc -= (int)(lin_pen < log_pen? lin_pen : log_pen); // deletion or jump between paired ends
110
+ else sc -= (int)(lin_pen + .5f * log_pen);
111
+ } else sc -= (int)(lin_pen + .5f * log_pen);
112
+ }
113
+ return sc;
114
+ }
115
+
116
+ /* Input:
117
+ * a[].x: tid<<33 | rev<<32 | tpos
118
+ * a[].y: flags<<40 | q_span<<32 | q_pos
119
+ * Output:
120
+ * n_u: #chains
121
+ * u[]: score<<32 | #anchors (sum of lower 32 bits of u[] is the returned length of a[])
122
+ * input a[] is deallocated on return
123
+ */
124
+ mm128_t *mg_lchain_dp(int max_dist_x, int max_dist_y, int bw, int max_skip, int max_iter, int min_cnt, int min_sc, float chn_pen_gap, float chn_pen_skip,
125
+ int is_cdna, int n_seg, int64_t n, mm128_t *a, int *n_u_, uint64_t **_u, void *km)
126
+ { // TODO: make sure this works when n has more than 32 bits
127
+ int32_t *f, *t, *v, n_u, n_v, mmax_f = 0;
128
+ int64_t *p, i, j, max_ii, st = 0, n_iter = 0;
129
+ uint64_t *u;
130
+
131
+ if (_u) *_u = 0, *n_u_ = 0;
132
+ if (n == 0 || a == 0) {
133
+ kfree(km, a);
134
+ return 0;
135
+ }
136
+ if (max_dist_x < bw) max_dist_x = bw;
137
+ if (max_dist_y < bw && !is_cdna) max_dist_y = bw;
138
+ KMALLOC(km, p, n);
139
+ KMALLOC(km, f, n);
140
+ KMALLOC(km, v, n);
141
+ KCALLOC(km, t, n);
142
+
143
+ // fill the score and backtrack arrays
144
+ for (i = 0, max_ii = -1; i < n; ++i) {
145
+ int64_t max_j = -1, end_j;
146
+ int32_t max_f = a[i].y>>32&0xff, n_skip = 0;
147
+ while (st < i && (a[i].x>>32 != a[st].x>>32 || a[i].x > a[st].x + max_dist_x)) ++st;
148
+ if (i - st > max_iter) st = i - max_iter;
149
+ for (j = i - 1; j >= st; --j) {
150
+ int32_t sc;
151
+ sc = comput_sc(&a[i], &a[j], max_dist_x, max_dist_y, bw, chn_pen_gap, chn_pen_skip, is_cdna, n_seg);
152
+ ++n_iter;
153
+ if (sc == INT32_MIN) continue;
154
+ sc += f[j];
155
+ if (sc > max_f) {
156
+ max_f = sc, max_j = j;
157
+ if (n_skip > 0) --n_skip;
158
+ } else if (t[j] == (int32_t)i) {
159
+ if (++n_skip > max_skip)
160
+ break;
161
+ }
162
+ if (p[j] >= 0) t[p[j]] = i;
163
+ }
164
+ end_j = j;
165
+ if (max_ii < 0 || a[i].x - a[max_ii].x > (int64_t)max_dist_x) {
166
+ int32_t max = INT32_MIN;
167
+ max_ii = -1;
168
+ for (j = i - 1; j >= st; --j)
169
+ if (max < f[j]) max = f[j], max_ii = j;
170
+ }
171
+ if (max_ii >= 0 && max_ii < end_j) {
172
+ int32_t tmp;
173
+ tmp = comput_sc(&a[i], &a[max_ii], max_dist_x, max_dist_y, bw, chn_pen_gap, chn_pen_skip, is_cdna, n_seg);
174
+ if (tmp != INT32_MIN && max_f < tmp + f[max_ii])
175
+ max_f = tmp + f[max_ii], max_j = max_ii;
176
+ }
177
+ f[i] = max_f, p[i] = max_j;
178
+ v[i] = max_j >= 0 && v[max_j] > max_f? v[max_j] : max_f; // v[] keeps the peak score up to i; f[] is the score ending at i, not always the peak
179
+ if (max_ii < 0 || (a[i].x - a[max_ii].x <= (int64_t)max_dist_x && f[max_ii] < f[i]))
180
+ max_ii = i;
181
+ if (mmax_f < max_f) mmax_f = max_f;
182
+ }
183
+
184
+ u = mg_chain_backtrack(km, n, f, p, v, t, min_cnt, min_sc, &n_u, &n_v);
185
+ *n_u_ = n_u, *_u = u; // NB: note that u[] may not be sorted by score here
186
+ kfree(km, p); kfree(km, f); kfree(km, t);
187
+ if (n_u == 0) {
188
+ kfree(km, a); kfree(km, v);
189
+ return 0;
190
+ }
191
+ return compact_a(km, n_u, u, n_v, v, a);
192
+ }
193
+
194
+ typedef struct lc_elem_s {
195
+ int32_t y;
196
+ int64_t i;
197
+ double pri;
198
+ KRMQ_HEAD(struct lc_elem_s) head;
199
+ } lc_elem_t;
200
+
201
+ #define lc_elem_cmp(a, b) ((a)->y < (b)->y? -1 : (a)->y > (b)->y? 1 : ((a)->i > (b)->i) - ((a)->i < (b)->i))
202
+ #define lc_elem_lt2(a, b) ((a)->pri < (b)->pri)
203
+ KRMQ_INIT(lc_elem, lc_elem_t, head, lc_elem_cmp, lc_elem_lt2)
204
+
205
+ KALLOC_POOL_INIT(rmq, lc_elem_t)
206
+
207
+ static inline int32_t comput_sc_simple(const mm128_t *ai, const mm128_t *aj, float chn_pen_gap, float chn_pen_skip, int32_t *exact, int32_t *width)
208
+ {
209
+ int32_t dq = (int32_t)ai->y - (int32_t)aj->y, dr, dd, dg, q_span, sc;
210
+ dr = (int32_t)(ai->x - aj->x);
211
+ *width = dd = dr > dq? dr - dq : dq - dr;
212
+ dg = dr < dq? dr : dq;
213
+ q_span = aj->y>>32&0xff;
214
+ sc = q_span < dg? q_span : dg;
215
+ if (exact) *exact = (dd == 0 && dg <= q_span);
216
+ if (dd || dq > q_span) {
217
+ float lin_pen, log_pen;
218
+ lin_pen = chn_pen_gap * (float)dd + chn_pen_skip * (float)dg;
219
+ log_pen = dd >= 1? mg_log2(dd + 1) : 0.0f; // mg_log2() only works for dd>=2
220
+ sc -= (int)(lin_pen + .5f * log_pen);
221
+ }
222
+ return sc;
223
+ }
224
+
225
+ mm128_t *mg_lchain_rmq(int max_dist, int max_dist_inner, int bw, int max_chn_skip, int cap_rmq_size, int min_cnt, int min_sc, float chn_pen_gap, float chn_pen_skip,
226
+ int64_t n, mm128_t *a, int *n_u_, uint64_t **_u, void *km)
227
+ {
228
+ int32_t *f,*t, *v, n_u, n_v, mmax_f = 0, max_rmq_size = 0;
229
+ int64_t *p, i, i0, st = 0, st_inner = 0, n_iter = 0;
230
+ uint64_t *u;
231
+ lc_elem_t *root = 0, *root_inner = 0;
232
+ void *mem_mp = 0;
233
+ kmp_rmq_t *mp;
234
+
235
+ if (_u) *_u = 0, *n_u_ = 0;
236
+ if (n == 0 || a == 0) {
237
+ kfree(km, a);
238
+ return 0;
239
+ }
240
+ if (max_dist < bw) max_dist = bw;
241
+ if (max_dist_inner <= 0 || max_dist_inner >= max_dist) max_dist_inner = 0;
242
+ KMALLOC(km, p, n);
243
+ KMALLOC(km, f, n);
244
+ KCALLOC(km, t, n);
245
+ KMALLOC(km, v, n);
246
+ mem_mp = km_init2(km, 0x10000);
247
+ mp = kmp_init_rmq(mem_mp);
248
+
249
+ // fill the score and backtrack arrays
250
+ for (i = i0 = 0; i < n; ++i) {
251
+ int64_t max_j = -1;
252
+ int32_t q_span = a[i].y>>32&0xff, max_f = q_span;
253
+ lc_elem_t s, *q, *r, lo, hi;
254
+ // add in-range anchors
255
+ if (i0 < i && a[i0].x != a[i].x) {
256
+ int64_t j;
257
+ for (j = i0; j < i; ++j) {
258
+ q = kmp_alloc_rmq(mp);
259
+ q->y = (int32_t)a[j].y, q->i = j, q->pri = -(f[j] + 0.5 * chn_pen_gap * ((int32_t)a[j].x + (int32_t)a[j].y));
260
+ krmq_insert(lc_elem, &root, q, 0);
261
+ if (max_dist_inner > 0) {
262
+ r = kmp_alloc_rmq(mp);
263
+ *r = *q;
264
+ krmq_insert(lc_elem, &root_inner, r, 0);
265
+ }
266
+ }
267
+ i0 = i;
268
+ }
269
+ // get rid of active chains out of range
270
+ while (st < i && (a[i].x>>32 != a[st].x>>32 || a[i].x > a[st].x + max_dist || krmq_size(head, root) > cap_rmq_size)) {
271
+ s.y = (int32_t)a[st].y, s.i = st;
272
+ if ((q = krmq_find(lc_elem, root, &s, 0)) != 0) {
273
+ q = krmq_erase(lc_elem, &root, q, 0);
274
+ kmp_free_rmq(mp, q);
275
+ }
276
+ ++st;
277
+ }
278
+ if (max_dist_inner > 0) { // similar to the block above, but applied to the inner tree
279
+ while (st_inner < i && (a[i].x>>32 != a[st_inner].x>>32 || a[i].x > a[st_inner].x + max_dist_inner || krmq_size(head, root_inner) > cap_rmq_size)) {
280
+ s.y = (int32_t)a[st_inner].y, s.i = st_inner;
281
+ if ((q = krmq_find(lc_elem, root_inner, &s, 0)) != 0) {
282
+ q = krmq_erase(lc_elem, &root_inner, q, 0);
283
+ kmp_free_rmq(mp, q);
284
+ }
285
+ ++st_inner;
286
+ }
287
+ }
288
+ // RMQ
289
+ lo.i = INT32_MAX, lo.y = (int32_t)a[i].y - max_dist;
290
+ hi.i = 0, hi.y = (int32_t)a[i].y;
291
+ if ((q = krmq_rmq(lc_elem, root, &lo, &hi)) != 0) {
292
+ int32_t sc, exact, width, n_skip = 0;
293
+ int64_t j = q->i;
294
+ assert(q->y >= lo.y && q->y <= hi.y);
295
+ sc = f[j] + comput_sc_simple(&a[i], &a[j], chn_pen_gap, chn_pen_skip, &exact, &width);
296
+ if (width <= bw && sc > max_f) max_f = sc, max_j = j;
297
+ if (!exact && root_inner && (int32_t)a[i].y > 0) {
298
+ lc_elem_t *lo, *hi;
299
+ s.y = (int32_t)a[i].y - 1, s.i = n;
300
+ krmq_interval(lc_elem, root_inner, &s, &lo, &hi);
301
+ if (lo) {
302
+ const lc_elem_t *q;
303
+ int32_t width, n_rmq_iter = 0;
304
+ krmq_itr_t(lc_elem) itr;
305
+ krmq_itr_find(lc_elem, root_inner, lo, &itr);
306
+ while ((q = krmq_at(&itr)) != 0) {
307
+ if (q->y < (int32_t)a[i].y - max_dist_inner) break;
308
+ ++n_rmq_iter;
309
+ j = q->i;
310
+ sc = f[j] + comput_sc_simple(&a[i], &a[j], chn_pen_gap, chn_pen_skip, 0, &width);
311
+ if (width <= bw) {
312
+ if (sc > max_f) {
313
+ max_f = sc, max_j = j;
314
+ if (n_skip > 0) --n_skip;
315
+ } else if (t[j] == (int32_t)i) {
316
+ if (++n_skip > max_chn_skip)
317
+ break;
318
+ }
319
+ if (p[j] >= 0) t[p[j]] = i;
320
+ }
321
+ if (!krmq_itr_prev(lc_elem, &itr)) break;
322
+ }
323
+ n_iter += n_rmq_iter;
324
+ }
325
+ }
326
+ }
327
+ // set max
328
+ assert(max_j < 0 || (a[max_j].x < a[i].x && (int32_t)a[max_j].y < (int32_t)a[i].y));
329
+ f[i] = max_f, p[i] = max_j;
330
+ v[i] = max_j >= 0 && v[max_j] > max_f? v[max_j] : max_f; // v[] keeps the peak score up to i; f[] is the score ending at i, not always the peak
331
+ if (mmax_f < max_f) mmax_f = max_f;
332
+ if (max_rmq_size < krmq_size(head, root)) max_rmq_size = krmq_size(head, root);
333
+ }
334
+ km_destroy(mem_mp);
335
+
336
+ u = mg_chain_backtrack(km, n, f, p, v, t, min_cnt, min_sc, &n_u, &n_v);
337
+ *n_u_ = n_u, *_u = u; // NB: note that u[] may not be sorted by score here
338
+ kfree(km, p); kfree(km, f); kfree(km, t);
339
+ if (n_u == 0) {
340
+ kfree(km, a); kfree(km, v);
341
+ return 0;
342
+ }
343
+ return compact_a(km, n_u, u, n_v, v, a);
344
+ }