In [60]:
import prody as pd
import pandas
import numpy as np
import seaborn as sns
from scipy import stats
import matplotlib.pyplot as plt
from collections import Counter

Загрузка структур

In [13]:
nmr = pd.parsePDB('/home/julybel/study/3d/prak-04/task2/2KFB.pdb')
RMSFs = [np.mean(pd.calcRMSF(res)) for res in nmr.iterResidues()]
residues_nmr = [res for res in nmr.iterResidues()]
@> 2823 atoms and 20 coordinate set(s) were parsed in 0.15s.

Была произведена предварительная предобработка структуры 4JGF (оставили только цепь А и убрали воду)

In [15]:
xray = pd.parsePDB('/home/julybel/study/3d/prak-04/task2/4JGF.pdb')
mean_betas = [np.mean(res.getBetas()) for res in xray.iterResidues()]
residues_xray = [res for res in xray.iterResidues()]
@> 1433 atoms and 1 coordinate set(s) were parsed in 0.02s.

Сопоставление остатков

Как мы уже заметили по предыдущему заданию, структура, полученная с помощью NMR длиннее на 3 аминокислотных остатка (1 в самом начале и 2 в конце). Проверим равенство длин полученных списков аминокислот для каждой из структур и проведем сопоставление

In [26]:
len(residues_nmr[1:-2]) == len(residues_xray)
Out[26]:
True
In [38]:
Counter([str(n).split()[0] == str(x).split()[0] for n, x in zip(residues_nmr[1:-2], residues_xray)])
Out[38]:
Counter({True: 171})

Мы видим, что наблюдается соответствие по длинам списков и по именам аминокислотных остатков. Номера их, конечно, будут различаться на 1

Построение графиков

In [58]:
x, y = mean_betas, RMSFs[1:-2]

fig, ax = plt.subplots(figsize=(10,7))
ax.set_title('Зависимость RMSFs, полученных по данным\n структуры NMR от средних значений В-факторов,\n полученных по X-ray структуре\n', 
            fontdict={'fontsize' : 20})
ax.set_xlabel('Средние значения В-факторов', fontdict={'fontsize' : 16})
ax.set_ylabel('RMSFs', fontdict={'fontsize' : 16})

sns.regplot(x, y, color='forestgreen')
Out[58]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f8e7264a810>

Посчитаем корреляции

In [70]:
print('Корреляция по Пирсону, rho=', round(stats.pearsonr(x, y)[0], 2), ', p-value=', round(stats.pearsonr(x, y)[1], 2))
print('Корреляция по Спирману, rho=', round(stats.spearmanr(x, y)[0], 2), ', p-value=', round(stats.spearmanr(x, y)[1], 2))
Корреляция по Пирсону, rho= 0.37 , p-value= 0.0
Корреляция по Спирману, rho= 0.33 , p-value= 0.0

В целом мы видим, что корреляция достаточно слабая, поэтому сложно точно утверждать о зависимости двух величин. По полученным значениям и виду построенного графика мы можем предположить наличие слабой линейной зависимости RMSFs от средних значений B-фактора - чем больше значение В-фактора, тем больше значение RMSFs.

RMSF, по определению, - мера отклонения позиции частицы i (атома) от некоторого референсного положения:
$ RMSF_i = [\frac {1} {T} \sum |r_i(t_j) - r^{ref}_i|^2 ]^{1/2} $, где T - время, по которому производится усреднение

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

Более точное сравнение

Нам нужно, чтобы NMR и X-ray структуры полностью соответствовали друг другу по составу атомов

In [116]:
sp = [(atom.getName(), atom.getResname(), atom.getResnum()) for atom in xray]
need = [atom.getIndex() for atom in nmr if (atom.getName(), atom.getResname(), atom.getResnum()-1) in sp]
len(sp) == len(need)
Out[116]:
True

$ RMSF^2_i = \frac {3B_i} {8\pi^2} $

In [ ]:
s = 'index '

for i in need:
    s += '{} or index '.format(i)
nmr.select('index 0 or index 1')

s = s[:-10]
In [179]:
modified_betas = [(3*atom.getBeta())/(8*(np.pi**2)) for atom in xray]
modified_rmsfs = list(map(lambda x: x**2, list(pd.calcRMSF(nmr.select(s)))))

atoms_xray = [(atom.getResname(), atom.getResnum()) for atom in xray]
atoms_nmr = [(atom.getResname(), atom.getResnum()-1) for atom in nmr if atom.getIndex() in need]
Counter([x == n for x, n in zip(atoms_xray, atoms_nmr)])
Out[179]:
Counter({True: 1433})
In [186]:
x, y = modified_betas, modified_rmsfs

fig, ax = plt.subplots(figsize=(10,7))
ax.set_title('RMSF^2 ~ 3Bi/8pi^2\n', 
            fontdict={'fontsize' : 20})
ax.set_xlabel('modified betas', fontdict={'fontsize' : 16})
ax.set_ylabel('modified RMSFs', fontdict={'fontsize' : 16})

sns.regplot(x, y, color='forestgreen')
Out[186]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f8e624aea10>

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

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

In [187]:
print('Корреляция по Пирсону, rho=', round(stats.pearsonr(x, y)[0], 2), ', p-value=', round(stats.pearsonr(x, y)[1], 2))
print('Корреляция по Спирману, rho=', round(stats.spearmanr(x, y)[0], 2), ', p-value=', round(stats.spearmanr(x, y)[1], 2))
Корреляция по Пирсону, rho= 0.34 , p-value= 0.0
Корреляция по Спирману, rho= 0.43 , p-value= 0.0