第3章:可选字段与扩展——score、strand、phase的常见约定与默认值
很多新手刚接触 GFF3 时,都觉得前 8 列是主体,后 3 列不过是「可选的」。嗯,这种想法会害死人。我刚开始处理酵母基因组注释时,就因为在 strand 列里填了个乱码……整个下游分析全跑偏了。
今天咱们把 score、strand、phase 三个字段的坑一个一个填平。说白了,它们虽然「可选」,但一旦用错,后果远比你想的严重。
3.1 score 字段:不是所有的「分数」都叫 score
score 是第 6 列,官方说它是「证据支持度」。但实际项目中,这个字段被滥用得太多了。
核心约定:
- 浮点数或整数,合法范围 0–1000
- 没有值时用
.占位 - 专指「该特征与参考序列比对的置信度」,不是任意打分
我个人习惯是:只有基于序列比对(BLAST、minimap2)产生的特征才填 score,而且一定是标准化后的值。例如 exon 来自 spliced 比对,score 可以填最大 1000;但你要是自己算了个基因长度作为「分数」放进去……抱歉,那不是 GFF3 的约定。
常见陷阱
| 错误写法 | 问题 | 正确做法 |
|---|---|---|
| score = 0.85(未乘 1000) | 范围外,工具可能报错或截断 | 填 850 或直接用 . |
| score = "high"/"low" | 字符串,不符合浮点数规范 | 填数值或 . |
| 所有行全填 1000 | 失去区分度,等于没意义 | 按实际置信度填写,或全部留 . |
曾经有一次,我帮同事排查一个 RNA-seq 的注释冲突。她所有基因模型的 score 都填了 999,结果 NCBI 的 RefSeq 验证工具直接跳过她的行,导致注释大面积丢失。后来才发现——score 列全是虚值,工具当作「不可信数据」处理了。
默认值策略
- 实验验证的特征(如 PCR 验证的转录本):填 1000
- 计算预测的特征(如 ab initio 预测):填预测概率×1000,取整
- 人工复核过的:填 1000 且注释 attribute 注明
- 拿不准、或不需要区分时:一律写
.,不要乱编数值
3.2 strand 字段:方向只有 + 和 -,没有也许
strand 是第 7 列。可选值只有 3 种:+、-、.。你想想看,是不是很简单?但现实中的混乱程度超出想象。
我给你们的建议:
- 明确特异的基因——填真实方向,别含糊
- 双向转录或有歧义的区域——填
.,然后加上Note=ambiguous_strand - 永远不要用
?、0、both、1——这些不是标准值
我在一个细菌项目里遇到过这种情况:有人把正链写成 plus,负链写成 minus。解析器直接跳过这些行,因为他没按规范。为什么不去标准化一下?可能是手写表格时的习惯。嗯,这个坑踩一次就够了。
默认值的潜规则
- 如果所有特征在同一行上(比如只注释了一条链),strand 必须统一
- mRNA 的 strand 必须与它的 exon 一致,否则视为非法结构
- 未定位到链的特征(如 repeat_region)建议始终用
.
3.3 phase 字段:CDS 的「对齐记号」,别乱填
phase 是第 8 列。只有 CDS 特征才需要它。其他特征(exon、mRNA、gene)应当填 .。这是很多人的误区——以为每个特征都要填 0。
phase 的取值规则:
0:这个 CDS 片段的第一个碱基正好是密码子的第一个碱基1:第一个碱基是密码子的第 2 个碱基(即前面有 1 碱基偏移)2:第一个碱基是密码子的第 3 个碱基(偏移 2 碱基).:不是 CDS 特征,或者相位不适用
怎么计算?很简单——看这个 CDS 片段的起始位置相对于密码子框架的偏移量。如果你从整个 CDS 的起始密码子开始数,首个 CDS 片段一定是 phase 0。后面的片段根据前一个片段长度 mod 3 来推算。
我拿个例子演示一下
# 假设 CDS 起始于基因组的 100 位,总长 18bp,分成三个片段
100 105 CDS phase 0 # 前 6bp,完整 2 个密码子
106 111 CDS phase 0 # 起始对齐
112 117 CDS phase 0 # 起始对齐
# 但如果第一个片段是 4bp(非 3 倍数)
100 103 CDS phase 0 # 4bp,多出 1 碱基
104 110 CDS phase 1 # 前面多 1 个,所以偏移 1
避坑提醒:我亲眼见过有人把所有 CDS 片段全标成 phase 0。结果翻译出来的蛋白质序列完全错位了——因为忽略了这个「偏移链条」。特别是内含子长度不是 3 的倍数时,相位一错,整个蛋白质序列都废了。
phase 的「默认值」陷阱
- 不填 phase → 工具要么报错,要么当
0处理,但可能错 - 非 CDS 特征填 phase → 很多解析器会忽略,但部分严格工具会报警告
- 相位值不能「中断」——必须连续传递。每个 CDS 片段的 phase 由前一个片段的长度决定
3.4 三个字段的整体使用检查清单
我把日常项目中常用的规则总结了一张表,你可以贴在工位上。
| 字段 | 合法值 | 必须填? | 典型错误 | 我的推荐 |
|---|---|---|---|---|
| score | 0–1000 浮点数或 . | 可选,但填了必须规范 | 字符串、超出范围、人为虚构 | 用 . 代替无意义数据 |
| strand | + - . | 建议填,除非未知 | ? 0 both | 未知则填 . 并加 Note |
| phase | 0 1 2 . | 仅 CDS 必须 | 非 CDS 也填数值、不连续 | 非 CDS 始终 . |
3.5 一张图看懂三个字段的关系
下面这张 SVG 图帮你理清每个字段的关键点和常见错误。画布小,但信息集中,一眼扫过去就明白。
你可以把这张图当作速查手册。下次写 GFF3 时,对着每个字段扫一遍这三个框——基本不会出大问题。
3.6 实战:如何用脚本自动校验这三个字段
总不能每次都手查吧?我写了一个简单的 awk 脚本,能快速扫描 GFF3 中这三个字段的异常。你直接贴到终端就能用。
awk -F'\t' '
!/^#/ {
# score 检查(第6列)
if($6 != "." && ($6 !~ /^[0-9]+\.?[0-9]*$/ || $6 > 1000 || $6 < 0))
print "score 异常: 行" NR, $0
# strand 检查(第7列)
if($7 != "+" && $7 != "-" && $7 != ".")
print "strand 异常: 行" NR, $0
# phase 检查(第8列)——只对 CDS 检查
if($3 == "CDS") {
if($8 != "0" && $8 != "1" && $8 != "2" && $8 != ".")
print "CDS phase 异常: 行" NR, $0
} else {
if($8 != ".")
print "非CDS 行 phase 异常: 行" NR, $0
}
}' your_file.gff3
小提示:这个脚本只做了基础格式检查。更严格的相位连续性校验,你需要结合前一个 CDS 片段的长度来做。不过,作为初筛,它已经能过滤掉 80% 的低级错误了。
好了,三个可选字段的核心要点就这些。记住一句话:. 是最好的默认值——比胡乱填一个数字安全得多。