MLIP Backends¶
pdb2reaction dispatches every workflow stage (opt, scan, tsopt, freq,
irc, path-search,…) through a single MLIPCalculator adapter. This page
documents how to select a backend, the per-backend kwargs, and how to add a new
backend.
Backend dispatcher pattern¶
from pdb2reaction.backends import create_calculator, create_ase_calculator
calc = create_calculator(
backend="uma", # one of: "uma", "orb", "mace", "aimnet2", "auto"
charge=0, spin=1,
device="cuda", workers=1,
model="uma-s-1p1",
)
# calc is a pysisyphus-compatible MLIPCalculator; pass it to any stage runner.
# ASE-based stages (e.g. DMF path optimization) use the ASE factory:
ase_calc = create_ase_calculator(backend="uma", model="uma-s-1p1", device="cuda")
create_calculator(...) filters **kwargs against each backend’s
_BACKEND_ACCEPTED_KEYS set, so workflow code can pass a superset and unknown
keys are silently dropped. The same pattern applies to create_ase_calculator().
backend="auto" resolves UMA → Orb → MACE → AIMNet2 in that order and picks the
first one whose import succeeds.
File map¶
file |
role |
|---|---|
|
|
|
|
|
UMA (Meta FAIR fairchem-core) — autograd Hessian path |
|
Orb (Orbital Materials) — precision / compile_model |
|
MACE — default_dtype |
|
AIMNet2 — charge-aware (excluded from 5-backend benchmark for the p2r paper) |
|
xTB ALPB wrap — wraps any base calculator with a solvent ΔE correction |
|
Standalone xTB ALPB correction (distinct API from the wrapper above; do not confuse) |
Per-backend characteristics¶
backend |
install |
model identifier |
precision option |
|---|---|---|---|
|
|
|
|
|
|
|
|
|
dedicated env: |
|
|
|
|
|
n/a |
UMA fp64¶
Switching OMol-trained UMA from default fp32 to fp64 can have non-trivial impact on TSopt and Hessian results. Enable via:
pdb2reaction tsopt -i ts.pdb -q 0 --precision fp64 ...
pdb2reaction freq -i opt.pdb -q 0 --precision fp64 ...
pdb2reaction irc -i ts.pdb -q 0 --precision fp64 ...
--precision is backend-agnostic: it routes to UMA precision /
ORB precision / MACE default_dtype automatically; AIMNet2 treats fp32 as a no-op and rejects fp64 (its model inputs are cast to float32 upstream).
--backend-model NAME overrides the model variant for the selected --backend
(e.g. --backend uma --backend-model uma-s-1p2); unset keeps the backend’s
built-in default model.
Or via YAML config:
calc:
precision: fp64
Requires fairchem-core ≥ 2.0 for the InferenceSettings API.
Custom backend — bring your own ASE Calculator (--calc-file)¶
Beyond the built-in MLIP backends, any ASE
Calculator can be supplied at run time with --calc-file, without modifying
pdb2reaction. This couples the pipeline to GFN-xTB (via tblite / xtb-python),
DFTB+, ORCA, Psi4, or any ASE-compatible engine — the boundary is the standard
ASE Calculator interface (energy in eV, forces in eV/Å).
Write a Python file exposing a get_calculator factory that returns an ASE
Calculator:
# my_calc.py (minimal illustrative example)
from ase.calculators.emt import EMT
def get_calculator(charge=0, spin=1, device="auto", **kwargs):
return EMT()
Swap EMT() for the engine you want — e.g. tblite.ase.TBLite(...) for
GFN-xTB, the DFTB+ ASE calculator, or ase.calculators.orca.ORCA(...). Then
pass the file to any single-stage subcommand (it selects the custom backend,
overriding --backend):
pdb2reaction sp -i model.xyz --calc-file my_calc.py -q 0 -m 1
pdb2reaction opt -i model.xyz --calc-file my_calc.py
pdb2reaction tsopt -i ts.xyz --calc-file my_calc.py
pdb2reaction freq -i ts.xyz --calc-file my_calc.py
Notes:
The factory receives
charge,spin(multiplicity; also offered asmult/multiplicity), anddevicewhen its signature accepts them, or unconditionally if it declares**kwargs, so engines that need the total charge (e.g. xTB) can be configured. Use a different factory name with--calc-factory NAME; a module-level Calculator instance is also accepted.Hessians use the finite-difference path inherited from
MLIPCalculator, sofreqandtsopt --opt-mode hesswork with any engine. Frozen atoms (--freeze-links/--freeze-atoms) are honored as usual.Available on the standalone subcommands (
sp,opt,tsopt,freq,irc,scan/scan2d/scan3d,path-opt,path-search). For a permanent, installable backend with its own--backendname instead, see the recipe below.
Add-a-backend recipe (5 steps)¶
To add a new backend XYZModel exposed as --backend xyz:
Create
pdb2reaction/backends/xyz.py: implementXYZCalculator(MLIPCalculator)(pysisyphus path) andXYZASECalculator(...)(ASE path). Both must accept the common kwargscharge / spin / device / freeze_atoms / hessian_calc_mode / return_partial_hessian / hessian_double / print_timing / modeland any backend-specific kwargs (precision,default_dtype, etc.).Inherit
MLIPCalculator(backends/base.py) and implement the subclass hook_compute_energy_forces_ev(elem, coord_ang) -> (energy_eV, forces_eV_Ang). Optionally override_compute_analytical_hessian_ev(elem, coord_ang) -> hessian_eV_Ang2if the backend exposes an analytical Hessian; otherwise the base class supplies the FD-Hessian assembly + unit conversion (eV/Å → Hartree/Bohr) for free.Register in
BACKEND_REGISTRY(backends/__init__.py): add"xyz": {"module": "pdb2reaction.backends.xyz", "pysis_cls": "XYZCalculator", "ase_cls": "XYZASECalculator"}next to existing entries.Declare accepted kwargs: add the set to
_BACKEND_ACCEPTED_KEYS["xyz"]and_ASE_ACCEPTED_KEYS["xyz"]. Add"xyz"to theresolve_backend('auto')fallback order if it should participate.Document + smoke: add an entry to this page’s file map / per-backend table, document model identifiers + install command, and add an
xyzline totests/smoke/run.shso the new backend is exercised end-to-end.
See Also¶
Architecture — 6-layer directory map + dependency direction.
CONTRIBUTING — Recipe 3.2 “Add an MLIP backend” with full gate cycle references.