#文件格式 #fasta #fastq #格式文件 #序列 #生物信息学 #读取

jseqio

在FASTA或FASTQ格式中读取和写入生物序列

4个版本

0.1.3 2024年6月5日
0.1.2 2024年4月26日
0.1.1 2024年4月26日
0.1.0 2024年4月26日

#112 in 生物学


用于 2 crate

MIT 许可证

33KB
648

此crate提供了FASTA和FASTQ格式序列的解析器。

库设计

在生物信息学中,序列通常以FASTA或FASTQ格式存储在文件中,这些文件通常使用gzip进行压缩。这总共有四种格式:有gzip和无gzip的FASTA,以及有gzip和无gzip的FASTQ。crate的目的是提供一种可以自动检测文件格式并解析它而无需用户事先知道正在使用哪种格式的解析器。文件格式从文件的前两个字节检测,不依赖于文件扩展名

我们使用动态调度来隐藏文件格式的细节。这引入了每个序列一个动态调度的开销,除非序列非常短,否则这种开销很可能可以忽略不计。这也允许我们支持从任何字节流读取,例如标准输入,而无需在解析器上附加泛型参数。接口实现于reader::DynamicFastXReader结构。还有一个reader::StaticFastXReader,它将输入流作为泛型参数。

序列使用指向读者内部缓冲区切片的record::RefRecord结构表示,以避免为每个序列分配新内存。还有一个record::OwnedRecord,它拥有内存。

由于读者流式传输数据,我们不能实现Rust的Iterator特质。Rust迭代器的生命周期限制要求所有元素在迭代结束时仍然有效。为了支持迭代器,我们提供了一个seq_db::SeqDB结构,它将所有序列、标题和质量值连接到内存中,并提供它们的迭代器。

示例

将文件中的所有序列流式传输并打印到标准输出。

use jseqio::reader::*;
fn main() -> Result<(), Box<dyn std::error::Error>>{
    // Reading from a FASTQ file. Also works for FASTA,
    // and seamlessly with/without gzip compression.
    let mut reader = DynamicFastXReader::from_file(&"tests/data/reads.fastq.gz")?;
    while let Some(rec) = reader.read_next().unwrap() {
        // Headers do not include the leading '>' in FASTA or '@' in FASTQ.
        eprintln!("Header: {}", std::str::from_utf8(rec.head)?);
        eprintln!("Sequence: {}", std::str::from_utf8(rec.seq)?);
        if let Some(qual) = rec.qual{
            // Quality values are present only in fastq files.
            eprintln!("Quality values: {}", std::str::from_utf8(qual)?);
        }
    }
    Ok(())
}

将序列加载到内存中,并使用迭代器计算总长度。

use jseqio::reader::DynamicFastXReader;
fn main() -> Result<(), Box<dyn std::error::Error>>{
    let reader = DynamicFastXReader::from_file(&"tests/data/reads.fna")?;
    let db = reader.into_db()?;
    let total_length = db.iter().fold(0_usize, |sum, rec| sum + rec.seq.len());
    eprintln!("Total sequence length: {}", total_length);
    Ok(())
}

依赖项

~385KB