← Files RowanARCHIVED FILE

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

3.53 KB · Oct 4, 2026 · 12:13 UTC

↓ Download file

# Covalent inhibitor scan

## Input

A `rowan.Protein` (or its UUID string) with the protein and ligand as separate entities — the ligand as a non-polymer residue. The complex can be covalently bonded already (e.g. from a crystal structure) or just a normally docked (non-covalent) pose; the scan runs from `scan_start` to `scan_stop` regardless of which end the input starts near. Plus two atom indices, both 0-based and in PDB record order (protein atoms, then ligand atoms):

- `protein_reactive_atom_index`: the reacting protein atom (e.g. a catalytic Cys `SG`).
- `ligand_reactive_atom_index`: the reacting ligand atom (e.g. the warhead carbon).
- `ligand_smiles`: SMILES of the ligand, used to parameterize it for the scan.

The ligand must be classified as non-polymer in the protein's data. When preparing the complex, pass the ligand residue name or index and its SMILES through `retain_non_polymer`. Verify the ligand remains a non-polymer in the prepared output; a covalently bonded ligand classified as part of the polymer chain causes the workflow to fail at compute time with "Complex PDB has no non-polymer atoms to use as the ligand". Measure both reactive atom indices from the final prepared structure, because preparation can change atom ordering.

If you don't already have a covalently-bonded complex (e.g. from a crystal structure), covalent docking (see `docking.md`, "gnina (noncovalent and covalent docking)") is a good way to generate one: it forms the bond between the specified reactive atoms and returns a complex whose `protein_reactive_atom_index`/`ligand_reactive_atom_index` (there, `covalent_protein_atom_index`/`covalent_ligand_atom_index`) can feed directly into this scan.

## Example

```python
import rowan

folder = rowan.get_folder("examples")

wf = rowan.submit_covalent_inhibitor_scan_workflow(
    protein=protein.uuid,  # covalently bonded or normally docked complex
    protein_reactive_atom_index=1571,
    ligand_reactive_atom_index=4492,
    ligand_smiles=ligand_smiles,
    settings=rowan.CovalentInhibitorScanSettings(scan_num=4),
    folder=folder,
)

result = wf.result()
for distance, energy in result.get_energies():
    print(f"{distance:.3f} Å  {energy}")
```

## Settings

`rowan.CovalentInhibitorScanSettings`:

- `truncation_radius` (default `6.0`): radius in angstrom beyond which the protein is truncated around the ligand.
- `unfreeze_radius` (default `0.0`): side chains with any atom within this radius (angstrom) of any ligand atom are relaxed during the scan; `0` freezes all side chains.
- `scan_start` (default `1.8`), `scan_stop` (default `3.5`): bond-distance range for the scan, in angstrom. Scans covalent to non-covalent by default, but the direction is just whichever end the input geometry is closer to. These defaults are tuned for a C–S bond (e.g. Cys `SG` to an acrylamide warhead carbon) — for other nucleophile/warhead pairs (Ser/Thr `O`, Lys `N`, His `N`, etc.), adjust both to bracket that bond's actual covalent and non-covalent distances.
- `scan_num` (default `10`): number of points along the scan.
- `calc_settings` (default `uma_s_omol`/`omol25`): settings for each scan-point optimization.
- `singlepoint_settings` (default `g_xtb`/`alpb(water)`): settings for the per-point implicit-solvent single-point energy.

## Result fields

- `scan_points`: list of `CovalentInhibitorScanPoint`, each with `index`, `distance` (Å), `molecule`, `energy` (Hartree, or `None` if the single-point failed), and `uuid`.
- `get_energies()`: list of `(distance, energy)` tuples, ordered by scan point index (`scan_start` to `scan_stop`).

SHA-256: d7252fa751698ec33a87b49260fa08b55cc856a17f6160b4c75302ee42a42e89