Skip to main content

ase_qsm

License: GPL v3

QSM-style chain-of-states path optimizer for ASE.

ase_qsm optimizes discrete chain-of-states paths between two molecular configurations.

Installation

pip install ase_qsm

From a source checkout:

git clone https://github.com/ss0832/ase_qsm
cd ase_qsm
pip install -e ".[dev]"
pytest

Requires Python 3.10+, NumPy 1.24+, SciPy 1.10+, ASE 3.23+.

Basic example

Prepare endpoint geometries as external structure files, for example reactant.xyz and product.xyz. The two endpoint files must use the same atom count and the same atom ordering; use auto_match_atoms=True only when you intentionally want ase_qsm to reorder atoms before path construction.

from ase.io import read
from ase.calculators.emt import EMT
from ase_qsm import QSM, finalize_path

reactant = read("reactant.xyz")
product = read("product.xyz")

# Replace EMT() with the calculator appropriate for the endpoint files.
calc = EMT()

# QSM with 11 images and explicit run/report settings.
# The run-level controls mirror the examples/08 suite invocation:
#   --steps 32 --output-dir lst_reaction_suite_results --full-hessian-for none
qsm = QSM(
    images=[reactant, product],
    calculator=calc,
    n_images=11,
    fmax=0.05,
    max_iter=32,
    blend_ratio=0.5,            # 50/50 FIRE/RFO
    hessian_mode="model",       # Fischer model Hessian per node
    redistribute_interval=1,    # redistribute nodes every 1 eligible steps
    trajectory="qsm.traj",
)
qsm.run()

report = finalize_path(
    qsm,
    "results",
    refine_ts=False,
    full_hessian_for="none",
)
print("TS candidates:", report.ts_candidates)

for k, atoms in enumerate(qsm.images):
    print(f"image {k}: E = {atoms.get_potential_energy():.6f} eV")

Additional usage patterns

Endpoint-only input can omit n_images. In that case the constructor infers the initial image count from the configured pre-climb target chord and minimum image count. Replace EMT() with the calculator appropriate for the system.

from ase.io import read
from ase.calculators.emt import EMT
from ase_qsm import QSM

reactant = read("reactant.xyz")
product = read("product.xyz")

qsm = QSM([reactant, product], calculator=EMT(), fmax=0.05)
converged = qsm.run()
print("converged:", converged)
print("images:", len(qsm.images))

For a pre-built image stack, pass all images directly. The constructor then ignores n_images and interpolation.

from ase.io import read
from ase.calculators.emt import EMT
from ase_qsm import QSM

images = read("initial_path.xyz", index=":")
qsm = QSM(images, calculator=EMT(), fix_endpoints="both")
qsm.run(steps=100)

Use QSMConfig when several controls should be recorded as one object. The example below enables climbing-image selection and monitor redistribution, while keeping final reporting limited by skipping post-run Hessian and TS-refinement work.

from ase.io import read
from ase.calculators.emt import EMT
from ase_qsm import QSM, QSMConfig, finalize_path

reactant = read("reactant.xyz")
product = read("product.xyz")
calc = EMT()

cfg = QSMConfig(
    climb=True,
    climb_use_rsirfo=True,
    max_climbers=3,
    redistribute_method="monitor",
    adaptive_image_insertion=True,
    adaptive_max_images=40,
)

qsm = QSM([reactant, product], calculator=calc, config=cfg)
qsm.run()
report = finalize_path(
    qsm,
    "qsm_results",
    refine_ts=False,
    full_hessian_for="none",
)
print(report.ts_candidates)

By default, QSM.run() writes monitoring files under qsm_path_history/. Set path_history_dir=None and path_metrics_enabled=False for an in-memory-only run. If path_history_dir=None but path metrics remain enabled, the metric CSVs are written in the current working directory as qsm_path_metrics*.csv.

File Written by Purpose
qsm_path_history/path_initial.xyz constructor Initial interpolated or supplied path with per-image metadata.
qsm_path_history/path_iter_*.xyz accepted QSM iterations One complete path snapshot per saved iteration.
qsm_path_history/qsm.log constructor/run loop Persistent text log in addition to logfile.
qsm_path_history/path_metrics.csv accepted QSM iterations Per-image diagnostics such as energy, force, chord, and role labels.
qsm_path_history/path_metrics_summary.csv accepted QSM iterations One summary row per saved iteration.
qsm_path_history/path_metrics_wide.csv accepted QSM iterations Wide-format monitoring table for plotting and spreadsheet inspection.

Three or more input structures are treated as waypoints by default. The constructor uses the waypoint polyline as a guide and resamples it to the requested or inferred total image count. This can increase or decrease the number of supplied structures.

from ase.io import read
from ase.calculators.emt import EMT
from ase_qsm import QSM

waypoints = read("waypoints.xyz", index=":")
qsm = QSM(
    waypoints,
    calculator=EMT(),
    n_images=17,                 # total images after waypoint resampling
    interpolation="lst",
    fix_endpoints="both",
)
qsm.run(steps=32)

For a pre-built image stack that should be preserved exactly, opt into image-stack mode. In this mode the constructor ignores n_images and interpolation.

from ase.io import read
from ase.calculators.emt import EMT
from ase_qsm import QSM

images = read("initial_path.xyz", index=":")
qsm = QSM(
    images,
    calculator=EMT(),
    initial_path_input_mode="images",
    fix_endpoints="both",
)
qsm.run(steps=32)

Reaction-path preset

For ordinary reaction-path searches, use the reaction_path preset rather than specifying the full set of QSM controls manually. This preset mirrors the settings used by examples/08_lst_reaction_suite.py and is intended as the main practical entry point for molecular reaction paths.

from ase.io import read
from ase.calculators.emt import EMT
from ase_qsm import QSM, QSMConfig, finalize_path

reactant = read("reactant.xyz")
product = read("product.xyz")
calc = EMT()

cfg = QSMConfig.reaction_path(
    steps=32,       # QSM iteration limit used by the reaction-suite example
    max_images=40,  # optional upper bound for adaptive image insertion
)

qsm = QSM(
    [reactant, product],
    calculator=calc,
    config=cfg,
)

qsm.run()

report = finalize_path(
    qsm,
    "results",
    refine_ts=False,
    full_hessian_for="none",
)

print("TS candidates:", report.ts_candidates)

References

  • ASE: Hjorth Larsen et al., The atomic simulation environment—A Python library for working with atoms. Journal of Physics: Condensed Matter 29, 273002 (2017). DOI: 10.1088/1361-648X/aa680e

  • ASE early interface paper: Bahn and Jacobsen, An object-oriented scripting interface to a legacy electronic structure code. Computing in Science & Engineering 4(3), 56–66 (2002). DOI: 10.1109/5992.998641

  • Quadratic String Method: Burger and Yang, Quadratic string method for determining the minimum-energy path based on multiobjective optimization. The Journal of Chemical Physics 124(5), 054109 (2006). DOI: 10.1063/1.2163875

License

GPL-3.0-or-later. See LICENSE and NOTICE.md for details.

Copyright (C) 2026 ss0832.

Release files for ase-qsm 0.2.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ase-qsm 0.2.3
File Size Uploaded
ase_qsm-0.2.3.tar.gz 232.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for ase-qsm 0.2.3
File Interpreter ABI Platform
ase_qsm-0.2.3-py3-none-any.whl Python 3 none any Details

Total release size: 468.9 kB

Release files / ase_qsm-0.2.3.tar.gz

Download URL ase_qsm-0.2.3.tar.gz
Size 232.2 kB
Tags Source
SHA-256 checksum
How to use checksums
532c25fcd046c817c9f8f428be9b6a1feb58944440671110cb702650bc4b7776
BLAKE2b-256 checksum
How to use checksums
b29a543c4ee9a56071b864e7ba2d14b5c73ee61d84229f66ec8720f94e8383a8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.9

Release files / ase_qsm-0.2.3-py3-none-any.whl

Download URL ase_qsm-0.2.3-py3-none-any.whl
Size 236.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
fd963d4fc4959f0c0c5c267ed274cad0ba4a2bacacdee90eaf283352c75ab8c7
BLAKE2b-256 checksum
How to use checksums
19fc98a8e1ae4eb47b86db1e0bb6b261d1702ba2ab4e23ca18b348656f4fc846
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.9

Release history Release notifications | RSS feed

This release

0.2.3 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page