Skip to main content

A dispatcher-based analytical and computational suite for chemical physics

Project description

Table of Contents

Canonical source note: this Org file is authoritative for contributor-facing documentation. Rendered Markdown files are derived artifacts and should not be edited separately.

About

img

Tests Linting Docs PyPI Python License: MIT One Good Tutorial docs checklist v1: adopted Benchmarks Hatch project DOI

A pure-python computational library and CLI toolkit for chemical physics research. rgpycrumbs provides both importable library modules for computational tasks (surface fitting, structure analysis, interpolation) and a dispatcher-based CLI for running self-contained research scripts.

Heavy optional dependencies (JAX, SciPy, ASE) are resolved lazily at first use. A bare pip install rgpycrumbs gives the full API surface; the actual backend libraries load on demand from the current environment, a shared cache, or (with RGPYCRUMBS_AUTO_DEPS=1) via automatic uv installation. CUDA-aware resolution avoids pulling GPU libraries on CPU-only machines.

The library side offers:

  • Surface fitting (rgpycrumbs.surfaces) – JAX-based kernel methods (TPS, RBF, Matern, SE, IMQ) with gradient-enhanced variants for energy landscape interpolation
  • Structure analysis (rgpycrumbs.geom.analysis) – distance matrices, bond matrices, and fragment detection via ASE
  • IRA matching (rgpycrumbs.geom.ira) – iterative rotations and assignments for RMSD-based structure comparison
  • Interpolation (rgpycrumbs.interpolation) – spline interpolation utilities
  • Data types (rgpycrumbs.basetypes) – shared data structures for NEB paths, saddle searches, and molecular geometries

The CLI tools rely on optional dependencies fetched on-demand via PEP 723 + uv.

Ecosystem Overview

rgpycrumbs is the central hub of an interlinked suite of libraries.

img

CLI Design Philosophy

The library is designed with the following principles in mind:

  • Dispatcher-Based Architecture (preferred entry): Use rgpycrumbs <group> <tool> or python -m rgpycrumbs.cli ...not raw uv run path/to/script.py as the primary path. The dispatcher sets PYTHONPATH, defaults RGPYCRUMBS_AUTO_DEPS=1, optional editable peers, and optional SBOM pins. Scripts remain self-contained PEP 723 units invoked in a subprocess via uv run when isolation is chosen.

  • Isolated & Reproducible Execution: Each script declares dependencies via PEP 723 (including a rgpycrumbs floor so standalone uv run can resolve the package). For pinned installs, pass a lock the uv resolver already understands:

    • uv.lock (native)
    • PEP 751 pylock.toml / pylock.*.toml (e.g. uv export --format pylock.toml)
    • CycloneDX JSON (e.g. eb-stack --sbom-out, uv export --format cyclonedx1.5)

    via --lock PATH / RGPYCRUMBS_LOCK (or --sbom / RGPYCRUMBS_SBOM). PyPI packages become name==version constraints for uv / ensure_import; non-PyPI CDX rows (pkg:generic/...) are skipped. No lock → floating PEP 723 / AUTO_DEPS.

    Suite config (TOML; shared with chemparseplot / other rgpkgs — not a per-package silo):

    • User: ~/.config/rgpkgs/config.toml
    • Project: rgpkgs.toml or .rgpkgs.toml (walk up from CWD)
    • Override: RGPKGS_CONFIG=/path/to.toml
    • Legacy: rgpycrumbs.toml and ~/.config/rgpycrumbs/ still work

    Shared [pins] / [pins.packages]; tool keys under [rgpycrumbs.dispatch]. Example: docs/examples/rgpkgs.config.toml.

    Stable consumer API (chemparseplot, pychum, wailord):

    from rgpycrumbs.api import load_config, load_pypi_pins, ensure_import
    

    See docs/orgmode/explanation/public_api.org. Debug: rgpycrumbs config show.

  • Lightweight Core, On-Demand Dependencies: The installable rgpycrumbs package has minimal core dependencies (click, numpy, rich). There are no runtime feature extras. CLI tools fetch deps via PEP 723 + uv run. Library modules use ensure_import when RGPYCRUMBS_AUTO_DEPS=1 (CLI dispatch enables this by default), with CUDA-aware resolution so CPU hosts do not pull GPU JAX. Install only rgpycrumbs; optional packages arrive on demand.

  • Modular & Extensible Tooling: Each utility is an independent script. This modularity simplifies development, testing, and maintenance, as changes to one tool cannot inadvertently affect another. New tools can be added to the collection without modifying the core dispatcher logic, making the system easily extensible.

Usage

Library API

The library modules can be imported directly. Dependencies resolve automatically when RGPYCRUMBS_AUTO_DEPS=1 is set (requires uv on PATH):

export RGPYCRUMBS_AUTO_DEPS=1

# Surface fitting (jax via ensure_import)
from rgpycrumbs.surfaces import get_surface_model
model = get_surface_model("tps")

# Structure analysis (ase/scipy via ensure_import)
from rgpycrumbs.geom.analysis import analyze_structure

# Spline interpolation (scipy via ensure_import)
from rgpycrumbs.interpolation import spline_interp

# Data types (core only)
from rgpycrumbs.basetypes import nebpath, SaddleMeasure

CLI Tools

The general command structure is:

python -m rgpycrumbs.cli [subcommand-group] [script-name] [script-options]

You can see the list of available command groups:

$ python -m rgpycrumbs.cli --help
Usage: rgpycrumbs [OPTIONS] COMMAND [ARGS]...

  A dispatcher that runs self-contained scripts using 'uv'.

Options:
  --help  Show this message and exit.

Commands:
  eon  Dispatches to a script within the 'eon' submodule.

eOn

  • Plotting NEB Paths (plt-neb), including energy-unit selection and xyzrender strips
  • Stitch multi-segment NEB bands (plt-neb-stitch) for full-path 1D/2D views (v1.8+)
  • Seed dimer searches from NEB peaks (gen-dimer) and KMC timeline plots (plt-kmc)
  • Single-ended minimization landscapes (plt-min) with optional --energy-cap windows

eOn job-config authorship (write_eon_config, seed_dimers, MLflow hydrate) needs eon-schema>=0.2 (pip install 'rgpycrumbs[eon]'). Plotting still uses chemparseplot; eon-akmc is not required for INI tooling.

Library NEB plots (no Click argv): from rgpycrumbs.eon import plot_neb then plot_neb(plot_type="profile", con_file="neb.con", output_file="1D.png").

This script visualizes the energy landscape of Nudged Elastic Band (NEB) calculations,
generating 2D surface plots with optional structure rendering.

The default `grad_imq` method uses gradient-enhanced Inverse Multiquadric interpolation
on 2D RMSD projections [1]. The approach projects high-dimensional structures onto
2D coordinates (reactant distance `r` vs product distance `p`) and fits a smooth
surface using energy values and their gradients.

[1] R. Goswami, "Two-dimensional RMSD projections for reaction path visualization
and validation," *MethodsX*, p. 103851, Mar. 2026,
doi: [10.1016/j.mex.2026.103851](https://doi.org/10.1016/j.mex.2026.103851).
generating 2D surface plots with optional structure rendering.

-   Basic Usage

        python -m rgpycrumbs.cli eon plt-neb --con-file trajectory.con --plot-type landscape -o neb_landscape.png

-   Key Options

    <table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">
    
    
    <colgroup>
    <col  class="org-left" />
    
    <col  class="org-left" />
    
    <col  class="org-left" />
    </colgroup>
    <thead>
    <tr>
    <th scope="col" class="org-left">Option</th>
    <th scope="col" class="org-left">Description</th>
    <th scope="col" class="org-left">Default</th>
    </tr>
    </thead>
    <tbody>
    <tr>
    <td class="org-left"><code>--con-file PATH</code></td>
    <td class="org-left">Trajectory file with NEB images</td>
    <td class="org-left">None</td>
    </tr>
    
    <tr>
    <td class="org-left"><code>--plot-type</code></td>
    <td class="org-left"><code>landscape</code> (2D surface) or <code>profile</code></td>
    <td class="org-left"><code>profile</code></td>
    </tr>
    
    <tr>
    <td class="org-left"><code>--surface-type</code></td>
    <td class="org-left">Surface method: <code>grad_imq</code>, <code>grad_matern</code>, <code>grad_imq_ny</code>, <code>rbf</code></td>
    <td class="org-left"><code>grad_imq</code></td>
    </tr>
    
    <tr>
    <td class="org-left"><code>--project-path</code> / <code>--no-project-path</code></td>
    <td class="org-left">Project to reaction valley coordinates</td>
    <td class="org-left"><code>--project-path</code></td>
    </tr>
    
    <tr>
    <td class="org-left"><code>--plot-structures</code></td>
    <td class="org-left">Structure strip: <code>none</code>, <code>all</code>, <code>crit_points</code></td>
    <td class="org-left"><code>none</code></td>
    </tr>
    
    <tr>
    <td class="org-left"><code>--energy-unit</code></td>
    <td class="org-left">Presentation unit: <code>eV</code>, <code>kcal/mol</code>, <code>kJ/mol</code></td>
    <td class="org-left"><code>eV</code></td>
    </tr>
    
    <tr>
    <td class="org-left"><code>--strip-renderer</code></td>
    <td class="org-left">Structure renderer backend</td>
    <td class="org-left"><code>xyzrender</code></td>
    </tr>
    
    <tr>
    <td class="org-left"><code>--xyzrender-config</code></td>
    <td class="org-left">xyzrender preset used for strips</td>
    <td class="org-left"><code>paton</code></td>
    </tr>
    
    <tr>
    <td class="org-left"><code>--show-legend</code></td>
    <td class="org-left">Show colorbar legend</td>
    <td class="org-left">Off</td>
    </tr>
    
    <tr>
    <td class="org-left"><code>--show-pts</code> / <code>--no-show-pts</code></td>
    <td class="org-left">Show data points on surface</td>
    <td class="org-left"><code>--show-pts</code></td>
    </tr>
    
    <tr>
    <td class="org-left"><code>--landscape-path</code></td>
    <td class="org-left">Path overlay: <code>final</code>, <code>all</code>, <code>none</code></td>
    <td class="org-left"><code>final</code></td>
    </tr>
    
    <tr>
    <td class="org-left"><code>--ira-kmax</code></td>
    <td class="org-left">kmax factor for IRA RMSD calculation</td>
    <td class="org-left">14.0</td>
    </tr>
    
    <tr>
    <td class="org-left"><code>-o PATH</code></td>
    <td class="org-left">Output image filename</td>
    <td class="org-left">None (display)</td>
    </tr>
    </tbody>
    </table>
    
    Use `--landscape-path all` to overlay all optimization steps and visualize convergence.
    This shows the full trajectory from initial guess to final path [1].

-   Examples

    Full landscape with gradient-enhanced IMQ surface and critical point structures:
    
        python -m rgpycrumbs.cli eon plt-neb \
          --con-file neb.con \
          --plot-type landscape \
          --project-path \
          --plot-structures crit_points \
          --surface-type grad_matern \
          --ira-kmax 14 \
          --energy-unit kJ/mol \
          --show-legend \
          -o neb_landscape.png
    
    Surface-only plot without structure strip:
    
        python -m rgpycrumbs.cli eon plt-neb \
          --plot-type landscape \
          --surface-type grad_matern \
          --no-show-pts \
          -o surface.png
    
    Convergence visualization with all optimization steps:
    
        python -m rgpycrumbs.cli eon plt-neb \
          --con-file neb.con \
          --plot-type landscape \
          --landscape-path all \
          --surface-type grad_imq \
          --show-legend \
          -o neb_convergence.png

-   Surface Methods

    -   **`grad_imq`:** Gradient-enhanced Inverse Multiquadric (recommended, uses energy + gradients)
    -   **`grad_matern`:** Gradient-enhanced Matérn 5/2 (uses energy + gradients)
    -   **`grad_imq_ny`:** Nystrom-approximated grad<sub>imq</sub> for large datasets (>1000 points)
    -   **`rbf`:** Radial Basis Function / Thin Plate Spline (fast, no gradients)
  • Splitting CON files (con-splitter)

    This script takes a multi-image trajectory file (e.g., from a finished NEB calculation) and splits it into individual frame files, creating an input file for a new calculation.

    To split a trajectory file:

    rgpycrumbs eon con-splitter neb_final_path.con -o initial_images
    

    This will create a directory named initial_images containing ipath_000.con, ipath_001.con, etc., along with an ipath.dat file listing their paths.

Contributing

All contributions are welcome, but for the CLI tools please follow established best practices.

Development

This project uses uv as the primary development tool with hatchling + hatch-vcs for building and versioning.

# Clone and install in development mode with test dependencies
uv sync --extra test

# Run the pure tests (no heavy optional deps)
uv run pytest -m pure

# Run interpolation tests (needs scipy)
uv run --extra interpolation pytest -m interpolation

Branch Structure

Development happens on the main branch. The readme branch is an auto-generated orphan containing only the rendered README.md and branding assets; it is the GitHub default branch.

When is pixi needed?

Pixi is mainly needed for pixi-only or heavy optional packages that we do not auto-install by default:

  • fragments tests: need tblite, ira_mod, and pyvista
  • some heavy visualization workflows may still be easier to manage in pixi

For everything else, uv is sufficient.

Versioning

Versions are derived automatically from git tags via hatch-vcs (setuptools-scm). There is no manual version field; the version is the latest tag (e.g. v1.0.01.0.0). Between tags, dev versions are generated automatically (e.g. 1.0.1.dev3+gabcdef).

Release Process

# 1. Run the same checks the tag-triggered release workflow expects
uv sync --extra test --extra release
uv run --extra test pytest -m pure
uv run --extra test pytest --pep723-check -m pep723 --override-ini="python_files=" --ignore=rgpycrumbs/chemgp rgpycrumbs/
uvx prek run -a -vvv
pixi run -e docs docbld

# 2. Preview the next semantic version from Conventional Commits
uvx cocogitto cog bump --dry-run --auto

# 3. Build the release notes from towncrier fragments
#    towncrier headings use X.Y.Z, while the git tag stays vX.Y.Z
uvx towncrier build --version "1.7.1"

# 4. Commit the release notes (historically: release: vX.Y.Z)
git add CHANGELOG.rst docs/newsfragments
git commit -m "release: v1.7.1"

# 5. Tag the release commit (hatch-vcs derives the package version from tags)
uvx cocogitto cog bump --auto

# 6. Push main and tags; GitHub Actions handles build/publish/release
git push origin main --tags

The existing .github/workflows/release.yml publishes to PyPI and creates the GitHub release when a v* tag is pushed.

License

MIT. However, this is an academic resource, so please cite as much as possible via:

  • The Zenodo DOI for general use.
  • The wailord paper for ORCA usage

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

rgpycrumbs-1.10.8.tar.gz (693.2 kB view details)

Uploaded Source

Built Distribution

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

rgpycrumbs-1.10.8-py3-none-any.whl (977.3 kB view details)

Uploaded Python 3

File details

Details for the file rgpycrumbs-1.10.8.tar.gz.

File metadata

  • Download URL: rgpycrumbs-1.10.8.tar.gz
  • Upload date:
  • Size: 693.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for rgpycrumbs-1.10.8.tar.gz
Algorithm Hash digest
SHA256 aeb4b01a5a9f9611ea457c265f50ccf01d8557fc8a8820c8206958caae5dee64
MD5 b961896897a1dfcc72ee482a25f0c429
BLAKE2b-256 98a3d4bbed82a95655c9c2a6dcd86692b348a1a293c379425d266282bcf0e518

See more details on using hashes here.

Provenance

The following attestation bundles were made for rgpycrumbs-1.10.8.tar.gz:

Publisher: release.yml on HaoZeke/rgpycrumbs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rgpycrumbs-1.10.8-py3-none-any.whl.

File metadata

  • Download URL: rgpycrumbs-1.10.8-py3-none-any.whl
  • Upload date:
  • Size: 977.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for rgpycrumbs-1.10.8-py3-none-any.whl
Algorithm Hash digest
SHA256 ef520b9eae27772cde841bc4c29289d7a6262d262c4b4160a468b4b21802ae7e
MD5 132ab1263ba8daff786665c3ff190975
BLAKE2b-256 a2312aacac5f0441ef3508fc0b9ad495f4881dc7b6f274ddd8980ce8dc973c51

See more details on using hashes here.

Provenance

The following attestation bundles were made for rgpycrumbs-1.10.8-py3-none-any.whl:

Publisher: release.yml on HaoZeke/rgpycrumbs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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