Class: HTS::Bcf::Info

Inherits:
Object
  • Object
show all
Defined in:
lib/hts/bcf/info.rb

Constant Summary collapse

TYPE_CODES =
{
  flag: Native::BCF_HT_FLAG, bool: Native::BCF_HT_FLAG,
  int: Native::BCF_HT_INT, int32: Native::BCF_HT_INT,
  int64: Native::BCF_HT_LONG, long: Native::BCF_HT_LONG,
  float: Native::BCF_HT_REAL, real: Native::BCF_HT_REAL,
  string: Native::BCF_HT_STR, str: Native::BCF_HT_STR
}.freeze

Instance Method Summary collapse

Constructor Details

#initialize(record) ⇒ Info

Returns a new instance of Info.



14
# File 'lib/hts/bcf/info.rb', line 14

def initialize(record) = @record = record

Instance Method Details

#[](key) ⇒ Object



35
# File 'lib/hts/bcf/info.rb', line 35

def [](key) = get(key)

#[]=(key, value) ⇒ Object



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/hts/bcf/info.rb', line 37

def []=(key, value)
  case value
  when nil then delete(key)
  when true, false then update_flag(key, value)
  when Integer
    unless int32?(value)
      raise RangeError,
            "Integer out of int32 range for []=. Current htslib backend does not support int64 INFO update."
    end

    update_int(key, [value])
  when Float then update_float(key, [value])
  when String then update_string(key, value)
  when Array
    raise ArgumentError, "Cannot set INFO field to empty array. Use nil to delete." if value.empty?

    if value.all? { |item| item.is_a?(Integer) }
      unless value.all? do |item|
        int32?(item)
      end
        raise RangeError,
              "Integer array contains out-of-int32 values for []=. Current htslib backend does not support int64 INFO update."
      end

      update_int(key, value)
    elsif value.all? { |item| item.is_a?(Numeric) }
      update_float(key, value)
    else
      raise ArgumentError, "INFO array must contain only integers or floats, got: #{value.map(&:class).uniq}"
    end
  else raise ArgumentError, "Unsupported INFO value type: #{value.class}"
  end
end

#delete(key) ⇒ Object



81
82
83
84
85
86
87
# File 'lib/hts/bcf/info.rb', line 81

def delete(key)
  schema = header.schema("INFO", key.to_s)
  return false unless schema && key?(key)

  native.info_update(header_native, key.to_s, TYPE_CODES.fetch(schema.first), false)
  true
end

#fieldsObject



95
# File 'lib/hts/bcf/info.rb', line 95

def fields = native.info_fields(header_native)

#get(key, type = nil) ⇒ Object



16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/hts/bcf/info.rb', line 16

def get(key, type = nil)
  schema = header.schema("INFO", key.to_s)
  return nil unless schema

  actual_type = schema.first
  requested = type&.to_sym
  if requested && !type_compatible?(actual_type, requested)
    raise InfoTypeError, "Tag #{key} is not #{type_label(requested)} INFO field"
  end

  code = TYPE_CODES.fetch(requested || actual_type)
  native.info_get(header_native, key.to_s, code)
end

#get_flag(key) ⇒ Object



34
# File 'lib/hts/bcf/info.rb', line 34

def get_flag(key) = get(key, :flag)

#get_float(key) ⇒ Object



31
# File 'lib/hts/bcf/info.rb', line 31

def get_float(key) = get(key, :float)

#get_int(key) ⇒ Object



30
# File 'lib/hts/bcf/info.rb', line 30

def get_int(key) = get(key, :int)

#get_int64(key) ⇒ Object



32
# File 'lib/hts/bcf/info.rb', line 32

def get_int64(key) = get(key, :int64)

#get_string(key) ⇒ Object



33
# File 'lib/hts/bcf/info.rb', line 33

def get_string(key) = get(key, :string)

#key?(key) ⇒ Boolean Also known as: include?

Returns:

  • (Boolean)


89
90
91
92
# File 'lib/hts/bcf/info.rb', line 89

def key?(key)
  schema = header.schema("INFO", key.to_s)
  schema ? native.info_present?(header_native, key.to_s, TYPE_CODES.fetch(schema.first)) : false
end

#keysObject



96
# File 'lib/hts/bcf/info.rb', line 96

def keys = fields.map { |field| field[:key] }

#lengthObject Also known as: size



97
# File 'lib/hts/bcf/info.rb', line 97

def length = fields.length

#to_hObject



99
# File 'lib/hts/bcf/info.rb', line 99

def to_h = fields.to_h { |field| [field[:name], get(field[:name])] }

#update_flag(key, present = true) ⇒ Object



79
# File 'lib/hts/bcf/info.rb', line 79

def update_flag(key, present = true) = update(key, Native::BCF_HT_FLAG, !!present, "flag")

#update_float(key, values) ⇒ Object



72
# File 'lib/hts/bcf/info.rb', line 72

def update_float(key, values) = update(key, Native::BCF_HT_REAL, Array(values).map(&:to_f), "float")

#update_int(key, values) ⇒ Object



71
# File 'lib/hts/bcf/info.rb', line 71

def update_int(key, values) = update(key, Native::BCF_HT_INT, Array(values).map { |value| Integer(value) }, "int")

#update_int64(_key, _values) ⇒ Object



75
76
77
# File 'lib/hts/bcf/info.rb', line 75

def update_int64(_key,
                       _values) = raise(UnsupportedInfoOperationError,
"htslib backend does not implement int64 INFO update (BCF_HT_LONG)")

#update_string(key, value) ⇒ Object



73
# File 'lib/hts/bcf/info.rb', line 73

def update_string(key, value) = update(key, Native::BCF_HT_STR, value.to_s, "string")