Class: HTS::Native::BamRecordHandle

Inherits:
Object
  • Object
show all
Defined in:
ext/htslib_native/native_bam.c

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.createObject



237
# File 'ext/htslib_native/native_bam.c', line 237

static VALUE native_record_create(VALUE klass) { return wrap_record(bam_init1()); }

Instance Method Details

#aux_append(key, type, payload) ⇒ Object



477
478
479
480
481
# File 'ext/htslib_native/native_bam.c', line 477

static VALUE native_record_aux_append(VALUE self, VALUE key, VALUE type, VALUE payload) {
    StringValue(payload);
    return INT2NUM(bam_aux_append(get_record(self)->pointer, StringValueCStr(key), StringValueCStr(type)[0],
                                  RSTRING_LEN(payload), (uint8_t *)RSTRING_PTR(payload)));
}

#aux_delete(key) ⇒ Object



505
506
507
508
509
510
511
# File 'ext/htslib_native/native_bam.c', line 505

static VALUE native_record_aux_delete(VALUE self, VALUE key) {
    bam1_t *record = get_record(self)->pointer;
    uint8_t *aux = bam_aux_get(record, StringValueCStr(key));
    if (!aux) return Qfalse;
    if (bam_aux_del(record, aux) < 0) rb_raise(rb_eRuntimeError, "failed to delete AUX tag");
    return Qtrue;
}

#aux_entriesObject



456
457
458
459
460
461
462
463
464
465
466
467
# File 'ext/htslib_native/native_bam.c', line 456

static VALUE native_record_aux_entries(VALUE self) {
    bam1_t *record = get_record(self)->pointer;
    uint8_t *aux = bam_aux_first(record);
    VALUE result = rb_ary_new();
    while (aux) {
        VALUE entry = aux_decode(aux, Qnil);
        rb_ary_unshift(entry, rb_str_new((char *)aux - 2, 2));
        rb_ary_push(result, entry);
        aux = bam_aux_next(record, aux);
    }
    return result;
}

#aux_get(key, requested) ⇒ Object



452
453
454
455
# File 'ext/htslib_native/native_bam.c', line 452

static VALUE native_record_aux_get(VALUE self, VALUE key, VALUE requested) {
    uint8_t *aux = bam_aux_get(get_record(self)->pointer, StringValueCStr(key));
    return aux ? aux_decode(aux, requested) : Qnil;
}

#aux_key?(key) ⇒ Boolean

Returns:

  • (Boolean)


512
513
514
# File 'ext/htslib_native/native_bam.c', line 512

static VALUE native_record_aux_key(VALUE self, VALUE key) {
    return bam_aux_get(get_record(self)->pointer, StringValueCStr(key)) ? Qtrue : Qfalse;
}

#aux_update_array(key, type_value, array) ⇒ Object



482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
# File 'ext/htslib_native/native_bam.c', line 482

static VALUE native_record_aux_update_array(VALUE self, VALUE key, VALUE type_value, VALUE array) {
    char type = StringValueCStr(type_value)[0];
    long count = RARRAY_LEN(array), i;
    size_t width;
    uint8_t *buffer;
    int result;
    switch (type) { case 'c': case 'C': width = 1; break; case 's': case 'S': width = 2; break; default: width = 4; }
    buffer = ALLOC_N(uint8_t, count * width + 1);
    for (i = 0; i < count; i++) {
        VALUE item = rb_ary_entry(array, i);
        if (type == 'c') { int8_t v = NUM2INT(item); memcpy(buffer + i, &v, 1); }
        else if (type == 'C') { uint8_t v = NUM2UINT(item); memcpy(buffer + i, &v, 1); }
        else if (type == 's') { int16_t v = NUM2INT(item); memcpy(buffer + i * 2, &v, 2); }
        else if (type == 'S') { uint16_t v = NUM2UINT(item); memcpy(buffer + i * 2, &v, 2); }
        else if (type == 'i') { int32_t v = NUM2INT(item); memcpy(buffer + i * 4, &v, 4); }
        else if (type == 'I') { uint32_t v = NUM2UINT(item); memcpy(buffer + i * 4, &v, 4); }
        else if (type == 'f') { float v = (float)NUM2DBL(item); memcpy(buffer + i * 4, &v, 4); }
        else { xfree(buffer); rb_raise(rb_eArgError, "invalid AUX array type"); }
    }
    result = bam_aux_update_array(get_record(self)->pointer, StringValueCStr(key), type, count, buffer);
    xfree(buffer);
    return INT2NUM(result);
}

#aux_update_float(key, value) ⇒ Object



471
472
473
# File 'ext/htslib_native/native_bam.c', line 471

static VALUE native_record_aux_update_float(VALUE self, VALUE key, VALUE value) {
    return INT2NUM(bam_aux_update_float(get_record(self)->pointer, StringValueCStr(key), NUM2DBL(value)));
}

#aux_update_int(key, value) ⇒ Object



468
469
470
# File 'ext/htslib_native/native_bam.c', line 468

static VALUE native_record_aux_update_int(VALUE self, VALUE key, VALUE value) {
    return INT2NUM(bam_aux_update_int(get_record(self)->pointer, StringValueCStr(key), NUM2LL(value)));
}

#aux_update_string(key, value) ⇒ Object



474
475
476
# File 'ext/htslib_native/native_bam.c', line 474

static VALUE native_record_aux_update_string(VALUE self, VALUE key, VALUE value) {
    return INT2NUM(bam_aux_update_str(get_record(self)->pointer, StringValueCStr(key), -1, StringValueCStr(value)));
}

#base_code(index) ⇒ Object



372
373
374
375
376
377
# File 'ext/htslib_native/native_bam.c', line 372

static VALUE native_record_base_code(VALUE self, VALUE index) {
    bam1_t *record = get_record(self)->pointer;
    long i = NUM2LONG(index);
    if (i < 0 || i >= record->core.l_qseq) return Qnil;
    return INT2NUM(bam_seqi(bam_get_seq(record), i));
}

#cigar=(text) ⇒ Object



322
323
324
325
326
# File 'ext/htslib_native/native_bam.c', line 322

static VALUE native_record_set_cigar(VALUE self, VALUE text) {
    int result = bam_parse_cigar(StringValueCStr(text), NULL, get_record(self)->pointer);
    if (result < 0) rb_raise(rb_eRuntimeError, "bam_parse_cigar failed: %d", result);
    return text;
}

#cigar_valuesObject



314
315
316
317
318
319
320
321
# File 'ext/htslib_native/native_bam.c', line 314

static VALUE native_record_cigar_values(VALUE self) {
    bam1_t *record = get_record(self)->pointer;
    uint32_t *cigar = bam_get_cigar(record);
    VALUE result = rb_ary_new_capa(record->core.n_cigar);
    uint32_t i;
    for (i = 0; i < record->core.n_cigar; i++) rb_ary_push(result, UINT2NUM(cigar[i]));
    return result;
}

#core_get(field) ⇒ Object



285
286
287
288
289
290
291
292
293
294
295
296
297
298
# File 'ext/htslib_native/native_bam.c', line 285

static VALUE native_record_core_get(VALUE self, VALUE field) {
    bam1_core_t *core = &get_record(self)->pointer->core;
    ID id = SYM2ID(field);
    if (id == rb_intern("tid")) return INT2NUM(core->tid);
    if (id == rb_intern("mtid")) return INT2NUM(core->mtid);
    if (id == rb_intern("pos")) return LL2NUM(core->pos);
    if (id == rb_intern("mpos")) return LL2NUM(core->mpos);
    if (id == rb_intern("bin")) return UINT2NUM(core->bin);
    if (id == rb_intern("isize")) return LL2NUM(core->isize);
    if (id == rb_intern("mapq")) return UINT2NUM(core->qual);
    if (id == rb_intern("flag")) return UINT2NUM(core->flag);
    if (id == rb_intern("length")) return LL2NUM(core->l_qseq);
    rb_raise(rb_eArgError, "unknown BAM core field");
}

#core_set(field, new_value) ⇒ Object



299
300
301
302
303
304
305
306
307
308
309
310
311
312
# File 'ext/htslib_native/native_bam.c', line 299

static VALUE native_record_core_set(VALUE self, VALUE field, VALUE new_value) {
    bam1_core_t *core = &get_record(self)->pointer->core;
    ID id = SYM2ID(field);
    if (id == rb_intern("tid")) core->tid = NUM2INT(new_value);
    else if (id == rb_intern("mtid")) core->mtid = NUM2INT(new_value);
    else if (id == rb_intern("pos")) core->pos = NUM2LL(new_value);
    else if (id == rb_intern("mpos")) core->mpos = NUM2LL(new_value);
    else if (id == rb_intern("bin")) core->bin = NUM2UINT(new_value);
    else if (id == rb_intern("isize")) core->isize = NUM2LL(new_value);
    else if (id == rb_intern("mapq")) core->qual = NUM2UINT(new_value);
    else if (id == rb_intern("flag")) core->flag = NUM2UINT(new_value);
    else rb_raise(rb_eArgError, "unknown or read-only BAM core field");
    return new_value;
}

#duplicateObject



238
# File 'ext/htslib_native/native_bam.c', line 238

static VALUE native_record_duplicate(VALUE self) { return wrap_record(bam_dup1(get_record(self)->pointer)); }

#endposObject



313
# File 'ext/htslib_native/native_bam.c', line 313

static VALUE native_record_endpos(VALUE self) { return LL2NUM(bam_endpos(get_record(self)->pointer)); }

#format(header_value) ⇒ Object



384
385
386
387
388
389
390
391
392
# File 'ext/htslib_native/native_bam.c', line 384

static VALUE native_record_to_s(VALUE self, VALUE header_value) {
    kstring_t string = KS_INITIALIZE;
    int result = sam_format1(get_header(header_value)->pointer, get_record(self)->pointer, &string);
    VALUE value;
    if (result < 0) { free(string.s); rb_raise(rb_eRuntimeError, "failed to format BAM record"); }
    value = rb_str_new(string.s, string.l);
    free(string.s);
    return value;
}

#qlenObject



327
328
329
330
# File 'ext/htslib_native/native_bam.c', line 327

static VALUE native_record_qlen(VALUE self) {
    bam1_t *record = get_record(self)->pointer;
    return LL2NUM(bam_cigar2qlen(record->core.n_cigar, bam_get_cigar(record)));
}

#qnameObject



279
# File 'ext/htslib_native/native_bam.c', line 279

static VALUE native_record_qname(VALUE self) { return rb_str_new_cstr(bam_get_qname(get_record(self)->pointer)); }

#qname=(name) ⇒ Object



280
281
282
283
284
# File 'ext/htslib_native/native_bam.c', line 280

static VALUE native_record_set_qname(VALUE self, VALUE name) {
    int result = bam_set_qname(get_record(self)->pointer, StringValueCStr(name));
    if (result < 0) rb_raise(rb_eRuntimeError, "bam_set_qname failed: %d", result);
    return name;
}

#qualitiesObject



353
354
355
356
357
358
359
360
# File 'ext/htslib_native/native_bam.c', line 353

static VALUE native_record_qualities(VALUE self) {
    bam1_t *record = get_record(self)->pointer;
    uint8_t *qualities = bam_get_qual(record);
    hts_pos_t i, length = record->core.l_qseq;
    VALUE result = rb_ary_new_capa(length);
    for (i = 0; i < length; i++) rb_ary_push(result, UINT2NUM(qualities[i]));
    return result;
}

#quality_at(index) ⇒ Object



378
379
380
381
382
383
# File 'ext/htslib_native/native_bam.c', line 378

static VALUE native_record_quality_at(VALUE self, VALUE index) {
    bam1_t *record = get_record(self)->pointer;
    long i = NUM2LONG(index);
    if (i < 0 || i >= record->core.l_qseq) return Qnil;
    return UINT2NUM(bam_get_qual(record)[i]);
}

#quality_stringObject



361
362
363
364
365
366
367
368
369
370
371
# File 'ext/htslib_native/native_bam.c', line 361

static VALUE native_record_quality_string(VALUE self) {
    bam1_t *record = get_record(self)->pointer;
    uint8_t *qualities = bam_get_qual(record);
    hts_pos_t i, length = record->core.l_qseq;
    VALUE result;
    if (length == 0) return rb_str_new("", 0);
    if (qualities[0] == 255) return rb_str_new("*", 1);
    result = rb_str_new(NULL, length);
    for (i = 0; i < length; i++) RSTRING_PTR(result)[i] = (char)(qualities[i] + 33);
    return result;
}

#replace(qname, flag, tid, pos, mapq, cigar_value, mtid, mpos, isize, sequence, qualities) ⇒ Object



239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
# File 'ext/htslib_native/native_bam.c', line 239

static VALUE native_record_replace(VALUE self, VALUE qname, VALUE flag, VALUE tid, VALUE pos,
                                   VALUE mapq, VALUE cigar_value, VALUE mtid, VALUE mpos,
                                   VALUE isize, VALUE sequence, VALUE qualities) {
    bam1_t *record = get_record(self)->pointer;
    long cigar_count, i;
    uint32_t *cigar = NULL;
    const char *quality_data = NULL;
    int result;

    StringValue(qname);
    StringValue(sequence);
    Check_Type(cigar_value, T_ARRAY);
    cigar_count = RARRAY_LEN(cigar_value);
    if (cigar_count > 0) {
        cigar = ALLOC_N(uint32_t, cigar_count);
        for (i = 0; i < cigar_count; i++) cigar[i] = NUM2UINT(rb_ary_entry(cigar_value, i));
    }
    if (!NIL_P(qualities)) {
        StringValue(qualities);
        if (RSTRING_LEN(qualities) != RSTRING_LEN(sequence)) {
            if (cigar) xfree(cigar);
            rb_raise(rb_eArgError, "qualities length must match sequence length");
        }
        quality_data = RSTRING_PTR(qualities);
    }

    errno = 0;
    result = bam_set1(record,
                      (size_t)RSTRING_LEN(qname) + 1, RSTRING_PTR(qname),
                      NUM2UINT(flag), NUM2INT(tid), NUM2LL(pos), NUM2UINT(mapq),
                      (size_t)cigar_count, cigar,
                      NUM2INT(mtid), NUM2LL(mpos), NUM2LL(isize),
                      (size_t)RSTRING_LEN(sequence), RSTRING_PTR(sequence), quality_data, 0);
    if (cigar) xfree(cigar);
    if (result < 0) {
        if (errno) rb_sys_fail("bam_set1");
        rb_raise(rb_eRuntimeError, "bam_set1 failed: %d", result);
    }
    return self;
}

#rlenObject



331
332
333
334
# File 'ext/htslib_native/native_bam.c', line 331

static VALUE native_record_rlen(VALUE self) {
    bam1_t *record = get_record(self)->pointer;
    return LL2NUM(bam_cigar2rlen(record->core.n_cigar, bam_get_cigar(record)));
}

#sequenceObject



335
336
337
338
339
340
341
342
343
344
# File 'ext/htslib_native/native_bam.c', line 335

static VALUE native_record_sequence(VALUE self) {
    static const char table[] = "=ACMGRSVTWYHKDBN";
    bam1_t *record = get_record(self)->pointer;
    uint8_t *packed = bam_get_seq(record);
    hts_pos_t i, length = record->core.l_qseq;
    VALUE result = rb_str_new(NULL, length);
    char *out = RSTRING_PTR(result);
    for (i = 0; i < length; i++) out[i] = table[bam_seqi(packed, i)];
    return result;
}

#sequence_codesObject



345
346
347
348
349
350
351
352
# File 'ext/htslib_native/native_bam.c', line 345

static VALUE native_record_sequence_codes(VALUE self) {
    bam1_t *record = get_record(self)->pointer;
    uint8_t *packed = bam_get_seq(record);
    hts_pos_t i, length = record->core.l_qseq;
    VALUE result = rb_ary_new_capa(length);
    for (i = 0; i < length; i++) rb_ary_push(result, INT2NUM(bam_seqi(packed, i)));
    return result;
}