Skip to content

Commit b84d285

Browse files
committed
rebase
1 parent 00da398 commit b84d285

File tree

1 file changed

+37
-30
lines changed

1 file changed

+37
-30
lines changed

docs/src/catalyst_functionality/example_networks/basic_CRN_library.md renamed to docs/src/model_creation/example/basic_CRN_library.md

Lines changed: 37 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -9,25 +9,26 @@ bd_process = @reaction_network begin
99
(p,d), ∅ <--> X
1010
end
1111
```
12-
Next, we define simulation conditions. Note that the initial condition is integer-valued (required to perform jump simulations).
12+
Next, we define simulation conditions. Note that the initial condition is integer-valued (more natural than decimal numbers for jump simulations).
1313
```@example crn_library_birth_death
1414
u0 = [:X => 1]
1515
tspan = (0.0, 10.0)
16-
ps = [:p => 1, :d => 0.2]
16+
ps = [:p => 1.0, :d => 0.2]
1717
nothing # hide
1818
```
1919
We can now simulate our model using all three interpretations. First, we perform a reaction rate equation-based ODE simulation:
2020
```@example crn_library_birth_death
2121
using OrdinaryDiffEq
2222
oprob = ODEProblem(bd_process, u0, tspan, ps)
23-
osol = solve(oprob, Tsit5())
23+
osol = solve(oprob)
2424
nothing # hide
2525
```
2626
Next, a chemical Langevin equation-based SDE simulation:
2727
```@example crn_library_birth_death
2828
using StochasticDiffEq
2929
sprob = SDEProblem(bd_process, u0, tspan, ps)
30-
ssol = solve(sprob, ImplicitEM())
30+
ssol = solve(sprob, STrapezoid())
31+
ssol = solve(sprob, STrapezoid(); seed = 12) # hide
3132
nothing # hide
3233
```
3334
Next, a stochastic chemical kinetics-based jump simulation:
@@ -36,6 +37,7 @@ using JumpProcesses
3637
dprob = DiscreteProblem(bd_process, u0, tspan, ps)
3738
jprob = JumpProblem(bd_process, dprob, Direct())
3839
jsol = solve(jprob, SSAStepper())
40+
jsol = solve(jprob, SSAStepper(); seed = 12) # hide
3941
nothing # hide
4042
```
4143
Finally, we plot the results:
@@ -60,11 +62,12 @@ tspan = (0.0, 1.0)
6062
ps = [:k1 => 2.0, :k2 => 3.0]
6163
6264
oprob = ODEProblem(two_state_model, u0, tspan, ps)
63-
osol = solve(oprob, Tsit5())
65+
osol = solve(oprob)
6466
oplt = plot(osol; title = "Reaction rate equation (ODE)")
6567
6668
sprob = SDEProblem(two_state_model, u0, tspan, ps)
67-
ssol = solve(sprob, ImplicitEM())
69+
ssol = solve(sprob, STrapezoid())
70+
ssol = solve(sprob, STrapezoid(); seed = 12) # hide
6871
splt = plot(ssol; title = "Chemical Langevin equation (SDE)")
6972
7073
plot(oplt, splt; lw = 3, size = (800,550), layout = (2,1))
@@ -74,8 +77,9 @@ What is interesting about this model is that it has a *conserved quantity*, wher
7477
@unpack X₁, X₂ = two_state_model
7578
oplt = plot(osol; idxs = X₁ + X₂, title = "Reaction rate equation (ODE)")
7679
splt = plot(ssol; idxs = X₁ + X₂, title = "Chemical Langevin equation (SDE)")
77-
plot(oplt, splt; lw = 3, size = (800,550), layout = (2,1))
80+
plot(oplt, splt; lw = 3, ylimit = (99,101), size = (800,450), layout = (2,1))
7881
```
82+
Catalyst has special methods for working with conserved quantities, which are described [here](@ref ref).
7983

8084
## [Michaelis-Menten enzyme kinetics](@id basic_CRN_library_mm)
8185
[Michaelis-Menten enzyme kinetics](https://en.wikipedia.org/wiki/Michaelis%E2%80%93Menten_kinetics) is a simple description of an enzyme ($E$) transforming a substrate ($S$) into a product ($P$). Under certain assumptions, it can be simplified to a single function (a Michaelis-Menten function) and used as a reaction rate. Here we instead present the full system model:
@@ -95,16 +99,18 @@ ps = [:kB => 0.00166, :kD => 0.0001, :kP => 0.1]
9599
96100
using OrdinaryDiffEq
97101
oprob = ODEProblem(mm_system, u0, tspan, ps)
98-
osol = solve(oprob, Tsit5())
102+
osol = solve(oprob)
99103
100104
using StochasticDiffEq
101105
sprob = SDEProblem(mm_system, u0, tspan, ps)
102-
ssol = solve(sprob, ImplicitEM())
106+
ssol = solve(sprob, STrapezoid())
107+
ssol = solve(sprob, STrapezoid(); seed = 12) # hide
103108
104109
using JumpProcesses
105110
dprob = DiscreteProblem(mm_system, u0, tspan, ps)
106111
jprob = JumpProblem(mm_system, dprob, Direct())
107112
jsol = solve(jprob, SSAStepper())
113+
jsol = solve(jprob, SSAStepper(); seed = 12) # hide
108114
109115
using Plots
110116
oplt = plot(osol; title = "Reaction rate equation (ODE)")
@@ -113,6 +119,7 @@ jplt = plot(jsol; title = "Stochastic chemical kinetics (Jump)")
113119
plot(oplt, splt, jplt; lw = 2, size=(800,800), layout = (3,1))
114120
plot!(bottom_margin = 3Plots.Measures.mm) # hide
115121
```
122+
Note that, due to the large amounts of the species involved, teh stochastic trajectories are very similar to the deterministic one.
116123

117124
## [SIR infection model](@id basic_CRN_library_sir)
118125
The [SIR model](https://en.wikipedia.org/wiki/Compartmental_models_in_epidemiology#The_SIR_model) is the simplest model of the spread of an infectious disease. While the real system is very different from the chemical and cellular processes typically modelled with CRNs, it (and several other epidemiological systems) can be modelled using the same CRN formalism. The SIR model consists of three species: susceptible ($S$), infected ($I$), and removed ($R$) individuals, and two reaction events: infection and recovery.
@@ -132,7 +139,7 @@ ps = [:α => 0.001, :β => 0.01]
132139
133140
# Solve ODEs.
134141
oprob = ODEProblem(sir_model, u0, tspan, ps)
135-
osol = solve(oprob, Tsit5())
142+
osol = solve(oprob)
136143
plot(osol; title = "Reaction rate equation (ODE)", size=(800,350))
137144
```
138145
Next, we perform 3 different Jump simulations. Note that for the stochastic model, the occurrence of an outbreak is not certain. Rather, there is a possibility that it fizzles out without a noteworthy peak.
@@ -177,7 +184,7 @@ ps = [:k₁ => 5.0, :k₂ => 5.0, :k₃ => 100.0]
177184
178185
# solve ODEs
179186
oprob = ODEProblem(cc_system, u0, tspan, ps)
180-
osol = solve(oprob, Tsit5())
187+
osol = solve(oprob)
181188
182189
plt1 = plot(osol; idxs = [:S₁, :S₂, :P], title = "Substrate and product dynamics")
183190
plt2 = plot(osol; idxs = [:C, :S₁C, :CP], title = "Catalyst and intermediaries dynamics")
@@ -205,15 +212,15 @@ ps = [:k1 => 8.0, :k2 => 2.0, :k3 => 1.0, :k4 => 1.5]
205212
206213
oprob1 = ODEProblem(wilhelm_model, u0_1, tspan, ps)
207214
oprob2 = ODEProblem(wilhelm_model, u0_2, tspan, ps)
208-
osol1 = solve(oprob1, Tsit5())
209-
osol2 = solve(oprob2, Tsit5())
215+
osol1 = solve(oprob1)
216+
osol2 = solve(oprob2)
210217
plot(osol1; lw = 4, idxs = :X, label = "X(0) = 1.5")
211218
plot!(osol2; lw = 4, idxs = :X, label = "X(0) = 2.5", yguide = "X", size = (800,350))
212219
plot!(bottom_margin = 3Plots.Measures.mm) # hide
213220
```
214221

215222
## [Simple self-activation loop](@id basic_CRN_library_self_activation)
216-
The simplest self-activation loop consists of a single species (here called $X$) which activates its own production. If its production rate is modelled with a hill function with $n>1$, the system may exhibit bistability.
223+
The simplest self-activation loop consists of a single species (here called $X$) which activates its own production. If its production rate is modelled as a [Hill function](https://en.wikipedia.org/wiki/Hill_equation_(biochemistry)) with $n>1$, the system may exhibit bistability.
217224
```@example crn_library_self_activation
218225
using Catalyst
219226
sa_loop = @reaction_network begin
@@ -231,12 +238,12 @@ tspan = (0.0, 1000.0)
231238
ps = [:v₀ => 0.1, :v => 2.0, :K => 10.0, :n => 2, :d => 0.1]
232239
233240
oprob = ODEProblem(sa_loop, u0, tspan, ps)
234-
osol = solve(oprob, Tsit5())
241+
osol = solve(oprob)
235242
236243
dprob = DiscreteProblem(sa_loop, u0, tspan, ps)
237244
jprob = JumpProblem(sa_loop, dprob, Direct())
238245
jsol = solve(jprob, SSAStepper())
239-
jsol = solve(jprob, SSAStepper(); seed = 2091) # hide
246+
jsol = solve(jprob, SSAStepper(); seed = 12) # hide
240247
241248
plot(osol; lw = 3, label = "Reaction rate equation (ODE)")
242249
plot!(jsol; lw = 3, label = "Stochastic chemical kinetics (Jump)", yguide = "X", size = (800,350))
@@ -254,7 +261,7 @@ brusselator = @reaction_network begin
254261
1, X --> ∅
255262
end
256263
```
257-
It is generally known to (for reaction rate equation-based ODE simulations) produce oscillations when $B > 1 + A^2$. However, this result is based on models generated when *combinatorial adjustment of rates is not performed*. Since Catalyst automatically perform these adjustments, and one reaction contains a stoichiometric constant $>1$, the threshold will be different. Here, we trial two different values of $B$. In both cases, $B < 1 + A^2$, however, in the second case the system can generate oscillations.
264+
It is generally known to (for reaction rate equation-based ODE simulations) produce oscillations when $B > 1 + A^2$. However, this result is based on models generated when *combinatorial adjustment of rates is not performed*. Since Catalyst [automatically perform these adjustments](@ref ref), and one reaction contains a stoichiometric constant $>1$, the threshold will be different. Here, we trial two different values of $B$. In both cases, $B < 1 + A^2$, however, in the second case the system can generate oscillations.
258265
```@example crn_library_brusselator
259266
using OrdinaryDiffEq, Plots
260267
u0 = [:X => 1.0, :Y => 1.0]
@@ -264,16 +271,16 @@ ps2 = [:A => 1.0, :B => 1.8]
264271
265272
oprob1 = ODEProblem(brusselator, u0, tspan, ps1)
266273
oprob2 = ODEProblem(brusselator, u0, tspan, ps2)
267-
osol1 = solve(oprob1, Rodas5P())
268-
osol2 = solve(oprob2, Rodas5P())
274+
osol1 = solve(oprob1)
275+
osol2 = solve(oprob2)
269276
oplt1 = plot(osol1; title = "No Oscillation")
270277
oplt2 = plot(osol2; title = "Oscillation")
271278
272279
plot(oplt1, oplt2; lw = 3, size = (800,600), layout = (2,1))
273280
```
274281

275-
## [The repressilator](@id basic_CRN_library_)
276-
The repressilator was introduced in [*Elowitz & Leibler (2000)*](https://www.nature.com/articles/35002125) as a simple system that can generate oscillations (most notably, they demonstrated this both in a model and in a synthetic in vivo implementation in *Escherichia col*). It consists of three genes, repressing each other in a cycle. Here, we will implement it using three species ($X$, $Y$, and $Z$) whose production rates are (repressing) [Hill functions](https://en.wikipedia.org/wiki/Hill_equation_(biochemistry)).
282+
## [The Repressilator](@id basic_CRN_library_)
283+
The Repressilator was introduced in [*Elowitz & Leibler (2000)*](https://www.nature.com/articles/35002125) as a simple system that can generate oscillations (most notably, they demonstrated this both in a model and in a synthetic in vivo implementation in *Escherichia col*). It consists of three genes, repressing each other in a cycle. Here, we will implement it using three species ($X$, $Y$, and $Z$) whose production rates are (repressing) [Hill functions](https://en.wikipedia.org/wiki/Hill_equation_(biochemistry)).
277284
```@example crn_library_brusselator
278285
using Catalyst
279286
repressilator = @reaction_network begin
@@ -283,7 +290,7 @@ repressilator = @reaction_network begin
283290
d, (X, Y, Z) --> ∅
284291
end
285292
```
286-
Whether it oscillates or not depends on its parameter values. Here, we will perform deterministic (ODE) simulations for two different values of $K$, showing that it oscillates for one value and not the other one. Next, we will perform stochastic (SDE) simulations for both $K$ values, showing that the stochastic model can sustain oscillations in both cases. This is an example of the phenomena of *noise-induced oscillation*.
293+
Whether the Repressilator oscillates or not depends on its parameter values. Here, we will perform deterministic (ODE) simulations for two different values of $K$, showing that it oscillates for one value and not the other one. Next, we will perform stochastic (SDE) simulations for both $K$ values, showing that the stochastic model can sustain oscillations in both cases. This is an example of the phenomena of *noise-induced oscillation*.
287294
```@example crn_library_brusselator
288295
using OrdinaryDiffEq, StochasticDiffEq, Plots
289296
u0 = [:X => 50.0, :Y => 15.0, :Z => 15.0]
@@ -293,17 +300,17 @@ ps2 = [:v => 10.0, :K => 50.0, :n => 3, :d => 0.1]
293300
294301
oprob1 = ODEProblem(repressilator, u0, tspan, ps1)
295302
oprob2 = ODEProblem(repressilator, u0, tspan, ps2)
296-
osol1 = solve(oprob1, Tsit5())
297-
osol2 = solve(oprob2, Tsit5())
303+
osol1 = solve(oprob1)
304+
osol2 = solve(oprob2)
298305
oplt1 = plot(osol1; title = "Oscillation (ODE, K = 20)")
299306
oplt2 = plot(osol2; title = "No oscillation (ODE, K = 50)")
300307
301308
sprob1 = SDEProblem(repressilator, u0, tspan, ps1)
302309
sprob2 = SDEProblem(repressilator, u0, tspan, ps2)
303-
ssol1 = solve(sprob1, ImplicitEM())
304-
ssol2 = solve(sprob2, ImplicitEM())
305-
ssol1 = solve(sprob1, ImplicitEM(); seed = 1) # hide
306-
ssol2 = solve(sprob2, ImplicitEM(); seed = 100) # hide
310+
ssol1 = solve(sprob1, STrapezoid())
311+
ssol2 = solve(sprob2, STrapezoid())
312+
ssol1 = solve(sprob1, STrapezoid(); seed = 1) # hide
313+
ssol2 = solve(sprob2, STrapezoid(); seed = 100) # hide
307314
splt1 = plot(ssol1; title = "Oscillation (SDE, K = 20)")
308315
splt2 = plot(ssol2; title = "Oscillation (SDE, K = 50)")
309316
@@ -324,14 +331,14 @@ wr_model = @reaction_network begin
324331
k7, Z --> ∅
325332
end
326333
```
327-
Here we first simulate the model for a single initial condition, showing in both time-state space and phase space how it reaches a [*strange attractor*](https://www.dynamicmath.xyz/strange-attractors/).
334+
Here we simulate the model for a single initial condition, showing both time-state space and phase space how it reaches a [*strange attractor*](https://www.dynamicmath.xyz/strange-attractors/).
328335
```@example crn_library_chaos
329336
using OrdinaryDiffEq, Plots
330337
u0 = [:X => 1.5, :Y => 1.5, :Z => 1.5]
331338
tspan = (0.0, 50.0)
332339
p = [:k1 => 2.1, :k2 => 0.7, :k3 => 2.9, :k4 => 1.1, :k5 => 1.0, :k6 => 0.5, :k7 => 2.7]
333340
oprob = ODEProblem(wr_model, u0, tspan, p)
334-
sol = solve(oprob, Rodas5P())
341+
sol = solve(oprob)
335342
336343
plt1 = plot(sol; title = "Time-state space")
337344
plt2 = plot(sol; idxs = (:X, :Y, :Z), title = "Phase space")

0 commit comments

Comments
 (0)