htslib 0.0.4 → 0.0.5
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/lib/hts/bam/record.rb +19 -0
- data/lib/hts/bam.rb +12 -12
- data/lib/hts/bcf/info.rb +58 -5
- data/lib/hts/bcf/record.rb +3 -9
- data/lib/hts/bcf.rb +8 -10
- data/lib/hts/faidx.rb +13 -4
- data/lib/hts/ffi_ext/struct.rb +1 -1
- data/lib/hts/libhts/constants.rb +11 -3
- data/lib/hts/libhts/vcf.rb +27 -0
- data/lib/hts/tabix.rb +13 -5
- data/lib/hts/version.rb +1 -1
- metadata +3 -4
- data/lib/hts/utils/open_method.rb +0 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3eb6fbb228a9fa0642c55cdfa39d5189b311df191725954ae46b8dda135dc8c7
|
4
|
+
data.tar.gz: c90ad39aa4919cefa56e534a706bf9659bba9c6ad69eb374491092ce16ae93f6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 392ea7c6acb5b86e9e1c1a29f066049c54954edfd277be30541aee433a7349f9d74df09e663ec0269f30d6b87ff47d66a4a668470d3aa536e25a2058cf963546
|
7
|
+
data.tar.gz: 9cc235f8876b8fd4339593eb84a0f2cb8b605b9c82b624cd0f97691b4109a672f55ae90447bba17fb5efcb8257279ad8c2d87234bca390b1624c7aa8f9a7014e
|
data/lib/hts/bam/record.rb
CHANGED
@@ -21,6 +21,8 @@ module HTS
|
|
21
21
|
@bam1.to_ptr
|
22
22
|
end
|
23
23
|
|
24
|
+
attr_reader :header
|
25
|
+
|
24
26
|
# def initialize_copy
|
25
27
|
# super
|
26
28
|
# end
|
@@ -161,6 +163,23 @@ module HTS
|
|
161
163
|
Flag.new(@bam1[:core][:flag])
|
162
164
|
end
|
163
165
|
|
166
|
+
def tag(str)
|
167
|
+
aux = LibHTS.bam_aux_get(@bam1, str)
|
168
|
+
return nil if aux.null?
|
169
|
+
|
170
|
+
t = aux.read_string(1)
|
171
|
+
case t
|
172
|
+
when "i", "I", "c", "C", "s", "S"
|
173
|
+
LibHTS.bam_aux2i(aux)
|
174
|
+
when "f", "d"
|
175
|
+
LibHTS.bam_aux2f(aux)
|
176
|
+
when "Z", "H"
|
177
|
+
LibHTS.bam_aux2Z(aux)
|
178
|
+
when "A"
|
179
|
+
LibHTS.bam_aux2A(aux)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
164
183
|
def to_s
|
165
184
|
kstr = LibHTS::KString.new
|
166
185
|
raise "Failed to format bam record" if LibHTS.sam_format1(@header.struct, @bam1, kstr) == -1
|
data/lib/hts/bam.rb
CHANGED
@@ -7,12 +7,10 @@ require_relative "bam/header"
|
|
7
7
|
require_relative "bam/cigar"
|
8
8
|
require_relative "bam/flag"
|
9
9
|
require_relative "bam/record"
|
10
|
-
require_relative "utils/open_method"
|
11
10
|
|
12
11
|
module HTS
|
13
12
|
class Bam
|
14
13
|
include Enumerable
|
15
|
-
extend Utils::OpenMethod
|
16
14
|
|
17
15
|
attr_reader :file_path, :mode, :header
|
18
16
|
# HtfFile is FFI::BitStruct
|
@@ -35,9 +33,6 @@ module HTS
|
|
35
33
|
@htf_file = LibHTS.hts_open(file_path, mode)
|
36
34
|
@header = Bam::Header.new(LibHTS.sam_hdr_read(htf_file))
|
37
35
|
|
38
|
-
# FIXME: should be defined here?
|
39
|
-
@bam1 = LibHTS.bam_init1
|
40
|
-
|
41
36
|
# read
|
42
37
|
if mode[0] == "r"
|
43
38
|
# load index
|
@@ -87,24 +82,29 @@ module HTS
|
|
87
82
|
# LibHTS.bgzf_flush(@htf_file.fp.bgzf)
|
88
83
|
end
|
89
84
|
|
90
|
-
def each
|
85
|
+
def each
|
91
86
|
# Each does not always start at the beginning of the file.
|
92
87
|
# This is the common behavior of IO objects in Ruby.
|
93
88
|
# This may change in the future.
|
94
|
-
|
95
|
-
|
96
|
-
|
89
|
+
return to_enum(__method__) unless block_given?
|
90
|
+
|
91
|
+
while LibHTS.sam_read1(htf_file, header, bam1 = LibHTS.bam_init1) > 0
|
92
|
+
record = Record.new(bam1, header)
|
93
|
+
yield record
|
97
94
|
end
|
95
|
+
self
|
98
96
|
end
|
99
97
|
|
100
98
|
# query [WIP]
|
101
99
|
def query(region)
|
102
100
|
qiter = LibHTS.sam_itr_querys(@idx, header, region)
|
103
101
|
begin
|
104
|
-
|
102
|
+
bam1 = LibHTS.bam_init1
|
103
|
+
slen = LibHTS.sam_itr_next(htf_file, qiter, bam1)
|
105
104
|
while slen > 0
|
106
|
-
yield Record.new(
|
107
|
-
|
105
|
+
yield Record.new(bam1, header)
|
106
|
+
bam1 = LibHTS.bam_init1
|
107
|
+
slen = LibHTS.sam_itr_next(htf_file, qiter, bam1)
|
108
108
|
end
|
109
109
|
ensure
|
110
110
|
LibHTS.hts_itr_destroy(qiter)
|
data/lib/hts/bcf/info.rb
CHANGED
@@ -7,6 +7,7 @@ module HTS
|
|
7
7
|
@record = record
|
8
8
|
end
|
9
9
|
|
10
|
+
# @note Specify the type. If you don't specify a type, it will still work, but it will be slower.
|
10
11
|
def get(key, type = nil)
|
11
12
|
n = FFI::MemoryPointer.new(:int)
|
12
13
|
p1 = @record.p1
|
@@ -20,19 +21,71 @@ module HTS
|
|
20
21
|
p1.read_pointer
|
21
22
|
end
|
22
23
|
|
23
|
-
|
24
|
+
type ||= info_type_to_string(get_info_type(key))
|
25
|
+
|
26
|
+
case type&.to_sym
|
24
27
|
when :int, :int32
|
25
28
|
info_values.call(LibHTS::BCF_HT_INT)
|
26
29
|
.read_array_of_int32(n.read_int)
|
27
30
|
when :float, :real
|
28
31
|
info_values.call(LibHTS::BCF_HT_REAL)
|
29
32
|
.read_array_of_float(n.read_int)
|
30
|
-
when :flag
|
31
|
-
|
32
|
-
|
33
|
+
when :flag, :bool
|
34
|
+
case ret = LibHTS.bcf_get_info_flag(h, r, key, p1, n)
|
35
|
+
when 1 then true
|
36
|
+
when 0 then false
|
37
|
+
when -1 then nil
|
38
|
+
else
|
39
|
+
raise "Unknown return value from bcf_get_info_flag: #{ret}"
|
40
|
+
end
|
33
41
|
when :string, :str
|
34
42
|
info_values.call(LibHTS::BCF_HT_STR)
|
35
|
-
.
|
43
|
+
.read_string
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def fields
|
48
|
+
n_info = @record.struct[:n_info]
|
49
|
+
Array.new(n_info) do |i|
|
50
|
+
fld = LibHTS::BcfInfo.new(
|
51
|
+
@record.struct[:d][:info] +
|
52
|
+
i * LibHTS::BcfInfo.size
|
53
|
+
)
|
54
|
+
{
|
55
|
+
name: LibHTS.bcf_hdr_int2id(
|
56
|
+
@record.bcf.header.struct, LibHTS::BCF_DT_ID, fld[:key]
|
57
|
+
),
|
58
|
+
n: LibHTS.bcf_hdr_id2number(
|
59
|
+
@record.bcf.header.struct, LibHTS::BCF_HL_INFO, fld[:key]
|
60
|
+
),
|
61
|
+
vtype: fld[:type], i: fld[:key]
|
62
|
+
}
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def get_info_type(key)
|
69
|
+
@record.struct[:n_info].times do |i|
|
70
|
+
fld = LibHTS::BcfInfo.new(
|
71
|
+
@record.struct[:d][:info] +
|
72
|
+
i * LibHTS::BcfInfo.size
|
73
|
+
)
|
74
|
+
id = LibHTS.bcf_hdr_int2id(
|
75
|
+
@record.bcf.header.struct, LibHTS::BCF_DT_ID, fld[:key]
|
76
|
+
)
|
77
|
+
return fld[:type] if id == key
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def info_type_to_string(t)
|
82
|
+
case t
|
83
|
+
when 0 then :flag
|
84
|
+
when 1, 2, 3, 4 then :int
|
85
|
+
when 5 then :float
|
86
|
+
when 7 then :string
|
87
|
+
else
|
88
|
+
raise "Unknown info type: #{t}"
|
36
89
|
end
|
37
90
|
end
|
38
91
|
end
|
data/lib/hts/bcf/record.rb
CHANGED
@@ -29,12 +29,7 @@ module HTS
|
|
29
29
|
hdr = @bcf.header.struct
|
30
30
|
rid = @bcf1[:rid]
|
31
31
|
|
32
|
-
|
33
|
-
|
34
|
-
LibHTS::BcfIdpair.new(
|
35
|
-
hdr[:id][LibHTS::BCF_DT_CTG].to_ptr +
|
36
|
-
LibHTS::BcfIdpair.size * rid # offset
|
37
|
-
)[:key]
|
32
|
+
LibHTS.bcf_hdr_id2name(hdr, rid)
|
38
33
|
end
|
39
34
|
|
40
35
|
def pos
|
@@ -106,9 +101,8 @@ module HTS
|
|
106
101
|
|
107
102
|
def to_s
|
108
103
|
ksr = LibHTS::KString.new
|
109
|
-
if LibHTS.vcf_format(@bcf.header.struct, @bcf1, ksr) == -1
|
110
|
-
|
111
|
-
end
|
104
|
+
raise "Failed to format record" if LibHTS.vcf_format(@bcf.header.struct, @bcf1, ksr) == -1
|
105
|
+
|
112
106
|
ksr[:s]
|
113
107
|
end
|
114
108
|
end
|
data/lib/hts/bcf.rb
CHANGED
@@ -4,15 +4,13 @@
|
|
4
4
|
# https://github.com/quinlan-lab/hts-python
|
5
5
|
|
6
6
|
require_relative "bcf/header"
|
7
|
-
require_relative "bcf/record"
|
8
7
|
require_relative "bcf/info"
|
9
8
|
require_relative "bcf/format"
|
10
|
-
require_relative "
|
9
|
+
require_relative "bcf/record"
|
11
10
|
|
12
11
|
module HTS
|
13
12
|
class Bcf
|
14
13
|
include Enumerable
|
15
|
-
extend Utils::OpenMethod
|
16
14
|
|
17
15
|
attr_reader :file_path, :mode, :header
|
18
16
|
# HtfFile is FFI::BitStruct
|
@@ -35,9 +33,6 @@ module HTS
|
|
35
33
|
@htf_file = LibHTS.hts_open(file_path, mode)
|
36
34
|
@header = Bcf::Header.new(LibHTS.bcf_hdr_read(htf_file))
|
37
35
|
|
38
|
-
# FIXME: should be defined here?
|
39
|
-
@bcf1 = LibHTS.bcf_init
|
40
|
-
|
41
36
|
# IO like API
|
42
37
|
if block_given?
|
43
38
|
begin
|
@@ -61,11 +56,14 @@ module HTS
|
|
61
56
|
LibHTS.hts_close(htf_file)
|
62
57
|
end
|
63
58
|
|
64
|
-
def each
|
65
|
-
|
66
|
-
|
67
|
-
|
59
|
+
def each
|
60
|
+
return to_enum(__method__) unless block_given?
|
61
|
+
|
62
|
+
while LibHTS.bcf_read(htf_file, header, bcf1 = LibHTS.bcf_init) != -1
|
63
|
+
record = Record.new(bcf1, self)
|
64
|
+
yield record
|
68
65
|
end
|
66
|
+
self
|
69
67
|
end
|
70
68
|
|
71
69
|
def n_samples
|
data/lib/hts/faidx.rb
CHANGED
@@ -3,17 +3,26 @@
|
|
3
3
|
# Based on hts-python
|
4
4
|
# https://github.com/quinlan-lab/hts-python
|
5
5
|
|
6
|
-
require_relative "utils/open_method"
|
7
|
-
|
8
6
|
module HTS
|
9
7
|
class Faidx
|
10
|
-
extend Utils::OpenMethod
|
11
|
-
|
12
8
|
attr_reader :file_path
|
13
9
|
|
10
|
+
class << self
|
11
|
+
alias open new
|
12
|
+
end
|
13
|
+
|
14
14
|
def initialize(file_path)
|
15
15
|
@file_path = File.expand_path(file_path)
|
16
16
|
@fai = LibHTS.fai_load(file_path)
|
17
|
+
|
18
|
+
# IO like API
|
19
|
+
if block_given?
|
20
|
+
begin
|
21
|
+
yield self
|
22
|
+
ensure
|
23
|
+
close
|
24
|
+
end
|
25
|
+
end
|
17
26
|
end
|
18
27
|
|
19
28
|
def close
|
data/lib/hts/ffi_ext/struct.rb
CHANGED
data/lib/hts/libhts/constants.rb
CHANGED
@@ -289,7 +289,7 @@ module HTS
|
|
289
289
|
:isize, :hts_pos_t
|
290
290
|
end
|
291
291
|
|
292
|
-
class Bam1 < FFI::
|
292
|
+
class Bam1 < FFI::ManagedStruct
|
293
293
|
layout \
|
294
294
|
:core, Bam1Core,
|
295
295
|
:id, :uint64,
|
@@ -301,6 +301,10 @@ module HTS
|
|
301
301
|
# bit_fields :_mempolicy,
|
302
302
|
# :mempolicy, 2,
|
303
303
|
# :_reserved, 30
|
304
|
+
|
305
|
+
def self.release(ptr)
|
306
|
+
LibHTS.bam_destroy1(ptr) unless ptr.null?
|
307
|
+
end
|
304
308
|
end
|
305
309
|
|
306
310
|
typedef :pointer, :bam_plp
|
@@ -457,7 +461,7 @@ module HTS
|
|
457
461
|
:id, :string,
|
458
462
|
:als, :pointer, # (\\0-separated string)
|
459
463
|
:allele, :pointer,
|
460
|
-
:info, BcfInfo.ptr,
|
464
|
+
:info, :pointer, # BcfInfo.ptr,
|
461
465
|
:fmt, BcfFmt.ptr,
|
462
466
|
:var, BcfVariant.ptr,
|
463
467
|
:n_var, :int,
|
@@ -466,7 +470,7 @@ module HTS
|
|
466
470
|
:indiv_dirty, :int
|
467
471
|
end
|
468
472
|
|
469
|
-
class Bcf1 < FFI::
|
473
|
+
class Bcf1 < FFI::ManagedBitStruct
|
470
474
|
layout \
|
471
475
|
:pos, :hts_pos_t,
|
472
476
|
:rlen, :hts_pos_t,
|
@@ -489,6 +493,10 @@ module HTS
|
|
489
493
|
bit_fields :_n_fmt_sample,
|
490
494
|
:n_fmt, 8,
|
491
495
|
:n_sample, 24
|
496
|
+
|
497
|
+
def self.release(ptr)
|
498
|
+
LibHTS.bcf_destroy(ptr) unless ptr.null?
|
499
|
+
end
|
492
500
|
end
|
493
501
|
end
|
494
502
|
end
|
data/lib/hts/libhts/vcf.rb
CHANGED
@@ -167,6 +167,33 @@ module HTS
|
|
167
167
|
LibHTS::BcfIdpair.size * int_id # offsets
|
168
168
|
)[:key]
|
169
169
|
end
|
170
|
+
|
171
|
+
def bcf_hdr_name2id(hdr, id)
|
172
|
+
bcf_hdr_id2int(hdr, BCF_DT_CTG, id)
|
173
|
+
end
|
174
|
+
|
175
|
+
def bcf_hdr_id2name(hdr, rid)
|
176
|
+
return nil if hdr.null? || rid < 0 || rid >= hdr[:n][LibHTS::BCF_DT_CTG]
|
177
|
+
|
178
|
+
LibHTS::BcfIdpair.new(
|
179
|
+
hdr[:id][LibHTS::BCF_DT_CTG].to_ptr +
|
180
|
+
LibHTS::BcfIdpair.size * rid # offset
|
181
|
+
)[:key]
|
182
|
+
end
|
183
|
+
|
184
|
+
def bcf_hdr_id2length(hdr, type, int_id)
|
185
|
+
LibHTS::BcfIdpair.new(
|
186
|
+
hdr[:id][LibHTS::BCF_DT_ID].to_ptr +
|
187
|
+
LibHTS::BcfIdpair.size * int_id # offset
|
188
|
+
)[:val][:info][type] >> 8 & 0xf
|
189
|
+
end
|
190
|
+
|
191
|
+
def bcf_hdr_id2number(hdr, type, int_id)
|
192
|
+
LibHTS::BcfIdpair.new(
|
193
|
+
hdr[:id][LibHTS::BCF_DT_ID].to_ptr +
|
194
|
+
LibHTS::BcfIdpair.size * int_id # offset
|
195
|
+
)[:val][:info][type] >> 12
|
196
|
+
end
|
170
197
|
end
|
171
198
|
|
172
199
|
# constants
|
data/lib/hts/tabix.rb
CHANGED
@@ -3,13 +3,21 @@
|
|
3
3
|
# Based on hts-python
|
4
4
|
# https://github.com/quinlan-lab/hts-python
|
5
5
|
|
6
|
-
require_relative "utils/open_method"
|
7
|
-
|
8
6
|
module HTS
|
9
7
|
class Tabix
|
10
|
-
|
11
|
-
|
12
|
-
|
8
|
+
class << self
|
9
|
+
alias open new
|
10
|
+
end
|
11
|
+
def initialize
|
12
|
+
# IO like API
|
13
|
+
if block_given?
|
14
|
+
begin
|
15
|
+
yield self
|
16
|
+
ensure
|
17
|
+
close
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
13
21
|
|
14
22
|
def build; end
|
15
23
|
|
data/lib/hts/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: htslib
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- kojix2
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-12-
|
11
|
+
date: 2021-12-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ffi
|
@@ -155,7 +155,6 @@ files:
|
|
155
155
|
- lib/hts/libhts/tbx.rb
|
156
156
|
- lib/hts/libhts/vcf.rb
|
157
157
|
- lib/hts/tabix.rb
|
158
|
-
- lib/hts/utils/open_method.rb
|
159
158
|
- lib/hts/version.rb
|
160
159
|
- lib/htslib.rb
|
161
160
|
homepage: https://github.com/kojix2/ruby-htslib
|
@@ -177,7 +176,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
177
176
|
- !ruby/object:Gem::Version
|
178
177
|
version: '0'
|
179
178
|
requirements: []
|
180
|
-
rubygems_version: 3.
|
179
|
+
rubygems_version: 3.3.3
|
181
180
|
signing_key:
|
182
181
|
specification_version: 4
|
183
182
|
summary: HTSlib bindings for Ruby
|