Skip to main content

QSM-style chain-of-states path optimizer for ASE with tangent-smoothed chain updates, climbing-image saddle search, adaptive redistribution, and SCF-failure resilience.

Project description

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.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ase_qsm-0.2.3.tar.gz (232.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ase_qsm-0.2.3-py3-none-any.whl (236.7 kB view details)

Uploaded Python 3

File details

Details for the file ase_qsm-0.2.3.tar.gz.

File metadata

  • Download URL: ase_qsm-0.2.3.tar.gz
  • Upload date:
  • Size: 232.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.9

File hashes

Hashes for ase_qsm-0.2.3.tar.gz
Algorithm Hash digest
SHA256 532c25fcd046c817c9f8f428be9b6a1feb58944440671110cb702650bc4b7776
MD5 47c3a1d46d432188205c7e8505402ff9
BLAKE2b-256 b29a543c4ee9a56071b864e7ba2d14b5c73ee61d84229f66ec8720f94e8383a8

See more details on using hashes here.

File details

Details for the file ase_qsm-0.2.3-py3-none-any.whl.

File metadata

  • Download URL: ase_qsm-0.2.3-py3-none-any.whl
  • Upload date:
  • Size: 236.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.9

File hashes

Hashes for ase_qsm-0.2.3-py3-none-any.whl
Algorithm Hash digest
SHA256 fd963d4fc4959f0c0c5c267ed274cad0ba4a2bacacdee90eaf283352c75ab8c7
MD5 f8cae3092a7fd1e3561d765ed98fcd51
BLAKE2b-256 19fc98a8e1ae4eb47b86db1e0bb6b261d1702ba2ab4e23ca18b348656f4fc846

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page