В данном практикуме я рассмотрел две структуры одной молекулы лигазы UFC1 человека, полученных методами РСА (7NW1) и ЯМР (7OVC).
Определение структуры белка методом ядерного магнитного резонанса отличается от метода РСА и имеет свои особенности. Образец находится в растворе, а не в кристалле, при этом регистрируются химические сдвиги и константы спин-спинового взаимодействия для ЯМР-активных ядер. Полученные данные дают набор ограничений, по которым рассчитываются возможные конформации молекулы, или состояния. Такой набор состояний может отражать динамику белка в растворе, но может и содержать вклад погрешностей эксперимента.
Сопоставим модели, полученые в результате экспериментов. На Рисунке 1 представлена модель РСА (цепь 7NW1 B), выравненная на модели ЯМР (цепь 7OVC A) с помощью команды super. Видно, что в целом структуры накладываются друг на друга почти полностью, а ансамбль ЯМР хорошо сходится, за исключением С-конца. На этом же конце две структуры накладываются плохо, а для конформаций ЯМР на этом участке определяется α-спираль. Другое различие в наложении двух экспериментальных моделей представлено на Рисунке 2. Здесь две петли в форме буквы S лежат в перпендикулярных плоскостях.
Я пердположил, что эти два различия связаны с положением молекулы белка в кристалле при проведении РСА, поэтому конформация получается несколько смещенной относительно ЯМР ансамбля. Я достроил соседей по ячейке для 7NW1 и заметил, что C-конец одной молекулы взаимодействует с вышеупомянутой петлей другой молекулы. На Рисунке 3 представлено такое возможное взаимодействие. Азот гуанидиновой группы ARG-111 может вступать в π-катионный стекинг с гистидином-161, а азот остова - образовывать водородную связь с глутамином 160.
Далее я выбрал остаток ARG-64 и сравнил его положение в двух моделях (Рисунок 4). Во-первых, для моделей ЯМР определены водороды, так как их ядра являются ЯМР-активными и их спектры регистрируются. Возможно, в 7NW1 водороды не определены, так как разрешение нетостаточно высокое - 1.95 Å. Во-вторых, боковые цепи аргинина во всех моделях ЯМР развернуты вокруг связи CA-CB в противоположную сторону от положения этого остатка по данным РСА. Также достроив соседние молекулы, я посчитал возможным взаимодействие этого остатка аргинина с одной из соседних по кристаллу молекул. На Рисунке 5 показаны возможный стекинг гуанидиновых групп аргининов и водородная связь от NH к O еще одного остатка аргинина.
Нельзя утверждать, что отличия в положении групп и цепей в этих двух структурах определяются только взаимодействиями крислаллизованных молекул, но в случае двух рассмотренных примеров это, скорее всего, так; ансамбль ЯМР при этом может в какой-то мере отражать колебания в растворе, которые гораздо сильнее таковых в кристаллах.
import prody
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
from IPython.display import Image
Image("all.png")
Image("turn.png")
Image("t1_1.png")
Image("arg64_2_all.png")
Image("arg64_1.png")
В данном задании я рассчитал и сравнил две меры подвижности атомов -
RMSF и В-фактор. Если ансамбль ЯМР моделей действительно
повторяет днамику белка в растворе, то RMSF, рассчитанный по нему, будет соответствовать значениям B-фактора аналогичных
атомов из РСА модели.
Рассчитаем эти показатели для каждого остатка и сопоставим. Чтобы првильно соотнести остатки, я посмотрел на аминокислотную последовательность белковых молекул в двух структурах. Последовательность в структуре ЯМР (GLY1 - GLN168) длиннее таковой в РС эксперименте (ASP3-CYS166) на 2 а.к. с каждого из концов, а в остальном они совпадают полностью. На Рисунке 6 представлено совместное распределение средних RMSF 7OVC и средних B-факторов 7NW1 для соответствующих остатков. Чтобы установить наличие корреляции между параметрами, посчитаем коэффициент ранговой корреляции Спирмана, H0: ρ = 0 (условие применения - объем выборок больше 5 - выполняется, нормальное распределение не требуется). Коэффициент равен 0.33, p-value = 1.43 10^-5, что позволяет отвергнуть нулевую гипотезу и сказать, что данные показатели коррелированы.
Тем не менее, нельзя говорить о наличии какой-то причинно-следственной связи между ними и нельзя принять, например, B-факторы за априорный показатель и делать вывод, соответствуют ли им значения RMSF и отражает ли ансамбль ЯМР моделей динамику белка в растворе. Аналогичный вывод можно сделать, сопоставив значения RMSF для каждого атома 7OVC и значения RMSF, рассчитанные из B-факторов 7NW1 по формуле RMSF = 3B/8/π^2 (Рисунок 7). Коэффициент Спирмана также значимо отличается от нуля и равен 0.40. Видно, что соответствие формуле плохое, есть достаточно сильный разброс в данных.
nmr_7ovc = prody.parsePDB('7ovc')
xray_7nw1 = prody.parseMMCIF('7nw1')
nmr_7ovc_A = nmr_7ovc.select('protein and chain A').toAtomGroup()
xray_7nw1_B = xray_7nw1.select('chain BB').toAtomGroup()
@> PDB file is found in working directory (7ovc.pdb). @> 3147 atoms and 20 coordinate set(s) were parsed in 0.13s. @> 3051 atoms and 1 coordinate set(s) were parsed in 0.07s.
xray_resid_beta = pd.DataFrame(columns = ['Res', 'MeanBeta'])
for res in xray_7nw1_B.iterResidues():
if "CA" in res.getNames():
beta = np.mean(res.getBetas())
xray_resid_beta.loc[str(res.getResnum())] = [res.getResname(), beta]
nmr_resid_rmsf = pd.DataFrame(columns = ['Res', 'MeanRMSF'])
for res in nmr_7ovc_A.iterResidues():
if "CA" in res.getNames():
rmsf = np.mean(prody.calcRMSF(res))
nmr_resid_rmsf.loc[str(res.getResnum())] = [res.getResname(), rmsf]
from scipy import stats
stats.spearmanr(xray_resid_beta['MeanBeta'],nmr_resid_rmsf.iloc[2:165, 1])
SpearmanrResult(correlation=0.3327458836960558, pvalue=1.4258689827173595e-05)
fig, ax = plt.subplots()
fig.set_size_inches(10, 7)
SMALL_SIZE = 14
MEDIUM_SIZE = 16
plt.rc('font', size=SMALL_SIZE)
plt.rc('axes', titlesize=SMALL_SIZE)
plt.rc('axes', labelsize=MEDIUM_SIZE)
plt.rc('xtick', labelsize=SMALL_SIZE)
plt.rc('ytick', labelsize=SMALL_SIZE)
sns.kdeplot(x = xray_resid_beta['MeanBeta'], y = nmr_resid_rmsf.iloc[2:165, 1], fill = True)
sns.scatterplot(x = xray_resid_beta['MeanBeta'], y = nmr_resid_rmsf.iloc[2:165, 1], s = 15, color = 'red', alpha = 0.5)
ax.set_xlabel('Mean Beta factor')
ax.set_ylabel('Mean RMSF')
plt.show()
xray_atom_rmsf = pd.DataFrame(columns = ['Res', 'AtomName', 'RMSF'])
for res in xray_7nw1_B.iterResidues():
if "CA" in res.getNames():
for atom in res.iterAtoms():
if atom.getName()[0] != 'H':
beta = atom.getBeta()
rmsf = 3 * beta / 8 / np.pi ** 2
name = atom.getName()
xray_atom_rmsf.loc[str(atom.getIndex())] = [res.getResname() + str(res.getResnum()), name ,rmsf]
else:
continue
nmr_atom_rmsf = pd.DataFrame(columns = ['Res', 'AtomName', 'RMSF'])
for res in nmr_7ovc_A.iterResidues():
if "CA" in res.getNames():
for atom in res.iterAtoms():
if atom.getName()[0] != 'H':
rmsf = prody.calcRMSF(res)[np.where(res.getNames() == atom.getName())[0][0]] ** 2
name = atom.getName()
nmr_atom_rmsf.loc[str(atom.getIndex())] = [res.getResname() + str(res.getResnum()), name , rmsf]
else:
continue
#Проверим, что атомы в двух структурах различаются только на N- и С- концах, где 7OVC длиннее
xray_at = []
nmr_at = []
for i in range(len(xray_atom_rmsf)):
#Имя атома и номер аминокислоты - его идентификатор
xray_at.append(xray_atom_rmsf.iloc[i, 0] + xray_atom_rmsf.iloc[i, 1])
for i in range(len(nmr_atom_rmsf)):
nmr_at.append(nmr_atom_rmsf.iloc[i, 0] + nmr_atom_rmsf.iloc[i, 1])
st = 0
dif = []
#Ожидаем, что 7NM1 будет совпадать с какой-то связной подпоследовательностью 7ovc по всем атомам
for i in range(0, len(nmr_at)):
if st < len(xray_at):
if nmr_at[i] != xray_at[st]:
dif.append(nmr_at[i])
else:
st = st + 1
else:
dif.append(nmr_at[i])
len(dif) == len(nmr_at) - len(xray_at)
True
Начиная с ASP-3 до CYS-166 аминоксилотная последовательность и все атомы в выбранных молекулах идентичны. Можем сопоставить RMSF для всех атомов 7OVC_A и RMSF, посчитанное из B - факторов, для всех атомов 7NW1_B.
from scipy import stats
stats.spearmanr(xray_atom_rmsf['RMSF'],nmr_atom_rmsf.iloc[13:1356, 2])
SpearmanrResult(correlation=0.4001641042709147, pvalue=8.278743458390352e-53)
fig, ax = plt.subplots()
fig.set_size_inches(10, 7)
SMALL_SIZE = 14
MEDIUM_SIZE = 16
plt.rc('font', size=SMALL_SIZE)
plt.rc('axes', titlesize=SMALL_SIZE)
plt.rc('axes', labelsize=MEDIUM_SIZE)
plt.rc('xtick', labelsize=SMALL_SIZE)
plt.rc('ytick', labelsize=SMALL_SIZE)
sns.kdeplot(x = xray_atom_rmsf['RMSF'], y = nmr_atom_rmsf.iloc[13:1356, 2], fill = True)
sns.scatterplot(x = xray_atom_rmsf['RMSF'],y = nmr_atom_rmsf.iloc[13:1356, 2], color = 'red', alpha = 0.3, s = 8)
ax.set_ylabel('RMSF^2 NMR')
ax.set_xlabel('RMSF^2 X-ray')
plt.show()
В данном задании я изучил, как в моделях ЯМР сохраняется расстояние между донорами и акцепторами водородных связей, которые прослеживаются в РС модели. Я выбрал три связи: связь кислорода остова аланина 135 и азота остова аланина 139, которые находятся в α-спирали внутри белка (Рисуонок 8), связь кислорода боковой группы тирозина 90 и азотов NH боковой группы аргинина 31 (два азота гуанидиновой группы идентичны), которые также находятся внутри белка (Рисунок 9), и связь кислорода OD1 аспарагина 128 и азота боковой цепи лизина 131, которые находятся на поверхности пелка в составе петель и смотрят в раствор (Рисунок 10). Я рассчитал расстояние между этимим атомами во всех конформациях ЯМР структуры и установил, что первая связь присутствует в 95% конформаций, вторая - в 30%, а последняя - ни в одной.
Первая связь находится внутри молекулы белка и поддерживает структуру α-спирали, возможные колебания в растворе и в кристалле здесь минимальны. Вторая связь образуется уже реже, тирозин 90 в РСА модели не очень хорошо накладывается на конформации ЯМР. Возможно, здесь уже существенно сказывается движения молекулы в растворе. Расстояние же между OD1 аспарагина 128 и NZ лизина 131 минимально составляет 6.5 Å, что почти в два раза больше допустимой дистанции установления водородной связи, что уже однозначно запрещает ее формирование. Если все-таки допустить, что ансамбль моделей как-то отражает движения молекулы белка в растворе, то колебания поверхностных остатков можно объяснить образованием водородных связей с водой, с молекулами которой тем больше возможность связаться, чем сильнее остаток открыт в раствор.
pairs = [(('ALA', '135', 'O'), ('ALA', '139', 'N')), (('TYR', '90', 'OH'), ('ARG', '31', 'NH2')), (('TYR', '90', 'OH'), ('ARG', '31', 'NH1')), (('ASN', '128', 'OD1'), ('LYS', '131', 'NZ'))]
#Рассчитаем расстояние между атомами в каждом
df_dist = pd.DataFrame(columns = ['dist_v'])
for i in pairs:
f = nmr_7ovc_A.select('resnum ' + i[0][1] + ' and name ' + i[0][2]).toAtomGroup()
s = nmr_7ovc_A.select('resnum ' + i[1][1] + ' and name ' + i[1][2]).toAtomGroup()
dist = []
for setf, sets in zip(f.iterCoordsets(), s.iterCoordsets()):
dist.append(float(prody.calcDistance(setf, sets)))
df_dist.loc[i[0][0] + i[0][1] + i[0][2] + '-' + i[1][0] + i[1][1] + i[1][2]] = [dist]
#Рассчитаем параметры водородных связей в NMR модели
#Для связи с аргинином учтем, что два азота NH гуанидиновой группы идентичны
df_dist.loc['TYR90OH-ARG31N'] = [[min(i,j) for i,j in zip(df_dist.iloc[1,0], df_dist.iloc[2,0])]]
r_d = ['2,9', '3,5','3,5', '3.1', '3,5']
df_dist['RSA_dist, Å'] = r_d
df_dist['inNMR'] = df_dist.apply(lambda row: len(list(filter(lambda x: x <= 3.5, row.dist_v))), axis = 1)
df_dist['PercNMR, %'] = df_dist.apply(lambda row: row.inNMR/20*100, axis = 1)
df_dist['Min, Å'] = df_dist.apply(lambda row: np.round(np.min(row.dist_v), 2), axis = 1)
df_dist['Max, Å'] = df_dist.apply(lambda row: np.round(np.max(row.dist_v), 2), axis = 1)
df_dist['Median, Å'] = df_dist.apply(lambda row: np.round(np.median(row.dist_v), 2), axis = 1)
df_dist_f = df_dist.iloc[[0,4,3], 1:]
#Итоговая таблица
df_dist_f
RSA_dist, Å | inNMR | PercNMR, % | Min, Å | Max, Å | Median, Å | |
---|---|---|---|---|---|---|
ALA135O-ALA139N | 2,9 | 19 | 95.0 | 2.89 | 3.61 | 3.01 |
TYR90OH-ARG31N | 3,5 | 6 | 30.0 | 3.20 | 4.40 | 3.75 |
ASN128OD1-LYS131NZ | 3.1 | 0 | 0.0 | 6.50 | 10.09 | 7.27 |
Image("t3_1.png")
Image("t3_2.png")
Image("t3_3.png")