Examples

Quick Start — EMT Calculator

The simplest way to test ML-FSM is with ASE’s built-in EMT calculator. The example below runs a full FSM calculation on the Diels-Alder reaction included in the examples/data/ directory. Note that the EMT calculator is only for quick tests and demonstrations and should not be used in serious TS searches.

from pathlib import Path
from ase.calculators.emt import EMT
from mlfsm.utils import load_xyz
from mlfsm.cos import FreezingString
from mlfsm.opt import CartesianOptimizer

reaction_dir = Path("examples/data/06_diels_alder")
reactant, product = load_xyz(reaction_dir)

# Set up the FSM with RIC interpolation (recommended)
fsm = FreezingString(reactant, product, nnodes_min=9, interp_method="ric")

# Set up the optimizer with an ASE calculator
optimizer = CartesianOptimizer(calc=EMT(), maxiter=1, maxls=3)

outdir = Path("fsm_output")
outdir.mkdir(exist_ok=True)

# Run the FSM loop
while fsm.growing:
    fsm.grow()
    fsm.optimize(optimizer)
    fsm.write(outdir)

print(f"FSM finished in {fsm.ngrad} gradient evaluations")
print(f"TS guess written to {outdir}")

Using Fixed Atoms

To freeze part of the system (e.g., a scaffold or periodic image atoms), pass a zero-indexed array of atom indices. Fixed atoms are excluded from interpolation displacement and held stationary during node optimization.

import numpy as np
from mlfsm.utils import load_xyz_fixed
from mlfsm.cos import FreezingString

# Freeze atoms 0–11 (zero-indexed)
fixed = np.arange(0, 12)
reactant, product = load_xyz_fixed("examples/data/my_reaction", fixed)

fsm = FreezingString(reactant, product, nnodes_min=9, interp_method="ric")

The FixAtoms constraint is propagated automatically through the FSM; project_trans_rot_fixed() is used for alignment and CartesianOptimizer zeroes gradients on fixed atoms.

Specifying a Step Size Directly

Instead of setting nnodes_min, you can pass an explicit Cartesian step size (in Angstrom). The number of nodes is then determined automatically from the path arc length.

fsm = FreezingString(reactant, product, stepsize=0.3, interp_method="ric")

Choosing an Interpolation Method

Three interpolation methods are available via the interp_method argument:

interp_method

Description

"ric" (default)

Linear interpolation in redundant internal coordinates. Produces physically realistic intermediate geometries and generally gives the best TS guess quality.

"lst"

Linear Synchronous Transit. Interpolates pairwise interatomic distances and minimises deviation from a Cartesian linear blend.

"cart"

Plain Cartesian linear interpolation. Fast but can produce unphysical structures for large conformational changes.

Using an ML Calculator (UMA Small 1.2)

ML-FSM is calculator-agnostic — any ASE-compatible calculator can be used as the gradient provider. Below is a minimal example using the UMA Small 1.2 model.

from pathlib import Path
from fairchem.core import FAIRChemCalculator, pretrained_mlip
from mlfsm.utils import load_xyz
from mlfsm.cos import FreezingString
from mlfsm.opt import CartesianOptimizer

predictor = pretrained_mlip.get_predict_unit("uma-s-1p2")
calc = FAIRChemCalculator(predictor, task_name="omol")

reactant, product = load_xyz("examples/data/06_diels_alder")
fsm = FreezingString(reactant, product, nnodes_min=9, interp_method="ric")
optimizer = CartesianOptimizer(calc=calc, maxiter=1, maxls=3)

outdir = Path("fsm_output")
outdir.mkdir(exist_ok=True)

while fsm.growing:
    fsm.grow()
    fsm.optimize(optimizer)
    fsm.write(outdir)

Google Colab Tutorial

See examples/FSM_Colab_AIMNet2.ipynb for an Colab notebook using AIMNet2.

Example Reactions

The examples/data/ directory contains nine test reactions:

Folder

Reaction

01_formaldehyde

H₂CO → H₂ + CO

02_isocyanate_water

Isocyanate + H₂O → carbamic acid

03_ethanal

Acetaldehyde keto–enol tautomerism

04_ethane_dehydrogenation

CH₃CH₃ → CH₂CH₂ + H₂

05_bicyclobutane

Bicyclo[1.1.0]butane → trans-butadiene

06_diels_alder

Parent Diels–Alder cycloaddition

07_hexadiene

cis,cis-2,4-hexadiene → 3,4-dimethylcyclobutene

08_alanine

Alanine dipeptide rearrangement

09_proton

Acid zeolite proton migration

Each directory contains initial.xyz (reactant + product frames), chg (molecular charge), and mult (spin multiplicity).