海津一成
In [1]:
%matplotlib inline
from ecell4 import *
In [2]:
import matplotlib.pylab as plt
import numpy as np
In [3]:
import seaborn
seaborn.set(font_scale=1.5)
In [4]:
import matplotlib as mpl
mpl.rc("figure", figsize=(6, 4))
| A | B | A AND B |
|---|---|---|
| 0 | 0 | 0 |
| 1 | 0 | 0 |
| 0 | 1 | 0 |
| 1 | 1 | 1 |
ふたつの入力のうち両方が活性でないと出力は活性化しない
ふたつの制御を組み合せてみる
$$\frac{\mathrm{d}[X]}{\mathrm{d}t}=f(A,B)-k[X]=\frac{[A]^{n_1}}{K_1^{n_1}+[A]^{n_1}}\times\frac{[B]^{n_2}}{K_2^{n_2}+[B]^{n_2}}-k[X]$$AとBふたつのスイッチが入らなければ発現しない
In [5]:
def Hill(E, Km, nH):
return E ** nH / (Km ** nH + E ** nH)
In [6]:
data = np.array([[Hill(A, 0.5, 8) * Hill(B, 0.5, 8)
for B in np.linspace(0, 1, 21)]
for A in np.linspace(0, 1, 21)])
plt.imshow(data, cmap='coolwarm')
plt.xlabel('A')
plt.ylabel('B')
plt.colorbar()
plt.clim(0, 1)
plt.show()
試すと
In [7]:
with reaction_rules():
~A > A | 0.2
~B > B | 0.2
~X > X | Hill(A, 0.2, 8) * Hill(B, 0.6, 8)
X > ~X | 1.0
~Y > Y | Hill(A, 0.2, 8)
Y > ~Y | 1.0
In [8]:
run_simulation(5, species_list=['X', 'Y', 'A'],
opt_args=['-', lambda t: 0.2, '--', lambda t: 0.6, '--'])
これは例えば
$$\frac{\mathrm{d}[X]}{\mathrm{d}t}=f(A,B)-k[X]=\frac{\left([A]/K_1\right)^{n_1}+\left([B]/K_2\right)^{n_2}}{1+\left([A]/K_1\right)^{n_1}+\left([B]/K_2\right)^{n_2}}-k[X]$$
In [9]:
def f(A, B, K1, K2, n1, n2):
term1 = (A / K1) ** n1
term2 = (B / K2) ** n1
return (term1 + term2) / (1 + term1 + term2)
複雑に見えるが、$K_1=K_2$かつ$n_1=n_2$の場合を考えればヒル式と同じ
In [10]:
data = np.array([[f(A, B, 0.5, 0.5, 8, 8) for B in np.linspace(0, 1, 21)]
for A in np.linspace(0, 1, 21)])
plt.imshow(data, cmap='coolwarm')
plt.xlabel('A')
plt.ylabel('B')
plt.colorbar()
plt.clim(0, 1)
plt.show()
In [11]:
with reaction_rules():
~A > A | 0.2
~B > B | 0.2
~X > X | f(A, B, 0.2, 0.6, 8, 8)
X > ~X | 1.0
~Y > Y | Hill(B, 0.6, 8)
Y > ~Y | 1.0
In [12]:
run_simulation(5, species_list=['X', 'Y', 'A'],
opt_args=['-', lambda t: 0.2, '--', lambda t: 0.6, '--'])
実は分解を制御しても似たようなことはできる
In [13]:
def Hill_compl(E, Km, nH):
return Km ** nH / (Km ** nH + E ** nH)
上の式においてA、Bがそれぞれ0もしくは十分に存在する場合の定常状態を考えると
| A | B | A OR B |
|---|---|---|
| 0 | 0 | 0 |
| $\infty$ | 0 | $\frac{1}{k1+k2}$ |
| 0 | $\infty$ | 0 |
| $\infty$ | $\infty$ | $\frac{1}{k1}$ |
$k_2$が十分大きければ、ANDゲートが実現できる
In [14]:
data = np.array([[Hill(A, 0.5, 8) / (1 + 100 * Hill_compl(B, 0.3, 8))
for B in np.linspace(0, 1, 21)]
for A in np.linspace(0, 1, 21)])
plt.imshow(data, cmap='coolwarm')
plt.xlabel('A')
plt.ylabel('B')
plt.colorbar()
plt.clim(0, 1)
plt.show()
In [15]:
with reaction_rules():
~A > A | 0.2
~B > B | 0.2
~X > X | Hill(A, 0.2, 8)
X > ~X | (1.0 + 100 * Hill_compl(B, 0.36, 8)) * X
~Y > Y | Hill(A, 0.2, 8)
Y > ~Y | 1.0
In [16]:
run_simulation(5, species_list=['X', 'Y', 'A'],
opt_args=['-', lambda t: 0.2, '--', lambda t: 0.36, '--'],
opt_kwargs={'ylim': (0, 1)})
In [17]:
x = np.linspace(0, 1, 101)
nH = 8
plt.plot(x, [Hill(xi, 0.5, nH) for xi in x], label='Hill eq.')
plt.plot(x, [Hill_compl(xi, 0.5, nH) for xi in x],
label='Complementary Hill eq.')
plt.legend(loc='best')
plt.xlabel('INPUT')
plt.ylabel('OUTPUT')
plt.show()
In [18]:
with reaction_rules():
A > B | 1
B > C | 1
run_simulation(5, {'A': 1})
ここにCの量が多くなると$A{\rightarrow}B$の反応を抑制するように制御を加えてみると
In [19]:
with reaction_rules():
A > B | 1
B > C | 1
obs = run_simulation(5, {'A': 1}, return_type='observer')
In [20]:
with reaction_rules():
A > B | 1 * Hill_compl(C, 0.1, 8) * A
B > C | 1
run_simulation(5, {'A': 1}, opt_args=('-', obs, '--'))
今度はさきほどのものに発現と分解を加えてみる
$${\emptyset}{\rightarrow}A{\rightarrow}B{\rightarrow}C{\rightarrow}{\emptyset}$$Aだけが発現して、Cだけが分解する
In [21]:
with reaction_rules():
~A > A | 1
A > B | 1 > C | 1 > ~C | 1
run_simulation(10)
発現にCの量に応じた抑制を加えると
In [22]:
with reaction_rules():
~A > A | Hill_compl(C, 0.5, 8)
A > B | 1 > C | 1 > ~C | 1
run_simulation(16, opt_args=['-', lambda t: 0.5, '--'],
opt_kwargs={'ylim': (0, 1)})
In [23]:
with reaction_rules():
~A > A | Hill_compl(C, 0.3, 8) > ~A | 1
~B > B | Hill_compl(A, 0.5, 8) > ~B | 1
~C > C | Hill_compl(B, 0.7, 8) > ~C | 1
run_simulation(np.linspace(0, 14, 201))
この場合はヒル係数が小さくなる(スイッチがゆるくなる)と振動は消えてしまう
In [24]:
with reaction_rules():
~A > A | Hill_compl(C, 0.3, 4) > ~A | 1
~B > B | Hill_compl(A, 0.5, 4) > ~B | 1
~C > C | Hill_compl(B, 0.7, 4) > ~C | 1
run_simulation(np.linspace(0, 14, 201))
In [25]:
with reaction_rules():
A > B | 1 > C | 1
run_simulation(8, {'A': 1})
ここにAの量が多いと$B{\rightarrow}C$の反応を抑制するように制御を加えてみると
In [26]:
with reaction_rules():
A > B | 1 > C | 1
obs = run_simulation(8, {'A': 1}, return_type='observer')
In [27]:
with reaction_rules():
A > B | 1 > C | Hill_compl(A, 0.05, 8) * B
run_simulation(8, {'A': 1}, opt_args=('-', obs, '--'))
制御の仕方を変えてみると
In [28]:
with reaction_rules():
~A > A | 1 > ~A | 1
~B > B | Hill(A, 0.5, 8) > ~B | 1
~C > C | Hill(A, 0.5, 8) * Hill_compl(B, 0.5, 8) > ~C | 1
run_simulation(5, opt_args=('-', lambda t: 0.5, '--'))
In [29]:
with reaction_rules():
~B > B | Hill(A, 0.2, 8) > ~B | 1
~C > C | Hill(A, 0.2, 8) * Hill(B, 0.5, 8) > ~C | 1
In [30]:
from ecell4_base.core import *
from ecell4_base import ode
m = get_model()
w = ode.World()
sim = ode.Simulator(w, m)
obs = FixedIntervalNumberObserver(0.01, ['A', 'B', 'C'])
sim.run(1, obs)
w.set_value(Species('A'), 1); sim.initialize()
sim.run(0.3, obs)
w.set_value(Species('A'), 0)
sim.initialize()
sim.run(4, obs)
w.set_value(Species('A'), 1)
sim.initialize()
sim.run(1.5, obs)
w.set_value(Species('A'), 0)
sim.initialize()
sim.run(3.2, obs)
In [31]:
viz.plot_number_observer(obs, '-', lambda t: 0.5, '--')