FASTQ 质控与预处理

系统讲解 FASTQ 质控与预处理:FastQC 报告逐项解读、接头与污染识别、fastp 实战配置、滑窗与全局质量剪裁策略、UMI 与去重、双端数据的同步处理、污染检测与去污染,以及质控指标如何与下游比对和变异检测衔接,并给出可直接复用的命令、阈值与质控闭环验证方法。

引言

质控(Quality Control, QC)是生信流程中「投入产出比最高」的一步。原始测序数据里混杂着接头、低质量碱基、PCR 重复、污染序列,如果不加处理直接比对,轻则比对率下降、假变异增多,重则整个分析结论被技术噪声主导。更关键的是,质控发现问题往往能反推出上游的建库或测序问题——这是排查事故的第一现场。

但质控也最容易「过度」或「不足」。过度剪裁会丢掉真实的生物学信号(比如把真实的低复杂度区域当成污染剪掉),不足则让噪声流入下游。判断「剪到什么程度合适」,需要理解每个指标背后的含义,而非机械地套用阈值。这正是本文要解决的核心问题。

工程上,质控脚本有三个典型陷阱:一是硬编码阈值,换个物种、换个测序平台就失效;二是只跑 FastQC 出个 HTML 报告却无人解读,报告沦为摆设;三是质控与下游脱节——剪裁后的数据没有重新验证,不知道剪裁是否有效。本文会给出可复用的配置与「质控 → 验证」的闭环做法。

质控是 测序原理与数据产出 之后的第一道工程关口,也是 SAM/BAM 与 samtools 里那些质量指标的上游来源。理解它们的衔接关系,才能判断「一个低比对率到底是质控没做干净,还是别的原因」。

本文按「指标解读 → 接头识别 → 工具实战 → 剪裁策略 → 去重与污染 → 下游衔接」的顺序展开。所有命令与阈值都基于 fastp 0.23.x 与 FastQC 0.12.x,面向有经验的工程师,重点讲清「为什么这么设」。

目录

  1. 质控的目标与核心指标
  2. FastQC 报告逐项解读
  3. 接头与污染序列识别
  4. fastp 实战配置详解
  5. 质量剪裁:滑窗与全局策略
  6. 去重、UMI 与分子计数
  7. 双端数据的同步处理
  8. 污染检测与去污染
  9. 质控与下游流程的衔接

1. 质控的目标与核心指标

质控要回答四个问题:数据够不够(数量)、干不干净(质量)、有没有污染(来源)、能不能用(适配下游)。对应的核心指标:

指标含义健康范围异常含义
总读段数数据量按深度需求不足需补测
Q30 比例高质量碱基占比≥ 85%测序或试剂问题
GC 含量GC 碱基比例与物种匹配污染或偏倚
接头含量含接头读段比例< 5%片段过短
重复率PCR 重复读段比例随深度变化循环过多/输入量低
N 碱基比例无法识别的碱基< 1%测序失败

这里有个重要的认知:指标的「健康范围」依赖于场景。同样是 30% 的重复率,在全基因组测序里是正常的(高深度必然有随机重复),在单细胞数据里可能提示严重问题(细胞数少、扩增过度)。所以不要背死阈值,而要理解「什么导致了它」。

以 GC 含量为例。人类基因组平均 GC 约 41%,如果样本 GC 显示 60%,可能有两种解释:一是样本来自高 GC 物种(如某些细菌),这是正常的;二是样本被高 GC 的污染物(如支原体)污染。区分方法是看 GC 分布的形状——正常样本是单峰且与理论分布吻合,污染会呈现双峰或偏移。

2. FastQC 报告逐项解读

FastQC 是质控的事实标准,输出 11 个模块的 HTML 报告。逐个模块的解读要点:

fastqc -t 8 -o qc/ sample_R1.fastq.gz sample_R2.fastq.gz
# 批量处理
fastqc -t 8 -o qc/ *.fastq.gz
# 汇总多个报告(推荐)
multiqc qc/ -o qc/multiqc_report.html

Per base sequence quality(每碱基质量):最重要的一张图。横轴是读段位置,纵轴是质量值。健康数据应该是「两端低、中间高」的平缓曲线。如果整条曲线在某个位置断崖式下跌,说明该循环测序失败(常见于读长过长或试剂耗尽)。

Per sequence quality scores(每读段质量):读段平均质量的分布。正常应该是单峰且偏向高分。如果出现明显的低质量峰,说明有大量读段整体质量差。

Per base sequence content(每碱基组成):A/T/C/G 的比例随位置变化。健康数据前几个碱基可能有波动(随机引物偏好),之后应稳定在 25% 附近。如果整条读段严重偏离,可能是污染或文库问题。

Adapter content(接头含量):随读段位置累积的接头比例。读段末端接头含量升高是正常的(短片段读完样本后读到接头),但如果从读段开头就高,说明片段极短,建库严重失败。

Sequence duplication levels(序列重复水平):重复读段的比例。高重复可能来自 PCR 过度扩增(应去重)或高表达基因(RNA-seq 中正常)。FastQC 默认只统计前 100k 读段,对高深度数据会高估重复率,需注意。

Overrepresented sequences(过表达序列):出现频率异常的序列。可能是接头、rRNA、或高丰度基因。这是发现污染的第一线索。

解读报告的关键心态是「看模式而非看红叉」。FastQC 会给每个模块标红/黄/绿,但这些标记的阈值是通用的,对某些场景(如 RNA-seq 的 GC 偏倚、长读数据)会误报。有经验的工程师会结合物种、文库类型、下游用途综合判断。

3. 接头与污染序列识别

接头(adapter)是最常见的「污染物」,也是最好处理的。识别接头的方法是「找读段末端的固定序列」:

Illumina TruSeq 接头(部分):
  Read1 adapter: AGATCGGAAGAGCACACGTCTGAACTCCAGTCA
  Read2 adapter: AGATCGGAAGAGCGTCGTGTAGGGAAAGAGTGT
  通用核心:      AGATCGGAAGAGC

Nextera 接头: CTGTCTCTTATACACATCT

如果 FastQC 的 Overrepresented sequences 里出现 AGATCGGAAGAGC 开头的序列,基本可以确定是接头污染。处理方式有两种:

  1. 自动检测 + 剪裁:fastp 默认启用接头自动检测,会比对已知接头库并剪除。
  2. 显式指定序列:非标准建库试剂盒需要手动提供接头序列。
# fastp 显式指定接头序列(非标准试剂盒)
fastp -i in.fq -o out.fq \
  --adapter_sequence AGATCGGAAGAGCACACGTCTGAACTCCAGTCA \
  --adapter_sequence_r2 AGATCGGAAGAGCGTCGTGTAGGGAAAGAGTGT

除接头外,还有几类「非接头但需处理」的序列:

  • Poly-G / Poly-A:NovaSeq 的 two-color 化学在信号缺失时会读成 G,导致读段末端出现连续 G。fastp 用 --trim_poly_g 处理。
  • Poly-X:某些平台或文库会有连续相同碱基,--trim_poly_x 处理。
  • rRNA 序列:RNA-seq 中未去除的核糖体 RNA,占比可能高达 50%,需在建库时用 rRNA depletion 或分析时过滤。

判断「剪多少」有个实用原则:剪到固定序列消失为止,但保留读段至少 30 bp。太短的读段比对不上(会被比对工具丢弃),剪得太狠反而浪费数据。fastp 的 --length_required 30 就是干这个的。

4. fastp 实战配置详解

fastp 是当前最主流的 FASTQ 预处理工具(C++ 实现,比 Trimmomatic 快数倍,且自带报告)。一个生产级配置:

fastp \
  -i sample_R1.fastq.gz -I sample_R2.fastq.gz \
  -o clean_R1.fastq.gz  -O clean_R2.fastq.gz \
  --detect_adapter_for_pe \
  --cut_front --cut_tail --cut_window_size 4 --cut_mean_quality 20 \
  --qualified_quality_phred 15 \
  --unqualified_percent_limit 40 \
  --n_base_limit 5 \
  --length_required 36 \
  --trim_poly_g \
  --dedup \
  --thread 8 \
  --json sample.fastp.json --html sample.fastp.html \
  2> sample.fastp.log

逐参数解释:

参数作用取值建议
--detect_adapter_for_pe双端接头自动检测PE 数据必开
--cut_front / --cut_tail从两端滑窗剪裁低质量配合窗口与均值阈值
--cut_window_size 4滑窗大小4 是默认,够用
--cut_mean_quality 20窗口平均质量阈值20(Q20)起步
--qualified_quality_phred 15单碱基合格线15(Q15)
--unqualified_percent_limit 40允许低质量碱基比例40%
--length_required 36最短保留长度36-50 bp
--dedup去重高深度 WGS 慎用

--dedup 需要特别注意:它会直接删除重复读段,而下游 picard MarkDuplicates 需要「标记」而非删除(因为某些重复是真实的生物学信号,如高覆盖的扩增子)。所以常规 WGS 流程不应在 fastp 阶段去重,而是留给 Picard 标记。只有在不需要考虑生物学重复的场景(如快速筛查)才用 --dedup。

另一个关键参数是 --qualified_quality_phred(默认 15)。这是「单个碱基是否算合格」的阈值,与 --unqualified_percent_limit(一条读段里不合格碱基的比例上限)配合:一条读段中超过 40% 的碱基低于 Q15,则整条丢弃。这两个参数的组合决定了「激进」还是「保守」。

5. 质量剪裁:滑窗与全局策略

质量剪裁(trimming)的核心是「在哪个位置切」。两种主流策略:

全局阈值(global):从两端逐碱基检查,遇到第一个低于阈值的碱基就切掉。简单但激进——一个孤立的低质量碱基会导致后面全被切掉,即使后面质量又变好了。

滑窗(sliding window):在窗口内计算平均质量,平均低于阈值才切。fastp 的 --cut_front/--cut_tail 就是滑窗。它更平滑,不会因为单个碱基波动就大段剪裁。

读段质量:  Q35 Q38 Q40 Q12 Q39 Q40 Q41 ...
全局策略:  ────────────┘ 从 Q12 处切断(后面全丢)
滑窗(4):   窗口[Q38,Q40,Q12,Q39]均值=32 > 20,保留;继续滑动

实践建议:

  1. 默认用滑窗(--cut_front --cut_tail),它对绝大多数数据都稳健。
  2. 只在读段末端质量崩塌时加大力度:如果 FastQC 显示末端质量 < Q20,可以调低 --cut_mean_quality 或增加 --cut_tail_window_size。
  3. 不要盲目追求「全 Q30」:强行剪到只剩高质量区,会损失大量数据且引入位置偏倚(所有读段都从同一位置开始)。质量值与比对工具是配合的,Q20 的碱基在比对中仍有价值。

还有一个常被忽略的剪裁:前几个碱基的处理。Illumina 读段前 1-3 个碱基常因随机引物而有组成偏倚,--cut_front 会处理。但如果数据本身没问题,强行剪前几碱基反而丢失信息。

剪裁效果的验证方法是「剪裁后再跑一次 FastQC」:看质量曲线是否变平、接头是否消失、总读段数损失多少。如果损失超过 20%,需要重新评估阈值是否过严。

6. 去重、UMI 与分子计数

去重(deduplication)处理的是 PCR 扩增引入的「伪重复」:同一个原始 DNA 分子被扩增成多个拷贝,测序后看起来像「多个分子」。如果不处理,会虚高覆盖度并产生假变异(一个错误被复制成「多数票」)。

两种去重时机:

工具时机方式适用
fastp --dedup比对前按序列精确匹配删除快速筛查
picard MarkDuplicates比对后按坐标+方向标记标准 WGS
samtools markdup比对后按坐标标记(更快)高通量
umi_tools dedup比对后按 UMI 分组低输入/单细胞

为什么标准流程在比对后去重? 因为比对前的「序列完全相同」不等于「来自同一分子」——高覆盖区可能有多个真实的相同片段。比对后结合坐标、方向、CIGAR 一起判断,准确性更高。

UMI(Unique Molecular Identifier) 是低输入量场景的关键。建库时给每个原始分子加上一段随机序列(如 8-12 bp),扩增后即使有多个拷贝,它们的 UMI 也相同,可以据此合并计数:

# UMI 处理三步:提取 → 比对 → 按 UMI 去重
umi_tools extract --bc-pattern=NNNNNNNNNN --stdin in.fq --stdout umi.fq
# ... 比对到 BAM ...
umi_tools dedup -I aln.bam -S dedup.bam --output-stats=umi_stats

UMI 的工程细节:UMI 本身也可能有测序错误,所以 umi_tools dedup 默认允许 1 个碱基的 UMI 差异(--edit-distance-threshold 1)来合并「同一分子的错误 UMI」。这个阈值的设置需要权衡——太大(如 2)会把不同分子错误合并,太小则同一个分子被拆成多个。

7. 双端数据的同步处理

双端(PE)数据的质控有一个铁律:R1 和 R2 必须同步。如果对 R1 剪了 10 个碱基而对 R2 没剪,两条读段的坐标就错位了,比对时会产生错误的插入片段长度,甚至比对失败。

错误做法(不同步):
  R1: ATCGATCGATCG----      (剪掉末端 4 个)
  R2: TTTTGGGGCCCCAAAA      (未剪)
  → R1 和 R2 长度不等,坐标错位

正确做法(fastp 自动同步):
  R1: ATCGATCG----
  R2: TTTTGGGG----          (同一位置同步剪裁)

fastp 对 PE 数据会自动同步剪裁,这是它的核心优势之一。但要注意几个细节:

  • --detect_adapter_for_pe:PE 接头检测比 SE 复杂,因为接头可能在 R1 末端、R2 末端或两者都有。这个参数让 fastp 从两端互相验证。
  • --unpaired 输出:当一条读段被丢弃而另一条保留时,剩下的「孤儿读段」默认会被丢弃(因为无法配对)。可以输出到 --unpaired 文件,用于某些不需要配对的场景(如组装)。
  • 读段顺序一致性:剪裁后的 FASTQ 中,R1 和 R2 的读段顺序必须严格对应。fastp 保证这一点,但自己写脚本时容易出错。

对于 Trimmomatic 用户,对应的是 PE 模式加 -baseout 参数;但 fastp 的接口更简洁且更快,新项目建议直接上 fastp。

8. 污染检测与去污染

污染(contamination)比接头更隐蔽,也更危险。常见来源:

  • 交叉污染:多样本混测时 index 串扰,或实验室操作污染;
  • 微生物污染:细胞系被支原体(Mycoplasma)污染是细胞实验的经典问题;
  • 人源污染:小鼠样本混入人 DNA(或反之);
  • 环境 DNA:低生物量样本(如空气、水)容易被环境微生物主导。

检测方法:

# 方法1:提取未比对上的读段,做物种分类
samtools view -f 4 aln.bam | awk '{print $10}' > unmapped.fa
# 用 Kraken2 分类
kraken2 --db standard --report report.txt unmapped.fa

# 方法2:用 FastQ Screen 快速筛查
fastq_screen --conf fastq_screen.conf sample.fastq.gz

FastQ Screen 的思路很巧妙:把样本读段同时比对到多个参考基因组(人、小鼠、细菌、真菌、病毒等),看有多少读段匹配到「不应该匹配」的物种。如果人类样本有 30% 的读段匹配到大肠杆菌,说明有严重污染。

支原体检测是细胞系实验的必查项。支原体基因组小(约 0.6-1.4 Mb),污染后会在数据里留下低比例但稳定的读段。可以用专门的工具(如 MycoSNP)或直接比对到支原体参考基因组检测。

去污染的策略取决于污染程度:

污染比例策略
< 5%记录,忽略(不影响结论)
5-30%比对后过滤污染读段(如 samtools view 排除污染 contig)
30-70%分析结果需谨慎,重新建库
> 70%数据不可用,必须重做

关键原则:污染检测应在流程早期做,而不是结果出来才发现。把 FastQ Screen 或 Kraken2 作为流程的可选步骤,能及早暴露问题。

9. 质控与下游流程的衔接

质控不是孤立的步骤,它的输出直接影响下游。几个必须衔接好的点:

一是「剪裁参数与比对参数」的配合。如果剪裁去掉了读段末端,比对工具就不该再对末端做宽松处理;反之亦然。例如 BWA-MEM 的 -T(最小比对得分)与剪裁强度需要匹配——剪得太狠导致读段变短,可能过不了比对阈值而被丢弃。

二是「质量值过滤的重复」。质控阶段已经过滤了低质量碱基,下游再用严格的 -q 过滤一遍,是重复劳动且可能过度。建议把质量过滤集中在质控阶段,下游用宽松阈值(如 samtools view -q 10)兜底即可。

三是「QC 指标的传递」。剪裁后的数据必须重新验证:

# 质控闭环:剪裁后重新评估
fastqc -o qc_after/ clean_R1.fastq.gz
multiqc qc/ qc_after/ -o multiqc_combined.html

# 关键对比:剪裁前后
#   - 总读段数:损失比例(应 < 20%)
#   - Q30 比例:是否提升
#   - 接头含量:是否归零
#   - 读长分布:是否出现异常截断

一个成熟的流程会把「质控报告」作为流程的产出物之一,与比对率、覆盖度等指标一起汇总到 MultiQC,形成样本级的质量档案。这样当某个样本的分析结果异常时,可以回查它的 QC 历史。

最后给一组「质控通过」的参考基线(人类 WGS,PE150):

Q30 比例        ≥ 85%
接头污染        < 5%
比对率          ≥ 95%(BWA-MEM)
重复率          < 20%(30x)
平均覆盖深度    ≥ 30x
覆盖均匀性      90% 位点 ≥ 10x

达不到这些基线时,先排查原因,而非硬着头皮往下跑。

权衡取舍

决策点方案 A方案 B建议
剪裁策略滑窗(平滑)全局(激进)默认滑窗,末端崩塌时调参
去重时机比对前(快)比对后(准)标准 WGS 比对后,UMI 场景专用
质量阈值严格(Q30)宽松(Q20)按下游容错度定,勿一刀切
污染处理过滤读段重做实验< 30% 过滤,> 30% 重做
工具fastp(快、全)Trimmomatic(老牌)新项目用 fastp
报告单样本 HTMLMultiQC 汇总批量项目必用 MultiQC

常见坑清单

  1. R1/R2 剪裁不同步:手动脚本只处理一条,导致坐标错位;用 fastp 的 PE 模式自动同步。
  2. fastp 阶段误去重:--dedup 删除了需要下游标记的重复;标准 WGS 交给 Picard。
  3. 阈值硬编码:把人类参数用到植物/微生物上,剪裁过度或不足;按物种与文库类型调参。
  4. 只看红叉不看模式:FastQC 的通用阈值对特殊场景误报;结合场景解读曲线形状。
  5. 忽略 Poly-G:NovaSeq two-color 化学的 Poly-G 未处理,导致末端质量虚低;开 --trim_poly_g。
  6. 剪裁后不验证:不知道剪掉了多少、效果如何;剪裁后重跑 FastQC 对比。
  7. 读段剪得过短:--length_required 设得太高,大量读段被丢;一般 36-50 bp 即可。
  8. 忽略污染筛查:结果异常才发现污染;把 FastQ Screen/Kraken2 纳入早期流程。
  9. UMI 阈值不当:edit distance 设太大合并了不同分子,太小则拆分同一分子;默认 1 通常合适。
  10. QC 指标不落盘:样本质量信息丢失,事后无法追溯;用 MultiQC 汇总并归档。

小结

FASTQ 质控的价值不在于「跑了几个工具」,而在于「理解了数据的健康状态并据此做决策」。FastQC 帮你看见问题,fastp 帮你处理问题,而「剪到什么程度」的判断来自对下游用途的理解——这是工具无法替代的部分。

工程上最该建立的习惯是「质控闭环」:原始数据 QC → 剪裁 → 剪裁后 QC → 指标归档。没有验证的剪裁等于没做剪裁,因为你不知道它是否有效、是否过度。把 QC 报告作为流程的标准产出,与样本元数据一起保存,是排查问题时的第一手资料。

下一步是 序列比对 ——干净的数据进入比对环节,你会看到质控的质量如何直接决定比对率与后续分析的可信度。如果你的数据质量指标异常,先别急着调比对参数,回头看看质控这一环是否还有空间。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「生物信息」更多文章

  1. 多组学整合与批次效应
  2. 蛋白质组学与质谱分析
  3. 变异注释与临床解读