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



504
505
506
507
508
# File 'ext/htslib_native/native_bam.c', line 504

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



533
534
535
536
537
538
539
# File 'ext/htslib_native/native_bam.c', line 533

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



483
484
485
486
487
488
489
490
491
492
493
494
# File 'ext/htslib_native/native_bam.c', line 483

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



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

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)


540
541
542
# File 'ext/htslib_native/native_bam.c', line 540

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



509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
# File 'ext/htslib_native/native_bam.c', line 509

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;
    VALUE buffer_storage = 0;
    int result;
    switch (type) { case 'c': case 'C': width = 1; break; case 's': case 'S': width = 2; break; default: width = 4; }
    buffer = ALLOCV_N(uint8_t, buffer_storage, 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 { ALLOCV_END(buffer_storage); rb_raise(rb_eArgError, "invalid AUX array type"); }
    }
    result = bam_aux_update_array(get_record(self)->pointer, StringValueCStr(key), type, count, buffer);
    ALLOCV_END(buffer_storage);
    return INT2NUM(result);
}

#aux_update_float(key, value) ⇒ Object



498
499
500
# File 'ext/htslib_native/native_bam.c', line 498

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



495
496
497
# File 'ext/htslib_native/native_bam.c', line 495

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



501
502
503
# File 'ext/htslib_native/native_bam.c', line 501

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



383
384
385
386
387
388
# File 'ext/htslib_native/native_bam.c', line 383

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



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

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

#cigar_valuesObject



323
324
325
326
327
328
329
330
# File 'ext/htslib_native/native_bam.c', line 323

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



292
293
294
295
296
297
298
299
300
301
302
303
304
305
# File 'ext/htslib_native/native_bam.c', line 292

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



306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
# File 'ext/htslib_native/native_bam.c', line 306

static VALUE native_record_core_set(VALUE self, VALUE field, VALUE new_value) {
    bam1_t *record = get_record(self)->pointer;
    bam1_core_t *core = &record->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");
    if (id == rb_intern("pos") || id == rb_intern("flag")) native_record_update_bin(record);
    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



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

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

#format(header_value) ⇒ Object



395
396
397
398
399
400
401
402
403
# File 'ext/htslib_native/native_bam.c', line 395

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



338
339
340
341
# File 'ext/htslib_native/native_bam.c', line 338

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



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

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

#qname=(name) ⇒ Object



284
285
286
287
288
# File 'ext/htslib_native/native_bam.c', line 284

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



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

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



389
390
391
392
393
394
# File 'ext/htslib_native/native_bam.c', line 389

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



372
373
374
375
376
377
378
379
380
381
382
# File 'ext/htslib_native/native_bam.c', line 372

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
279
280
281
282
# 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;
    VALUE cigar_storage = 0;
    const char *quality_data = NULL;
    int result;

    StringValue(qname);
    StringValue(sequence);
    if (memchr(RSTRING_PTR(qname), '\0', RSTRING_LEN(qname))) {
        rb_raise(rb_eArgError, "qname must not contain NUL bytes");
    }
    Check_Type(cigar_value, T_ARRAY);
    cigar_count = RARRAY_LEN(cigar_value);
    if (cigar_count > 0) {
        cigar = ALLOCV_N(uint32_t, cigar_storage, 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)) {
            ALLOCV_END(cigar_storage);
            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), 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);
    ALLOCV_END(cigar_storage);
    if (result < 0) {
        if (errno) rb_sys_fail("bam_set1");
        rb_raise(rb_eRuntimeError, "bam_set1 failed: %d", result);
    }
    return self;
}

#rlenObject



342
343
344
345
# File 'ext/htslib_native/native_bam.c', line 342

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



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

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



356
357
358
359
360
361
362
363
# File 'ext/htslib_native/native_bam.c', line 356

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;
}