Skip to content

Instantly share code, notes, and snippets.

@iwatobipen
Created October 10, 2021 13:19
Show Gist options
  • Save iwatobipen/ff7bbd7e188f2dd6b544e67ae384cb46 to your computer and use it in GitHub Desktop.
Save iwatobipen/ff7bbd7e188f2dd6b544e67ae384cb46 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<div class=\"alert alert-block alert-info\">\n",
"<b>How to run this notebook?</b><br />\n",
"<ol>\n",
" <li>Install the DockStream environment: conda env create -f environment.yml in the DockStream directory</li>\n",
" <li>Activate the environment: conda activate DockStreamCommunity</li>\n",
" <li>Execute jupyter: jupyter notebook</li>\n",
" <li> Copy the link to a browser</li>\n",
" <li> Update variables <b>dockstream_path</b> and <b>dockstream_env</b> (the path to the environment DockStream) in the \n",
" first code block below</li>\n",
" </ol>\n",
"</div>\n",
"\n",
"<div class=\"alert alert-block alert-warning\">\n",
" <b>Caution:</b>\n",
" Make sure, you have the AutoDock Vina binary available somewhere.\n",
"</div>\n",
"\n",
"# `AutoDock Vina` backend demo\n",
"This notebook will demonstrate how to **(a)** set up a `AutoDock Vina` backend run with `DockStream`, including the most important settings and **(b)** how to set up a `REINVENT` run with `AutoDock` docking enabled as one of the scoring function components.\n",
"\n",
"**Steps:**\n",
"* a: Set up `DockStream` run\n",
" 1. Prepare the receptor\n",
" 2. Prepare the input: SMILES and configuration file (JSON format)\n",
" 3. Execute the docking and parse the results\n",
"* b: Set up `REINVENT` run with a `DockStream` component\n",
" 1. Prepare the receptor (see *a.1*)\n",
" 2. Prepare the input (see *a.2*)\n",
" 3. Prepare the `REINVENT` configuration (JSON format)\n",
" 4. Execute `REINVENT`\n",
"\n",
"The following imports / loadings are only necessary when executing this notebook. If you want to use `DockStream` directly from the command-line, it is enough to execute the following with the appropriate configurations:\n",
"\n",
"```\n",
"conda activate DockStream\n",
"python /path/to/DockStream/target_preparator.py -conf target_prep.json\n",
"python /path/to/DockStream/docker.py -conf docking.json\n",
"```"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"import json\n",
"import tempfile\n",
"\n",
"# update these paths to reflect your system's configuration\n",
"dockstream_path = os.path.expanduser(\"~/dev/DockStream\")\n",
"dockstream_env = os.path.expanduser(\"~/miniconda3/envs/DockStream\")\n",
"vina_binary_location = os.path.expanduser(\"~/src/autodock_vina_1_1_2_linux_x86/bin\")\n",
"\n",
"# no changes are necessary beyond this point\n",
"# ---------\n",
"# get the notebook's root path\n",
"try: ipynb_path\n",
"except NameError: ipynb_path = os.getcwd()\n",
"\n",
"# generate the paths to the entry points\n",
"target_preparator = dockstream_path + \"/target_preparator.py\"\n",
"docker = dockstream_path + \"/docker.py\"\n",
"\n",
"# generate a folder to store the results\n",
"output_dir = os.path.expanduser(\"~/Desktop/AutoDock_Vina_demo\")\n",
"try:\n",
" os.mkdir(output_dir)\n",
"except FileExistsError:\n",
" pass"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'/home/iwatobipen/dev/DockStreamCommunity/notebooks'"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ipynb_path"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"# generate the paths to the files shipped with this implementation\n",
"apo_1UYD_path = ipynb_path + \"/../data/1UYD/1UYD_apo.pdb\"\n",
"reference_ligand_path = ipynb_path + \"/../data/1UYD/PU8.pdb\"\n",
"smiles_path = ipynb_path + \"/../data/1UYD/ligands_smiles.txt\"\n",
"\n",
"# generate output paths for the configuration file, the \"fixed\" PDB file and the \"Gold\" receptor\n",
"target_prep_path = output_dir + \"/ADV_target_prep.json\"\n",
"fixed_pdb_path = output_dir + \"/ADV_fixed_target.pdb\"\n",
"adv_receptor_path = output_dir + \"/ADV_receptor.pdbqt\"\n",
"log_file_target_prep = output_dir + \"/ADV_target_prep.log\"\n",
"log_file_docking = output_dir + \"/ADV_docking.log\"\n",
"\n",
"# generate output paths for the configuration file, embedded ligands, the docked ligands and the scores\n",
"docking_path = output_dir + \"/ADV_docking.json\"\n",
"ligands_conformers_path = output_dir + \"/ADV_embedded_ligands.sdf\"\n",
"ligands_docked_path = output_dir + \"/ADV_ligands_docked.sdf\"\n",
"ligands_scores_path = output_dir + \"/ADV_scores.csv\""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Target preparation\n",
"`AutoDock Vina` uses the `PDBQT` format for both the receptors and the (individual ligands). First, we will generate the receptor into which we want to dock the molecules. This is a semi-automated process and while `DockStream` has an entry point to help you setting this up, it might be wise to think about the details of this process beforehand, including:\n",
"* Is my target structure complete (e.g. has it missing loops in the area of interest)?\n",
"* Do I have a reference ligand in a complex (holo) structure or do I need to define the binding cleft (cavity) in a different manner?\n",
"* Do I want to keep the crystal water molecules, potential co-factors and such or not?\n",
"\n",
"This step has to be done once per project and target. Typically, we start from a PDB file with a holo-structure, that is, a protein with its ligand. Using a holo-structure as input is convenient for two reasons:\n",
"1. The cavity can be specified as being a certain area around the ligand in the protein (assuming the binding mode does not change too much).\n",
"2. One can align other ligands (often a series with considerable similarity is used in docking studies) to the \"reference ligand\", potentially improving the performance.\n",
"\n",
"![](img/target_preparation_template_method.png)\n",
"\n",
"For this notebook, it is assumed that you are able to\n",
"\n",
"1. download `1UYD` and\n",
"2. split it into `1UYD_apo.pdb` and `reference_ligand.pdb` (name is `PU8` in the file), respectively.\n",
"\n",
"We will now set up the JSON instruction file for the target preparator that will help us build a receptor suitable for `AutoDock Vina` docking later. We will also include a small section (internally using [PDBFixer](https://github.com/openmm/pdbfixer)) that will take care of minor problems of the input structure, such as missing hetero atoms - but of course you can address these things with a program of your choice as well. We will write the JSON to the output folder in order to load it with the `target_preparator.py` entry point of `DockStream`.\n",
"\n",
"Note, that we can use the (optional) `extract_box` block in the configuration to specify the cavity's box (the area where the algorithm will strive to optimize the poses). For this we simply specify a reference ligand and the algorithm will extract the center-of-geometry and the minimum and maximum values for all three axes. This information is printed to the log file and can be used to specify the cavity in the docking step."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"# specify the target preparation JSON file as a dictionary and write it out\n",
"tp_dict = {\n",
" \"target_preparation\":\n",
" {\n",
" \"header\": { # general settings\n",
" \"logging\": { # logging settings (e.g. which file to write to)\n",
" \"logfile\": log_file_target_prep\n",
" }\n",
" },\n",
" \"input_path\": apo_1UYD_path, # this should be an absolute path\n",
" \"fixer\": { # based on \"PDBFixer\"; tries to fix common problems with PDB files\n",
" \"enabled\": True,\n",
" \"standardize\": True, # enables standardization of residues\n",
" \"remove_heterogens\": True, # remove hetero-entries\n",
" \"fix_missing_heavy_atoms\": True, # if possible, fix missing heavy atoms\n",
" \"fix_missing_hydrogens\": True, # add hydrogens, which are usually not present in PDB files\n",
" \"fix_missing_loops\": False, # add missing loops; CAUTION: the result is usually not sufficient\n",
" \"add_water_box\": False, # if you want to put the receptor into a box of water molecules\n",
" \"fixed_pdb_path\": fixed_pdb_path # if specified and not \"None\", the fixed PDB file will be stored here\n",
" },\n",
" \"runs\": [ # \"runs\" holds a list of backend runs; at least one is required\n",
" {\n",
" \"backend\": \"AutoDockVina\", # one of the backends supported (\"AutoDockVina\", \"OpenEye\", ...)\n",
" \"output\": {\n",
" \"receptor_path\": adv_receptor_path # the generated receptor file will be saved to this location\n",
" },\n",
" \"parameters\": {\n",
" \"pH\": 7.4, # sets the protonation states (NOT used in Vina)\n",
" \"extract_box\": { # in order to extract the coordinates of the pocket (see text)\n",
" \"reference_ligand_path\": reference_ligand_path, # path to the reference ligand\n",
" \"reference_ligand_format\": \"PDB\" # format of the reference ligand\n",
" }\n",
"}}]}}\n",
"\n",
"with open(target_prep_path, 'w') as f:\n",
" json.dump(tp_dict, f, indent=\" \")"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"REMARK Name = /tmp/tmp9ypjaoif.pdb\r\n",
"REMARK x y z vdW Elec q Type\r\n",
"REMARK _______ _______ _______ _____ _____ ______ ____\r\n",
"ATOM 1 N GLU A 1 6.484 28.442 39.441 0.00 0.00 +0.386 N \r\n",
"ATOM 2 CA GLU A 1 7.718 28.546 38.611 0.00 0.00 -0.005 C \r\n",
"ATOM 3 C GLU A 1 7.625 27.706 37.277 0.00 0.00 +0.199 C \r\n",
"ATOM 4 O GLU A 1 7.333 26.478 37.304 0.00 0.00 -0.278 OA\r\n",
"ATOM 5 CB GLU A 1 8.951 28.140 39.474 0.00 0.00 -0.048 C \r\n",
"ATOM 6 CG GLU A 1 9.355 26.647 39.367 0.00 0.00 +0.048 C \r\n",
"ATOM 7 CD GLU A 1 10.138 26.088 40.562 0.00 0.00 +0.356 C \r\n",
"ATOM 8 OE1 GLU A 1 11.022 26.816 41.117 0.00 0.00 -0.246 OA\r\n",
"ATOM 9 OE2 GLU A 1 9.875 24.900 40.943 0.00 0.00 -0.246 OA\r\n",
"ATOM 10 N VAL A 2 7.856 28.355 36.137 0.00 0.00 -0.305 N \r\n",
"ATOM 11 CA VAL A 2 8.110 27.634 34.889 0.00 0.00 +0.102 C \r\n",
"ATOM 12 C VAL A 2 9.523 27.050 34.954 0.00 0.00 +0.234 C \r\n",
"ATOM 13 O VAL A 2 10.499 27.794 35.209 0.00 0.00 -0.274 OA\r\n",
"ATOM 14 CB VAL A 2 7.967 28.556 33.636 0.00 0.00 -0.020 C \r\n",
"ATOM 15 CG1 VAL A 2 8.234 27.763 32.310 0.00 0.00 -0.061 C \r\n",
"ATOM 16 CG2 VAL A 2 6.598 29.245 33.609 0.00 0.00 -0.061 C \r\n",
"ATOM 17 N GLU A 3 9.626 25.731 34.766 0.00 0.00 -0.302 N \r\n",
"ATOM 18 CA GLU A 3 10.912 25.034 34.705 0.00 0.00 +0.100 C \r\n",
"ATOM 19 C GLU A 3 11.363 24.695 33.258 0.00 0.00 +0.234 C \r\n",
"ATOM 20 O GLU A 3 10.557 24.225 32.446 0.00 0.00 -0.274 OA\r\n",
"ATOM 21 CB GLU A 3 10.872 23.762 35.555 0.00 0.00 -0.016 C \r\n",
"ATOM 22 CG GLU A 3 10.774 24.017 37.048 0.00 0.00 +0.051 C \r\n"
]
}
],
"source": [
"# execute this in a command-line environment after replacing the parameters\n",
"!{dockstream_env}/bin/python {target_preparator} -conf {target_prep_path}\n",
"!head -n 25 {adv_receptor_path}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This is it, now we have **(a)** fixed some minor issues with the input structure and **(b)** generated a reference ligand-based receptor and stored it in a binary file. For inspection later, we will write out the \"fixed\" PDB structure (parameter `fixed_pdb_path` in the `fixer` block above)."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Docking\n",
"In this section we consider a case where we have just prepared the receptor and want to dock a bunch of ligands (molecules, compounds) into the binding cleft. Often, we only have the structure of the molecules in the form of `SMILES`, rather than a 3D structure so the first step will be to generate these conformers before proceeding. In `DockStream` you can embed your ligands with a variety of programs including `Corina`, `RDKit`, `OMEGA` and `LigPrep` and use them freely with any backend. Here, we will use `Corina` for the conformer embedding.\n",
"\n",
"But first, we will have a look at the ligands:"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"['C#CCCCn1c(Cc2cc(OC)c(OC)c(OC)c2Cl)nc2c(N)ncnc21', 'CCCCn1c(Cc2cc(OC)c(OC)c(OC)c2)nc2c(N)ncnc21', 'CCCCn1c(Cc2cc(OC)ccc2OC)nc2c(N)ncnc21', 'CCCCn1c(Cc2cccc(OC)c2)nc2c(N)ncnc21', 'C#CCCCn1c(Cc2cc(OC)c(OC)c(OC)c2Cl)nc2c(N)nc(F)nc21', 'CCCCn1c(Cc2ccc(OC)cc2)nc2c(N)ncnc21', 'CCCCn1c(Cc2ccc3c(c2)OCO3)nc2c(N)ncnc21', 'CCCCn1c(Cc2cc(OC)ccc2OC)nc2c(N)nc(F)nc21', 'CCCCn1c(Cc2ccc3c(c2)OCO3)nc2c(N)nc(F)nc21', 'C#CCCCn1c(Cc2cc(OC)ccc2OC)nc2c(N)nc(F)nc21', 'CC(C)NCCCn1c(Cc2cc3c(cc2I)OCO3)nc2c(N)nc(F)nc21', 'CC(C)NCCCn1c(Sc2cc3c(cc2Br)OCO3)nc2c(N)ncnc21', 'CC(C)NCCCn1c(Sc2cc3c(cc2I)OCO3)nc2c(N)ncnc21', 'COc1ccc(OC)c(Cc2nc3nc(F)nc(N)c3[nH]2)c1', 'Nc1nccn2c(NCc3ccccc3)c(Cc3cc4c(cc3Br)OCO4)nc12']\n"
]
}
],
"source": [
"# load the smiles (just for illustrative purposes)\n",
"# here, 15 moleucles will be used\n",
"with open(smiles_path, 'r') as f:\n",
" smiles = [smile.strip() for smile in f.readlines()]\n",
"print(smiles)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"While the embedding and docking tasks in `DockStream` are both specified in the same configuration file, they are handled independently. This means it is perfectly fine to either load conformers (from an `SDF` file) directly or to use a call of `docker.py` merely to generate conformers without doing the docking afterwards.\n",
"\n",
"`DockStream` uses the notion of (embedding) \"pool\"s, of which multiple can be specified and accessed via identifiers. Note, that while the way conformers are generated is highly backend specific, `DockStream` allows you to use the results interchangably. This allows to (a) re-use embedded molecules for multiple docking runs (e.g. different scoring functions), without the necessity to embed them more than once and (b) to combine embeddings and docking backends freely.\n",
"\n",
"One important feature is that you can also specify an `align` block for the pools, which will try to align the conformers produced to the reference ligand's coordinates. Alignment is especially useful if your molecules have a large common sub-structure, as it will potentially enhance the results. **Warning:** At the moment, this feature is a bit unstable at times (potentially crashes, if no overlap of a ligand with the reference ligand can be found).\n",
"\n",
"As mentioned at the target preparation stage, we need to specify the cavity (binding cleft) or search space for `AutoDock Vina`. As we have extracted the \"box\" (see print-out of the logging file below) using a reference ligand, this helps us deciding on the dimensions of the search space:"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"2021-09-28 21:40:00 - DockStream version used: 1.0.0\r\n",
"2021-09-28 21:40:00 - Warning: importing 'simtk.openmm' is deprecated. Import 'openmm' instead.\r\n",
"2021-09-28 21:40:02 - Started preparation run number 0.\r\n",
"2021-09-28 21:40:02 - Ligand from file /home/iwatobipen/dev/DockStreamCommunity/notebooks/../data/1UYD/PU8.pdb has the following dimensions:\r\n",
"X coordinates: min=-2.44, max=8.12, mean=3.19\r\n",
"Y coordinates: min=7.27, max=15.53, mean=11.48\r\n",
"Z coordinates: min=23.0, max=26.95, mean=24.76\r\n",
"2021-09-28 21:40:02 - Wrote AutoDock Vina target to file /home/iwatobipen/Desktop/AutoDock_Vina_demo/ADV_receptor.pdbqt.\r\n",
"2021-09-28 21:40:02 - Completed target preparation run number 0.\r\n"
]
}
],
"source": [
"!cat {log_file_target_prep}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The three `mean` values will serve as the center of the search space and from the minimum and maximum values in all three dimensions, we decide to use 15 (for `x`) and 10 (for `y` and `z`, respectively). As larger ligands could be used, we will give the algorithm some leeway in each dimension."
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"/home/iwatobipen/Desktop/AutoDock_Vina_demo/ADV_docking.json\n"
]
}
],
"source": [
"# specify the embedding and docking JSON file as a dictionary and write it out\n",
"ed_dict = {\n",
" \"docking\": {\n",
" \"header\": { # general settings\n",
" \"logging\": { # logging settings (e.g. which file to write to)\n",
" \"logfile\": log_file_docking\n",
" }\n",
" },\n",
" \"ligand_preparation\": { # the ligand preparation part, defines how to build the pool\n",
" \"embedding_pools\": [\n",
" {\n",
" \"pool_id\": \"RDkit\", # here, we only have one pool\n",
" \"type\": \"RDkit\",\n",
" \"parameters\": {\n",
" \"prefix_execution\": \"\" # only required, if a module needs to be loaded to execute \"Corina\"\n",
" },\n",
" \"input\": {\n",
" \"standardize_smiles\": False,\n",
" \"type\": \"smi\",\n",
" \"input_path\": smiles_path\n",
" },\n",
" \"output\": { # the conformers can be written to a file, but \"output\" is\n",
" # not required as the ligands are forwarded internally\n",
" \"conformer_path\": ligands_conformers_path, \n",
" \"format\": \"sdf\"\n",
" }\n",
" }\n",
" ]\n",
" },\n",
" \"docking_runs\": [\n",
" {\n",
" \"backend\": \"AutoDockVina\",\n",
" \"run_id\": \"AutoDockVina\",\n",
" \"input_pools\": [\"RDkit\"],\n",
" \"parameters\": {\n",
" \"binary_location\": vina_binary_location, # absolute path to the folder, where the \"vina\" binary\n",
" # can be found\n",
" \"parallelization\": {\n",
" \"number_cores\": 4\n",
" },\n",
" \"seed\": 42, # use this \"seed\" to generate reproducible results; if\n",
" # varied, slightly different results will be produced\n",
" \"receptor_pdbqt_path\": [adv_receptor_path], # paths to the receptor files\n",
" \"number_poses\": 2, # number of poses to be generated\n",
" \"search_space\": { # search space (cavity definition); see text\n",
" \"--center_x\": 3.3,\n",
" \"--center_y\": 11.5,\n",
" \"--center_z\": 24.8,\n",
" \"--size_x\": 15,\n",
" \"--size_y\": 10,\n",
" \"--size_z\": 10\n",
" }\n",
" },\n",
" \"output\": {\n",
" \"poses\": { \"poses_path\": ligands_docked_path },\n",
" \"scores\": { \"scores_path\": ligands_scores_path }\n",
"}}]}}\n",
"\n",
"with open(docking_path, 'w') as f:\n",
" json.dump(ed_dict, f, indent=2)\n",
"\n",
"# print out path to generated JSON\n",
"print(docking_path)"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[21:40:05] Molecule does not have explicit Hs. Consider calling AddHs()\n",
"[21:40:05] Molecule does not have explicit Hs. Consider calling AddHs()\n",
"[21:40:05] Molecule does not have explicit Hs. Consider calling AddHs()\n",
"[21:40:05] Molecule does not have explicit Hs. Consider calling AddHs()\n",
"[21:40:05] Molecule does not have explicit Hs. Consider calling AddHs()\n",
"[21:40:05] Molecule does not have explicit Hs. Consider calling AddHs()\n",
"[21:40:05] Molecule does not have explicit Hs. Consider calling AddHs()\n",
"[21:40:05] Molecule does not have explicit Hs. Consider calling AddHs()\n",
"[21:40:05] Molecule does not have explicit Hs. Consider calling AddHs()\n",
"[21:40:05] Molecule does not have explicit Hs. Consider calling AddHs()\n",
"[21:40:05] Molecule does not have explicit Hs. Consider calling AddHs()\n",
"[21:40:05] Molecule does not have explicit Hs. Consider calling AddHs()\n",
"[21:40:05] Molecule does not have explicit Hs. Consider calling AddHs()\n",
"[21:40:05] Molecule does not have explicit Hs. Consider calling AddHs()\n",
"[21:40:05] Molecule does not have explicit Hs. Consider calling AddHs()\n",
"[21:40:05] Molecule does not have explicit Hs. Consider calling AddHs()\n",
"[21:40:05] Molecule does not have explicit Hs. Consider calling AddHs()\n",
"[21:40:05] Molecule does not have explicit Hs. Consider calling AddHs()\n",
"[21:40:05] Molecule does not have explicit Hs. Consider calling AddHs()\n",
"[21:40:05] Molecule does not have explicit Hs. Consider calling AddHs()\n",
"[21:40:05] Molecule does not have explicit Hs. Consider calling AddHs()\n",
"[21:40:05] Molecule does not have explicit Hs. Consider calling AddHs()\n",
"[21:40:05] Molecule does not have explicit Hs. Consider calling AddHs()\n",
"[21:40:05] Molecule does not have explicit Hs. Consider calling AddHs()\n",
"[21:40:05] Molecule does not have explicit Hs. Consider calling AddHs()\n",
"[21:40:05] Molecule does not have explicit Hs. Consider calling AddHs()\n",
"[21:40:05] Molecule does not have explicit Hs. Consider calling AddHs()\n",
"[21:40:05] Molecule does not have explicit Hs. Consider calling AddHs()\n",
"[21:40:05] Molecule does not have explicit Hs. Consider calling AddHs()\n",
"[21:40:05] Molecule does not have explicit Hs. Consider calling AddHs()\n",
"-9.2\n",
"-9.0\n",
"-9.1\n",
"-9.2\n",
"-9.4\n",
"-9.0\n",
"-9.8\n",
"-9.4\n",
"-10.1\n",
"-9.3\n",
"-9.3\n",
"-9.2\n",
"-9.1\n",
"-9.5\n",
"-8.9\n"
]
}
],
"source": [
"# execute this in a command-line environment after replacing the parameters\n",
"!{dockstream_env}/bin/python {docker} -conf {docking_path} -print_scores"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Note, that the scores are usually only outputted to a `CSV` file specified by the `scores` block, but that since we have used parameter `-print_scores` they will also be printed to `stdout` (line-by-line).\n",
"\n",
"These scores are associated with docking poses (see picture below for a couple of ligands overlaid in the binding pocket).\n",
"\n",
"![](img/docked_ligands_overlay_holo.png)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Using `DockStream` as a scoring component in `REINVENT`\n",
"The *de novo* design platform `REINVENT` holds a recently added `DockStream` scoring function component (also check out our collection of notebooks in the [ReinventCommunity](https://github.com/MolecularAI/ReinventCommunity) repository). This means, provided that all necessary input files and configurations are available, you may run `REINVENT` and incorporate docking scores into the score of the compounds generated. Together with `FastROCS`, this represents the first step to integrate physico-chemical 3D information.\n",
"\n",
"While the docking scores are a very crude proxy for the actual binding affinity (at best), it does prove useful as a *geometric filter* (removing ligands that obviously do not fit the binding cavity). Furthermore, a severe limitation of knowledge-based predictions e.g. in activity models is the domain applicability. Docking, as a chemical space agnostic component, can enhance the ability of the agent for scaffold-hopping, i.e. to explore novel sub-areas in the chemical space.\n",
"\n",
"### The `REINVENT` configuration JSON\n",
"\n",
"While every docking backend has its own configuration (see section above), calling `DockStream`'s `docker.py` entry point ensures that they all follow the same external API. Thus the component that needs to be added to `REINVENT`'s JSON configuration (to the `scoring_function`->`parameters` list) looks as follows for `AutoDock Vina`:\n",
"\n",
"```\n",
"{\n",
" \"component_type\": \"dockstream\",\n",
" \"name\": \"dockstream\",\n",
" \"weight\": 1,\n",
" \"model_path\": \"\",\n",
" \"smiles\": [],\n",
" \"specific_parameters\": {\n",
" \"transformation\": true,\n",
" \"transformation_type\": \"reverse_sigmoid\",\n",
" \"low\": -12,\n",
" \"high\": -8,\n",
" \"k\": 0.25,\n",
" \"configuration_path\": \"<absolute_path_to_DockStream_configuration>/docking.json\",\n",
" \"docker_script_path\": \"<absolute_path_to_DockStream_source>/docker.py\",\n",
" \"environment_path\": \"<absolute_path_to_miniconda_installation>/miniconda3/envs/DockStream/bin/python\"\n",
" }\n",
"}\n",
"```\n",
"\n",
"You will need to update `configuration_path`, `docker_script_path` and the link to the environment, `environment_path` to match your system's configuration. It might be, that the latter two are already set to meaningful defaults, but your `DockStream` configuration JSON file will be specific for each run. \n",
"\n",
"#### How to find an appropriate transformation?\n",
"We use a *reverse sigmoid* score transformation to bring the numeric, continuous value that was outputted by `DockStream` and fed back to `REINVENT` into a 0 to 1 regime. The parameters `low`, `high` and `k` are critical: their exact value naturally depends on the backend used, but also on the scoring function (make sure, \"more negative is better\" - otherwise you are looking for a *sigmoid* transformation) and potentially also the project used. The values reported here can be used as rule-of-thumb for an `AutoDock Vina` run. Below is a code snippet, that helps to find the appropriate parameters (excerpt of the `ReinventCommunity` notebook `Score_Transformations`)."
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"# load the dependencies and classes used\n",
"%run code/score_transformation.py\n",
"\n",
"# set plotting parameters\n",
"small = 12\n",
"med = 16\n",
"large = 22\n",
"params = {\"axes.titlesize\": large,\n",
" \"legend.fontsize\": med,\n",
" \"figure.figsize\": (16, 10),\n",
" \"axes.labelsize\": med,\n",
" \"axes.titlesize\": med,\n",
" \"xtick.labelsize\": med,\n",
" \"ytick.labelsize\": med,\n",
" \"figure.titlesize\": large}\n",
"plt.rcParams.update(params)\n",
"plt.style.use(\"seaborn-whitegrid\")\n",
"sns.set_style(\"white\")\n",
"%matplotlib inline\n",
"\n",
"# set up Enums and factory\n",
"tt_enum = TransformationTypeEnum()\n",
"csp_enum = ComponentSpecificParametersEnum()\n",
"factory = TransformationFactory()"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 1280x800 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"# sigmoid transformation\n",
"# ---------\n",
"values_list = np.arange(-14, -7, 0.25).tolist()\n",
"specific_parameters = {csp_enum.TRANSFORMATION: True,\n",
" csp_enum.LOW: -12,\n",
" csp_enum.HIGH: -8,\n",
" csp_enum.K: 0.25,\n",
" csp_enum.TRANSFORMATION_TYPE: tt_enum.REVERSE_SIGMOID}\n",
"transform_function = factory.get_transformation_function(specific_parameters)\n",
"transformed_scores = transform_function(predictions=values_list,\n",
" parameters=specific_parameters)\n",
"\n",
"# render the curve\n",
"render_curve(title=\" Reverse Sigmoid Transformation\", x=values_list, y=transformed_scores)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### How to specify the `DockStream` configuration file?\n",
"In principle, all options that are supported in a \"normal\" `DockStream` run (see above) are supported for usage with `REINVENT` as well, with a few notable exceptions. First, as we report only one value per ligand (and a \"consensus score\" is not yet supported), you should only use **one** embedding / pool and **one** backend (as in the example above). Second, the prospective ligands are not supplied via a file but from `stdin`, thus we will need to change the `input` part of the pool definition. Also, we might not want to write-out all conformers, so we will remove the `output` block entirely. The updated section then looks as follows:\n",
"\n",
"```\n",
"{\n",
" \"pool_id\": \"Corina_pool\",\n",
" \"type\": \"Corina\",\n",
" \"parameters\": {\n",
" \"removeHs\": False\n",
" },\n",
" \"input\": {\n",
" \"standardize_smiles\": False\n",
" }\n",
"}\n",
"```\n",
"\n",
"Finally, we will update the docking run as well. Typically, we want to see the docked poses per epoch and maybe also the scores and the SMILES in a well-tabulated format. Thus, we might retain the `output` block here, but as every epoch generates each of the files, it would overwrite it by default. If parameter `overwrite` is set to `False`, each consecutive write-out will be appended by a number, e.g. first epoch *poses.sdf* and *scores.csv*, second epoch *0001_poses.sdf* and *0001_scores.csv*, third epoch *0002_poses.sdf* and *0002_scores.csv* and so on.\n",
"\n",
"```\n",
"{\n",
" \"backend\": \"AutoDockVina\",\n",
" \"run_id\": \"AutoDockVina\",\n",
" \"input_pools\": [\"Corina_pool\"],\n",
" ...\n",
" \"output\": {\n",
" \"poses\": { \"poses_path\": ligands_docked_path, \"overwrite\": False },\n",
" \"scores\": { \"scores_path\": ligands_scores_path, \"overwrite\": False }\n",
" }\n",
"}\n",
"```"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.10"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment