reactiontools
A centralised set of tools for looking at transition state (TS) and nudged elastic band (NEB) calculations.
reactiontools wraps the parts of an ASE
reaction-path workflow that get rewritten in every project: interpolating a
band, relaxing the endpoints, pulling the TS image out and refining it to a
true saddle point, following the IRC away from it, driving PLUMED, and
producing publication-ready figures with consistent styling.
It also holds the collective variables an enhanced-sampling run is biased
along — tools_cv for proton transfer, tools_path for turning a steered
trajectory into a PATHMSD reference. Those are written
as text for whatever runs PLUMED, so they are equally usable from an ASE run
here or from an OpenMM one driven by
openmmnqe, which depends on this
package for exactly that.
It is calculator-agnostic — anything that behaves like an ASE calculator works, from EMT to a machine-learned potential to a DFT code.
Installation
pip install reactiontools
That covers everything. The saddle-point searches and geodesic interpolation
need nothing extra: both are part of the package, in tools_sella and
tools_geodesic. The one thing still installed separately is ORCA, which
tools_orca shells out to and which is licensed separately.
For everything at once, including PLUMED built with the OPES module, one command from the repository root:
bash build_tools/conda_install.sh
That creates the reactiontools conda environment, compiles PLUMED and the
matching Python bindings into it, and installs this package in editable mode.
For the environment-only route, the dependencies that fall outside pip
(the plumed executable, py-plumed and ORCA), and the Sol cluster, see
Installation or
build_tools/README.md.
Quickstart
Relax two endpoints, run a climbing-image NEB between them, and plot the barrier. This example is a gold adatom hopping between hollow sites on an Al(100) surface, and runs in a few seconds with EMT:
from ase.build import add_adsorbate, fcc100
from ase.calculators.emt import EMT
from ase.constraints import FixAtoms
from reactiontools import (
optimise_neb,
optimise_reactant_product,
plot_neb,
prepare_neb,
summarise_neb,
)
calc = EMT()
slab = fcc100("Al", size=(2, 2, 3))
add_adsorbate(slab, "Au", 1.7, "hollow")
slab.center(axis=2, vacuum=4.0)
slab.set_constraint(FixAtoms(mask=[atom.tag > 1 for atom in slab]))
reactant = slab.copy()
product = slab.copy()
product.positions[-1, 0] += product.cell[0, 0] / 2 # hop to the next site
reactant, product = optimise_reactant_product(reactant, product, calc, fmax=0.05)
# rm_ro_trans=False: the slab is periodic and constrained, so the rigid-body
# degrees of freedom are already pinned -- see the NEB guide.
neb = prepare_neb(
reactant, product, calc, n_images=7, climb=True, rm_ro_trans=False, geo_int=False
)
images = optimise_neb(neb, fmax=0.05, ts_traj="ts.traj")
print(summarise_neb(images))
plot_neb(images, calc, filename="neb")
This converges in 17 NEB steps and prints:
Barrier: 0.374 eV
Reverse barrier: 0.374 eV
Reaction energy: 0.000 eV
TS image: 3 of 6
plot_neb writes neb.png and neb.pdf, with energies referenced to the
lowest image and reported in meV.
Documentation
Full documentation is at reactiontools.readthedocs.io.
- Installation — environment, PLUMED, ORCA
- Nudged elastic bands — settings, reading a band, convergence, optimisers
- Continuing a band
- Sockets and parallel bands
- Refining the transition state
- Building end states
- Running metadynamics
- PLUMED post-processing
- Units — eV/Å against kJ/mol/nm, and the factor-of-ten trap between them
- API reference — every public function and class, generated from the docstrings
Testing
The test runner and the linter are not runtime dependencies; install the dev
extra to get them:
pip install -e ".[dev]"
pytest --cov
The suite builds its own structures with ase.build and evaluates them with
EMT. Offline unit tests cover orchestration without opening sockets; a small
set of integration tests exercises real local socket transport when the
runner permits it. Checks needing ORCA, PLUMED or OpenMM skip when those are
unavailable, so a plain pip install -e ".[dev]" runs the suite green. The
saddle-point and IRC tests always run: tests/test_sella.py is the upstream
Sella suite, brought across with the module it exercises. Coverage is
branch-aware and enforces the configured floor.
CI tests Python 3.12–3.14 and also tests the minimum scientific, pytest and Ruff
versions together on Python 3.12. To reproduce that environment, install with
pip install -c .github/requirements-min.txt -e ".[dev]" in a fresh Python 3.12
environment. Keep those constraints in step with the bounds in pyproject.toml.
Citing
If reactiontools is useful in your work, please cite it and whichever of the
codes it wraps you actually exercised. Every entry is in
CITATIONS.bib, and
Citing says which to use for what.
License
MIT, with one exception — see LICENSE.
reactiontools/tools_sella.py is derived from
Sella and is LGPL-3.0-or-later, not
MIT, as the code it derives from is: copyright Sandia National Laboratories
(NTESS) under US Government contract DE-NA0003525. The licence travels with the
package in LICENSE.LGPL, together with
LICENSE.GPL, which it incorporates by reference. You may modify
that module and relink it against the rest of the package under those terms;
its header lists the changes already made relative to upstream. Everything else
here is MIT, so the distribution as a whole is MIT AND LGPL-3.0-or-later.
reactiontools/tools_geodesic.py is derived from
geodesic-interpolate,
also MIT, copyright Xiaolei Zhu; the notice is at the foot of
LICENSE. reactiontools/opes/ holds PLUMED's OPES post-processing
scripts, which carry their own upstream licence.
Metadata
Release files for reactiontools 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| reactiontools-1.0.0.tar.gz | 370.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| reactiontools-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 637.5 kB
Release files / reactiontools-1.0.0.tar.gz
| Download URL | reactiontools-1.0.0.tar.gz |
|---|---|
| Size | 370.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
4ad0345f196379b1a631082b44cd1ad1a65d0bdee2fa010d96f46154fe2fdc6d
|
|
BLAKE2b-256 checksum How to use checksums |
79d67b789b6444be0d16add74beae58f617bf524fd8ec40e98cfa4b43e3f6b7f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 18, 2026.
Transparency logRelease files / reactiontools-1.0.0-py3-none-any.whl
| Download URL | reactiontools-1.0.0-py3-none-any.whl |
|---|---|
| Size | 266.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
67afb4ffaac2b2a9ebfba64b8184132152cbcd1f53e3ab36d29c9388a28e9d18
|
|
BLAKE2b-256 checksum How to use checksums |
f02bba8a924537a408d413e3566895e05a58b3bd893765622b3ac6995d2863b1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 18, 2026.
Transparency log