1. GFF/GTF 格式概述与区别归纳总结
做基因组分析的朋友,一定绕不开 GFF 和 GTF。这两个格式就像一对双胞胎,长得像,但性格不同。我刚入行那会儿,就因为这俩格式混用,把一个流程跑出了莫名其妙的错误,排查了整整一天。嗯,从那天起我就养成了一个习惯——拿到注释文件先看一眼是 GFF 还是 GTF。
说白了,GFF 是通用特征格式(General Feature Format),GTF 是基因转移格式(Gene Transfer Format)。它们都用来描述基因组上的注释信息——基因在哪个位置、有多少个外显子、UTR 边界在哪等等。但设计思路和语法细节上,差别不小。你想想看,如果拿 GTF 的解析器去读 GFF3 文件,大概率会在第 9 列报错。这不是工具不好,是格式没对齐。
1.1 格式起源与版本演变
GFF 最早由 Sanger 研究所推动,目的是为基因组注释提供一个统一的表格形式。我记得最早接触的是 GFF2,那时候还在用 Perl 脚本手工解析。后来社区发现 GFF2 在表示复杂基因结构时不够灵活,于是在 2005 年左右推出了 GFF3,这也是目前最主流的版本。
GTF 呢,本质上是从 GFF2 衍生出来的。UCSC 和 Ensembl 这两个基因组浏览器团队,为了更精确地描述基因和转录本关系,在 GFF2 基础上做了一些调整,形成了 GTF。所以你会发现,GTF 的很多规则跟 GFF2 很像,但跟 GFF3 反而不太兼容。
下面是几个常见版本的对照:
| 格式名称 | 全称 | 当前状态 | 主要维护方 |
|---|---|---|---|
| GFF1 | General Feature Format 1 | 已淘汰 | Sanger |
| GFF2 | General Feature Format 2 | 少量使用 | Sanger |
| GFF3 | General Feature Format 3 | 推荐使用 | GMOD / NCBI |
| GTF1 | Gene Transfer Format 1 | 已淘汰 | UCSC |
| GTF2 | Gene Transfer Format 2 | 广泛使用 | Ensembl / UCSC |
个人建议:新项目优先用 GFF3 或 GTF2。如果团队已有管道,别急着换,先把格式兼容性测清楚。我曾经见过一个团队因为升级 GFF 版本,导致所有下游分析脚本全部重写,代价不小。
1.2 九列核心结构——万变不离其宗
不管 GFF 还是 GTF,核心都是 9 列,用 Tab 分隔。每一行代表一个注释特征。我习惯把这 9 列分成三组:定位信息(1-5列)、打分与方向(6-8列)、属性描述(第9列)。下面这张表你最好收藏一下,排查格式错误时经常要用到。
| 列号 | 字段名 | GFF3 规则 | GTF2 规则 |
|---|---|---|---|
| 1 | seqid | 染色体/ scaffold ID | 同 GFF3 |
| 2 | source | 注释来源(如 Braker3) | 同 GFF3 |
| 3 | type | 特征类型(如 gene, mRNA, exon) | 同 GFF3,但必须用受控词汇 |
| 4 | start | 起始坐标(1-based) | 同 GFF3,也是 1-based |
| 5 | end | 终止坐标(包含) | 同 GFF3 |
| 6 | score | 置信度或 E-value | 同 GFF3,可用 . 填充 |
| 7 | strand | + / - / . |
同 GFF3 |
| 8 | phase / frame | CDS 相位(0, 1, 2) | 读框(0, 1, 2),含义相同 |
| 9 | attributes / group | Tag=Value 格式,分号分隔 | key "value" 格式,引号包裹 |
避坑指南:我曾经犯过一个低级错误——把 GFF3 中第 8 列的 phase 直接当成 GTF 的 frame 用,结果翻译起始位点总是偏移一个碱基。后来一查才发现,phase 和 frame 虽然含义一样,但 GFF3 要求 CDS 特征必须填,而 GTF 允许用 . 代替。这点差异在长基因流程中特别容易踩坑。
1.3 第 9 列——核心差异所在
前 8 列两家基本一致,真正的分歧在第 9 列。这也是我排查格式错误时第一个检查的位置。来看两个实际例子:
GFF3 的第 9 列风格:
ID=transcript_001;Parent=gene_001;Name=TP53-201;biotype=protein_coding
GTF2 的第 9 列风格:
gene_id "ENSG000001"; transcript_id "ENST000002"; gene_name "TP53"; transcript_name "TP53-201"
看出来了吗?GFF3 用 key=value,等号两边没有空格,多个标签用分号隔开。GTF 用 key "value",值和关键词之间用空格,值必须用双引号包裹。就这个小小的引号差异,每年不知道让多少管道崩溃。
还有一个容易忽略的点:GFF3 要求 ID 和 Parent 标签来构建层级关系,而 GTF 用 gene_id 和 transcript_id 来表达归属。这意味着,GFF3 可以轻松表示 mRNA ↔ 外显子 ↔ CDS 的多级嵌套,GTF 则更扁平,适合基因→转录本→外显子这种两层结构。
1.4 格式选择——没有银弹
到底该用 GFF 还是 GTF?说实话,得看你的下游工具链。我个人遵循三条原则:
- 看浏览器:去 UCSC 提交数据,优先用 GTF;去 JBrowse 或 IGV,GFF3 表现更好。
- 看流程:如果管道里有
gffread、agat这类工具,它们对 GFF3 支持更完整。如果用的是cufflinks、stringtie,那 GTFs 是标准输入。 - 看复杂度:需要表示可变剪接、融合基因、假基因这些复杂结构时,GFF3 的层级模型更灵活。
实用建议:如果你跟我一样,经常在两种格式之间切换,可以在流程里内置一个格式检测步骤。检测方法很简单——读取第 9 列的第一个特征,看看值是跟在 = 后面还是包在引号里。一两行脚本就能避免后续所有解析错误。
1.5 知识体系一览
下面这张图把这章的核心逻辑串起来了。你可以把它当作一个快速索引,遇到格式问题先在这张图上定位一下。
看着这张图,其实就一句话:前 8 列两者高度一致,第 9 列是分水岭。你只要抓住第 9 列的语法差异,就能快速判断手里的文件是 GFF 还是 GTF,也能解释为什么同一个解析器换了文件就罢工。
一个小技巧:在 Linux 下,直接用 head -1 your_file.gff | cut -f9 | head -c 50 看一眼第 9 列的前 50 个字符。如果有 = 且没有引号,大概率是 GFF3;如果有 " 包裹的值,那就是 GTF。这个办法在我手里救过无数次急。