Molecular Mechanics + Machine-Learned Force-Field Toolkit
MMML combines CHARMM/OpenMM workflows with JAX-based neural models for electrostatics and force prediction, for building and running hybrid ML/MM condensed-phase simulations.
MMML is in alpha. The core calculator, CLI, and md-system YAML workflow are usable today, but interfaces are still settling and may change without notice ahead of a first tagged release. Feedback and issues are welcome — see Getting Help.
Requires Python 3.13. Prefer uv.
git clone https://github.com/EricBoittier/mmml.git
cd mmml
uv sync
# Optional extras
uv sync --extra cli # shell tab completion (argcomplete)
uv sync --extra md-cpu # Vesin NL + MDAnalysis (CPU MD smokes)
uv sync --extra dev # pytest, MkDocs, ruff
make install-gpu # JAX CUDA 13 + CuPy (GPU nodes; SM 7.5+)
# make install-gpu-cuda12 # older GPUs / CUDA 12For PyCHARMM / Packmol (native libs, not installed by uv):
make install-native # builds libcharmm + packmol under setup/charmm
make doctor # mmml doctor — env / CHARMM readinessOr from a fresh clone: make install-full (uv sync + native build).
Register the project venv as its own kernel once, and select it in the
notebook (Kernel → Change Kernel → mmml-venv):
.venv/bin/python -m ipykernel install --user --name mmml-venv --display-name "mmml venv"Without this, Jupyter's default python3 kernel may start a different
interpreter: the kernelspec uv installs uses a bare "python" in its argv,
so it resolves against PATH and picks up an active conda environment instead of
.venv. The symptom is an immediate
TypeError: 'type' object is not subscriptable
on the first import mmml..., because that interpreter is too old to parse
tuple[float, ...] annotations. It looks like broken code but is purely kernel
selection. Check with import sys; print(sys.executable) — it must point inside
.venv.
# Conda
conda env create -f setup/environment.yml
conda activate mmml
# Or Makefile micromamba targets (preferred on clusters)
make micromamba-create
make micromamba-create-gpu # CUDA 12 env file
make micromamba-create-gpu-cuda13GPU env files: setup/environment-gpu.yml, setup/environment-gpu-cuda13.yml.
Dockerfile and Compose live under devtools/docker/:
cd devtools/docker
docker compose up -d mmml-cpu
docker compose exec mmml-cpu bash
# GPU: docker compose up -d mmml-gpuuv sync --extra cli
eval "$(register-python-argcomplete mmml)"
# or: eval "$(mmml completion bash)"mmml -h # compact top-level help
mmml commands # all subcommands by category
mmml examples # copy-paste invocations
mmml configure # interactive YAML / Snakemake wizard
mmml env # checkpoints + CHARMM paths
mmml md-system --help # condensed-phase MD flags
mmml doctor # environment health checkCondensed-phase campaigns: start from
mmml/cli/run/md_system.example.yaml
and the md-system YAML config guide.
CPU MD smokes (no CUDA; bundled DESdimers JSON checkpoint):
make install-md-cpu
source examples/md_cpu/_env.sh
bash examples/md_cpu/run_all.shSee examples/md_cpu/README.md.
ML-only energy/forces via ASE using the bundled ACO/DESdimers checkpoint
(examples/ckpts_json/DESdimers_params.json):
from pathlib import Path
import ase
import numpy as np
from mmml.interfaces.pycharmmInterface.calculator_utils import unpack_factory_result
from mmml.interfaces.pycharmmInterface.mmml_calculator import setup_calculator
ATOMS_PER_MONOMER = 10
N_MONOMERS = 2
Z = np.array([6, 1, 1, 1, 6, 1, 1, 1, 8, 1] * N_MONOMERS, dtype=np.int32)
R = np.zeros((ATOMS_PER_MONOMER * N_MONOMERS, 3), dtype=np.float64)
# Place monomers apart so the dimer is non-overlapping
R[ATOMS_PER_MONOMER:, 0] = 5.0
ckpt = Path("examples/ckpts_json/DESdimers_params.json")
factory = setup_calculator(
ATOMS_PER_MONOMER=ATOMS_PER_MONOMER,
N_MONOMERS=N_MONOMERS,
doML=True,
doMM=False,
model_restart_path=str(ckpt),
MAX_ATOMS_PER_SYSTEM=ATOMS_PER_MONOMER * N_MONOMERS,
defer_xla_gpu_warmup=True,
verbose=False,
)
calc, _, _ = unpack_factory_result(
factory(atomic_numbers=Z, atomic_positions=R, n_monomers=N_MONOMERS)
)
atoms = ase.Atoms(numbers=Z, positions=R)
atoms.calc = calc
print("Energy (kcal/mol):", atoms.get_potential_energy())For a geometry-aware version of the same path, run
uv run python examples/md_cpu/02_ml_energy_ase.py.
Published site: Read the Docs.
Serve the current MkDocs tree locally: uv sync --extra dev && make docs-serve → http://127.0.0.1:8000.
Highlights (in-repo):
- Getting started — install, CLI, local docs
- CLI overview —
mmml commands, examples, tab completion md-systemYAML configs — campaigns and condensed-phase builders- Calculator capability matrix — calculators, hybrid assembly, LR solvers
- PyCHARMM + MM/ML checklist — status, examples, diagrams
- MLpot settings — COM handoff, medium PBC, spatial MPI
- Documentation: Read the Docs
- Issues: GitHub Issues
MIT License, Copyright (c) 2025, Eric Boittier. See LICENSE for details.
Project based on the Computational Molecular Science Python Cookiecutter version 1.10.