必需字段详解:seqid、source、type、start、end、score、strand、phase、attributes

GFF3的每一行,都必须包含这9个字段。

缺一个都不行。顺序也不能乱。

我刚接触GFF3那会儿,总以为这是搞形式主义。后来被坑过几次,才明白每个字段都有它的设计逻辑。

2.1 字段概览

先说整体结构。9个字段用制表符分隔,做成一列一列的样子。

字段名 类型 必填 占位符
seqid 字符串 是 无
source 字符串 是 .
type 字符串 是 无
start 正整数 是 无
end 正整数 是 无
score 浮点数 否 .
strand 字符 是 .
phase 整数 参见说明 .
attributes 键值对 是 无

这张表可以当速查卡用。

我习惯把它贴在终端旁边的墙上,编码的时候瞄一眼就行。

2.2 字段逐个拆解

下面一个一个讲。

每个字段我都会给出:官方定义、我的理解、常见错误。

2.2.1 seqid:序列标识符

这个字段就是告诉你,当前记录在哪个染色体或scaffold上。

我曾碰到有人把seqid写成"chr1"和"1"混着来。文件里一半是chr1,一半是1。结果下游工具当成两个不同的序列在处理,注释全乱了。

注意: seqid必须与FASTA文件头部名称严格一致。差异哪怕小到一个字符,都会造成对应关系断裂。

我的建议很简单。统一用同一个命名约定,大小写、前缀、连字符都要保持一致。

个人技巧: 用grep按seqid分组计数,快速排查不一致问题。

2.2.2 source:注释来源

这个字段描述注释的产生方式。可以是软件名、数据库名、或者实验方法。

比如Augustus、RefSeq、RNA-Seq_evidence。

如果不知道来源,就用点做占位符:.。

为什么重要? 多源注释合并时,source字段可以帮你追踪每条记录的来源。这相当于一个"质检章"。

但我必须提醒你。source字段不要写太个性化的名字。

我见过有人写my_best_guess,虽然语法没问题,但别人根本看不懂。最好使用标准名称。

2.2.3 type:特征类型

这是核心字段。它指定这条记录是什么。比如gene、mRNA、CDS、exon。

类型名必须符合SO(Sequence Ontology)术语。GFF3官方推荐使用SO术语。但这不是强制性的。

不过我个人强烈建议遵守。否则兼容性会很差。

# 推荐写法
gene
mRNA
CDS
exon
# 不推荐写法(虽然能通过语法检查)
genetic_element
coding_region
transcript_unit

我在项目中遇到过使用自定义类型名的情况。结果下游工具解析时直接崩溃了。因为那种工具只认特定几个SO术语。从那以后我就再也不敢乱取名了。

2.2.4 start和end:坐标对

这两个字段定义特征在序列上的起止位置。

关键规则有两条:

  • 坐标是基于1的整数。不是0基。
  • end必须大于等于start。

也许有人会问:为什么不是0基?

因为GFF3从GenBank格式继承来的一套规则。最早就是这么设计的。你想想看,生物学家习惯从1开始数碱基位置。所以GFF3遵循了这个习惯。

还有一个容易搞混的概念:区间类型。

区间 坐标示例 起始 终止
点特征 start=10, end=10 10 10
区间特征 start=10, end=20 10 20
常见坑: 点特征如果写错成start=10, end=11,虽然语法检查能通过,但代表一个长度为1的碱基区间。意义完全不同。

2.2.5 score:分数

这个字段可选。通常用于表示比对置信度或计算得分。

如果不使用,用点.占位。

典型用法如下:

# 比对得分
score=254.3

# 无得分
score=.

要注意的是,score不是自由格式的文本。必须是一个数字或点。我曾经看到有人写high和low。结果下游统计脚本直接炸了。

2.2.6 strand:链方向

这个字段告诉特征位于DNA的正链还是负链。

取值就3种:

  • +:正链
  • -:负链
  • .:不知道或不适用(链不明)

有一个很容易忽略的点:链方向影响CDS相位计算。

负链基因的外显子和CDS坐标,基因组浏览器内部会进行反向翻译。如果你手动调整坐标,很可能搞错。

我的经验: 尽量不要手动调整负链特征的坐标。除非你非常清楚自己在做什么。直接交给专业工具处理最稳妥。

2.2.7 phase:相位

这个字段只对CDS特征有意义。表示CDS的第一个碱基相对于密码子起始位置的偏移量。

取值只能是0、1、2或者点。

  • 0:特征起始与密码子边界对齐
  • 1:特征起始相对于密码子边界右移一个碱基
  • 2:特征起始相对于密码子边界右移两个碱基
  • 只用于CDS,其他类型用点占位

我遇到的最离谱的错误,是把负链的phase算错了。

负链CDS的phase计算是基于反向互补序列,而不是原始序列。很多人直接复用正链phase,结果翻译出来的蛋白质序列全错。

# 负链CDS的phase示例:第二个外显子phase=2
# 表示这个外显子起始处缺失两个碱基,才能对齐密码子
警告: phase错误会造成蛋白质序列翻译出错。而且这种错误非常隐蔽,如果不做翻译验证,可能在文件里藏很久才发现不了。

2.2.8 attributes:属性键值对

这个字段是最灵活,也是最多人出错的地方。

它是Key=Value;Key=Value的格式。多个键值对用分号分隔。

ID=gene001;Name=BRCA1;Note=tumor suppressor gene

属性键值对的编码规则:某些特殊字符需要进行Percent-Encoding(百分号编码)。

  • 分号;需要编码为%3B
  • 等号=需要编码为%3D
  • 制表符、换行符也需要编码

我在项目中遇到过有人把Note=gene mutation写成了Note=splice variant;functional。因为分号没编码,解析器把functional当成了另一个键,直接解析出错了。

核心原则

推荐保留的键有:ID、Name、Parent、Alias、Note、Ontology_term、Dbxref。

ID必须是唯一的。Parent用于建立层次关系。

GFF3还有一个推荐但非强制的要求:ID值应该在整个文件中唯一。

虽然这不是语法错误,但多个特征共享同一个ID,下游工具往往会报错或忽略重复记录。

2.3 字段关系图

下面这张图能帮助你直观理解各个字段如何协同工作。

GFF3 字段关系概览 标识类字段 seqid source type 位置类字段 start end strand 属性类字段 attributes score phase 字段如何共同描述一个特征? • seqid + start + end + strand:确定特征在基因组上的精确区间 • type:定义特征的生物学含义(基因/外显子/CDS等) • attributes:提供特征的附加描述(ID/Name/Parent/Note等) • source + score + phase:补充元数据,增强注释可追溯性

2.4 常见错误与避坑指南

下面我列出一些我实际踩过的坑。希望能帮你避免走弯路。

  • seqid不一致:FASTA头部和GFF3的seqid对不上。解决方案:做一次交叉验证。
  • 坐标混淆:0基和1基混用。GFF3固定使用1基。转换时务必确认。
  • phase用错:负链CDS的phase需要基于反向互补序列计算。不要直接用正链的值。
  • 属性键名冲突:同一个特征内出现重复的键名。虽然语法不禁止,但多数解析器会覆盖前面的值。
  • 占位符与值的混淆:score和phase使用.占位,表示缺失。不要填NA、none或其他字符串。
检查清单 每次写完GFF3,可以跑一遍这个清单:
- seqid是否唯一且与FASTA匹配?
- start是否小于等于end?
- 负链CDS的phase计算是否正确?
- attributes是否做了百分号编码?
- ID是否全局唯一?

2.5 本章小结

9个字段,每个都有它的设计逻辑。

标识类字段帮你定位特征在哪里、由谁产生、是什么类型。

位置类字段告诉你特征的位置坐标和链方向。

属性类字段提供剩余的所有辅助信息。

只要把这三类字段搞清楚,GFF3的骨架就搭起来了。