Visualizing Optimization Trajectories¶
eOn can embed structured per-iteration metadata directly into trajectory movie
frames when write_movies = true is set in the [Debug] section of
config.ini. These metadata-rich .con movies enable rich 2D reaction-valley
projections and convergence plots via
rgpycrumbs and
chemparseplot.
For one compatibility window, write_deprecated_outs = true can also be used
to emit the older minimization and saddle-search .dat sidecars. NEB continues
to write its existing neb.dat / neb_*.dat outputs alongside the .con
movies.
This tutorial walks through two complete workflows with PET-MAD:
a single-ended minimization of a perturbed vinyl alcohol structure
an OCI-NEB calculation for vinyl alcohol -> acetaldehyde
For each workflow we run eonclient, then visualize the result through the
public rgpycrumbs dispatcher so the tutorial matches current command-line
usage.
Setup¶
Minimization¶
We start by minimizing a slightly distorted vinyl alcohol molecule to
demonstrate the single-ended optimization outputs consumed by
rgpycrumbs eon plt-min.
Energy profile¶
min_profile = plot_dir / "min_profile.png"
run_rgpycrumbs(
"eon", "plt-min",
"--job-dir", str(min_dir),
"--prefix", "minimization",
"--plot-type", "profile",
"--dpi", "150",
"--output", str(min_profile),
)
show_plot(min_profile)
$ /home/runner/work/eOn/eOn/.pixi/envs/docs-mta/bin/python3.12 -m rgpycrumbs.cli eon plt-min --job-dir /tmp/eon_tutorial_mccjsfde/minimization --prefix minimization --plot-type profile --dpi 150 --output /tmp/eon_tutorial_mccjsfde/plots/min_profile.png
---------------------------------------------------------------------------
KeyboardInterrupt Traceback (most recent call last)
Cell In[5], line 2
1 min_profile = plot_dir / "min_profile.png"
----> 2 run_rgpycrumbs(
3 "eon", "plt-min",
4 "--job-dir", str(min_dir),
5 "--prefix", "minimization",
6 "--plot-type", "profile",
7 "--dpi", "150",
8 "--output", str(min_profile),
9 )
10 show_plot(min_profile)
Cell In[3], line 30, in run_rgpycrumbs(group, command, cwd, timeout, *args)
24 def run_rgpycrumbs(group, command, *args, cwd=None, timeout=600):
25 # 600s caps first-call rgpycrumbs overhead on the weakest GHA runner.
26 # Landscape plots (grad_matern / grad_imq surface fits) dominate wall
27 # time; profile and convergence panels land well under a minute locally,
28 # but cold matplotlib + CLI import on ubuntu-latest has been observed
29 # past the old 180s ceiling.
---> 30 return run_cli_or_raise(
31 [sys.executable, "-m", "rgpycrumbs.cli", group, command, *args],
32 cwd=cwd,
33 timeout=timeout,
34 )
Cell In[3], line 8, in run_cli_or_raise(args, cwd, timeout)
6 def run_cli_or_raise(args, *, cwd=None, timeout=300):
7 print("$", " ".join(args))
----> 8 result = subprocess.run(
9 args,
10 cwd=cwd,
11 capture_output=True,
12 text=True,
13 timeout=timeout,
14 )
15 if result.stdout:
16 print(result.stdout)
File ~/work/eOn/eOn/.pixi/envs/docs-mta/lib/python3.12/subprocess.py:550, in run(input, capture_output, timeout, check, *popenargs, **kwargs)
548 with Popen(*popenargs, **kwargs) as process:
549 try:
--> 550 stdout, stderr = process.communicate(input, timeout=timeout)
551 except TimeoutExpired as exc:
552 process.kill()
File ~/work/eOn/eOn/.pixi/envs/docs-mta/lib/python3.12/subprocess.py:1209, in Popen.communicate(self, input, timeout)
1206 endtime = None
1208 try:
-> 1209 stdout, stderr = self._communicate(input, endtime, timeout)
1210 except KeyboardInterrupt:
1211 # https://bugs.python.org/issue25942
1212 # See the detailed comment in .wait().
1213 if timeout is not None:
File ~/work/eOn/eOn/.pixi/envs/docs-mta/lib/python3.12/subprocess.py:2115, in Popen._communicate(self, input, endtime, orig_timeout)
2108 self._check_timeout(endtime, orig_timeout,
2109 stdout, stderr,
2110 skip_check_and_raise=True)
2111 raise RuntimeError( # Impossible :)
2112 '_check_timeout(..., skip_check_and_raise=True) '
2113 'failed to raise TimeoutExpired.')
-> 2115 ready = selector.select(timeout)
2116 self._check_timeout(endtime, orig_timeout, stdout, stderr)
2118 # XXX Rewrite these to use non-blocking I/O on the file
2119 # objects; they are no longer using C stdio!
File ~/work/eOn/eOn/.pixi/envs/docs-mta/lib/python3.12/selectors.py:415, in _PollLikeSelector.select(self, timeout)
413 ready = []
414 try:
--> 415 fd_event_list = self._selector.poll(timeout)
416 except InterruptedError:
417 return ready
KeyboardInterrupt:
2D optimization landscape¶
min_landscape = plot_dir / "min_landscape.png"
run_rgpycrumbs(
"eon", "plt-min",
"--job-dir", str(min_dir),
"--prefix", "minimization",
"--plot-type", "landscape",
"--project-path",
"--surface-type", "grad_matern",
"--plot-structures", "endpoints",
"--strip-renderer", "xyzrender",
"--perspective-tilt", "8",
"--dpi", "150",
"--output", str(min_landscape),
)
show_plot(min_landscape)
Convergence panel¶
min_convergence = plot_dir / "min_convergence.png"
run_rgpycrumbs(
"eon", "plt-min",
"--job-dir", str(min_dir),
"--prefix", "minimization",
"--plot-type", "convergence",
"--dpi", "150",
"--output", str(min_convergence),
)
show_plot(min_convergence)
Nudged Elastic Band¶
We run an OCI-NEB calculation on the vinyl alcohol -> acetaldehyde keto-enol tautomerization using PET-MAD.
Energy profile¶
neb_profile = plot_dir / "neb_profile.png"
run_rgpycrumbs(
"eon", "plt-neb",
"--input-dat-pattern", str(neb_dir / "neb_*.dat"),
"--con-file", str(neb_dir / "neb.con"),
"--ira-kmax", "14",
"--force-recompute",
"--rc-mode", "rmsd",
"--plot-type", "profile",
"--plot-structures", "crit_points",
"--strip-renderer", "xyzrender",
"--perspective-tilt", "8",
"--zoom-ratio", "0.15",
"--dpi", "150",
"--output-file", str(neb_profile),
)
show_plot(neb_profile)
2D reaction landscape¶
neb_landscape = plot_dir / "neb_landscape.png"
run_rgpycrumbs(
"eon", "plt-neb",
"--input-dat-pattern", str(neb_dir / "neb_*.dat"),
"--input-path-pattern", str(neb_dir / "neb_path_*.con"),
"--con-file", str(neb_dir / "neb.con"),
"--ira-kmax", "14",
"--force-recompute",
"--rc-mode", "rmsd",
"--plot-type", "landscape",
"--surface-type", "grad_imq",
"--show-pts",
"--landscape-path", "all",
"--project-path",
"--plot-structures", "crit_points",
"--strip-renderer", "xyzrender",
"--strip-dividers",
"--perspective-tilt", "8",
"--zoom-ratio", "0.2",
"--show-legend",
"--dpi", "150",
"--output-file", str(neb_landscape),
)
show_plot(neb_landscape)
See also¶
For producing your own NEB trajectories beyond this tutorial:
The
eon-pet-nebexample in the lab-cosmo/atomistic-cookbook: a step-by-step PET-MAD NEB walkthrough using ASE for path setup. This is the canonical metatomic-consumer integration test for eOn.HaoZeke/eon_orchestrator: Snakemake-orchestrated workflow for batches of NEB calculations with PET-MAD, including IRA pre-alignment, endpoint minimization, energy profiles, and 2D RMSD landscapes. The vinyl alcohol config used in this tutorial is taken from
examples/vinyl_alcohol/.
Further reading¶
rgpycrumbs documentation for advanced options (structure rendering, multiple trajectory overlays, custom themes)
Minimization and Saddle Search for output file details
Dictionary-Style Configuration for programmatic configuration