System Building: μ-opioid Receptor in Membrane with morphinan antagonist#
In this tutorial, we will showcase how to build a protein system embeded in a membrane with a ligand in one of the compartments for simulating binding. The sample system is a mu-opioid receptor (the protein) in a membrane and a morphinan antagonist (the ligand).
Let’s start by doing some imports and definitions:
from htmd.ui import *
from htmd.home import home
from os.path import join
from moleculekit.config import config
config(viewer='webgl')
datadir = home(dataDir='mor')
2024-06-11 15:51:03,138 - numexpr.utils - INFO - Note: NumExpr detected 20 cores but "NUMEXPR_MAX_THREADS" not set, so enforcing safe limit of 8.
2024-06-11 15:51:03,138 - numexpr.utils - INFO - NumExpr defaulting to 8 threads.
2024-06-11 15:51:03,219 - rdkit - INFO - Enabling RDKit 2022.09.1 jupyter extensions
Please cite HTMD: Doerr et al.(2016)JCTC,12,1845. https://dx.doi.org/10.1021/acs.jctc.6b00049
HTMD Documentation at: https://software.acellera.com/htmd/
You are on the latest HTMD version (2.3.28+0.g1f64e666d.dirty).
Prepare the protein#
View the file as it comes from the OPM database:
Molecule(join(datadir, '4dkl.pdb')).view()
NGLWidget()
Retrieve the structure from OPM, do not keep the DUM
atoms, and
print the thickness as calculated by OPM:
from moleculekit.opm import get_opm_pdb
prot, thickness = get_opm_pdb('4dkl', keep=False)
thickness
32.0
Remove non-protein atoms, and keep only a monomer.
prot.filter('(protein and noh and chain B) or (water and within 5 of (chain B and protein))')
2024-06-11 15:51:05,557 - moleculekit.molecule - INFO - Removed 2574 atoms. 2262 atoms remaining in the molecule.
array([ 0, 1, 2, ..., 4808, 4809, 4810], dtype=int32)
Automatically detecting segments and assigning names to them.
prot = autoSegment(prot, sel="protein")
prot.set("segid", "W", sel="water")
2024-06-11 15:51:05,587 - moleculekit.tools.autosegment - INFO - Created segment P0 between resid 65 and 263.
2024-06-11 15:51:05,588 - moleculekit.tools.autosegment - INFO - Created segment P1 between resid 270 and 352.
prot = systemPrepare(prot)
2024-06-11 15:51:05,684 - moleculekit.tools.preparation - WARNING - Both chains and segments are defined in Molecule.chain / Molecule.segid, however they are inconsistent. Protein preparation will use the chain information.
---- Molecule chain report ----
Chain A:
First residue: HOH 717
Final residue: HOH 717
Chain B:
First residue: MET 65
Final residue: HOH 735
---- End of chain report ----
2024-06-11 15:51:07,626 - moleculekit.tools.preparation - INFO - Modified residue ASP 114 B to ASH
2024-06-11 15:51:07,627 - moleculekit.tools.preparation - INFO - Modified residue CYS 140 B to CYX
2024-06-11 15:51:07,627 - moleculekit.tools.preparation - INFO - Modified residue HIS 171 B to HID
2024-06-11 15:51:07,627 - moleculekit.tools.preparation - INFO - Modified residue CYS 217 B to CYX
2024-06-11 15:51:07,628 - moleculekit.tools.preparation - INFO - Modified residue HIS 223 B to HID
2024-06-11 15:51:07,628 - moleculekit.tools.preparation - INFO - Modified residue HIS 297 B to HID
2024-06-11 15:51:07,628 - moleculekit.tools.preparation - INFO - Modified residue HIS 319 B to HIE
2024-06-11 15:51:07,629 - moleculekit.tools.preparation - WARNING - Dubious protonation state: the pKa of 1 residues is within 1.0 units of pH 7.4.
2024-06-11 15:51:07,630 - moleculekit.tools.preparation - WARNING - Dubious protonation state: ASP 114 B (pKa= 7.85)
prot.reps.add(sel='segid P0', style='NewCartoon', color=1)
prot.reps.add(sel='segid P1', style='NewCartoon', color=2)
prot.view()
NGLWidget()
Add a sodium atom in the receptor#
sod = Molecule(join(datadir, 'sod.pdb'))
sod.set('segid','S1')
prot.append(sod)
prot.reps.add(sel='ions', style='VDW', color='green')
prot.view()
NGLWidget()
Embed the protein into a membrane#
memb = Molecule(join(datadir, 'membrane80by80C36.pdb'))
memb.set('segid', 'M')
Center the membrane onto the protein center
pcenter = np.mean(prot.get('coords','protein'),axis=0)
mcenter = np.mean(memb.get('coords'),axis=0)
memb.moveBy(pcenter-mcenter)
And now embed.
The two are equivalent - append
with collisions=True
only adds
atoms if they do not clash sterically.
mol = prot.copy()
mol.append(memb, collisions=True)
2024-06-11 15:51:08,522 - moleculekit.molecule - INFO - Removed 319 residues from appended Molecule due to collisions.
Visualize the embedded system#
mol.reps.add(sel='protein', style='NewCartoon', color='Secondary Structure')
mol.reps.add(sel='ions', style='VDW', color='green')
mol.reps.add(sel='lipids', style='Lines')
mol.view()
NGLWidget()
Add a ligand#
import random
lig = Molecule(join(datadir, 'MOL.cif'))
lig.set('segid','L');
lcenter = np.mean(lig.get('coords'),axis=0)
newlcenter=[random.uniform(-10, 10), random.uniform(-10, 10), 43 ]
lig.rotateBy(uniformRandomRotation(), lcenter)
lig.moveBy(newlcenter-lcenter)
mol.append(lig)
Put it in a water box#
coo = mol.get('coords','noh and (lipids or protein)')
m = np.min(coo, axis=0) + [0, 0, -5]
M = np.max(coo, axis=0) + [0, 0, 20]
smol = solvate(mol, minmax=np.vstack((m,M)))
2024-06-11 15:51:10,118 - htmd.builder.solvate - INFO - Using water pdb file at: /home/sdoerr/Work/htmd/htmd/share/solvate/wat.pdb
2024-06-11 15:51:10,551 - htmd.builder.solvate - INFO - Replicating 8 water segments, 2 by 2 by 2
Solvating: 100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 8/8 [00:10<00:00, 1.27s/it]
2024-06-11 15:51:21,290 - htmd.builder.solvate - INFO - 8853 water molecules were added to the system.
Visualize#
smol.reps.add(sel='segid L', style='Licorice')
smol.reps.add(sel='water', style='Lines')
smol.view()
NGLWidget()
Build with AMBER#
molbuilt = amber.build(smol, param=[join(datadir, 'MOL.frcmod')], topo=[join(datadir, 'MOL.cif')], outdir='./final-build', saltconc=0.15)
2024-06-11 15:51:26,607 - htmd.builder.amber - INFO - Detecting disulfide bonds.
2024-06-11 15:51:26,614 - htmd.builder.builder - INFO - One disulfide bond was added
Disulfide Bond between: UniqueResidueID<resname: 'CYX', chain: 'B', resid: 78, insertion: '', segid: 'P0'>
and: UniqueResidueID<resname: 'CYX', chain: 'B', resid: 155, insertion: '', segid: 'P0'>
2024-06-11 15:51:27,682 - htmd.builder.amber - INFO - Starting the build.
2024-06-11 15:51:29,609 - htmd.builder.amber - INFO - Finished building.
2024-06-11 15:51:30,594 - moleculekit.writers - WARNING - Field "resid" of PDB overflows. Your data will be truncated to 4 characters.
2024-06-11 15:51:35,176 - htmd.builder.builder - WARNING - Found cis peptide bond in 1 frames: [0] in the omega diheral "Angle of (HID 160 CA ) (HID 160 C ) (PRO 161 N ) (PRO 161 CA ) " with indexes [2528, 2541, 2543, 2553]
2024-06-11 15:51:35,516 - htmd.builder.ionize - INFO - Adding 15 anions + 0 cations for neutralizing and 64 ions for the given salt concentration 0.15 M.
2024-06-11 15:51:44,191 - htmd.builder.amber - INFO - Starting the build.
2024-06-11 15:51:46,213 - htmd.builder.amber - INFO - Finished building.
2024-06-11 15:51:47,141 - moleculekit.writers - WARNING - Field "resid" of PDB overflows. Your data will be truncated to 4 characters.
2024-06-11 15:51:51,546 - htmd.builder.builder - WARNING - Found cis peptide bond in 1 frames: [0] in the omega diheral "Angle of (HID 160 CA ) (HID 160 C ) (PRO 161 N ) (PRO 161 CA ) " with indexes [2528, 2541, 2543, 2553]
2024-06-11 15:51:51,569 - py.warnings - WARNING - /home/sdoerr/miniforge3/envs/htmd/lib/python3.10/site-packages/Bio/pairwise2.py:278: BiopythonDeprecationWarning: Bio.pairwise2 has been deprecated, and we intend to remove it in a future release of Biopython. As an alternative, please consider using Bio.Align.PairwiseAligner as a replacement, and contact the Biopython developers if you still need the Bio.pairwise2 module.
warnings.warn(
2024-06-11 15:51:54,048 - moleculekit.tools.sequencestructuralalignment - INFO - Alignment #0 was done on 282 residues: 2-285
Visualize built system#
molbuilt.view()
2024-06-11 15:51:54,436 - moleculekit.writers - WARNING - Field "resid" of PDB overflows. Your data will be truncated to 4 characters.
NGLWidget()
The molbuilt
is a Molecule
object that contains the built
system, but the full contents to run a simulation are located in the
outdir
(./final-build
in this case).