htslib 0.4.1 → 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.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +79 -49
  3. data/TUTORIAL.md +9 -20
  4. data/ext/htslib_native/extconf.rb +41 -0
  5. data/ext/htslib_native/htslib_native.h +11 -0
  6. data/ext/htslib_native/htslib_native_ext.c +48 -0
  7. data/ext/htslib_native/native_bam.c +1108 -0
  8. data/ext/htslib_native/native_bcf.c +369 -0
  9. data/ext/htslib_native/native_faidx.c +155 -0
  10. data/ext/htslib_native/native_tabix.c +246 -0
  11. data/lib/hts/bam/auxi.rb +87 -342
  12. data/lib/hts/bam/base_mod.rb +37 -73
  13. data/lib/hts/bam/cigar.rb +9 -55
  14. data/lib/hts/bam/flag.rb +19 -27
  15. data/lib/hts/bam/header.rb +29 -56
  16. data/lib/hts/bam/mpileup.rb +158 -132
  17. data/lib/hts/bam/pileup.rb +120 -145
  18. data/lib/hts/bam/record.rb +233 -270
  19. data/lib/hts/bam.rb +102 -42
  20. data/lib/hts/bcf/errors.rb +1 -0
  21. data/lib/hts/bcf/format.rb +278 -379
  22. data/lib/hts/bcf/header.rb +38 -123
  23. data/lib/hts/bcf/header_record.rb +9 -35
  24. data/lib/hts/bcf/info.rb +72 -320
  25. data/lib/hts/bcf/record.rb +61 -102
  26. data/lib/hts/bcf.rb +149 -323
  27. data/lib/hts/faidx.rb +28 -87
  28. data/lib/hts/hts.rb +6 -94
  29. data/lib/hts/native.rb +13 -0
  30. data/lib/hts/tabix.rb +93 -48
  31. data/lib/hts/version.rb +1 -1
  32. data/lib/htslib.rb +6 -52
  33. metadata +13 -64
  34. data/lib/hts/ffi_ext/README.md +0 -8
  35. data/lib/hts/ffi_ext/pointer.rb +0 -18
  36. data/lib/hts/ffi_ext/struct.rb +0 -45
  37. data/lib/hts/libhts/bgzf.rb +0 -199
  38. data/lib/hts/libhts/constants.rb +0 -658
  39. data/lib/hts/libhts/cram.rb +0 -471
  40. data/lib/hts/libhts/fai.rb +0 -146
  41. data/lib/hts/libhts/hfile.rb +0 -109
  42. data/lib/hts/libhts/hts.rb +0 -477
  43. data/lib/hts/libhts/kfunc.rb +0 -38
  44. data/lib/hts/libhts/sam.rb +0 -760
  45. data/lib/hts/libhts/sam_funcs.rb +0 -155
  46. data/lib/hts/libhts/tbx.rb +0 -79
  47. data/lib/hts/libhts/tbx_funcs.rb +0 -32
  48. data/lib/hts/libhts/thread_pool.rb +0 -139
  49. data/lib/hts/libhts/vcf.rb +0 -557
  50. data/lib/hts/libhts/vcf_funcs.rb +0 -353
  51. data/lib/hts/libhts.rb +0 -47
@@ -1,658 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module HTS
4
- # Module for working with C HTSlib.
5
- module LibHTS
6
- typedef :int64, :hts_pos_t
7
-
8
- # kstring
9
-
10
- class KString < FFI::Struct
11
- layout \
12
- :l, :size_t,
13
- :m, :size_t,
14
- :s, :string
15
-
16
- def buffer_ptr
17
- to_ptr.get_pointer(self.class.offset_of(:s))
18
- end
19
-
20
- def read_string_copy
21
- ptr = buffer_ptr
22
- return "" if ptr.null?
23
-
24
- ptr.read_string(self[:l])
25
- end
26
-
27
- def free_buffer
28
- ptr = buffer_ptr
29
- return if ptr.null?
30
-
31
- LibHTS.hts_free(ptr)
32
- to_ptr.put_pointer(self.class.offset_of(:s), FFI::Pointer::NULL)
33
- self[:l] = 0
34
- self[:m] = 0
35
- end
36
- end
37
-
38
- class KSeq < FFI::Struct
39
- layout \
40
- :name, KString,
41
- :comment, KString,
42
- :seq, KString,
43
- :qual, KString,
44
- :last_char, :int,
45
- :f, :pointer # kstream_t
46
- end
47
-
48
- # HFile
49
-
50
- class HFile < FFI::BitStruct
51
- layout \
52
- :buffer, :string,
53
- :begin, :string,
54
- :end, :string,
55
- :limit, :string,
56
- :backend, :pointer,
57
- :offset, :size_t,
58
- :_flags, :uint,
59
- :has_errno, :int
60
-
61
- bit_fields :_flags,
62
- :at_eof, 1,
63
- :mobile, 1,
64
- :readonly, 1
65
- end
66
-
67
- # BGZF
68
- class BGZF < FFI::BitStruct
69
- layout \
70
- :_flags, :uint, # bit_fields
71
- :cache_size, :int,
72
- :block_length, :int,
73
- :block_clength, :int,
74
- :block_offset, :int,
75
- :block_address, :int64,
76
- :uncompressed_address, :int64,
77
- :uncompressed_block, :pointer,
78
- :compressed_block, :pointer,
79
- :cache, :pointer,
80
- :fp, HFile.ptr,
81
- :mt, :pointer,
82
- :idx, :pointer,
83
- :idx_build_otf, :int,
84
- :gz_stream, :pointer,
85
- :seeked, :int64
86
-
87
- bit_fields :_flags,
88
- :errcode, 16,
89
- :_reserved, 1,
90
- :is_write, 1,
91
- :no_eof_block, 1,
92
- :is_be, 1,
93
- :compress_level, 9,
94
- :last_block_eof, 1,
95
- :is_compressed, 1,
96
- :is_gzip, 1
97
- end
98
-
99
- # hts
100
- HtsLogLevel = enum(
101
- :off, # All logging disabled.
102
- :error, # Logging of errors only.
103
- :warning, 3, # Logging of errors and warnings.
104
- :info, # Logging of errors, warnings, and normal but significant events.
105
- :debug, # Logging of all except the most detailed debug events.
106
- :trace # All logging enabled.
107
- )
108
-
109
- HtsFormatCategory = enum(
110
- :unknown_category,
111
- :sequence_data, # Sequence data -- SAM, BAM, CRAM, etc
112
- :variant_data, # Variant calling data -- VCF, BCF, etc
113
- :index_file, # Index file associated with some data file
114
- :region_list, # Coordinate intervals or regions -- BED, etc
115
- :category_maximum, 32_767
116
- )
117
-
118
- HtsExactFormat = enum(
119
- :unknown_format,
120
- :binary_format, :text_format,
121
- :sam, :bam, :bai, :cram, :crai, :vcf, :bcf, :csi, :gzi, :tbi, :bed,
122
- :htsget, :json,
123
- :empty_format,
124
- :fasta_format, :fastq_format, :fai_format, :fqi_format,
125
- :hts_crypt4gh_format,
126
- :format_maximum, 32_767
127
- )
128
-
129
- HtsCompression = enum(
130
- :no_compression, :gzip, :bgzf, :custom,
131
- :compression_maximum, 32_767
132
- )
133
-
134
- HtsFmtOption = enum(
135
- :CRAM_OPT_DECODE_MD,
136
- :CRAM_OPT_PREFIX,
137
- :CRAM_OPT_VERBOSITY, # obsolete, use hts_set_log_level() instead
138
- :CRAM_OPT_SEQS_PER_SLICE,
139
- :CRAM_OPT_SLICES_PER_CONTAINER,
140
- :CRAM_OPT_RANGE,
141
- :CRAM_OPT_VERSION, # rename to :CRAM_version?
142
- :CRAM_OPT_EMBED_REF,
143
- :CRAM_OPT_IGNORE_MD5,
144
- :CRAM_OPT_REFERENCE, # make general
145
- :CRAM_OPT_MULTI_SEQ_PER_SLICE,
146
- :CRAM_OPT_NO_REF,
147
- :CRAM_OPT_USE_BZIP2,
148
- :CRAM_OPT_SHARED_REF,
149
- :CRAM_OPT_NTHREADS, # deprecated, use HTS_OPT_NTHREADS
150
- :CRAM_OPT_THREAD_POOL, # make general
151
- :CRAM_OPT_USE_LZMA,
152
- :CRAM_OPT_USE_RANS,
153
- :CRAM_OPT_REQUIRED_FIELDS,
154
- :CRAM_OPT_LOSSY_NAMES,
155
- :CRAM_OPT_BASES_PER_SLICE,
156
- :CRAM_OPT_STORE_MD,
157
- :CRAM_OPT_STORE_NM,
158
- :CRAM_OPT_RANGE_NOSEEK, # CRAM_OPT_RANGE minus the seek
159
- # General purpose
160
- :HTS_OPT_COMPRESSION_LEVEL, 100,
161
- :HTS_OPT_NTHREADS,
162
- :HTS_OPT_THREAD_POOL,
163
- :HTS_OPT_CACHE_SIZE,
164
- :HTS_OPT_BLOCK_SIZE
165
- )
166
-
167
- class HtsFormat < FFI::Struct
168
- layout \
169
- :category, HtsFormatCategory,
170
- :format, HtsExactFormat,
171
- :version,
172
- struct_layout(
173
- :major, :short,
174
- :minor, :short
175
- ),
176
- :compression, HtsCompression,
177
- :compression_level, :short,
178
- :specific, :pointer
179
- end
180
-
181
- class HtsIdx < FFI::Struct
182
- layout \
183
- :fmt, :int,
184
- :min_shift, :int,
185
- :n_lvls, :int,
186
- :n_bins, :int,
187
- :l_meta, :uint32,
188
- :n, :int32,
189
- :m, :int32,
190
- :n_no_coor, :uint64,
191
- :bidx, :pointer,
192
- :lidx, :pointer,
193
- :meta, :pointer,
194
- :tbi_n, :int,
195
- :last_tbi_tid, :int,
196
- :z,
197
- union_layout(
198
- :last_bin, :uint32,
199
- :save_bin, :uint32,
200
- :last_coor, :pointer,
201
- :last_tid, :int,
202
- :save_tid, :int,
203
- :finished, :int,
204
- :last_off, :uint64,
205
- :save_off, :uint64,
206
- :off_beg, :uint64,
207
- :off_end, :uint64,
208
- :n_mapped, :uint64,
209
- :n_unmapped, :uint64
210
- )
211
-
212
- # def self.release(ptr)
213
- # LibHTS.hts_idx_destroy(ptr) unless ptr.null?
214
- # end
215
- end
216
-
217
- class HtsReglist < FFI::Struct
218
- layout \
219
- :reg, :string,
220
- :intervals, :pointer, # hts_pair_pos_t
221
- :tid, :int,
222
- :count, :uint32,
223
- :min_beg, :hts_pos_t,
224
- :max_end, :hts_pos_t
225
- end
226
-
227
- # HtsFile
228
- class SamHdr < FFI::ManagedStruct
229
- layout \
230
- :n_targets, :int32,
231
- :ignore_sam_err, :int32,
232
- :l_text, :size_t,
233
- :target_len, :pointer,
234
- :cigar_tab, :pointer,
235
- :target_name, :pointer,
236
- :text, :string,
237
- :sdict, :pointer,
238
- :hrecs, :pointer,
239
- :ref_count, :uint32
240
-
241
- def self.release(ptr)
242
- LibHTS.sam_hdr_destroy(ptr) unless ptr.null?
243
- end
244
- end
245
-
246
- BamHdr = SamHdr
247
-
248
- class HtsFile < FFI::BitStruct
249
- layout \
250
- :_flags, :uint32, # bit_fields
251
- :lineno, :int64,
252
- :line, KString,
253
- :fn, :string,
254
- :fn_aux, :string,
255
- :fp,
256
- union_layout(
257
- :bgzf, BGZF.ptr,
258
- :cram, :pointer, # cram_fd
259
- :hfile, HFile.ptr
260
- ),
261
- :state, :pointer,
262
- :format, HtsFormat,
263
- :idx, HtsIdx.ptr,
264
- :fnidx, :string,
265
- :bam_header, SamHdr.ptr
266
-
267
- bit_fields :_flags,
268
- :is_bin, 1,
269
- :is_write, 1,
270
- :is_be, 1,
271
- :is_cram, 1,
272
- :is_bgzf, 1,
273
- :dummy, 27
274
- end
275
-
276
- SamFile = HtsFile
277
-
278
- class HtsTpool < FFI::ManagedStruct
279
- layout \
280
- :pool, :pointer,
281
- :qsize, :int
282
-
283
- def self.release(ptr)
284
- LibHTS.hts_tpool_destroy(ptr) unless ptr.null?
285
- end
286
- end
287
-
288
- class HtsOpt < FFI::Struct
289
- layout \
290
- :arg, :string,
291
- :opt, HtsFmtOption,
292
- :val,
293
- union_layout(
294
- :i, :int,
295
- :s, :string
296
- ),
297
- :next, HtsOpt.ptr
298
- end
299
-
300
- class HtsItr < FFI::BitStruct # FIXME: ManagedBitStruct
301
- layout \
302
- :_flags, :uint32, # bit_fields
303
- :tid, :int,
304
- :n_off, :int,
305
- :i, :int,
306
- :n_reg, :int,
307
- :beg, :int64,
308
- :end, :int64,
309
- :reg_list, :pointer, # HtsReglist.ptr,
310
- :curr_tid, :int,
311
- :curr_reg, :int,
312
- :curr_intv, :int,
313
- :curr_beg, :int64,
314
- :curr_end, :int64,
315
- :curr_off, :uint64,
316
- :nocoor_off, :uint64,
317
- :off, :pointer,
318
- :readrec, :pointer,
319
- :seek, :pointer,
320
- :tell, :pointer,
321
- :bins,
322
- union_layout(
323
- :n, :int,
324
- :m, :int,
325
- :a, :pointer
326
- )
327
-
328
- bit_fields :_flags,
329
- :read_rest, 1,
330
- :finished, 1,
331
- :is_cram, 1,
332
- :nocoor, 1,
333
- :multi, 1,
334
- :dummy, 27
335
-
336
- def self.release(ptr)
337
- LibHTS.hts_itr_destroy(ptr) unless ptr.null?
338
- end
339
- end
340
-
341
- class Bam1Core < FFI::Struct
342
- layout \
343
- :pos, :hts_pos_t,
344
- :tid, :int32,
345
- :bin, :uint16,
346
- :qual, :uint8,
347
- :l_extranul, :uint8,
348
- :flag, :uint16,
349
- :l_qname, :uint16,
350
- :n_cigar, :uint32,
351
- :l_qseq, :int32,
352
- :mtid, :int32,
353
- :mpos, :hts_pos_t,
354
- :isize, :hts_pos_t
355
- end
356
-
357
- class Bam1 < FFI::ManagedStruct
358
- layout \
359
- :core, Bam1Core,
360
- :id, :uint64,
361
- :data, :pointer, # uint8_t
362
- :l_data, :int,
363
- :m_data, :uint32,
364
- :_mempolicy, :uint32 # bit_fields
365
-
366
- # bit_fields :_mempolicy,
367
- # :mempolicy, 2,
368
- # :_reserved, 30
369
-
370
- def self.release(ptr)
371
- LibHTS.bam_destroy1(ptr) unless ptr.null?
372
- end
373
- end
374
-
375
- # Internal: Non-owning view of bam1_t used when the pointer is managed by HTSlib
376
- # (e.g., pileup/mpileup). This struct mirrors the layout of bam1_t and MUST NOT
377
- # free memory on GC. Do not expose publicly; use only for read-only access.
378
- class Bam1View < FFI::Struct
379
- layout \
380
- :core, Bam1Core,
381
- :id, :uint64,
382
- :data, :pointer, # uint8_t
383
- :l_data, :int,
384
- :m_data, :uint32,
385
- :_mempolicy, :uint32 # bit_fields
386
- end
387
-
388
- # Base modification structure
389
- class HtsBaseMod < FFI::Struct
390
- layout \
391
- :modified_base, :int,
392
- :canonical_base, :int,
393
- :strand, :int,
394
- :qual, :int
395
- end
396
-
397
- # Base modification state (opaque pointer)
398
- # Use AutoPointer since the structure is opaque and we only need custom release.
399
- class HtsBaseModState < FFI::AutoPointer
400
- def self.release(ptr)
401
- LibHTS.hts_base_mod_state_free(ptr) unless ptr.null?
402
- end
403
- end
404
-
405
- typedef :pointer, :bam_plp
406
- typedef :pointer, :bam_mplp
407
-
408
- class BamPileupCd < FFI::Union
409
- layout \
410
- :p, :pointer,
411
- :i, :int64,
412
- :f, :double
413
- end
414
-
415
- class BamPileup1 < FFI::BitStruct
416
- layout \
417
- :b, :pointer,
418
- :qpos, :int32,
419
- :indel, :int,
420
- :level, :int,
421
- :_flags, :uint32, # bit_fields
422
- :cd, BamPileupCd,
423
- :cigar_ind, :int
424
-
425
- bit_fields :_flags,
426
- :is_del, 1,
427
- :is_head, 1,
428
- :is_tail, 1,
429
- :is_refskip, 1,
430
- :_reserved, 1,
431
- :aux, 27
432
-
433
- # def self.release(ptr)
434
- # LibHTS.bam_plp_destroy(ptr) unless ptr.null?
435
- # end
436
- end
437
-
438
- class TbxConf < FFI::Struct
439
- layout \
440
- :preset, :int32,
441
- :sc, :int32,
442
- :bc, :int32,
443
- :ec, :int32,
444
- :meta_char, :int32,
445
- :line_skip, :int32
446
- end
447
-
448
- class Tbx < FFI::ManagedStruct
449
- layout \
450
- :conf, TbxConf,
451
- :idx, HtsIdx.ptr,
452
- :dict, :pointer
453
-
454
- def close
455
- return if @closed
456
-
457
- ptr = to_ptr
458
- unless ptr.null?
459
- ptr.autorelease = false if ptr.respond_to?(:autorelease=)
460
- self.class.release(ptr)
461
- end
462
- @closed = true
463
- end
464
-
465
- def self.release(ptr)
466
- LibHTS.tbx_destroy(ptr) unless ptr.null?
467
- end
468
- end
469
-
470
- # faidx
471
-
472
- FaiFormatOptions = enum(:FAI_NONE, :FAI_FASTA, :FAI_FASTQ)
473
-
474
- # Faidx represents a faidx_t handle which is treated as a
475
- # file-level RAII object in HTS::Faidx. It is intentionally
476
- # kept as a plain Struct and is destroyed explicitly via
477
- # LibHTS.fai_destroy in HTS::Faidx#close. Do not convert this
478
- # to ManagedStruct; that would interfere with the explicit
479
- # lifetime managed by the Ruby wrapper.
480
- class Faidx < FFI::Struct
481
- layout :bgzf, BGZF.ptr,
482
- :n, :int,
483
- :m, :int,
484
- :name, :pointer,
485
- :hash, :pointer,
486
- :format, FaiFormatOptions
487
-
488
- def self.release(ptr)
489
- LibHTS.fai_destroy(ptr) unless ptr.null?
490
- end
491
- end
492
-
493
- # bcf
494
-
495
- class BcfVariant < FFI::Struct
496
- layout \
497
- :type, :int,
498
- :n, :int
499
- end
500
-
501
- # Complete textual representation of a header line owned by Ruby.
502
- class BcfHrec < FFI::ManagedStruct
503
- layout \
504
- :type, :int,
505
- :key, :string,
506
- :value, :string,
507
- :nkeys, :int,
508
- :keys, :pointer,
509
- :vals, :pointer
510
-
511
- def self.release(ptr)
512
- LibHTS.bcf_hrec_destroy(ptr) unless ptr.null?
513
- end
514
- end
515
-
516
- class BcfInfo < FFI::BitStruct
517
- layout \
518
- :key, :int,
519
- :type, :int,
520
- :v1,
521
- union_layout(
522
- :i, :int64,
523
- :f, :float
524
- ),
525
- :vptr, :pointer,
526
- :vptr_len, :uint32,
527
- :_vptr_off_free, :uint32, # bit_fields
528
- :len, :int
529
-
530
- bit_fields :_vptr_off_free,
531
- :vptr_off, 31,
532
- :vptr_free, 1
533
- end
534
-
535
- class BcfIdinfo < FFI::Struct
536
- layout \
537
- :info, [:uint64, 3],
538
- :hrec, [:pointer, 3],
539
- :id, :int
540
- end
541
-
542
- class BcfIdpair < FFI::Struct
543
- layout \
544
- :key, :string,
545
- :val, BcfIdinfo.ptr
546
- end
547
-
548
- class BcfHdr < FFI::ManagedStruct
549
- layout \
550
- :n, [:int, 3],
551
- :id, [:pointer, 3], # BcfIdpair.ptr
552
- :dict, [:pointer, 3],
553
- :samples, :pointer,
554
- :hrec, :pointer,
555
- :nhrec, :int,
556
- :dirty, :int,
557
- :ntransl, :int,
558
- :transl, [:pointer, 2],
559
- :nsamples_ori, :int,
560
- :keep_samples, :pointer,
561
- :mem, KString,
562
- :m, [:int, 3]
563
-
564
- def self.release(ptr)
565
- LibHTS.bcf_hdr_destroy(ptr) unless ptr.null?
566
- end
567
- end
568
-
569
- class BcfFmt < FFI::BitStruct
570
- layout \
571
- :id, :int,
572
- :n, :int,
573
- :size, :int,
574
- :type, :int,
575
- :p, :pointer, # uint8_t
576
- :p_len, :uint32,
577
- :_p_off_free, :uint32 # bit_fields
578
-
579
- bit_fields :_p_off_free,
580
- :p_off, 31,
581
- :p_free, 1
582
- end
583
-
584
- class BcfDec < FFI::Struct
585
- layout \
586
- :m_fmt, :int,
587
- :m_info, :int,
588
- :m_id, :int,
589
- :m_als, :int,
590
- :m_allele, :int,
591
- :m_flt, :int,
592
- :n_flt, :int,
593
- :flt, :pointer,
594
- :id, :string,
595
- :als, :pointer, # (\\0-separated string)
596
- :allele, :pointer,
597
- :info, :pointer, # array of BcfInfo.ptr,
598
- :fmt, :pointer, # array of BcfFmt.ptr,
599
- :var, BcfVariant.ptr,
600
- :n_var, :int,
601
- :var_type, :int,
602
- :shared_dirty, :int,
603
- :indiv_dirty, :int
604
- end
605
-
606
- class Bcf1 < FFI::ManagedBitStruct
607
- layout \
608
- :pos, :hts_pos_t,
609
- :rlen, :hts_pos_t,
610
- :rid, :int32,
611
- :qual, :float,
612
- :_n_info_allele, :uint32,
613
- :_n_fmt_sample, :uint32,
614
- :shared, KString,
615
- :indiv, KString,
616
- :d, BcfDec,
617
- :max_unpack, :int,
618
- :unpacked, :int,
619
- :unpack_size, [:int, 3],
620
- :errcode, :int
621
-
622
- bit_fields :_n_info_allele,
623
- :n_info, 16,
624
- :n_allele, 16
625
-
626
- bit_fields :_n_fmt_sample,
627
- :n_fmt, 8,
628
- :n_sample, 24
629
-
630
- def self.release(ptr)
631
- LibHTS.bcf_destroy(ptr) unless ptr.null?
632
- end
633
- end
634
-
635
- CramContentType = enum(
636
- :ct_error, -1,
637
- :file_header, 0,
638
- :compression_header, 1,
639
- :mapped_slice, 2,
640
- :unmapped_slice, 3, # cram v1.0 only
641
- :external, 4,
642
- :core, 5
643
- )
644
-
645
- CramBlockMethod = enum(
646
- :unknown, -1,
647
- :raw, 0,
648
- :gzip, 1,
649
- :bzip2, 2,
650
- :lzma, 3,
651
- :rans4x8, 4,
652
- :ransnx16, 5,
653
- :arith, 6,
654
- :fqz, 7,
655
- :tok3, 8
656
- )
657
- end
658
- end