Skip to content

Commit 0052d27

Browse files
Merge pull request #15 from Gaussia/reaction_network
Reaction Network Remake
2 parents 54e1b10 + 6e56cca commit 0052d27

16 files changed

+842
-371
lines changed

README.md

Lines changed: 104 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,109 @@
99
[![DiffEqBiological](http://pkg.julialang.org/badges/DiffEqBiological_0.5.svg)](http://pkg.julialang.org/?pkg=DiffEqBiological)
1010
[![DiffEqBiological](http://pkg.julialang.org/badges/DiffEqBiological_0.6.svg)](http://pkg.julialang.org/?pkg=DiffEqBiological)
1111

12-
This repository holds functionality for easily building systems biological models
13-
for the DifferentialEquations ecosystem. This has tools for developing chemical
14-
reaction networks and simulating them with Gillespie, ODE, SDE, DDE, and DAE
15-
algorithms.
16-
1712
Full documentation is in the
1813
[DifferentialEquations.jl models documentation](http://docs.juliadiffeq.org/latest/models/biological.html)
14+
15+
##The Reaction DSL
16+
17+
The `@reaction_network` DSL allows you to define reaction networks in a more scientific format. Its input is a set of chemical reactions and from them it generates a reaction network object which can be used as input to `ODEProblem`, `SDEProblem` and `JumpProblem` constructors.
18+
19+
The basic syntax is
20+
```julia
21+
rn = @reaction_network rType begin
22+
2.0, X + Y --> XY
23+
1.0, XY --> Z
24+
end
25+
```
26+
where each line corresponds to a chemical reaction. The input `rType` designates the type of this instance (all instances will inherit from the abstract type `AbstractReactionNetwork`).
27+
28+
The DSL can handle several types of arrows, in both backwards and forward direction. If a bi-directional arrow is used two reaction rates must be designated. These two reaction networks are identical
29+
```julia
30+
rn1 = @reaction_network rType begin
31+
2.0, X + Y XY
32+
1.0, XY > Z
33+
1.0, X + Y XY
34+
0.5, XY < Z
35+
end
36+
rn1 = @reaction_network rType begin
37+
(2.0,1.0), X + Y XY
38+
(1.0, 0.5), XY Z
39+
end
40+
```
41+
The empty set can be used for production or degradation and is declared using either `0` or ``. Integers denote the number of each reactant partaking in the reaction.
42+
```julia
43+
rn1 = @reaction_network rType begin
44+
2.0, 2X --> 0
45+
2.0, ∅ --> X
46+
end
47+
```
48+
Multiple reactions can be declared in a single line
49+
```julia
50+
rn = @reaction_network rType begin
51+
2.0, (X,Y) --> 0 #Identical to reactions [2.0, X --> 0] and [2.0, Y --> 0]
52+
(2.0, 1.0), (X,Y) --> 0 #Identical to reactions [2.0, X --> 0] and [1.0, X --> 0]
53+
2.0, (X1,Y1) --> (X2,Y2) #Identical to reactions [2.0, X1 --> X2] and [2.0, Y1 --> Y2]
54+
(2.0,1.0), X + Y XY #Identical to reactions [2.0, X + Y --> XY] and [1.0, XY --> X + Y].
55+
((2.0,1.0),(1.0,2.0)), (X,Y) 0 #Identical to reactions [(2.0,1.0), X ↔ 0] and [(1.0,2.0), Y ↔ 0].
56+
end
57+
```
58+
Parameters can be added to the network by declaring them after the reaction network. Parameters can only exist in the reaction rate and not as a part of the reaction.
59+
```julia
60+
rn = @reaction_network rType begin
61+
(kB, kD), X + Y XY
62+
end kB, kD
63+
p = [2.0, 1.0]
64+
```
65+
The parameter set `p` must be passed to the problem constructor. The parameter values can be changed after the reaction network is defined.
66+
67+
The reaction rate do not need to be constant, but maybe depend on the concentration of the reactants.
68+
```julia
69+
rn = @reaction_network rType begin
70+
(1.0,2XY), X + Y XY
71+
end
72+
```
73+
The hill function `hill(x,v,K,n) = v*(x^n)/(x^n + K^n)` can be used, as well as the michaelis menten function (the hill function with `n = 1`).
74+
```julia
75+
rn = @reaction_network rType begin
76+
(1.0,hill(XY,1.5,2.0,2)), X + Y XY
77+
end
78+
```
79+
By using the `@reaction_func` macro it is possible to define your own functions, which may then be used when creating new reaction networks.
80+
```julia
81+
@reaction_func hill2(x, v, k) = v*x^2/(k^2+x^2)
82+
@reaction_network macro can see.
83+
rn = @reaction_network rType begin
84+
(1.0,hill2(XY,1.5,2.0)), X + Y XY
85+
end
86+
```
87+
88+
Reaction rates are automatically adjusted according mass kinetics, including taking special account of higher order terms like `2X -->`. This can be disabled using any non-filled arrow (`⇐, ⟽, ⇒, ⟾, ⇔, ⟺`), in which case the reaction rate will be exactly as input. E.g the two reactions in
89+
rn = @reaction_network rType begin
90+
2.0, X + Y --> XY
91+
2.0*X*Y X + Y ⟾ XY
92+
end
93+
will both have reaction rate equal to 2[X][Y].
94+
95+
Once a reaction network has been created it can be passed as input to either one of the `ODEProblem`, `SDEProblem` or `JumpProblem` constructors.
96+
```julia
97+
probODE = ODEProblem(rn, args...; kwargs...)
98+
probSDE = SDEProblem(rn, args...; kwargs...)
99+
probJump = JumpProblem(prob,aggregator::Direct,rn)
100+
```
101+
the output problems may then be used as normal input to the solvers of the `DifferentialEquations` package.
102+
103+
The noise used by the SDEProblem will correspond to the Chemical Langevin Equations. However it is possible to scale the amount of noise be declaring a noise parameter. This will be done after declaring the type but before the network.
104+
```julia
105+
rn = @reaction_network \eta begin
106+
2.0, X + Y XY
107+
end
108+
p = [0.5]
109+
```
110+
The noise term is then added as an additional parameter to the network (by default the last parameter in the parameter array, unless also declared after the reaction network among the other parameters). By reducing (or increasing) the noise term the amount stochastic fluctuations in the system can be reduced (or increased).
111+
112+
It is possible to access expressions corresponding to the functions determining the deterministic and stochastic development of the network using.
113+
```julia
114+
f_expr = rn.f_func
115+
g_expr = rn.g_func
116+
```
117+
This can e.g. be used to generate LaTeX code corresponding to the system.

REQUIRE

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
julia 0.6
22
DiffEqJump 1.0.0
3-
DiffEqBase 3.0.0
3+
DiffEqBase 3.4.0
44
Compat 0.17.0
55
DataStructures 0.4.6
6+
Reexport 0.1.0
7+
SymEngine 0.3.0
8+
MacroTools 0.4.0

src/DiffEqBiological.jl

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,27 @@ __precompile__()
22

33
module DiffEqBiological
44

5+
using Reexport
6+
using DiffEqBase
57
using DiffEqJump
8+
using SymEngine
9+
using MacroTools
10+
using DataStructures
11+
@reexport using DiffEqJump
612

713
using Compat
8-
abstract type AbstractReaction end
914

10-
import DataStructures: OrderedDict
11-
12-
include("reactions.jl")
15+
include("reaction_network.jl")
16+
include("maketype.jl")
1317
include("problem.jl")
1418

15-
export GillespieProblem
16-
17-
export VariableRateReaction, Reaction, ReactionSet, build_jumps_from_reaction
19+
export @reaction_network, @reaction_func
20+
export ODEProblem, SDEProblem, JumpProblem
1821

19-
export @reaction_network
22+
Reaction(args...) = error("""
23+
The old Reaction DSL is deprecated for a new
24+
macro-based DSL which supports parameters, regulation,
25+
etc. Please see the documentation for details
26+
""")
2027

2128
end # module

src/maketype.jl

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
function maketype(name,
2+
f,
3+
f_func,
4+
f_symfuncs,
5+
g,
6+
g_func,
7+
jumps,
8+
jump_rate_expr,
9+
jump_affect_expr,
10+
p_matrix,
11+
syms;
12+
params = Symbol[],
13+
pfuncs=Vector{Expr}(0),
14+
symjac=Matrix{SymEngine.Basic}(0,0),
15+
)
16+
17+
typeex = :(mutable struct $name <: AbstractReactionNetwork
18+
f::Function
19+
f_func::Vector{Expr}
20+
f_symfuncs::Matrix{SymEngine.Basic}
21+
g::Function
22+
g_func::Vector{Any}
23+
jumps::Tuple{ConstantRateJump,Vararg{ConstantRateJump}}
24+
jump_rate_expr::Tuple{Any,Vararg{Any}}
25+
jump_affect_expr::Tuple{Vector{Expr},Vararg{Vector{Expr}}}
26+
p_matrix::Array{Float64,2}
27+
syms::Vector{Symbol}
28+
params::Vector{Symbol}
29+
symjac::Matrix{SymEngine.Basic}
30+
end)
31+
# Make the default constructor
32+
constructorex = :($(name)(;
33+
$(Expr(:kw,:f,f)),
34+
$(Expr(:kw,:f_func,f_func)),
35+
$(Expr(:kw,:g,g)),
36+
$(Expr(:kw,:g_func,g_func)),
37+
$(Expr(:kw,:jumps,jumps)),
38+
$(Expr(:kw,:jump_rate_expr,jump_rate_expr)),
39+
$(Expr(:kw,:jump_affect_expr,jump_affect_expr)),
40+
$(Expr(:kw,:p_matrix,p_matrix)),
41+
$(Expr(:kw,:f_symfuncs,f_symfuncs)),
42+
$(Expr(:kw,:syms,syms)),
43+
$(Expr(:kw,:params,params)),
44+
$(Expr(:kw,:symjac,symjac))) =
45+
$(name)(
46+
f,
47+
f_func,
48+
f_symfuncs,
49+
g,
50+
g_func,
51+
jumps,
52+
jump_rate_expr,
53+
jump_affect_expr,
54+
p_matrix,
55+
syms,
56+
params,
57+
symjac,
58+
)) |> esc
59+
60+
#f_funcs,symfuncs,pfuncs,syms,symjac) |> esc
61+
62+
# Make the type instance using the default constructor
63+
typeex,constructorex
64+
end

src/problem.jl

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1-
GillespieProblem(prob,aggregator::AbstractAggregatorAlgorithm,
2-
rs::AbstractReaction...;kwargs...) =
3-
JumpProblem(prob,aggregator,build_jumps_from_reaction(rs...);kwargs...)
4-
5-
GillespieProblem(prob,aggregator::AbstractAggregatorAlgorithm,
6-
r::ReactionSet;kwargs...) =
7-
JumpProblem(prob,aggregator,build_jumps_from_reaction(r);kwargs...)
1+
### ODEProblem ###
2+
DiffEqBase.ODEProblem(rn::AbstractReactionNetwork, args...; kwargs...) =
3+
ODEProblem(rn.f, args...; kwargs...)
4+
5+
### SDEProblem ###
6+
DiffEqBase.SDEProblem(rn::AbstractReactionNetwork, args...; kwargs...) =
7+
SDEProblem(rn.f,rn.g, args...;noise_rate_prototype=rn.p_matrix, kwargs...)
8+
9+
### JumpProblem ###
10+
DiffEqJump.JumpProblem(prob,aggregator::Direct,rn::AbstractReactionNetwork) =
11+
JumpProblem(prob,aggregator::Direct,rn.jumps...)

0 commit comments

Comments
 (0)