Class: HTS::Bam::Pileup

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/hts/bam/pileup.rb

Defined Under Namespace

Classes: BorrowedColumnView, BorrowedEntryView, PileupColumn, PileupRecord

Constant Summary collapse

BASE_COUNT_FIELDS =
%i[depth a c g t n forward reverse deletion insertion].freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(bam, region: nil, beg: nil, end_: nil, maxcnt: nil) ⇒ Pileup

Returns a new instance of Pileup.

Raises:

  • (ArgumentError)


82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/hts/bam/pileup.rb', line 82

def initialize(bam, region: nil, beg: nil, end_: nil, maxcnt: nil)
  raise ArgumentError, "beg and end_ must be specified together" if beg.nil? != end_.nil?
  raise ArgumentError, "region is required when beg/end_ are specified" if !beg.nil? && region.nil?

  @bam = bam
  @header = bam.header
  if region && !bam.__send__(:ensure_index_loaded)
    raise "Index file is required to use region pileup."
  end
  @native = Native::PileupHandle.open(
    bam.__send__(:native_handle), @header.__send__(:native_handle), region, beg, end_, maxcnt
  )
end

Class Method Details

.open(*args, **keywords) ⇒ Object



11
12
13
14
15
16
17
18
19
20
21
# File 'lib/hts/bam/pileup.rb', line 11

def self.open(*args, **keywords)
  pileup = new(*args, **keywords)
  return pileup unless block_given?

  begin
    yield pileup
  ensure
    pileup.close
  end
  pileup
end

Instance Method Details

#closeObject



163
# File 'lib/hts/bam/pileup.rb', line 163

def close = @native&.close

#eachObject



96
97
98
99
100
101
102
103
104
# File 'lib/hts/bam/pileup.rb', line 96

def each
  return to_enum(__method__) unless block_given?

  each_raw_column do |tid, pos, rows|
    alignments = rows.map { |row| PileupRecord.new(row, @header) }
    yield PileupColumn.new(tid:, pos:, alignments:)
  end
  self
end

#each_base_counts(min_base_quality: 0, min_mapping_quality: 0) ⇒ Object



130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/hts/bam/pileup.rb', line 130

def each_base_counts(min_base_quality: 0, min_mapping_quality: 0)
  return to_enum(__method__, min_base_quality:, min_mapping_quality:) unless block_given?

  min_base_quality = Integer(min_base_quality)
  min_mapping_quality = Integer(min_mapping_quality)
  if min_base_quality.negative? || min_mapping_quality.negative?
    raise ArgumentError,
          "quality thresholds must be non-negative"
  end

  counts = Array.new(BASE_COUNT_FIELDS.length, 0)
  each_raw_column do |tid, pos, rows|
    counts.fill(0)
    rows.each do |row|
      next if row[6] || row[10] < min_mapping_quality

      if row[3] || row[1].negative?
        counts[8] += 1
      else
        next if row[9] < min_base_quality

        counts[{ 1 => 1, 2 => 2, 4 => 3, 8 => 4 }.fetch(row[8], 5)] += 1
      end
      counts[0] += 1
      counts[(row[7] & 16).zero? ? 6 : 7] += 1
      counts[9] += 1 if row[2].positive?
    end
    yield tid, pos, counts
  end
  self
end

#each_depthObject



106
107
108
109
110
111
# File 'lib/hts/bam/pileup.rb', line 106

def each_depth
  return to_enum(__method__) unless block_given?

  each_raw_column { |tid, pos, rows| yield tid, pos, rows.length }
  self
end

#each_entry_rawObject



121
122
123
124
125
126
127
128
# File 'lib/hts/bam/pileup.rb', line 121

def each_entry_raw
  return to_enum(__method__) unless block_given?

  each_raw_column do |tid, pos, rows|
    rows.each { |row| yield tid, pos, row[1], row[7], row[8], row[9] }
  end
  self
end

#each_viewObject



113
114
115
116
117
118
119
# File 'lib/hts/bam/pileup.rb', line 113

def each_view
  return to_enum(__method__) unless block_given?

  view = BorrowedColumnView.new
  each_raw_column { |tid, pos, rows| yield view.reset(rows, tid, pos) }
  self
end

#resetObject



162
# File 'lib/hts/bam/pileup.rb', line 162

def reset = @native.reset