In [2]:
## Задание 0

В этой работе PyMOL был использован как модуль из Jupyter Notebook.  
Структура 1cll была загружена программно командой `fetch`.  
Для backbone-атомов было включено представление `lines`, после чего выполнено приближение к остаткам 4 и 5.  
Для наглядности остатки 4 и 5 были дополнительно выделены стиками и цветом.  
Итоговое изображение было сохранено в PNG и выведено в ноутбуке.
In [2]:
import __main__
__main__.pymol_argv = ['pymol', '-x']

import pymol
pymol.finish_launching()

from pymol import cmd
from IPython.display import Image, display
In [4]:
# Сбрасываем прошлое состояние
cmd.reinitialize()

# Загружаем структуру
cmd.do('''
fetch 1cll, async=0
as lines, n. C+O+N+CA
zoom i. 4+5
''')
In [10]:
# Немного улучшаем вид
cmd.do('''
bg_color white
color gray70, all
show sticks, i. 4+5
color hotpink, i. 4+5
orient i. 4+5
zoom i. 4+5, 8
''')
In [11]:
# Сохраняем итоговую картинку
out_png = r"C:\Users\Tata\Documents\jupyter_pol\seminar1_task1_1cll.png"
cmd.png(out_png, width=1400, height=1000, dpi=200, ray=1)

print(out_png)
In [12]:
display(Image(filename=out_png))
No description has been provided for this image
In [ ]:
## Задание 1
## Sculpting в PyMOL на примере 1LMP

В этом задании была изучена возможность интерактивного изменения структуры белка с помощью режима Sculpting в PyMOL. В качестве примера использовалась структура 1LMP. Сначала структура была загружена в Jupyter через модуль PyMOL, после чего белковая цепь была показана в виде cartoon, а связанный лиганд — в виде sticks.

Далее был выделен участок белка, расположенный рядом с лигандом, и для него был опробован режим Sculpting. С помощью интерактивного редактирования был изменён локальный участок структуры: боковая цепь/небольшой фрагмент около сайта связывания был слегка смещён. Это позволило оценить, как PyMOL поддерживает локальную геометрию при ручном изменении конформации.

Таким образом, Sculpting можно использовать для наглядного локального редактирования структуры и демонстрации того, как меняется форма участка белка при небольших конформационных изменениях.
In [16]:
# Загружаем структуру
cmd.reinitialize()
cmd.fetch('1lmp', async_=0)

# Убираем воду и мусор
cmd.remove('solvent')

# Делаем понятное отображение
cmd.hide('everything', 'all')
cmd.show('cartoon', 'chain A')
cmd.color('palegreen', 'chain A')

# Лиганд показываем стиками
cmd.show('sticks', 'chain B')
cmd.color('orange', 'chain B')

# Общий вид
cmd.orient()
cmd.zoom('all', 3)
In [18]:
before1_png = r"C:\Users\Tata\Documents\jupyter_pol\1lmp_before_sculpt.png"
cmd.png(before_png, width=1400, height=1000, dpi=200, ray=1)

display(Image(filename=before_png))
No description has been provided for this image
In [10]:
# Остатки белка рядом с лигандом
cmd.select('site', 'byres (chain A within 5 of chain B)')

# Показываем их стиками
cmd.show('sticks', 'site')
cmd.color('yellow', 'site')

# Приближаем активную область
cmd.zoom('site or chain B', 3)
In [20]:
before2_png = r"C:\Users\Tata\Documents\jupyter_pol\1lmp_before_sculpt.png"
cmd.png(before_png, width=1400, height=1000, dpi=200, ray=1)

display(Image(filename=before_png))
No description has been provided for this image
In [21]:
before3_png = r"C:\Users\Tata\Documents\jupyter_pol\1lmp_before_sculpt.png"
cmd.png(before_png, width=1400, height=1000, dpi=200, ray=1)

display(Image(filename=before_png))
No description has been provided for this image
In [22]:
after_png = r"C:\Users\Tata\Documents\jupyter_pol\1lmp_after_sculpt.png"
cmd.png(after_png, width=1400, height=1000, dpi=200, ray=1)

display(Image(filename=after_png))
No description has been provided for this image
In [23]:
session_file = r"C:\Users\Tata\Documents\jupyter_pol\1lmp_sculpt_session.pse"
cmd.save(session_file)

print(session_file)
In [ ]:
## Задание 2
In [26]:
import __main__
__main__.pymol_argv = ['pymol', '-x']

import pymol
pymol.finish_launching()

from pymol import cmd
from IPython.display import Image, display
In [3]:
cmd.reinitialize()

cmd.fetch('1lmp', async_=0)
cmd.remove('solvent')

cmd.hide('everything', 'all')
cmd.show('cartoon', 'chain A')
cmd.color('palegreen', 'chain A')

cmd.show('sticks', 'chain B')
cmd.color('orange', 'chain B')

cmd.orient()
cmd.zoom('all', 3)
In [ ]:
## предварительная зона оценки контактов
In [28]:
cmd.select('contact_zone', 'byres (chain A within 4 of chain B)')

cmd.show('sticks', 'contact_zone')
cmd.color('yellow', 'contact_zone')

cmd.set('label_size', 10)
cmd.set('label_color', 'black')
cmd.label('contact_zone and name CA', '"%s%s" % (resn, resi)')

cmd.zoom('contact_zone or chain B', 5)
In [30]:
before_mut_png = r"C:\Users\Tata\Documents\jupyter_pol\1lmp_contact_before_mut.png"
cmd.png(before_mut_png, width=1400, height=1000, dpi=200, ray=1)

display(Image(filename=before_mut_png))
No description has been provided for this image
In [31]:
after_mut_2_png = r"C:\Users\Tata\Documents\jupyter_pol\1lmp_contact_before_mut.png"
cmd.png(after_mut_2_png, width=1400, height=1000, dpi=200, ray=1)

display(Image(filename=after_mut_2_png))
No description has been provided for this image
In [ ]:
## Задание 3
In [27]:
import __main__
__main__.pymol_argv = ['pymol', '-x']

import pymol
pymol.finish_launching()

from pymol import cmd
In [1]:
## Делаем копию белка, чтобы 1 мутировать, а вотрой оставить исходным
In [2]:
cmd.reinitialize()

# Загружаем исходную структуру
cmd.fetch('1lmp', 'WT', async_=0)

# Делаем полную копию, вместе с лигандом
cmd.create('MUT', 'WT')

# Убираем воду
cmd.remove('solvent')

# Белки
cmd.hide('everything', 'all')
cmd.show('cartoon', 'WT and chain A')
cmd.show('cartoon', 'MUT and chain A')

cmd.color('palegreen', 'WT and chain A')
cmd.color('lightblue', 'MUT and chain A')

# Лиганд показываем у ОБОИХ объектов
cmd.show('sticks', 'WT and chain B')
cmd.show('sticks', 'MUT and chain B')

cmd.color('orange', 'WT and chain B')
cmd.color('tv_red', 'MUT and chain B')

# Чтобы сначала объекты не лежали друг на друге, уводим MUT вправо
cmd.translate([35, 0, 0], object='MUT', camera=0)

cmd.zoom('WT or MUT', 4)
In [3]:
# Выбираем остатки белка рядом с лигандом
cmd.select('wt_site', 'byres (WT and chain A within 4 of WT and chain B)')
cmd.select('mut_site', 'byres (MUT and chain A within 4 of MUT and chain B)')

# Показываем это окружение стиками
cmd.show('sticks', 'wt_site')
cmd.show('sticks', 'mut_site')

cmd.color('yellow', 'wt_site')
cmd.color('cyan', 'mut_site')

cmd.zoom('wt_site or mut_site or WT and chain B or MUT and chain B', 5)
In [4]:
# Подписываем номера остатков у MUT, чтобы было удобно выбирать мутацию
cmd.set('label_size', 10)
cmd.set('label_color', 'black')

cmd.label('mut_site and name CA', '"%s%s" % (resn, resi)')
cmd.zoom('mut_site or MUT and chain B', 6)
In [5]:
cmd.hide('labels', 'all')
In [5]:
## Вручную мутируем TRP63 через Wizard -> Mutation на ALA
In [5]:
## Накладываем мутированную форму белка на исходную и выделяем мутированный остаток для лучшей визуализации
In [16]:
# Совмещаем только белковые цепи
cmd.super('MUT and chain A and name CA', 'WT and chain A and name CA')

# Место мутации показываем стиками
cmd.show('sticks', 'WT and chain A and resi 63')
cmd.show('sticks', 'MUT and chain A and resi 63')

cmd.color('firebrick', 'WT and chain A and resi 63')
cmd.color('blue', 'MUT and chain A and resi 63')

# Если окружение лиганда уже было выделено, можно оставить его стиками
cmd.zoom('WT or MUT', 4)
In [7]:
cmd.bg_color('white')
cmd.set('cartoon_transparency', 0.25, 'MUT and chain A')
cmd.set('stick_radius', 0.18)

# Лиганд у MUT лучше сделать полупрозрачным, чтобы при совмещении не мешал
cmd.set('stick_transparency', 0.5, 'MUT and chain B')
In [8]:
cmd.matrix_reset('WT', mode=1)
cmd.matrix_reset('MUT', mode=1)

cmd.super('MUT and chain A and name CA', 'WT and chain A and name CA')
cmd.zoom('WT or MUT', 4)
In [ ]:
## Создание видео с местом мутации
In [24]:
cmd.mstop()
cmd.mview('clear')
cmd.mset('1 x1')
cmd.frame(1)

cmd.matrix_reset('MUT', mode=1)
cmd.matrix_reset('WT', mode=1)
In [25]:
cmd.mview('clear')
cmd.mset('1 x1')
cmd.frame(1)
cmd.matrix_reset('MUT', mode=1)
In [26]:
# 2) новый медленный ролик
cmd.mset('1 x420')
cmd.frame(1)

# старт: только MUT, WT скрыт
cmd.enable('MUT')
cmd.disable('WT')

# медленные переключения WT поверх MUT
cmd.mdo(120, 'enable WT')
cmd.mdo(200, 'disable WT')
cmd.mdo(280, 'enable WT')
cmd.mdo(360, 'disable WT')
cmd.mdo(420, 'enable WT')

# запуск
cmd.frame(1)
cmd.mplay()
In [26]:
## Сохраняем в PyMol кадры, совмещаим их для аолучения фильма, загружаем его и выводим в Jupyter
In [33]:
import os

frames_dir = r"C:\Users\Tata\Documents\jupyter_pol\movie_frames"
os.makedirs(frames_dir, exist_ok=True)

print(os.path.exists(frames_dir))
print(frames_dir)
In [34]:
cmd.png(r"C:\Users\Tata\Documents\jupyter_pol\movie_frames\test.png")
Out[34]:
1
In [35]:
cmd.set('cache_frames', 0)
cmd.mpng("C:/Users/Tata/Documents/jupyter_pol/movie_frames/frame")
In [39]:
from glob import glob
import imageio.v2 as imageio
import os

frames = sorted(glob(r"C:\Users\Tata\Documents\jupyter_pol\movie_frames\frame*.png"))
out_mp4 = r"C:\Users\Tata\Documents\jupyter_pol\mutation_movie.mp4"

print("Кадров найдено:", len(frames))
print("Первый кадр:", frames[0] if frames else "нет кадров")

with imageio.get_writer(
    out_mp4,
    fps=25,               # меньше fps = медленнее видео
    codec="libx264",
    pixelformat="yuv420p"
) as writer:
    for f in frames:
        writer.append_data(imageio.imread(f))

print("Видео сохранено:", out_mp4)
print("Размер файла:", os.path.getsize(out_mp4))
In [43]:
from IPython.display import Video
Video("mutation_movie.mp4", embed=True, width=800)
Out[43]:
Your browser does not support the video tag.
In [ ]:
## Задание 4

Для присоединения TAMRA я использовала карбоксильную группу красителя и гидроксильную группу Tyr62 белка. Поскольку по условию нужна именно сложноэфирная связь, пришивку выполняли не через аминогруппу, а через кислород тирозина. Сначала у TAMRA был выбран карбоксильный углерод и удалён кислород из группы –OH, который должен уходить при образовании эфира. Затем командой fuse карбоксильный углерод TAMRA был соединён с кислородом Tyr62, а командой torsion метка была довернута в более удобное положение, чтобы уменьшить перекрывание с белком.

In [19]:
cmd.reinitialize()

# Белок
cmd.fetch("1lmp", "WT", type="pdb", async_=0)
cmd.create("prot_tamra", "WT")
cmd.remove("hydro")

# TAMRA из локального файла
cmd.load(r"C:\Users\Tata\Documents\jupyter_pol\tamra.sdf", "TAMRA")
cmd.remove("TAMRA and hydro")

# Показываем TAMRA и подписываем номера атомов
cmd.show("sticks", "TAMRA")
cmd.label("TAMRA and not hydro", "str(ID)")

# Место пришивки: OH Tyr62
cmd.select("site_oh", "prot_tamra and chain A and resi 62 and resn TYR and name OH")
cmd.show("sticks", "site_oh")

cmd.zoom("site_oh or TAMRA", 8)
In [21]:
# остатки белка в копии, которые находятся рядом с лигандом
cmd.select("prot_site", "byres (prot_tamra and chain A within 4 of prot_tamra and chain B)")

# показать это окружение стиками
cmd.show("sticks", "prot_site")

# при желании покрасить
cmd.color("yellow", "prot_site")

# лиганд тоже показать стиками
cmd.show("sticks", "prot_tamra and chain B")
cmd.color("orange", "prot_tamra and chain B")
In [22]:
# выбираем атомы
cmd.select("tamra_c",  "TAMRA and id 29")
cmd.select("tamra_oh", "TAMRA and id 2")
cmd.select("site_oh",  "prot_tamra and chain A and resi 62 and resn TYR and name OH")

# удаляем OH у TAMRA
cmd.remove("id 2")

# ВАЖНО: меняем порядок selection
cmd.fuse("site_oh", "tamra_c")
cmd.unpick()
In [26]:
tamra_png = r"C:\Users\Tata\Documents\jupyter_pol\tamra.png"
cmd.png(tamra_png, width=1400, height=1000, dpi=200, ray=1)

display(Image(filename=tamra_png))
No description has been provided for this image

Задание 5¶

В этом задании я построила поли-аланиновую α-спираль длиной 100 аминокислот в PyMOL. Сначала был создан первый остаток alanine, а затем цепь достраивалась по одному остатку через edit и editor.attach_amino_acid: команда edit каждый раз выбирала C-конец растущей цепи, а attach_amino_acid(..., ss=1) присоединяла следующий alanine в α-спиральной геометрии. Команду bond я отдельно оставила в скрипте как явный пример работы с пептидной связью: на практике после attach_amino_acid она уже обычно создана автоматически. Команду torsion я использовала для аккуратного поворота терминальной метильной группы у последнего alanine — так я показала, как можно вращать фрагмент вокруг выбранной связи, не разрушая общую форму спирали. В итоге получилась длинная регулярная поли-аланиновая α-спираль из 100 аминокислот.

In [28]:
from pymol import cmd, editor

# параметры
aa = "ala"        
n = 100
obj = "polyA_100"

cmd.reinitialize()

# первая аминокислота
cmd.fragment(aa, obj)
cmd.alter(obj, "chain='A'")
cmd.sort(obj)

# C-концевой атом C
cterm_C = f"({obj} and name C and not (neighbor name N))"

# достраиваем цепь до 100 остатков
for _ in range(n - 1):
    cmd.edit(cterm_C)
    editor.attach_amino_acid("pk1", aa, ss=1)
    cmd.sort(obj)

try:
    cmd.bond(f"{obj} and resi 1 and name C", f"{obj} and resi 2 and name N")
except:
    pass


# довернем метильную группу у последнего alanine
cmd.edit(f"{obj} and resi {n} and name CA", f"{obj} and resi {n} and name CB")
cmd.torsion(60)
cmd.unpick()

# оформление
cmd.hide("everything", obj)
#cmd.show("cartoon", obj)
#cmd.color("wheat", obj)

cmd.orient(obj)
cmd.zoom(obj)
In [29]:
# считаем всю цепь спиралью
cmd.alter(obj, "ss='H'")
cmd.rebuild()

# показываем только cartoon
cmd.hide("everything", obj)
cmd.show("cartoon", obj)

# делаем спираль красивее и толще
cmd.set("cartoon_fancy_helices", 1)
cmd.set("cartoon_smooth_loops", 1)
cmd.set("cartoon_tube_radius", 0.6)
cmd.set("cartoon_oval_length", 1.2)
cmd.set("cartoon_oval_width", 0.5)

# оформление
cmd.bg_color("white")
cmd.color("deepsalmon", obj)

cmd.orient(obj)
cmd.zoom(obj)
In [30]:
ala_png = r"C:\Users\Tata\Documents\jupyter_pol\ala.png"
cmd.png(ala_png, width=1400, height=1000, dpi=200, ray=1)

display(Image(filename=ala_png))
No description has been provided for this image

Задание 6¶

В этом задании я строила длинную B-форму ДНК не вручную по одному нуклеотиду, а через матрицу преобразования. Сначала я взяла из структуры 1BNA две соседние пары оснований и командой pair_fit совместила первую пару со второй по нескольким атомам сахаро-фосфатного остова. После этого с помощью get_object_matrix получила матрицу перехода от одной пары к следующей. Дальше первая пара была размножена 100 раз: каждую новую копию я создавала командой create и сдвигала на один шаг вдоль спирали командой transform_selection с той самой матрицей. В результате получилась длинная правозакрученная B-ДНК из 100 пар оснований.

In [33]:
from pymol import cmd

cmd.reinitialize()
cmd.fetch("1bna", "templ", type="pdb", async_=0)
cmd.remove("solvent")

# Берем НЕ концевую, а внутреннюю пару
cmd.create("pair0", "templ and ((chain A and resi 2) or (chain B and resi 23))")
cmd.create("pair", "pair0")
cmd.create("nextpair", "templ and ((chain A and resi 3) or (chain B and resi 22))")

# Совмещаем pair с nextpair по атомам сахаро-фосфатного остова
cmd.pair_fit(
    "pair and chain A and resi 2  and name P",   "nextpair and chain A and resi 3  and name P",
    "pair and chain A and resi 2  and name C1'", "nextpair and chain A and resi 3  and name C1'",
    "pair and chain A and resi 2  and name C4'", "nextpair and chain A and resi 3  and name C4'",
    "pair and chain B and resi 23 and name P",   "nextpair and chain B and resi 22 and name P",
    "pair and chain B and resi 23 and name C1'", "nextpair and chain B and resi 22 and name C1'",
    "pair and chain B and resi 23 and name C4'", "nextpair and chain B and resi 22 and name C4'"
)

# Получаем матрицу перехода
trans = cmd.get_object_matrix("pair")

# Размножаем первую пару 100 раз
cmd.create("bp001", "pair0")

prev = "bp001"
for i in range(2, 101):
    name = f"bp{i:03d}"
    cmd.create(name, prev)
    cmd.transform_selection(name, trans)
    prev = name

# Собираем все пары в один объект
cmd.create("dna100", "bp*")

# Оформление
cmd.hide("everything", "templ or pair0 or pair or nextpair or bp*")
cmd.show("cartoon", "dna100")
cmd.color("marine", "dna100 and chain A")
cmd.color("lightpink", "dna100 and chain B")

cmd.bg_color("white")
cmd.orient("dna100")
cmd.zoom("dna100", 2)

Для итоговой визуализации B-ДНК я использовала представление sticks, так как объект был собран из отдельных повторяющихся пар оснований и cartoon-режим отображался некорректно. Чтобы двойная спираль была лучше видна, радиус sticks был увеличен, поэтому модель стала более толстой и наглядной.

In [39]:
cmd.hide("everything", "all")
cmd.show("sticks", "dna100")
cmd.set("stick_radius", 0.29)
cmd.color("marine", "dna100 and chain A")
cmd.color("lightpink", "dna100 and chain B")

cmd.bg_color("white")
cmd.orient("dna100")
cmd.zoom("dna100", 2)
In [40]:
dna_b_png = r"C:\Users\Tata\Documents\jupyter_pol\dna_b.png"
cmd.png(dna_b_png, width=1400, height=1000, dpi=200, ray=1)

display(Image(filename=dna_b_png))
No description has been provided for this image
In [ ]: