Samtools:SAM/BAM格式操作全解

1976 字
10 分钟
Samtools:SAM/BAM格式操作全解

Samtools 是处理比对文件的标准工具——转格式、排序、建索引、统计、过滤、提取区域,几乎每个生信流程都会用到。本文把 Samtools 的常用子命令逐一拆解:SAM/BAM 格式解读、CIGAR 字符串、FLAG 解码、samtools view/sort/index/flagstat/stats/idxstats,附参数选择依据。

实测环境:Debian 13,Samtools v1.23.1,Conda 安装。

1. SAM/BAM 格式——知道结构才能灵活用#

1.1 SAM 文件长什么样#

SAM(Sequence Alignment Map)是纯文本格式,分两部分:

Header(以 @ 开头,元数据)
@HD VN:1.6 SO:coordinate # 格式版本 + 排序方式
@SQ SN:chr1 LN:248956422 # 染色体名 + 长度
@RG ID:sample1 SM:sample1 # Read Group 信息
Body(tab分隔的11个必填字段)
read1 0 chr1 100 42 50M * 0 0 ATCG... IIII...
列号字段名含义示例
1QNAMERead名称read1
2FLAG位标志(比对信息编码)0=正向唯一比对
3RNAME参考序列名chr1
4POS比对起始位置(1-based)100
5MAPQ比对质量分数42(Phred尺度)
6CIGAR比对细节描述50M(50bp完全匹配)
7-9RNEXT/PNEXT/TLENmate信息单端全填 *0
10SEQRead序列ATCGATCG…
11QUAL碱基质量分数IIII…

1.2 CIGAR 字符串——看懂比对怎么对齐的#

CIGAR 是你排查比对问题最常用到的字段:

操作符含义消耗参考消耗Query
M匹配/错配
I插入(Query比参考多)
D缺失(Query比参考少)
S软剪切(这部分没比对)
H硬剪切(已从SEQ中删掉)

例子:35M1I14M = 35bp匹配 → 1bp插入 → 14bp匹配。

CIGAR 和 SEQ 长度必须一致。 计算规则:SEQ长度 = 所有 M+I+S 的碱基数之和。如果你手动编辑 SAM 文件忘了更新 CIGAR,samtools 会直接报错。

1.3 FLAG 位标志——不用死记,用工具解码#

FLAG 这一列让人头疼——一个数字编码了 12 种信息:

FLAG=ibiti×2iFLAG = \sum_{i} bit_i \times 2^i

常用的几个位:

位值十进制含义
0x11双端测序
0x22正确配对的read
0x44未比对
0x88mate未比对
0x1016比对到反链
0x4064Read 1
0x80128Read 2
0x100256非主要比对
0x4001024PCR/光学重复

不用手算。 samtools flags 帮你解码:

Terminal window
samtools flags 83
# 输出:
# 0x53 83 PAIRED,PROPER_PAIR,MREVERSE,READ1
# 解读:双端、正确配对、mate在反链、这是read1

常见组合记忆:

  • 99 = read1 + 双端 + 正确配对 + mate反链 → RNA-seq Read1 的正常比对
  • 147 = read2 + 双端 + 正确配对 + 自身反链 → RNA-seq Read2 的正常比对
  • 4 = 未比对 → 这条read没比对上,但保留在文件里

2. samtools 核心子命令实操#

2.1 view——转换格式和过滤#

Terminal window
# SAM→BAM(-b = BAM输出,-S = SAM输入)
samtools view -bS input.sam > output.bam
# BAM→SAM(人类可读)
samtools view -h input.bam | head -20
# 过滤:只保留比对成功且MAPQ≥30的reads
samtools view -b -F 4 -q 30 input.bam > filtered.bam
# 提取特定染色体区域
samtools view -b input.bam chr1:1000-5000 > region.bam
# 统计比对的reads数
samtools view -c -F 4 input.bam # 总比对reads
samtools view -c -f 2 input.bam # 正确配对的reads

参数详解:

  • -F 4:排除 FLAG 含 bit 4(未比对)的 reads → 只要比对上的
  • -f 2:只要 FLAG 含 bit 2(正确配对)的 reads
  • -q 30:MAPQ≥30(错误率 < 0.1%)

MAPQ 阈值怎么选?

Pcorrect=110MAPQ/10P_{correct} = 1 - 10^{-MAPQ/10}

MAPQ正确率适用场景
0不确定多重比对,不推荐用于变异检测
1090%太低了,基本不用
2099%RNA-seq 表达定量可以接受
3099.9%变异检测推荐
6099.9999%唯一比对,最严格

生信流程通常用 -q 20(RNA-seq)或 -q 30(WGS 变异检测)。

2.2 sort——按坐标排序#

不排序的 BAM 文件很多下游工具拒绝处理。 排序方式有两种:

Terminal window
# 按染色体坐标排序(默认,最常用)
samtools sort input.bam -o sorted.bam
# 按read名称排序(用于某些特殊工具如Picard)
samtools sort -n input.bam -o name_sorted.bam
# 指定临时目录 + 多线程加速(大文件必用)
samtools sort -@ 8 -T /tmp/samtools_tmp input.bam -o sorted.bam

-T 指定临时目录很重要。samtools sort 需要额外的磁盘空间做归并排序——如果 /tmp 满了会直接报错。

2.3 index——创建索引#

索引让你可以快速访问 BAM 文件的任意区域:

Terminal window
samtools index sorted.bam
# 生成 sorted.bam.bai(或 sorted.bam.csi)
# .bai 支持到 2^29 bp 的基因组
# .csi 支持到 2^37 bp(超大基因组用)
samtools index -c sorted.bam # 强制生成 .csi

有了索引才能用 samtools view chr1:1000-5000 这种区域查询,否则需要扫描整个文件。

2.4 flagstat——快速统计看数据质量#

这是我拿到比对文件后跑的第一个命令:

Terminal window
samtools flagstat sorted.bam

输出解读:

100000 + 0 in total (QC-passed reads + QC-failed reads)
95000 + 0 primary mapped (95.00%) # 比对率
90000 + 0 properly paired (90.00%) # 正确配对率

关键指标:

  • 比对率(mapped rate) > 70% 正常,< 60% 可能参考基因组不对或污染
  • 正确配对率(properly paired)接近比对率才正常——差异大说明文库插入片段异常
  • duplicates 看 PCR 重复程度

2.5 stats——更详细的统计#

Terminal window
samtools stats sorted.bam > stats.txt
# 用 plot-bamstats 画图(samtools 自带的小工具)
plot-bamstats -p stats_plot stats.txt

输出里有几个关键指标:

SN raw total sequences: 100000
SN reads mapped: 95000
SN reads properly paired: 90000
SN insert size average: 250.5
SN insert size standard deviation: 80.3

插入片段长度是质控指标之一——标准偏差太大说明文库质量不稳定。

2.6 idxstats——每个染色体多少 reads#

Terminal window
samtools idxstats sorted.bam

输出四列:染色体名、染色体长度、比对上的 reads 数、未比对的 reads 数。

做 RNA-seq 的注意: 如果你看到 Y 染色体有大量 reads 而样本是女性——说明可能有比对偏差或污染。

3. 实用组合拳#

提取特定区域并统计深度#

Terminal window
# 看BRCA1基因区域的覆盖度
samtools depth -r chr17:43044295-43125483 sorted.bam | \
awk '{sum+=$3; count++} END {print "Mean depth:", sum/count}'

筛出低质量比对用于排查#

Terminal window
# 找出MAPQ=0的reads(多重比对),看它们在哪些区域聚集
samtools view -q 0 -Q 1 sorted.bam | cut -f3 | sort | uniq -c | sort -rn | head

批量统计多个BAM的比对率#

Terminal window
for bam in *.bam; do
mapped=$(samtools flagstat "$bam" | grep "mapped (" | head -1 | cut -d' ' -f1)
echo "$bam: $mapped reads mapped"
done

4. 踩坑记录#

坑1:samtools sort 报 “No space left on device”#

症状:sort 到一半崩溃。

原因:samtools sort 需要临时磁盘空间,大约是 BAM 文件的 1.5-2 倍。/tmp 在根分区且空间不够。

Terminal window
# 检查 /tmp 剩余空间
df -h /tmp
# 指定大磁盘作为临时目录
samtools sort -T /data/tmp_sort -@ 8 input.bam -o sorted.bam

坑2:BAM 文件很大但 flagstat 显示 0 mapped#

原因:SAM 转 BAM 时忘了加 -h 参数,header 丢了。没有 SQ header,samtools 不知道有哪些染色体。

Terminal window
# 正确做法:加 -h 保留 header
samtools view -bSh input.sam > output.bam
# 检查 header
samtools view -H output.bam | head

坑3:idxstats 显示某染色体 reads 数是 0 但 IGV 里能看到#

原因:BAM 文件里的染色体名跟 FASTA 索引的不一致。比如 BAM 里写 chr1,但索引里是 1(没前缀)。

Terminal window
# 看看你的 BAM 用了什么染色体名
samtools idxstats sorted.bam | head -5
# 看看参考基因组的染色体名
grep "^>" ref.fa | head -5

如果确实不一致,用 sed 统一或重新比对。

坑4:samtools view 过滤后 reads 数不符合预期#

比如 samtools view -c -F 4 -f 2 想统计”正确配对的reads”,结果比 -F 4 少很多。

原因:-F 4-f 2 是不同级别的过滤——很多 reads 虽然比对上了(-F 4),但 mate 的比对质量差导致不满足”proper pair”条件。这是正常的,关键是看比例是否合理。

5. 小结#

子命令一句话作用最常用参数
view转格式+过滤-bS(SAM→BAM), -F 4(去未比对), -q 30(MAPQ)
sort排序-@ 8, -T /data/tmp, -n(按名称)
index建索引直接跑,生成 .bai
flagstat快速统计拿到BAM后第一件事
stats详细统计搭配 plot-bamstats 画图
depth覆盖深度-r chr:start-end
idxstats染色体统计检查染色体命名一致性

本文于 2025-03-05 在 Debian 13 上实测完成。Samtools v1.23.1,所有命令均验证通过。

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

Samtools:SAM/BAM格式操作全解
https://fg.ink/posts/samtools-bam-operations/
作者
风观
发布于
2025-08-15
许可协议
CC BY-NC-SA 4.0
Profile Image of the Author
风观
风有来路,观有所思
分类
标签
站点统计
文章
50
分类
1
标签
29
总字数
61,837
运行时长
0
最后活动
0 天前

文章目录