Github开源生信云平台 DEMO
下面用表格形式把你这条 build_db 命令涉及的参数做系统说明(按“类别 → 参数 → 作用 → 影响”整理)。
build_db
-k INT
-l INT
-S BITSTRING
-T BITSTRING
-X
-H FILE
hash.k2d
-t FILE
taxo.k2d
-o FILE
opts.k2d
-n DIR
nodes.dmp
-m FILE
seqid2taxid.map
-c INT
-M INT
-r INT
📌 你用的是:
-c 24137
约等于 24G 容量。
-p INT
-F
-B INT
-b INT
k (35) └─ 内部选 l (31) └─ 应用 S mask └─ 插入 CHT (capacity=c)
如果你只记住三个:
| 排名 | 参数 | 决定什么 || -- | -- | ---------- || ① | -k | 准确率 vs 敏感度 || ② | -l | 数据库大小 || ③ | -c | 内存占用 |
我可以再给你:
你想看哪一块?
很好 👍 我来专门解释:
在 Kraken 2 中,这个哈希表是如何用于“基因序列”的?
你刚刚看到的 Rust 示例:
table.compare_and_set(12345, 5, &mut old);
这里的 12345 在真实 Kraken 中并不是随便的数字,而是:
12345
🔬 一个 k-mer(DNA 片段)的编码结果
Kraken 不是直接存整条基因序列。
它存的是:
k-mer → taxid
例如:
DNA 序列:
ATGCGTACGTTAGC
如果 k = 5
会被切成:
ATGCG TGCGT GCGTA CGTAC ...
这些 5-mer 就是哈希表的 key。
Kraken 里会把 DNA 编码成 2-bit 表示:
| 碱基 | 二进制 || -- | --- || A | 00 || C | 01 || G | 10 || T | 11 |
比如:
ATGC
变成:
00 11 10 01
变成一个 8-bit 整数。
k=31 时,就是 62-bit 整数。
👉 这就是:
hkey_t key
Kraken 不存完整 key。
它存:
hash(key) 的高位部分 → taxid
结构:
[ hashed_key | taxid ]
总共 32 bits。
数据库构建阶段:
对每个参考基因组:
for 每条DNA序列: for 每个k-mer: key = encode(k-mer) taxid = 当前物种ID hash_table.compare_and_set(key, taxid)
如果:
当 Kraken 分类一条 read:
输入 read: ATGCGTACGTTAGC...
步骤:
1️⃣ 切成 k-mer2️⃣ 每个 k-mer 查询 hash 表:
let taxid = table.get(encoded_kmer);
3️⃣ 得到一堆 taxid:
562 562 561 562 0
4️⃣ 投票决定最终分类
你写的:
在 Kraken 里真实对应的是:
let encoded_kmer = encode_dna("ATGCGT..."); let taxid = 562; // E. coli table.compare_and_set(encoded_kmer, taxid, &mut old);
因为数据库非常巨大。
假设:
如果每个 cell 8 字节:
8GB 内存
但 Kraken 只用:
4 字节 / cell
节省一半内存。
它是:
🧠 所有 k-mer 到物种 ID 的高速查找索引
构建数据库:
Genome → k-mer → encode → hash → CompactHashTable
分类 read:
Read → k-mer → encode → hash lookup → taxid → 投票
因为只存 hash 的高位部分。
可能发生:
两个不同 k-mer → 同样的 compacted_key
这叫:
假阳性
但概率极低,而且:
假设数据库中:
ATGCG → 562 (E. coli)
查询时:
read: ATGCGTACG...
切片:
ATGCG → 查到 562
如果 read 中 80% k-mer 都指向 562
最终分类为:
Escherichia coli
在 Kraken 2 中:
CompactHashTable 存储的是“DNA k-mer → 物种 taxid” 的压缩索引用于超高速分类基因序列
如果你愿意,我可以下一步讲:
你想往哪块深入?