☰
GROMACS模拟文件全解析:.tpr/.xtc/.edr/.cpt的生成与避坑指南
2026/10/5 1:06:20 网站建设 项目流程

如果让我用一个词概括 GROMACS 模拟里最容易翻车的地方,我会选"文件"而不是"力场"。.tpr、.xtc、.edr、.cpt这四类文件贯穿了从 grompp 生成输入、mdrun 生产轨迹、再到期后分析的完整链条。很多人跑模拟只盯着 log 里的温度和压力,却不知道轨迹碎片化、续跑失败、能量统计跑偏,根子都在这几个文件的生成和使用细节上。这篇文章不打算展开讲分子模拟理论,只讲文件:四种文件各管什么、怎么生成、怎么校验、怎么在分析和续跑时避开最常见的坑。适合刚接触 GROMACS 的学生,也适合跑了好几年但偶尔还在文件上栽跟头的老人。

1. 先把四种文件的职能盘清楚,模拟流程才不会乱

1.1 一次模拟会"产出"哪些文件

很多新手第一次跑完 mdrun,看到目录里冒出来一大堆扩展名直接懵了。我先给一张全家福,把每个文件的角色说清楚。

文件全称/内容生成者典型用途
.tprrun input:拓扑、力场参数、坐标、速度、盒子、全部 mdp 参数gromppmdrun 的输入,也是后续所有分析工具对齐系统的"标准参照"
.xtc压缩轨迹:只含坐标,有损压缩mdrun结构分析、RMSD、距离、氢键等
.trr全精度轨迹:坐标+速度+力,无损mdrun需要速度/力的分析,文件极大
.edr能量数据:能量项、温度、压力、密度、体积等mdrun热力学量分析、平衡判断
.cpt检查点:完整模拟状态mdrun 周期写入断点续跑、扩展模拟
.gro坐标文件:末尾帧坐标mdrun下一阶段 grompp 的输入
.log运行日志与性能统计mdrun排查崩溃、查看步数
.mdp模拟参数用户编写grompp 输入
.top拓扑用户编写或 pdb2gmx 生成grompp 输入

这张表里最容易被忽略的是.tpr和.cpt的"锚点"属性。.tpr是空间上的锚点,所有分析都要靠它知道"这个体系由哪些原子组成、原子叫什么名字、力场参数是什么";.cpt是时间上的锚点,它记录了模拟进行到哪一步、当时体系处于什么状态。这两个文件一旦丢了或弄混,后面所有操作都会出问题。

1.2 文件之间的依赖顺序

正确的数据流是这样的:

  1. 用户准备.mdp(参数)、.top(拓扑)、.gro(坐标)。
  2. 执行gmx grompp,把三者打包成.tpr。
  3. 执行gmx mdrun,读入.tpr,产出.xtc、.edr、.cpt、.log和最终坐标.gro。
  4. 分析阶段,用.tpr + .xtc做结构分析,用.edr做热力学量分析,必要时用.cpt续跑。

我见过最典型的错误是把.tpr当成一次性用品。grompp跑完生成md.tpr,mdrun跑完,有人嫌文件乱,直接把md.tpr删了。等到要分析 RMSD 时,发现gmx rms -s没有参照物,只能重新 grompp 一个新 tpr。如果记忆中的力场版本、加氢方式、盐浓度有偏差,新 tpr 和旧 xtc 虽然是同一套原子,细节上已经有微妙差别,分析结果的说服力就打了折扣。所以我的第一条铁律是:模拟一旦开始,生成这个模拟的.tpr就要永久保留,和.xtc、.edr放在一起归档。

2. .tpr:模拟参数的"封存现场",grompp 的两个细节别跳过

2.1 grompp 到底把什么装进了 tpr

从功能上说,grompp 干的事相当于"把散落的零件组装成一台只能执行固定动作的机器"。你写的.mdp里每一项参数,.top里的每一根键、每一个电荷,.gro里的坐标和盒子信息,全都会被写进二进制的.tpr文件里。此后mdrun运行期间,GROMACS 完全按照.tpr里固化下来的参数执行,.mdp文件后续改了什么,它一概不认。

实际命令通常是:

gmx grompp -f md.mdp -c npt.gro -t npt.cpt -p topol.top -o md.tpr -r npt.gro

几个容易忽视的细节:

  • -c是输入坐标,-r是位置限制的参考结构。如果体系里有位置限制(比如把蛋白质重原子限制在初始位置),而-r没给或给错了文件,grompp 会把你-c提供的坐标当作参考。如果-c是续跑后的npt.gro,那问题不大;但如果你把-c换成别的结构(比如想换一个初始朝向),位置限制的参考也跟着换了,平衡阶段蛋白就会被慢慢推往你给定的新结构,这个偏差很隐蔽,跑完看 RMSD 才会发现。
  • -t是从 checkpoint 读取速度。从 NVT 接到 NPT 时,用-t nvt.cpt能保留已有的原子速度和耦合状态,避免重新从零初始化速度。很多人从 NPT 开始跑生产,-t不带,结果速度场重新随机化,前面 NVT/NPT 的平衡白做了一半。
  • -maxwarn只是"忽略警告计数",不是"解决问题"。grompp 遇到警告时,默认会停下来。加-maxwarn 1或-maxwarn 10能跳过一些非致命警告,但很多人把它当成万能钥匙,遇到任何 warning 都-maxwarn 10压过去。这里头最常见的隐患是"温度耦合组和索引组不匹配""盒子尺寸与坐标文件不一致""总电荷不为零"这类警告,它们往往意味着你的体系设置有问题,压掉警告等于带着装错零件的机器出厂。

2.2 换参数忘了重新 grompp,是最隐蔽的翻车点

我辅导过的学生里,几乎每个人都犯过同一个错:改完.mdp里的nsteps,直接执行gmx mdrun -s md.tpr,以为延长模拟只需要改步数就行。错得离谱。mdrun读的是.tpr,不是.mdp。你改参数的一瞬间,旧的md.tpr里固化的仍然是旧参数。你以为跑了 20 ns,实际上mdrun还是按原来nsteps跑,到时间就自然退出,log 里也看不出异常,因为 GROMACS 认为你本来就想跑那么长。

正确的做法是:修改.mdp后重新执行 grompp,生成新的.tpr,再用新的.tpr运行。但这里有个配套问题——如果你只是单纯想延长一段已经跑完的模拟,直接重新 grompp 会生成一个全新的.tpr,它和原来的.cpt在 GROMACS 的校验体系里对不上,续跑就会报错。这个情况我在第 5 节专门讲,正确工具是gmx convert-tpr,不是 grompp。

2.3 从 tpr 反查参数:没留 mdp 也能验尸

排错时,最常遇到的问题是"这个模拟当初到底用的什么参数?"如果 mdp 没进版本管理,别慌,.tpr里全都有。用:

gmx dump -s md.tpr | less

能翻出完整参数表,包括温度、压力、步长、每一步的时间、力场类型、非键作用参数、约束算法等等。我排查过几次"为什么两组模拟结果差异巨大"的案例,最后都是靠gmx dump -s对比发现其中一组 grompp 时用错了 mdp 文件,或者用了老版本的力场。所以排查的第一步永远是 dump 出 tpr 看参数,而不是盯着 xtc 里的奇怪构象猜原因。

另外,gmx check -s md.tpr会做基础一致性检查,能发现拓扑和坐标之间的原子数量不一致等问题。我习惯在归档前跑一遍这个命令,比把文件放三个月后再找问题省事得多。

3. .xtc:压缩轨迹用起来爽,分析前这几道手续不能省

3.1 xtc 和 trr 的取舍

.xtc是 GROMACS 默认输出的坐标轨迹,它做了有损压缩,只保留坐标,不保存速度和力。精度通常在千分之一纳米量级,对绝大多数结构分析(RMSD、距离、氢键、接触面积)完全够用。.trr则是什么都存,坐标、速度、力全都有,而且是无损全精度,文件体积轻松比.xtc大两个数量级。

我的建议很实际:默认跑.xtc就够,只有两种情况必须开.trr——一是你要用gmx trajectory做需要速度协方差的分析,二是你要做精确的动能/温度相关分析,或者需要精确还原坐标。.trr的开法是在.mdp里设置nstxout、nstvout、nstfout的步长,但注意频率不要设太高,否则一份几微秒的轨迹能把硬盘写爆。如果只是偶尔需要一帧的完整信息,trjconv -dump单帧导出可比全程开.trr划算得多。

3.2 PBC 处理:为什么分析的轨迹经常是"碎的"

这是分析阶段最高频的问题。MD 模拟开了周期边界(PBC),水盒子的原子流出左边界就会从右边界流回来,坐标文件里记录的是"折叠回盒子"后的位置。于是在.xtc里直接画图或算距离,会看到一条完整的蛋白链被拦腰截断,或者两个原子明明在物理上靠得很近,坐标却差出半个盒子。

解决办法是在分析前统一做一次 PBC 处理:

printf "Protein\nProtein\n" | gmx trjconv -s md.tpr -f md.xtc -o md_pbc.xtc -pbc mol -center

-pbc mol会把每个分子恢复完整后再决定怎么回卷,-center让蛋白一直待在盒子中央,方便可视化。执行时 trjconv 会要求你输入两次组名,一次是居中组,一次是输出组,上面命令里的两个Protein就对应这两次输入。

不同分析场景要选不同的-pbc选项,我整理成速查表:

你要做的分析推荐选项原因
RMSD、RMSF、距离、氢键-pbc mol分子恢复完整,直接可比
扩散系数(MSD)-pbc nojump消除原子跨盒子的"跳变",否则 MSD 被极大高估
可视化出图-pbc whole只补完整,不改写折叠逻辑,适合渲染
膜体系-pbc res或-pbc cluster防止脂分子和蛋白被盒子切断、甩散

这里我踩过一个实打实的坑:做扩散系数时没用-pbc nojump,结果水分子每跨一次边界,MSD 就多出几乎半个盒子平方的贡献,扩散系数算出来比文献值高了一个数量级。后来用-pbc nojump处理后再算,数值立刻回到正常范围。所以别嫌多一步脏活,这一步直接决定定量分析对不对。

3.3 轨迹拼接和完整性校验

跑长模拟被集群作业超时中断是常态,你可能会得到md_part1.xtc、md_part2.xtc好几段轨迹。拼接用:

gmx trjcat -f md_part1.xtc md_part2.xtc -o md_all.xtc

如果两段轨迹在时间上有重叠(比如因为续跑时没正确 append),直接拼接会出现重复帧,后面算时间平均时会莫名其妙地偏向重叠区。所以拼接前先各跑一遍gmx check -f,看每段轨迹的起始和结束时间,确认没有重叠再拼。

gmx check还有另一个妙用:核对轨迹和能量文件时间轴是否对齐。

gmx check -f md.xtc -f2 md.edr

它会打印两个文件各自覆盖的时间范围,如果轨迹产出 10000 步而能量文件只记到 9000 步,说明模拟在最后阶段被异常中断,能量文件缺了尾巴,后续算温度平均时就得小心。这条检查我建议每次分析前必跑,成本极低,收益极高。

4. .edr:热力学量的"体检表",别只会看温度一条线

4.1 先澄清一个命名误会

如果你是搜到这篇文章的,可能查过.edr相关的"检测""卸载""占用资源"这些词。这里必须说明:那些词指的是终端安全防护工具,和 GROMACS 的.edr没有任何关系。GROMACS 里.edr是 energy data file 的缩写,一个二进制格式的能量数据库,每次 mdrun 都会自动产出,记录每个输出步的能量项、温度、压力、密度、体积等状态量。它只能被 GROMACS 自己的工具读取,不要试图用文本编辑器打开。

4.2 gmx energy 的正确打开方式

分析能量文件的主工具是gmx energy。基本用法:

gmx energy -f md.edr -o temperature.xvg -b 1000 -e 5000 -xvg none

执行后工具会列出所有能量项,每个项前面有编号。输入编号(可以同时选多个,用空格分隔),最后输入0结束选择。结束后它不只导出数据,还会在屏幕上打印一张统计表,包含每个能量项的平均值、标准误差、RMSD 涨落和总漂移。这张表很多人不看,其实它是判断平衡是否到位最直接的证据。

选中 "Temperature" 时要注意:如果你的 mdp 里设了多个温度耦合组(比如tc-grps = Protein Non-Protein),能量项列表里会有Temperature-Protein、Temperature-non-Protein和总的Temperature好几个相似项。别随手选第一个,要想清楚你关心的是哪个对象的温度。我就见过有人把蛋白质组的温度当体系温度汇报,差了好几 K 还没发现。

-b和-e参数的单位是皮秒(ps),用来跳过平衡段。生产模拟一般是前面几百 ps 平衡,后面的几十 ns 才能用于统计。不加-b直接全段平均,平衡期的温度弛豫会把平均值拉偏,等温线看起来达不到目标温度,很多人误以为温控坏了,其实只是统计范围错了。

4.3 最容易骗到自己的三个数值细节

第一,压力只看瞬时值或短区间平均没有意义。水盒子里的瞬时压力波动经常在 ±200 bar 量级,这是正常的机械涨落。要判断 NPT 平衡是否达到目标压力 1 bar,至少取几千步以上的平均,看gmx energy统计表里的平均压力和总漂移。如果平均值在 1 bar 附近且漂移很小,才算真正平衡。

第二,能量单位是 kJ/mol 不是 kcal/mol。同样一个数,数值上差 4.184 倍。写成文章时如果想用 kcal/mol,记得除以 4.184,并注明换算关系。压强单位是 bar,密度单位是 kg/m³,换算成常用的 g/cm³ 要除以 1000。

第三,看能量图时,重点不是单个时刻的势能绝对值,而是它的漂移趋势。平衡良好的体系,势能应该围绕一个稳定值上下小幅波动;如果势能一路下行不带回头,说明体系还在缓慢结构调整,这时做的任何时间平均都不可靠。用gmx energy选 "Potential" 导出后,直接看曲线的后 1/3 是否平,比看平均值更直观。

5. .cpt:续跑和扩产的正确姿势,别让几千步白跑

5.1 checkpoint 里到底存了什么

.cpt是模拟的完整快照:所有原子的坐标、速度、力,盒子向量,每一步的能量累加器,还有热浴和压浴的耦合器内部状态,连随机数生成器的状态都记在里面。这就是为什么它比.gro大得多,也是为什么只有它能做真正的"无缝续跑"。

如果没有.cpt,你只能从md.gro(最终坐标)重新开始,但原子速度需要重新随机初始化,温度耦合器的历史状态也没了。后续几万步,体系会重新经历一段"遗忘旧状态"的过程,这段轨迹的统计价值和连续模拟相比要大打折扣。所以在集群上跑任务,.cpt比.xtc还娇贵,丢了它,前面几百度 CPU 小时基本白烧。

mdrun 默认每隔一段时间自动写一次 checkpoint(默认约 15 分钟,可用 mdrun 的-cpt参数修改,或在.mdp里设置nstcheckpoint按步数控制)。作业被中断后,找到最新的.cpt就能续跑。

5.2 续跑命令与 append 的讲究

最常见的续跑命令:

gmx mdrun -deffnm md -cpi md.cpt -append -v

-cpi指定 checkpoint 文件,-append让新产生的轨迹和能量直接追加到已有的.xtc、.edr后面,时间轴保持连续。在 GROMACS 较新版本里-append是默认行为,但我习惯显式写出来,因为这样命令本身就能说明意图,半年后再回看命令历史也一目了然。

如果你忘了写-cpi,mdrun 会闷头从 step 0 重新跑一遍,而且日志里不会主动提醒你"你本来应该续跑"。等你看时间线才发现不对,已经又跑掉几万步。另一个常见失误是在有旧输出文件的情况下直接重跑,GROMACS 可能会拒绝覆盖现有轨迹文件。这时候不要急着删文件,先用gmx check看看旧轨迹的时间范围,确认没有价值再清理。

5.3 扩展模拟用 convert-tpr,而不是重新 grompp

想延长一段已经跑完或正在跑的模拟,新手会改.mdp里的nsteps再 grompp,然后用新.tpr加旧.cpt续跑。GROMACS 会报错,告诉你 tpr 和 checkpoint 不匹配——因为两个 tpr 的参数指纹对不上,系统拒绝把旧状态硬塞进新参数模板里。

正确做法是用gmx convert-tpr只修改停止条件:

gmx convert-tpr -s md.tpr -extend 100000 -o md_ext.tpr gmx mdrun -s md_ext.tpr -cpi md.cpt -deffnm md -append -v

-extend的单位是 ps,含义是"在原有停止时间基础上延长这么长时间"。如果不喜欢相对延长,可以用-until直接指定绝对停止时间。这个工具只改停止时间,其他所有参数都保持原样,所以生成的md_ext.tpr能被md.cpt接受。

同理,如果你希望跑完的体系在相同条件下多跑几段,每次都该走convert-tpr路线,而不是重新 grompp。重新 grompp 生成的 tpr 和旧 checkpoint 没有血缘关系,续跑必然失败。

5.4 续跑后核对时间轴

续跑完成后,别急着分析。先做两件事:一是打开md.log看开头有没有 "Restarting from checkpoint" 之类的记录,确认读对了 checkpoint;二是跑gmx check -f md.xtc -f2 md.edr,看轨迹和能量的时间轴是否都延伸到预期终点。如果 xtc 只到一半而 edr 到了终点,说明续跑过程中轨迹写入出了状况,可能需要回去找更早的 checkpoint 重跑。

另外提醒一点:-append续跑会把新轨迹追加进同一个文件,这个文件在续跑前后的完整性依赖 GROMACS 内部的写入逻辑,正常情况下安全。但如果你的集群环境在续跑过程中又崩了一次,那就以最新的.cpt继续下一次续跑即可,不要手动去改 xtc 文件。

6. 一条龙实例:从 grompp 到能量统计的完整命令链

6.1 一套可直接套用的三阶段流程

假设你已经从 pdb2gmx 得到了protein.gro和topol.top,以下是我常用的完整流程:

# NVT 平衡 gmx grompp -f nvt.mdp -c protein.gro -p topol.top -o nvt.tpr gmx mdrun -deffnm nvt -v # NPT 平衡:继承 NVT 的坐标和速度 gmx grompp -f npt.mdp -c nvt.gro -t nvt.cpt -p topol.top -o npt.tpr -r nvt.gro gmx mdrun -deffnm npt -v # 生产模拟:继承 NPT 的坐标和速度 gmx grompp -f md.mdp -c npt.gro -t npt.cpt -p topol.top -o md.tpr -r npt.gro gmx mdrun -deffnm md -v

生产跑完后,标准分析链:

# 1. PBC 处理 printf "Protein\nProtein\n" | gmx trjconv -s md.tpr -f md.xtc -o md_pbc.xtc -pbc mol -center # 2. 骨架 RMSD printf "Backbone\nBackbone\n" | gmx rms -s md.tpr -f md_pbc.xtc -o rmsd.xvg # 3. 只统计生产段的温度(假设前 1000 ps 是平衡段) printf "Temperature\n" | gmx energy -f md.edr -o temp_prod.xvg -b 1000 -e 10000 -xvg none

这套流程我把每个阶段的-t都显式带上了,就是为了让速度场和耦合器状态一路继承下去。很多人省掉-t也能跑,但模拟前段会有一段重新平衡的尾巴,等于每换一次系综就浪费一部分计算资源。

6.2 常见报错速查表

为了让你排查时不抓瞎,我把这些年见过的高频问题整理成了一张表:

现象/报错根本原因处理办法
Mismatch between checkpoint and tpr续跑用的 tpr 不是产生这个 cpt 的那个 tpr找回原 tpr;想延长时间用gmx convert-tpr,不要重新 grompp
log 里显示 From step 0,而你以为在续跑忘了加-cpi中断后立即用-cpi 最新的.cpt -append重启
Group 'Backbone' not found索引文件里没有这个组用gmx make_ndx -f md.gro生成 index.ndx,分析命令加-n index.ndx
轨迹里分子碎成几段没做 PBC 处理trjconv 加-pbc mol(扩散分析用nojump)
温度涨落几百 K,怎么都压不下平衡段没截掉,或选错了温度耦合组gmx energy加-b-e只统计生产段;核对温度组名
grompp 警告一堆,-maxwarn 10压掉后跑完结果离谱maxwarn 只是忽略警告,不解决问题逐条读警告,尤其是盒子尺寸、温度耦合组、电荷总量这几类

6.3 我自己的归档与自检习惯

最后分享几个已经形成肌肉记忆的习惯。

我在集群上跑生产模拟,提交脚本里会写一段"自动续跑"逻辑:如果存在md.cpt,就执行mdrun -s md.tpr -cpi md.cpt -append;如果不存在,才从头开始跑。这样作业排队超时、节点被杀,下次重新提交时自动从断点接着跑,不用人肉盯。

每次生产模拟结束后,我会把md.tpr、md.cpt、md.gro、md.xtc、md.edr五件套放在一个独立目录并设为只读,然后跑一遍gmx check -f md.xtc -f2 md.edr确认时间轴完整。归档前我会顺手用gmx dump -s md.tpr | grep -i "nsteps"之类的方式再确认一次步数和时间设定。这些小动作看起来琐碎,但能挡住绝大多数"模拟白跑"的惨剧。

写完这些,回头想想,这四种文件其实对应着模拟的四个关键词:.tpr是"确定性",.xtc是"采样",.edr是"验证",.cpt是"可持续"。能把这四个关键词吃透,GROMACS 这条路你会走得比大多数人稳。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询