OpenMMDL
Prepare scripts, submit drafts, and run OpenMMDL workflows from local files or existing workflows.
Use OpenMMDL to run openmmdl_v1 workflows.
- Workflow
openmmdl_v1· taskinference_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):
| Name | Type | Description |
|---|---|---|
metrics.ligand_detected | key/boolean | Ligand atoms detected |
metrics.rmsd.mean_angstrom | key/float | Mean RMSD (Å) |
metrics.rmsd.stddev_angstrom | key/float | RMSD σ (Å) |
metrics.rmsf.mean_angstrom | key/float | Mean RMSF (Å) |
metrics.rmsf.stddev_angstrom | key/float | RMSF σ (Å) |
metrics.rmsf.max_residue | key/integer | Residue index with highest RMSF |
metrics.radius_of_gyration.mean_angstrom | key/float | Mean Rg (Å) |
metrics.radius_of_gyration.stddev_angstrom | key/float | Rg σ (Å) |
metrics.free_energy_landscape.min_frame | key/integer | FEL minimum frame |
metrics.free_energy_landscape.min_time_ns | key/float | Time at FEL minimum (ns) |
metrics.free_energy_landscape.min_rmsd_angstrom | key/float | RMSD at minimum (Å) |
metrics.free_energy_landscape.min_rg_angstrom | key/float | Rg at minimum (Å) |
metrics.binding_energy.available | key/boolean | Binding energy computed |
metrics.binding_energy.mean_kj_per_mol | key/float | Mean interaction energy |
metrics.binding_energy.stddev_kj_per_mol | key/float | Binding energy σ |
metrics.protein_ligand_distance.available | key/boolean | PL distance computed |
metrics.protein_ligand_distance.mean_angstrom | key/float | Mean min distance (Å) |
metrics.protein_ligand_distance.stddev_angstrom | key/float | Distance σ (Å) |
Files (patterns):
| Name | Type | Description |
|---|---|---|
analysis/metrics.json | file/JSON | MD quick analysis JSON |
analysis/*_rmsd.png | file/PNG | RMSD plot |
analysis/*_rmsf.png | file/PNG | RMSF plot |
analysis/*_rg.png | file/PNG | Rg plot |
analysis/*_fel.png | file/PNG | FEL plot |
analysis/*_binding_energy.png | file/PNG | Binding energy plot |
analysis/*_pl_distance.png | file/PNG | Protein–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> --jsonFirst 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.jsonKey fields in this example:
smallMoleculeMode: "single"for the ligand-bound setupequilibration: "only_minimization"for a short initial runsim_length_ns: 0.05andstep_time_ps: 0.002boxType: "geometry"withgeomPadding: 1.0addWater: falseandaddMembrane: falsefailure_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.jsonQuick 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.jsonFull 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.nameandworkflow_input.files.topologyare required.workflow_input.files.ligandsmay be a single object or an array. The backend normalizes it to an array.topologyCodeandsdfResnameare mirrored. If you omit both, the backend falls back toUNK.sim_length_nsandsim_lengthare mirrored aliases.step_time_psanddtare also mirrored aliases.run_analysisis the boolean input.openmmdl_analysisis the derived string form used by the downstream script layer.membranePaddingis always required and must be> 0. WhenaddMembraneistrue, it must be at least2.0.analysis_cpusmust be an integer>= 1.failure_retriesmust be an integer>= 0.forcefieldandwaterModelare normalized and validated as a compatible pair by the backend.platformis pinned toCUDAandmd_postprocessingis forced totrueby the backend even if you pass something else.create_modeis 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.jsonThe package also ships helper override files for these presets:
fastfold/examples/openmmdl/workflow_input.jsonfastfold/examples/openmmdl/quick_water_box.workflow_input.jsonfastfold/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.jsonDraft 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 10Related API docs:
Last updated on