ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

OrthoFinder实战教程:直系同源群推断与结果解读

OrthoFinder实战教程:直系同源群推断与结果解读 平时跑比较基因组学项目我最常被问到的工具就是OrthoFinder。原因无他直系同源群推断这个环节它几乎是当前默认选择尤其是你想在十几个、几十个物种之间做基因家族收缩扩张、功能注释迁移、比较转录组的时候手里这份正交群结果的质量直接决定后面所有分析靠不靠谱。这篇博文我把OrthoFinder从“它到底是干嘛的”讲到“输出文件每一行每一列怎么用”中间穿插我实际跑项目时积累的参数取舍、文件命名、运行日志识别和排坑经验。如果你正准备对一批蛋白组做直系同源分析或者已经跑完在对着输出目录发懵这篇应该能帮你省下一两天摸索时间。1. 先讲清楚OrthoFinder到底在解决什么问题1.1 从“同源”这个词的歧义说起做跨物种比较的时候你会听到两个特别容易混淆的词“同源基因”和“直系同源基因”。同源基因homolog是一个大概念指来自共同祖先基因的所有序列。它下面又分两类直系同源ortholog是物种形成事件产生的基因旁系同源paralog是物种内部的基因复制事件产生的基因。为什么必须把这两者区分开核心原因是功能推断的可靠性。两个物种里的直系同源基因大概率还保留着祖先基因的功能而旁系同源基因因为经历了复制后的功能分化可能已经演化出新功能甚至发生假基因化。所以你拿人类某个基因去鱼、鼠里找“对应基因”做功能迁移时真正应该找的是ortholog而不是随手一个blast出来的最佳命中的旁系同源。OrthoFinder就是专门干这个的输入一批物种的蛋白组序列它把所有基因按直系同源关系分成一个个群落orthogroup然后在这个基础上进一步判断哪些基因两两之间是严格的直系同源关系并把每个orthogroup里更深层的谱系分化关系也整理出来。1.2 OrthoFinder能输出的核心结果一套OrthoFinder跑完你能得到的不仅仅是“基因分群表”而是一整套互相配套的进化分析结果全物种两两之间的同源搜索矩阵和基于此的orthogroup聚类结果每个orthogroup的基因树以及基于所有基因树综合推断出的有根物种树直系同源基因列表、单拷贝直系同源基因列表层次直系同源群HOGHierarchical Orthogroups这是2.x版本的一大核心特性能把基因家族在物种树不同分支上的扩张收缩关系细分出来全基因组范围内的基因复制事件统计定位到具体物种树分支上。这意味着有了OrthoFinder的输出你后续很少需要再额外调用其他工具去构建物种树、找单拷贝基因或者统计拷贝数变化一份结果直接衔接下游的CAFE、GO富集、选择压力分析等流程。1.3 和同类工具比较OrthoFinder的优势是什么目前主流的直系同源推断工具还有InParanoid、OMA、eggNOG-mapper等但它们定位差别挺大。InParanoid擅长两两物种之间的直系同源分析多物种场景下需要两两组合跑一遍结果整合麻烦OMA精度公认很高但计算资源消耗大遇到大规模基因组集会非常吃力eggNOG-mapper则是基于已有数据库的功能注释工具必须依赖于eggNOG数据库里的物种覆盖范围不适合研究新测序的、数据库里没有的物种。OrthoFinder在这几个维度上取得了比较优秀的平衡支持任意数量的物种同时分析内置了高效的DIAMOND序列搜索和MCL聚类流程同时输出基因树和物种树运行速度远快于基于传统BLAST的流程。所以它成了比较基因组学项目的首选尤其适合基因组数量在几十到一两百个规模的项目。2. 算法流程拆解从蛋白序列到正交群2.1 整个流程实际上分几个阶段OrthoFinder的完整流程可以理解成一条流水线分成四个阶段。第一阶段是预处理和同源搜索。先把每个物种的蛋白序列提取出来、过滤掉过短或者含非法字符的序列然后做全序列两两对比。这里对象是全部物种的所有蛋白序列得到的是一张huge的“谁和谁相似”的矩阵。第二阶段是orthogroup聚类。基于第一阶段搜索到的相似性关系和得分采用马尔可夫聚类算法MCL即Markov Clustering把相似基因聚成一个一个群落这就是最初的orthogroup。第三阶段是树推断。对每个orthogroup进行多序列比对后构建基因树再把所有基因树拿来做综合分析用STAG算法推断出物种树并据此对每一棵基因树进行根定向。第四阶段是直系同源判定。利用根定向后的基因树和物种树OrthoFinder会把每个基因树上的节点映射到物种树上判断哪些基因为物种分化产生直系同源、哪些为复制产生旁系同源最终输出正交群、直系同源基因表和HOG层次直系同源群。2.2 同源搜索为什么默认用DIAMOND而不用BLAST你可能会疑惑BLAST用了这么多年也很成熟为什么OrthoFinder默认跑的是DIAMOND关键原因在于全基因组的all-versus-all搜索计算量非常大。假设你有10个物种每个物种4万个基因总序列数就是40万条两两比较理论上就是1.6×10的11次方量级的比较。BLAST跑完这个规模可能需要好几天但DIAMOND通过把序列打碎成种子和k-mer索引在保持相似灵敏度的前提下速度提升了几百倍到上千倍。我实际跑过一个50个物种、约200万条蛋白序列的项目Diamond的搜索阶段用32线程大概跑了半天到一天量级换成传统BLAST几乎不可接受。OrthoFinder在检测到DIAMOND可用时默认采用它并且内部会启用一个比较灵敏的搜索模式确保和BLAST的结果在主要同源关系检出上基本一致。如果你实在需要BLAST结果用于后续的特殊验证可以通过参数强制指定。2.3 基因树和物种树STAG算法解决了什么问题早期比较基因组学分析里物种树通常是从少数保守单拷贝基因或核糖体RNA基因单独构建的。但这样做有个问题单基因树本身存在基因缺失、长枝吸引、复制丢失事件干扰等问题用少数基因重建的物种树可能与真实物种关系产生系统性偏差。OrthoFinder的STAG算法思路是不依赖预先指定的“物种树”而是从全体orthogroup基因树中综合提取物种关系的信号。每棵基因树都包含一些物种分叉的信息当几十上百棵基因树放在一起真实的物种关系信号会重复出现而基因复制、丢失导致的噪声会被削弱。最终推断出的物种树覆盖所有输入物种并且会被用于后续所有基因树的根定向。这一步的实际意义很直接你不用再额外准备一棵“参考物种树”OrthoFinder自己推断出的物种树在大多数已发表项目里与已知分类学关系比对的准确率都很高。2.4 从基因树到直系同源与HOG当物种树确定后OrthoFinder会对每棵基因树做根定向把基因树的根放到与物种树一致的位置。此时整棵基因树里每个树节点的分裂事件可以被划分为两类如果这个节点分裂出的两支在物种树上处于不同的物种分支就对应物种形成事件如果两支对应同一个物种就对应基因复制事件。基于这个划分OrthoFinder可以在不同水平上定义直系同源关系。最直观的orthogroup相当于一个大筐把同一个祖先基因的所有后裔基因都装进去而HOG则精细到“物种树某个分支的最近共同祖先基因所产生的直系同源组”。举个实际例子一个物种里一个有4个拷贝的基因家族可能在其他物种里只有1个拷贝。整体被打进同一个orthogroup没错但这个orthogroup内部4个拷贝与另一个物种那1个拷贝之间谁是真正的直系同源谁是被复制后旁系出来的必须依靠基因树和HOG才能说清楚。这也是相对于老一代工具OrthoFinder 2.x最有价值的改进之一。3. 输入文件要求与运行准备3.1 输入目录和序列文件怎么组织OrthoFinder的输入非常简洁一个目录目录里每个物种一个蛋白组fasta文件。比如我经常这样组织/your_path/proteomes/ ├── Human.fa ├── Mouse.fa ├── Zebrafish.fa └── Arabidopsis.fa每个fasta文件即一个物种的全部蛋白序列序列头部的格式一般是“基因ID”后面可以加描述信息。OrthoFinder会自动把“”后的第一个词当作基因ID忽略后面的描述所以类似ENSP00000001 pep:known chr:1:1000-2000这样的头是没问题的它只取“ENSP00000001”。文件后缀支持.fa、.fasta、.faa、.fas等但必须全部是蛋白序列你不能丢一堆基因组DNA序列进去。输入里尽量不要混入RNA序列、非编码转录本或伪基因注释因为直系同源推断建立在蛋白功能保守性的假设上垃圾进垃圾出。3.2 命名规则和常见坑这一步看着不起眼实际项目里踩坑最多。物种名会直接从文件名里提取比如Homo_sapiens.fa对应的物种标签就是Homo_sapiens。这个标签会出现在最终所有输出文件里包括N0.tsv的表头和Orthogroups.tsv的列名。所以建议开始跑之前就把文件名改成你能识别的稳定ID比如Zmays.fa、Osativa.fa最好别用带空格、括号、中文等特殊字符的文件名。基因ID同样需要规范。我见过有人fasta头里带了冒号和竖线比如gene1|transcript1|chr1:100-200这种ID在后续Newick树文件、HOG文件里会被一些下游软件解析出错甚至部分版本OrthoFinder运行中也会报异常。保险的做法是只保留简洁的唯一ID像G00001、evm.model.chr1.100这种。基因模型层面还有一个重要选择如果你拿到的注释包含多个转录本那么同一基因可能有多个蛋白序列。OrthoFinder会把它们当成多个独立序列参与聚类和树构建这会给后续的直系同源判定带来偏差。通常做比较基因组学分析前应该每个基因只保留一个代表性转录本比如选择最长转录本或首选转录本。这一步建议在输入前用AGAT等工具处理干净。3.3 关键运行参数逐个说OrthoFinder的运行命令并不复杂核心参数就几个orthofinder -f proteomes -t 16 -a 4 -o ortho_results-f输入目录位置后面直接跟包含各物种蛋白文件的目录-t同源搜索Diamond/BLAST阶段的线程数这是最耗时、最占资源的阶段建议给满物理核数比如服务器是32核就给32或30-a分析阶段的线程数用于多序列比对、树构建等给个4到8就够了给太多容易内存冲突-o输出目录的路径。如果不给OrthoFinder默认会在输入目录的上级目录生成一个以“输入目录名物种数”命名的结果文件夹。还有几个我不常用但值得一提的参数-M聚类方式默认是mcl。较新版本里还有基于深度学习的dl模式但我个人建议常规项目用默认的mcl结果更稳定、解释性更好。-S同源搜索程序默认diamond可以改成blast。-A多序列比对程序默认mafft。-T基因树构建程序默认fasttree。基于我个人的使用体验除非你有特殊理由这些默认参数基本不要动动了反而容易出兼容问题。一个例外是你明确想用BLAST的结果去发文章但那样就得接受慢得多的运行时间。3.4 一个端到端运行示例假设我有三个物种的蛋白组文件已经准备好了conda activate orthofinder_env orthofinder -f proteomes -t 32 -a 8 -o ortho_results运行时屏幕会持续刷日志关键节点大概长这样Using Diamond in ultra-sensitive mode ... MCL clustering ... Orthogroups: Number of orthogroups: 15034 Number of genes assigned to orthogroups: 112345 ... Inferring gene trees ... Inferring species tree ... OrthoFinder wrote results to: ortho_results/Results_...看到“OrthoFinder wrote results to”这一行基本就说明正常结束。整个流程短则几十分钟长则数天取决于物种数量和蛋白总条数。另外OrthoFinder有一个很实用的特性如果你在中途因为超时或断电中断了任务直接再运行一次完全相同的命令它会检测到已有输出并尽量断点续跑而不是从头开始。这点在大数据集上非常救命后面我会专门展开说。4. 输出文件全注释拿到结果怎么读4.1 输出目录总览运行完成后OrthoFinder会在你指定的目录下生成一个以Results_开头的文件夹里面内容相当丰富。每个版本细节略有出入但核心目录结构基本是Results_... ├── Comparative_Genomics_Statistics/ ├── Gene_Duplication_Events/ ├── Gene_Trees/ ├── Genes_With_Species_IDs/ ├── Orthogroups/ ├── Orthogroup_Sequences/ ├── Phylogenetic_Hierarchical_Orthogroups/ ├── Single_Copy_Orthologue_Sequences/ ├── Species_Tree/ ├── WorkingDirectory/ └── logs/下面我把每个目录和关键文件的用途一块一块讲清楚。4.2 Orthogroups目录下的三个核心文件这是绝大多数人最关心的部分也是下游分析的主要数据来源。Orthogroups.tsv或Orthogroups.txt是正交群的主表。每一行代表一个orthogroup第一列是OG编号形如OG0000000后面的每一列对应一个物种单元格里是所有属于该群的基因ID用空格分隔。比如某一行你看到OG0000012这一行里人类那列有ENSG00000130小鼠那列有ENSMUSG00000021说明这两个基因血缘关系最近。Orthogroups.GeneCount.tsv是基因计数矩阵。行是OG编号列是物种值是该物种在这个OG里的基因拷贝数。绝大多数基因家族收缩扩张分析比如CAFE5需要的数据就是这张表。每个物种同一OG的拷贝数之和、不同物种之间的拷贝数差异可以直接用来判断基因家族在第一视角上的扩张压缩趋势。Orthogroups.UnassignedGenes.tsv记录的是没有进入任何orthogroup的“孤儿基因”。这些基因可能是物种特有基因、注释质量太差的片段或者是假基因。分析时注意关注这个表如果某个物种大量基因都没有分到OG里大概率是该物种蛋白组注释质量有问题而不是物种特殊性太强。我碰到过某样本近30%基因未分配后来一查是输入fasta里混入了大量转座子开放阅读框。4.3 HOG与Phylogenetic_Hierarchical_Orthogroups这个目录里的N0.tsv是我个人觉得OrthoFinder最被低估的结果文件但理解门槛也最高。N0.tsv的第一行以#开头记录工具版本和运行参数。第二行开始每一行是一个层次直系同源群HOG列结构类似HOG ID、OG然后是各物种列。HOG ID的格式是N0.HOG0000000它并不是一个平面编号而是内嵌了物种树层级信息。怎么理解“层级”举个实例物种树分成哺乳动物支、鸟类支、鱼类支等OrthoFinder会在哺乳动物这个分支的共同祖先水平上定义一个HOG这个HOG包含所有哺乳动物物种里与祖先基因直系同源的成员但它可能只是整个OG的一个子集。这种层级结构让N0.tsv尤其适用于跨物种的基因家族亚功能化研究。N0.tsv中每一列物种下的基因ID是以空格分隔的如果某一列显示为空代表该物种在这个HOG里没有直系同源成员。做比较分析时需要注意的是同一个OG可能被拆分成多个HOG尤其在基因复制频繁的家族里。你先看OG编号再看HOG编号能很快判断哪些物种的基因属于同一谱系的直系群。4.4 统计文件和物种树文件Comparative_Genomics_Statistics/Statistics_PerSpecies.tsv和Statistics_Overall.tsv是两份非常有用的质量检查报告。Statistics_PerSpecies.tsv里每个物种一行列包括物种名、蛋白总数、被分配到orthogroup的基因数、未分配基因数、分配给单拷贝直系同源群的基因数、最大正交群的大小等。我拿到一份结果第一步就是看这个表格通过“分配到OG的基因比例”能快速评估一个物种注释质量以及OrthoFinder运行是否正常。正常情况下真核生物的基因分配到OG的比例在85%以上比较合理。Statistics_Overall.tsv则是整个运行的整体统计比如OG总数、不同物种间共享的OG数量、特有OG数量、单拷贝OG数量。写文章方法部分的时候直接引用这里面的数字就行。物种树目录下最重要的是SpeciesTree_rooted.txt这是最终用于全部分析的有根物种树Newick格式。你可以直接放到FigTree、iTOL或者ggtree里可视化检查物种关系与你预期的是否一致如果出现明显违背分类学的“怪树”要回头检查输入数据里是否混入污染序列或错误标注的样本。4.5 树文件、序列文件和中间文件怎么用Gene_Trees/目录下每个orthogroup一个Newick格式文件文件名对应OG编号。这些基因树可以直接用来检查基因家族内部的复制丢失事件用在R的phytools或ggtree里做可视化也很方便。Single_Copy_Orthologue_Sequences/里是每个物种都恰好有且只有一个拷贝的直系同源基因的蛋白序列每个这类OG一个fasta文件。这些序列是做多物种系统发育基因组学、分歧时间估算的黄金数据。如果你的目标是构建物种树这一目录挑着用就对了。Orthogroup_Sequences/则是全部OG的序列文件比较大用于后续你需要对每个OG做自定义分析时的序列来源。Genes_With_Species_IDs/保存的是加上物种前缀的基因序列用于内部处理一般不用去管。WorkingDirectory/和logs/里存放的是中间文件和运行日志排查问题时会用到日常分析不要修改这两个目录里的内容否则可能导致结果不一致。5. 实际项目中常见问题与排坑实录5.1 运行报错和输入问题对照最常遇到的报错是输入文件不符合要求。比如ERROR: No sequence files found in directory ...这个通常是输入目录里没有支持的fasta扩展名检查一下文件后缀是不是.fa、.fasta、.faa。另一个高频报错是fasta文件里出现了非蛋白字符比如含有终止密码子的*或者序列里混入了U这种RNA碱基。OrthoFinder在预处理阶段会尝试过滤但过滤掉太多序列时会直接报错或导致该物种基因数异常低。我建议在你自己的流程里提前清洗去掉*统一字母大小写过滤长度小于30的序列。还有一类坑是物种名重复。两个文件一个叫Human.fa另一个叫Human_isoforms.fa实际提取出的物种标签可能是同一个。运行不会报错但结果里两个物种会混在一起下游分析直接错乱。开始前检查一下每个文件名是否唯一、提取出的物种标签是否唯一这个成本几乎为零。5.2 资源占用和运行速度问题Diamond阶段占用的资源最多。如果你跑的是几十个物种的大项目建议提前用free -h看下内存一般来说总序列数百万条量级时32线程运行Diamond峰值内存接近50-100GB内存不够会导致进程被系统直接kill掉。这时可以适当降低-t线程数因为Diamond的峰值内存和并发线程正相关或者换个更高内存的节点。如果你发现时间太长先看一眼日志卡在哪个阶段。卡在Diamond搜索阶段说明比对量太大卡在树构建阶段说明某几个超大基因家族拖慢了MAFFT和FastTree。对超大基因家族可以考虑提前过滤掉注释里的转座子相关序列它们通常导致产生超级大的OG占用大量计算资源且对主分析帮助不大。还有个小经验同一份数据-t给32核和给16核总耗时差距可能没有想象中那么大因为Diamond阶段在多线程下的加速比受磁盘IO影响明显。我当时配SSD之后整个流程提速明显高于单纯加核的效果。5.3 结果解读的几个常见误区第一个误区是看到某一个OG里各个物种拷贝数不一样就直接说“这个基因家族发生了扩张”。拷贝数差异只是表象必须结合基因树、HOG信息和物种树分支来判断扩张事件发生在哪个谱系。比如A物种有5个拷贝但形成单系支B物种一个拷贝才倾向说明A的祖先发生了谱系特异性扩张如果5个拷贝分散成好几支情况就复杂得多。第二个误区是忽略单拷贝基因的筛选标准。你从Single_Copy_Orthologue_Sequences里挑基因做系统发育分析没错但要注意这些序列对应的物种数量是否覆盖全部物种。如果某OG只覆盖了80%的物种直接拿来串联建树会引入大量缺失数据建议在后续比对前过滤掉缺失严重的位置。第三个误区是拿Orthogroups.tsv里的OG编号直接当功能注释结果。OG编号本身不具备功能语义你需要把OG和参考物种的基因功能注释关联起来才能推断这个基因家族大概的功能。一个实用做法是用你在Orthogroups.tsv里所在OG的参考基因ID去比对eggNOG、NR等数据库或者做GO富集不要自己盲目按编号猜。5.4 断点续跑与版本兼容再强调一下断点续跑这个特性。OrthoFinder运行到一半被中断后重新执行一模一样的命令即可继续。它的续跑逻辑是按阶段判断的如果Diamond搜索已完成直接从基因树推断开始如果基因树已构建完直接从直系同源判定开始。这个功能在大数据集上真的能救命我建议中断后先检查日志最后几行确认当前阶段再有针对性地决定是否重跑。版本兼容问题则要格外上心。不同OrthoFinder版本之间输出格式有细微差异尤其是N0.tsv的列顺序、HOG命名规则以及部分目录结构。如果你同时在维护多个项目尽量固定一个版本比如2.5.4并在文档里记录版本号。上游数据或者下游分析如果依赖旧版本结果升级前一定要留备份不要直接覆盖。最后分享一个实操习惯运行之前我会在输入目录下放一个README.txt记录数据来源、注释版本、软件版本和运行命令运行完成后把logs/目录一并存档。这样不管过多久回来翻结果都能快速还原当时的数据处理路径这在写文章和应对审稿意见时非常有用。
返回列表