Skip to main content
Docs

Search guides and API endpoints, for example “Idempotency-Key” or “submit job”.

    Tools · Computational Biology

    Relative Binding Free Energy

    Alchemical free-energy calculations for protein–ligand complexes — relative binding ΔΔG over a ligand network, absolute hydration ΔG, and REST2 replica-exchange sampling — with convergence checks on every result.

    Updated October 19, 2026

    On this page

    Prices, workflows, and method papersOpen in the app

    Relative Binding Free Energy is the validation step after docking and rescoring. Where MM-GBSA Rescoring gives an end-point estimate with no sampling, this tool samples alchemical intermediate states in explicit water and reports free-energy differences with their uncertainty. It runs OpenFE on OpenMM, on GPU hardware only.

    Choosing a mode

    ModeQuestion it answersInputs
    rbfe (default)How much tighter does ligand B bind than ligand A?Receptor PDB, docked poses, ligand pairs
    ahfeHow favourable is moving each ligand from vacuum into water?3D ligands only
    rest2Does a docked pose stay put, and where do binding-site waters sit?Receptor PDB, one docked pose

    How it works

    rbfe. For each pair a → b you nominate, a hybrid topology morphs a into b along a series of lambda windows, once bound to the receptor (complex leg) and once free in water (solvent leg). Windows swap configurations by Hamiltonian replica exchange, and MBAR turns the samples into a free energy for each leg:

    ΔΔG(a → b) = ΔG(complex) − ΔG(solvent) = ΔG_bind(b) − ΔG_bind(a)

    in kcal/mol; negative means b binds more tightly. The atoms of a and b are matched with kartograf, so pairs should share a scaffold. All pairs run in one job, so closed cycles in your network give a cycle-closure residual, and a maximum-likelihood fit of the network gives a ΔG for each ligand: relative (centred on zero), or anchored to an experimental value for one reference ligand.

    ahfe. Each ligand's charges are switched off and then its van der Waals contacts are removed, in water and in vacuum, giving its hydration free energy.

    rest2. Replica exchange with solute scaling: the ligand and every residue within 5 Å of it are simulated as if heated, replica by replica, while the rest of the system stays at the physical temperature. Only snapshots of the unscaled replica are reported.

    Ligands use the OpenFF Sage force field (openff-2.2.0), the protein ff14SB, and water TIP3P. Each ligand is charged once, before anything runs, so both ends of every pair share the same charges. To reuse charges from the Small-Molecule Force-Field Parameterizer, bind its systems to ligand_systems in a workflow; otherwise AM1-BCC runs once per ligand.

    Inputs

    • protein: a prepared receptor PDB with hydrogens (for example from the Protein Preparer); rbfe and rest2.
    • poses: docked poses as SDF, for example from GNINA or AutoDock Vina. Each ligand is named by its SDF title, and the first pose of each name is used.
    • edges (rbfe): the pairs, as [ligand_a, ligand_b] names. Choosing pairs that differ by a small change is your call; the tool does not design the network.
    • ligands (ahfe): 3D ligands as SDF.

    Sampling settings are the lambda windows per leg, equilibration and production time per window (or per replica), independent repeats, the temperature, and for rest2 the number of replicas and the hottest effective solute temperature. Their defaults and ranges are listed below.

    Outputs

    • ddg.csv: one row per pair with ΔΔG, its uncertainty, both leg ΔGs, the diagnostics below, the cycle-closure residual, and converged / status.
    • dg.csv: one ΔG per ligand (network fit or hydration).
    • rest2.csv and frames/: protein–ligand snapshots with the ligand's RMSD from the docked pose and the number of waters within 3.5 Å of it.
    • summary.json (settings, versions, warnings) and the full OpenFE results.

    In a workflow, pairs carry rbfe_ddg_kcal_mol, ligands rbfe_dg_kcal_mol or hydration_dg_kcal_mol, and both fe_uncertainty_kcal_mol, so filter steps can rank on them.

    Convergence

    Each result is checked three ways: its uncertainty (MBAR, or the spread across repeats), the agreement of forward and reverse estimates on half the data, and the overlap between neighbouring lambda windows. A result that fails any check keeps its value but is marked converged=false, with a warning in summary.json; it is never averaged in silently. Treat those values as unconverged and rerun with longer sampling or more windows.

    Limits

    • One job has a fixed budget of simulated time across all its pairs, windows, repeats and nanoseconds; split a larger network across jobs. Pairs a job cannot start within its time limit are reported as not run, never estimated.
    • This is hit validation for tens of pairs, not screening.
    • REST2 ligand RMSD is not corrected for symmetry: a flipped ring reads as a large RMSD. Look at the frames before concluding a pose is lost.

    Not covered

    Absolute protein–ligand binding free energies, membrane or cofactor-dependent targets, QM/MM, and protein–protein binding. For a quick physics re-rank without sampling, use MM-GBSA Rescoring; to run plain MD of a complex, use OpenMM MD.

    Run it from the API

    Submit with Submit a job and the job_type below. Price it first with Estimate job reservation cost: submitting reserves that amount from your wallet, and the charge settles at the actual runtime.

    Relative Binding Free Energy openmm-rbfe

    Job type
    openmm-rbfe
    Hardware
    l4a10l40s (default)a100-40gba100-80gbh100
    Typical runtime
    3 h on Nvidia L40S

    Payload

    Payload fields
    FieldTypeDescription
    modestring

    Default: "rbfe"One of: "rbfe", "ahfe", "rest2"

    proteinfile_object
    posesfile_object | file_object[]
    ligandsfile_object | file_object[]
    ligand_systemsartifact_ref | artifact_ref[]
    edges[]string[][]

    Limits: min items 1, max items 60

    referenceobject
    reference.ligandrequiredstring

    Limits: min length 1

    reference.dg_kcal_molrequirednumber
    lambda_windowsinteger

    Limits: ≥ 3, ≤ 24

    equilibration_nsnumber

    Default: 0.5Limits: ≥ 0.05, ≤ 5

    production_nsnumber

    Limits: ≥ 0.1, ≤ 50

    repeatsinteger

    Default: 1Limits: ≥ 1, ≤ 3

    temperature_knumber

    Default: 298.15Limits: ≥ 273, ≤ 373

    rest2_replicasinteger

    Default: 8Limits: ≥ 4, ≤ 16

    rest2_tmax_knumber

    Default: 600Limits: ≤ 1200

    File fields take {"name": "x.pdb", "content_b64": "…"} or a stored artifact, {"$artifact": {"id": "art-…", "port": "…"}}. Files are up to 25 MiB each.

    Example

    from cognichem_client import CogniChem
    
    client = CogniChem.from_env()  # reads COGNICHEM_API_KEY
    payload = {
        "mode": "rbfe",
        "protein": {
            "name": "protein.pdb",
            "content_b64": "<file contents, base64>",
        },
        "poses": {
            "name": "ligands.sdf",
            "content_b64": "<file contents, base64>",
        },
        "edges": [["lig_a", "lig_b"]],
        "lambda_windows": 3,
        "equilibration_ns": 0.05,
        "production_ns": 0.1,
        "repeats": 1,
        "temperature_k": 298.15,
    }
    
    estimate = client.jobs.estimate(job_type="openmm-rbfe", payload=payload, resource="l40s")
    print(f"Reserves ${estimate.cost:.2f}")
    
    job = client.jobs.submit(
        job_name="my-openmm-rbfe-run",
        job_type="openmm-rbfe",
        payload=payload,
        resource="l40s",
    )
    status = client.jobs.wait(job.process_id)
    if status.status == "completed":
        client.jobs.result(job.process_id, save_path=".")

    Sample data from the job catalog; long values are shortened here. Each job_name must be unique among your jobs.

    Workflow inputs

    • Force-field system (list) · optionalOPENMM_XML
    • Molecules (list) · optionalSDF
    • Docked poses (list)SDF
    • Protein structurePDB

    Workflow outputs

    • ArchiveZIP
    • TableCSV
    • TableCSV
    • StructuresPDB