04 - 过渡态前后体表示¶
本 Notebook 展示过渡态的标准前后体,以及固定成键或断键相关原子后重新扫描其余原子得到的额外采样前后体。额外采样结果不会替换标准推断。
实际使用时先保留标准端点的三维构象,再调用额外采样接口:
standard_pre, standard_post = ts_frame.possible_pre_post_ts(show_3D=True)
additional_pre, additional_post = ts_frame.additional_pre_post_ts(
standard_pre, standard_post
)
下面的代码从随文档提供的 Gaussian TS 输出读取 frame,直接完成标准前后体推断和额外采样,再在 Notebook 中绘图。上半部分保留标准前后体,下半部分展示额外采样前后体;每个面板的 legend 标出碎片数。还会调用 to_diff_rdmol() 查看键变化差异图。
In [1]:
Copied!
from pathlib import Path
from IPython.display import SVG, display
from rdkit import Chem
from rdkit_dof import MolsToGridDofImage
from molop import AutoParser, molopconfig
molopconfig.quiet()
sample_candidates = (
Path("docs/assets/examples/ts_endpoint_additional_sampling.log"),
Path("../../assets/examples/ts_endpoint_additional_sampling.log"),
Path("ts_endpoint_additional_sampling.log"),
)
sample_path = next((path for path in sample_candidates if path.is_file()), None)
if sample_path is None:
raise FileNotFoundError("请将 ts_endpoint_additional_sampling.log 放在 Notebook 同目录,或使用文档中的样例文件。")
batch = AutoParser(sample_path, n_jobs=1, only_last_frame=True)
ts_frame = next((frame for frame in batch[0] if frame.is_TS), None)
if ts_frame is None:
raise ValueError("样例文件中没有找到过渡态 frame。")
standard_pre, standard_post = ts_frame.possible_pre_post_ts(show_3D=True)
additional_pre, additional_post = ts_frame.additional_pre_post_ts(
standard_pre, standard_post
)
endpoint_molecules = [standard_pre, standard_post, additional_pre, additional_post]
labels = [
f"standard pre | {len(Chem.GetMolFrags(standard_pre))} fragments",
f"standard post | {len(Chem.GetMolFrags(standard_post))} fragments",
f"additional-sampling pre | {len(Chem.GetMolFrags(additional_pre))} fragments",
f"additional-sampling post | {len(Chem.GetMolFrags(additional_post))} fragments",
]
print("输入文件:", sample_path)
print("标准前后体碎片数:", len(Chem.GetMolFrags(standard_pre)), len(Chem.GetMolFrags(standard_post)))
print("额外采样前后体碎片数:", len(Chem.GetMolFrags(additional_pre)), len(Chem.GetMolFrags(additional_post)))
difference = ts_frame.to_diff_rdmol()
if difference is None:
raise ValueError("样例文件中没有得到键变化差异图。")
changed_bonds = [
bond for bond in difference.GetBonds() if bond.GetBondType() == Chem.BondType.ZERO
]
print("差异图键数:", difference.GetNumBonds())
print("其中的 ZERO 键数:", len(changed_bonds))
svg = MolsToGridDofImage(
endpoint_molecules,
molsPerRow=2,
subImgSize=(380, 320),
legends=labels,
use_svg=True,
return_image=False,
)
if not isinstance(svg, str):
raise RuntimeError("rdkit-dof 没有返回 SVG 图像。")
display(SVG(data=svg))
difference_svg = MolsToGridDofImage(
[difference],
molsPerRow=1,
subImgSize=(760, 320),
legends=["to_diff_rdmol | ZERO bonds mark changes"],
use_svg=True,
return_image=False,
)
if not isinstance(difference_svg, str):
raise RuntimeError("rdkit-dof 没有返回差异图 SVG。")
display(SVG(data=difference_svg))
from pathlib import Path
from IPython.display import SVG, display
from rdkit import Chem
from rdkit_dof import MolsToGridDofImage
from molop import AutoParser, molopconfig
molopconfig.quiet()
sample_candidates = (
Path("docs/assets/examples/ts_endpoint_additional_sampling.log"),
Path("../../assets/examples/ts_endpoint_additional_sampling.log"),
Path("ts_endpoint_additional_sampling.log"),
)
sample_path = next((path for path in sample_candidates if path.is_file()), None)
if sample_path is None:
raise FileNotFoundError("请将 ts_endpoint_additional_sampling.log 放在 Notebook 同目录,或使用文档中的样例文件。")
batch = AutoParser(sample_path, n_jobs=1, only_last_frame=True)
ts_frame = next((frame for frame in batch[0] if frame.is_TS), None)
if ts_frame is None:
raise ValueError("样例文件中没有找到过渡态 frame。")
standard_pre, standard_post = ts_frame.possible_pre_post_ts(show_3D=True)
additional_pre, additional_post = ts_frame.additional_pre_post_ts(
standard_pre, standard_post
)
endpoint_molecules = [standard_pre, standard_post, additional_pre, additional_post]
labels = [
f"standard pre | {len(Chem.GetMolFrags(standard_pre))} fragments",
f"standard post | {len(Chem.GetMolFrags(standard_post))} fragments",
f"additional-sampling pre | {len(Chem.GetMolFrags(additional_pre))} fragments",
f"additional-sampling post | {len(Chem.GetMolFrags(additional_post))} fragments",
]
print("输入文件:", sample_path)
print("标准前后体碎片数:", len(Chem.GetMolFrags(standard_pre)), len(Chem.GetMolFrags(standard_post)))
print("额外采样前后体碎片数:", len(Chem.GetMolFrags(additional_pre)), len(Chem.GetMolFrags(additional_post)))
difference = ts_frame.to_diff_rdmol()
if difference is None:
raise ValueError("样例文件中没有得到键变化差异图。")
changed_bonds = [
bond for bond in difference.GetBonds() if bond.GetBondType() == Chem.BondType.ZERO
]
print("差异图键数:", difference.GetNumBonds())
print("其中的 ZERO 键数:", len(changed_bonds))
svg = MolsToGridDofImage(
endpoint_molecules,
molsPerRow=2,
subImgSize=(380, 320),
legends=labels,
use_svg=True,
return_image=False,
)
if not isinstance(svg, str):
raise RuntimeError("rdkit-dof 没有返回 SVG 图像。")
display(SVG(data=svg))
difference_svg = MolsToGridDofImage(
[difference],
molsPerRow=1,
subImgSize=(760, 320),
legends=["to_diff_rdmol | ZERO bonds mark changes"],
use_svg=True,
return_image=False,
)
if not isinstance(difference_svg, str):
raise RuntimeError("rdkit-dof 没有返回差异图 SVG。")
display(SVG(data=difference_svg))
输入文件: ../../assets/examples/ts_endpoint_additional_sampling.log 标准前后体碎片数: 3 2 额外采样前后体碎片数: 3 2
差异图键数: 48 其中的 ZERO 键数: 5