RBFE¶
Plan, run, and inspect Relative Binding Free Energy (RBFE) workflows in Deep Origin.
This page covers the tools around an RBFE run: planning and visualizing a ligand network, inspecting prepared systems, and reading results. For an end-to-end walk through of submitting a run, see the RBFE tutorial.
The RBFE class follows the common tool lifecycle: construct it,
start(quote=True) to estimate cost, confirm(), then watch() for progress.
It is submitted asynchronously, so your notebook stays responsive while it runs.
Planning and visualizing a network¶
When you pass a ligands set to RBFE, the workflow plans the pairwise network
for you. To see or tune that network before submitting a full run, run
Konnektor on its own:
from deeporigin.drug_discovery import Konnektor
kn = Konnektor(ligands=ligands, network_type="mst")
network = kn.run()
network.show_network() # interactive network view in the notebook
network.pairs # list of (ligand, ligand) tuples
network.is_connected # True if every ligand is reachable
show_network() renders an interactive graph:
network.pairs can be fed straight into RBFE(protein=..., pairs=network.pairs)
if you want to review the plan first and submit the FEP step separately. Konnektor
runs synchronously and is inexpensive, so it's a cheap way to sanity-check
connectivity before spending on simulation.
Choose network_type based on the trade-off you want:
"mst"— minimum spanning tree; fewest edges, lowest cost, no redundancy."star"— all ligands connected to one reference."cyclic"— redundant edges that form cycles, enabling consistency checks.
Inspecting prepared systems¶
System preparation builds two solvated models per pair — a binding system (protein + ligand) and a solvation system (ligand alone). Once the system-prep step of your run finishes, load and visualize a prepared system:
# Any prepared system from this run (first available):
system = rbfe.get_prepared_system()
system.show()
# A specific pair, when the run has many:
system = rbfe.get_prepared_system(
ligand1_id=ligand1.id,
ligand2_id=ligand2.id,
)
system.show()
system.show(solute=True) # solute-only view, when available
You will see something like:
You do not need to wait for the whole run to finish — prepared systems become
available as soon as the system-prep step completes. If no prepared-system rows
exist yet, get_prepared_system() raises an error telling you to wait or to pass
ligand1_id/ligand2_id to disambiguate.
Reading results¶
Pairwise ΔΔG¶
After the RBFE step completes, get_results() returns one row per pair:
rbfe.get_results()
| protein_id | ligand1_id | ligand2_id | ddG |
|---|---|---|---|
| prot-... | lig-... | lig-... | -1.23 kcal/mol |
ddG is the relative binding free energy difference between ligand1 and
ligand2, formatted with its unit. A more negative ddG means ligand2 binds
more tightly than ligand1.
Per-ligand absolute dG (cycle closure)¶
If you submitted the run with exp_abfe and/or fep_abfe anchors, the
cycle-closure step converts the pairwise network into absolute per-ligand
values:
rbfe.get_cycle_closure_results()
| ligand_id | dG | unit | cluster |
|---|---|---|---|
| lig-... | -9.9 | kcal/mol | 0 |
cluster groups ligands that are connected in the network; ligands in separate,
unconnected clusters cannot be placed on the same absolute scale. See the
RBFE tutorial
for how to supply anchors.
Tool logs¶
To see what the underlying tools reported during the run — useful for diagnosing a failure or slow step:
df = rbfe.get_user_logs()
df
Working with existing runs¶
Reconnect to a run started earlier, in this or a previous session:
# By execution id:
rbfe = RBFE.from_id("<executionId>")
# Or the most recently created RBFE run:
rbfe = RBFE.from_last_run()
rbfe.sync() # refresh status from the platform
rbfe.get_results()
This rehydrates the stored inputs (steps, protein, ligands/pairs, prepared systems, parameters) so you can check status, watch progress, or fetch results without re-specifying anything.
Troubleshooting¶
- No results yet — RBFE runs asynchronously. Call
rbfe.sync()and confirm the status isCompletedbefore expectingget_results()to return rows. get_prepared_system()raises — the system-prep step hasn't produced rows yet, or several pairs match. Wait, or passligand1_id/ligand2_id.- Empty cycle-closure results — cycle closure only runs when you pass
exp_abfeorfep_abfe; check that"cycle-closure"is inrbfe.steps. - Konnektor network not connected —
network.is_connectedisFalsewhen ligands are too dissimilar to map; trynetwork_type="star"or curate the set.
Additional resources¶
- RBFE tutorial
- RBFE reference (generated API docs)
- Work with Ligands