一、FASTQ 文件格式简介与结构
好,咱们直接切入正题。FASTQ 这个格式,在生物信息领域几乎天天见。我第一次接触它的时候,感觉就是一堆乱码混着字母。但后来被一个项目坑过——解析错了质量行,导致下游变异检测全翻车。从那以后,我养成了一个习惯:拿到 FASTQ 文件,第一件事就是确认它的结构是否标准。实际上,它比你想象的要简单,就四个部分。
1.1 什么是 FASTQ?为什么要懂结构?
FASTQ 是目前高通量测序数据存储的通用格式。说白了,它就是一条测序片段 + 它的质量信息。你想想看,如果没有质量值,我怎么知道你这条序列是真实信号还是噪声?
每条记录固定由四行组成。我建议你记住这个模板,很多麻烦都能避免。
@SEQ_ID
GATTTGGGGTTCAAAGCAGTATCGATCAAATAGTAAATCCATTTGTTCAACTCACAGTTT
+
!''*((((***+))%%%++)(%%%%).1***-+*''))**55CCF>>>>>>CCCCCCC65
看到没?第一行以 @ 开头,第二行是碱基序列,第三行是 + 分隔符(有时后面也跟ID),第四行就是核心的质量行。这四行是一条完整的记录。
1.2 标识行(Header)解析:比想象中重要
标识行,也就是第一行。这行里藏着很多元数据。我习惯把它拆成几段来看。比如上面例子中的 @SEQ_ID,实际场景里会复杂得多。
先看一个 Illumina 平台典型的标识行:
@EAS139:136:FC706VJ:2:2104:15343:197393 1:Y:18:ATCACG
这一串用冒号分隔的字段,每一个都有具体含义。我来拆解一下:
| 字段序号 | 示例值 | 含义 |
|---|---|---|
| 1 | EAS139 | 仪器名称 / ID |
| 2 | 136 | 测序运行编号 |
| 3 | FC706VJ | 流动槽 ID |
| 4 | 2 | 泳道号 |
| 5 | 2104 | Tile 编号(芯片上小区域) |
| 6 | 15343 | X 坐标 |
| 7 | 197393 | Y 坐标 |
| 8 | 1:Y:18:ATCACG | Pair info + filter flag + 索引 |
我个人的习惯是,在清理 FASTQ 文件前,先用 head -n 4 看一下标识行的格式,确定是谁家的数据。有一次我在一个公共数据集里发现标识行里居然混了换行符,差点把样本混淆了。从那以后,我每次跑流程之前都会加一步标识行格式校验。
1.3 碱基序列行:不仅仅是 ATCG
第二行是序列,标准字符包括 A、T、C、G、U 以及代表简并碱基的 N。这里要注意,U 在 RNA 测序中常见,DNA 测序里如果出现大量 U,大概率是实验污染或数据错误。记得我接手过一个 plant RNA-seq 项目,序列行里 N 超过了 30%,其实就是文库质量太差,但我花了两天时间去排查流程配置问题……
序列行长度在不同平台有差异:
| 平台 | 典型读长 | 备注 |
|---|---|---|
| Illumina 短读 | 150 bp | 双端常见 |
| PacBio Hifi | 10-30 kbp | 长读长 |
| Nanopore | 可变,通常 >10 kbp | 最长可超 2 Mbp |
1.4 质量评分行:最容易出问题的部分
第四行是质量行,每个字符对应序列行每个位置的质量值。你肯定会问:“那个感叹号、星号、加号是什么意思?”嗯,说白了就是ASCII 码转换后的 Phred 质量分数。
质量行的字符数与序列行必须完全一致。我遇到过最坑的一次是,一个工具在 trim 的时候没同步处理质量行,序列和质量的长度差了 1 个 bp,结果解析器直接报错。所以检查 序列长度 == 质量行长度 是基本操作。
有两种常见的质量编码方案,搞混了就是灾难:
| 编码标准 | ASCII 起始值 | Phred 范围 | 常见场景 |
|---|---|---|---|
| Phred+33 | 33 ('!') | 0 - 40 | Illumina 1.8+ |
| Phred+64 | 64 ('@') | 0 - 40 | 旧版 Illumina / Solexa |
我早期的一个教训:从 SRA 下载的旧数据集,质量行开头是 'B'(ASCII 66),我却当成 Phred+33 来解,导致所有质量值都偏差了 31。最终下游组装一塌糊涂。记得每次打开文件前,先扫一眼质量行前几个字符的 ASCII 值。
- 确认 @ 或 + 开头正确
- 序列行是否只含 ATCGUN
- 序列行长度 == 质量行长度
- 质量行前几个字符的 ASCII 值是否 ≥ 64(判断编码)
结构清楚了,后面的事情才好办。特别是做元数据嵌入文件命名那些操作,你对原始格式越熟悉,遇到异常情况就越快定位。好,这部分内容就到这儿。接下来我要给你讲的是如何通过文件名系统性地绑定元数据——嗯,那才是真正提升可复现性的第一步。