htslib 0.4.2 → 0.5.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.
- checksums.yaml +4 -4
- data/README.md +79 -49
- data/TUTORIAL.md +9 -20
- data/ext/htslib_native/extconf.rb +41 -0
- data/ext/htslib_native/htslib_native.h +11 -0
- data/ext/htslib_native/htslib_native_ext.c +48 -0
- data/ext/htslib_native/native_bam.c +1108 -0
- data/ext/htslib_native/native_bcf.c +369 -0
- data/ext/htslib_native/native_faidx.c +155 -0
- data/ext/htslib_native/native_tabix.c +246 -0
- data/lib/hts/bam/auxi.rb +87 -342
- data/lib/hts/bam/base_mod.rb +37 -73
- data/lib/hts/bam/cigar.rb +9 -55
- data/lib/hts/bam/flag.rb +19 -27
- data/lib/hts/bam/header.rb +29 -56
- data/lib/hts/bam/mpileup.rb +158 -132
- data/lib/hts/bam/pileup.rb +120 -145
- data/lib/hts/bam/record.rb +233 -270
- data/lib/hts/bam.rb +102 -42
- data/lib/hts/bcf/errors.rb +1 -0
- data/lib/hts/bcf/format.rb +278 -379
- data/lib/hts/bcf/header.rb +38 -122
- data/lib/hts/bcf/header_record.rb +9 -35
- data/lib/hts/bcf/info.rb +72 -320
- data/lib/hts/bcf/record.rb +61 -102
- data/lib/hts/bcf.rb +149 -323
- data/lib/hts/faidx.rb +28 -87
- data/lib/hts/hts.rb +6 -94
- data/lib/hts/native.rb +13 -0
- data/lib/hts/tabix.rb +93 -48
- data/lib/hts/version.rb +1 -1
- data/lib/htslib.rb +6 -52
- metadata +13 -64
- data/lib/hts/ffi_ext/README.md +0 -8
- data/lib/hts/ffi_ext/pointer.rb +0 -18
- data/lib/hts/ffi_ext/struct.rb +0 -45
- data/lib/hts/libhts/bgzf.rb +0 -199
- data/lib/hts/libhts/constants.rb +0 -658
- data/lib/hts/libhts/cram.rb +0 -471
- data/lib/hts/libhts/fai.rb +0 -146
- data/lib/hts/libhts/hfile.rb +0 -121
- data/lib/hts/libhts/hts.rb +0 -477
- data/lib/hts/libhts/kfunc.rb +0 -38
- data/lib/hts/libhts/sam.rb +0 -760
- data/lib/hts/libhts/sam_funcs.rb +0 -155
- data/lib/hts/libhts/tbx.rb +0 -94
- data/lib/hts/libhts/tbx_funcs.rb +0 -36
- data/lib/hts/libhts/thread_pool.rb +0 -139
- data/lib/hts/libhts/vcf.rb +0 -567
- data/lib/hts/libhts/vcf_funcs.rb +0 -366
- data/lib/hts/libhts.rb +0 -47
data/lib/hts/bam/base_mod.rb
CHANGED
|
@@ -133,11 +133,10 @@ module HTS
|
|
|
133
133
|
# @param auto_parse [Boolean] If true, parse MM/ML lazily on first access
|
|
134
134
|
def initialize(record, auto_parse: true)
|
|
135
135
|
@record = record
|
|
136
|
-
@state =
|
|
136
|
+
@state = Native::BaseModHandle.open(record.__send__(:native_handle))
|
|
137
137
|
@closed = false
|
|
138
138
|
@auto_parse = !!auto_parse
|
|
139
139
|
@parsed = false
|
|
140
|
-
raise Error, "Failed to allocate hts_base_mod_state" if @state.null?
|
|
141
140
|
end
|
|
142
141
|
|
|
143
142
|
# Explicitly free the state
|
|
@@ -145,8 +144,7 @@ module HTS
|
|
|
145
144
|
def close
|
|
146
145
|
return if @closed
|
|
147
146
|
|
|
148
|
-
|
|
149
|
-
# is sufficient. Avoid manual free to prevent double-free.
|
|
147
|
+
@state.close
|
|
150
148
|
@state = nil
|
|
151
149
|
@closed = true
|
|
152
150
|
end
|
|
@@ -173,7 +171,7 @@ module HTS
|
|
|
173
171
|
# @return [Integer] Number of modification types found, or -1 on error
|
|
174
172
|
# @raise [Error] If parsing fails
|
|
175
173
|
def parse(flags = 0)
|
|
176
|
-
ret =
|
|
174
|
+
ret = @state.parse(flags)
|
|
177
175
|
raise Error, "Failed to parse base modifications" if ret < 0
|
|
178
176
|
|
|
179
177
|
@parsed = true
|
|
@@ -188,13 +186,10 @@ module HTS
|
|
|
188
186
|
# Reset state to ensure deterministic results even after prior iteration
|
|
189
187
|
parsed? ? parse : ensure_parsed!
|
|
190
188
|
|
|
191
|
-
|
|
189
|
+
values = @state.at(position, max_mods)
|
|
190
|
+
return nil unless values
|
|
192
191
|
|
|
193
|
-
|
|
194
|
-
mods_ptr, max_mods)
|
|
195
|
-
return nil if ret <= 0
|
|
196
|
-
|
|
197
|
-
build_position(position, mods_ptr, [ret, max_mods].min)
|
|
192
|
+
build_position(position, values)
|
|
198
193
|
end
|
|
199
194
|
|
|
200
195
|
# Array-style access to modifications at a position
|
|
@@ -211,36 +206,41 @@ module HTS
|
|
|
211
206
|
def each_position(max_mods: 10)
|
|
212
207
|
return enum_for(__method__, max_mods: max_mods) unless block_given?
|
|
213
208
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
yield build_position(position, mods_ptr, [ret, max_mods].min)
|
|
209
|
+
current_position = nil
|
|
210
|
+
modifications = []
|
|
211
|
+
each_raw(max_mods: max_mods) do |position, canonical, modified, strand, qual|
|
|
212
|
+
if current_position && position != current_position
|
|
213
|
+
yield Position.new(current_position, modifications)
|
|
214
|
+
modifications = []
|
|
215
|
+
end
|
|
216
|
+
current_position = position
|
|
217
|
+
modifications << Modification.new(
|
|
218
|
+
modified_base: modified, canonical_base: canonical,
|
|
219
|
+
strand: strand, qual: qual
|
|
220
|
+
)
|
|
227
221
|
end
|
|
222
|
+
yield Position.new(current_position, modifications) if current_position
|
|
223
|
+
self
|
|
228
224
|
end
|
|
229
225
|
|
|
230
226
|
alias each each_position
|
|
231
227
|
|
|
228
|
+
# Iterate primitive modification values without Position/Modification
|
|
229
|
+
# object allocation.
|
|
230
|
+
def each_raw(max_mods: 10)
|
|
231
|
+
return enum_for(__method__, max_mods: max_mods) unless block_given?
|
|
232
|
+
|
|
233
|
+
parsed? ? parse : ensure_parsed!
|
|
234
|
+
@state.each_raw(max_mods) { |*values| yield(*values) }
|
|
235
|
+
self
|
|
236
|
+
end
|
|
237
|
+
|
|
232
238
|
# Get list of modification types present in this record
|
|
233
239
|
# @return [Array<Integer>] Array of modification codes (char code or -ChEBI)
|
|
234
240
|
def modification_types
|
|
235
241
|
ensure_parsed!
|
|
236
242
|
|
|
237
|
-
|
|
238
|
-
codes_ptr = LibHTS.bam_mods_recorded(@state, ntype_ptr)
|
|
239
|
-
|
|
240
|
-
ntype = ntype_ptr.read_int
|
|
241
|
-
return [] if ntype <= 0 || codes_ptr.null?
|
|
242
|
-
|
|
243
|
-
codes_ptr.read_array_of_int(ntype)
|
|
243
|
+
@state.types
|
|
244
244
|
end
|
|
245
245
|
|
|
246
246
|
alias recorded_types modification_types
|
|
@@ -253,19 +253,7 @@ module HTS
|
|
|
253
253
|
|
|
254
254
|
code = code.ord if code.is_a?(String)
|
|
255
255
|
|
|
256
|
-
|
|
257
|
-
implicit_ptr = FFI::MemoryPointer.new(:int)
|
|
258
|
-
canonical_ptr = FFI::MemoryPointer.new(:char, 1)
|
|
259
|
-
|
|
260
|
-
ret = LibHTS.bam_mods_query_type(@state, code, strand_ptr,
|
|
261
|
-
implicit_ptr, canonical_ptr)
|
|
262
|
-
return nil if ret < 0
|
|
263
|
-
|
|
264
|
-
{
|
|
265
|
-
canonical: canonical_ptr.read_char.chr,
|
|
266
|
-
strand: strand_ptr.read_int,
|
|
267
|
-
implicit: implicit_ptr.read_int != 0
|
|
268
|
-
}
|
|
256
|
+
@state.query(code)
|
|
269
257
|
end
|
|
270
258
|
|
|
271
259
|
# Query information about i-th modification type
|
|
@@ -274,21 +262,7 @@ module HTS
|
|
|
274
262
|
def query_type_at(index)
|
|
275
263
|
ensure_parsed!
|
|
276
264
|
|
|
277
|
-
|
|
278
|
-
implicit_ptr = FFI::MemoryPointer.new(:int)
|
|
279
|
-
canonical_ptr = FFI::MemoryPointer.new(:char, 1)
|
|
280
|
-
|
|
281
|
-
ret = LibHTS.bam_mods_queryi(@state, index, strand_ptr,
|
|
282
|
-
implicit_ptr, canonical_ptr)
|
|
283
|
-
return nil if ret < 0
|
|
284
|
-
|
|
285
|
-
types = modification_types
|
|
286
|
-
{
|
|
287
|
-
code: types[index],
|
|
288
|
-
canonical: canonical_ptr.read_char.chr,
|
|
289
|
-
strand: strand_ptr.read_int,
|
|
290
|
-
implicit: implicit_ptr.read_int != 0
|
|
291
|
-
}
|
|
265
|
+
@state.query_at(index)
|
|
292
266
|
end
|
|
293
267
|
|
|
294
268
|
# Get all modifications as an array
|
|
@@ -319,21 +293,11 @@ module HTS
|
|
|
319
293
|
|
|
320
294
|
# Build Position object from hts_base_mod array
|
|
321
295
|
# @param position [Integer] Query position
|
|
322
|
-
# @param
|
|
323
|
-
# @param n_mods [Integer] Number of modifications
|
|
296
|
+
# @param values [Array<Array>] Native modification values
|
|
324
297
|
# @return [Position] Position object
|
|
325
|
-
def build_position(position,
|
|
326
|
-
modifications =
|
|
327
|
-
|
|
328
|
-
n_mods.times do |i|
|
|
329
|
-
mod_struct = LibHTS::HtsBaseMod.new(mods_ptr + i * LibHTS::HtsBaseMod.size)
|
|
330
|
-
|
|
331
|
-
modifications << Modification.new(
|
|
332
|
-
modified_base: mod_struct[:modified_base],
|
|
333
|
-
canonical_base: mod_struct[:canonical_base],
|
|
334
|
-
strand: mod_struct[:strand],
|
|
335
|
-
qual: mod_struct[:qual]
|
|
336
|
-
)
|
|
298
|
+
def build_position(position, values)
|
|
299
|
+
modifications = values.map do |canonical, modified, strand, qual|
|
|
300
|
+
Modification.new(modified_base: modified, canonical_base: canonical, strand:, qual:)
|
|
337
301
|
end
|
|
338
302
|
|
|
339
303
|
Position.new(position, modifications)
|
data/lib/hts/bam/cigar.rb
CHANGED
|
@@ -2,78 +2,32 @@
|
|
|
2
2
|
|
|
3
3
|
module HTS
|
|
4
4
|
class Bam < Hts
|
|
5
|
-
# CIGAR string
|
|
6
5
|
class Cigar
|
|
7
6
|
include Enumerable
|
|
8
7
|
|
|
9
|
-
|
|
8
|
+
OP_CHARS = "MIDNSHP=XB"
|
|
10
9
|
attr_accessor :array
|
|
11
10
|
|
|
12
|
-
# Create a new Cigar object from a string.
|
|
13
|
-
# @param [String] cigar_str
|
|
14
|
-
# The CIGAR string is converted to a uint32_t array in htslib.
|
|
15
11
|
def self.parse(str)
|
|
16
|
-
|
|
17
|
-
m = FFI::MemoryPointer.new(:size_t)
|
|
18
|
-
c.write_pointer(FFI::Pointer::NULL)
|
|
19
|
-
m.write(:size_t, 0)
|
|
20
|
-
ptr = nil
|
|
21
|
-
n_cigar = LibHTS.sam_parse_cigar(str, FFI::Pointer::NULL, c, m)
|
|
22
|
-
raise "sam_parse_cigar failed: #{n_cigar}" if n_cigar.negative?
|
|
23
|
-
|
|
24
|
-
ptr = c.read_pointer
|
|
25
|
-
cigar_array = ptr.null? ? [] : ptr.read_array_of_uint32(n_cigar)
|
|
26
|
-
obj = new
|
|
27
|
-
obj.array = cigar_array
|
|
28
|
-
obj
|
|
29
|
-
ensure
|
|
30
|
-
LibHTS.hts_free(ptr) if ptr && !ptr.null?
|
|
12
|
+
new.tap { |cigar| cigar.array = Native.cigar_parse(str.to_s) }
|
|
31
13
|
end
|
|
32
14
|
|
|
33
15
|
def initialize(record = nil)
|
|
34
|
-
|
|
35
|
-
# The record is used at initialization and is not retained after that.
|
|
36
|
-
bam1 = record.struct
|
|
37
|
-
n_cigar = bam1[:core][:n_cigar]
|
|
38
|
-
@array = LibHTS.bam_get_cigar(bam1).read_array_of_uint32(n_cigar)
|
|
39
|
-
else
|
|
40
|
-
@array = []
|
|
41
|
-
end
|
|
16
|
+
@array = record ? record.__send__(:native_handle).cigar_values : []
|
|
42
17
|
end
|
|
43
18
|
|
|
44
|
-
def to_s
|
|
45
|
-
map { |op, len| "#{len}#{op}" }.join
|
|
46
|
-
end
|
|
19
|
+
def to_s = map { |op, len| "#{len}#{op}" }.join
|
|
47
20
|
|
|
48
21
|
def each
|
|
49
22
|
return to_enum(__method__) unless block_given?
|
|
50
23
|
|
|
51
|
-
@array.each
|
|
52
|
-
op = LibHTS.bam_cigar_opchr(c)
|
|
53
|
-
len = LibHTS.bam_cigar_oplen(c)
|
|
54
|
-
yield [op, len]
|
|
55
|
-
end
|
|
24
|
+
@array.each { |encoded| yield OP_CHARS[encoded & 15], encoded >> 4 }
|
|
56
25
|
end
|
|
57
26
|
|
|
58
|
-
def qlen
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
def rlen
|
|
65
|
-
a = FFI::MemoryPointer.new(:uint32, @array.size)
|
|
66
|
-
a.write_array_of_uint32(@array)
|
|
67
|
-
LibHTS.bam_cigar2rlen(@array.size, a)
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
def ==(other)
|
|
71
|
-
other.is_a?(Cigar) && (@array == other.array)
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
def eql?(other)
|
|
75
|
-
other.is_a?(Cigar) && @array.eql?(other.array)
|
|
76
|
-
end
|
|
27
|
+
def qlen = Native.cigar_qlen(@array)
|
|
28
|
+
def rlen = Native.cigar_rlen(@array)
|
|
29
|
+
def ==(other) = other.is_a?(Cigar) && @array == other.array
|
|
30
|
+
def eql?(other) = other.is_a?(Cigar) && @array.eql?(other.array)
|
|
77
31
|
end
|
|
78
32
|
end
|
|
79
33
|
end
|
data/lib/hts/bam/flag.rb
CHANGED
|
@@ -15,31 +15,24 @@ module HTS
|
|
|
15
15
|
|
|
16
16
|
attr_accessor :value
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
TABLE = { paired?:
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
mate_reverse?: LibHTS::BAM_FMREVERSE,
|
|
37
|
-
read1?: LibHTS::BAM_FREAD1,
|
|
38
|
-
read2?: LibHTS::BAM_FREAD2,
|
|
39
|
-
secondary?: LibHTS::BAM_FSECONDARY,
|
|
40
|
-
qcfail?: LibHTS::BAM_FQCFAIL,
|
|
41
|
-
duplicate?: LibHTS::BAM_FDUP,
|
|
42
|
-
supplementary?: LibHTS::BAM_FSUPPLEMENTARY }.freeze
|
|
18
|
+
PAIRED = 1
|
|
19
|
+
PROPER_PAIR = 2
|
|
20
|
+
UNMAPPED = 4
|
|
21
|
+
MATE_UNMAPPED = 8
|
|
22
|
+
REVERSE = 16
|
|
23
|
+
MATE_REVERSE = 32
|
|
24
|
+
READ1 = 64
|
|
25
|
+
READ2 = 128
|
|
26
|
+
SECONDARY = 256
|
|
27
|
+
QCFAIL = 512
|
|
28
|
+
DUPLICATE = 1024
|
|
29
|
+
SUPPLEMENTARY = 2048
|
|
30
|
+
|
|
31
|
+
TABLE = { paired?: PAIRED, proper_pair?: PROPER_PAIR, unmapped?: UNMAPPED,
|
|
32
|
+
mate_unmapped?: MATE_UNMAPPED, reverse?: REVERSE,
|
|
33
|
+
mate_reverse?: MATE_REVERSE, read1?: READ1, read2?: READ2,
|
|
34
|
+
secondary?: SECONDARY, qcfail?: QCFAIL, duplicate?: DUPLICATE,
|
|
35
|
+
supplementary?: SUPPLEMENTARY }.freeze
|
|
43
36
|
|
|
44
37
|
# @!macro [attach] generate_flag_methods
|
|
45
38
|
# @!method $1
|
|
@@ -99,8 +92,7 @@ module HTS
|
|
|
99
92
|
end
|
|
100
93
|
|
|
101
94
|
def to_s
|
|
102
|
-
|
|
103
|
-
# "0x#{format('%x', @value)}\t#{@value}\t#{LibHTS.bam_flag2str(@value)}"
|
|
95
|
+
Native.bam_flag_string(@value)
|
|
104
96
|
end
|
|
105
97
|
end
|
|
106
98
|
end
|
data/lib/hts/bam/header.rb
CHANGED
|
@@ -40,17 +40,15 @@ module HTS
|
|
|
40
40
|
}.freeze
|
|
41
41
|
|
|
42
42
|
def self.parse(text)
|
|
43
|
-
new(
|
|
43
|
+
new(Native::SamHeaderHandle.parse(text))
|
|
44
44
|
end
|
|
45
45
|
|
|
46
46
|
def initialize(arg = nil)
|
|
47
47
|
case arg
|
|
48
|
-
when
|
|
49
|
-
@
|
|
50
|
-
when LibHTS::SamHdr
|
|
51
|
-
@sam_hdr = arg
|
|
48
|
+
when Native::SamHeaderHandle
|
|
49
|
+
@native = arg
|
|
52
50
|
when nil
|
|
53
|
-
@
|
|
51
|
+
@native = Native::SamHeaderHandle.create
|
|
54
52
|
else
|
|
55
53
|
raise TypeError, "Invalid argument"
|
|
56
54
|
end
|
|
@@ -58,25 +56,16 @@ module HTS
|
|
|
58
56
|
yield self if block_given?
|
|
59
57
|
end
|
|
60
58
|
|
|
61
|
-
def struct
|
|
62
|
-
@sam_hdr
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
def to_ptr
|
|
66
|
-
@sam_hdr.to_ptr
|
|
67
|
-
end
|
|
68
|
-
|
|
69
59
|
def targets
|
|
70
60
|
Array.new(target_count) do |i|
|
|
71
|
-
name =
|
|
72
|
-
len =
|
|
61
|
+
name = @native.target_name(i)
|
|
62
|
+
len = @native.target_length(i)
|
|
73
63
|
{ name:, len: }
|
|
74
64
|
end
|
|
75
65
|
end
|
|
76
66
|
|
|
77
67
|
def target_count
|
|
78
|
-
|
|
79
|
-
@sam_hdr[:n_targets]
|
|
68
|
+
@native.target_count
|
|
80
69
|
end
|
|
81
70
|
|
|
82
71
|
def target_name(tid)
|
|
@@ -85,13 +74,13 @@ module HTS
|
|
|
85
74
|
|
|
86
75
|
def target_names
|
|
87
76
|
Array.new(target_count) do |i|
|
|
88
|
-
|
|
77
|
+
@native.target_name(i)
|
|
89
78
|
end
|
|
90
79
|
end
|
|
91
80
|
|
|
92
81
|
def target_len
|
|
93
82
|
Array.new(target_count) do |i|
|
|
94
|
-
|
|
83
|
+
@native.target_length(i)
|
|
95
84
|
end
|
|
96
85
|
end
|
|
97
86
|
|
|
@@ -118,68 +107,50 @@ module HTS
|
|
|
118
107
|
|
|
119
108
|
# experimental
|
|
120
109
|
def find_line(type, key, value)
|
|
121
|
-
|
|
122
|
-
begin
|
|
123
|
-
r = LibHTS.sam_hdr_find_line_id(@sam_hdr, type, key, value, ks)
|
|
124
|
-
r == 0 ? ks.read_string_copy : nil
|
|
125
|
-
ensure
|
|
126
|
-
ks.free_buffer
|
|
127
|
-
end
|
|
110
|
+
@native.find_line(type, key, value)
|
|
128
111
|
end
|
|
129
112
|
|
|
130
113
|
def find_tag(type, id_key, id_value, key)
|
|
131
|
-
|
|
132
|
-
begin
|
|
133
|
-
r = LibHTS.sam_hdr_find_tag_id(@sam_hdr, type, id_key, id_value, key, ks)
|
|
134
|
-
r == 0 ? ks.read_string_copy : nil
|
|
135
|
-
ensure
|
|
136
|
-
ks.free_buffer
|
|
137
|
-
end
|
|
114
|
+
@native.find_tag(type, id_key, id_value, key)
|
|
138
115
|
end
|
|
139
116
|
|
|
140
117
|
# experimental
|
|
141
118
|
def find_line_at(type, pos)
|
|
142
|
-
|
|
143
|
-
begin
|
|
144
|
-
r = LibHTS.sam_hdr_find_line_pos(@sam_hdr, type, pos, ks)
|
|
145
|
-
r == 0 ? ks.read_string_copy : nil
|
|
146
|
-
ensure
|
|
147
|
-
ks.free_buffer
|
|
148
|
-
end
|
|
119
|
+
@native.find_line_at(type, pos)
|
|
149
120
|
end
|
|
150
121
|
|
|
151
122
|
# experimental
|
|
152
123
|
def remove_line(type, key, value)
|
|
153
|
-
|
|
124
|
+
@native.remove_line(type, key, value)
|
|
154
125
|
end
|
|
155
126
|
|
|
156
127
|
# experimental
|
|
157
128
|
def remove_line_at(type, pos)
|
|
158
|
-
|
|
129
|
+
@native.remove_line_at(type, pos)
|
|
159
130
|
end
|
|
160
131
|
|
|
161
132
|
def delete_line(type, key = nil, value = nil)
|
|
162
|
-
|
|
133
|
+
@native.remove_line(type, key, value).zero?
|
|
163
134
|
end
|
|
164
135
|
|
|
165
136
|
def delete_tag(type, id_key, id_value, key)
|
|
166
|
-
|
|
137
|
+
@native.remove_tag(type, id_key, id_value, key) == 1
|
|
167
138
|
end
|
|
168
139
|
|
|
169
140
|
def count_lines(type)
|
|
170
|
-
|
|
141
|
+
@native.count_lines(type)
|
|
171
142
|
end
|
|
172
143
|
|
|
173
144
|
def line_index(type, key)
|
|
174
|
-
|
|
145
|
+
@native.line_index(type, key)
|
|
175
146
|
end
|
|
176
147
|
|
|
177
148
|
def line_name(type, pos)
|
|
178
|
-
|
|
149
|
+
@native.line_name(type, pos)
|
|
179
150
|
end
|
|
180
151
|
|
|
181
152
|
def to_s
|
|
182
|
-
|
|
153
|
+
@native.to_s
|
|
183
154
|
end
|
|
184
155
|
|
|
185
156
|
# experimental
|
|
@@ -241,7 +212,7 @@ module HTS
|
|
|
241
212
|
# header.add_pg("samtools", VN: "1.15", PP: "bwa")
|
|
242
213
|
def add_pg(program_name, **options)
|
|
243
214
|
line = build_pg_line(program_name.to_s, options)
|
|
244
|
-
result =
|
|
215
|
+
result = @native.add_lines(line)
|
|
245
216
|
raise "Failed to add @PG line" if result < 0
|
|
246
217
|
|
|
247
218
|
self
|
|
@@ -418,26 +389,28 @@ module HTS
|
|
|
418
389
|
end
|
|
419
390
|
|
|
420
391
|
def name2tid(name)
|
|
421
|
-
|
|
392
|
+
@native.name2tid(name)
|
|
422
393
|
end
|
|
423
394
|
|
|
424
395
|
def tid2name(tid)
|
|
425
|
-
|
|
396
|
+
@native.target_name(tid)
|
|
426
397
|
end
|
|
427
398
|
|
|
428
399
|
def add_lines(str)
|
|
429
|
-
|
|
400
|
+
@native.add_lines(str)
|
|
430
401
|
end
|
|
431
402
|
|
|
432
403
|
def add_line(*args)
|
|
433
404
|
type = args.shift
|
|
434
|
-
|
|
435
|
-
|
|
405
|
+
pairs = args.each_slice(2).map { |key, value| "#{key}:#{value}" }
|
|
406
|
+
@native.add_lines("@#{type}\t#{pairs.join("\t")}\n")
|
|
436
407
|
end
|
|
437
408
|
|
|
438
409
|
def initialize_copy(orig)
|
|
439
|
-
@
|
|
410
|
+
@native = orig.__send__(:native_handle).duplicate
|
|
440
411
|
end
|
|
412
|
+
|
|
413
|
+
def native_handle = @native
|
|
441
414
|
end
|
|
442
415
|
end
|
|
443
416
|
end
|