Class: Bio::MAF::FASTARangeReader

Inherits:
Object
  • Object
show all
Defined in:
lib/bio/maf/tiler.rb

Constant Summary collapse

GT =
'>'.getbyte(0)

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(fspec) ⇒ FASTARangeReader

Returns a new instance of FASTARangeReader.



138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/bio/maf/tiler.rb', line 138

def initialize(fspec)
  if fspec.respond_to? :seek
    @f = fspec
  else
    reader_class = if fspec =~ /.gz$/
                     Zlib::GzipReader
                   else
                     File
                   end
    @f = reader_class.open(fspec)
  end
  position_at_start
end

Instance Attribute Details

#fObject (readonly)

Returns the value of attribute f.



136
137
138
# File 'lib/bio/maf/tiler.rb', line 136

def f
  @f
end

#posObject (readonly)

Returns the value of attribute pos.



136
137
138
# File 'lib/bio/maf/tiler.rb', line 136

def pos
  @pos
end

Instance Method Details

#position_at_startObject



154
155
156
157
158
# File 'lib/bio/maf/tiler.rb', line 154

def position_at_start
  first = f.readline
  raise "expected FASTA comment" unless first =~ /^>/
  @pos = 0
end

#read_interval(z_start, z_end) ⇒ Object



160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/bio/maf/tiler.rb', line 160

def read_interval(z_start, z_end)
  if z_start < pos
    position_at_start
  end
  data = ''
  region_size = z_end - z_start
  in_region = false
  f.each_line do |line_raw|
    if line_raw.getbyte(0) == GT
      raise "unexpected description line: #{line_raw.inspect}"
    end
    line = line_raw.strip
    end_pos = pos + line.size
    if (! in_region) && pos <= z_start && z_start < end_pos
      offset = z_start - pos
      end_offset = [(offset + region_size), line.size].min
      data << line.slice(offset...end_offset)
      in_region = true
    elsif in_region
      need = region_size - data.size
      raise "should not happen: region #{region_size}, data #{data.size}, need #{need}" if need < 0
      if need > line.size
        data << line
      else
        # last line
        data << line.slice(0, need)
        break
      end
    end
    @pos = end_pos
  end
  return data
end