Class: HTS::Bcf
- Inherits:
-
Hts
show all
- Includes:
- Enumerable
- Defined in:
- lib/hts/bcf.rb,
lib/hts/bcf/info.rb,
lib/hts/bcf/errors.rb,
lib/hts/bcf/format.rb,
lib/hts/bcf/header.rb,
lib/hts/bcf/record.rb,
lib/hts/bcf/header_record.rb
Defined Under Namespace
Classes: Error, FieldError, Format, FormatDefinitionError, FormatError, FormatReadError, FormatTypeError, FormatUpdateError, Header, HeaderError, HeaderRecord, IndexError, Info, InfoDefinitionError, InfoError, InfoReadError, InfoTypeError, InfoUpdateError, InvalidBorrowedViewError, MissingIndexError, OpenError, QueryError, Record, RecordError, SubsetError, UnknownSampleError, UnsupportedFormatOperationError, UnsupportedInfoOperationError, WriteError
Instance Attribute Summary collapse
Class Method Summary
collapse
-
.build_index(file_name, index_name = nil, min_shift = 14, threads = 0, verbose = true) ⇒ Object
-
.filter_records(records, rid: nil, beg: nil, end_: nil, min_qual: nil, filter_id: nil) ⇒ Object
-
.open(*args, **keywords) ⇒ Object
Instance Method Summary
collapse
-
#<<(record) ⇒ Object
-
#build_index(index_name = nil, min_shift: 14, verbose: true) ⇒ Object
-
#close ⇒ Object
-
#closed? ⇒ Boolean
-
#collect_records ⇒ Object
-
#each(copy: false, &block) ⇒ Object
-
#each_format(key) ⇒ Object
-
#each_info(key) ⇒ Object
-
#file_format ⇒ Object
-
#file_format_version ⇒ Object
-
#format(key = nil) ⇒ Object
(also: #format_array)
-
#index_loaded? ⇒ Boolean
-
#info(key = nil) ⇒ Object
(also: #info_array)
-
#initialize(file_name, mode = "r", index: nil, threads: nil, build_index: false, subset: nil, samples: nil, unpack: :all) ⇒ Bcf
constructor
-
#load_index(index_name = nil) ⇒ Object
-
#nsamples ⇒ Object
-
#query(region, beg = nil, end_ = nil, copy: false, &block) ⇒ Object
-
#rewind ⇒ Object
-
#samples ⇒ Object
-
#seek(offset) ⇒ Object
-
#set_threads(count = nil) ⇒ Object
-
#tell ⇒ Object
-
#to_a ⇒ Object
Materialize independent, owning records rather than retaining the reused Record yielded by the allocation-conscious default iterator.
-
#try_load_index(index_name = nil) ⇒ Object
-
#write(record) ⇒ Object
-
#write_header(header) ⇒ Object
Constructor Details
#initialize(file_name, mode = "r", index: nil, threads: nil, build_index: false, subset: nil, samples: nil, unpack: :all) ⇒ Bcf
Returns a new instance of Bcf.
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
# File 'lib/hts/bcf.rb', line 51
def initialize(file_name, mode = "r", index: nil, threads: nil, build_index: false,
subset: nil, samples: nil, unpack: :all)
raise "HTS::Bcf.new() does not take block; Please use HTS::Bcf.open() instead" if block_given?
raise ArgumentError, "specify either samples: or subset:, not both" if samples && subset
subset = samples unless samples.nil?
@unpack = unpack.to_sym
@max_unpack = resolve_max_unpack(@unpack)
@file_name = file_name
@index_name = index
@mode = mode
@nthreads = threads
@index_load_attempted = false
@native = Native::BcfFileHandle.open(@file_name, mode)
set_threads(threads) if threads
if subset && mode.start_with?("w")
raise SubsetError,
"Sample subsetting is only available when reading BCF/VCF files"
end
if writing?
@auto_index_on_close = build_index
@index_name_on_close = index
return
end
@read_header = Header.new(@native.)
@header = subset ? @read_header.subset(subset) : @read_header
if build_index
build_index(index)
load_index(index)
elsif index
load_index(index)
end
@start_position = tell
rescue Errno::ENOENT
raise OpenError, "Failed to open #{@file_name}"
end
|
Instance Attribute Details
#file_name ⇒ Object
Returns the value of attribute file_name.
25
26
27
|
# File 'lib/hts/bcf.rb', line 25
def file_name
@file_name
end
|
Returns the value of attribute header.
25
26
27
|
# File 'lib/hts/bcf.rb', line 25
def
@header
end
|
#index_name ⇒ Object
Returns the value of attribute index_name.
25
26
27
|
# File 'lib/hts/bcf.rb', line 25
def index_name
@index_name
end
|
#mode ⇒ Object
Returns the value of attribute mode.
25
26
27
|
# File 'lib/hts/bcf.rb', line 25
def mode
@mode
end
|
#nthreads ⇒ Object
Returns the value of attribute nthreads.
25
26
27
|
# File 'lib/hts/bcf.rb', line 25
def nthreads
@nthreads
end
|
#unpack ⇒ Object
Returns the value of attribute unpack.
25
26
27
|
# File 'lib/hts/bcf.rb', line 25
def unpack
@unpack
end
|
Class Method Details
.build_index(file_name, index_name = nil, min_shift = 14, threads = 0, verbose = true) ⇒ Object
39
40
41
42
43
44
45
46
47
48
49
|
# File 'lib/hts/bcf.rb', line 39
def self.build_index(file_name, index_name = nil, min_shift = 14, threads = 0, verbose = true)
warn(index_name ? "Create index for #{file_name} to #{index_name}" : "Create index for #{file_name}") if verbose
case Native::BcfFileHandle.build_index(file_name, index_name, min_shift, threads)
when 0 then nil
when -1 then raise IndexError, "Indexing failed for #{file_name}"
when -2 then raise IndexError, "Opening #{file_name} failed while building the index"
when -3 then raise IndexError, "#{file_name} is not in an indexable format"
when -4 then raise IndexError, "Failed to create or save the index for #{file_name}"
else raise IndexError, "Unknown index build error for #{file_name}"
end
end
|
.filter_records(records, rid: nil, beg: nil, end_: nil, min_qual: nil, filter_id: nil) ⇒ Object
16
17
18
19
20
21
22
23
|
# File 'lib/hts/bcf.rb', line 16
def self.filter_records(records, rid: nil, beg: nil, end_: nil, min_qual: nil, filter_id: nil)
Array(records).select do |record|
(rid.nil? || record.rid == Integer(rid)) &&
(beg.nil? || record.endpos > Integer(beg)) && (end_.nil? || record.pos < Integer(end_)) &&
(min_qual.nil? || (!record.qual.nan? && record.qual >= Float(min_qual))) &&
(filter_id.nil? || record.filter_id?(filter_id))
end
end
|
.open(*args, **keywords) ⇒ Object
27
28
29
30
31
32
33
34
35
36
37
|
# File 'lib/hts/bcf.rb', line 27
def self.open(*args, **keywords)
file = new(*args, **keywords)
return file unless block_given?
begin
result = yield file
ensure
file.close
end
result
end
|
Instance Method Details
#<<(record) ⇒ Object
176
177
178
179
|
# File 'lib/hts/bcf.rb', line 176
def <<(record)
write(record)
self
end
|
#build_index(index_name = nil, min_shift: 14, verbose: true) ⇒ Object
89
90
91
92
93
94
95
|
# File 'lib/hts/bcf.rb', line 89
def build_index(index_name = nil, min_shift: 14, verbose: true)
check_closed
self.class.build_index(@file_name, index_name, min_shift, @nthreads || 0, verbose)
@index_name = index_name
@index_load_attempted = false
self
end
|
#close ⇒ Object
115
116
117
118
119
120
121
122
123
124
125
126
|
# File 'lib/hts/bcf.rb', line 115
def close
was_closed = closed?
result = @native&.close
raise WriteError, "Failed to close #{@file_name}: buffered output may be incomplete" if writing? && result&.negative?
if writing? && @auto_index_on_close && !was_closed
@auto_index_on_close = false
self.class.build_index(@file_name, @index_name_on_close, 14, @nthreads || 0, false)
end
nil
end
|
#closed? ⇒ Boolean
127
|
# File 'lib/hts/bcf.rb', line 127
def closed? = @native.nil? || @native.closed?
|
#collect_records ⇒ Object
218
|
# File 'lib/hts/bcf.rb', line 218
def collect_records = each(copy: true).to_a
|
#each(copy: false, &block) ⇒ Object
247
|
# File 'lib/hts/bcf.rb', line 247
def each(copy: false, &block) = copy ? each_record_copy(&block) : each_record_reuse(&block)
|
240
241
242
243
244
245
|
# File 'lib/hts/bcf.rb', line 240
def each_format(key)
return to_enum(__method__, key) unless block_given?
each { |record| yield record.format(key) }
self
end
|
#each_info(key) ⇒ Object
233
234
235
236
237
238
|
# File 'lib/hts/bcf.rb', line 233
def each_info(key)
return to_enum(__method__, key) unless block_given?
each { |record| yield record.info(key) }
self
end
|
128
|
# File 'lib/hts/bcf.rb', line 128
def file_format = @native.file_format
|
129
|
# File 'lib/hts/bcf.rb', line 129
def file_format_version = @native.file_format_version
|
209
210
211
212
213
214
215
|
# File 'lib/hts/bcf.rb', line 209
def format(key = nil)
check_closed
raise NotImplementedError unless key
position = tell
map { |record| record.format(key) }.tap { seek(position) if position }
end
|
#index_loaded? ⇒ Boolean
110
111
112
113
|
# File 'lib/hts/bcf.rb', line 110
def index_loaded?
check_closed
@native.index_loaded?
end
|
#info(key = nil) ⇒ Object
Also known as:
info_array
200
201
202
203
204
205
206
|
# File 'lib/hts/bcf.rb', line 200
def info(key = nil)
check_closed
raise NotImplementedError unless key
position = tell
map { |record| record.info(key) }.tap { seek(position) if position }
end
|
#load_index(index_name = nil) ⇒ Object
97
98
99
100
101
|
# File 'lib/hts/bcf.rb', line 97
def load_index(index_name = nil)
return self if try_load_index(index_name)
raise MissingIndexError, "Failed to load index #{index_name || "for #{@file_name}"}"
end
|
#nsamples ⇒ Object
181
182
183
184
|
# File 'lib/hts/bcf.rb', line 181
def nsamples
check_closed
.nsamples
end
|
#query(region, beg = nil, end_ = nil, copy: false, &block) ⇒ Object
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
|
# File 'lib/hts/bcf.rb', line 249
def query(region, beg = nil, end_ = nil, copy: false, &block)
check_closed
unless ensure_index_loaded
raise MissingIndexError, "Index file is required to call the query method for #{@file_name}"
end
case region
when Array
raise ArgumentError, "beg and end must not be specified when region is an Array" unless beg.nil? && end_.nil?
return to_enum(__method__, region, copy:) unless block
region.each { |item| query(item, copy:, &block) }
self
else
if beg && end_
iterate_query(@native.query_interval(, .name2id(region), beg, end_), copy, region,
&block)
elsif beg.nil? && end_.nil?
iterate_query(@native.query_region(, region), copy, region, &block)
else
raise ArgumentError, "beg and end must be specified together"
end
end
end
|
#rewind ⇒ Object
133
134
135
136
137
138
139
140
|
# File 'lib/hts/bcf.rb', line 133
def rewind
raise "Cannot rewind: no start position" unless @start_position
result = seek(@start_position)
raise "Failed to rewind: #{result}" if result.negative?
tell
end
|
#samples ⇒ Object
186
187
188
189
|
# File 'lib/hts/bcf.rb', line 186
def samples
check_closed
.samples
end
|
#seek(offset) ⇒ Object
130
|
# File 'lib/hts/bcf.rb', line 130
def seek(offset) = @native.seek(offset)
|
#set_threads(count = nil) ⇒ Object
142
143
144
145
146
147
148
149
150
151
152
153
|
# File 'lib/hts/bcf.rb', line 142
def set_threads(count = nil)
if count.nil?
require "etc"
count = [Etc.nprocessors - 1, 1].max
end
raise TypeError unless count.is_a?(Integer)
raise ArgumentError, "Number of threads must be positive" if count < 1
raise "Failed to set number of threads: #{count}" if @native.set_threads(count).negative?
@nthreads = count
self
end
|
#tell ⇒ Object
131
|
# File 'lib/hts/bcf.rb', line 131
def tell = @native.tell
|
#to_a ⇒ Object
Materialize independent, owning records rather than retaining the
reused Record yielded by the allocation-conscious default iterator.
222
|
# File 'lib/hts/bcf.rb', line 222
def to_a = collect_records
|
#try_load_index(index_name = nil) ⇒ Object
103
104
105
106
107
108
|
# File 'lib/hts/bcf.rb', line 103
def try_load_index(index_name = nil)
check_closed
@index_name = index_name
@index_load_attempted = true
@native.load_index(index_name)
end
|
#write(record) ⇒ Object
168
169
170
171
172
173
174
|
# File 'lib/hts/bcf.rb', line 168
def write(record)
check_closed
result = @native.write(.__send__(:native_handle), record.__send__(:native_handle))
raise "Failed to write record" if result.negative?
nil
end
|
155
156
157
158
159
160
161
162
|
# File 'lib/hts/bcf.rb', line 155
def ()
check_closed
@header = .dup
result = @native.(.__send__(:native_handle))
raise HeaderError, "Failed to write BCF header" if result.negative?
nil
end
|