Skip to content

Repository files navigation

md-workflows

A Python CLI and Docker image for running the full molecular-dynamics workflow pipeline (GROMACS + AmberTools + DIALS/cctbx + lunus).

Docker image layout

The image is built in stages so the architecture-specific GROMACS compile is isolated from the portable scientific stack — forks targeting other hardware can swap the GROMACS stage without rebuilding the base:

Stage Dockerfile Contents
base Dockerfile.base CUDA 12.6 devel toolchain, micromamba/conda lunus env, lunus, ChimeraX. Architecture-neutral.
gromacs Dockerfile.gromacs GROMACS (CUDA, tuned for H100 / AVX-512 by default) + the md_workflows package. The consumable image.

(An Astera-specific Dockerfile.actl overlay adds workspace conventions on top of gromacs. It is tracked here so it stays under CI lint coverage, but is built and published only from the astera deployment branch.)

1) Build the images

From the project root:

# 1. Base — architecture-neutral foundation
docker build -f Dockerfile.base -t md-base:local .

# 2. GROMACS + md-workflows (the runnable image).
#    Override the GMX_* build args for non-H100 / non-AVX-512 hardware, e.g.
#    --build-arg GMX_CUDA_TARGET_SM=80 --build-arg GMX_SIMD=AVX2_256
docker build -f Dockerfile.gromacs --build-arg BASE_IMAGE=md-base:local -t md-gromacs:local .

CI builds these stages and pushes versioned tags (derived from the version in pyproject.toml) to the Astera Harbor registry; see .github/workflows/build-images.yml on the astera branch.

2) Start a container

Run interactively, mounting the project directory so inputs/outputs are available on the host:

docker run --rm -it \
  --user "$(id -u):$(id -g)" \
  --gpus all \
  --name md_container \
  -e HOME=/workspace \
  -v "$(pwd):/workspace" \
  -w /workspace \
  md-gromacs:local \
  bash

This registers the single md-workflows CLI entry point from pyproject.toml.

3) Run the workflow

The CLI is one Typer app with a subcommand per step plus run-pipeline. Global options --workdir/-w (run directory), --config/-c (YAML/TOML), and --resume/--force come before the subcommand.

Run the full prep pipeline (param_prot → make_crystal → make_waterbox → solvate → minimize → equilibrate → resolvate, ending with the adaptive pressure loop):

md-workflows --workdir . run-pipeline --pdb-id 4LZT --ix 5

Run a single step (each resolves its inputs from --workdir and fails loudly if any are missing):

md-workflows -w . minimize
md-workflows -w . resolvate --target-bar 1.0

Per-system settings live in a config file; flags override individual values. The dominant cross-machine knob is the per-invocation GROMACS mdrun profile (run_profiles, e.g. GPU offload + thread counts):

# config.yaml
pdb_id: 4LZT
crystal: { ix: 5 }
waterbox: { nc_scale: 5, conc: 60.0 }
solvate: { ionic_strength: 0.1 }
run_profiles:
  equil: { ntomp: 16, nb: gpu, pme: gpu, bonded: gpu, tunepme: false }
  min:   { ntomp: 16, nb: gpu, pme: cpu, bonded: cpu, tunepme: false }
md-workflows -w run_dir -c config.yaml run-pipeline
md-workflows -w run_dir -c config.yaml --resume run-pipeline   # skip completed steps

--resume skips a step whose durable outputs already exist. Exit codes: 0 ok, 1 domain error, 2 missing input, 3 external tool failed.

Python / SDK

The same logic is importable:

from md_workflows import run_standard_md
result = run_standard_md("4LZT", "run_dir", crystal={"ix": 5}, resume=True)

To see all commands and flags:

md-workflows --help
md-workflows run-pipeline --help

Development

Lint and format with ruff (config in pyproject.toml):

pip install '.[dev]'
ruff check md_workflows
ruff format --check md_workflows

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages