4. 测序数据(FASTQ)质量控制基础
FASTQ 质控,听起来像是 pipeline 里的例行公事。很多新手拿到数据直接就跑 spaceranger,结果要么比对率低得可怜,要么基因表达矩阵里全是背景噪声。我最初做 Visium 项目时就吃过这个亏——跑了三天,最后一看报告,30% 的 reads 都没比对上去。后来回头补做质控,才发现是接头污染和质量过低导致的。从那以后,我再也不敢跳过这步了。
4.1 FASTQ 文件长什么样?
先快速回顾一下 FASTQ 格式,每四条记录为一组:
- 第一行:@ 开头,ID+注释
- 第二行:原始序列(A/T/C/G/N)
- 第三行:+ 分隔符(通常只有 +)
- 第四行:质量值字符串,每个字符代表一个碱基的质量(Phred+33 编码)
4.2 常见质量“陷阱”
Visium 的文库制备有其特殊性:poly-A 捕获 + 空间条形码连接。这导致三个常见问题:
- 低质量尾巴 —— 测序仪读到末端时荧光信号衰减,3′ 端质量尤其差。
- 接头污染 —— 空间条形码和 UMI 连接引物未完全去除,会干扰比对。
- 重复序列过多 —— PCR 扩增导致的 duplication,影响基因定量。
| 问题类型 | 诱因 | 后果 |
|---|---|---|
| 低质量碱基(Q<20) | 测序仪末端衰减 | 错配率高,比对失败 |
| 接头残留 | 文库纯化不够 | read 被错误截断或比对到接头序列 |
| GC bias | PCR 扩增偏好 | 部分基因被低估或高估 |
| N 含量过高 | 测序错误或 base caller 无法判定 | 比对时 soft-clip 增多 |
4.3 我的质控工具选型
我习惯用这三个工具的配合:
- FastQC —— 快速生成 HTML 项目报告,各模块一目了然。
- MultiQC —— 汇总所有样本的 FastQC 结果,适合横向对比。
- Cutadapt —— 专门用来去接头和质量修剪,灵活且快。
运行 FastQC 极其简单:
fastqc sample_R1.fastq.gz sample_R2.fastq.gz -o fastqc_output/
输出会得到一个 .html 和一个 .zip。打开 HTML,我通常按这个顺序筛查:
- Per base sequence quality —— 看第一个 box plot 是否在绿色区域。
- Per sequence GC content —— 理想曲线是近似正态分布,如果出现双峰可能意味着污染。
- Overrepresented sequences —— 如果出现在前 10 名且占比 >1%,多半是接头或 rRNA。
- Adapter content —— 直接告诉你哪一类接头需要去除。
快速参考表:FastQC 核心指标评判
| 模块 | PASS(优秀) | WARN(注意) | FAIL(必需处理) |
|---|---|---|---|
| Per base quality | 所有位置中位数 Q≥28 | 有位置中位数 20–28 | 有位置中位数 <20 |
| Per sequence GC content | 与理论曲线偏差 <15% | 偏差 15–30% | 偏差 >30% 或双峰 |
| Adapter content | 任何接头占比 <0.1% | 0.1–1% | >1% |
| Overrepresented seq | 无超过 0.1% 的序列 | 有 0.1–1% | 有 >1% |
4.4 修剪策略与实战命令
拿到 FastQC 报告后,我开始写修剪脚本。基本思路:去接头 → 质量裁剪 → 最小长度过滤。Cutadapt 可以一条命令搞定:
cutadapt -a AGATCGGAAGAGCACACGTCTGAACTCCAGTCA \
-A AGATCGGAAGAGCGTCGTGTAGGGAAAGAGTGT \
-q 20,20 \
--minimum-length 50 \
-o clean_R1.fastq.gz \
-p clean_R2.fastq.gz \
raw_R1.fastq.gz raw_R2.fastq.gz
参数说明:
-a/-A:R1 和 R2 的 adapter 序列。-q 20,20:两端 5′→3′ 滑动窗口修剪,当平均质量低于 20 时切除。--minimum-length 50:扔掉修剪后短于 50 bp 的 read pair。
-u -10 从 3′ 端去掉 10 bp 低质量区域,而不是用滑动窗口。
修剪完别忘了再做一次 FastQC,确认问题已解决:
fastqc clean_R1.fastq.gz clean_R2.fastq.gz -o fastqc_post/
4.5 进阶:k-mer 分析与污染排查
如果你发现 Per base GC 和 Per sequence GC 都正常,但比对率仍然偏低,可以跑 FastQC 的“Kmer Content”模块。它会列出过度表示的 k-mer(默认 7-mer)。我遇到过一例:k-mer 中出现大量 “CCCCCCC” 和 “GGGGGGG” —— 后来发现是样本中的线粒体 rRNA 污染。这种污染普通接头去不掉,需要额外用 bbmap 或 bowtie2 过滤。
方法很简单:构建一个已知污染序列库(rRNA、线粒体、phiX),用 bowtie2 直接比对并取出未比对的 reads:
bowtie2 -x contaminants_index -U clean_R2.fastq.gz \
--un unaligned.fastq.gz -S /dev/null
然后用 unaligned.fastq.gz 跑 spaceranger。这一步我通常在质控报告里记录了 k-mer warning 之后才执行,属于“按需操作”。
4.6 关于 MultiQC 的横向对比
如果项目里有几十个样本,逐个点开 HTML 太慢。MultiQC 能汇总所有 FastQC 输出:
multiqc fastqc_output/ -o multiqc_report/
我最看重的是“General Statistics”表格 —— 一行就能看到所有样本的总 reads 数、GC 含量、Q20/Q30 比例。如果某个样本的 GC 异常偏离群体,我会单独标记它,准备深度排查。
4.7 整章知识脉络
下面这张图概括了我日常的 FASTQ 质控流程,从原始数据到可以放心提交给 spaceranger 的干净数据:
总结一下:质控不是跑一次工具就完了,它是一轮迭代。先跑 FastQC 看状况,再根据问题选择合适的修剪手段,最后用第二次 FastQC 确认干净。我刚开始带团队时,总有人嫌这一步耽误时间,想直接跳到比对。但你想啊,如果输入数据就有 30% 的无用 reads,后面花更多时间调试参数、怀疑算法,岂不是更亏?