During the UGM, I was interested in Ben Tehan & Rob Smith’s great work.
They showed me a nice example of molecular alignment with RDKit.
RDKit has several function to perform 3D alignment. In the Drug Discovery 3D alignment of ligands is important not only Comp Chem but also Med Chem. After their presentation, I talked them and they told me that GetCrippenO3A is useful for 3D alignment.
Hmm, that’s sounds interesting.
I tried to use the function.
My example code is below. Following code run on ipython notebook. To visualize 3D structure of molecules, I used py3Dmol. It can visualize multiple 3D molecules and easy to use!
import py3Dmol import copy from rdkit import Chem from rdkit.Chem import Draw from rdkit.Chem.Draw import IPythonConsole from rdkit.Chem import AllChem from rdkit.Chem import rdBase from rdkit.Chem import rdMolAlign from rdkit.Chem import rdMolDescriptors import numpy as np p = AllChem.ETKDGv2() p.verbose = True
If p.verbose set True, user can get SMARTS patterns which hit the definition of ETKDG like below.
[cH0:1]c:2!@;-[O:3][C:4]: 8 7 6 5, (100, 0, 0, 0, 0, 0)
[C:1][CX4H2:2]!@;-[OX2:3][c:4]: 3 5 6 7, (0, 0, 4, 0, 0, 0)
[O:1][CX4:2]!@;-[CX3:3]=[O:4]: 6 5 3 4, (0, 3, 0, 0, 0, 0)
[C:1][CX4:2]!@;-[CX3:3]=[O:4]: 0 1 3 4, (0, 0, 1, 0, 0, 0)
[cH0:1]c:2!@;-[O:3][C:4]: 3 5 10 11, (100, 0, 0, 0, 0, 0)
[C:1][CX4H2:2]!@;-[OX2:3][c:4]: 12 11 10 5, (0, 0, 4, 0, 0, 0)
[OX2:1][CX4:2]!@;-[CX4:3][OX2:4]: 10 11 12 16, (0, 0, 3, 0, 0, 0)
[cH0:1]c:2!@;-[O:3][C:4]: 3 5 10 11, (100, 0, 0, 0, 0, 0)
[C:1][CX4H2:2]!@;-[OX2:3][c:4]: 12 11 10 5, (0, 0, 4, 0, 0, 0)
[OX2:1][CX4:2]!@;-[CX4:3][N:4]: 10 11 12 17, (0, 0, 4, 0, 0, 0)
[cH0:1]c:2!@;-[O:3][C:4]: 3 5 10 11, (100, 0, 0, 0, 0, 0)
Next load molecules and generate conformers. I used cdk2.sdf which is provided in rdkit as sample.
mols = [m for m in Chem.SDMolSupplier('cdk2.sdf') if m != None][:6] for mol in mols: mol.RemoveAllConformers() hmols_1 = [Chem.AddHs(m) for m in mols] hmols_2 = copy.deepcopy(hmols_1) # Generate 100 conformers per each molecule for mol in hmols_1: AllChem.EmbedMultipleConfs(mol, 100, p) for mol in hmols_2: AllChem.EmbedMultipleConfs(mol, 100, p) # for Ipython notebook Draw.MolsToGridImage(mols)
To conduct GetCrippenO3A and GetO3A, I calculate crippen_contrib of each atom and MMFF params of molecules.
crippen_contribs = [rdMolDescriptors._CalcCrippenContribs(mol) for mol in hmols_1] crippen_ref_contrib = crippen_contribs[0] crippen_prob_contribs = crippen_contribs[1:] ref_mol1 = hmols_1[0] prob_mols_1 = hmols_1[1:] mmff_params = [AllChem.MMFFGetMoleculeProperties(mol) for mol in hmols_2] mmff_ref_param = mmff_params[0] mmff_prob_params = mmff_params[1:] ref_mol2 = hmols_2[0] prob_mols_2 = hmols_2[1:]
OK Let’s align molecules and visualize them!
I retrieved the best score index from multi conformers of each molecule and added viewer.
For crippenO3A…
p_crippen = py3Dmol.view(width=600, height=400) p_crippen.addModel(Chem.MolToMolBlock(ref_mol1), 'sdf') crippen_score = [] for idx, mol in enumerate(prob_mols_1): tempscore = [] for cid in range(100): crippenO3A = rdMolAlign.GetCrippenO3A(mol, ref_mol1, crippen_prob_contribs[idx], crippen_ref_contrib, cid, 0) crippenO3A.Align() tempscore.append(crippenO3A.Score()) best = np.argmax(tempscore) p_crippen.addModel(Chem.MolToMolBlock(mol, confId=int(best)), 'sdf') crippen_score.append(tempscore[best]) p_crippen.setStyle({'stick':{}}) p_crippen.render()
For O3A…
p_O3A = py3Dmol.view(width=600, height=400) p_O3A.addModel(Chem.MolToMolBlock(ref_mol2), 'sdf') pyO3A_score = [] for idx, mol in enumerate(prob_mols_2): tempscore = [] for cid in range(100): pyO3A = rdMolAlign.GetO3A(mol, ref_mol2, mmff_prob_params[idx], mmff_ref_param, cid, 0) pyO3A.Align() tempscore.append(pyO3A.Score()) best = np.argmax(tempscore) p_O3A.addModel(Chem.MolToMolBlock(mol, confId=int(best)), 'sdf') pyO3A_score.append(tempscore[best]) p_O3A.setStyle({'stick':{'colorscheme':'cyanCarbon'}}) p_O3A.render()
In my example, both methods shows good results. To check the details, I will calculate ShapeTanimoto and/or RMSD etc.
In summary, rdkit has many useful functions not only 2D but also 3D. I would like to use this function in my project.
All code of the post, I uploaded my github repo.
https://nbviewer.jupyter.org/github/iwatobipen/chemo_info/blob/master/rdkit_notebook/rdkit_3d.ipynb