← Files RowanARCHIVED FILE

skills/computational-chemistry-and-biology/reference/binding_affinity.md

3 KB · Oct 3, 2026 · 06:14 UTC

↓ Download file

# Binding Affinity

## Input

Two submission modes — choose based on whether the ligand is already in the protein PDB.

**Mode 1 — holo protein:** the protein PDB already contains the bound ligand as a residue. Pass `ligand_residue_name` to identify which residue is the ligand; everything else is treated as receptor.

**Mode 2 — apo protein + external poses:** the protein has no bound ligand. Pass `ligand_structures` with one or more molecules that are already in the protein's coordinate frame (e.g. from a prior docking run). When scoring multiple ligands, this mode is preferred over submitting separate workflows — all poses share the same pocket geometry.

- Protein: a `rowan.Protein` or its UUID. Get one from the PDB with `rowan.create_protein_from_pdb_id(pdb_code)`, or upload your own with `rowan.upload_protein(name, path)`.
- `ligand_residue_name`: residue name of the bound ligand in a holo protein PDB (mode 1).
- `ligand_structures`: list of `StructureInput` molecules with 3D coordinates, already aligned to the protein (mode 2). Load from an SDF with `rowan.load_named_ligands(path)`.

Binding affinity is computed using SQM energies (PM6-D3H4X: COSMO geometry optimization followed by COSMO2 single-point, in water by default) on a truncated pocket around the ligand. When scoring multiple ligands, submitting them together in one workflow is preferred over separate workflows — all poses share the same pocket environment, making scores directly comparable.

## Example

```python
from pathlib import Path
import rowan

folder = rowan.get_folder("examples")
data_dir = Path("examples/data")

protein = rowan.upload_protein("TYK2", data_dir / "tyk2_structure.pdb")
ligands = rowan.load_named_ligands(data_dir / "tyk2_ligands.sdf")

workflow = rowan.submit_binding_affinity_workflow(
    protein=protein.uuid,
    ligand_structures=list(ligands.values()),
    name="Binding Affinity — TYK2 ligands",
    folder=folder,
)

result = workflow.result()
for name, score in zip(ligands.keys(), result.scores):
    print(f"{name}: {score.binding_affinity:.2f} kcal/mol (strain: {score.strain})")
```

## Settings

`binding_affinity_settings` accepts a `rowan.SinglePointEnergySettings` object:

- `multistage_opt_settings` (default PM6-D3H4X/COSMO optimization + PM6-D3H4X/COSMO2 single-point in water): a `rowan.MultiStageOptSettings` controlling ligand geometry optimization and energy evaluation.
- `truncation_radius` (default `6.0` Å): protein residues beyond this distance from the ligand are excluded from the calculation.

```python
rowan.submit_binding_affinity_workflow(
    protein=protein.uuid,
    ligand_residue_name="LIG",
    binding_affinity_settings=rowan.SinglePointEnergySettings(truncation_radius=8.0),
)
```

## Results

`result.scores` is a list of `BindingAffinityScore` objects in the same order as the input ligands:

- `binding_affinity`: binding affinity in kcal/mol (ΔE = E(complex) − E(protein_region) − E(ligand)).
- `strain`: energy difference between the input pose and the SQM-optimized pose, in kcal/mol.

SHA-256: c483fc8ed9a99b39e2a16f7168c3a8f1af508747e19d5dccd981e295d975c23b