minibwa 0.0.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 (52) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +21 -0
  3. data/README.md +119 -0
  4. data/ext/minibwa/extconf.rb +105 -0
  5. data/ext/minibwa/mb_buffer.c +113 -0
  6. data/ext/minibwa/mb_hit.c +192 -0
  7. data/ext/minibwa/mb_index.c +462 -0
  8. data/ext/minibwa/mb_index_build.c +174 -0
  9. data/ext/minibwa/mb_options.c +301 -0
  10. data/ext/minibwa/minibwa/LICENSE.txt +37 -0
  11. data/ext/minibwa/minibwa/align.c +930 -0
  12. data/ext/minibwa/minibwa/bseq.h +45 -0
  13. data/ext/minibwa/minibwa/bwt.c +715 -0
  14. data/ext/minibwa/minibwa/bwt.h +86 -0
  15. data/ext/minibwa/minibwa/cs.c +161 -0
  16. data/ext/minibwa/minibwa/format.c +356 -0
  17. data/ext/minibwa/minibwa/index.c +342 -0
  18. data/ext/minibwa/minibwa/kalloc.c +224 -0
  19. data/ext/minibwa/minibwa/kalloc.h +54 -0
  20. data/ext/minibwa/minibwa/ketopt.h +123 -0
  21. data/ext/minibwa/minibwa/kommon.c +374 -0
  22. data/ext/minibwa/minibwa/kommon.h +85 -0
  23. data/ext/minibwa/minibwa/kseq.h +256 -0
  24. data/ext/minibwa/minibwa/ksort.h +163 -0
  25. data/ext/minibwa/minibwa/ksw2.h +220 -0
  26. data/ext/minibwa/minibwa/ksw2_extd2_sse.c +403 -0
  27. data/ext/minibwa/minibwa/ksw2_extz2_sse.c +296 -0
  28. data/ext/minibwa/minibwa/ksw2_ll_sse.c +341 -0
  29. data/ext/minibwa/minibwa/kthread.h +15 -0
  30. data/ext/minibwa/minibwa/l2bit.c +479 -0
  31. data/ext/minibwa/minibwa/l2bit.h +72 -0
  32. data/ext/minibwa/minibwa/lchain.c +231 -0
  33. data/ext/minibwa/minibwa/libsais.c +6985 -0
  34. data/ext/minibwa/minibwa/libsais.h +106 -0
  35. data/ext/minibwa/minibwa/libsais64.c +7064 -0
  36. data/ext/minibwa/minibwa/libsais64.h +81 -0
  37. data/ext/minibwa/minibwa/map-algo.c +769 -0
  38. data/ext/minibwa/minibwa/mbpriv.h +148 -0
  39. data/ext/minibwa/minibwa/minibwa.h +176 -0
  40. data/ext/minibwa/minibwa/options.c +116 -0
  41. data/ext/minibwa/minibwa/pe.c +559 -0
  42. data/ext/minibwa/minibwa/s2n-lite.h +59 -0
  43. data/ext/minibwa/minibwa/seed.c +354 -0
  44. data/ext/minibwa/minibwa.c +67 -0
  45. data/ext/minibwa/minibwa.h +51 -0
  46. data/lib/minibwa/hit.rb +110 -0
  47. data/lib/minibwa/index.rb +77 -0
  48. data/lib/minibwa/options.rb +235 -0
  49. data/lib/minibwa/sam.rb +85 -0
  50. data/lib/minibwa/version.rb +6 -0
  51. data/lib/minibwa.rb +11 -0
  52. metadata +88 -0
@@ -0,0 +1,235 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Minibwa
4
+ # Alignment parameters, a Ruby view of mb_opt_t.
5
+ #
6
+ # The class and all of its field accessors come from mb_options.c; this file
7
+ # reopens it for what reads better in Ruby -- keyword initialization,
8
+ # #to_h and #inspect, and rejecting an unknown preset name before it reaches
9
+ # mb_opt_preset().
10
+ #
11
+ # Presets are "sr", "adap" and "lr". Note that mb_opt_init() applies "adap",
12
+ # so a fresh Options is paired-end and adaptive by default.
13
+ #
14
+ # @!attribute [rw] flag
15
+ # @return [Integer] raw bit flags.
16
+ # @!attribute [rw] min_len
17
+ # @return [Integer] minimum seed length.
18
+ # @!attribute [rw] max_sub_occ
19
+ # @return [Integer] maximum occurrence count for sub-seeds.
20
+ # @!attribute [rw] max_occ
21
+ # @return [Integer] maximum occurrence count for seeds.
22
+ # @!attribute [rw] bw
23
+ # @return [Integer] band width for dynamic programming.
24
+ # @!attribute [rw] bw_long
25
+ # @return [Integer] band width for long alignments.
26
+ # @!attribute [rw] max_gap
27
+ # @return [Integer] maximum gap size considered during chaining.
28
+ # @!attribute [rw] max_sr_len
29
+ # @return [Integer] maximum short-read length.
30
+ # @!attribute [rw] max_chain_skip
31
+ # @return [Integer] maximum skipped anchors during chaining.
32
+ # @!attribute [rw] max_chain_iter
33
+ # @return [Integer] maximum chaining iterations.
34
+ # @!attribute [rw] min_chain_score
35
+ # @return [Integer] minimum chaining score.
36
+ # @!attribute [rw] chain_gap_scale
37
+ # @return [Float] gap penalty scale for chaining.
38
+ # @!attribute [rw] mask_level
39
+ # @return [Float] masking level for secondary hits.
40
+ # @!attribute [rw] mask_len
41
+ # @return [Integer] masking length threshold.
42
+ # @!attribute [rw] pri_ratio
43
+ # @return [Float] primary-to-secondary score ratio.
44
+ # @!attribute [rw] best_n
45
+ # @return [Integer] number of best hits retained.
46
+ # @!attribute [rw] a
47
+ # @return [Integer] match score.
48
+ # @!attribute [rw] b
49
+ # @return [Integer] mismatch penalty.
50
+ # @!attribute [rw] b_ts
51
+ # @return [Integer] transition mismatch penalty.
52
+ # @!attribute [rw] b_ambi
53
+ # @return [Integer] ambiguous-base mismatch penalty.
54
+ # @!attribute [rw] q
55
+ # @return [Integer] gap-open penalty.
56
+ # @!attribute [rw] q2
57
+ # @return [Integer] second gap-open penalty.
58
+ # @!attribute [rw] e
59
+ # @return [Integer] gap-extension penalty.
60
+ # @!attribute [rw] e2
61
+ # @return [Integer] second gap-extension penalty.
62
+ # @!attribute [rw] end_bonus
63
+ # @return [Integer] alignment end bonus.
64
+ # @!attribute [rw] min_dp_max
65
+ # @return [Integer] minimum dynamic-programming score.
66
+ # @!attribute [rw] zdrop
67
+ # @return [Integer] Z-drop threshold.
68
+ # @!attribute [rw] zdrop_inv
69
+ # @return [Integer] inversion Z-drop threshold.
70
+ # @!attribute [rw] min_ksw_len
71
+ # @return [Integer] minimum length for Smith-Waterman alignment.
72
+ # @!attribute [rw] max_pe_ins
73
+ # @return [Integer] maximum paired-end insert size.
74
+ # @!attribute [rw] max_rescue
75
+ # @return [Integer] maximum rescue attempts.
76
+ # @!attribute [rw] pen_unpair
77
+ # @return [Integer] unpaired alignment penalty.
78
+ # @!attribute [rw] pe_avg
79
+ # @return [Integer] paired-end insert-size average.
80
+ # @!attribute [rw] pe_std
81
+ # @return [Integer] paired-end insert-size standard deviation.
82
+ # @!attribute [rw] pe_lo
83
+ # @return [Integer] paired-end lower insert-size bound.
84
+ # @!attribute [rw] pe_hi
85
+ # @return [Integer] paired-end upper insert-size bound.
86
+ # @!attribute [rw] sb_len
87
+ # @return [Integer] sequence batch length.
88
+ # @!attribute [rw] sb_seq
89
+ # @return [Integer] sequence batch count.
90
+ # @!attribute [rw] n_thread
91
+ # @return [Integer] number of threads for batch work.
92
+ # @!attribute [rw] out_n
93
+ # @return [Integer] maximum number of output alignments.
94
+ # @!attribute [rw] out_s
95
+ # @return [Float] minimum output score ratio.
96
+ # @!attribute [rw] seed
97
+ # @return [Integer] random seed.
98
+ # @!attribute [rw] xa_max
99
+ # @return [Integer] maximum XA tag hits.
100
+ # @!attribute [rw] mb_size
101
+ # @return [Integer] mini-batch size.
102
+ # @!attribute [rw] max_mb_size
103
+ # @return [Integer] maximum mini-batch size.
104
+ # @!attribute [rw] max_sw_mat
105
+ # @return [Integer] maximum Smith-Waterman matrix size.
106
+ # @!attribute [rw] cap_kalloc
107
+ # @return [Integer] kalloc capacity limit.
108
+ #
109
+ # @!method paf?
110
+ # @return [Boolean] whether PAF output mode is enabled.
111
+ # @!method paf=(value)
112
+ # @return [Object] value
113
+ # @!method no_unmap?
114
+ # @return [Boolean] whether unmapped records are suppressed.
115
+ # @!method no_unmap=(value)
116
+ # @return [Object] value
117
+ # @!method copy_comment?
118
+ # @return [Boolean] whether FASTQ comments are copied.
119
+ # @!method copy_comment=(value)
120
+ # @return [Object] value
121
+ # @!method pe?
122
+ # @return [Boolean] whether paired-end mode is enabled.
123
+ # @!method pe=(value)
124
+ # @return [Object] value
125
+ # @!method long_mode?
126
+ # @return [Boolean] whether long-read mode is enabled.
127
+ # @!method long_mode=(value)
128
+ # @return [Object] value
129
+ # @!method eqx?
130
+ # @return [Boolean] whether CIGAR uses =/X operators.
131
+ # @!method eqx=(value)
132
+ # @return [Object] value
133
+ # @!method no_kalloc?
134
+ # @return [Boolean] whether kalloc is disabled.
135
+ # @!method no_kalloc=(value)
136
+ # @return [Object] value
137
+ # @!method no_aln?
138
+ # @return [Boolean] whether alignment is disabled.
139
+ # @!method no_aln=(value)
140
+ # @return [Object] value
141
+ # @!method pe_predef?
142
+ # @return [Boolean] whether paired-end bounds are predefined.
143
+ # @!method pe_predef=(value)
144
+ # @return [Object] value
145
+ # @!method write_ds?
146
+ # @return [Boolean] whether the DS tag is emitted.
147
+ # @!method write_ds=(value)
148
+ # @return [Object] value
149
+ # @!method write_cs?
150
+ # @return [Boolean] whether the CS tag is emitted.
151
+ # @!method write_cs=(value)
152
+ # @return [Object] value
153
+ # @!method write_md?
154
+ # @return [Boolean] whether the MD tag is emitted.
155
+ # @!method write_md=(value)
156
+ # @return [Object] value
157
+ # @!method second_seq?
158
+ # @return [Boolean] whether second-sequence output is enabled.
159
+ # @!method second_seq=(value)
160
+ # @return [Object] value
161
+ # @!method supp_soft?
162
+ # @return [Boolean] whether supplementary alignments use soft clipping.
163
+ # @!method supp_soft=(value)
164
+ # @return [Object] value
165
+ # @!method adap?
166
+ # @return [Boolean] whether adaptive mode is enabled.
167
+ # @!method adap=(value)
168
+ # @return [Object] value
169
+ # @!method primary5?
170
+ # @return [Boolean] whether primary alignment selection is 5-prime based.
171
+ # @!method primary5=(value)
172
+ # @return [Object] value
173
+ # @!method no_pairing?
174
+ # @return [Boolean] whether pairing is disabled.
175
+ # @!method no_pairing=(value)
176
+ # @return [Object] value
177
+ # @!method meth?
178
+ # @return [Boolean] whether methylation mode is enabled.
179
+ # @!method meth=(value)
180
+ # @return [Object] value
181
+ class Options
182
+ # Supported preset names for {#preset}.
183
+ PRESETS = %w[sr adap lr].freeze
184
+
185
+ # Applies a named preset with validation.
186
+ #
187
+ # opt.preset("sr") # => true
188
+ # opt.preset("bad") # raises ArgumentError
189
+ def preset(name)
190
+ unless PRESETS.include?(name.to_s)
191
+ raise ArgumentError, "unknown preset: #{name.inspect}, expected one of #{PRESETS.inspect}"
192
+ end
193
+
194
+ preset!(name)
195
+ end
196
+
197
+ # Returns all field values as a Hash.
198
+ def to_h
199
+ {
200
+ flag: flag, min_len: min_len, max_sub_occ: max_sub_occ, max_occ: max_occ,
201
+ bw: bw, bw_long: bw_long, max_gap: max_gap, max_sr_len: max_sr_len,
202
+ max_chain_skip: max_chain_skip, max_chain_iter: max_chain_iter,
203
+ min_chain_score: min_chain_score, chain_gap_scale: chain_gap_scale,
204
+ mask_level: mask_level, mask_len: mask_len, pri_ratio: pri_ratio,
205
+ best_n: best_n, a: a, b: b, b_ts: b_ts, b_ambi: b_ambi,
206
+ q: q, q2: q2, e: e, e2: e2, end_bonus: end_bonus,
207
+ min_dp_max: min_dp_max, zdrop: zdrop, zdrop_inv: zdrop_inv,
208
+ min_ksw_len: min_ksw_len, max_pe_ins: max_pe_ins, max_rescue: max_rescue,
209
+ pen_unpair: pen_unpair, pe_avg: pe_avg, pe_std: pe_std,
210
+ pe_lo: pe_lo, pe_hi: pe_hi, sb_len: sb_len, sb_seq: sb_seq,
211
+ n_thread: n_thread, out_n: out_n, out_s: out_s, seed: seed,
212
+ xa_max: xa_max, mb_size: mb_size, max_mb_size: max_mb_size,
213
+ max_sw_mat: max_sw_mat, cap_kalloc: cap_kalloc
214
+ }
215
+ end
216
+
217
+ # Returns a compact representation of all option fields.
218
+ def inspect
219
+ "#<#{self.class.name} #{to_h.map { |k, v| "#{k}=#{v.inspect}" }.join(', ')}>"
220
+ end
221
+
222
+ private
223
+
224
+ # Called from C's initialize with a keyword-arguments Hash.
225
+ # @api private
226
+ def __keyword_new__(kwargs)
227
+ kwargs.each do |key, value|
228
+ setter = :"#{key}="
229
+ raise ArgumentError, "unknown option: #{key}" unless respond_to?(setter)
230
+
231
+ public_send(setter, value)
232
+ end
233
+ end
234
+ end
235
+ end
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Minibwa
4
+ # SAM output built from Hit objects, in pure Ruby.
5
+ #
6
+ # Upstream's mb_fmt_sam() is deliberately not wrapped: it takes types that
7
+ # live in the private mbpriv.h (l2b_t, mb_bseq1_t) and would tie the gem to
8
+ # minibwa's internals. Doing it here also puts the soft clips that
9
+ # Hit#cigar omits back into the emitted CIGAR.
10
+ #
11
+ # == Reverse-strand alignments
12
+ #
13
+ # For reverse-strand alignments (Hit#rev == true), the SAM spec requires
14
+ # SEQ to be the reverse complement of the original query and the FLAG
15
+ # to have 0x10 set. Sam.format does NOT do this automatically: callers
16
+ # must pass the already-oriented sequence and the correct flag. This is
17
+ # because the library does not retain the original query sequence after
18
+ # mapping.
19
+ module Sam
20
+ module_function
21
+
22
+ # Generates a SAM header from an Index.
23
+ #
24
+ # puts Minibwa::Sam.header(index)
25
+ def header(index, hd: nil, pg: nil, rg: nil)
26
+ lines = [hd || "@HD\tVN:1.6\tSO:unsorted"]
27
+
28
+ # Reference sequences from the index
29
+ tid = 0
30
+ while (name = index.ctg_name(tid))
31
+ len = index.ctg_len(tid)
32
+ lines << "@SQ\tSN:#{name}\tLN:#{len}"
33
+ tid += 1
34
+ end
35
+
36
+ lines << pg if pg
37
+ lines << rg if rg
38
+ lines.join("\n") + "\n"
39
+ end
40
+
41
+ # Formats a single alignment as a SAM line.
42
+ #
43
+ # +qname+:: query name.
44
+ # +flag+:: SAM flag (Integer).
45
+ # +hit+:: a Minibwa::Hit.
46
+ # +seq+:: the original query sequence.
47
+ # +qual+:: the original quality string (or "*").
48
+ # +mate+:: optional mate Hit for paired-end reads.
49
+ #
50
+ # Returns a SAM line String (without trailing newline).
51
+ def format(qname, flag, hit, seq, qual = '*', mate: nil)
52
+ rnext, pnext = if mate
53
+ # '=' means the mate is on the same reference sequence.
54
+ mate_ref = mate.ctg == hit.ctg && hit.ctg ? '=' : mate.ctg || '*'
55
+ [mate_ref, mate.ts + 1]
56
+ else
57
+ ['*', 0]
58
+ end
59
+
60
+ # For reverse-strand alignments the SEQ field should be the reverse
61
+ # complement of the original query (SAM spec). Callers must pass the
62
+ # already-oriented sequence; see the module documentation at the top
63
+ # of this file.
64
+ # NM is the edit distance, not the number of suboptimal alignments.
65
+ # blen - mlen counts the non-matching positions within the alignment.
66
+ [
67
+ qname, flag, hit.ctg || '*', hit.ts + 1, hit.mapq,
68
+ build_full_cigar(hit, seq.length), rnext, pnext, 0,
69
+ seq || '*', qual || '*',
70
+ "NM:i:#{hit.blen - hit.mlen}", "AS:i:#{hit.score}"
71
+ ].join("\t")
72
+ end
73
+
74
+ # Builds the full CIGAR string including soft clips.
75
+ def build_full_cigar(hit, query_len)
76
+ parts = []
77
+ parts << "#{hit.qs}S" if hit.qs > 0
78
+ cigar = hit.cigar_str
79
+ parts << cigar unless cigar.empty?
80
+ soft_clip = query_len - hit.qe
81
+ parts << "#{soft_clip}S" if soft_clip > 0
82
+ parts.empty? ? '*' : parts.join
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Minibwa
4
+ # Gem version.
5
+ VERSION = '0.0.0'
6
+ end
data/lib/minibwa.rb ADDED
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'minibwa/version'
4
+ require 'minibwa/minibwa'
5
+
6
+ require_relative 'minibwa/options'
7
+ require_relative 'minibwa/index'
8
+ require_relative 'minibwa/hit'
9
+ require_relative 'minibwa/sam'
10
+
11
+ # Minibwa::Error is defined in the C extension (minibwa.c).
metadata ADDED
@@ -0,0 +1,88 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: minibwa
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ platform: ruby
6
+ authors:
7
+ - kojix2
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies: []
12
+ executables: []
13
+ extensions:
14
+ - ext/minibwa/extconf.rb
15
+ extra_rdoc_files: []
16
+ files:
17
+ - LICENSE.txt
18
+ - README.md
19
+ - ext/minibwa/extconf.rb
20
+ - ext/minibwa/mb_buffer.c
21
+ - ext/minibwa/mb_hit.c
22
+ - ext/minibwa/mb_index.c
23
+ - ext/minibwa/mb_index_build.c
24
+ - ext/minibwa/mb_options.c
25
+ - ext/minibwa/minibwa.c
26
+ - ext/minibwa/minibwa.h
27
+ - ext/minibwa/minibwa/LICENSE.txt
28
+ - ext/minibwa/minibwa/align.c
29
+ - ext/minibwa/minibwa/bseq.h
30
+ - ext/minibwa/minibwa/bwt.c
31
+ - ext/minibwa/minibwa/bwt.h
32
+ - ext/minibwa/minibwa/cs.c
33
+ - ext/minibwa/minibwa/format.c
34
+ - ext/minibwa/minibwa/index.c
35
+ - ext/minibwa/minibwa/kalloc.c
36
+ - ext/minibwa/minibwa/kalloc.h
37
+ - ext/minibwa/minibwa/ketopt.h
38
+ - ext/minibwa/minibwa/kommon.c
39
+ - ext/minibwa/minibwa/kommon.h
40
+ - ext/minibwa/minibwa/kseq.h
41
+ - ext/minibwa/minibwa/ksort.h
42
+ - ext/minibwa/minibwa/ksw2.h
43
+ - ext/minibwa/minibwa/ksw2_extd2_sse.c
44
+ - ext/minibwa/minibwa/ksw2_extz2_sse.c
45
+ - ext/minibwa/minibwa/ksw2_ll_sse.c
46
+ - ext/minibwa/minibwa/kthread.h
47
+ - ext/minibwa/minibwa/l2bit.c
48
+ - ext/minibwa/minibwa/l2bit.h
49
+ - ext/minibwa/minibwa/lchain.c
50
+ - ext/minibwa/minibwa/libsais.c
51
+ - ext/minibwa/minibwa/libsais.h
52
+ - ext/minibwa/minibwa/libsais64.c
53
+ - ext/minibwa/minibwa/libsais64.h
54
+ - ext/minibwa/minibwa/map-algo.c
55
+ - ext/minibwa/minibwa/mbpriv.h
56
+ - ext/minibwa/minibwa/minibwa.h
57
+ - ext/minibwa/minibwa/options.c
58
+ - ext/minibwa/minibwa/pe.c
59
+ - ext/minibwa/minibwa/s2n-lite.h
60
+ - ext/minibwa/minibwa/seed.c
61
+ - lib/minibwa.rb
62
+ - lib/minibwa/hit.rb
63
+ - lib/minibwa/index.rb
64
+ - lib/minibwa/options.rb
65
+ - lib/minibwa/sam.rb
66
+ - lib/minibwa/version.rb
67
+ homepage: https://github.com/kojix2/ruby-minibwa
68
+ licenses:
69
+ - MIT
70
+ metadata: {}
71
+ rdoc_options: []
72
+ require_paths:
73
+ - lib
74
+ required_ruby_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: 3.2.0
79
+ required_rubygems_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ requirements: []
85
+ rubygems_version: 4.0.16
86
+ specification_version: 4
87
+ summary: Ruby bindings for minibwa, a short-read aligner
88
+ test_files: []