minimap2 0.2.30.3 → 1.2.31.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +48 -63
  3. data/ext/minimap2/Makefile +1 -1
  4. data/ext/minimap2/format.c +12 -2
  5. data/ext/minimap2/hit.c +19 -8
  6. data/ext/minimap2/ksw2_ll_sse.c +2 -2
  7. data/ext/minimap2/minimap.h +2 -1
  8. data/ext/minimap2/pe.c +7 -2
  9. data/ext/ruby_minimap2/extconf.rb +47 -0
  10. data/ext/ruby_minimap2/native_main.c +15 -0
  11. data/ext/ruby_minimap2/ruby_minimap2.c +1134 -0
  12. data/lib/minimap2/aligner.rb +66 -374
  13. data/lib/minimap2/alignment.rb +22 -11
  14. data/lib/minimap2/version.rb +2 -1
  15. data/lib/minimap2.rb +39 -110
  16. metadata +8 -89
  17. data/ext/Rakefile +0 -60
  18. data/ext/cmappy/cmappy.c +0 -134
  19. data/ext/cmappy/cmappy.h +0 -46
  20. data/ext/minimap2/FAQ.md +0 -46
  21. data/ext/minimap2/MANIFEST.in +0 -10
  22. data/ext/minimap2/Makefile.simde +0 -97
  23. data/ext/minimap2/NEWS.md +0 -989
  24. data/ext/minimap2/README.md +0 -428
  25. data/ext/minimap2/code_of_conduct.md +0 -30
  26. data/ext/minimap2/cookbook.md +0 -243
  27. data/ext/minimap2/minimap2.1 +0 -844
  28. data/ext/minimap2/misc/README.md +0 -180
  29. data/ext/minimap2/misc/pafcluster.js +0 -241
  30. data/ext/minimap2/misc/paftools.js +0 -3734
  31. data/ext/minimap2/pyproject.toml +0 -2
  32. data/ext/minimap2/python/README.rst +0 -198
  33. data/ext/minimap2/python/cmappy.h +0 -152
  34. data/ext/minimap2/python/cmappy.pxd +0 -156
  35. data/ext/minimap2/python/mappy.pyx +0 -289
  36. data/ext/minimap2/python/minimap2.py +0 -41
  37. data/ext/minimap2/setup.py +0 -55
  38. data/ext/minimap2/test/MT-human.fa +0 -278
  39. data/ext/minimap2/test/MT-orang.fa +0 -276
  40. data/ext/minimap2/test/q-inv.fa +0 -4
  41. data/ext/minimap2/test/q2.fa +0 -2
  42. data/ext/minimap2/test/t-inv.fa +0 -127
  43. data/ext/minimap2/test/t2.fa +0 -2
  44. data/ext/minimap2/test/x3s-aln.txt +0 -5
  45. data/ext/minimap2/test/x3s-qry.fa +0 -5
  46. data/ext/minimap2/test/x3s-ref.fa +0 -10
  47. data/ext/minimap2/tex/Makefile +0 -21
  48. data/ext/minimap2/tex/bioinfo.cls +0 -930
  49. data/ext/minimap2/tex/blasr-mc.eval +0 -17
  50. data/ext/minimap2/tex/bowtie2-s3.sam.eval +0 -28
  51. data/ext/minimap2/tex/bwa-s3.sam.eval +0 -52
  52. data/ext/minimap2/tex/bwa.eval +0 -55
  53. data/ext/minimap2/tex/eval2roc.pl +0 -33
  54. data/ext/minimap2/tex/graphmap.eval +0 -4
  55. data/ext/minimap2/tex/hs38-simu.sh +0 -10
  56. data/ext/minimap2/tex/minialign.eval +0 -49
  57. data/ext/minimap2/tex/minimap2.bib +0 -460
  58. data/ext/minimap2/tex/minimap2.tex +0 -724
  59. data/ext/minimap2/tex/mm2-s3.sam.eval +0 -62
  60. data/ext/minimap2/tex/mm2-update.tex +0 -240
  61. data/ext/minimap2/tex/mm2.approx.eval +0 -12
  62. data/ext/minimap2/tex/mm2.eval +0 -13
  63. data/ext/minimap2/tex/natbib.bst +0 -1288
  64. data/ext/minimap2/tex/natbib.sty +0 -803
  65. data/ext/minimap2/tex/ngmlr.eval +0 -38
  66. data/ext/minimap2/tex/roc.gp +0 -60
  67. data/ext/minimap2/tex/snap-s3.sam.eval +0 -62
  68. data/ext/minimap2.patch +0 -19
  69. data/lib/minimap2/ffi/constants.rb +0 -267
  70. data/lib/minimap2/ffi/functions.rb +0 -239
  71. data/lib/minimap2/ffi/mappy.rb +0 -104
  72. data/lib/minimap2/ffi.rb +0 -27
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2a3bf89a18a50825f14454ce8683dd019377fc45e59a4d46eee617a55d0e64e8
4
- data.tar.gz: c1dd61ced844c50b7aec1ba1f9da8d8b47ab3b94a1e2f4b0b4bcdd16169e4f0c
3
+ metadata.gz: 66111ad941edb14875a0f3c66f8ac1f5cbef18182bb96cb2a363f8ec29e6e817
4
+ data.tar.gz: 2ce71684a6a25196f7735252888cbdc1ff66674829edbb72d492184ecc171510
5
5
  SHA512:
6
- metadata.gz: 198ae12116da51051dcac0665a85611a2d5bbe5df49ff854fff02c1f686f6c5fd7d40378876de81542d8ca9fe6fb8d71c0c59cde53497368ae4fc83b06a4c685
7
- data.tar.gz: 1226cb572e95c805d3817bcaf5048fcc6a3bb217e7ac86b56f866b132c3ffe9ed5f8a1ba8e67b1bb798a1c2852e060f611229ccae9364b477a9863366717ce5c
6
+ metadata.gz: 6f708837128825a21efe2428ccef35f985c6de313d7dc2a669ef45b6ba17873a3672859fcc72c11f2dfd12af26686f5e5909f952a99fb7a519a37749d59798c4
7
+ data.tar.gz: '0083cf367e4bfd1c9eeeeea626289d97d064cc69efd47e1bcb50fddbe13ffece5f5d8b4f540926daaaa3224eed225227cd2a07b367d310bbf34a906c164dafb3'
data/README.md CHANGED
@@ -4,16 +4,16 @@
4
4
  [![test](https://github.com/kojix2/ruby-minimap2/actions/workflows/ci.yml/badge.svg)](https://github.com/kojix2/ruby-minimap2/actions/workflows/ci.yml)
5
5
  [![Docs Latest](https://img.shields.io/badge/docs-latest-blue.svg)](https://kojix2.github.io/ruby-minimap2/)
6
6
  [![The MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE.txt)
7
- [![DOI](https://zenodo.org/badge/325711305.svg)](https://zenodo.org/badge/latestdoi/325711305)
7
+ [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.18489817.svg)](https://doi.org/10.5281/zenodo.18489817)
8
8
  [![Lines of Code](https://img.shields.io/endpoint?url=https%3A%2F%2Ftokei.kojix2.net%2Fbadge%2Fgithub%2Fkojix2%2Fruby-minimap2%2Flines)](https://tokei.kojix2.net/github/kojix2/ruby-minimap2)
9
9
 
10
10
  :dna: [minimap2](https://github.com/lh3/minimap2) - the long-read mapper - for [Ruby](https://github.com/ruby/ruby)
11
11
 
12
12
  ## Installation
13
13
 
14
- ruby-minimap2 bundles the Minimap2 C source code and builds it automatically during installation.
14
+ ruby-minimap2 bundles the Minimap2 C source code and builds a native extension during installation.
15
15
 
16
- Just install the gem. Works on Linux, macOS, and Windows.
16
+ Ruby 3.3 or later is required. Works on Linux, macOS, and Windows.
17
17
 
18
18
  ```
19
19
  gem install minimap2
@@ -41,29 +41,39 @@ ruby -r minimap2 -e 'Minimap2.execute("--version")'
41
41
  ```ruby
42
42
  require "minimap2"
43
43
 
44
- aligner = Minimap2::Aligner.new("ext/minimap2/test/MT-human.fa")
45
- seq = aligner.seq("MT_human", 100, 200)
46
- hits = aligner.align(seq)
44
+ reference = <<~DNA.delete("\n")
45
+ GATCACAGGTCTATCACCCTATTAACCACTCACGGGAGCTCTCCATGCATTTGGTATTTTCGTCTGGGGGGTATGCACGC
46
+ GATAGCATTGCGAGACGCTGGAGCCGGAGCACCCTATGTCGCAGTATCTGTCTTTGATTCCTGCCTCATCCTATTATTTAT
47
+ CGCACCTACGTTCAATATTACAGGCGAACATACTTACTAAAGTGTGTTAATTAATTAATGCTTGTAGGACATAATAATAACA
48
+ ATTGAATGTCTGCACAGCCACTTTCCACACAGACATCATAACAAAAAATTTCCACCAAACCCCCCCTCCCCCGCTTC
49
+ DNA
50
+
51
+ aligner = Minimap2::Aligner.new(seq: reference)
52
+ query = reference[50, 200]
53
+ hits = aligner.align(query, name: "query", cs: true, ds: true)
47
54
  pp hits
48
55
  ```
49
56
 
50
57
  ```
51
58
  [#<Minimap2::Alignment:0x000055bbfde2d128
52
- @blen=100,
53
- @cigar=[[100, 0]],
54
- @cigar_str="100M",
55
- @cs="",
56
- @ctg="MT_human",
57
- @ctg_len=16569,
59
+ @blen=200,
60
+ @cigar=[[200, 0]],
61
+ @cigar_str="200M",
62
+ @cs=":200",
63
+ @ctg="N/A",
64
+ @ctg_len=320,
65
+ @ds=":200",
58
66
  @mapq=60,
59
- @md="",
60
- @mlen=100,
67
+ @md=nil,
68
+ @mlen=200,
61
69
  @nm=0,
62
70
  @primary=1,
63
- @q_en=100,
71
+ @q_en=200,
64
72
  @q_st=0,
65
- @r_en=200,
66
- @r_st=100,
73
+ @qlen=200,
74
+ @qname="query",
75
+ @r_en=250,
76
+ @r_st=50,
67
77
  @read_num=1,
68
78
  @strand=1,
69
79
  @trans_strand=0>]
@@ -76,19 +86,25 @@ pp hits
76
86
  - fastx_read Read fasta/fastq file.
77
87
  - revcomp Reverse complement sequence.
78
88
  - execute Calls the main function of Minimap2 with arguments. `Minimap2.execute("--version")`
89
+ - verbose Returns the Minimap2 verbosity level.
90
+ - verbose= Sets the Minimap2 verbosity level.
79
91
 
80
92
  * Aligner class
81
- * attributes
82
- - index Returns the value of attribute index.
83
- - idx_opt Returns the value of attribute idx_opt.
84
- - map_opt Returns the value of attribute map_opt.
85
93
  * methods
86
- - new(path, preset: nil) Create a new aligner. (presets: sr, map-pb, map-out, map-hifi, splice, asm5, etc.)
94
+ - new(path, preset: nil) Create a new aligner. (presets: sr, map-pb, map-ont, map-hifi, splice, asm5, etc.)
87
95
  - align Maps and returns alignments.
88
96
  - seq Retrieve a subsequence from the index.
97
+ - k Returns the minimizer k-mer length.
98
+ - w Returns the minimizer window size.
99
+ - n_seq Returns the number of sequences in the index.
100
+ - seq_names Returns sequence names in the index.
101
+ - index? Returns whether the aligner has a live index.
102
+ - free_index Releases the index.
89
103
 
90
104
  * Alignment class
91
105
  * attributes
106
+ - qname Returns the query sequence name.
107
+ - qlen Returns the query sequence length.
92
108
  - ctg Returns name of the reference sequence the query is mapped to.
93
109
  - ctg_len Returns total length of the reference sequence.
94
110
  - r_st Returns start positions on the reference.
@@ -104,46 +120,22 @@ pp hits
104
120
  - mapq Returns mapping quality.
105
121
  - cigar Returns CIGAR returned as an array of shape (n_cigar,2). The two numbers give the length and the operator of each CIGAR operation.
106
122
  - read_num Returns read number that the alignment corresponds to; 1 for the first read and 2 for the second read.
107
- - cs Returns the cs tag.
108
- - md Returns the MD tag as in the SAM format. It is an empty string unless the md argument is applied when calling Aligner#align.
123
+ - cs Returns the cs tag, or nil unless requested.
124
+ - ds Returns the ds tag, or nil unless requested.
125
+ - md Returns the MD tag, or nil unless requested.
109
126
  - cigar_str Returns CIGAR string.
110
127
  * methods
111
128
  - to_h Convert Alignment to hash.
112
- - to_s Convert to the PAF format without the QueryName and QueryLength columns.
113
-
114
- ## FFI module
115
- * IdxOpt class Indexing options.
116
- * MapOpt class Mapping options.
129
+ - to_s Convert to the PAF format.
117
130
  ```
118
131
 
119
132
  - API is based on [Mappy](https://github.com/lh3/minimap2/tree/master/python), the official Python binding for Minimap2.
120
133
  - `Aligner#map` has been changed to `align`, because `map` means iterator in Ruby.
134
+ - Calls on the same Aligner are thread-safe and serialized. Different Aligner instances can run concurrently.
135
+ - Multipart indexes are supported, but primary alignments and mapping quality are calculated independently for each part.
136
+ - Sequence data uses ASCII-8BIT. Names read from an index use UTF-8.
121
137
  - See [documentation](https://kojix2.github.io/ruby-minimap2/) for details.
122
138
 
123
- <details>
124
- <summary><b>C Structures and Functions</b></summary>
125
-
126
- ### FFI
127
-
128
- - Ruby-Minimap2 is built on top of [Ruby-FFI](https://github.com/ffi/ffi).
129
- - Native C functions can be called from the `Minimap2::FFI` module.
130
- - Native C structure members can be accessed.
131
- - Bitfields are supported by [ffi-bitfield](https://github.com/kojix2/ffi-bitfield) gems.
132
-
133
- ```ruby
134
- aligner.idx_opt.members
135
- # => [:k, :w, :flag, :bucket_bits, :mini_batch_size, :batch_size]
136
- aligner.kds_opt.values
137
- # => [15, 10, 0, 14, 50000000, 9223372036854775807]
138
- aligner.idx_opt[:k]
139
- # => 15
140
- aligner.idx_opt[:k] = 14
141
- aligner.idx_opt[:k]
142
- # => 14
143
- ```
144
-
145
- </details>
146
-
147
139
  ## Contributing
148
140
 
149
141
  <details>
@@ -159,21 +151,14 @@ git clone --recursive https://github.com/kojix2/ruby-minimap2
159
151
  # git submodule update -i
160
152
  ```
161
153
 
162
- Build Minimap2 and Mappy.
154
+ Build the native extension.
163
155
 
164
156
  ```sh
165
157
  cd ruby-minimap2
166
- bundle install # Install dependent packages including Ruby-FFI
158
+ bundle install
167
159
  bundle exec rake minimap2:build
168
160
  ```
169
161
 
170
- A shared library will be created in the vendor directory.
171
-
172
- ```
173
- └── vendor
174
- └── libminimap2.so
175
- ```
176
-
177
162
  Run tests.
178
163
 
179
164
  ```
@@ -185,7 +170,7 @@ Release a Gem.
185
170
  ```
186
171
  bundle exec rake minimap2:cleanall
187
172
  bundle exec rake build
188
- ls -l pkg # Check the size of the Gem and make sure it does not contain any unused code such as shared libraries or lib/simde.
173
+ ls -l pkg # Check the size of the Gem.
189
174
  bundle exec rake release
190
175
  ```
191
176
 
@@ -102,7 +102,7 @@ ksw2_exts2_neon.o:ksw2_exts2_sse.c ksw2.h kalloc.h
102
102
  # other non-file targets
103
103
 
104
104
  clean:
105
- rm -fr gmon.out *.o a.out $(PROG) $(PROG_EXTRA) *~ *.a *.dSYM build dist mappy*.so mappy.c python/mappy.c mappy.egg*
105
+ rm -fr gmon.out *.o a.out $(PROG) $(PROG_EXTRA) *~ *.a *.dSYM build dist mappy*.so mappy.c python/mappy.c mappy.egg* .eggs
106
106
 
107
107
  depend:
108
108
  (LC_ALL=C; export LC_ALL; makedepend -Y -- $(CFLAGS) $(CPPFLAGS) -- *.c)
@@ -361,24 +361,34 @@ static void write_cs_ds_or_MD(void *km, kstring_t *s, const mm_idx_t *mi, const
361
361
  kfree(km, qseq); kfree(km, tseq); kfree(km, tmp);
362
362
  }
363
363
 
364
- int mm_gen_cs_or_MD(void *km, char **buf, int *max_len, const mm_idx_t *mi, const mm_reg1_t *r, const char *seq, int is_MD, int no_iden, int is_qstrand)
364
+ int mm_gen_cs_ds_or_MD(void *km, char **buf, int *max_len, const mm_idx_t *mi, const mm_reg1_t *r, const char *seq, int is_MD, int is_ds, int no_iden, int is_qstrand)
365
365
  {
366
366
  mm_bseq1_t t;
367
367
  kstring_t str;
368
368
  str.s = *buf, str.l = 0, str.m = *max_len;
369
369
  t.l_seq = strlen(seq);
370
370
  t.seq = (char*)seq;
371
- write_cs_ds_or_MD(km, &str, mi, &t, r, no_iden, is_MD, 0, 0, is_qstrand);
371
+ write_cs_ds_or_MD(km, &str, mi, &t, r, no_iden, is_MD, is_ds, 0, is_qstrand);
372
372
  *max_len = str.m;
373
373
  *buf = str.s;
374
374
  return str.l;
375
375
  }
376
376
 
377
+ int mm_gen_cs_or_MD(void *km, char **buf, int *max_len, const mm_idx_t *mi, const mm_reg1_t *r, const char *seq, int is_MD, int no_iden, int is_qstrand)
378
+ {
379
+ return mm_gen_cs_ds_or_MD(km, buf, max_len, mi, r, seq, is_MD, 0, no_iden, is_qstrand);
380
+ }
381
+
377
382
  int mm_gen_cs(void *km, char **buf, int *max_len, const mm_idx_t *mi, const mm_reg1_t *r, const char *seq, int no_iden)
378
383
  {
379
384
  return mm_gen_cs_or_MD(km, buf, max_len, mi, r, seq, 0, no_iden, 0);
380
385
  }
381
386
 
387
+ int mm_gen_ds(void *km, char **buf, int *max_len, const mm_idx_t *mi, const mm_reg1_t *r, const char *seq, int no_iden)
388
+ {
389
+ return mm_gen_cs_ds_or_MD(km, buf, max_len, mi, r, seq, 0, 1, no_iden, 0);
390
+ }
391
+
382
392
  int mm_gen_MD(void *km, char **buf, int *max_len, const mm_idx_t *mi, const mm_reg1_t *r, const char *seq)
383
393
  {
384
394
  return mm_gen_cs_or_MD(km, buf, max_len, mi, r, seq, 1, 0, 0);
data/ext/minimap2/hit.c CHANGED
@@ -256,19 +256,25 @@ void mm_select_sub(void *km, float pri_ratio, int min_diff, int best_n, int chec
256
256
  {
257
257
  if (pri_ratio > 0.0f && *n_ > 0) {
258
258
  int i, k, n = *n_, n_2nd = 0;
259
- for (i = k = 0; i < n; ++i) {
259
+ uint8_t *keep = (uint8_t*)kmalloc(km, n);
260
+ for (i = 0; i < n; ++i) {
260
261
  int p = r[i].parent;
262
+ keep[i] = 0;
261
263
  if (p == i || r[i].inv) { // primary or inversion
262
- r[k++] = r[i];
264
+ keep[i] = 1;
263
265
  } else if ((r[i].score >= r[p].score * pri_ratio || r[i].score + min_diff >= r[p].score) && n_2nd < best_n) {
264
266
  if (!(r[i].qs == r[p].qs && r[i].qe == r[p].qe && r[i].rid == r[p].rid && r[i].rs == r[p].rs && r[i].re == r[p].re)) // not identical hits
265
- r[k++] = r[i], ++n_2nd;
266
- else if (r[i].p) free(r[i].p);
267
+ keep[i] = 1, ++n_2nd;
267
268
  } else if (check_strand && n_2nd < best_n && r[i].score > min_strand_sc && r[i].rev != r[p].rev) {
268
269
  r[i].strand_retained = 1;
269
- r[k++] = r[i], ++n_2nd;
270
- } else if (r[i].p) free(r[i].p);
270
+ keep[i] = 1, ++n_2nd;
271
+ }
272
+ }
273
+ for (i = k = 0; i < n; ++i) {
274
+ if (keep[i]) r[k++] = r[i];
275
+ else if (r[i].p) free(r[i].p);
271
276
  }
277
+ kfree(km, keep);
272
278
  if (k != n) mm_sync_regs(km, k, r); // removing hits requires sync()
273
279
  *n_ = k;
274
280
  }
@@ -277,13 +283,18 @@ void mm_select_sub(void *km, float pri_ratio, int min_diff, int best_n, int chec
277
283
  int mm_filter_strand_retained(int n_regs, mm_reg1_t *r)
278
284
  {
279
285
  int i, k;
280
- for (i = k = 0; i < n_regs; ++i) {
286
+ uint8_t *keep = (uint8_t*)malloc(n_regs);
287
+ for (i = 0; i < n_regs; ++i) {
281
288
  int p = r[i].parent;
282
- if (!r[i].strand_retained || r[i].div < r[p].div * 5.0f || r[i].div < 0.01f) {
289
+ keep[i] = (!r[i].strand_retained || r[i].div < r[p].div * 5.0f || r[i].div < 0.01f);
290
+ }
291
+ for (i = k = 0; i < n_regs; ++i) {
292
+ if (keep[i]) {
283
293
  if (k < i) r[k++] = r[i];
284
294
  else ++k;
285
295
  }
286
296
  }
297
+ free(keep);
287
298
  return k;
288
299
  }
289
300
 
@@ -67,7 +67,7 @@ void *ksw_ll_qinit(void *km, int size, int qlen, const uint8_t *query, int m, co
67
67
  const int8_t *ma = mat + a * m;
68
68
  for (i = 0; i < slen; ++i)
69
69
  for (k = i; k < nlen; k += slen) // p iterations
70
- *t++ = (k >= qlen? 0 : ma[query[k]]) + q->shift;
70
+ *t++ = (k >= qlen? -1 : ma[query[k]]) + q->shift;
71
71
  }
72
72
  } else {
73
73
  int16_t *t = (int16_t*)q->qp;
@@ -76,7 +76,7 @@ void *ksw_ll_qinit(void *km, int size, int qlen, const uint8_t *query, int m, co
76
76
  const int8_t *ma = mat + a * m;
77
77
  for (i = 0; i < slen; ++i)
78
78
  for (k = i; k < nlen; k += slen) // p iterations
79
- *t++ = (k >= qlen? 0 : ma[query[k]]);
79
+ *t++ = (k >= qlen? -1 : ma[query[k]]);
80
80
  }
81
81
  }
82
82
  return q;
@@ -5,7 +5,7 @@
5
5
  #include <stdio.h>
6
6
  #include <sys/types.h>
7
7
 
8
- #define MM_VERSION "2.30-r1287"
8
+ #define MM_VERSION "2.31-r1302"
9
9
 
10
10
  #define MM_F_NO_DIAG (0x001LL) // no exact diagonal hit
11
11
  #define MM_F_NO_DUAL (0x002LL) // skip pairs where query name is lexicographically larger than target name
@@ -408,6 +408,7 @@ int mm_map_file_frag(const mm_idx_t *idx, int n_segs, const char **fn, const mm_
408
408
  * @return the length of cs
409
409
  */
410
410
  int mm_gen_cs(void *km, char **buf, int *max_len, const mm_idx_t *mi, const mm_reg1_t *r, const char *seq, int no_iden);
411
+ int mm_gen_ds(void *km, char **buf, int *max_len, const mm_idx_t *mi, const mm_reg1_t *r, const char *seq, int no_iden);
411
412
  int mm_gen_MD(void *km, char **buf, int *max_len, const mm_idx_t *mi, const mm_reg1_t *r, const char *seq);
412
413
 
413
414
  // query sequence name and sequence in the minimap2 index
data/ext/minimap2/pe.c CHANGED
@@ -8,7 +8,8 @@ void mm_select_sub_multi(void *km, float pri_ratio, float pri1, float pri2, int
8
8
  if (pri_ratio > 0.0f && *n_ > 0) {
9
9
  int i, k, n = *n_, n_2nd = 0;
10
10
  int max_dist = n_segs == 2? qlens[0] + qlens[1] + max_gap_ref : 0;
11
- for (i = k = 0; i < n; ++i) {
11
+ uint8_t *keep = (uint8_t*)kmalloc(km, n);
12
+ for (i = 0; i < n; ++i) {
12
13
  int to_keep = 0;
13
14
  if (r[i].parent == i) { // primary
14
15
  to_keep = 1;
@@ -34,9 +35,13 @@ void mm_select_sub_multi(void *km, float pri_ratio, float pri1, float pri2, int
34
35
  if (to_keep && r[i].parent != i) {
35
36
  if (n_2nd++ >= best_n) to_keep = 0; // don't keep if there are too many secondary hits
36
37
  }
37
- if (to_keep) r[k++] = r[i];
38
+ keep[i] = to_keep;
39
+ }
40
+ for (i = k = 0; i < n; ++i) {
41
+ if (keep[i]) r[k++] = r[i];
38
42
  else if (r[i].p) free(r[i].p);
39
43
  }
44
+ kfree(km, keep);
40
45
  if (k != n) mm_sync_regs(km, k, r); // removing hits requires sync()
41
46
  *n_ = k;
42
47
  }
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "mkmf"
4
+ require "fileutils"
5
+ require "rbconfig"
6
+ require "shellwords"
7
+
8
+ source_dir = File.expand_path("../minimap2", __dir__)
9
+ build_dir = File.expand_path("build/minimap2", Dir.pwd)
10
+
11
+ abort "minimap2 sources are missing; initialize the git submodule" unless File.file?(File.join(source_dir, "minimap.h"))
12
+ abort "zlib is required to build ruby-minimap2" unless have_library("z", "gzopen")
13
+ have_func("log") || have_library("m", "log")
14
+ if !(RbConfig::CONFIG.fetch("host_os") =~ /mswin/) && !(have_func("pthread_create") || have_library("pthread",
15
+ "pthread_create"))
16
+ abort "pthread is required to build ruby-minimap2"
17
+ end
18
+
19
+ FileUtils.rm_rf(build_dir)
20
+ FileUtils.mkdir_p(build_dir)
21
+ FileUtils.cp_r(Dir.glob(File.join(source_dir, "*")), build_dir)
22
+
23
+ host_cpu = RbConfig::CONFIG.fetch("host_cpu")
24
+ cflags = %w[-O2 -fPIC]
25
+ cflags.concat(Shellwords.split(RbConfig::CONFIG["ARCH_FLAG"].to_s))
26
+ make_args = ["libminimap2.a", "CC=#{RbConfig::CONFIG.fetch('CC')}"]
27
+ make_args << "AR=#{RbConfig::CONFIG['AR']}" unless RbConfig::CONFIG["AR"].to_s.empty?
28
+
29
+ case host_cpu
30
+ when /arm64|aarch64/
31
+ make_args.concat(["aarch64=1", "INCLUDES=-Isse2neon"])
32
+ cflags.concat(%w[-D_FILE_OFFSET_BITS=64 -fsigned-char])
33
+ when /arm/
34
+ make_args.concat(["arm_neon=1", "INCLUDES=-Isse2neon"])
35
+ cflags.concat(%w[-D_FILE_OFFSET_BITS=64 -mfpu=neon -fsigned-char])
36
+ end
37
+ make_args << "CFLAGS=#{cflags.join(' ')}"
38
+
39
+ Dir.chdir(build_dir) do
40
+ abort "failed to build bundled minimap2" unless system(RbConfig::CONFIG.fetch("MAKE", "make"), *make_args)
41
+ end
42
+
43
+ $INCFLAGS << " -I#{build_dir.quote}"
44
+ $LOCAL_LIBS << " #{File.join(build_dir, 'libminimap2.a').quote}"
45
+ $defs << "-DRUBY_MINIMAP2_TESTING" if enable_config("testing", false)
46
+
47
+ create_makefile("minimap2/minimap2_ext")
@@ -0,0 +1,15 @@
1
+ #include <stdlib.h>
2
+
3
+ #ifdef __clang__
4
+ #pragma clang diagnostic push
5
+ #pragma clang diagnostic ignored "-Wshorten-64-to-32"
6
+ #pragma clang diagnostic ignored "-Wincompatible-pointer-types-discards-qualifiers"
7
+ #endif
8
+
9
+ #define main mm2_embedded_main
10
+ #define exit(status) return (status)
11
+ #include "build/minimap2/main.c"
12
+
13
+ #ifdef __clang__
14
+ #pragma clang diagnostic pop
15
+ #endif