In [30]:
import numpy as np
import copy

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

# 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 [36]:
pdb=pmx.Model('with_legand.B99990001.pdb')#/home/shad/hse/kononkova/

for r in pdb.residues[135:]:
    print r
<Molecule: id = 136 name = ASN chain_id =    natoms = 8>
<Molecule: id = 137 name = SER chain_id =    natoms = 7>
<Molecule: id = 138 name = NAG chain_id =    natoms = 14>
<Molecule: id = 139 name = NAG chain_id =    natoms = 14>
<Molecule: id = 140 name = NDG chain_id =    natoms = 15>
In [37]:
# создание объектов белок и лиганда
newpdb = pdb.copy()
for r in newpdb.residues[137:]:
    newpdb.remove_residue(r)
    

lig = pdb.copy()
for r in lig.residues[0:137]:
    lig.remove_residue(r)
In [38]:
for r in lig.residues[0:]:
    print(r)
<Molecule: id = 1 name = NAG chain_id =    natoms = 14>
<Molecule: id = 2 name = NAG chain_id =    natoms = 14>
<Molecule: id = 3 name = NDG chain_id =    natoms = 15>

Находим геометрический центр лиганда

In [39]:
tmp=[]
for a in lig.atoms:
    tmp.append(a.x)
tmp=np.array(tmp)
cent=tmp.mean(axis=0)
In [40]:
newpdb.writePDB('lonely_protein.pdb')
In [41]:
prot = oddt.toolkit.readfile('pdb','lonely_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: 15270.22846

Программа считает, что это не белок. Ну и что. Заменим метильный радикал на другие (OH,NH3+,H,Ph, COO-) и проведем докинг.

In [42]:
smiles = ['O=C(NC1C(O)C(O)C(OC1O)CO)C','O=C(NC1C(O)C(O)C(OC1O)CO)O','O=C(NC1C(O)C(O)C(OC1O)CO)[NH3+]','O=C(NC1C(O)C(O)C(OC1O)CO)','O=C(NC1C(O)C(O)C(OC1O)CO)C1=CC=[C]C=C1','O=C(NC1C(O)C(O)C(OC1O)CO)C(=O)[O-]']
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 H H H H H CH 3 O O O O O O N *****
***** - Open Babel Depiction H H H H H H O O O O O O O N *****
***** - Open Babel Depiction O H H H H H H H H N O O O O O N *****
***** - Open Babel Depiction O H H H H H O O O O O N *****
***** - Open Babel Depiction H H H H H O O O O O O N *****
***** - Open Babel Depiction O H H H H H HO O O O O O O N *****
In [43]:
#create docking object
dock_obj= oddt.docking.AutodockVina.autodock_vina(
    protein=prot,size=(20,20,20),center=cent,
    executable='/usr/bin/vina',autocleanup=True, num_modes=9)

print dock_obj.tmp_dir
print " ".join(dock_obj.params) # Опишите выдачу
/tmp/autodock_vina_sUtPSO
--center_x 53.7483023256 --center_y 38.7396976744 --center_z 26.0129767442 --size_x 20 --size_y 20 --size_z 20 --cpu 1 --exhaustiveness 8 --num_modes 9 --energy_range 3

" ".join(dock_obj.params):
center - геометрический центр лиганда, size - размер docking box - пространство, которым будет ограничиваться докинг, cpu - количество процессоров, exhaustiveness - "полнота охвата" поиска (пропорциональна времени поиска) или количество попыток (чтобы найти наилучшую конформацию) в одном докинг-эксперименте, num_modes - количество конформаций c энергиями, energy_range - максимальная разница в "очках" для конформаций: если для какой-то конформации отклонение от наилучшего score окажется больше этой величины (по дефолту - 3 ккал/моль), то эта конформация исключается.

In [44]:
res = dock_obj.dock(mols,prot)
In [72]:
print 'description: №, formula, affinity, rmsd, name, hbonds, pi_stacking, hydrophobic_contacts'  
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 "%4d%10s%8s%8s%8s%8s%8s%8s" %(i,r.formula, r.data['vina_affinity'],  r.data['vina_rmsd_ub'], r.residues[0].name,len(hbs[1]),len(stack[1]), len(phob[1]))
    
description: №, formula, affinity, rmsd, name, hbonds, pi_stacking, hydrophobic_contacts
   0  C8H15NO6    -5.9   0.000     UNL      10       0       1
   1  C8H15NO6    -5.9   3.344     UNL      10       0       0
   2  C8H15NO6    -5.6   4.052     UNL       4       0       0
   3  C8H15NO6    -5.3   6.568     UNL       5       0       2
   4  C8H15NO6    -5.3   5.935     UNL       5       0       0
   5  C8H15NO6    -5.2   7.469     UNL       6       0       0
   6  C8H15NO6    -5.2   7.072     UNL       5       0       2
   7  C8H15NO6    -5.2   6.887     UNL       5       0       3
   8  C8H15NO6    -5.1   6.666     UNL       6       0       3
   9  C7H13NO7    -6.2   0.000     UNL      10       0       0
  10  C7H13NO7    -6.1   4.771     UNL       7       0       0
  11  C7H13NO7    -5.9   5.012     UNL      10       0       0
  12  C7H13NO7    -5.8   3.195     UNL      10       0       0
  13  C7H13NO7    -5.6   2.516     UNL       7       0       0
  14  C7H13NO7    -5.4   6.530     UNL       6       0       0
  15  C7H13NO7    -5.4   5.840     UNL      12       0       0
  16  C7H13NO7    -5.4   6.219     UNL       8       0       0
  17  C7H13NO7    -5.1   7.933     UNL       5       0       0
  18 C7H15N2O6    -6.2   0.000     UNL       7       0       0
  19 C7H15N2O6    -6.2   4.774     UNL       5       0       0
  20 C7H15N2O6    -5.9   2.728     UNL       5       0       0
  21 C7H15N2O6    -5.7   5.872     UNL       7       0       0
  22 C7H15N2O6    -5.6   6.389     UNL       4       0       0
  23 C7H15N2O6    -5.6   3.809     UNL       3       0       0
  24 C7H15N2O6    -5.5   5.527     UNL       3       0       0
  25 C7H15N2O6    -5.5   4.136     UNL       2       0       0
  26 C7H15N2O6    -5.4   6.710     UNL       5       0       0
  27  C7H13NO6    -5.5   0.000     UNL       5       0       0
  28  C7H13NO6    -5.5   4.401     UNL       8       0       0
  29  C7H13NO6    -5.3   3.537     UNL       5       0       0
  30  C7H13NO6    -5.2   5.314     UNL       3       0       0
  31  C7H13NO6    -5.1   7.220     UNL       6       0       0
  32  C7H13NO6    -4.9   6.985     UNL       5       0       0
  33  C7H13NO6    -4.7   5.894     UNL       5       0       0
  34  C7H13NO6    -4.6   5.591     UNL       3       0       0
  35  C7H13NO6    -4.6   6.318     UNL       7       0       0
  36 C13H17NO6    -7.1   0.000     UNL       5       0       4
  37 C13H17NO6    -6.6   2.566     UNL       6       0       4
  38 C13H17NO6    -6.3   7.235     UNL       6       0       8
  39 C13H17NO6    -6.2   2.084     UNL       2       0       4
  40 C13H17NO6    -6.2   8.290     UNL       5       0       7
  41 C13H17NO6    -6.0   2.184     UNL       5       0       2
  42 C13H17NO6    -6.0   2.555     UNL       1       0       3
  43 C13H17NO6    -5.9   6.559     UNL       6       0       5
  44 C13H17NO6    -5.8   6.133     UNL       9       0       1
  45  C8H13NO8    -6.0   0.000     UNL       5       0       0
  46  C8H13NO8    -6.0   5.828     UNL       4       0       0
  47  C8H13NO8    -5.9   2.416     UNL       4       0       0
  48  C8H13NO8    -5.8   2.864     UNL       7       0       0
  49  C8H13NO8    -5.8   6.961     UNL       5       0       0
  50  C8H13NO8    -5.7   6.419     UNL       8       0       0
  51  C8H13NO8    -5.6   6.182     UNL       7       0       0
  52  C8H13NO8    -5.6   6.851     UNL       6       0       0
  53  C8H13NO8    -5.5   5.610     UNL       7       0       0

По результатам докинга лучшим лигандом оказался лиганд с заместителем - фенильной группой. У него самая лучшая афинность (самая малая энергия образования комплекса белок-лиганд) и больше всего гидрофобных контактов. Заметим, что замещение метильной группы на фенильную приближает лиганд к первоначальному лиганду из трех остатков, для которого считали центр.

In [60]:
for i,r in enumerate(res):
    r.write(filename='r%s.pdb' % i, format='pdb')

Белок с "родным" лигандом

In [31]:
display(Image('native.png'))

Все лиганды (по одной конформации на лиганд (с разными заместителями))

In [33]:
display(Image('ligands.png'))

3 конформации для лучшего заместителя

In [34]:
display(Image('3best.png'))

Лиганд с лучшим заместителем

In [35]:
display(Image('best.png'))

Лиганд с разными заместителями метильной группы от лучшего к худшему, средняя афинность для 9 конформаций, ккал/моль. Афинность здесь пропорциональна dG. Победила фенильная группа.

In [37]:
from IPython.display import HTML, display
import tabulate
table = [["ligand", "mean affinity"],["C13H17NO6",-6.12],["C7H15N2O6",-5.66],["C7H13NO7",-5.53],["C7H13NO6",-5.42],["C8H13NO8",-5.35],["C8H15NO6",-5.26]]
display(HTML(tabulate.tabulate(table, tablefmt='html')))
ligand mean affinity
C13H17NO6-6.12
C7H15N2O6-5.66
C7H13NO7 -5.53
C7H13NO6 -5.42
C8H13NO8 -5.35
C8H15NO6 -5.26

По данным из статьи с помощью oddt можно протестировать разные scoring functions для наших молекул, можно попробовать предсказать афинность с помощью разных моделей (random forests, support vector machines, neural networks and multiple linear regression). Также в статье говорится о том, что oddt дает возможность