Skip to content

Commit

Permalink
Add cookbook entry for user charges
Browse files Browse the repository at this point in the history
  • Loading branch information
IAlibay committed Dec 4, 2023
1 parent 049759b commit 72fc69f
Showing 1 changed file with 394 additions and 0 deletions.
394 changes: 394 additions & 0 deletions cookbook/user_charges.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,394 @@
{
"cells": [
{
"cell_type": "raw",
"id": "4d9beae7-b6bd-4743-9614-42450df0697d",
"metadata": {
"editable": true,
"raw_mimetype": "text/restructuredtext",
"slideshow": {
"slide_type": ""
},
"tags": []
},
"source": [
".. _User Charges:\n",
"\n",
"Assining partial Charges to Small Molecule Components\n",
"====================================================="
]
},
{
"cell_type": "markdown",
"id": "088a1bc4-e5f3-47ac-8ebf-1a904fa82f80",
"metadata": {
"editable": true,
"nbsphinx": "hidden",
"slideshow": {
"slide_type": ""
},
"tags": []
},
"source": [
"# Assigning partial charges to Small Molecule Components"
]
},
{
"cell_type": "raw",
"id": "acb1ed05-1874-4dd3-a41d-e18623bece44",
"metadata": {
"editable": true,
"raw_mimetype": "text/restructuredtext",
"slideshow": {
"slide_type": ""
},
"tags": []
},
"source": [
"On partial charge assignment\n",
"----------------------------"
]
},
{
"cell_type": "markdown",
"id": "00d9ca69-1b38-4cf8-9c93-1fc4c08dae15",
"metadata": {
"editable": true,
"nbsphinx": "hidden",
"slideshow": {
"slide_type": ""
},
"tags": []
},
"source": [
"## On partial charge assignment"
]
},
{
"cell_type": "markdown",
"id": "8bc61b88-0c8d-4b89-b704-8ac4ade19c6c",
"metadata": {
"editable": true,
"raw_mimetype": "",
"slideshow": {
"slide_type": ""
},
"tags": []
},
"source": [
"Components are usually by default loaded into OpenFE without pre-existing partial charges. This is particularly true when loading from [SDF and PDB files](?how do I reference another section?).\n",
"\n",
"In those cases, partial charges will be assigned within the selected Protocol. As of writing, for `SmallMoleculeComponent`s this is done using [antechamber's](https://ambermd.org/antechamber/ac.html) `am1bcc` charge assignment, using the input conformer as the pre-optimized input for `sqm`'s AM1 calculation. For `ProteinComponent`s and `SolventComponent`s this is done by assigning charges from the chosen protein and solvent force fields.\n",
"\n",
"Unfortunately charge assignment can be both, a) time consuming for large molecules, and b) non-deterministic, especially when the molecule occupies a conformation far from a local minima in the AM1 energetic landscape. The latter can be particularly problematic as this can lead to significant differences in assigned partial charges between Protocol simulation repeats.\n",
"\n",
"To avoid these issues, we recommend applying `user charges` to `SmallMoleculeComponents`. In its simplest form, this is done by converting the `SmallMoleculeComponent` to an `OpenFF Molecule` calling the [OpenFF Molecule's `assign_partial_charges method`](https://docs.openforcefield.org/projects/toolkit/en/0.9.2/api/generated/openff.toolkit.topology.Molecule.html#openff.toolkit.topology.Molecule.assign_partial_charges) and then re-loading it back into a `SmallMoleculeComponent` before further manipulation."
]
},
{
"cell_type": "raw",
"id": "d7277536-be61-4d45-b09f-1a7b355bee82",
"metadata": {
"editable": true,
"raw_mimetype": "text/restructuredtext",
"slideshow": {
"slide_type": ""
},
"tags": []
},
"source": [
".. _Loading small molecules and converting them to OpenFF Molecules:\n",
"\n",
"Loading small molecules and converting them to OpenFF Molecules\n",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
]
},
{
"cell_type": "markdown",
"id": "d2658885-8ad9-4142-b163-17c8aa576b00",
"metadata": {
"editable": true,
"nbsphinx": "hidden",
"slideshow": {
"slide_type": ""
},
"tags": []
},
"source": [
"### Loading small molecules from an SDF, and converting them to OpenFF Molecules"
]
},
{
"cell_type": "markdown",
"id": "15115699-8bdb-4261-9afd-18ebd55bd06a",
"metadata": {
"editable": true,
"slideshow": {
"slide_type": ""
},
"tags": []
},
"source": [
"Here we demonstrate how to first load a set of small molecules from an SDF and converting them to OpenFF Molecules"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "1436cd71-2a65-4cef-9f9f-73013c791a17",
"metadata": {
"editable": true,
"raw_mimetype": "text/restructuredtext",
"slideshow": {
"slide_type": ""
},
"tags": []
},
"outputs": [],
"source": [
"from rdkit import Chem\n",
"from openff.toolkit import Molecule\n",
"\n",
"off_molecules = [\n",
" Molecule.from_rdkit(mol)\n",
" for mol in Chem.SDMolSupplier(\n",
" \"assets/somebenzenes.sdf\",\n",
" removeHs=False,\n",
" )\n",
"]"
]
},
{
"cell_type": "markdown",
"id": "8c78efe2-5a0d-4aac-afd1-3e6c5b7a1efc",
"metadata": {
"editable": true,
"slideshow": {
"slide_type": ""
},
"tags": []
},
"source": [
"<div class=\"alert alert-warning\">\n",
" Remember to include the <code>removeHs=False</code> keyword argument so that RDKit does not strip your hydrogens!\n",
"</div>"
]
},
{
"cell_type": "raw",
"id": "4b70d3b8-0e89-4165-ac01-4eef5f4fe311",
"metadata": {},
"source": [
".. _Assigning partial charges to an OpenFF Molecule:\n",
"\n",
"Assigning partial charges to an OpenFF Molecule\n",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
]
},
{
"cell_type": "markdown",
"id": "b092b780-a2cb-4ece-9d77-c09f2e035b8f",
"metadata": {
"editable": true,
"raw_mimetype": "text/restructuredtext",
"slideshow": {
"slide_type": ""
},
"tags": []
},
"source": [
"Next we assign partial charges to the OpenFF Molecule using the `am1bcc` method and the conformation taken from the input SDF file."
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "7f7e56c9-2bee-46a1-9ccf-7003b4886249",
"metadata": {
"editable": true,
"raw_mimetype": "text/restructuredtext",
"slideshow": {
"slide_type": ""
},
"tags": []
},
"outputs": [],
"source": [
"# Loop through each Molecule and call `assign_partial_charges`\n",
"\n",
"for offmol in off_molecules:\n",
" offmol.assign_partial_charges('am1bcc', use_conformers=offmol.conformers)"
]
},
{
"cell_type": "markdown",
"id": "2dbd57c0-87ee-426a-b0ac-1861480a0d34",
"metadata": {
"editable": true,
"raw_mimetype": "text/restructuredtext",
"slideshow": {
"slide_type": ""
},
"tags": []
},
"source": [
"<div class=\"alert alert-info\">\n",
" By default this will default to using the OEChem TK if available, otherwise AmberTools' antechamber will be used.\n",
"</div>"
]
},
{
"cell_type": "markdown",
"id": "2ae36cf5-a109-4abb-8427-d2c1015e097d",
"metadata": {},
"source": [
"Alternative partial charge methods can be used. For example one could ask for `am1-mulliken` charges. Please see the [OpenFF documentation](https://docs.openforcefield.org/projects/toolkit/en/stable/) for more information."
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "85704a16-86b6-4c25-9a4d-050fd215a2ef",
"metadata": {
"editable": true,
"slideshow": {
"slide_type": ""
},
"tags": []
},
"outputs": [],
"source": [
"# Instead assign am1-mulliken charges\n",
"\n",
"for offmol in off_molecules:\n",
" offmol.assign_partial_charges('am1-mulliken', use_conformers=offmol.conformers)"
]
},
{
"cell_type": "markdown",
"id": "b079d97e-fd81-4720-aae0-6c562b772439",
"metadata": {},
"source": [
"<div class=\"alert alert-warning\">\n",
" Any kind of charge assignment will be usable by OpenFE, except if all the partial charges are set to zero!\n",
"</div>"
]
},
{
"cell_type": "raw",
"id": "b1c7eea8-7aaa-4a72-8d48-dfb7c32a60eb",
"metadata": {
"editable": true,
"raw_mimetype": "text/restructuredtext",
"slideshow": {
"slide_type": ""
},
"tags": []
},
"source": [
".. _Converting to OpenFE SmallMoleculeComponents:\n",
"\n",
"Converting to OpenFE SmallMoleculeComponents\n",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
]
},
{
"cell_type": "markdown",
"id": "852c038e-d4dc-4fac-975c-d5e6baee719e",
"metadata": {
"editable": true,
"nbsphinx": "hidden",
"slideshow": {
"slide_type": ""
},
"tags": []
},
"source": [
"### Converting to OpenFE `SmallMoleculeComponents`"
]
},
{
"cell_type": "markdown",
"id": "13839df1-fa2c-4e0a-8322-56ce466aea37",
"metadata": {
"editable": true,
"slideshow": {
"slide_type": ""
},
"tags": []
},
"source": [
"Once we have the desired partial charges for our small molecules, we can then convert them to `SmallMoleculeComponents` for further use within the OpenFE toolkit."
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "669ea0d6-3f49-4e91-b992-95f1bd5e7174",
"metadata": {
"editable": true,
"raw_mimetype": "text/restructuredtext",
"slideshow": {
"slide_type": ""
},
"tags": []
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/ialibay/software/mambaforge/install/envs/alchemiscale-client-0.2.1/lib/python3.10/site-packages/gufe/components/explicitmoleculecomponent.py:79: UserWarning: Partial charges have been provided, these will preferentially be used instead of generating new partial charges\n",
" warnings.warn(wmsg)\n"
]
}
],
"source": [
"import openfe\n",
"\n",
"small_molecule_components = [\n",
" openfe.SmallMoleculeComponent.from_openff(mol)\n",
" for mol in off_molecules\n",
"]"
]
},
{
"cell_type": "markdown",
"id": "26495e97-9501-4971-a274-1cae8946eee9",
"metadata": {},
"source": [
"<div class=\"alert alert-info\">\n",
" A warning is expected on SmallMoleculeComponent creation. This is to tell you that input partial charges have been provided. Where appropriate these will be preferrentially used within OpenFE, avoiding any subsequent charge assignment steps.\n",
"</div>"
]
}
],
"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.10.13"
},
"widgets": {
"application/vnd.jupyter.widget-state+json": {
"state": {},
"version_major": 2,
"version_minor": 0
}
}
},
"nbformat": 4,
"nbformat_minor": 5
}

0 comments on commit 72fc69f

Please sign in to comment.