{ "cells": [ { "cell_type": "markdown", "id": "088a1bc4-e5f3-47ac-8ebf-1a904fa82f80", "metadata": { "nbsphinx": "hidden", "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "# Selecting partial charge assigment methods when loading small molecules" ] }, { "cell_type": "markdown", "id": "00d9ca69-1b38-4cf8-9c93-1fc4c08dae15", "metadata": { "nbsphinx": "hidden", "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "## On partial charge assignment" ] }, { "cell_type": "markdown", "id": "8bc61b88-0c8d-4b89-b704-8ac4ade19c6c", "metadata": { "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](https://docs.openfree.energy/en/stable/cookbook/loading_molecules.html#Loading-small-molecules).\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/latest/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": "markdown", "id": "d2658885-8ad9-4142-b163-17c8aa576b00", "metadata": { "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": { "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": { "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": { "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "
removeHs=False keyword argument so that RDKit does not strip your hydrogens!\n",
"