Skip to content

Commit dd56eef

Browse files
Shih-Huan HuangShih-Huan Huang
authored andcommitted
add Gillepse
1 parent 3429b62 commit dd56eef

9 files changed

Lines changed: 733 additions & 0 deletions

Gillepse_sim/Dimerization.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
from gillespy2.core import (
2+
Model,
3+
Species,
4+
Reaction,
5+
Parameter
6+
)
7+
import numpy
8+
import matplotlib.pyplot as plt
9+
class Dimerization(Model):
10+
def __init__(self, parameter_values=None):
11+
# First call the gillespy2.Model initializer.
12+
Model.__init__(self, name='Dimerization')
13+
14+
# Define parameters for the rates of creation and dissociation.
15+
k_c = Parameter(name='k_c', expression=0.5)
16+
k_d = Parameter(name='k_d', expression=0.5)
17+
self.add_parameter([k_c, k_d])
18+
19+
# Define variables for the molecular species representing M and D.
20+
m = Species(name='M', initial_value=30)
21+
d = Species(name='D', initial_value=0)
22+
self.add_species([m, d])
23+
24+
# The list of reactants and products for a Reaction object are each a
25+
# Python dictionary in which the dictionary keys are Species objects
26+
# and the values are stoichiometries of the species in the reaction.
27+
r_c = Reaction(name="r_creation", rate=k_c, reactants={m:2}, products={d:1})
28+
r_d = Reaction(name="r_dissociation", rate=k_d, reactants={d:1}, products={m:2})
29+
self.add_reaction([r_c, r_d])
30+
31+
# Set the timespan for the simulation.
32+
self.timespan(numpy.linspace(0, 100, 101))
33+
34+
model = Dimerization()
35+
results = model.run(number_of_trajectories=10)
36+
results.plot()
37+
38+
# Save the figure
39+
plt.savefig("Dimerization.png")
93 KB
Loading
228 KB
Loading
258 KB
Loading

Gillepse_sim/Gillepse.py

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
# 'os' and 'sys' allow us to modify the directory Python searches for source code.
2+
# If you wish to use an installed GillesPy2 package, you do not need to run this cell.
3+
import os
4+
import sys
5+
6+
# If this notebook is being run from within the GillesPy2 source code directory
7+
# we need to let Python know that we want to use it, not the GillesPy2 package.
8+
sys.path.append(os.path.abspath(os.path.join(os.getcwd(), '../')))
9+
10+
# Numpy is used to set the timespan of the Model.
11+
import numpy
12+
13+
# Import the types that'll be needed to define your Model.
14+
from gillespy2.core import (
15+
Model,
16+
Species,
17+
Reaction,
18+
Parameter
19+
)
20+
import matplotlib.pyplot as plt
21+
22+
"""
23+
Your model is declared and configured as a Python class. As such, the name
24+
between `class` and `(Model):` can be of your choosing.
25+
26+
For this example we'll be modeling a Michaelis-Menten enzymatic reaction,
27+
so lets set the name accordingly.
28+
"""
29+
class MichaelisMenten(Model):
30+
def __init__(self, parameter_values=None):
31+
32+
# Intialize the Model with a name of your choosing.
33+
Model.__init__(self, name="Michaelis_Menten")
34+
35+
"""
36+
Parameters are constant values relevant to the system, such as reaction kinetic rates.
37+
38+
- name: A user defined name for reference.
39+
- expression: Some constant value.
40+
"""
41+
42+
rate1 = Parameter(name="rate1", expression=0.0017)
43+
rate2 = Parameter(name="rate2", expression=0.5)
44+
rate3 = Parameter(name="rate3", expression=0.1)
45+
46+
# Add the Parameters to the Model.
47+
self.add_parameter([rate1, rate2, rate3])
48+
49+
"""
50+
Species can be anything that participates in or is produced by a reaction channel.
51+
52+
- name: A user defined name for the species.
53+
- initial_value: A value/population count of species at start of simulation.
54+
"""
55+
56+
A = Species(name="A", initial_value=301)
57+
B = Species(name="B", initial_value=120)
58+
C = Species(name="C", initial_value=0)
59+
D = Species(name="D", initial_value=0)
60+
61+
# Add the Species to the Model.
62+
self.add_species([A, B, C, D])
63+
64+
"""
65+
Reactions are the reaction channels which cause the system to change over time.
66+
67+
- name: A user defined name for the reaction.
68+
- reactants: A dictionary with participant reactants as keys, and consumed per reaction as value.
69+
- products: A dictionary with reaction products as keys, and number formed per reaction as value.
70+
- rate: A parameter rate constant to be applied to the propensity of this reaction firing.
71+
- propensity_function: Can be used instead of rate in order to declare a custom propensity function in string format.
72+
"""
73+
74+
r1 = Reaction(
75+
name="r1",
76+
reactants={A: 1, B: 1},
77+
products={C: 1},
78+
rate=rate1
79+
)
80+
81+
r2 = Reaction(
82+
name="r2",
83+
reactants={C: 1},
84+
products={A: 1, B: 1},
85+
rate=rate2
86+
)
87+
88+
r3 = Reaction(
89+
name="r3",
90+
reactants={C: 1},
91+
products={B: 1, D: 1},
92+
rate=rate3
93+
)
94+
95+
# Add the Reactions to the Model.
96+
self.add_reaction([r1, r2, r3])
97+
98+
# Use NumPy to set the timespan of the Model.
99+
self.timespan(numpy.linspace(0, 100, 101))
100+
101+
# Instantiate your Model.
102+
model = MichaelisMenten()
103+
"""
104+
Run a stochastic simulation on the Model and store the results in the 'results' variable.
105+
GillesPy2 will use the best solver for the Model if no solver is declared (see below).
106+
"""
107+
108+
results = model.run()
109+
110+
"""
111+
These are the possible pure-Python solvers. These may be faster for small (tiny) problem sizes,
112+
but performance can drop off extremely quickly.
113+
"""
114+
115+
from gillespy2.solvers.numpy import (
116+
NumPySSASolver,
117+
ODESolver,
118+
TauLeapingSolver,
119+
TauHybridSolver
120+
)
121+
122+
"""
123+
These are the C++ solvers. These can have slower startup time but will quickly outpace their
124+
Python counterparts for larger problem sets.
125+
126+
Note: The usage of the C++ solver family requires dependencies 'GCC' and 'Make' to be installed
127+
on your system. If neither of these can be found, GillesPy2 will select alternate solvers.
128+
"""
129+
from gillespy2.solvers.cpp import (
130+
SSACSolver,
131+
ODECSolver,
132+
TauLeapingCSolver
133+
)
134+
135+
"""
136+
The following code shows how to run the previously defined Model on a solver of your choosing.
137+
Note: You may use the prior imports as a reference, but you do not need to import them all.
138+
139+
The following code shows two example usages -- one using the C++ SSA solver, the other
140+
using the Python Tau Leaping solver.
141+
"""
142+
143+
# Import the C++ SSA Solver. This will compute highly accurate results, but will be slow for large
144+
# problem sets.
145+
from gillespy2.solvers.cpp import SSACSolver
146+
147+
# Run the previously defined and instantiate Model with an extra argument.
148+
results = model.run(solver=SSACSolver)
149+
150+
# If we instead want to use a Python solver, we can import and use it in the same way.
151+
from gillespy2.solvers.numpy import TauLeapingSolver
152+
153+
results = model.run(solver=TauLeapingSolver)
154+
155+
"""
156+
Plot the results of the simulation.
157+
158+
There are a multitude of arguments that can be set to tweak the behavior and visuals of the plot.
159+
For now though, lets run it with default settings.
160+
"""
161+
162+
results.plot()
163+
plt.savefig("Gillepse.png")
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
[Meeting note](https://www.dropbox.com/s/ebpsm4r1vqf635s/Shih%20Huan%20Summer%20project.pdf?dl=0)
2+
3+
# [Protein aggregation](https://pubmed.ncbi.nlm.nih.gov/21842954/ "Cohen JCP")
4+
### Master equation
5+
$\frac{df(t,j)}{dt}=2m(t)k_+(f(t,j-1)-f(t,j))+2k_{off}(f(t,j+1)-f(t,j))-k_-(j-1)f(t,j))+2k_-\displaystyle{\sum_{i=j+1}^{\infty}}f(t,i)+k_2m(t)^{n2}M(t)\delta_{j,n_2}+k_nm(t)^{n_c}\delta_{j,n_c}$
6+
7+
8+
### Equations for the moments (similar notation as Georg's thesis):
9+
$\frac{dP(t)}{dt}=k_-[M(t)-(2n_c-1)P(t))]+k_2m(t)^{n_2}M(t)+k_nm(t)^{n_c}
10+
\\\coloneqq \alpha_0P(t)+\beta_0(t)M(t)+c(t)$
11+
12+
$\frac{dM(t)}{dt}=2[m(t)k_+-k_{off}-k_-n_c(n_c-1)/2]P(t)+n_2k_2m(t)^{n_2}M(t)+n_ck_nm(t)^{n_c}
13+
\\\coloneqq \alpha_1P(t)+\beta_1(t)M(t)+n_cc(t)$
14+
15+
### Solutions to the master equation
16+
>*Assumption:*
17+
>1. *the monomer concentration is constant.*
18+
>1. *monomer-dependent secondary nucleation is negligible*
19+
20+
$\frac{dP_0(t)}{dt}=k_-[M_0(t)-(2n_c-1)P_0(t))]+k_nm(0)^{n_c}$
21+
22+
$\frac{dM(t)}{dt}=2[m(0)k_+-k_{off}-k_-n_c(n_c-1)/2]P_0(t)+n_ck_nm(0)^{n_c}$
23+
24+
The solution is
25+
26+
$$P_0(t)=C_1e^{\kappa_1t}+C_2e^{\kappa_2t}-\frac{\eta_2}{\xi_2}$$
27+
28+
$$M_0(t)=\frac{C_1\xi_2}{\kappa_1}e^{\kappa_1t}+\frac{C_2\xi_2}{\kappa_2}e^{\kappa_2t}-\frac{\eta_1}{k_-}-\frac{\xi_1\eta_2}{\xi_2}$$
29+
, where
30+
31+
$\kappa_{1,2}=\frac{1}{2}(-k_-\xi_1\pm\sqrt{k^2_-\xi^2_1+4k_-\xi_2})$
32+
33+
$\xi_1=2n_c-1$
34+
35+
$\xi_2=2m(0)k_+-2k_{off}-k_-n_c(n_c-1)$
36+
37+
$\eta_1=k_nm(0)^{n_c}$
38+
39+
$\eta_2=n_ck_nm(0)^{n_c}$
40+
41+
$C_{1,2}=\frac{1}{1-\frac{\kappa_{2,1}}{\kappa_{1,2}}}(\frac{\eta_2}{\xi_2}-\frac{\eta_1\kappa_{2,1}}{k_-\xi_2}-\frac{\xi_1\eta_2\kappa_{2,1}}{\xi_2^2}+P(0)-M(0)\frac{\kappa_{2,1}}{\xi_2})$
42+
43+
>*Here, we make a further assumption:*
44+
>1. *$m(0)k_+>>k_-$*
45+
46+
Hence,
47+
48+
$\xi_2\approx 2[m(0)k_+-k_{off}]$
49+
50+
$\kappa_{1,2}\approx \pm\frac{1}{2}\sqrt{k^2_-\xi^2_1+4k_-\xi_2}\approx \pm\sqrt{k_-\xi_2}=\pm\sqrt{2[m(0)k_+-k_{off}]k_-}\coloneqq\pm\kappa$
51+
52+
$P_0(t)=C_1e^{\kappa t}+C_2e^{-\kappa t}-\frac{n_ck_nm(0)^{n_c}}{2[m(0)k_+-k_{off}]}$
53+
54+
$M_0(t)=\frac{C_12[m(0)k_+-k_{off}]}{\kappa}e^{\kappa t}-\frac{C_22[m(0)k_+-k_{off}]}{\kappa}e^{-\kappa t}-\frac{k_nm(0)^{n_c}}{k_-}$
55+
56+
$C_{1,2}\approx \frac{1}{2}(P(0)\pm\frac{\kappa M(0)}{2[m(0)k_+-k_{off}]}\pm \frac{\kappa k_nm(0)^{n_c}}{2[m(0)k_+-k_{off}]k_-})$
57+
58+
### Analysis of limiting cases
59+
60+
### Analysis of the central moments
61+
62+
#### Mean filament length
63+
$\mu(t)=\frac{M(t)}{P(t)}$
64+
65+
>At early times in *growth* phase, when the monomer concentration is held constant, denoted by a subscript 0,
66+
67+
$\mu_0(t)=\frac{2[k_+m(0)-k_off]}{\kappa}tanh(\frac{\kappa t}{2})$
68+
69+
For long time,
70+
71+
$\mu_0(\infty)=\frac{2[k_+m(0)-k_off]}{\kappa}=\frac{2[k_+m(0)-k_off]}{\sqrt{2[m(0)k_+-k_{off}]k_-}}=\sqrt{\frac{2[m(0)k_+-k_{off}]}{k_-}}$
72+
73+
>When $k_+m(0)>>k_{off}$
74+
75+
$\mu_0(\infty)=\sqrt{\frac{2m(0)k_+}{k_-}}$
76+
77+
> At later times, as the monomer is depleted, the full nonlinear solutions for M(t) and P(t ) show that the length decreases due to fragmentation dominating over [elongation](https://drive.google.com/file/d/1Zsb-pEJCJipKvLfSNm7JHBHA3KU5va7M/view?usp=sharing "time evolution of average length").
78+
79+
80+
### Convert Gillespie to bulk rates
81+
The units of concentation and rate constant in Gillespie are $_gC=(molecules)$ and $_gk=(time)^{-1}(molecule)^{-n}$. There is lack of volume term is unit. he relevant volume should be the cell volume $(10^{-5}m)^3\approx 1pl$.
82+
#### Concentration
83+
To convert Gillespie concentration to real concentration, we do the following calculation
84+
$$C={_g}C*\frac{1}{VN_0}={_g}C*\frac{10^{12}}{6\times10^{23}}$$
85+
86+
According to experiments, concentrations of protein aggregates are in the range of $$10^{-9}M<C<10^{-5}M$$
87+
Hence, $$600<{_gC}<6000000$$
88+
#### Rate constant
89+
Typical $k_+ =3\times10^{6}M^{-1}s^{-1}$, $k_+ = {_g}k*VN_0$.
90+
91+
Hence, $_gk_+=5*10^{-6}s^{-1}(molec.)^{-1}$
92+
93+
$k_{off} =10^{-14}(sec)^{-1}$
94+
95+
Similarly, $_gk_n=5*10^{-16}s^{-1}(molec.)^{-1}$, $_gk_-=10^{-8}s^{-1}=k_-$, $k_2 = 10^4M^{-2}s^{-1}$ is equivalent to $k_- = 10^{-8}s^{-1}$ at $1\mu M$.
96+
97+
### Estimate the simulation time
98+
From the [performance test](https://docs.google.com/spreadsheets/d/1CLMphbjoKtfBzVSIach01P74-mYVi8oHnucBW3zwJ0Y/edit?usp=sharing), to simulate a total fibril length of 20, it requires 100s.
99+
To scale to a longer fibril, the time requires
100+
$$c\times(20)^2=100s$$
101+
$$c\times(10^5)^2=2\times10^9s\approx5.5\times10^5hr\approx63yr$$
102+
for size = 10000 fibril.
103+
104+
----
105+
106+
Simulation conditions:
107+
108+
$_gk_+=5*10^{-8}s^{-1}(molec.)^{-1}$
109+
110+
$_gk_n=5*10^{-16}s^{-1}(molec.)^{-1}$
111+
112+
$_gk_- = 10^{-6}s^{-1}$ at $1\mu M$.
113+
114+
$_gk_{off} =10^{-14}(sec)^{-1}$
115+
116+
$600<{_gC}=m_0<6000000$
117+
118+
Expected average length = $\sqrt{\frac{k_+m}{k_-}}= \sqrt{\frac{0.00000005*100000}{0.000001}}\approx 70$
119+
120+
121+
$t = 10000000s, steps = 100$
122+
123+
Number of trajectories = $50$
124+
125+
Command line:
126+
> python Trial_of_fibril.py -kn 0.0000000000000005 -k+ 0.00000005 -k- 0.000001 -t 10000000 -s 100 -m *variable* -si *variable* -nc 2
127+
128+
Results:
129+
130+
|Test|k+|k-|kn|koff|Monomer|mu|simu_time|Time lapsed(s)|
131+
|--|--|--|--|--|--|--|--|--|
132+
|[1](https://drive.google.com/drive/folders/1tfLI7LaKOBCA7KZ02mXJ8B9CVynnTW5x?usp=sharing)|5e-07|1e-5|5e-12|1e-14|10000|31|10kappa^-1|82|
133+
|[2](https://drive.google.com/drive/folders/1PSzZkhybYjH4cKAqt495gqDukM8HQreZ?usp=sharing)|5e-08|1e-6|5e-13|1e-14|10000|31|10kappa^-1|78|
134+
|[3](https://drive.google.com/drive/folders/1wGQPBlnAReI3hkU3TecssuA7qowlsLqw?usp=sharing)|5e-08|1e-6|5e-15|1e-14|10000|31|100kappa^-1|73|
135+
|[4](https://drive.google.com/drive/folders/1rH8IpQdwlV0gglCmh1GUn4TsqLpJzo4_?usp=sharing)|5e-08|1e-6|5e-16|1e-14|10000|31|100kappa^-1|43|
136+
|[5](https://drive.google.com/drive/folders/1P3tyLJB9chWP5PCb9D1GzxJF3JsdrnwR?usp=sharing)|5e-08|1e-6|5e-16|1e-14|20000|44|10kappa^-1|129|
137+
|[6](https://drive.google.com/drive/folders/12uOOCnkXwTl5msmmuuLSpDyvUGY1meXu?usp=sharing)|5e-08|1e-6|5e-16|1e-14|20000|44|100kappa^-1|176|
138+
139+
|Test|k+|k-|kn|koff|Monomer|mu|simu_time|Time lapsed(s)|
140+
|--|--|--|--|--|--|--|--|--|
141+
|[1](https://drive.google.com/file/d/1UvCaYXt1UvvNvfgn9x7DK_-Y8iwu0iqE/view?usp=sharing)|5e-07|1e-5|5e-12|1e-14|1000|10|30kappa^-1|4|
142+
|[2](https://drive.google.com/file/d/12jvMo0A_zDzqzVCncRZhq9VVLwTPr7be/view?usp=sharing)|5e-07|1e-5|5e-12|1e-14|10000|31|30kappa^-1|82|
143+
|[3](https://drive.google.com/file/d/1GqySia9hsL-M-e9Wd6NKg-eVddrltNCc/view?usp=sharing)|5e-07|1e-5|5e-12|1e-14|20000|44|30kappa^-1|117|
144+
145+
146+
### Fibril length coarse-graining - bulk --> This part does not have a conclusion
147+
148+
### Fibril length coarse-graining - stochastic
149+

0 commit comments

Comments
 (0)