Docking¶
Dock ligands to a Protein with the Deep Origin docking tool.
Prerequisites¶
- You have a prepared Protein
- You have a Ligand or LigandSet
- You have protonated your ligands
- You have found pockets in your protein using PocketFinder
Docking a single Ligand¶
Use Docking with your protein, pocket, and ligand. Here pocket is a Pocket from PocketFinder . Both Docking.run() and Docking.start() use client.executions.create: run() sets sync=True for one ligand (one blocking request until completion), and start() sets sync=False for a single persisted async job with two or more ligands. Docking.run() returns a LigandSet of poses.
from deeporigin.drug_discovery import Docking
docking = Docking(protein=protein, pocket=pocket, ligand=ligand)
poses = docking.run()
Estimating cost¶
To get a cost estimate without running the docking, call quote() on the Docking instance:
docking = Docking(protein=protein, pocket=pocket, ligand=ligand)
docking.quote() # populates docking.estimate
docking.estimate # estimated cost in dollars
docking.cost # None until a billable run completes
After a completed run, the actual cost is on the same object:
docking = Docking(protein=protein, pocket=pocket, ligand=ligand)
poses = docking.run()
docking.cost # actual cost in dollars
Viewing docked poses¶
Docked poses for that ligand can be viewed using:
protein.show(poses=poses)
You will see something similar to the following. Use the arrows to inspect individual poses.
Viewing pose scores and binding energy¶
Every pose is assigned a pose score and a binding energy. These can be viewed using:
poses
A widget similar to the following will be shown:
LigandSet with 15 poses
SMILES: Cc1[nH]c2cc(Cl)cc(Cl)c2c1CCN
Properties: Binding Energy, POSE SCORE, SMILES, initial_smiles
Use .to_dataframe() to convert to a dataframe, .show_df() to view dataframewith structures, or .show() for 3D visualization
To work with a dataframe containing this data, use:
df = poses.to_dataframe()
Exporting poses to SDF¶
Poses can be saved to a SDF file using:
poses.to_sdf()
Docking many ligands¶
Using batch jobs¶
Tutorial
Follow the tutorial on how to dock ligands using batch jobs. This is best suited for large jobs with 100+ ligands.
Using functions¶
Several ligands in a LigandSet can be docked by passing ligands to Docking, then Docking.start() (async). Poll with sync() or Jupyter helpers until the job completes, then call get_results() to retrieve a LigandSet of poses.
docking = Docking(protein=protein, pocket=pocket, ligands=ligands)
docking.start()
# … wait for completion (docking.sync() in a loop, or watch() in notebooks) …
poses = docking.get_results()
poses is a LigandSet containing the docked poses. To work with a DataFrame:
df = poses.to_dataframe()
To filter poses to keep only top poses, use:
top_poses = poses.filter_top_poses()
These poses can be visualized as before:
protein.show(poses=poses)
If you need SDF files for the poses (e.g. for export), use get_poses() instead, which downloads the SDF files from the platform:
poses = docking.get_poses()
poses.to_sdf("my_poses.sdf")
To estimate the cost of docking a full LigandSet without running it:
docking = Docking(protein=protein, pocket=pocket, ligands=ligands)
docking.quote()
docking.estimate # total estimated cost across all ligands
Constrained docking¶
Use ConstrainedDocking to dock a ligand while pulling selected atoms toward target coordinates with harmonic constraints.
Typically, constraints are derived from a reference docked pose for a similar ligand using a Maximum Common Substructure (MCS). You can pass a docked reference ligand directly, or supply explicit constraint dictionaries.
MCS workflow (reference pose)¶
Dock a reference ligand, then constrained-dock a query ligand aligned to that pose:
from deeporigin.drug_discovery import ConstrainedDocking, Docking
ref_poses = Docking(protein=protein, pocket=pocket, ligand=reference_ligand).run()
reference_pose = ref_poses.ligands[0]
cd = ConstrainedDocking(
protein=protein,
pocket=pocket,
ligand=query_ligand,
reference=reference_pose,
)
poses = cd.run()
The query ligand must have a structure file on the platform (load from SDF/MOL2 and call query_ligand.sync()). The reference pose must have 3D coordinates (for example from Docking.run()).
To view new poses together with the reference pose:
protein.show(poses=reference_pose + poses)
Explicit constraints¶
For advanced use, pass precomputed constraints (1-based atom indices in the ligand structure file):
ligand = Ligand.from_sdf("query.sdf")
ligand.sync()
cd = ConstrainedDocking(
protein=protein,
pocket=pocket,
ligand=ligand,
constraints=[
{"index": 1, "coordinates": [-15.0, -0.23, 10.56], "energy": 5.0},
],
)
poses = cd.run()
You can also build constraints locally with LigandSet.compute_constraints() and pass the first list entry for a single ligand.
Filtering docking outputs¶
Filter docking results by score and related properties.
Deprecated: Complex
The examples below use the deprecated Complex type. New workflows should use Docking (and related APIs) instead of Complex.docking.
Here we assume that you have constructed a Complex object and successfully run Docking.
Following convention, we assume that the Complex object is called sim.
Fetch docked poses¶
First, we get the results of Docking in a pandas DataFrame using:
poses = sim.docking.get_poses()
poses object shows us:
LigandSet with 2246 ligands
157 unique SMILES
Properties: Binding Energy, POSE SCORE, SCORE, SMILES, initial_smiles
Use .to_dataframe() to convert to a dataframe, .show_df() to view dataframewith structures, or .show() for 3D visualization
Plot docking results¶
The metrics of all docked poses can be plotted in a scatter plot using:
poses.plot()
Pick top results¶
We can pick the top pose for each SMILES string using:
poses.filter_top_poses()