4. Per tile sequence quality 模块详解与阈值设定
这个模块,很多人一开始容易忽略。它看的是测序芯片上每个小格子(tile)的质量波动。说白了,就是检查你的测序反应在芯片上是不是均匀的。万一某个区域出了毛病,整条lane的数据都会被拖累。
我自己刚接触FastQC时,看到那个花花绿绿的热图,第一反应是“挺好看的”。直到有一次,一个样本的tile质量热图出现了一条明显的红色竖条,对应的文库测序深度就是偏低。从那以后,我每次质控都会盯着这个模块看几秒。
4.1 热图怎么看
FastQC会给每个flow cell生成一张热图。横轴是文库位置(通常从左到右),纵轴是tile编号(从上到下)。颜色代表每个tile的平均质量偏离全局平均值的程度。
- 蓝色/绿色:该tile质量高于平均水平。
- 黄色/橙色:略低于平均,通常可接受。
- 红色:显著偏低,需要警惕。
你可能会问:为什么有的热图整体偏蓝?那是因为大部分tile质量都很好,少数差的被压下去了。我这里有个经验:如果整个热图颜色均匀,深浅差异小,基本没问题。但要是出现成片红色或一条红色竖线/横线,那就得仔细查原因了。
4.2 常见问题根因
我总结了几种常见场景,你对照一下就能快速定位。
| 热图表现 | 可能原因 | 严重程度 |
|---|---|---|
| 某一行tile整体偏红 | 该tile的孔道堵塞或表面污染 | 中 |
| 出现一条垂直红色带 | 液流不均匀,某个通道局部失效 | 高 |
| 边缘一圈偏红 | 边缘效应(即“边缘气泡”) | 低(可容忍) |
| 随机散布红点 | 单tile随机故障 | 低 |
记得有一次我处理一个RNA-seq项目,热图中间出现了一条很窄的红色竖线。我一开始以为是偶然,后来发现那条竖线正好对应着某个文库的index区域,导致该样本的barcode识别成功率下降。所以,别小看这种细微的线索。
4.3 默认阈值 vs. 我常用的调整值
FastQC官方的默认阈值是这样设定的:
# 默认参数(嵌入式,不可直接修改)
# fastqc 默认将“平均偏差超过2”标记为warning
# 将“平均偏差超过3”标记为failure
# 这里的“平均偏差”是指每个tile的平均质量得分与所有tile均值的差值
但在实际项目中,我发现这个阈值有点太松。尤其是在高深度测序(比如≥50X的WGS)中,单个tile的偏差即使只有1.5,也可能导致下游变异检测的假阳性。所以我建议:
- 严谨项目:warning设为1.5,failure设为2.5。
- 常规项目:保持默认的2/3,但禁止出现成片红色区域。
- 单细胞RNA-seq:由于UMI矫正,公差可以放宽,warning 2.5,failure 3.5。
下面是一个示例YAML配置:
# tile_quality_config.yaml
thresholds:
warning: 1.5
failure: 2.5
flags:
reject_if_red_cluster: true
cluster_size: 3 # 连续3个tile以上才算cluster
output_dir: "qc_reports"
然后配合一个简单的Python脚本去解析:
import yaml
import re
with open("tile_quality_config.yaml") as f:
config = yaml.safe_load(f)
# 读取fastqc_data.txt中的tile质量行
with open("sample_fastqc/fastqc_data.txt") as f:
lines = f.readlines()
in_tile_section = False
tile_data = []
for line in lines:
if line.startswith(">>Per tile sequence quality"):
in_tile_section = True
continue
if in_tile_section and line.startswith(">>END_MODULE"):
break
if in_tile_section and line.strip() and not line.startswith("#"):
parts = line.strip().split("\t")
if len(parts) >= 3:
tile_data.append({
"flowcell": parts[0],
"tile": parts[1],
"mean_deviation": float(parts[2])
})
warn_tiles = [t for t in tile_data if t["mean_deviation"] > config["thresholds"]["warning"]]
fail_tiles = [t for t in tile_data if t["mean_deviation"] > config["thresholds"]["failure"]]
print(f"Warning tiles: {len(warn_tiles)}")
print(f"Failure tiles: {len(fail_tiles)}")
4.4 阈值设定决策流程图
下面这张图是我自己总结的决策逻辑,帮助你快速判断该tile模块是pass还是需要干预。
4.5 避坑指南与我的个人习惯
最后,说几个容易踩的坑。
- 别把热图当唯一依据。颜色映射范围是自动的,如果整体质量都很高,微小的偏差也会显示为红色。所以一定要结合数值看。
- 不同测序平台宽容度不同。Illumina的tile质量通常很稳定,红色很少见;而华大(BGI)的芯片偶尔会有区域偏差,阈值可以放宽0.5。
- 复测样本慎重处理。如果同一个样本在两个批次中tile质量差异很大,那大概率是实验操作问题,不是文库本身问题。
嗯,模块讲完了。总结一下:Per tile sequence quality这个模块,核心是看空间均匀性。阈值要根据项目目的、测序平台、文库类型灵活调整。别死守默认值,也别过度解读。用一个简单的脚本把数值提出来,画个分布图,比盯着热图靠谱得多。