Team:Moscow/Kinetics

<!DOCTYPE html> .ipynb

In [6]:
from bokeh.plotting import Figure, output_notebook, show
import math
import scipy
import numpy as np
from bokeh.layouts import widgetbox, row, column
from bokeh.models import CustomJS, ColumnDataSource, Slider, Button, PreText, TextInput

A = 0.35
Em = 20000*math.pow(10,-6)
L = 1
DNA = 2.5 #(наномоль/л) - концентрация ДНК
Cas1 = 5 #(наномоль/л) - концентрация dCas9_1
Cas2 = 5 #(наномоль/л) - концентрация dCas9_2
print((A/(Em*L))*1000)
SO = ((A/(Em*L))*1000)*4 + 10000 #(наномоль/л) - концентрация субстрата
CpO = 0
if (DNA < Cas1 and DNA < Cas2):
    CEBL = DNA
else:
    if(Cas1>Cas2):
        CEBL = Cas2
    else:
        CEBL = Cas1
Km = 10*1000 #(наномоль/л) 
kcat =  2.22 
dt1=[dt for dt in range(0, 3600)] #Изменение времени в секундах
C = [0]*3600
b = 0

#Построение графика
y1 = list(C)
x1 = list(dt1)
source = ColumnDataSource(data=dict(x1=x1, y1=y1))
fig = Figure(plot_width=700, plot_height=500, title="Зависимость концентрации продукта расщепления нитроцефина бета-лактамазой от времени",x_axis_label='Время, с', y_axis_label='Концентрация продукта, нМ')
for i in range(0,3600):
    if (i == 0):
        Cp = CpO
    else:  
        Cp = Cp + ((kcat*CEBL*(SO - Cp))*(dt1[i] - dt1[i-1])/(Km + (SO - Cp)))
        if (Cp >= (A/(Em*L))*1000):
            b = i
    y1[i] = Cp

print(Cp)
dt1 = [dt for dt in range(0,b)]
x1 = list(dt1)
source = ColumnDataSource(data=dict(x1=x1, y1=y1))


#Перестройка графика при изменении параметров

#Общий callback
callback = CustomJS(args=dict(source=source), code="""
    DNA = parseFloat(DNA.value)
    Cas1 = parseFloat(Cas1.value)
    Cas2 = parseFloat(Cas2.value)
    SO = parseInt(SO.value)
    CpO = 0
    CEBL = 0
    if(DNA < Cas1 && DNA < Cas2){CEBL = DNA}else{if(Cas1>Cas2){CEBL = Cas2}else{CEBL = Cas1}}
    Km = parseFloat(Km.value)
    data = source.data
    kcat = 2.22
    dt1=data['x1']
    C=data['y1']
    b = 0

    for (var i = 0; i < 3600; i++)
    {
        if (i == 0)
        {
            Cp = CpO
        }
        else
        {
            Cp = Cp + ((CEBL*kcat*(SO - Cp))*(dt1[i] - dt1[i-1])/(Km + (SO - Cp)))
            if (Cp > SO)
            {
                b = i-1
                break;
            }
        }
        C[i] = Cp
    }
    b.value = b
    source.change.emit();
""")

reset = CustomJS(args=dict(source=source), code="""
    A = 0.2
    Em = 20000*Math.pow(10,-6)
    L = 1
    DNA = 2.5
    Cas1 = 5 
    Cas2 = 5 
    SO = (A/(Em*L))*1000 
    CpO = 0
    CEBL = 0
    if(DNA < Cas1 && DNA < Cas2){CEBL = DNA}else{if(Cas1>Cas2){CEBL = Cas2}else{CEBL = Cas1}}
    Km = 10*1000
    kcat = 2.22
    data = source.data
    dt1=data['x1']
    C=data['y1']
    b = 0

    for (var i = 0; i < 3600; i++)
    {
        if (i == 0)
        {
            Cp = CpO
        }
        else
        {
            Cp = Cp + ((CEBL*kcat*(SO - Cp))*(dt1[i] - dt1[i-1])/(Km + (SO - Cp)))
            if (Cp > SO)
            {
                b = i-1
                break
            }
        }
        C[i] = Cp
    }
    SO.value = A/(Em*L)
    DNA.value = 2
    Cas1.value = 3
    Cas2.value = 3
    Km.value = (10).toString()
    source.change.emit();
""")


#Слайдеры
DNAsl = Slider(title = '[DNA], nM', start=0, end=DNA*2, value=DNA, step=0.5, callback=callback)
callback.args["DNA"] = DNAsl
reset.args["DNA"] = DNAsl
Casasl = Slider(title = '[sgRNA-dCas9_1], nM', start=0, end=Cas1*2, value=Cas1, step=0.5, callback=callback)
callback.args["Cas1"] = Casasl
reset.args["Cas1"] = Casasl
Casbsl = Slider(title = '[sgRNA-dCas9_2], nM', start=0, end=Cas2*2, value=Cas2, step=0.5, callback=callback)
callback.args["Cas2"] = Casbsl
reset.args["Cas2"] = Casbsl
SOsl = Slider(title = '[Nitrocefin], nM', start=SO/2, end=SO*2, value=SO, step=5, callback=callback)
callback.args["SO"] = SOsl
reset.args["SO"] = SOsl

#Textbox'ы
IKm = TextInput(callback=callback, value=str(Km))
callback.args["Km"] = IKm
TKm = PreText(text = "Km")
ITime = TextInput(callback=callback, value=str(b))
callback.args["b"] = ITime
Ttime = PreText(text = "time, needed to detect signal")

#Кнопка Reset
resetbt = Button(callback=reset,label="Reset")
fig.circle('x1','y1', source=source, size = 1.5, color = 'red')
output_notebook()
show(column(row(fig,widgetbox(IKm,TKm,ITime,Ttime)),widgetbox(DNAsl,Casasl,Casbsl,SOsl,resetbt)))
17500.0
17505.115719408626
BokehUserWarning: ColumnDataSource's columns must be of the same length. Current lengths: ('x1', 3599), ('y1', 3600)
Loading BokehJS ...

Для описания кинетики реакций, используемых в нашем проекте, мы разделили их на три части: • Взаимодействие dCas9 с ДНК (связывание) • Взаимодействие разъединенных доменов бета-лактамазы с образованием молекулы фермента • Фермент-субстратное взаимодействие

Исходя из источников литературы, константы связывания dCas9 с ДНК велики, поэтому ими можно пренебречь, следовательно, в рамках модели считается, что связывание dCas9 c ДНК происходит мгновенно.

Фермент-субстратное взаимодействие описывается уравнением Михаэлиса-Ментен:

$$\frac{d[P]}{dt} = \frac{kcat[E0][S]}{Km + [S]}$$

Модель представляет собой интерактивный график зависимости концентрации продукта гидролиза нитроцефина бета-лактамазой от времени. Уравнение имеет следующий вид:

$$[P] = [P] + \frac{kcat[E][S]dt}{Km + [S]}$$