Предварительные ласки.
from IPython.display import Image, display
import __main__
__main__.pymol_argv = [ 'pymol', '-x' ]
import pymol
pymol.finish_launching()
from pymol import cmd, stored
cmd.reinitialize()
cmd.do('bg_color white; set antialias, 2; set ray_trace_mode, 3;')
Загрузим данные.
cmd.fetch('1lmp')
cmd.do('remove resn hoh')
cmd.do('png 1lmp.png, width=1080, height=1080')
Image('1lmp.png', width=600, height=600)
Тут мы ручками проскульптировали леую альфа-цепь белка (на картинке выше) и ниже отрисуем сравнение нескульптированного и скульптированного белка.
cmd.do('zoom')
cmd.do('png 1lmp_sculpted.png, width=1080, height=1080')
display(Image('1lmp.png', width=300, height=300), Image('1lmp_sculpted.png', width=300, height=300))
Перезагрузим модель.
cmd.delete('1lmp')
cmd.fetch('1lmp')
cmd.do('remove resn hoh')
cmd.do('util.cbag 1lmp')
Посмотрим на связывание лигандов из данных PDB.
display(Image('https://cdn.rcsb.org/etl/poseview/img/lm/1lmp/N/NDG/1lmp_NDG.png', width=600),
Image('https://cdn.rcsb.org/etl/poseview/img/lm/1lmp/N/NAG/1lmp_NAG.png', width=600))
Нас интересуют именно боковые цепи АК (иначе мутагенез так себе скажется). Для NDG перспективными кажутся ASP52 и GLU35. Для NAG кажется перспективным ASP101. Все связи являются водородными.
Отметим, что в модели два NAG (130 и 131) и один NDG (132). Именно NAG130 взаимодействует с ASP101. Согласно данным Ligand viewer на PDB, NAG131 взаимодействует с TRP63 водородной связью. NDG132 взаимодействует ещё и с боковыми остатками ASN46 и VAL109 (якобы гидрофобно). Все взаимодействия указаны для боковых цепей.
Лиганд | Остаток | Тип |
---|---|---|
NAG130 | ASP101 | Водородная связь |
NAG131 | TRP63 | Водородная связь |
NDG132 | GLU35 | Водоробная связь |
NDG132 | ASN46 | Водородная связь |
NDG132 | ASP52 | Водородная связь |
NDG132 | VAL109 | Гидрофобное взаимодействие |
Теперь посмотрим на зону контакта.
cmd.do('select ligand, resn NAG or resn NDG\n'
'select contact_zone, ligand around 3.5\n'
'select contact_res, byres contact_zone\n'
'as wire, not ligand\n'
'show sticks, contact_res\n'
'distance contact_dist, ligand, contact_zone, 3.5\n'
'orient ligand or contact_zone\n'
'rotate x, 90')
cmd.do('label name CA and contact_res, "%s%s" % (resn, resi)')
cmd.do('png all_contacts.png, 1080, 1080')
cmd.do('rotate y, 90')
cmd.do('png all_contacts_y_90.png, 1080, 1080')
cmd.do('rotate y, -90')
display(Image('all_contacts.png', width=600), Image('all_contacts_y_90.png', width=600))
Мы видим, что у нас много просто "контактов" на расстоянии 3.5Å. Якобы гидрофобное взаимодействие с VAL109 не подтвердилось — этот остаток выходит на поверхность. Правда, белок может димеризоваться с собой (но в PDB нет такой информации) или с другими белками (но это мы смотреть не будем). Таким образом, мы дальше будем смотреть только полярные контакты боковых цепей.
cmd.do('hide everything, contact_dist\n'
'distance contact_dist_polar, ligand, contact_zone and not (name O or name N), 3.5, 2\n'
'orient ligand or cont\n')
cmd.do('png polar_contacts.png, 1920, 1080')
cmd.do('rotate x, 30')
cmd.do('png polar_contacts_x_30.png, 1920, 1080')
cmd.do('rotate y, -60')
cmd.do('png polar_contacts_y_m_60.png, 1920, 1080')
cmd.do('rotate y, 60')
display(Image('polar_contacts.png', width=720),
Image('polar_contacts_x_30.png', width=720),
Image('polar_contacts_y_m_60.png', width=720))
Мы видим два наиболее перспективных взаимодействия: NAG130 с ASP101 и NDG132 с ASP52. Оба взаимодействия — предполагаемые водородные связи с длиной 2.4Å. Остальные взаимодействия больше 3Å.
Ещё посмотрим на красивую поверхность контакта.
cmd.do('show surface, contact_zone\n'
'hide sticks labels, contact_res and not (resi 101 or resi 52)\n')
cmd.do('png contact_surface.png, 1920, 1080')
display(Image('contact_surface.png', width=720))
Перед тем, чтобы приступить к мутагенезу, надо посмотреть, а как поведёт себя скульптирование без мутаций.
import time
cmd.do('set auto_sculpt, on\n'
'set sculpting, on\n'
'sculpt_activate all\n')
time.sleep(60)
cmd.do('set sculpting, off')
cmd.do('png naive_scuplt.png, 1920, 1080')
display(Image('naive_scuplt.png', width=720))
Лиганд-связывающий карман на глаз поменялся незначительно, лиганд не вытолкнулся.
Теперь проведём замену ASP101 на ALA и посмотрим, что получится.
cmd.do('hide everything, contact_dist_pol')
cmd.do('orient ligand or contact_zone\n')
cmd.do('rotate x, 90')
cmd.do('png asp101ala.png, 1920, 1080')
display(Image('asp101ala.png', width=720))
Теперь NAG130 не удерживается водородной связью с ALA101.
cmd.do('set auto_sculpt, on\n'
'set sculpting, on\n'
'sculpt_activate all\n')
time.sleep(60)
cmd.do('set sculpting, off')
cmd.do('png asp101ala_after_sculpt.png, 1920, 1080')
display(Image('asp101ala_after_sculpt.png', width=720))
Ничего особенно не изменилось.
Давайте заменим 101 остаток на TRP.
cmd.do('util.cbac resi 101')
cmd.do('orient ligand or contact_zone')
cmd.do('rotate x, 90')
cmd.do('png asp101trp.png, 1920, 1080')
display(Image('asp101trp.png', width=720))
Теперь скульптируем.
cmd.do('set auto_sculpt, on\n'
'set sculpting, on\n'
'sculpt_activate all\n')
time.sleep(60)
cmd.do('set sculpting, off')
cmd.do('png asp101trp_after_sculpting.png, 1920, 1080')
display(Image('asp101trp_after_sculpting.png', width=720))
И опять ничего не поменялось!
Вернём ASP на 101 и будем развлекаться с ASP52. Сделаем на этот раз по-красивому, через команды.
cmd.wizard('mutagenesis')
cmd.refresh_wizard()
cmd.get_wizard().do_select('resi 52')
cmd.get_wizard().set_mode('TRP')
cmd.refresh_wizard()
cmd.get_wizard().apply()
cmd.set_wizard()
cmd.do('util.cbag resi 101\n'
'util.cbac resi 52\n'
'orient ligand or contact_zone\n')
cmd.rotate('x', 90)
Заменили ASP52 на TRP, далее скульптирование.
cmd.do('set auto_sculpt, on\n'
'set sculpting, on\n'
'sculpt_activate all\n')
time.sleep(60)
cmd.do('set sculpting, off')
cmd.do('png asp52trp_after_scuplting.png, 1920, 1080')
display(Image('asp52trp_after_scuplting.png', width=720))
Да тоже ничего не поменялось, в общем-то.
Ну и ладно, оставим так.
Сначала подготовим мутант.
cmd.do('hide surface\n'
'as cartoon, not resi 52 and not hetatm')
cmd.do('zoom')
Теперь загрузим нативный белок.
cmd.fetch('1lmp', 'native')
cmd.do('remove resn hoh')
cmd.do('util.cbaw native and resi 52')
cmd.do('show sticks, native and resi 52')
cmd.center('1lmp or native')
cmd.zoom('1lmp or native')
cmd.super('1lmp', 'native')
cmd.translate('[-30, 0, 0]', 'native')
cmd.center('1lmp or native')
cmd.zoom('1lmp or native')
Рисуем кадры.
# Начальный кадр
cmd.mset('1 x300')
cmd.frame('1')
cmd.mview('store')
cmd.mview('store', object='native')
# Совмещаем структуры
cmd.frame('100')
cmd.mview('store')
cmd.translate('[30, 0, 0]', object='native')
cmd.mview('store', object='native')
# Центрируем по совмещённым структурам
cmd.frame('150')
cmd.center('native')
cmd.zoom('native')
cmd.mview('store', object='native')
cmd.mview('store')
# Приближаем к лиганду
cmd.frame('200')
cmd.mview('store', object='native')
cmd.center('1lmp and resi 52')
cmd.zoom('1lmp and resi 52')
cmd.mview('store')
# Вращаемся вокруг лиганда
cmd.frame('300')
cmd.mview('store', object='native')
cmd.center('1lmp and resi 52')
cmd.zoom('1lmp and resi 52')
cmd.turn('y', 90)
cmd.mview('store')
# Заполняем кадры
cmd.mview('reinterpolate')
cmd.mview('reinterpolate', object='native_protein')
Сохраняем картинки и собираем гифку, ибо неохота маяться с установкой кодека.
cmd.mpng('movie\\', mode=1, width=480, height=360)
import imageio
with imageio.get_writer('movie.gif', mode='I', fps=30) as writer:
for i in range(300):
writer.append_data(imageio.imread(f'movie\\{i + 1:04}.png'))
display(Image('movie.gif', format='png'))