Задание №1

Prody и B-факторы часть 1

In [1]:
import prody
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
import seaborn as sns
from IPython.display import Image
In [2]:
struc = prody.parsePDB('3q3y')
@> PDB file is found in working directory (3q3y.pdb.gz).
@> 3464 atoms and 1 coordinate set(s) were parsed in 0.07s.
In [3]:
mean_betas = [(r, np.mean(r.getBetas())) for r in struc.iterResidues() if 'CA' in r.getNames()]
In [4]:
len(mean_betas)
Out[4]:
362
In [5]:
mean_betas.sort(key=lambda x: x[1])

print(mean_betas[0], mean_betas[-1], sep='\n')
(<Residue: ALA 172 from Chain A from 3q3y (5 atoms)>, 5.106)
(<Residue: LYS 0 from Chain B from 3q3y (9 atoms)>, 58.693333333333335)
In [6]:
r_min, r_max = mean_betas[0][0], mean_betas[-1][0]
In [7]:
for r in r_min, r_max:
    betas = r.getBetas()
    print(r.getResname(),
         f'std: {round(np.var(betas), 6)}',
         f'var: {round(np.std(betas), 6)}\n{"-"*10}', sep='\n')
ALA
std: 0.073544
var: 0.27119
----------
LYS
std: 310.024356
var: 17.607508
----------

Таким образом, остаток с наименьшим средним B-фактором -- аланин цепи А, с наибольшим - знакомый нам по второму практикуму лизин 0.

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

In [8]:
Image('1_1.png')
Out[8]:

Рисунок 1: Структура 3Q3Y. Остатки LYS-0 и ALA-172 с наибольшим и наименьшим средними значениями B-фактора. Окрашены в зеленый и розовый соответственно.

Как видно из рисунка 1, лизину предположительно может соответствовать высокая подпижность, так как он "выходит на поверхность" своим боковым радикалом, а вот аланин находится внутри глобулы, таким образом и подвижность мы должны наблюдать минимальную.
Локализация остатков относительно поверхности лучше видна на рисунке 2.

In [9]:
Image('1_2.png')
Out[9]:

Рисунок 2: Структура 3Q3Y. Остатки LYS-0 и ALA-172 с наибольшим и наименьшим средними значениями B-фактора. Окрашены в зеленый и розовый соответственно. Добавлена surface для наглядности расположения относительно поверхности.

Боковой радикал Lys-0 стабилизирован лишь потенциальными водородными связями с плохой геометрией (рисунок 3), а Ala-172 находится в бета складчатом слое и связан с соседними листами водородными связями (рисунок 4). Образование водородных связей для аланина через боковой радикал не характерно.

In [10]:
Image('1_3.png')
Out[10]:

Рисунок 3: Остаток LYS-0 и его окружение.

In [11]:
Image('1_4.png')
Out[11]:

Рисунок 4 Остаток ALA-172 и его окружение.

Prody и B-факторы часть 2

In [12]:
protein_mass_center = prody.calcCenter(struc, weights=struc.getMasses())

mean_betas, distances = [], []

for r in struc.iterResidues():
    if 'CA' in r.getNames():
        mean_betas.append(np.mean(r.getBetas()))
        mass_center = prody.calcCenter(r, weights=r.getMasses())
        distances.append(prody.calcDistance(protein_mass_center, mass_center))
In [13]:
fig, ax = plt.subplots(figsize=(12, 8))
sns.scatterplot(distances, mean_betas, color='darkblue')

ax.set_title('Зависимость B-фатора от расстояния между центрами масс', )
ax.set_xlabel('Расстояния между центрацми масс остатка и белка, Å')
ax.set_ylabel('B-фактор')
fig.show()
/home/krokodil194/.local/lib/python3.8/site-packages/seaborn/_decorators.py:36: FutureWarning: Pass the following variables as keyword args: x, y. From version 0.12, the only valid positional argument will be `data`, and passing other arguments without an explicit keyword will result in an error or misinterpretation.
  warnings.warn(
<ipython-input-13-ec4c9c68d6b3>:7: UserWarning: Matplotlib is currently using module://ipykernel.pylab.backend_inline, which is a non-GUI backend, so cannot show the figure.
  fig.show()
In [14]:
import statsmodels.formula.api as smf


model1 = smf.ols(formula = 'B_factor ~ Distances', 
                 data=pd.DataFrame({'Distances':distances, 'B_factor':mean_betas}))
print(model1.fit().summary())
                            OLS Regression Results                            
==============================================================================
Dep. Variable:               B_factor   R-squared:                       0.019
Model:                            OLS   Adj. R-squared:                  0.016
Method:                 Least Squares   F-statistic:                     6.889
Date:                Mon, 04 Jan 2021   Prob (F-statistic):            0.00904
Time:                        06:33:56   Log-Likelihood:                -1182.1
No. Observations:                 362   AIC:                             2368.
Df Residuals:                     360   BIC:                             2376.
Df Model:                           1                                         
Covariance Type:            nonrobust                                         
==============================================================================
                 coef    std err          t      P>|t|      [0.025      0.975]
------------------------------------------------------------------------------
Intercept      9.4284      1.013      9.306      0.000       7.436      11.421
Distances      0.1209      0.046      2.625      0.009       0.030       0.211
==============================================================================
Omnibus:                      280.090   Durbin-Watson:                   0.935
Prob(Omnibus):                  0.000   Jarque-Bera (JB):             4613.106
Skew:                           3.147   Prob(JB):                         0.00
Kurtosis:                      19.317   Cond. No.                         66.8
==============================================================================

Notes:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.

Предположим, что регрессор в виде расстояния между центрами масс линейно описиывает зависимую переменную, то бишь B-фактор.
Как видно из модели выше, линейно зависимость не описывается, R-squared никакой и т.д.
Единственное, что интересное, - коэффициент Дурбина-Уотсона. Если он стремится к 0, то мы отвергаем нулевую гипотезу о независимости отклонений. Здесь значение где-то посередине, но автокорреляция отклонений B-факторов в рамках белка звучит крайне логично, так как есть у нас идёт, например, череда бета слоёв, то подвижность в рамках них будет минимальна. Получается, автокорреляция.

In [15]:
from scipy.stats import spearmanr, pearsonr
print(spearmanr(mean_betas, distances), pearsonr(mean_betas, distances), sep='\n')
SpearmanrResult(correlation=0.2570837376279221, pvalue=7.121778667339029e-07)
(0.13703143245798485, 0.009040755476374956)

Ни монотонная, ни линейная корреляция также не обнаружены.
Если о монотонной можно как-то аккуратно поговорить, то вот линейной точно не видно, в чём мы уже убедились выше, потерпев фиаско в построении модели.

Задание 3. Как работает восстановление функции электронной плотности по экспериментальным данным

In [16]:
run compile-func.py -g 30,3,5+24,3,4+40,2.5,12+30,4,10.5+25,3,11.2
File func.txt created

Рисунок 4: Модель электронной плотности одномерной системы атомов из двух молекул, состоящих из 2 и 3 атомов соответственно.

Отныне и впредь все несовместимости исходных скриптов с python3 будут фикситься, потому что добавлять новый интерпретатор в kernel сложнее, чем добавить скобки к print.

С помощью скрипта получаем файл с амплитудами и фазами

In [17]:
run func2fourier.py -i func.txt -o out.txt
..Done
In [18]:
Image('screen1.png')
Out[18]:

Мною были выбраны следующие критерии для классификации восстановления по качеству:

  1. Плохое: возможно только угадывать со свечкой в руках
  2. Среднее: определение положения атомов возможно частично
  3. Хорошее: возможно предположить положение всех максимумов, зная число атомов, но максимумы при этом не отличимы от шума
  4. Отличное: можно определить местоположение всех атомов

Сначала рассмотрим несколько полных наборов гармоник без добавления шума.
Для интервалов взял степени двойки: 0-2, 0-4, 0-8, 0-16, 0-32, 0-64, 0-128.

Результаты дальнейшего моделирования занесены в таблицу.

In [19]:
run fourier-filter.py -i out.txt -r 0-2 -o 11.txt
..Done
In [20]:
run fourier2func.py -f func.txt -i 11.txt -o 12.txt
File 12.txt with function and its recovering is created

Рисунок 5: Восстановление функции электронной плотности по полному набору гармоник (интервал гармоник: 0-2).

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

In [21]:
run fourier-filter.py -i out.txt -r 0-4 -o 21.txt
..Done
In [22]:
run fourier2func.py -f func.txt -i 21.txt -o 22.txt
File 22.txt with function and its recovering is created

Рисунок 6: Восстановление функции электронной плотности по полному набору гармоник (интервал гармоник: 0-4).

Пока ещё всё плохо, но уже можно вполне уверенно предполагать, что мы имеем дело с двумя молекулами. Количество атомов остаётся неизвестным.

In [23]:
run fourier-filter.py -i out.txt -r 0-8 -o 31.txt
..Done
In [24]:
run fourier2func.py -f func.txt -i 31.txt -o 32.txt
File 32.txt with function and its recovering is created

Рисунок 7: Восстановление функции электронной плотности по полному набору гармоник (интервал гармоник: 0-8).

Стало лучше, но стоит попробовать ещё раз увеличить набор.

In [25]:
run fourier-filter.py -i out.txt -r 0-16 -o 41.txt
..Done
In [26]:
run fourier2func.py -f func.txt -i 41.txt -o 42.txt
File 42.txt with function and its recovering is created

Рисунок 8: Восстановление функции электронной плотности по полному набору гармоник (интервал гармоник: 0-16).

Стоит ещё раз увеличить набор.

In [27]:
run fourier-filter.py -i out.txt -r 0-32 -o 51.txt
..Done
In [28]:
run fourier2func.py -f func.txt -i 51.txt -o 52.txt
File 52.txt with function and its recovering is created

Рисунок 9: Восстановление функции электронной плотности по полному набору гармоник (интервал гармоник: 0-32).

Теперь мы уже можем предположить, где находятся максимумы, а для первой молекулы всё видно однозначно. Хорошее восстановление.

In [29]:
run fourier-filter.py -i out.txt -r 0-64 -o 61.txt
..Done
In [30]:
run fourier2func.py -f func.txt -i 61.txt -o 62.txt
File 62.txt with function and its recovering is created

Рисунок 10: Восстановление функции электронной плотности по полному набору гармоник (интервал гармоник: 0-64).

Первая восстановление, которое я классифицирую как отличное.

In [31]:
run fourier-filter.py -i out.txt -r 0-128 -o 71.txt
..Done
In [32]:
run fourier2func.py -f func.txt -i 71.txt -o 72.txt
File 72.txt with function and its recovering is created

Рисунок 11: Восстановление функции электронной плотности по полному набору гармоник (интервал гармоник: 0-128).

Видно, что теперь увеличение числа гармоник не сказывается на качестве восстановления ЭП и мы всё так же точно определяем максимумы гауссовых слагаемых.

На основании проведенных экспериментов можно сделать вывод, что качество восстановления ЭП увеличивается с длиной интервала гармоник, что логично, так как мы с большей точностью способы апроксимировать нашу функцию тригонометрией.

Теперь попробуем восстановление ЭП с дополнительным шумом амплитуды и/или фазы в размере 25, 50, 75%.
Буду производить восстановление по полному набору гармоник на интервале 0-64.

In [33]:
run func2fourier.py -i func.txt -o F11.txt -F 25
..Done
In [34]:
run fourier-filter.py -i F11.txt -r 0-64 -o F12.txt
..Done
In [35]:
run fourier2func.py -f func.txt -i F12.txt -o F13.txt
File F13.txt with function and its recovering is created

Рисунок 12: Восстановление функции электронной плотности по полному набору гармоник (интервал гармоник: 0-64), шум амплитуды равен 25%.

Даже при 25% уровне зашумления качество восстановления всё ещё можно назвать отличным.

In [36]:
run func2fourier.py -i func.txt -o F21.txt -F 50
..Done
In [37]:
run fourier-filter.py -i F21.txt -r 0-64 -o F22.txt
..Done
In [38]:
run fourier2func.py -f func.txt -i F22.txt -o F23.txt
File F23.txt with function and its recovering is created

Рисунок 13: Восстановление функции электронной плотности по полному набору гармоник (интервал гармоник: 0-64), шум амплитуды равен 50%.

При 50% уровне зашумления всё еще можно точно определить положения всех атомов, а значит модель всё еще отличная, хоть и, действительно, шумненькая.

In [39]:
run func2fourier.py -i func.txt -o F31.txt -F 75
..Done
In [40]:
run fourier-filter.py -i F31.txt -r 0-64 -o F32.txt
..Done
In [41]:
run fourier2func.py -f func.txt -i F32.txt -o F32.txt
File F32.txt with function and its recovering is created

Рисунок 14: Восстановление функции электронной плотности по полному набору гармоник (интервал гармоник: 0-64), шум амплитуды равен 75%.

Положения исходных атомов всё еще можно точно определить, но уровень шума настолько велик, что можно предположить и существования других атомов.

Если знать состав, то можно с большой долей вероятности угадать правильную локализацию всех атомов. А значит и модель хорошая.

Думаю, восстановление получается неплохим из-за большого интервала гармоник. Уменьшим его до 48.

In [42]:
run func2fourier.py -i func.txt -o F41.txt -F 75
..Done
In [43]:
run fourier-filter.py -i F41.txt -r 0-48 -o F42.txt
..Done
In [44]:
run fourier2func.py -f func.txt -i F42.txt -o F43.txt
File F43.txt with function and its recovering is created

Рисунок 15: Восстановление функции электронной плотности по полному набору гармоник (интервал гармоник: 0-48), шум амплитуды равен 75%.

Получаем хорошее качество, но хуже, чем в предыдущем эксперименте

In [45]:
run func2fourier.py -i func.txt -o P11.txt -P 25
..Done
In [46]:
run fourier-filter.py -i P11.txt -r 0-64 -o P12.txt
..Done
In [47]:
run fourier2func.py -f func.txt -i P12.txt -o P13.txt
File P13.txt with function and its recovering is created

Рисунок 16: Восстановление функции электронной плотности по полному набору гармоник (интервал гармоник: 0-64), шум фазы равен 25%.
Отличная модель.

In [48]:
run func2fourier.py -i func.txt -o P21.txt -P 50
..Done
In [49]:
run fourier-filter.py -i P21.txt -r 0-64 -o P22.txt
..Done
In [50]:
run fourier2func.py -f func.txt -i P22.txt -o P23.txt
File P23.txt with function and its recovering is created

Рисунок 17: Восстановление функции электронной плотности по полному набору гармоник (интервал гармоник: 0-64), шум фазы равен 50%.

Средняя модель.

In [51]:
run func2fourier.py -i func.txt -o P31.txt -P 75
..Done
In [52]:
run fourier-filter.py -i P31.txt -r 0-64 -o P32.txt
..Done
In [53]:
run fourier2func.py -f func.txt -i P32.txt -o P33.txt
File P33.txt with function and its recovering is created

Рисунок 18: Восстановление функции электронной плотности по полному набору гармоник (интервал гармоник: 0-64), шум фазы равен 75%.

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

Пока можно предположить, что зашумленность фазы критичнее для восстановления электронной плотности, чем шум амплитуды.

Попробуем теперь скомбинировать шумы.

In [54]:
run func2fourier.py -i func.txt -o T11.txt -P 10 -F 40
..Done
In [55]:
run fourier-filter.py -i T11.txt -r 0-64 -o T12.txt
..Done
In [56]:
run fourier2func.py -f func.txt -i T12.txt -o T13.txt
File T13.txt with function and its recovering is created

Рисунок 19: Восстановление функции электронной плотности по полному набору гармоник (интервал гармоник: 0-64), шум фазы равен 10%, амплитуды -- 40%.

Восстановление можно считать отличным. Из рисунка можно делать однозначные выводы.

In [57]:
run func2fourier.py -i func.txt -o T21.txt -P 40 -F 10
..Done
In [58]:
run fourier-filter.py -i T21.txt -r 0-64 -o T22.txt
..Done
In [59]:
run fourier2func.py -f func.txt -i T22.txt -o T23.txt
File T23.txt with function and its recovering is created

Рисунок 20: Восстановление функции электронной плотности по полному набору гармоник (интервал гармоник: 0-64), шум фазы равен 40%, амплитуды -- 10%.

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

Теперь попробуем восстановить ЭП без шумов, но по неполным наборам гармоник: 8-56, 6-64, 0-50.

In [60]:
run fourier-filter.py -i out.txt -r 8-56 -o N11.txt
..Done
In [61]:
run fourier2func.py -f func.txt -i N11.txt -o N12.txt
File N12.txt with function and its recovering is created

Рисунок 21: Восстановление функции электронной плотности по неполному набору гармоник (интервал гармоник: 8-56).

Модель средняя. Потеря начала и конца критична.

In [62]:
run fourier-filter.py -i out.txt -r 6-64 -o N21.txt
..Done
In [63]:
run fourier2func.py -f func.txt -i N21.txt -o N22.txt
File N22.txt with function and its recovering is created

Рисунок 22: Восстановление функции электронной плотности по неполному набору гармоник (интервал гармоник: 6-64).

Большая беда с baseline, но картинку всё ещё можно успешно интерпретировать. Оценим модель как хорошую.

In [64]:
run fourier-filter.py -i out.txt -r 0-50 -o N31.txt
..Done
In [65]:
run fourier2func.py -f func.txt -i N31.txt -o N32.txt
File N32.txt with function and its recovering is created

Рисунок 23: Восстановление функции электронной плотности по неполному набору гармоник (интервал гармоник: 0-50).

Получаем отличную картинку.

ps. Я часто классифицировал модели как отилчные в виду отсутствия некоторого атома с маленьким пиком. В нашем случае, например, водорода, а то, что я моделировал, больше похоже на неорганику.