About
ChemFit is a Python framework for building and optimizing simulation-based parameter-fitting problems in computational chemistry, molecular dynamics, and materials science.
A ChemFit objective can combine many systems, observables, reference data sets, and simulation workflows into a single fitting problem. Individual terms can use ASE calculators, external simulation programs, or arbitrary Python code.
Under the hood, ChemFit provides a lightweight, flexible framework for composing scientific computations into pipelines, independent branches, and arbitrary dependency graphs.
Although parameter fitting is its primary application, ChemFit's composition and execution machinery can also be used independently of an optimizer.
What can ChemFit do?
ChemFit can be used to:
- fit model parameters simultaneously against energies, forces, structures, densities, or other observables;
- combine reference data from different systems and simulation conditions into one objective;
- use ASE calculations and geometry optimizations as fitting terms;
- build external simulation workflows that generate input, run programs, post-process output, and extract quantities;
- evaluate independent calculations concurrently using threads, processes, or custom schedulers, or distribute them using MPI;
- compose pipelines, joins, and arbitrary dependency graphs, including nested components and shared intermediate computations;
- use Nevergrad, SciPy, or a custom optimization loop.
Installation
From PyPI:
pip install chemfit
Or, locally:
git clone git@github.com:MSallermann/chemfit.git
pip install -e chemfit
Quick start: fit a Lennard-Jones potential
A ChemFit fitting problem is built from quantity computations, losses, and objective composition.
The following example fits the Lennard-Jones energy scale epsilon against two reference energies while keeping sigma fixed:
import chemfit
from ase import Atoms
from ase.calculators.lj import LennardJones
reference_energies = {
1.1: -0.98,
1.5: -0.32,
}
objective = chemfit.combine(
chemfit.ase_quantity(
Atoms("Ar2", positions=[(0, 0, 0), (distance, 0, 0)])
)
.with_calculator(
lambda p, atoms, ctx: LennardJones(
epsilon=p["epsilon"], sigma=1.0, rc=100.0
)
)
.with_loss(
lambda q, target: (q["energy"] - target) ** 2,
target=target,
)
for distance, target in reference_energies.items()
)
result = chemfit.fit_nevergrad(
objective,
initial={"epsilon": 0.7},
bounds={"epsilon": (0.1, 2.0)},
budget=100,
)
print(result.best_parameters)
Each ASE calculation produces quantities, with_loss() turns those quantities into a scalar fitting term, and chemfit.combine() joins the independent terms into one objective.
chemfit.fit_nevergrad() then optimizes the parameters and returns a FitResult containing the best parameters and loss, the optimizer recommendation, and one fitting context per candidate slot. Each context records its slot's current and best evaluation state; it is not a history of every evaluation.
For more examples of constructing objectives, see the common workflows.
From small examples to larger fitting problems
The example above has only two energy terms, but the same structure can combine different systems, observables, and simulation methods:
┌─ structure 1 / energy ── loss ─┐
├─ structure 2 / forces ── loss ─┤
parameters ────├─ liquid / density ────── loss ─┼─ objective
├─ external simulation ─── loss ─┤
└─ custom observable ───── loss ─┘
The individual terms do not need to use the same simulation method. ASE calculations, external programs, and custom Python computations can participate in the same objective.
Objectives can also be nested and combined with weights, custom reductions, evaluation metadata, and exception handling.
External simulation workflows
ChemFit can turn external simulation programs into reusable quantity computations.
For example:
term = (
chemfit.external_quantity("runs")
.with_hook(write_input, template="input.template")
.with_cmd(run_simulation, executable="my-simulator")
.with_hook(postprocess)
.with_parser(parse_results, "results.dat")
.wait_for("simulation.done")
.with_loss(loss, target=reference)
)
An external workflow can contain Python hooks, commands, output parsers, and completion files. Each evaluation runs in an isolated working directory.
This allows external simulation codes that can be launched and inspected from Python to participate in a ChemFit objective alongside native Python or ASE calculations.
See the external simulation documentation for details on commands, hooks, parsers, completion files, working directories, and failure handling.
Concurrent execution
The scientific objective does not determine how it is executed.
For example, the Lennard-Jones fit above can evaluate multiple parameter candidates and objective terms concurrently:
result = chemfit.fit_nevergrad(
objective,
initial={"epsilon": 0.7},
bounds={"epsilon": (0.1, 2.0)},
budget=100,
batch_size=2,
execution_workers=4,
)
batch_size=2 allows Nevergrad to evaluate two parameter candidates at a time, while execution_workers=4 allows up to four objective tasks to run concurrently.
An explicit concurrent.futures-compatible executor can also be supplied, for example to use processes for CPU-bound Python workloads.
The objective itself does not change.
See parallel execution for executors, schedulers, batching, and lower-level control.
MPI
The same objective can also be evaluated across MPI ranks:
from chemfit.mpi_graph_schedule import MPIGraphScheduler
scheduler = MPIGraphScheduler()
with scheduler.prepare(objective) as schedule:
if schedule.rank == 0:
result = chemfit.fit_nevergrad(
schedule,
initial={"epsilon": 0.7},
bounds={"epsilon": (0.1, 2.0)},
budget=100,
batch_size=2,
)
else:
schedule.worker_loop()
Run the script using the MPI launcher available on your system:
mpiexec -n 4 python fit.py
Install the MPI dependencies with:
pip install "chemfit[mpi]"
See the MPI documentation for setup and execution details.
Optimization
ChemFit does not tie an objective to a particular optimizer.
The high-level chemfit.fit_nevergrad() interface provides derivative-free optimization with Nevergrad. chemfit.Fitter provides lower-level control and can be used with SciPy, callbacks, explicit evaluation, batch evaluation, or custom optimization loops.
The objective and its execution strategy can therefore be reused when changing optimization methods.
See the fitting documentation for the available fitting interfaces.
Evaluation data and instrumentation
ChemFit retains inputs, outputs, metadata, failures, and nested evaluations in evaluation contexts.
Evaluation hooks can add instrumentation such as timing, unique evaluation IDs, logging, or application-specific diagnostics without changing the simulation or loss implementation.
Limitations and alternatives
ChemFit is designed for simulation-based parameter fitting, particularly when an objective combines multiple calculations, observables, or simulation methods. It provides reusable building blocks for quantities, losses, and nested objectives, while keeping their execution and optimization separate. The same fitting problem can run locally or across an HPC cluster without requiring a workflow-management system.
ChemFit does not implement its own optimization algorithms or simulation engines. Out of the box, it integrates with SciPy and Nevergrad, and its objectives can also be optimized using Optuna or custom optimization loops. For simple objectives, using these tools directly may be easier.
Related frameworks offer different strengths:
- AiiDA provides comprehensive workflow management, including persistent provenance, recovery, and HPC job management. Its aiida-optimize plugin supports parameter optimization. If you already use AiiDA workflows, this is a natural choice. ChemFit is a lighter alternative when starting a fitting project without existing workflow infrastructure.
- Dakota offers extensive capabilities for optimization, parameter estimation, sensitivity analysis, and uncertainty quantification. ChemFit emphasizes defining and customizing fitting objectives directly in Python rather than providing a comprehensive numerical methods suite.
- pyiron provides an integrated environment for atomistic simulations, including job management, data storage, and potential fitting. ChemFit is more narrowly focused on fitting objectives that can combine arbitrary Python computations, ASE calculations, and external simulation programs.
ChemFit's built-in schedulers execute component dependency graphs, but they are not general workflow-management systems. Persistent provenance, automatic recovery, and resource-aware scheduling are not provided out of the box. Custom schedulers, executors, and hooks allow more sophisticated infrastructure to be integrated.
ChemFit remains focused on parameter fitting rather than general workflow management. Its composition and execution machinery can be used independently or integrated with a larger workflow ecosystem.
Documentation
The full ChemFit documentation covers the high-level API as well as structural and opaque composition, ASE integration, external programs, combined objectives, fitting, parallel execution, MPI, hooks, and custom quantity computers.
Citation
If you use ChemFit in academic work, please cite:
@misc{sallermann2026chemfitframeworkautomatedhighdimensional,
title={ChemFit: A framework for automated high-dimensional model parameter optimization},
author={Moritz Sallermann and Amrita Goswami and Rosana Collepardo-Guevara and Alberto Ocana and Hannes Jónsson and Elvar Ö. Jónsson and Jorge R. Espinosa},
year={2026},
eprint={2603.11769},
archivePrefix={arXiv},
primaryClass={physics.chem-ph},
url={https://arxiv.org/abs/2603.11769},
}
Problems?
Please open an issue on the ChemFit issue tracker.
Metadata
Release files for chemfit 4.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| chemfit-4.0.0.tar.gz | 131.4 kB | With provenance | Details for chemfit-4.0.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| chemfit-4.0.0-py3-none-any.whl | Python 3 | none | any | Details for chemfit-4.0.0-py3-none-any.whl |
Total release size: 231.3 kB
Release files / chemfit-4.0.0.tar.gz
| Download URL | chemfit-4.0.0.tar.gz |
|---|---|
| Size | 131.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
fea0ba1e8b478740ff9651b811b423096828b8f45ed98e77668e415fa6127d96
|
|
BLAKE2b-256 checksum How to use checksums |
58cc10dbfae421fb2d6d1ef3e34ed0d5d7ed7bdf6d68c5595790d4278bd8918d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 29, 2026.
Transparency logRelease files / chemfit-4.0.0-py3-none-any.whl
| Download URL | chemfit-4.0.0-py3-none-any.whl |
|---|---|
| Size | 99.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
fee3e6c10bcb66bf049e891d2526196cd754b417a471b145ae49cbc164e386d8
|
|
BLAKE2b-256 checksum How to use checksums |
b78dee8c422798e5245e27f1f187d1de1fee2a26e0af9b30f229189d56e06872
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 29, 2026.
Transparency logSecurity for chemfit 4.0.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
Both files in this release have been uploaded with provenance metadata.
Attestation for chemfit-4.0.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 29, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.