In [1]:
from dotenv import load_dotenv
load_dotenv()
Out[1]:
True
In [2]:
%load_ext autoreload
%autoreload 2

Docking a single ligand¶

This notebook shows you how to dock a single ligand to a protein.

Setup¶

First, we'll import the necessary Deep Origin drug discovery modules.

In [3]:
from deeporigin.drug_discovery import (
    BRD_DATA_DIR,
    Pocket,
    Protein,
    Protonation,
    Docking,
    Ligand,
    LigandSet,
)

from deeporigin.platform import DeepOriginClient

You don't have to explictitly initialize a client, but you can if you want:

In [4]:
client = DeepOriginClient()
client
/home/runner/work/do-dd-client/do-dd-client/.venv/lib/python3.11/site-packages/jwt/api_jwt.py:147: InsecureKeyLengthWarning: The HMAC key is 6 bytes long, which is below the minimum recommended length of 32 bytes for SHA256. See RFC 7518 Section 3.2.
  return self._jws.encode(
Out[4]:
DeepOrigin Platform Client for Local User (org_key=deeporigin, base_url=http://127.0.0.1:4931/)

Load protein and register on the platform¶

We use the the same BRD protein as in our other notebooks, and use the sync method to upload the PDB file and register it with the data platform:

In [5]:
protein = Protein.from_file(BRD_DATA_DIR / "brd.pdb")
protein.remove_water()
protein.sync()
protein.id
Out[5]:
'brd'

Load ligand¶

We load a ligand from a SDF file on disk. You can also import a ligand from a SMILES string, etc. Once again, we use the sync method to upload the file (if any) and register with the data platform.

In [6]:
ligand = Ligand.from_sdf(BRD_DATA_DIR/"brd-2.sdf")
ligand.sync()
ligand
<rdkit.Chem.rdchem.Mol object at 0x7fe6c769c6d0>
Out[6]:
In [7]:
ligand.id
Out[7]:
'brd-2'

Protonate Ligand¶

We use the protonation tool to protonate the ligand and use the most probable species at that pH to dock. Note that the Protonator tool can modify our ligand.

In [8]:
protonator = Protonation(ligand=ligand)
protonator.run()
Out[8]:

LigandSet with 1 ligand

SMILES: CN(C)C(=O)c1cccc(-c2cn(C)c(=O)c3[nH]ccc23)c1 PROTONATED (pH=7.4) 2D

Properties: initial_smiles, r_exp_dg

Use .to_dataframe() to convert to a dataframe, .show_df() to view dataframewith structures, or .show() for 3D visualization, .prepare() to prepare ligands for docking

Work with a pocket¶

Here, we will use a previously identified novel pocket using the PocketFinder tool.

In [9]:
pockets = Pocket.from_result(protein_id=protein.id)
pocket = pockets[0]
pocket
Out[9]:
Pocket:
╭─────────────────────────┬──────────────────────────────────────╮
│ Name                    │ pocket_1                             │
├─────────────────────────┼──────────────────────────────────────┤
│ ID                      │ c002d6b3-0d66-4265-91db-8bec0392751d │
├─────────────────────────┼──────────────────────────────────────┤
│ Protein ID              │ brd                                  │
├─────────────────────────┼──────────────────────────────────────┤
│ Color                   │ red                                  │
├─────────────────────────┼──────────────────────────────────────┤
│ Center                  │ (-13.52, -4.94, 15.46)               │
├─────────────────────────┼──────────────────────────────────────┤
│ Box size                │ 14.00 × 14.00 × 19.00 Å              │
├─────────────────────────┼──────────────────────────────────────┤
│ Volume                  │ 300 ų                               │
├─────────────────────────┼──────────────────────────────────────┤
│ Total SASA              │ 1225.8883 Ų                         │
├─────────────────────────┼──────────────────────────────────────┤
│ Polar SASA              │ 309.8629 Ų                          │
├─────────────────────────┼──────────────────────────────────────┤
│ Polar/Apolar SASA ratio │ 0.3382689                            │
├─────────────────────────┼──────────────────────────────────────┤
│ Hydrophobicity          │ 29.92                                │
├─────────────────────────┼──────────────────────────────────────┤
│ Polarity                │ 10                                   │
├─────────────────────────┼──────────────────────────────────────┤
│ Drugability score       │ 0.94304204                           │
├─────────────────────────┼──────────────────────────────────────┤
│ Pocket count            │ 1                                    │
├─────────────────────────┼──────────────────────────────────────┤
│ Pocket min size         │ 30 ų                                │
╰─────────────────────────┴──────────────────────────────────────╯

Show pocket¶

Here, we view the pocket in the protein:

In [10]:
protein.show(pockets=[pocket])

Show docking box¶

We can also view the docking box that is constructed from this pokcet:

In [11]:
docking = Docking(protein=protein, pocket=pockets[0], ligand=ligand)
docking.show_box()

Estimate cost¶

Before running any tool, we can estimate the cost by passing quote=True as follows:

In [12]:
docking.run(quote=True)
docking.estimate
Out[12]:
0.2

Dock ligand¶

We can now run the docking tool. Because we're docking a single ligand, we get back poses immediately. Docking.run (like all run methods) is a blocking synchronouse operation.

In [13]:
poses = docking.run()

We can view all poses in a dataframe:

In [14]:
poses.to_dataframe()
Out[14]:
id SMILES best_pose binding_energy box_size_x box_size_y box_size_z pocket_center pocket_id pose_score protein_id
0 brd-2 CN(C)C(=O)c1cccc(-c2cn(C)c(=O)c3[nH]ccc23)c1 True -8.015328 20 20 20 [-13.146394729614258, -5.712231636047363, 14.7... pocket-test-id 0.904670 brd
1 brd-2 CN(C)C(=O)c1cccc(-c2cn(C)c(=O)c3[nH]ccc23)c1 False -8.961081 20 20 20 [-13.146394729614258, -5.712231636047363, 14.7... pocket-test-id 0.898408 brd
2 brd-2 CN(C)C(=O)c1cccc(-c2cn(C)c(=O)c3[nH]ccc23)c1 False -7.692511 20 20 20 [-13.146394729614258, -5.712231636047363, 14.7... pocket-test-id 0.852781 brd
3 brd-2 CN(C)C(=O)c1cccc(-c2cn(C)c(=O)c3[nH]ccc23)c1 False -9.012382 20 20 20 [-13.146394729614258, -5.712231636047363, 14.7... pocket-test-id 0.807688 brd
4 brd-2 CN(C)C(=O)c1cccc(-c2cn(C)c(=O)c3[nH]ccc23)c1 False -7.441937 20 20 20 [-13.146394729614258, -5.712231636047363, 14.7... pocket-test-id 0.796831 brd
5 brd-2 CN(C)C(=O)c1cccc(-c2cn(C)c(=O)c3[nH]ccc23)c1 False -8.609729 20 20 20 [-13.146394729614258, -5.712231636047363, 14.7... pocket-test-id 0.757949 brd
6 brd-2 CN(C)C(=O)c1cccc(-c2cn(C)c(=O)c3[nH]ccc23)c1 False -8.411566 20 20 20 [-13.146394729614258, -5.712231636047363, 14.7... pocket-test-id 0.709940 brd
7 brd-2 CN(C)C(=O)c1cccc(-c2cn(C)c(=O)c3[nH]ccc23)c1 False -7.697807 20 20 20 [-13.146394729614258, -5.712231636047363, 14.7... pocket-test-id 0.624421 brd
8 brd-2 CN(C)C(=O)c1cccc(-c2cn(C)c(=O)c3[nH]ccc23)c1 False -7.191995 20 20 20 [-13.146394729614258, -5.712231636047363, 14.7... pocket-test-id 0.594424 brd
9 brd-2 CN(C)C(=O)c1cccc(-c2cn(C)c(=O)c3[nH]ccc23)c1 False -6.837277 20 20 20 [-13.146394729614258, -5.712231636047363, 14.7... pocket-test-id 0.585849 brd
10 brd-2 CN(C)C(=O)c1cccc(-c2cn(C)c(=O)c3[nH]ccc23)c1 False -6.739297 20 20 20 [-13.146394729614258, -5.712231636047363, 14.7... pocket-test-id 0.573230 brd
11 brd-2 CN(C)C(=O)c1cccc(-c2cn(C)c(=O)c3[nH]ccc23)c1 False -8.172841 20 20 20 [-13.146394729614258, -5.712231636047363, 14.7... pocket-test-id 0.544384 brd
12 brd-2 CN(C)C(=O)c1cccc(-c2cn(C)c(=O)c3[nH]ccc23)c1 False -7.280019 20 20 20 [-13.146394729614258, -5.712231636047363, 14.7... pocket-test-id 0.537316 brd
13 brd-2 CN(C)C(=O)c1cccc(-c2cn(C)c(=O)c3[nH]ccc23)c1 False -8.083034 20 20 20 [-13.146394729614258, -5.712231636047363, 14.7... pocket-test-id 0.535973 brd
14 brd-2 CN(C)C(=O)c1cccc(-c2cn(C)c(=O)c3[nH]ccc23)c1 False -7.644990 20 20 20 [-13.146394729614258, -5.712231636047363, 14.7... pocket-test-id 0.534965 brd
15 brd-2 CN(C)C(=O)c1cccc(-c2cn(C)c(=O)c3[nH]ccc23)c1 False -8.500072 20 20 20 [-13.146394729614258, -5.712231636047363, 14.7... pocket-test-id 0.513628 brd

Show poses¶

To visualize the poses, we download them and show them in the protein:

In [15]:
poses.download()
protein.show(poses=poses)
Downloading files:   0%|          | 0/16 [00:00<?, ?file/s]
Downloading files: 100%|██████████| 16/16 [00:00<00:00, 187.10file/s]

In [ ]:
 
In [ ]: