
手里的玉米VCF文件终于整理完了几百份材料、几十万个变异位点躺在服务器上接下来最想干的一件事就是先建一棵系统发育树快速看群体之间的亲疏远近。这类分析在玉米群体遗传里太常见了无论是自交系谱系梳理、地方品种群体归属还是育种材料亲缘关系排查都会用同一套思路从SNP数据出发用最大似然法把样本聚成有层次的树而IQtree是最常用的建树工具之一。在这篇文章里我会把从VCF到系统发育树的整个流程讲透包括IQtree安装、VCF过滤、模型选择、跑树命令、结果解读以及一堆文档里不会写的坑。核心不是机械地跑完一条命令而是理解每个参数为什么这么设遇到问题能从原理层面去排查而不是到处搜答案。适合谁看呢适合手里已经有一份VCF文件、想用SNP数据做玉米或其他作物群体遗传分析但还没正式跑过IQtree的读者。不管你是刚接触群体遗传的学生还是想换工具重新处理旧数据的从业者按这套流程走基本不会跑冤枉路。如果你只是想找现成命令可以直接跳到第四部分但我还是建议把预处理看完因为这种项目一半以上的坑都埋在VCF处理环节。1. 项目概述与整体思路1.1 为什么群体遗传分析要先建树群体遗传分析里系统发育树是最直观的一张图。它的本质是基于样本间的遗传差异程度把所有个体重新排列成一颗有层次的树亲缘关系近的样本聚在一起关系远的自然分离。在玉米这种驯化作物里数据通常包含不同热带、温带亚群甚至野生近缘种一棵树扫一眼就能看出样本是否按预期分组、有没有标注错误、有没有混入异源材料。我自己的做法是拿到处理干净的VCF之后不给任何预设信息先让树自己说话再结合群体结构分析去验证。但这里有一个前提必须说清楚系统发育树适合描述分化关系不适合描述存在大量基因流和重组的群体结构。玉米是异交为主的作物群体内部重组信号很强树的分枝不一定完全代表真实亲缘关系尤其在亚群内部。我的习惯是把树当作“第一眼筛选工具”而不是最终结论。它可以快速暴露异常样本也能为后续PCA、admixture分析提供方向但反过来这些分析之间是互补关系不能互相替代。建树和PCA的视角不同树更强调历史的谱系关系PCA更擅长展示连续的遗传梯度两者结合才能给出完整判断。1.2 为什么选IQtree而不是其他建树工具建树工具很多老牌的RAxML、FastTree、MEGA、MrBayes各有拥趸。我选IQtree 2核心原因是它在速度、准确性和易用性之间平衡得最好。RAxML-NG很快但不支持直接读VCFFastTree在大数据量下很能打但模型相对粗糙也没有VCF输入接口MEGA适合教学和小数据量跑几十万位点会非常吃力。IQtree 2有几个非常实用的特点内置ModelFinder自动选模型、支持VCF直接输入、自带UFBoot2和SH-aLRT两个分支支持度检验、多线程和内存控制都很成熟。工具最大亮点直接支持VCF适合场景IQtree 2自动模型选择、VCF直读支持群体规模SNP建树速度与准确度平衡RAxML-NG高并行、大规模ML树不支持基因组级数据传统PHYLIP输入FastTree极快近似ML不支持超大数据量快速看树形MEGA图形界面友好不支持教学、小数据集这种对比不是说要否定其他工具而是提醒你在选工具时先看输入格式。如果你的数据管线已经习惯生成PHYLIP或FASTARAxML也完全能用。但对我这种日常工作要处理大量VCF文件的人来说少一步格式转换、少踩一步坑就是实打实省时间。IQtree还有一个好处是模型选择集成在同一个程序里不用像RAxML那样先跑ModelTest再跑建树。1.3 完整流程预览我自己的标准流程固定五步拿到VCF后先做位点和样本层面的过滤按需做LD剪枝控制位点间冗余决定是直接输入VCF还是转成PHYLIP格式跑IQtree包含模型选择、建树、支持率评估最后解读输出文件并可视化。后面每一部分都会展开。如果只是想先跑通可以直接跳到第四部分复制命令但我还是建议把预处理看完因为大多数“树很奇怪”的问题都出在VCF没处理干净而不是建树软件本身。整个项目从拿到VCF到出图通常一周内可以完成其中大头时间往往耗在VCF过滤和反复调参上。真正跑IQtree的时间反而不长。把握好这个时间分配你的效率会明显提升。2. 环境准备把IQtree装稳再谈建树2.1 三种安装方式怎么选IQtree安装方式常见有三种conda/mamba环境、官方预编译二进制、源码编译。我推荐前两种源码编译除非你对自己编译依赖很有把握否则没必要碰。用mamba创建独立环境最省事mamba create -n phylo -c bioconda -c conda-forge iqtree conda activate phylo iqtree2 -vconda环境的好处是所有依赖自动打包不会污染系统里的其他软件。这在集群上尤其重要因为很多服务器管理员不会给你装系统级软件你自己装一个conda环境就能解决权限问题。如果你机器上还没有mamba可以用conda install -n base -c conda-forge mamba先装上。官方预编译二进制适合没有conda环境或者想快速部署的场景wget https://github.com/iqtree/iqtree2/releases/download/v2.3.6/iqtree-2.3.6-Linux.tar.gz tar -xzf iqtree-2.3.6-Linux.tar.gz iqtree-2.3.6-Linux/bin/iqtree2 -v解压后把二进制路径加进PATH或者建立软链接。没有sudo权限就把下面这行写进~/.bashrc然后source ~/.bashrcexport PATH/path/to/iqtree-2.3.6-Linux/bin:$PATH需要注意版本。IQtree从2.0开始才支持VCF直接输入1.x版本完全没有这个功能。如果你在集群里只找到了老版本用VCF输入会直接报错或不识别参数所以起手先确认iqtree2 -v输出的至少是2.x版本。2.2 安装自检与常见报错安装完成后第一件事就是跑一条最小命令验证iqtree2 -v如果提示command not found多半是PATH没设置好如果提示没有执行权限用chmod x iqtree2修复即可。我遇到比较多的是这个报错iqtree2: error while loading shared libraries: libgomp.so.1: cannot open shared object file这是缺少OpenMP运行库。在conda环境里基本不会出现系统裸装时可以通过安装gcc或libgomp解决。Debian/Ubuntu用apt install libgomp1CentOS/Rocky用yum install libgomp。如果服务器权限不够就别折腾系统环境直接回到conda方案把依赖一起装进去省事得多。还有一类问题是二进制平台不一致。下载Linux版本放到macOS上跑或者反过来都会报各种奇怪的错误。下载前先确认uname -a的系统类型。这一步虽然简单但在集群环境里经常搞错。3. VCF预处理这步决定建树成败3.1 过滤标准质量、MAF、缺失率一个都不能少VCF文件里的位点不是都能直接喂给IQtree。原始VCF里混有低质量位点、稀有变异、高缺失位点甚至多等位位点。其中多等位位点尤其麻烦IQtree的VCF模块在很多版本里会明确报错要求输入双等位位点所以第一步就是过滤。我自己常用的bcftools过滤命令bcftools view --threads 4 \ -m2 -M2 -v snps \ -i QUAL30 MAF0.05 F_MISSING0.2 \ input.vcf.gz -Oz -o clean.vcf.gz bcftools index -t clean.vcf.gz逐个解释这些参数-m2 -M2表示只保留双等位位点多等位位点会直接排除-v snps只保留SNP把INDEL丢掉因为INDEL在进化模型里的处理方式和SNP不一样QUAL30过滤掉低质量的变异MAF0.05要求次等位基因频率大于5%用来剔除极稀有变异F_MISSING0.2要求位点在样本中的缺失率低于20%。注意阈值不是铁律。如果你的样本量只有几十份MAF0.05会丢掉大量有效信息可以放宽到0.02或者干脆不做MAF过滤。玉米这种大基因组、多亚群的材料原始SNP动辄上百万过滤后剩十万到几十万都很正常。样本层面的缺失率也得看。我会用vcftools看每个样本的缺失情况vcftools --gzvcf clean.vcf.gz --missing-indv输出的out.imiss文件里F_MISSING过高的样本要及时标记建树时可以考虑剔除。一个缺失率70%的样本挂在树上不仅自己形成一条不真实的长枝还会拉低周围分支的bootstrap支持率这种问题在预处理阶段解决成本最低。3.2 LD剪枝避免个别基因组区域绑架整棵树连锁不平衡是群体遗传分析里绕不开的问题。如果基因组上某个区域因为选择、参考基因组组装不完整或测序偏好贡献了大量连锁SNP那么这些位点会在建树时被重复加权导致树被这个区域“绑架”。玉米是大基因组不同染色体区域的LD衰减速度差异很大不做剪枝很容易让树反映的是某个染色体片段的历史而不是全基因组水平的群体关系。LD剪枝常用plinkplink --vcf clean.vcf.gz --double-id --allow-extra-chr \ --indep-pairwise 50 10 0.2 --out clean plink --vcf clean.vcf.gz --double-id --allow-extra-chr \ --extract clean.prune.in --make-bed --out clean_ld解释一下关键参数50 10 0.2的意思是窗口大小为50个SNP每次滑动10个SNP窗口内两两位点的r²超过0.2时剔除其中一个--allow-extra-chr是因为玉米数据里除了1到10号染色体还可能有大量scaffold不加这个参数plink会直接报错--double-id解决样本ID里有空格或FID/IID拆分的问题。剪枝后的数据可以转回VCF也可以直接从plink生成的clean.prune.in文件里提取保留位点。如果说清楚适用场景如果你的目标是看全基因组水平的群体分化LD剪枝后的数据更稳妥如果你想尽量保留所有信息做精细的样本亲缘关系梳理不剪枝也可以但最好两个版本都跑一遍对比结果。3.3 输入格式选择直接读VCF还是转PHYLIPIQtree 2直接支持VCF输入命令里用-vcf指定文件这是最方便的路径。不过要注意几点第一IQtree会把VCF里的杂合基因型转成IUPAC简并碱基相当于把二倍体的不确定性编码进序列里但它并不真正解析单倍型所以树实际反映的是样本在SNP位点上的综合相似度第二缺失基因型会被当作未知状态处理缺失率过高会让树的支撑率崩掉第三VCF文件最好用bgzip压缩并用bcftools索引防止读取大文件时出错。如果你更习惯先转成PHYLIP或FASTA我常用的工具是vcf2phylip.pypython vcf2phylip.py --input clean_ld.vcf.gz --output-prefix maize转格式最大的好处是文件结构透明出了问题更容易定位坏处是多一道工序、多占一点磁盘。在几百份样本、几十万SNP的规模下直接输入VCF和转成PHYLIP在运行时间上没有本质差别按个人习惯选择即可。有一点我建议保持固定无论走哪条路都要用过滤剪枝后的VCF不要把原始VCF直接灌进去。4. IQtree建树核心参数与实战命令4.1 最稳妥的启动命令我的标准建树命令长这样假设直接用过滤剪枝后的VCFiqtree2 -vcf clean_ld.vcf.gz \ -m MFPASC \ -B 1000 -alrt 1000 \ -T AUTO --prefix maize转成PHYLIP之后把-vcf换成-s maize.phy即可其余参数一样。逐项解释-m MFPASC让ModelFinder自动选择含ASC校正的最佳模型-B 1000跑1000次UFBoot2超快自助法-alrt 1000同时做1000次SH-aLRT似然比检验-T AUTO自动检测可用CPU--prefix maize让所有输出文件都以maize开头不会污染目录。这个命令会把模型选择、最大似然建树、两种分支支持率一次跑完。对于几百份样本、几十万SNP的数据通常几十分钟到几小时内可以完成。如果位点数量特别大比如超过百万跑之前先看一眼模型选择阶段的时间因为模型选择往往比建树本身更耗时。4.2 模型选择MFP还是直接指定GTRASC-m MFP是IQtree 2的招牌功能全称ModelFinder它会在输入数据上评估上百种替代模型挑出最适合的一个。但从实际经验看位点越多模型选择越慢。对于50万甚至上百万SNP直接让MFP完整跑完可能在模型选择阶段就卡很久。两种策略数据量在十万位点以内直接用-m MFPASC省心数据量很大先用-m GTRASC固定模型跑一版或者抽样一部分位点跑MFP看最佳模型——通常结果都是GTRASC这类复杂模型——然后全量数据用这个固定模型重新跑。关于ASC我必须单独提醒一下。绝大多数从VCF构建系统发育树的场景位点是只含有变异位点的SNP不变位点根本不在数据里。这种情况下如果不用ASC校正模型会低估不变位点的相对比例结果就是枝长被系统性拉长、模型参数出现偏差严重时影响拓扑结构。ASC让模型在已知所有位点都可变的前提下重新计算似然近似校正这种由于SNP筛选造成的偏差。我早期没有加ASC时树长得离奇尤其是根部枝长爆炸加上ASC之后整体才回归正常。你可以自己对比两个版本效果非常直观。4.3 分支支持率UFBoot2和SH-aLRT怎么配合IQtree跑完后-B 1000的UFBoot2和-alrt 1000的SH-aLRT会同时出现在树文件和报告文件里。前者是基于自举重采样的频率支持度后者是每个分支的似然比检验值。两者互补SH-aLRT对单分支的替代信号更敏感UFBoot2更看重整体重采样稳定性。我自己的经验判断标准SH-aLRT大于等于80且UFBoot大于等于95可以算强支持SH-aLRT大于等于70且UFBoot大于等于90算中等支持低于这个范围的分支写论文时我会谨慎描述不能硬撑。但这套标准是在正常分化尺度下用的。玉米不同亚群之间差异大支持度通常很高亚群内部的个体之间SNP差异很小很多短枝的支持率天然就低就算把所有位点都用上也很难改变。这时候别硬调参数把所有分支都撑到99那往往是过拟合。合理做法是承认分辨率边界用PCA或亲缘关系矩阵辅助解读近缘个体之间的位置。4.4 并行与内存控制的实际调优IQtree默认会用满机器上所有核心-T AUTO很方便但在共享服务器上我推荐手动指定核心数避免把节点资源全抢光iqtree2 -s maize.phy -m GTRASC -B 1000 -alrt 1000 -T 16 -mem 60G-mem限制最大内存使用量。几十万SNP、几百样本的情况下60G通常够用。如果内存不够先检查VCF是否压缩、是否包含大量无效位点实在不行就减少样本或位点量。我试过在内存只有32G的机器上跑30万SNP指定-mem 30G后勉强能跑但速度会明显变慢所以有条件还是优先保证CPU和内存的平衡。还有一个小建议建树之前先df -h看一眼磁盘剩余空间。IQtree在大数据量下会生成临时文件如果写满磁盘运行到一半报错或段错误排查起来非常痛苦。建议留出至少数据文件体积十几倍的空间。5. 结果解读与可视化从输出文件到发表级图片5.1 IQtree输出文件到底该怎么看一次完整的IQtree运行会生成一堆文件第一次跑的人容易看懵。我按重要性逐个说明maize.iqtree主报告纯文本。包含运行参数、最佳模型、碱基频率、有效位点数、树的分支支持率统计分析前必看maize.treefile最大似然树Newick格式每个分支都带着UFBoot和SH-aLRT支持值maize.contree基于UFBoot2得到的共识树如果想展示一个相对可信的拓扑一般用这个文件maize.model.gz压缩后的模型参数里面记录替换速率、均衡频率等maize.log运行日志排查问题用。打开.iqtree报告时我最先看三处开头的“Model of substitution”确认最终模型中间的“Number of informative sites”确认有效位点数树的部分看支持率分布。如果有效位点只有一两千个那后面描述得再漂亮都是虚的得回到过滤那一步放宽条件。5.2 三种常用的可视化路线拿到maize.contree之后可视化方式很多。最简单的是FigTree图形界面操作直接把Newick文件拖进去在Node Labels里选择显示支持率再导出PDF。适合快速看树形、检查样本分组。如果想做文章级别的图我推荐用R语言的ggtreelibrary(ape) library(ggtree) tr - read.tree(maize.contree) p - ggtree(tr, layoutcircular) geom_tiplab(size3) geom_nodelab(aes(labellabel), size2) ggsave(maize_tree.pdf, p, width10, height10)如果你有样本对应的群体信息可以映射到颜色上把不同亚群标出来比单纯黑白的树直观很多。还有在线工具iTOL上传树文件后可以通过网页调整颜色、形状、标签很多期刊里精致的进化树就是这么做的。必须提醒一句可视化解决的是展示问题不是验证问题。无论图上多好看结论都要回到.iqtree报告里的支持率和模型参数。如果支持率很低图上颜色再丰富也不能改变结论的可靠性。6. 避坑指南与问题排查6.1 我踩过的五个真实坑第一个坑是直接拿原始VCF跑IQtree没过滤多等位位点。当时跑了三个多小时快结束时报错VCF has multi-allelic sites整个人都很崩溃。后来把-m2 -M2放进预处理命令再也没出过这个问题。第二个坑是ASC校正。有一版树整体结构很奇怪所有个体之间的枝长都明显偏长根部距离大到不真实。群里的朋友提醒可能是SNP数据没有ASC校正我加上ASC重跑后树才正常。从那以后我默认只要是VCF里的多态SNP建树就至少跑一个含ASC的版本作对照。第三个坑是高缺失样本。我有一份玉米数据某个样本测序质量差缺失率接近70%。跑出来的树里这个样本被挂在很长的孤立枝条上接着这个长枝又拉低了周围几个分支的支持率。后来用vcftools查看了样本缺失率删掉这个样本后整棵树都稳定了。现在我在预处理阶段一定先看样本缺失率不让明显质量差的样本进树。第四个坑是模型选择耗时失控。早期拿到40万SNP直接-m MFPASC上模型选择阶段跑了快三个小时还没结束。后来改成先随机抽样3万位点、固定GTRASC模型做一个快速预跑确认拓扑合理之后再放全量数据跑效率提升非常明显。第五个坑是不做LD剪枝。当时用的SNP里有一段染色体区域因为参考基因组重复序列导致成百上千个连锁位点富集树的亚群结构严重偏向这个区域。剪枝之后重新跑树形才和已知系谱吻合。所以现在正式分析我都会同时跑剪枝和不剪枝两个版本防止单版本误导结论。6.2 常见报错速查表现象主要原因处理建议command not found: iqtree2PATH没有配置好检查~/.bashrc或使用绝对路径libgomp.so.1: cannot open shared object file缺少OpenMP运行库装libgomp或直接用conda环境VCF has multi-allelic sites多等位位点未过滤bcftools view -m2 -M2segmentation fault内存不足、文件损坏检查内存和磁盘用-mem限制重新生成VCF模型选择速度过慢位点太多抽样跑MFP或直接固定GTRASC几乎所有bootstrap都很低近缘个体多或信息位点不足增加位点、剔除高缺失样本调整对短枝支持率的预期树中某个样本长枝不自然混合样本、样本鉴定错误或缺失过高核查样本信息必要时剔除问题样本树拓扑与已知群体关系不符未加ASC、未做LD剪枝或样本标签错乱逐项排查先跑剪枝加ASC的版本对照最后再分享一个小技巧我在这类项目里从不只跑一棵树。同一份VCF我会同时生成一个“全位点GTRASC”版本和一个“剪枝后MFPASC”版本对比哪些分支稳定、哪些分支对位点选择敏感。如果两者差异很大说明数据里可能存在地区特异的信号或样本结构干扰需要进一步排查。这种多重对照的习惯比把宝押在一次运气好的运行上靠谱得多。