Dihydrofolate ReductaseΒΆ
This example is similar to the factor Xa example in that we set up a number of perturbations from custom SDF files whilst keeping the parametrised files.
In this example we show how to prepare the same ligands with different crystal structures. In the first case we use the original ligand orientation, while in the second one we use a custom one provided by an external SDF file that we generated using PyMOL.
We also demonstrate that it is also possible to edit the PDB file inside ProtoCaller by creating two batches of structures - one from the altLoc A coordinates and one from the altLoc B coordinates in the original PDB file. This functionality can be very useful when the PDB files are not perfect and one needs to edit them in a controlled manner.
Finally, DHFR has a cofactor (NADPH) close to the active site and as
such needs modelling. In this case we use one of the parameter sets
included in ProtoCaller from the AMBER parameter database website. This means
that ProtoCaller can currently handle systems with some of the
most common cofactors. The full list of cofactors supported by
ProtoCaller can be accessed from the global variable
ProtoCaller.COFACTORNAMES
.
import logging
logging.basicConfig(level=logging.INFO)
import glob
from ProtoCaller.Utils.fileio import Dir
from ProtoCaller.Ensemble import Ensemble, Protein, Ligand
from ProtoCaller.Parametrise import Params
params = Params(ligand_ff="GAFF2")
with Dir("DHFR", overwrite=False):
# create a ligand dictionary and populate it from the Ligands folder.
# this block makes sure we don't reparametrise if we rerun the script.
ligands = {}
with Dir("Ligands") as ligdir:
lignames = [x.split(".")[0] for x in glob.glob("*.sdf")]
for ligname in lignames:
sdf = "{}.sdf".format(ligname)
prmtop = "{}.prmtop".format(ligname)
inpcrd = "{}.inpcrd".format(ligname)
if len(glob.glob(prmtop)) and len(glob.glob(inpcrd)):
parametrised_files = [prmtop, inpcrd]
else :
parametrised_files = None
# here we initialise the ligand with custom structures.
ligands[ligname] = Ligand(sdf, protonated=True, minimise=False,
parametrised_files=parametrised_files,
name=ligname, workdir=ligdir.path)
# there is no point in protonating and parametrising the reference
if parametrised_files is None and sdf != "reference.sdf":
ligands[ligname].parametrise(params=params)
# all of the perturbations
morphs = [
[ligands["Me_H"], ligands["Me_Me"]],
[ligands["Me_Me"], ligands["H_H"]],
[ligands["Me_H"], ligands["H_H"]],
[ligands["Cl_Cl"], ligands["Cl_H"]],
[ligands["Cl_H"], ligands["H_H"]],
[ligands["Me_Me"], ligands["Cl_H"]],
[ligands["Me_H"], ligands["Cl_Cl"]],
[ligands["NO2"], ligands["H_H"]],
[ligands["Br"], ligands["H_H"]],
[ligands["NO2"], ligands["Br"]],
[ligands["OMe"], ligands["H_H"]],
[ligands["OMe"], ligands["Br"]],
]
# now we generate all input structures for 5HPB
print("Generating input files for 5HPB...")
# here we initialise the Ensemble class which is responsible for handling
# all perturbations
system = Ensemble(protein="5HPB", morphs=morphs, box_length_complex=8,
workdir="5HPB", ligand_ref="202")
# we discard everything apart from the crystal waters
system.protein.filter(ligands=None, simple_anions=None, simple_cations=None,
complex_anions=None, waters="all")
system.protein.prepare()
# save all merged structures
system.prepareComplexes()
print("Generating input files for: 6DAV with altLoc A")
# here we supply a custom ligand orientation as a reference
protein_A = Protein("6DAV", ligand_ref=ligands["reference"],
workdir="6DAV_A")
# delete any atoms with altLoc B
for chain in protein_A.pdb_obj:
for residue in chain:
atoms_to_purge = [x for x in residue if x.altLoc == "B"]
residue.purgeAtoms(atoms_to_purge, "discard")
protein_A.pdb_obj.writePDB()
system_A = Ensemble(protein=protein_A, morphs=morphs,
box_length_complex=8, workdir="6DAV_A")
# here we only keep chain A and the crystal waters that belong to it
system_A.protein.filter(ligands=None, simple_anions=None,
simple_cations=None, waters="chains",
chains=["A"])
system_A.protein.prepare()
system_A.prepareComplexes()
# repeat but for altLoc B
print("Generating input files for: 6DAV with altLoc B")
protein_B = Protein("6DAV", ligand_ref=ligands["reference"],
workdir="6DAV_B")
for chain in protein_B.pdb_obj:
for residue in chain:
atoms_to_purge = [x for x in residue if x.altLoc == "A"]
residue.purgeAtoms(atoms_to_purge, "discard")
protein_B.pdb_obj.writePDB()
system_B = Ensemble(protein=protein_B, morphs=morphs,
box_length_complex=8, workdir="6DAV_B")
system_B.protein.filter(ligands=None, simple_anions=None,
simple_cations=None, waters="chains",
chains=["A"])
system_B.protein.prepare()
system_B.prepareComplexes()