Fastfold Docs
Apps

OpenMMDL

Prepare scripts, submit drafts, and run OpenMMDL workflows from local files or existing workflows.

Use OpenMMDL to run openmmdl_v1 workflows.

Quick reference
Workflow
openmmdl_v1 · task inference_openmmdl
CLI

fastfold-cli workflows openmmdl prepare-script …, from-local-files …, from-workflow …, execute-draft …, extract-frame … — see SDK CLI

Docker Hub
fastfold/openmmdl (tag from deployment; defaults include fastfold/openmmdl:latest)

Metrics and Artifacts

The Fastfold API uses the same availableOutput catalog for inference_openmmdl as for inference_calvados_openmm on POST /v1/workflows/node/output-schema (one shared implementation in the backend). Use workflowTaskTypeId: inference_openmmdl when requesting schema hints for OpenMMDL.

After completion, artifacts appear under output_library_items on GET /v1/workflows/task-results/<workflow_id> (same pattern as OpenMM). parsed_results is only used for BoltzGen.

Declared keys (output-schema)

The response lists availableOutput[] entries with name, type, and description.

Scalars (examples):

NameTypeDescription
metrics.ligand_detectedkey/booleanLigand atoms detected
metrics.rmsd.mean_angstromkey/floatMean RMSD (Å)
metrics.rmsd.stddev_angstromkey/floatRMSD σ (Å)
metrics.rmsf.mean_angstromkey/floatMean RMSF (Å)
metrics.rmsf.stddev_angstromkey/floatRMSF σ (Å)
metrics.rmsf.max_residuekey/integerResidue index with highest RMSF
metrics.radius_of_gyration.mean_angstromkey/floatMean Rg (Å)
metrics.radius_of_gyration.stddev_angstromkey/floatRg σ (Å)
metrics.free_energy_landscape.min_framekey/integerFEL minimum frame
metrics.free_energy_landscape.min_time_nskey/floatTime at FEL minimum (ns)
metrics.free_energy_landscape.min_rmsd_angstromkey/floatRMSD at minimum (Å)
metrics.free_energy_landscape.min_rg_angstromkey/floatRg at minimum (Å)
metrics.binding_energy.availablekey/booleanBinding energy computed
metrics.binding_energy.mean_kj_per_molkey/floatMean interaction energy
metrics.binding_energy.stddev_kj_per_molkey/floatBinding energy σ
metrics.protein_ligand_distance.availablekey/booleanPL distance computed
metrics.protein_ligand_distance.mean_angstromkey/floatMean min distance (Å)
metrics.protein_ligand_distance.stddev_angstromkey/floatDistance σ (Å)

Files (patterns):

NameTypeDescription
analysis/metrics.jsonfile/JSONMD quick analysis JSON
analysis/*_rmsd.pngfile/PNGRMSD plot
analysis/*_rmsf.pngfile/PNGRMSF plot
analysis/*_rg.pngfile/PNGRg plot
analysis/*_fel.pngfile/PNGFEL plot
analysis/*_binding_energy.pngfile/PNGBinding energy plot
analysis/*_pl_distance.pngfile/PNGProtein–ligand distance plot

SDK and CLI

from fastfold import Client

client = Client()
out = client.workflows.task_results(workflow_id)
print(out.raw)
fastfold-cli workflows task-results <workflow_id>
fastfold-cli workflows task-results <workflow_id> --json

First run from local topology + ligand files

This KEAP1 + IQK example is a practical first run because it starts from local inputs and does not require any prior workflow.

Required local files:

  • topology: .pdb, .gro, or your supported topology input
  • ligands: .sdf, .mol2, or similar ligand files

Download the exact files used in these examples:

Note: These examples are intentionally minimal. They highlight the core runtime fields needed for a first submission without forcing the full workflow_input surface into the first example.

from fastfold import Client

client = Client()
workflow = client.openmmdl.submit_from_local_files(
    topology_path="./KEAP1kd.pdb",
    ligand_paths=["./IQK.sdf"],
    simulation_name="KEAP1 + IQK",
    input_json={
        "smallMoleculeMode": "single",
        "equilibration": "only_minimization",
        "sim_length_ns": 0.05,
        "step_time_ps": 0.002,
        "failure_retries": 0,
        "addWater": False,
        "addMembrane": False,
        "boxType": "geometry",
        "geomPadding": 1.0,
        "geometryDropdown": "cube",
        "membranePadding": 2.0,
        "writeDCD": True,
        "dcdFrames": 5,
        "pdbInterval_ns": 0.05,
        "writeData": False,
        "writeCheckpoint": False,
    },
)
print(workflow.workflow_id)
fastfold-cli workflows openmmdl from-local-files \
  --topology ./KEAP1kd.pdb \
  --ligand ./IQK.sdf \
  --simulation-name "KEAP1 + IQK" \
  --input-json fastfold/examples/openmmdl/workflow_input.json

Key fields in this example:

  • smallMoleculeMode: "single" for the ligand-bound setup
  • equilibration: "only_minimization" for a short initial run
  • sim_length_ns: 0.05 and step_time_ps: 0.002
  • boxType: "geometry" with geomPadding: 1.0
  • addWater: false and addMembrane: false
  • failure_retries: 0

Tip: Start with the base example before moving to the water-box or membrane variants. It is the easiest way to confirm your topology and ligand inputs are accepted before adding solvent or membrane configuration.

Quick water box

Use this variant to run the same input set in a water box.

from fastfold import Client

client = Client()
workflow = client.openmmdl.submit_from_local_files(
    topology_path="./KEAP1kd.pdb",
    ligand_paths=["./IQK.sdf"],
    simulation_name="KEAP1 + IQK (Quick Water Box)",
    input_json={
        "name": "KEAP1 + IQK (Quick Water Box)",
        "smallMoleculeMode": "single",
        "equilibration": "only_minimization",
        "sim_length_ns": 0.05,
        "step_time_ps": 0.002,
        "failure_retries": 0,
        "addWater": True,
        "addMembrane": False,
        "boxType": "geometry",
        "geomPadding": 1.0,
        "geometryDropdown": "cube",
        "membranePadding": 2.0,
        "writeDCD": True,
        "dcdFrames": 5,
        "pdbInterval_ns": 0.05,
        "writeData": False,
        "writeCheckpoint": False,
    },
)
print(workflow.workflow_id)
fastfold-cli workflows openmmdl from-local-files \
  --topology ./KEAP1kd.pdb \
  --ligand ./IQK.sdf \
  --simulation-name "KEAP1 + IQK (Quick Water Box)" \
  --input-json fastfold/examples/openmmdl/quick_water_box.workflow_input.json

Quick membrane

Use this variant to run the same input set in membrane mode.

Reminder: When addMembrane is true, use a membrane-compatible topology and keep membranePadding aligned with the backend constraints documented in the full schema below.

from fastfold import Client

client = Client()
workflow = client.openmmdl.submit_from_local_files(
    topology_path="./KEAP1kd.pdb",
    ligand_paths=["./IQK.sdf"],
    simulation_name="KEAP1 + IQK (Quick Membrane)",
    input_json={
        "name": "KEAP1 + IQK (Quick Membrane)",
        "smallMoleculeMode": "single",
        "equilibration": "only_minimization",
        "sim_length_ns": 0.05,
        "step_time_ps": 0.002,
        "failure_retries": 0,
        "addWater": False,
        "addMembrane": True,
        "membranePadding": 2.0,
        "lipidType": "POPC",
        "writeDCD": True,
        "dcdFrames": 5,
        "pdbInterval_ns": 0.05,
        "writeData": False,
        "writeCheckpoint": False,
    },
)
print(workflow.workflow_id)
fastfold-cli workflows openmmdl from-local-files \
  --topology ./KEAP1kd.pdb \
  --ligand ./IQK.sdf \
  --simulation-name "KEAP1 + IQK (Quick Membrane)" \
  --input-json fastfold/examples/openmmdl/quick_membrane.workflow_input.json

Full input schema

Use this section as a reference for the full workflow_input shape used by the backend for openmmdl_v1:

{
  "workflow_name": "openmmdl_v1",
  "name": "Example OpenMMDL Workflow",
  "create_mode": "",
  "workflow_input": {
    "name": "openmmdl_local_example",
    "files": {
      "topology": {
        "libraryItemId": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
        "fileName": "protein.pdb"
      },
      "ligands": [
        {
          "libraryItemId": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb",
          "fileName": "ligand.sdf"
        }
      ]
    },
    "topologyCode": "UNK",
    "sdfResname": "UNK",
    "ligand_selection": "resname UNK",
    "forcefield": "AMBER19",
    "waterModel": "TIP3P",
    "smallMoleculeMode": "none",
    "smallMoleculeForceField": "gaff",
    "smallMoleculeForceFieldVersion": "gaff-2.2.20",
    "ligandMinimization": false,
    "ligandSanitization": false,
    "addHydrogens": true,
    "add_missing_residues": false,
    "selected_missing_residue_spans": [],
    "ph": 7.0,
    "addWater": false,
    "addMembrane": false,
    "boxType": "custom",
    "boxx": 12.0,
    "boxy": 12.0,
    "boxz": 12.0,
    "geomPadding": 1.0,
    "geometryDropdown": "cube",
    "lipidType": "POPC",
    "membranePadding": 2.0,
    "ionicstrength": 0.15,
    "positiveion": "Na",
    "negativeion": "Cl",
    "sim_length_ns": 1.0,
    "sim_length": 1.0,
    "step_time_ps": 0.002,
    "dt": 0.002,
    "equilibration": "minimization_and_equilibration",
    "precision": "mixed",
    "writeDCD": true,
    "dcdFilename": "trajectory.dcd",
    "dcdFrames": 100,
    "pdbInterval_ns": 0.01,
    "writeData": true,
    "dataFilename": "log.txt",
    "dataInterval": 5000,
    "dataFields": ["step", "speed", "progress", "potentialEnergy", "temperature"],
    "writeCheckpoint": true,
    "checkpointFilename": "checkpoint.chk",
    "checkpointInterval_ns": 0.02,
    "writeSimulationXml": false,
    "systemXmlFilename": "system.xml",
    "integratorXmlFilename": "integrator.xml",
    "writeFinalState": false,
    "finalStateFileType": "stateXML",
    "finalStateFilename": "final_state.xml",
    "restart_checkpoint": "no",
    "restart_step": 0,
    "mdtraj_output": "mdtraj_pdb_dcd",
    "mda_output": "mda_pdb_dcd",
    "mda_selection": "mda_prot_lig_all",
    "cleanup": false,
    "analysis_selection": "analysis_all_prot_lig",
    "binding_mode": 40,
    "min_transition": 1,
    "rmsd_diff": "No",
    "stable_water": true,
    "pml_generation": true,
    "wc_distance": 1.0,
    "run_analysis": true,
    "openmmdl_analysis": "Yes",
    "analysis_cpus": 4,
    "failure_retries": 1,
    "nonbondedMethod": "PME",
    "cutoff": 1.0,
    "ewaldTol": 0.0005,
    "constraints": "hbonds",
    "constraintTol": 0.000001,
    "hmr": true,
    "hmrMass": 1.5,
    "ensemble": "npt",
    "temperature": 300.0,
    "friction": 1.0,
    "pressure": 1.0,
    "barostatInterval": 25,
    "platform": "CUDA",
    "md_postprocessing": true
  }
}

Field notes:

  • workflow_input.name and workflow_input.files.topology are required.
  • workflow_input.files.ligands may be a single object or an array. The backend normalizes it to an array.
  • topologyCode and sdfResname are mirrored. If you omit both, the backend falls back to UNK.
  • sim_length_ns and sim_length are mirrored aliases. step_time_ps and dt are also mirrored aliases.
  • run_analysis is the boolean input. openmmdl_analysis is the derived string form used by the downstream script layer.
  • membranePadding is always required and must be > 0. When addMembrane is true, it must be at least 2.0.
  • analysis_cpus must be an integer >= 1. failure_retries must be an integer >= 0.
  • forcefield and waterModel are normalized and validated as a compatible pair by the backend.
  • platform is pinned to CUDA and md_postprocessing is forced to true by the backend even if you pass something else.
  • create_mode is optional. Use the regular run path unless you specifically want draft-script flows.

Generic payload file

If you upload the topology and ligand files to the library first, the packaged payload file matches the request body closely:

Note: Choose this payload form when you want reproducible automation around library uploads, stored payload files, or CI-driven workflow submission.

fastfold-cli workflows create --payload-file fastfold/examples/openmmdl/from_local_files.json

The package also ships helper override files for these presets:

  • fastfold/examples/openmmdl/workflow_input.json
  • fastfold/examples/openmmdl/quick_water_box.workflow_input.json
  • fastfold/examples/openmmdl/quick_membrane.workflow_input.json

Prepare script only

import json
from pathlib import Path

from fastfold import Client

client = Client()
payload = json.loads(Path("fastfold/examples/openmmdl/from_local_files.json").read_text())
workflow_input = payload["workflow_input"]
prepared = client.openmmdl.prepare_script(workflow_input)
print(prepared.generated_script)
fastfold-cli workflows openmmdl prepare-script --input-json fastfold/examples/openmmdl/from_local_files.json

Draft script, then execute

from fastfold import Client

client = Client()
draft = client.openmmdl.submit_from_local_files(
    topology_path="./protein.pdb",
    ligand_paths=["./ligand.sdf"],
    draft_script=True,
)
client.openmmdl.execute_draft(draft.workflow_id)
print(draft.workflow_id)
fastfold-cli workflows openmmdl from-local-files \
  --topology ./protein.pdb \
  --ligand ./ligand.sdf \
  --draft-script

fastfold-cli workflows openmmdl execute-draft <workflow_id>

Rerun from an existing workflow

from fastfold import Client

client = Client()
workflow = client.openmmdl.submit_from_workflow(
    "af2473ef-820d-44df-98fe-fa15103157d5",
    simulation_name="openmmdl_rerun",
    prepare=True,
)
print(workflow.workflow_id)

Extract a frame

fastfold-cli workflows openmmdl extract-frame af2473ef-820d-44df-98fe-fa15103157d5 --time-ns 10

Related API docs:

Last updated on

On this page