Class: HTS::Bam::BaseMod
- Inherits:
-
Object
- Object
- HTS::Bam::BaseMod
- Includes:
- Enumerable
- Defined in:
- lib/hts/bam/base_mod.rb
Overview
BaseMod is a view object that references data in a Record. The state is maintained in hts_base_mod_state structure.
Base modification information from MM/ML tags
This class provides access to DNA/RNA base modifications such as methylation. It wraps the htslib base modification API and provides a Ruby-friendly interface.
Defined Under Namespace
Classes: Modification, NotParsedError, Position
Instance Attribute Summary collapse
-
#record ⇒ Object
readonly
Returns the value of attribute record.
Instance Method Summary collapse
-
#[](position) ⇒ Position?
Array-style access to modifications at a position.
-
#at_pos(position, max_mods: 10) ⇒ Position?
Get modification information at a specific query position.
-
#close ⇒ void
Explicitly free the state.
-
#each_position(max_mods: 10) {|Position| ... } ⇒ Enumerator
(also: #each)
Iterate over all positions with modifications.
-
#ensure_parsed!(flags = 0) ⇒ void
Ensure MM/ML have been parsed, performing lazy parse if enabled.
-
#initialize(record, auto_parse: true) ⇒ BaseMod
constructor
Initialize a new BaseMod object.
-
#inspect ⇒ String
Inspect string.
-
#modification_types ⇒ Array<Integer>
(also: #recorded_types)
Get list of modification types present in this record.
-
#parse(flags = 0) ⇒ Integer
Parse MM and ML tags from the record.
-
#parsed? ⇒ Boolean
Whether this object has parsed MM/ML tags already.
-
#query_type(code) ⇒ Hash?
Query information about a specific modification type by code.
-
#query_type_at(index) ⇒ Hash?
Query information about i-th modification type.
-
#to_a ⇒ Array<Position>
Get all modifications as an array.
-
#to_s ⇒ String
String representation for debugging.
Constructor Details
#initialize(record, auto_parse: true) ⇒ BaseMod
Initialize a new BaseMod object
134 135 136 137 138 139 140 141 |
# File 'lib/hts/bam/base_mod.rb', line 134 def initialize(record, auto_parse: true) @record = record @state = LibHTS.hts_base_mod_state_alloc @closed = false @auto_parse = !!auto_parse @parsed = false raise Error, "Failed to allocate hts_base_mod_state" if @state.null? end |
Instance Attribute Details
#record ⇒ Object (readonly)
Returns the value of attribute record.
17 18 19 |
# File 'lib/hts/bam/base_mod.rb', line 17 def record @record end |
Instance Method Details
#[](position) ⇒ Position?
Array-style access to modifications at a position
203 204 205 |
# File 'lib/hts/bam/base_mod.rb', line 203 def [](position) at_pos(position) end |
#at_pos(position, max_mods: 10) ⇒ Position?
Get modification information at a specific query position
187 188 189 190 191 192 193 194 195 196 197 198 |
# File 'lib/hts/bam/base_mod.rb', line 187 def at_pos(position, max_mods: 10) # Reset state to ensure deterministic results even after prior iteration parsed? ? parse : ensure_parsed! mods_ptr = FFI::MemoryPointer.new(LibHTS::HtsBaseMod, max_mods) ret = LibHTS.bam_mods_at_qpos(@record.struct, position, @state, mods_ptr, max_mods) return nil if ret <= 0 build_position(position, mods_ptr, [ret, max_mods].min) end |
#close ⇒ void
This method returns an undefined value.
Explicitly free the state
145 146 147 148 149 150 151 152 |
# File 'lib/hts/bam/base_mod.rb', line 145 def close return if @closed # With HtsBaseModState as an AutoPointer, releasing the Ruby object # is sufficient. Avoid manual free to prevent double-free. @state = nil @closed = true end |
#each_position(max_mods: 10) {|Position| ... } ⇒ Enumerator Also known as: each
Iterate over all positions with modifications
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 |
# File 'lib/hts/bam/base_mod.rb', line 211 def each_position(max_mods: 10) return enum_for(__method__, max_mods: max_mods) unless block_given? # Reset state at the start of iteration to allow repeated enumerations parsed? ? parse : ensure_parsed! pos_ptr = FFI::MemoryPointer.new(:int) mods_ptr = FFI::MemoryPointer.new(LibHTS::HtsBaseMod, max_mods) loop do ret = LibHTS.bam_next_basemod(@record.struct, @state, mods_ptr, max_mods, pos_ptr) break if ret <= 0 position = pos_ptr.read_int yield build_position(position, mods_ptr, [ret, max_mods].min) end end |
#ensure_parsed!(flags = 0) ⇒ void
This method returns an undefined value.
Ensure MM/ML have been parsed, performing lazy parse if enabled.
163 164 165 166 167 168 169 |
# File 'lib/hts/bam/base_mod.rb', line 163 def ensure_parsed!(flags = 0) return if @parsed raise NotParsedError, "BaseMod is not parsed. Call #parse first (auto_parse is disabled)." unless @auto_parse parse(flags) end |
#inspect ⇒ String
Inspect string
314 315 316 |
# File 'lib/hts/bam/base_mod.rb', line 314 def inspect to_s end |
#modification_types ⇒ Array<Integer> Also known as: recorded_types
Get list of modification types present in this record
234 235 236 237 238 239 240 241 242 243 244 |
# File 'lib/hts/bam/base_mod.rb', line 234 def modification_types ensure_parsed! ntype_ptr = FFI::MemoryPointer.new(:int) codes_ptr = LibHTS.bam_mods_recorded(@state, ntype_ptr) ntype = ntype_ptr.read_int return [] if ntype <= 0 || codes_ptr.null? codes_ptr.read_array_of_int(ntype) end |
#parse(flags = 0) ⇒ Integer
Parse MM and ML tags from the record
175 176 177 178 179 180 181 |
# File 'lib/hts/bam/base_mod.rb', line 175 def parse(flags = 0) ret = LibHTS.bam_parse_basemod2(@record.struct, @state, flags) raise Error, "Failed to parse base modifications" if ret < 0 @parsed = true ret end |
#parsed? ⇒ Boolean
Whether this object has parsed MM/ML tags already
156 157 158 |
# File 'lib/hts/bam/base_mod.rb', line 156 def parsed? @parsed end |
#query_type(code) ⇒ Hash?
Query information about a specific modification type by code
251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 |
# File 'lib/hts/bam/base_mod.rb', line 251 def query_type(code) ensure_parsed! code = code.ord if code.is_a?(String) strand_ptr = FFI::MemoryPointer.new(:int) implicit_ptr = FFI::MemoryPointer.new(:int) canonical_ptr = FFI::MemoryPointer.new(:char, 1) ret = LibHTS.bam_mods_query_type(@state, code, strand_ptr, implicit_ptr, canonical_ptr) return nil if ret < 0 { canonical: canonical_ptr.read_char.chr, strand: strand_ptr.read_int, implicit: implicit_ptr.read_int != 0 } end |
#query_type_at(index) ⇒ Hash?
Query information about i-th modification type
274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 |
# File 'lib/hts/bam/base_mod.rb', line 274 def query_type_at(index) ensure_parsed! strand_ptr = FFI::MemoryPointer.new(:int) implicit_ptr = FFI::MemoryPointer.new(:int) canonical_ptr = FFI::MemoryPointer.new(:char, 1) ret = LibHTS.bam_mods_queryi(@state, index, strand_ptr, implicit_ptr, canonical_ptr) return nil if ret < 0 types = modification_types { code: types[index], canonical: canonical_ptr.read_char.chr, strand: strand_ptr.read_int, implicit: implicit_ptr.read_int != 0 } end |
#to_a ⇒ Array<Position>
Get all modifications as an array
296 297 298 |
# File 'lib/hts/bam/base_mod.rb', line 296 def to_a each_position.to_a end |
#to_s ⇒ String
String representation for debugging
302 303 304 305 306 307 308 309 310 |
# File 'lib/hts/bam/base_mod.rb', line 302 def to_s return "#<HTS::Bam::BaseMod (not parsed)>" unless @parsed mods = [] each_position do |pos| mods << pos.to_s end "#<HTS::Bam::BaseMod #{mods.join(' ')}>" end |