4. 质控数据格式:FASTA、FASTQ、GFF3、GTF、BED、VCF 等格式介绍

做基因组注释质控,第一件事就是搞清楚你在跟什么格式打交道。我这些年批过不少批次数据,发现一大半问题都出在格式理解上——不是字段弄反了,就是坐标搞乱了。说白了,这些格式就像不同工种用的工具:你不能拿扳手去拧螺丝刀。下面我把最常用的六种格式捋一遍,结合我踩过的坑,给你讲清楚。

一句话总结:FASTA 存序列,FASTQ 存序列+质量,GFF3/GTF 存基因结构,BED 存区间,VCF 存变异。各格式之间经常互相转换,但坐标系、字段定义、索引要求不同,容易出错。

4.1 FASTA —— 序列的基础盘

FASTA 是最简单的序列格式。一行头(以 > 开头),后面跟着碱基或氨基酸序列。没有质量值,没有额外属性。

>chr1
ACGTACGTACGTACGTACGTACGTACGT
>chr2
TGCATGCATGCATGCATGCATGCATGCA

我个人习惯:拿到 FASTA 第一件事先跑 seqkit stat,看看每条染色体的长度、N 含量。为什么?因为很多组装出来的 FASTA 有大量未解开的 N,会影响比对和注释。

小技巧:用 seqkit grep -n -r -p "^>chr" 提取染色体主链,排除 scaffold 或 contig,可以加速后续分析。

还有一个坑:FASTA 里换行长度不统一。有些工具要求每行 80 个碱基,有些接受任意长度。我遇到过把 60bp 一行的 FASTA 喂给 bwa mem,它其实能处理,但换行不一致时 samtools faidx 会报错。所以建索引前最好做一遍 seqkit seq -w 80 重新格式化。

小心:FASTA 的描述行不能有空格?不,> 后的所有内容都是描述,有些软件会解析空格后的字段。比如 >chr1 length=1000,某些工具会把它识别成不同的 ID。建议统一用下划线或冒号分隔。

4.2 FASTQ —— 质量就在名字里

FASTQ 和 FASTA 长得像,但多了质量行。每一组有四行:@头、序列、+头(可省略)、质量值。

@EAS139:136:FC706VJ:2:2104:15343:197393
GTATCATCATAAGTACCTGCGACATACTCATTCTAA
+
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII

质量值那一行最容易被忽略。我曾经处理一批 RNA-seq 数据,FASTQ 看起来正常,结果比对率只有 30%。拿 fastqc 一测,发现质量值编码是 Sanger,而比对器却按 Illumina 1.3 去解释,结果质量全部偏高。嗯,这里要注意:质量编码方式必须在头信息或元数据里注明。常用的有三种:

编码方式 质量范围 ASCII 偏移 常见于
Sanger / Phred+33 0–40 33 Illumina 1.8+, SRA
Illumina 1.3+ / Phred+64 0–40 64 早期 Illumina
Solexa / Solexa+64 −5–40 64 更早期的 Solexa
避坑:我遇到过一批 FASTQ 文件,头信息写的是 Illumina 1.8,实际质量值却是 Phred+64。用 seqtk trimfq 时没指定编码,结果低质量碱基没过滤掉。所以上游拿到数据后,第一件事用 fastqc 或 seqtk fqchk 确认编码。

4.3 GFF3 —— 注释的“本体”格式

GFF3 是目前最通用的基因注释格式。每行 9 列,以 tab 分隔。第 9 列是属性,可以嵌套多个键值对。

chr1    .       exon    1000    1200    .       +       .       ID=exon1;Parent=transcript1
chr1    .       CDS     1100    1200    .       +       0       ID=cds1;Parent=transcript1

我个人觉得 GFF3 比 GTF 更灵活。属性里可以放 ID、Parent、Name、Note 等,而且支持双向关联。但这也带来一个麻烦:属性之间的引用关系必须严格一致。如果某个 exon 的 Parent 指向一个不存在的 transcript,整个注释文件就废了。

检查命令:gff3check --full path/to/your.gff3 或者用 agat_sp_statistics.pl。我习惯在批次质控里先跑一遍 stat,看看基因数、转录本数、外显子数是否在合理范围。

另一个常见错误:坐标系统。GFF3 是 1-based,而且区间是闭区间。例如起始 1000,结束 1200,包含第 1000 和第 1200 两个碱基。而 BED 是 0-based 半开区间。两者转换时经常差 1,我在这上面吃过亏。

4.4 GTF —— 比 GFF3 更“严”

GTF(也叫 GFF2)格式,和 GFF3 很像,但第 9 列的属性必须用 gene_id 和 transcript_id 开头。其他属性和 GFF3 不一样,不能用 Parent,而是用 transcript_id 来关联 exon 和 CDS。

chr1    .       exon    1000    1200    .       +       .       gene_id "gene1"; transcript_id "t1";
chr1    .       CDS     1100    1200    .       +       0       gene_id "gene1"; transcript_id "t1";

我建议:如果上游工具明确要求 GTF,那就用 GTF;否则优先用 GFF3。为什么?因为 GTF 的参数更少,很多物种特有属性(如 UTR 类型、生物类型)很难塞进去。而且某些比对器(如 STAR)原生支持 GTF,但如果你给它一个 GFF3,它会认错 exon_number 之类的字段。

注意:GTF 对引号有严格要求——属性值必须被双引号包围(如 gene_id "ENSG000001")。而 GFF3 不需要引号。如果你从 GFF3 转 GTF,一定要用 gffread 来做,别手写 sed。

4.5 BED —— 轻量化区间工具

BED 文件最少只需要 3 列:染色体、起始、结束。起始是 0-based,结束是 1-based(半开区间)。经常用于 ChIP-seq peaks、覆盖度统计等。

chr1    1000    2000    peak1    42    +
chr1    3000    3500    peak2    18    -

我最常用的是 BED 的第六列(链方向)、第七列(thickStart)、第八列(thickEnd)、第九列(itemRGB)。不过说实话,质控时最要紧的是检查 起始 < 结束 和 坐标在染色体长度范围内。我之前用 bedtools intersect 时,遇到过一个 BED 文件第 1 行 0-10,但染色体长度才 5,结果跑出来一堆负数长度,导致程序崩溃。

命令:bedtools intersect -a query.bed -b reference.bed -wa -u 可以快速查重叠情况。质控时我一般还会用 sort -k1,1 -k2,2n 先排序,避免 bedtools 报错。

4.6 VCF —— 变异的详细档案

VCF 是存储单核苷酸变异、插入缺失、结构变异的通用格式。头部分行以 ## 开头,数据行 8 列 + 样本列。第 8 列 INFO 字段有很多预定义标志(如 DP、AF、QS)。

##fileformat=VCFv4.2
#CHROM  POS     ID      REF     ALT     QUAL    FILTER  INFO
chr1    1000    .       A       G       30.0    PASS    DP=50;AF=0.25
chr1    2000    rs1234  T       C       99.0    PASS    DP=120;AF=0.5

VCF 质控最容易出问题的点:FILTER 列。很多 VCF 会把所有位点都标记为 PASS,但实际质量很差。我见过一个 VCF,里面 90% 的位点支持深度只有 3,但 FILTER 列全是 PASS,因为过滤条件写得太宽松。所以做批次质控时,我习惯按 DP>=10 && QUAL>=30 && MQ >= 40 先硬过滤一波。

重要:VCF 坐标是 1-based,和 GFF3 一致。但插入缺失的 POS 记录的是第一个变异碱基之前的位置。比如插入 AG,参考序列是 A,那么 POS=1000,REF=A,ALT=AG。这个规则很多新手会搞错,我也是写了一个脚本才发现坐标对不上的。

4.7 各格式核心区别一览

格式 坐标系统 区间类型 是否含质量 是否含序列 典型应用
FASTA 1-based(隐含) 单碱基 否 是 参考基因组建索引
FASTQ 1-based(隐含) 读长 是(Phred) 是 原始测序数据
GFF3 1-based,闭区间 基因、外显子、CDS 否 否 完整注释
GTF 1-based,闭区间 同上 否 否 比对器(STAR、TopHat)
BED 0-based,半开 区间 否 否 ChIP-seq peak、覆盖度
VCF 1-based 单位点 是(QUAL) 否 变异检测与注释

4.8 格式间的“说话”方式:转换与质控流程

我画了一张图,把六种格式放在一个工作流里,你看看它们是怎么串起来的:

常见基因组注释质控数据格式流转关系 FASTA 参考基因组序列 FASTQ 原始reads(含质量) BAM/SAM 比对后的中间结果 BED peak/覆盖度区间 GFF3 / GTF 基因结构注释 VCF 变异位点 比对 比对 peak calling 转录本组装 变异检测 注释 说明:BAM 不是本章重点,但它连接了原始数据与三种下游格式:BED、GFF3/GTF、VCF。

看到没?FASTA 和 FASTQ 是输入,比对后变成 BAM(二进制 SAM),然后再根据你的目的生成 BED、注释(GFF3/GTF)或 VCF。质控需要贯穿全程:上游 FASTQ 质量不行,下游 VCF 就不准;参考基因组 FASTA 有错,注释的 GFF3 坐标就全跑偏。

我的批次质控习惯:
  • 每个批次先检查 FASTA 完整性(seqkit stat)和 FASTQ 质量分布(fastqc)。
  • 比对后检查 BAM 的 mapping rate 和 insert size 分布。
  • 产出的 GFF3 用 gff3check 做结构完整性校验,BED 用 bedtools complement 检查染色体边界,VCF 用 bcftools stats 统计 variant density。
  • 最后所有格式的染色体命名必须统一,否则一切交集都是空集。