rust 读取基因组文件并保存为哈希

1引言

我们尝试 使用 rust 来读取基因组文件 并 保存到哈希数据结构 里面。

2代码

这是参照 chatgpt 的代码,测试是可以看到染色体和序列分别一一对应保存到了哈希里面:

// ########################################################################
// load genome and save in hash

use std::collections::HashMap;
use std::fs::File;
use std::io::{BufRead, BufReader};
fn read_genome(genome_file: &str) -> HashMap<String, String> {
    let file = File::open(genome_file).expect("无法打开文件");
    let reader = BufReader::new(file);
    let mut seq_map: HashMap<String, String> = HashMap::new();
    let mut chr = String::new();
    let mut seq = String::new();

    for line in reader.lines() {
        let line = line.expect("读取文件失败");
        if line.starts_with('>') {  // 处理注释行
            if !chr.is_empty() {   // 保存上一个染色体的序列
                seq_map.insert(chr.clone(), seq.clone());
                seq.clear();
            }
            chr = line[1..].trim().to_string();  // 去掉注释行的 ">" 符号
        } else {
            seq.push_str(&line.trim());
        }
    }
    seq_map.insert(chr, seq);  // 保存最后一个染色体的序列
    seq_map
}

fn main() {
    let genome_file = "./test.fa";
    let seq_map = read_genome(genome_file);

    // 通过键值对的方式访问染色体序列
    for (key,val) in &seq_map {
        println!("chromosome is {}; sequnence is {}.",key,val);
    };
}
[Running] cd "c:UsersadminDesktoprust-learn" && rustc 1_readGenome.rs && "c:UsersadminDesktoprust-learn"1_readGenome
chromosome is A1BG-AS1|A1BG-AS1|NR_015380.2|1|2130|2130|NC;
sequnence is ATTTTTAGTAGAGACGGGGTTTCGTCATGTTGGGTAGACTGGTCTCGATCTCTTGACCTCATGATCCGCTGGCCT
CAGCCTCCCAAAGTGCTGGGATTATAGGCGTGAGCCACCGCACCCGGCCTCACCCTTCCATTCTTTGGGCATCCTCTGCCCAAACTCCTTTGCAACCAT.
chromosome is A1CF|A1CF|NM_001198819.2|353|2159|9481|CD;
sequnence is ATAATCAAGGAAACCTTTTCCGGGTGGGGATCTCTGAAATTACTCAGATAACAGTGCTGTGCCAAAAACCTGTGGATT
TTCTCTACAAAAATTATCATGACTGTTATCTTTTTGATGGAAAAGATGAAGTTCAGCGAAGAACAAATCTACAACTTGGCCAGAAGACTGTAGA.
chromosome is A2M|A2M|XM_006719056.4|71|4607|4953|CD;
sequnence is GGGACCAGATGGATTGTAGGGAGTAGGGTACAATACAGTCTGTTCTCCTCCAGCTCCTTCTTTCTGCAACATGGGGAAGAA
CAAACTCCTTCATCCAAGTCTGGTTCTTCTCCTCTTGGTCCTCCTGCCCACAGACGCCTCAGTCTCTGGAAAACCGCAGTATATGGTTCTGGTCCCCTC.
chromosome is A1BG|A1BG|NM_130786.4|56|1541|3382|CD;
sequnence is ATTGCTGCAGACGCTCACCCCAGACACTCACTGCACCGGAGTGAGCGCGACCATCATGTCCATGCTCGTGGTCTTTCTCTTG
CTGTGGGGTGTCACCTGGGGCCCAGTGACAGAAGCAGCCATATTTTATGAGACGCAGCCCAGCCTGTGGGCAGAGTCCGAATCACTGC.

[Done] exited with code=0 in 0.798 seconds

我们自己写一个,主要思路就是: 先建立一个空的哈希,然后遇到 > 符号开头的,就把染色体添加到哈希里作为键,如果不是 > 开头的,则把序列添加到哈希的值里。

use std::collections::HashMap;
use std::fs::File;
use std::io::{BufRead, BufReader};

// define function load genome and save in hash
fn read_genome(genome_file: &str) -> HashMap<String, String> {
    let file = File::open(genome_file).expect("can't open file!");
    let reader = BufReader::new(file);
    let mut seq_map: HashMap<String, String> = HashMap::new();
    let mut chr = String::new();

    for line in reader.lines() {
        let line = line.expect("load file failed! ");
        // 处理注释行
        if line.starts_with('>') {
            // 去掉注释行的 ">" 符号
            chr = line[1..].trim().to_string();
            seq_map.insert(chr.clone(), String::new());
        } else {
            // 获取对应键的值,并添加字符串
            if seq_map.contains_key(&chr) {
                seq_map.entry(chr.clone()).or_insert(String::new()).push_str(&line.trim());
            }
        }
    }
    seq_map
}

fn main() {
    let genome_file = "./test.fa";
    let seq_map = read_genome(genome_file);

    println!("done!");

    // 通过键值对的方式访问染色体序列
    for (key,val) in &seq_map {
        println!("chromosome is {}; sequnence is {}.",key,val);
    }
}
图片

rust 还有关于分析生信数据的 crate,叫做 bio, 我们可以使用这个来读取基因组文件。

我们先用 cargo new bioreadgenome_1 命令建个新项目,下面是文件夹结构:

图片

然后在 cargo.toml 文件的依赖添加:

图片

然后在 mian.rs 里面写代码,这里我们循环打印 id 和序列:

extern crate bio;
use bio::io::fasta;
use std::fs::File;

fn main() {
    let file = File::open("C:\Users\admin\Desktop\rust-learn\test.fa").expect("can't open file!");
    let mut records = fasta::Reader::new(file).records();

    while let Some(Ok(record)) = records.next() {
        println!("id: {:?}", record.id());
        println!("seq: {:?}", String::from_utf8_lossy(record.seq()));
    }
}

cargo build 编译:

图片

cargo run 测试运行, 运行顺利:

图片

3结尾

有关 rust 是什么,如何安装,大家可自行网上搜索,这里不再赘述。


欢迎加入生信交流群。加我微信我也拉你进 微信群聊 老俊俊生信交流群 (微信交流群需收取 20 元入群费用,一旦交费,拒不退还!(防止骗子和便于管理)) 。QQ 群可免费加入, 记得进群按格式修改备注哦。

声明:文中观点不代表本站立场。本文传送门:https://eyangzhen.com/190540.html

(0)
联系我们
联系我们
分享本页
返回顶部