#bcf #生物信息学 #跨平台 #访问 #迭代器 #数字 #

bcf_reader

一个轻量级、纯Rust库,允许高效、跨平台访问BCF文件中的基因型数据

6个版本

新版本 0.3.1 2024年8月22日
0.3.0 2024年8月20日
0.2.4 2024年7月1日
0.2.3 2024年4月21日
0.1.2 2024年2月25日

#593 in 解析器实现

Download history 148/week @ 2024-06-28 55/week @ 2024-07-05 7/week @ 2024-07-19 31/week @ 2024-07-26 239/week @ 2024-08-16

每月下载量 272

MIT 协议

545KB
2K SLoC

Crates.io Crates.io Crates.io docs.rs GitHub Workflow Status

bcf_reader

这是一个尝试创建一个轻量级、纯Rust库,以允许高效、跨平台访问BCF文件中的基因型数据。

目前,rust_htslib 包只适用于Linux和macOS(不适用于Windows?)。noodles包是一个适用于多种生物信息学文件格式的纯Rust库,可以在Windows、Linux和macOS上运行。然而,由于内存分配模式,noodles包读取BCF文件中的基因型数据的API可能较慢。此外,这两个包都有大量的依赖项,因为它们提供许多功能并支持广泛的文件格式。

解决内存分配和依赖问题的一种方法是根据其规范手动解析BCF记录(https://samtools.github.io/hts-specs/VCFv4.2.pdf)并在可能的情况下使用迭代器,特别是对于每个样本的字段,如GT和AD。

注意:此包处于早期开发阶段。

使用方法

use bcf_reader::*;
let mut reader = smart_reader("testdata/test2.bcf");
let header = Header::from_string(&read_header(&mut reader));
// find key for a field in INFO or FORMAT or FILTER
let key = header.get_idx_from_dictionary_str("FORMAT", "GT").unwrap();
// access header dictionary
let d = &header.dict_strings()[&key];
assert_eq!(d["ID"], "GT");
assert_eq!(d["Dictionary"], "FORMAT");
/// get chromosome name
assert_eq!(header.get_chrname(0), "Pf3D7_01_v3");
let fmt_ad_key = header
    .get_idx_from_dictionary_str("FORMAT", "AD")
    .expect("FORMAT/AD not found");
let info_af_key = header
    .get_idx_from_dictionary_str("INFO", "AF")
    .expect("INFO/AF not found");

// this can be and should be reused to reduce allocation
let mut record = Record::default();
while let Ok(_) = record.read(&mut reader) {
    let pos = record.pos();

    // use byte ranges and shared buffer to get allele string values
    let allele_byte_ranges = record.alleles();
    let share_buf = record.buf_shared();
    let ref_rng = &allele_byte_ranges[0];
    let ref_allele_str =
        std::str::from_utf8(&share_buf[ref_rng.start..ref_rng.end]).unwrap();
    let alt1_rng = &allele_byte_ranges[1];
    let alt1_allele_str =
        std::str::from_utf8(&share_buf[alt1_rng.start..alt1_rng.end]).unwrap();
    // ...

    // access FORMAT/GT via iterator
    for nv in record.fmt_gt(&header) {
        let (has_no_ploidy, is_missing, is_phased, allele_idx) = nv.gt_val();
        // ...
    }

    // access FORMAT/AD via iterator
    for nv in record.fmt_field(fmt_ad_key) {
        match nv.int_val() {
            None => {}
            Some(ad) => {
                // ...
            }
        }
        // ...
    }

    // access FILTERS via itertor
    record.filters().for_each(|nv| {
        let filter_key = nv.int_val().unwrap() as usize;
        let dict_string_map = &header.dict_strings()[&filter_key];
        let filter_name = &dict_string_map["ID"];
        // ...
    });

    // access INFO/AF via itertor
    record.info_field_numeric(info_af_key).for_each(|nv| {
        let af = nv.float_val().unwrap();
        // ...
    });
}

依赖项

~2MB
~35K SLoC