pymatgen:分子匹配、构象与去重
比较乙醇的旋转、原子重排、受控扭转及二甲醚,区分几何匹配和按编号比较连接。
阅读本篇目录
两个XYZ看起来不一样,可能只是分子转了方向,也可能是原子顺序变了、构象变了,或者已经是不同异构体。先确定要比较什么,再选择接口。
本例使用实际GFN2乙醇和二甲醚几何,另对乙醇做整体旋转/平移、原子倒序,以及绕C–O键转动羟基H的90°受控变换。受控扭转结构没有重新优化,也没有新的能量。
unzip pymatgen-molecule-tools-wave712-*.zip
cd pymatgen-molecule-tools
bash prepare.sh
bash run.sh
bash plot.sh
环境为pymatgen2026.9.24、Python3.11及个人目录OpenBabel3.1.0。准备步骤见分子成键图。

1. 先列清比较对象#
| 名称 | 操作 | 是否有新量化能量 |
|---|---|---|
| ethanol | 实际GFN2优化结构 | 沿用原计算 |
| rotated-ordered | 整体旋转和平移,原子顺序保留 | 没有 |
| rotated-permuted | 同样旋转和平移,再倒序原子 | 没有 |
| controlled-OH-torsion | 只把羟基H绕C–O轴转动90° | 没有 |
| dimethyl-ether | 实际优化的同分子式异构体 | 独立GFN2结构 |
旋转和平移保持结构本身;原子重排改变文件行号。受控扭转则改变内部几何,不能把它当作已经松弛的低能构象。
2. 用MoleculeMatcher找原子映射#
bash python.sh - <<'PY'
from pymatgen.core import Molecule
from pymatgen.analysis.molecule_matcher import MoleculeMatcher
a = Molecule.from_file('inputs/ethanol.xyz')
b = Molecule.from_file('reference-structures/ethanol-rotated-permuted.xyz')
matcher = MoleculeMatcher(tolerance=0.01)
print('RMSD / Å:', matcher.get_rmsd(a, b))
print('是否匹配:', matcher.fit(a, b))
PY
该接口寻找原子映射并对齐几何,可以识别整体旋转、平移和等价原子重排。本例仍匹配;XYZ输出精度会留下很小的数值RMSD,不必要求每个坐标文本完全相同。
get_rmsd返回Å;找不到适用映射时可能返回None,不能当作0。fit还应用设定的RMSD容差。本例0.01Å是用于几何一致性演示的阈值,热运动轨迹和不同优化精度的数据需另行选择。
3. 为什么另一个接口得到不同结果#
bash python.sh - <<'PY'
from pymatgen.core import Molecule
from pymatgen.analysis.molecule_structure_comparator import MoleculeStructureComparator
a = Molecule.from_file('inputs/ethanol.xyz')
b = Molecule.from_file('reference-structures/ethanol-rotated-permuted.xyz')
c = Molecule.from_file('reference-structures/ethanol-controlled-OH-torsion.xyz')
comparator = MoleculeStructureComparator()
print('重排后:', comparator.are_equal(a, b))
print('受控扭转后:', comparator.are_equal(a, c))
PY
本例分别为False和True。这个比较器按原子编号检查连接:重排后需要先对齐编号;受控扭转没有改变本例的连接,所以仍被视为相同。它不判断两个构象是否几何重合,也不计算构象能量。
二甲醚与乙醇分子式相同,但连接不同,本例两个接口均将其区分。仅按分子式去重会丢掉这类异构体信息。
4. 实际分组#
cat reference-data/Molecule-matching-matrix.csv
按本例几何匹配阈值,五个对象分为3、1、1三个组:原始/整体旋转/原子重排乙醇为一组;受控扭转乙醇和二甲醚分别单列。
批量使用时,把Molecule对象列表交给:
groups = matcher.group_molecules(molecules)
print([len(group) for group in groups])
真实构象搜索还应保存每个构象的优化状态和能量,几何去重之后再按适用的能量或自由能排序。匹配分组本身没有判断哪个构象更稳定。
5. 换自己的数据#
先统一元素、氢原子、电荷/自旋信息与坐标单位。需要几何重合时用映射与RMSD;需要按固定原子序号比较成键变化时,保留同一编号,再检查成键规则和距离阈值。
读取已有参考结果用results.sh,完整实际分析用run.sh,图片生成到figures。接口见pymatgen分子匹配和结构比较器。