htslib 0.3.0 → 0.3.2

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.
@@ -2,6 +2,11 @@
2
2
 
3
3
  module HTS
4
4
  module LibHTS
5
+ # Callback type for bam_plp_auto_f: int (*)(void *data, bam1_t *b)
6
+ # Use raw pointer for bam1_t to avoid creating ManagedStruct wrappers (which would double-free)
7
+ callback :bam_plp_auto_f, %i[pointer pointer], :int
8
+ # callback :bam_plp_auto_f, [:pointer, Bam1.by_ref], :int
9
+
5
10
  # Generates a new unpopulated header structure.
6
11
  attach_function \
7
12
  :sam_hdr_init,
@@ -414,24 +419,24 @@ module HTS
414
419
 
415
420
  attach_function \
416
421
  :sam_parse1,
417
- [KString, SamHdr, Bam1],
422
+ [KString, SamHdr, :pointer], # [KString, SamHdr, (Bam1 | Bam1View)]
418
423
  :int
419
424
 
420
425
  attach_function \
421
426
  :sam_format1,
422
- [SamHdr, Bam1, KString],
427
+ [SamHdr, :pointer, KString], # [SamHdr, (Bam1 | Bam1View), KString]
423
428
  :int
424
429
 
425
430
  # Read a record from a file
426
431
  attach_function \
427
432
  :sam_read1,
428
- [HtsFile, SamHdr, Bam1],
433
+ [HtsFile, SamHdr, :pointer], # [HtsFile, SamHdr, (Bam1 | Bam1View)]
429
434
  :int
430
435
 
431
436
  # Write a record to a file
432
437
  attach_function \
433
438
  :sam_write1,
434
- [HtsFile, SamHdr, Bam1],
439
+ [HtsFile, SamHdr, :pointer], # [HtsFile, SamHdr, (Bam1 | Bam1View)]
435
440
  :int
436
441
 
437
442
  # Checks whether a record passes an hts_filter.
@@ -555,28 +560,28 @@ module HTS
555
560
 
556
561
  attach_function \
557
562
  :bam_plp_push,
558
- [:bam_plp, Bam1],
563
+ [:bam_plp, Bam1.by_ref],
559
564
  :int
560
565
 
561
566
  attach_function \
562
567
  :bam_plp_next,
563
568
  %i[bam_plp pointer pointer pointer],
564
- BamPileup1.by_ref
569
+ :pointer # BamPileup1.by_ref
565
570
 
566
571
  attach_function \
567
572
  :bam_plp_auto,
568
573
  %i[bam_plp pointer pointer pointer],
569
- BamPileup1.by_ref
574
+ :pointer # BamPileup1.by_ref
570
575
 
571
576
  attach_function \
572
577
  :bam_plp64_next,
573
578
  %i[bam_plp pointer pointer pointer],
574
- BamPileup1.by_ref
579
+ :pointer # BamPileup1.by_ref
575
580
 
576
581
  attach_function \
577
582
  :bam_plp64_auto,
578
583
  %i[bam_plp pointer pointer pointer],
579
- BamPileup1.by_ref
584
+ :pointer # BamPileup1.by_ref
580
585
 
581
586
  attach_function \
582
587
  :bam_plp_set_maxcnt,
@@ -588,7 +593,9 @@ module HTS
588
593
  [:bam_plp],
589
594
  :void
590
595
 
591
- callback :bam_plp_callback_function, [:pointer, Bam1, BamPileupCd], :int
596
+ # Callback type for constructor/destructor: int (*)(void *data, const bam1_t *b, bam_pileup_cd *cd)
597
+ callback :bam_plp_callback_function, [:pointer, :pointer, BamPileupCd.by_ref], :int
598
+ # callback :bam_plp_callback_function, [:pointer, Bam1.by_ref, BamPileupCd.by_ref], :int
592
599
 
593
600
  # sets a callback to initialise any per-pileup1_t fields.
594
601
  attach_function \
@@ -602,17 +609,21 @@ module HTS
602
609
  :void
603
610
 
604
611
  # Get pileup padded insertion sequence
612
+ # Make pointer passing explicit by using by_ref for structs
605
613
  attach_function \
606
614
  :bam_plp_insertion,
607
- [BamPileup1, KString, :pointer],
615
+ [BamPileup1.by_ref, KString.by_ref, :pointer],
608
616
  :int
609
617
 
610
618
  # Get pileup padded insertion sequence, including base modifications
611
619
  attach_function \
612
620
  :bam_plp_insertion_mod,
613
- [BamPileup1, :pointer, KString, :pointer],
621
+ [BamPileup1.by_ref, HtsBaseModState, KString.by_ref, :pointer],
614
622
  :int
615
623
 
624
+ # NOTE: There is no bam_plp_init_overlaps in HTSlib (only bam_mplp_init_overlaps exists).
625
+ # The incorrect binding is removed to avoid undefined symbol errors.
626
+
616
627
  attach_function \
617
628
  :bam_mplp_init,
618
629
  %i[int bam_plp_auto_f pointer],
@@ -672,61 +683,61 @@ module HTS
672
683
  attach_function \
673
684
  :hts_base_mod_state_alloc,
674
685
  [],
675
- :pointer # hts_base_mod_state
686
+ HtsBaseModState
676
687
 
677
688
  # Destroys an hts_base_mode_state.
678
689
  attach_function \
679
690
  :hts_base_mod_state_free,
680
- [:pointer], # hts_base_mod_state
691
+ [HtsBaseModState],
681
692
  :void
682
693
 
683
694
  # Parses the MM and ML tags out of a bam record.
684
695
  attach_function \
685
696
  :bam_parse_basemod,
686
- [Bam1, :pointer],
697
+ [Bam1, HtsBaseModState],
687
698
  :int
688
699
 
689
700
  # Parses the MM and ML tags out of a bam record.
690
701
  attach_function \
691
702
  :bam_parse_basemod2,
692
- [Bam1, :pointer, :uint32],
703
+ [Bam1, HtsBaseModState, :uint32],
693
704
  :int
694
705
 
695
706
  # Returns modification status for the next base position in the query seq.
696
707
  attach_function \
697
708
  :bam_mods_at_next_pos,
698
- [Bam1, :pointer, :pointer, :int],
709
+ [Bam1, HtsBaseModState, :pointer, :int],
699
710
  :int
700
711
 
701
712
  # Finds the next location containing base modifications and returns them
702
713
  attach_function \
703
714
  :bam_next_basemod,
704
- [Bam1, :pointer, :pointer, :int, :pointer],
715
+ [Bam1, HtsBaseModState, :pointer, :int, :pointer],
705
716
  :int
706
717
 
707
718
  # Returns modification status for a specific query position.
708
719
  attach_function \
709
720
  :bam_mods_at_qpos,
710
- [Bam1, :int, :pointer, :pointer, :int],
721
+ [Bam1, :int, HtsBaseModState, :pointer, :int],
711
722
  :int
712
723
 
713
724
  # Returns data about a specific modification type for the alignment record.
714
725
  attach_function \
715
726
  :bam_mods_query_type,
716
- %i[pointer int pointer pointer string],
727
+ [HtsBaseModState, :int, :pointer, :pointer, :pointer],
717
728
  :int
718
729
 
719
730
  # Returns data about the i^th modification type for the alignment record.
720
731
  attach_function \
721
732
  :bam_mods_queryi,
722
- %i[pointer int pointer pointer string],
733
+ [HtsBaseModState, :int, :pointer, :pointer, :pointer],
723
734
  :int
724
735
 
725
736
  # Returns the list of base modification codes provided for this
726
737
  attach_function \
727
738
  :bam_mods_recorded,
728
- %i[pointer pointer],
729
- :int
739
+ [HtsBaseModState, :pointer],
740
+ :pointer
730
741
  end
731
742
  end
732
743
 
data/lib/hts/libhts.rb CHANGED
@@ -23,6 +23,12 @@ module HTS
23
23
  rescue FFI::NotFoundError => e
24
24
  warn e.message if $VERBOSE
25
25
  end
26
+
27
+ def self.attach_variable(*)
28
+ super
29
+ rescue FFI::NotFoundError => e
30
+ warn e.message if $VERBOSE
31
+ end
26
32
  end
27
33
  end
28
34
 
data/lib/hts/tabix.rb CHANGED
@@ -44,11 +44,31 @@ module HTS
44
44
  @idx = load_index(index)
45
45
  end
46
46
 
47
- def build_index
48
- raise "Not implemented yet"
47
+ def build_index(index_name = nil, min_shift: 0)
48
+ check_closed
49
+
50
+ if index_name
51
+ warn "Create index for #{@file_name} to #{index_name}"
52
+ case LibHTS.tbx_index_build2(@file_name, index_name, min_shift, LibHTS.tbx_conf_vcf)
53
+ when 0 # successful
54
+ when -1 then raise "general failure"
55
+ when -2 then raise "compression not BGZF"
56
+ else raise "unknown error"
57
+ end
58
+ else
59
+ warn "Create index for #{@file_name}"
60
+ case LibHTS.tbx_index_build(@file_name, min_shift, LibHTS.tbx_conf_vcf)
61
+ when 0 # successful
62
+ when -1 then raise "general failure"
63
+ when -2 then raise "compression not BGZF"
64
+ else raise "unknown error"
65
+ end
66
+ end
67
+ self # for method chaining
49
68
  end
50
69
 
51
70
  def load_index(index_name = nil)
71
+ check_closed
52
72
  if index_name
53
73
  LibHTS.tbx_index_load2(@file_name, index_name)
54
74
  else
@@ -57,14 +77,17 @@ module HTS
57
77
  end
58
78
 
59
79
  def index_loaded?
80
+ check_closed
60
81
  !@idx.null?
61
82
  end
62
83
 
63
84
  def name2id(name)
85
+ check_closed
64
86
  LibHTS.tbx_name2id(@idx, name)
65
87
  end
66
88
 
67
89
  def seqnames
90
+ check_closed
68
91
  nseq = FFI::MemoryPointer.new(:int)
69
92
  LibHTS.tbx_seqnames(@idx, nseq).then do |pts|
70
93
  pts.read_array_of_pointer(nseq.read_int).map(&:read_string)
@@ -82,6 +105,20 @@ module HTS
82
105
  end
83
106
  end
84
107
 
108
+ def close
109
+ return if closed?
110
+
111
+ # @idx is an internal index (LibHTS::Tbx, a ManagedStruct).
112
+ # Do not call tbx_destroy here; the FFI finalizer will
113
+ # release the underlying C struct when @idx becomes unreachable.
114
+ @idx = nil
115
+ super
116
+ end
117
+
118
+ def closed?
119
+ @hts_file.nil? || @hts_file.null?
120
+ end
121
+
85
122
  private
86
123
 
87
124
  def queryi(id, start, end_, &block)
@@ -112,5 +149,9 @@ module HTS
112
149
  LibHTS.hts_itr_destroy(qiter)
113
150
  end
114
151
  end
152
+
153
+ def check_closed
154
+ raise IOError, "closed Tabix" if closed?
155
+ end
115
156
  end
116
157
  end
data/lib/hts/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module HTS
4
- VERSION = "0.3.0"
4
+ VERSION = "0.3.2"
5
5
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: htslib
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - kojix2
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 1980-01-02 00:00:00.000000000 Z
10
+ date: 2025-11-27 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: ffi
@@ -62,10 +62,13 @@ files:
62
62
  - TUTORIAL.md
63
63
  - lib/hts/bam.rb
64
64
  - lib/hts/bam/auxi.rb
65
+ - lib/hts/bam/base_mod.rb
65
66
  - lib/hts/bam/cigar.rb
66
67
  - lib/hts/bam/flag.rb
67
68
  - lib/hts/bam/header.rb
68
69
  - lib/hts/bam/header_record.rb
70
+ - lib/hts/bam/mpileup.rb
71
+ - lib/hts/bam/pileup.rb
69
72
  - lib/hts/bam/record.rb
70
73
  - lib/hts/bcf.rb
71
74
  - lib/hts/bcf/format.rb
@@ -116,7 +119,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
116
119
  - !ruby/object:Gem::Version
117
120
  version: '0'
118
121
  requirements: []
119
- rubygems_version: 3.7.1
122
+ rubygems_version: 3.6.2
120
123
  specification_version: 4
121
124
  summary: HTSlib bindings for Ruby
122
125
  test_files: []