Низкомолекулярный докинг

Цель данного занятия ознакомится с возможностями докинга низкомолекулярного лиганда в структуру белка. Мы работаем с белком лизоцимом структуру которого построили на основе гомологичного моделирования на прошлом практикуме.

Загружаем модули:

In [2]:
import numpy as np
import copy

# Отображение структур
import IPython.display
import ipywidgets
from IPython.display import display,display_svg,SVG,Image

# Open Drug Discovery Toolkit
import oddt
import oddt.docking
import oddt.interactions

# Органика
from rdkit.Chem import Draw
from rdkit.Chem.Draw import IPythonConsole

import pmx # Модуль для манипулирования pdb 

Подготовка белка:

In [4]:
pdb=pmx.Model('P50717_with_ligand.B99990001.pdb')

for r in pdb.residues[135:]:
    print r #посмотрим остатки
<Molecule: id = 136 name = LEU chain_id =    natoms = 8>
<Molecule: id = 137 name = PRO chain_id =    natoms = 7>
<Molecule: id = 138 name = ASP chain_id =    natoms = 8>
<Molecule: id = 139 name = THR chain_id =    natoms = 7>
<Molecule: id = 140 name = SER chain_id =    natoms = 6>
<Molecule: id = 141 name = ASN chain_id =    natoms = 8>
<Molecule: id = 142 name = CYS chain_id =    natoms = 7>
<Molecule: id = 143 name = NAG chain_id =    natoms = 14>
<Molecule: id = 144 name = NAG chain_id =    natoms = 14>
<Molecule: id = 145 name = NDG chain_id =    natoms = 15>

1-142 остаток принадлежит белку, 143-145 остатки являются лигандом.

In [5]:
# создаем объект белка newpdb и лиганда lig
newpdb = pdb.copy()
lig = pdb.copy()
del newpdb.residues[142:]
del lig.residues[:142]
In [6]:
# находим геометрический центр лиганда
def average_in_list(lst):
   return reduce(lambda x, y: x+y, lst) / len(lst)
x=[]
y=[]
z=[]
for a in lig.atoms:
    x.append(a.x[0])
    y.append(a.x[1])
    z.append(a.x[2])
centre_x=average_in_list(x)
centre_y=average_in_list(y)
centre_z=average_in_list(z)
In [7]:
# создаем pdb файл белка без лиганда
newpdb.writePDB("protein.pdb")

Подготовка белка для докинга:

In [22]:
prot = oddt.toolkit.readfile('pdb','protein.pdb').next()
prot.OBMol.AddPolarHydrogens()
prot.OBMol.AutomaticPartialCharge()

print 'is it the first mol in 1lmp is protein?',prot.protein,':) and MW of this mol is:', prot.molwt 
is it the first mol in 1lmp is protein? False :) and MW of this mol is: 16865.9877

Мой белок не распознан как белок. Молекулярная масса 16865.9877.

Создаем лиганды для докинга:

In [52]:
smiles = ['c1cccc(O)c1', 'c1c(O)ccc(O)c1','c1(O)cc(c2ccccc2)cc(O)c1']
mols= []
images =[]

for s in smiles:
    m = oddt.toolkit.readstring('smi', s)
    if not m.OBMol.Has3D(): 
        m.make3D(forcefield='mmff94', steps=150)
        m.removeh()
        m.OBMol.AddPolarHydrogens()

    mols.append(m)
    ###with print m.OBMol.Has3D() was found that:
    ### deep copy needed to keep 3D , write svg make mols flat
    images.append((SVG(copy.deepcopy(m).write('svg'))))
    
display_svg(*images)
***** - Open Babel Depiction O H *****
***** - Open Babel Depiction O O H H *****
***** - Open Babel Depiction O O H H *****

Создаем объекты для докинга и запускаем его:

In [53]:
#create docking object
dock_obj= oddt.docking.AutodockVina.autodock_vina(
    protein=prot,size=(20,20,20),center=(centre_x, centre_y, centre_z),
    executable='/usr/bin/vina',autocleanup=True, num_modes=20)

print dock_obj.tmp_dir
print " ".join(dock_obj.params)
/tmp/autodock_vina_WCJW7f
--center_x 35.2862977099 --center_y 33.8978091603 --center_z 22.1482078032 --size_x 20 --size_y 20 --size_z 20 --cpu 1 --exhaustiveness 8 --num_modes 20 --energy_range 3
In [54]:
# do it
res = dock_obj.dock(mols,prot)

Описываем результаты докинга:

In [63]:
print "   ".join(["№", "formula", "affinity", "rmsd_ub", "name"])
for i,r in enumerate(res):
    print "%4d%10s%8s%8s%8s" %(i,r.formula, r.data['vina_affinity'],  r.data['vina_rmsd_ub'], r.residues[0].name)
№   formula   affinity   rmsd_ub   name
   0     C6H6O    -3.3   0.000     UNL
   1     C6H6O    -3.1  18.177     UNL
   2     C6H6O    -2.9  15.273     UNL
   3     C6H6O    -2.9   2.229     UNL
   4     C6H6O    -2.8  14.531     UNL
   5     C6H6O    -2.7   9.014     UNL
   6     C6H6O    -2.7   8.851     UNL
   7     C6H6O    -2.6  15.489     UNL
   8     C6H6O    -2.5   2.029     UNL
   9    C6H6O2    -3.1   0.000     UNL
  10    C6H6O2    -3.0   3.657     UNL
  11    C6H6O2    -2.6   3.884     UNL
  12    C6H6O2    -2.6  12.212     UNL
  13    C6H6O2    -2.5  28.118     UNL
  14    C6H6O2    -2.5  27.940     UNL
  15    C6H6O2    -2.5  28.163     UNL
  16    C6H6O2    -2.5  12.293     UNL
  17    C6H6O2    -2.5  11.969     UNL
  18  C12H10O2    -2.9   0.000     UNL
  19  C12H10O2    -1.6  25.158     UNL
In [56]:
for i,r in enumerate(res):
    hbs = oddt.interactions.hbonds(prot,r) #количество водородных связей 
    stack= oddt.interactions.pi_stacking(prot,r) #количество стэкинг взаимодействий 
    phob = oddt.interactions.hydrophobic_contacts(prot,r) #количество гидрофобных контактов
    print "%8s%8s%8s" %(len(hbs[1]),len(stack[1]), len(phob[1]))
       7       0       5
       3       0       5
       3       0       5
       4       0       8
       3       0       8
       4       0       3
       4       0       3
       2       0       8
       2       0       6
       3       0       5
       3       0       4
       0       0       7
       4       0       2
       0       0       3
       0       0       3
       0       0       3
       3       0       1
       1       0       2
       0       0       4
       0       0       9

Задание

N-Ацетилглюкозамин (NAG) содержит в себе СH3C(=O)NH группу. Создаем лиганды, где метильный радикал этой группы будет заменён на: OH, NH3+, H, Ph, COO-.

In [17]:
smiles_2 = ['CC(=O)N[C@H]1[C@H](O)O[C@H](CO)[C@@H](O)[C@@H]1O', 'OC(=O)N[C@H]1[C@H](O)O[C@H](CO)[C@@H](O)[C@@H]1O',
            '[NH3+]C(=O)N[C@H]1[C@H](O)O[C@H](CO)[C@@H](O)[C@@H]1O', 'C(=O)N[C@H]1[C@H](O)O[C@H](CO)[C@@H](O)[C@@H]1O',
           'C1=CC=C(C=C1)OC(=O)N[C@H]1[C@H](O)O[C@H](CO)[C@@H](O)[C@@H]1O', '[O-]C(=O)C(=O)N[C@H]1[C@H](O)O[C@H](CO)[C@@H](O)[C@@H]1O']
name=["C8H15NO6", "C7H13NO7", "C7H15N2O6", "C7H13NO6", "C13H17NO7", "C8H13NO8"]
mols_2= []
images_2 =[]

for i in range(len(smiles_2)):
    m = oddt.toolkit.readstring('smi', smiles_2[i])
    m.title=name[i]
    if not m.OBMol.Has3D(): 
        m.make3D(forcefield='mmff94', steps=150)
        m.removeh()
        m.OBMol.AddPolarHydrogens()

    mols_2.append(m)
    ###with print m.OBMol.Has3D() was found that:
    ### deep copy needed to keep 3D , write svg make mols flat
    images_2.append((SVG(copy.deepcopy(m).write('svg'))))
    
display_svg(*images_2)
C8H15NO6 - Open Babel Depiction O H H H H H O O CH 3 O O N O C8H15NO6
C7H13NO7 - Open Babel Depiction O H H H H H H O O O O O N O C7H13NO7
C7H15N2O6 - Open Babel Depiction H H H H H H H H O O N O O O N O C7H15N2O6
C7H13NO6 - Open Babel Depiction O H H H H H O O O O N O C7H13NO6
C13H17NO7 - Open Babel Depiction O H H H H H O O O O N O O C13H17NO7
C8H13NO8 - Open Babel Depiction H H H H H O O O O O O N O OH C8H13NO8

Запускаем докинг:

In [18]:
#create docking object
dock_obj_2= oddt.docking.AutodockVina.autodock_vina(
    protein=prot,size=(20,20,20),center=(centre_x, centre_y, centre_z),
    executable='/usr/bin/vina',autocleanup=True, num_modes=20)

print dock_obj_2.tmp_dir
print " ".join(dock_obj_2.params)
/tmp/autodock_vina_Us36Lv
--center_x 35.2862977099 --center_y 33.8978091603 --center_z 22.1482078032 --size_x 20 --size_y 20 --size_z 20 --cpu 1 --exhaustiveness 8 --num_modes 20 --energy_range 3
In [19]:
# do it
res_2 = dock_obj_2.dock(mols_2,prot)
In [51]:
A=[]
for i,r in enumerate(res_2):
    A.append([])
    line=[i, r.formula, float(r.data['vina_affinity']), float(r.data['vina_rmsd_ub']), r.residues[0].name, len(oddt.interactions.hbonds(prot,r)[1]), len(oddt.interactions.pi_stacking(prot,r)[1]), len(oddt.interactions.hydrophobic_contacts(prot,r)[1])]
    A[i].extend(line)
A = sorted(A, key=lambda k: k[2]) #сортируем по аффинности
print '\t'.join(["№", "formula", "affinity", "rmsd_ub", "name", "hbond", "stacking", "hydrophobic_contacts"])
for row in A:
    print('\t'.join(list(map(str, row))))
 
№	formula	affinity	rmsd_ub	name	hbond	stacking	hydrophobic_contacts
6	C7H15N2O6	-1.0	0.0	UNL	6	0	0
7	C7H13NO6	-0.8	0.0	UNL	6	0	0
8	C7H13NO6	1.0	4.444	UNL	7	0	0
9	C7H13NO6	2.0	3.62	UNL	7	0	0
10	C7H13NO6	2.0	2.917	UNL	9	0	0
5	C7H13NO7	3.5	0.0	UNL	8	0	0
15	C8H13NO8	10.0	0.0	UNL	12	0	0
0	C8H15NO6	10.7	0.0	UNL	12	0	7
1	C8H15NO6	11.1	4.181	UNL	11	0	8
16	C8H13NO8	11.2	2.625	UNL	7	0	0
2	C8H15NO6	11.3	4.844	UNL	9	0	6
3	C8H15NO6	11.9	3.732	UNL	11	0	7
11	C13H17NO7	12.4	0.0	UNL	19	0	10
12	C13H17NO7	12.7	7.887	UNL	10	1	31
4	C8H15NO6	13.0	3.486	UNL	8	0	1
13	C13H17NO7	13.6	2.514	UNL	15	0	11
14	C13H17NO7	14.2	2.064	UNL	10	0	12

Для всех модификаций N-ацетилглюкозамина афинность получилась невысокая. Самой лучшей находкой стала та, где метильный радикал был заменен на NH3+ - она имеет наименьшую энергию связывания и всего 6 водородных связей. Все остальные находки имеют большее количество связей, хотя и меньшую аффинность. Гидрофобные взаимодействия наблюдается лишь в случае метильного радикала и его замены на фенил.