Skip to content

ABFE

This document describes how to run a ABFE simulation using Deep Origin tools.

Deprecated: Complex

This tutorial uses the deprecated Complex type. For new code, use ABFE, SystemPrep, and related APIs instead of orchestrating ABFE through Complex.

Prerequisites

We assume that we have an initialized and configured Complex object:

from deeporigin.drug_discovery import Complex, BRD_DATA_DIR

sim = Complex.from_dir(BRD_DATA_DIR)

Here, ABFE requires that the Complex object have an already prepared protein (PDB), and the associated ligands (SDF) are in a docked pose.

Warning

The Complex.from_dir() function only accepts 1 PDB file per directory. This function will throw an error if it finds more than 1 PDB file per directory.

For more details on how to get started, see Getting Started .

System Preparation

First, make sure you have prepared your system and verified that everything is as expected. To prepare a system for a single ligand, use:

ligand = sim.ligands[0]
prepared_system = sim.prepare(ligand=ligand)
prepared_system.show()

You will see something like:

Estimating costs

Before starting a ABFE run, you can estimate costs using:

# assuming we want to perform a single ABFE run on a single ligand
ligand = sim.ligands[0]
jobs = sim.abfe.run(ligand=ligand, quote=True)
job = jobs[0]

You will get back a widget representing this job such as this:

Example widget

Prices shown here are for demonstrative purposes only. Actual prices can vary.

Note that this Job is ready to run, but will not actually run unless you approve the amount and confirm.

Starting an ABFE run

Confirming a quoted Job

If you have already generated a quoted Job (using quote as shown above), you can start the ABFE run using:

job.confirm()

This will start the ABFE run and the job widget will now display:

Multiple ligands

To run an end-to-end ABFE workflow on multiple ligands, we use:

jobs = sim.abfe.run(ligands=[sim.ligands[0],sim.ligands[1]]) 

Omitting the ligand will run ABFE on all ligands in the Complex object.

jobs = sim.abfe.run() 

Each ligand will be run in parallel on a separate instance, and each Job can be monitored and controlled independently.

Watch Jobs

To monitor the status of this job, use:

job.watch() 

This makes the widget auto-update, and monitor the status of the job till it reaches a terminal state (Cancelled, Succeeded, or Failed).

If you are using the jobs-centric ABFE class with a prepared system, after abfe.start() you can monitor in Jupyter in two ways:

  • Non-blocking cell (same idea as job.watch()): the cell returns immediately while the widget keeps updating; you can run other cells in the meantime.
task = await abfe.watch()
  • Blocking cell: the cell does not finish until the execution reaches a terminal state.
await abfe.watch_async()

In a plain Python script (no running event loop), use:

import asyncio

asyncio.run(abfe.watch_async())

Monitoring Jobs

For more details about how to monitor jobs, look at this How To section.

Parameters

ABFE simulation parameters are controlled via the ABFEParams dataclass. Default values are tuned for production runs; most users will only need to adjust a small number of fields.

Viewing parameters

To inspect the current parameters on an ABFE object, access the params property:

from deeporigin.drug_discovery import Complex, BRD_DATA_DIR

sim = Complex.from_dir(BRD_DATA_DIR)
sim.abfe.params
Expected output

Parameters are printed one per line. Fields that have been changed from their defaults are marked with an asterisk (*):

ABFEParams(
  annihilate: True
  dt: 0.004
  temperature: 298.15
  cutoff: 0.9
  repeats: 3 *
  replex_period_ps: 2.5
  test_run: 0
  binding_n_windows: 48
  binding_npt_reduce_restraints_ns: 2.0
  binding_nvt_heating_ns: 1.0
  binding_steps: 1250000
  solvation_n_windows: 32
  solvation_npt_reduce_restraints_ns: 0.2
  solvation_nvt_heating_ns: 0.1
  solvation_steps: 500000
)

Modifying parameters

ABFEParams is an immutable (frozen) dataclass. To change parameters, use dataclasses.replace() to create a modified copy and assign it back to the ABFE object:

from dataclasses import replace
from deeporigin.drug_discovery import Complex, BRD_DATA_DIR

sim = Complex.from_dir(BRD_DATA_DIR)

params = sim.abfe.params
params = replace(params, repeats=3, test_run=1)
sim.abfe.params = params

Multiple fields can be changed in a single replace() call. The original params object is never modified — replace() always returns a new instance.

Changing parameters may lead to simulation failures

Some parameters, such as dt, are constrained to specific ranges. You will not be allowed to start a simulation run if these parameters fall outside valid ranges.

Changing parameters away from their defaults may lead to simulation failures.

Results

Viewing results

After initiating a run, we can view results using:

df = sim.abfe.show_results()
df

This shows a table similar to:

dG Std AnalyticalCorr Repeats SMILES r_exp_dg
-9.98 0.0 -11.46 1 COCCn1cc(-c2cccc(C(=O)N(C)C)c2)c2cc[nH]c2c1=O -7.22

Viewing trajectories

To view MD trajectories from this run, refer to this How-to section

Viewing overlap matrix

An FEP overlap matrix is a diagnostic used in free energy perturbation calculations to evaluate how well neighboring λ states sample overlapping regions of configuration space. Each matrix element measures the statistical overlap between configurations from different states based on their energy distributions. The goal is to ensure every state has overlap with its neighbors in both directions – so that off-diagonal elements are sufficiently larger than zero.

The overlap matrix between windows can be viewed using:

sim.abfe.show_overlap_matrix(ligand=ligand, run="binding")

An image such as the following will be shown:

Overlap matrix for Binding Run

To view the overlap matrix for the solvation run, use:

sim.abfe.show_overlap_matrix(ligand=ligand, run="solvation")

Viewing convergence time plots

To view the convergence time plots for a run, use:

sim.abfe.show_convergence_time(ligand=ligand, run="binding")
An image such as the following will be shown:

Convergence plot for Binding Run