-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathtetheredMinimization.py
64 lines (52 loc) · 2.72 KB
/
tetheredMinimization.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import sys
from rdkit import Chem
from rdkit.Chem import AllChem
from rdkit.Chem import rdFMCS
from rdkit.Chem.rdMolAlign import AlignMol
#from rdkit.Chem.rdMolTransforms import GetDihedralDeg, SetDihedralDeg
"""Script taking a single reference molecule and a set of ligands
The MCS between each molecule and the reference is identified and if more than x% of the reference molecule match
then the common atom ids of the set of ligands are written to the output SDF.
If no MCS is found ligands are written into another output file.
Both output SD files can be easily used for constrained or free docking with rdock.
If you want you can adapt the code very easily also to do tethered minimization of 3D molecules.
"""
if len(sys.argv)!=5 :
sys.exit("usage : python tetheredMinimization.py reference.sdf ligand.sdf outputtethered.sdf outputnontethered.sdf")
ratioThreshold=0.20 #minimum portion of the rerence molecule that should be found as common substructure to consider it for tethered minimization: 0.0-1.0
reference = Chem.MolFromMolFile(sys.argv[1], removeHs=True)
ligands = Chem.SDMolSupplier(sys.argv[2],removeHs=True)
w=Chem.SDWriter(sys.argv[3]) #output ligands with constrained atoms
wnt=Chem.SDWriter(sys.argv[4]) #output of ligands without constraints (no MCS with reference ligand)
for mol in ligands:
mols=[reference,mol]
mcsResult=rdFMCS.FindMCS(mols,threshold=0.9,completeRingsOnly=True) #find the maximum common substructure
if mcsResult.smartsString and len(mcsResult.smartsString)>0 :
patt = Chem.MolFromSmarts(mcsResult.smartsString,mergeHs=True)
#keep only the core of the reference molecule
ref=AllChem.ReplaceSidechains(reference,patt)
if ref:
core=AllChem.DeleteSubstructs(ref,Chem.MolFromSmiles('*'))
core.UpdatePropertyCache()
newmol=Chem.Mol(mol) #create a new instance of the molecule, as we will change the coordinates
AllChem.ConstrainedEmbed(newmol,core) #constrained minimization of newmol versus the core of the reference
rms=float(newmol.GetProp('EmbedRMS'))
print('Common core: ',Chem.MolToSmiles(core),' - RMSD:',rms)
matchratio=float(core.GetNumAtoms())/float(reference.GetNumAtoms())
tethered_atom_ids=newmol.GetSubstructMatches(patt) #that's to get the atom ids only
if tethered_atom_ids and matchratio>ratioThreshold :
t=tethered_atom_ids[0]
t1=map(lambda x:x+1, list(t))
ta=','.join(str(el) for el in t1)
nm=Chem.AddHs(newmol, addCoords=True) #create a new 3D molecule and add the TETHERED ATOMS property
nm.SetProp('TETHERED ATOMS',ta)
w.write(nm)
else :
nm=Chem.AddHs(mol,addCoords=True)
wnt.write(nm)
else :
nm=Chem.AddHs(mol,addCoords=True)
wnt.write(nm)
else :
nm=Chem.AddHs(mol,addCoords=True)
wnt.write(nm)