667 原核生物比较基因组ANI¶
一句话概述:ANI(平均核苷酸一致性)是基因组时代原核生物物种划分的金标准——两个基因组ANI≥95%即为同一物种。
核心知识点速查表¶
| 知识点 | 关键内容 |
|---|---|
| ANI阈值 | ≥95-96%为同一物种,<83%为不同物种 |
| dDDH阈值 | ≥70%为同一物种(数字化DDH) |
| AAI | 平均氨基酸一致性,用于属级以上比较 |
| FastANI | 快速ANI计算,比ANIb快50倍+ |
| skani | 比FastANI快20倍+,对碎片化基因组更准 |
| 2025新工具 | PyOrthoANI/PyFastANI/Pyskani Python套件 |
一、什么是ANI?(白话解释)¶
打个比方:ANI就像比较两本书有多少文字是相同的。把两个细菌的基因组切成小段(通常1000bp),然后互相比对,看平均有百分之多少的碱基是一样的。如果95%以上的碱基相同,就认为它们是同一个"物种"。
为什么取代了DDH:传统的DNA-DNA杂交(DDH)需要活菌和复杂的实验操作,而ANI只需要基因组序列就能算——更快、更可重复、更标准化。
二、ANI计算方法对比¶
| 方法 | 算法 | 速度 | 精度 | 工具 |
|---|---|---|---|---|
| ANIb | BLAST比对 | 慢(金标准) | 最高 | pyani |
| ANIm | MUMmer比对 | 中等 | 高 | pyani |
| FastANI | MinHash+映射 | 快(50x) | 高(完整基因组) | FastANI |
| skani | 稀疏比对 | 最快(20x于FastANI) | 高(碎片化基因组更优) | skani |
| OrthoANI | 正交比对 | 中等 | 高 | OAT/PyOrthoANI |
三、实战操作¶
3.1 FastANI¶
# FastANI安装
conda install -c bioconda fastani # conda安装
# 1. 两两比较
fastANI \
-q query_genome.fna \ # 查询基因组
-r reference_genome.fna \ # 参考基因组
-o ani_result.txt # 输出结果
# 2. 多基因组批量比较
# 准备基因组列表文件
ls genomes/*.fna > genome_list.txt # 所有基因组路径
# 全 vs 全比较
fastANI \
--ql genome_list.txt \ # 查询列表
--rl genome_list.txt \ # 参考列表
-o all_vs_all_ani.txt \ # 输出
-t 16 \ # 线程数
--matrix # 输出矩阵格式
# 输出格式:query reference ANI fragments_mapped total_fragments
# 只输出ANI≥80%的结果
3.2 skani(更快更适合MAG)¶
# skani安装
conda install -c bioconda skani # conda安装
# 1. 两两比较
skani dist \
query.fna reference.fna \ # 输入两个基因组
-o result.txt # 输出
# 2. 批量比较(sketch + dist 两步)
# 第一步:预计算sketch(只需做一次)
skani sketch \
genomes/*.fna \ # 所有基因组
-o sketches/ \ # sketch输出目录
-t 16 # 线程数
# 第二步:计算距离
skani triangle \
genomes/*.fna \ # 输入基因组
-o triangle_ani.txt \ # 输出三角矩阵
-t 16 # 线程数
# 3. 搜索最近参考基因组
skani search \
query_mag.fna \ # 查询MAG
-d reference_sketches/ \ # 参考sketch库
-o search_result.txt \ # 输出
-n 5 # 返回前5个最近的
3.3 dDDH(GGDC在线工具)¶
# GGDC (Genome-to-Genome Distance Calculator) 在线使用
# 网址: https://ggdc.dsmz.de/ggdc.php
# 或使用命令行版本
# Formula 2 (推荐): 基于HSP长度/总基因组长度
# dDDH ≥ 70% → 同一物种
# Python调用GGDC API(示例)
# Python计算ANI和可视化
import subprocess # 调用命令行
import pandas as pd # 数据处理
import numpy as np # 数值计算
import seaborn as sns # 热图
import matplotlib.pyplot as plt # 绑图
def parse_fastani_output(filepath):
"""解析FastANI输出为矩阵"""
data = []
with open(filepath) as f:
for line in f:
parts = line.strip().split('\t')
query = parts[0].split('/')[-1].replace('.fna', '') # 提取文件名
ref = parts[1].split('/')[-1].replace('.fna', '')
ani = float(parts[2]) # ANI值
data.append({"query": query, "ref": ref, "ANI": ani})
df = pd.DataFrame(data)
# 转为方阵
matrix = df.pivot(index="query", columns="ref", values="ANI")
matrix = matrix.fillna(100) # 对角线=100%
return matrix
# 解析结果
ani_matrix = parse_fastani_output("all_vs_all_ani.txt")
# 热图可视化
fig, ax = plt.subplots(figsize=(12, 10))
sns.heatmap(ani_matrix,
annot=True, fmt=".1f", # 显示数值
cmap="RdYlGn", # 颜色方案
vmin=75, vmax=100, # 色彩范围
linewidths=0.5,
ax=ax)
ax.set_title("ANI热图 (≥95%为同种)")
plt.tight_layout()
plt.savefig("ani_heatmap.png", dpi=150)
# 自动物种划分
def delineate_species(ani_matrix, threshold=95):
"""基于ANI阈值自动划分物种"""
from scipy.cluster.hierarchy import fcluster, linkage
from scipy.spatial.distance import squareform
# ANI转距离
dist = 100 - ani_matrix.values # 距离 = 100 - ANI
np.fill_diagonal(dist, 0) # 对角线为0
# 层次聚类
linkage_matrix = linkage(squareform(dist), method='average') # UPGMA
clusters = fcluster(linkage_matrix, t=100-threshold, criterion='distance')
# 输出物种组
species_groups = {}
for genome, cluster_id in zip(ani_matrix.index, clusters):
species_groups.setdefault(cluster_id, []).append(genome)
print(f"按{threshold}% ANI阈值,划分为 {len(species_groups)} 个物种:")
for sp_id, members in species_groups.items():
print(f" 物种{sp_id}: {', '.join(members)}")
return species_groups
3.4 2025年Python套件¶
# PyOrthoANI/PyFastANI/Pyskani (2025 NAR Genomics)
# pip install pyorthoani pyfastani pyskani
# PyFastANI使用
import pyfastani # 导入PyFastANI
# 创建ANI计算器
mapper = pyfastani.Mapper() # 初始化
mapper.add_draft("ref_genome.fna") # 添加参考基因组
# 计算ANI
hits = mapper.query_draft("query_genome.fna") # 查询
for hit in hits:
print(f"ANI: {hit.identity:.2f}%, 比对片段: {hit.matches}/{hit.fragments}")
# Pyskani使用(最快)
import pyskani
# 批量计算
db = pyskani.Database()
db.sketch("genome1.fna", name="genome1") # sketch
db.sketch("genome2.fna", name="genome2")
results = db.dist() # 计算距离
for r in results:
print(f"{r.query} vs {r.reference}: ANI={r.identity:.2f}%")
四、AAI(平均氨基酸一致性)¶
# AAI用于属级以上的分类比较
# CompareM工具
comparem aai_wf \
genome_dir/ \ # 基因组目录
output_dir/ \ # 输出目录
--proteins \ # 使用蛋白质序列
--cpus 16 # CPU数
# AAI阈值(粗略)
# >90% → 同属
# >60% → 同科
# >45% → 同目
常见报错与解决¶
| 报错 | 原因 | 解决方案 |
|---|---|---|
| FastANI无输出 | ANI<80%不输出 | 使用skani或ANIb,它们无最低阈值 |
| ANI值与预期不符 | 基因组质量差/污染 | 先用CheckM评估基因组质量 |
| 大规模比较太慢 | 基因组数>1000 | 用skani (最快) 或先用Mash预筛选 |
| 内存不足 | 基因组太多/太大 | 分批处理或用Mash预聚类 |
| FastANI和skani结果略有差异 | 算法差异 | FastANI对完整基因组更准,skani对碎片化更准 |
速查表¶
# ANI分析流程
1. 基因组质量评估 (CheckM/CheckM2)
2. 选择ANI工具:
- 少量高质量基因组 → FastANI
- 大量/碎片化基因组(MAG) → skani
- 需要金标准精度 → pyani (ANIb)
- Python集成 → PyFastANI/Pyskani (2025)
3. 计算全 vs 全 ANI矩阵
4. 基于95%阈值划分物种
5. 热图可视化 + 系统发育树
# 物种划分阈值速查
ANI ≥ 95%: 同一物种
ANI 83-95%: 同属不同种
ANI < 83%: 不同属
dDDH ≥ 70%: 同一物种
AAI > 90%: 同属
# 工具速度排名(快→慢)
skani >> FastANI >> OrthoANI > ANIm > ANIb
面试高频问题¶
Q1:ANI 95%阈值是怎么来的? A:通过对90,000+已知原核生物基因组的大规模分析(Nature Communications 2018),发现物种内ANI通常>95%,物种间ANI通常<83%,在83-95%之间存在明显的"间隙"(genetic discontinuity),99.8%的基因组对符合这个规律。95%ANI对应传统DDH的70%阈值。
Q2:FastANI和skani怎么选? A:FastANI对参考级完整基因组更准确(≥50x faster than ANIb),skani对碎片化基因组(如MAG)更准确(>20x faster than FastANI)。2025年PyFastANI和Pyskani提供了Python接口,且值与原工具几乎完全一致(R²>0.999)。
Q3:ANI和dDDH有什么关系? A:dDDH是对传统湿实验DDH的数字化替代,通过GGDC工具计算。ANI 95%大致对应dDDH 70%,两者都用于物种划分。实际研究中ANI用得更多,因为计算更简单直接。
Q4:AAI用在什么场景? A:AAI(平均氨基酸一致性)用于属级及以上的分类比较。因为核苷酸在远缘物种间变异饱和(同义突变累积),而氨基酸更保守,所以远缘比较用AAI更合适。AAI>90%通常表示同属。