@@ -92,6 +92,14 @@ function Reaction(rate, subs, prods; kwargs...)
92
92
Reaction (rate, subs, prods, sstoich, pstoich; kwargs... )
93
93
end
94
94
95
+ function namespace_equation (rx:: Reaction , name, iv)
96
+ Reaction (namespace_expr (rx. rate, name, iv),
97
+ namespace_expr (rx. substrates, name, iv),
98
+ namespace_expr (rx. products, name, iv),
99
+ rx. substoich, rx. prodstoich,
100
+ [namespace_expr (n[1 ],name,iv) => n[2 ] for n in rx. netstoich], rx. only_use_rate)
101
+ end
102
+
95
103
# calculates the net stoichiometry of a reaction as a vector of pairs (sub,substoich)
96
104
function get_netstoich (subs, prods, sstoich, pstoich)
97
105
# stoichiometry as a Dictionary
@@ -134,7 +142,7 @@ struct ReactionSystem <: AbstractSystem
134
142
""" The name of the system"""
135
143
name:: Symbol
136
144
""" systems: The internal systems"""
137
- systems:: Vector{ReactionSystem}
145
+ systems:: Vector
138
146
139
147
function ReactionSystem (eqs, iv, states, ps, observed, name, systems)
140
148
new (eqs, value (iv), value .(states), value .(ps), observed, name, systems)
@@ -143,13 +151,31 @@ end
143
151
144
152
function ReactionSystem (eqs, iv, species, params;
145
153
observed = [],
146
- systems = ReactionSystem [],
154
+ systems = [],
147
155
name = gensym (:ReactionSystem ))
148
156
149
- isempty (species) && error (" ReactionSystems require at least one species." )
157
+ # isempty(species) && error("ReactionSystems require at least one species.")
150
158
ReactionSystem (eqs, iv, species, params, observed, name, systems)
151
159
end
152
160
161
+ function ReactionSystem (iv; kwargs... )
162
+ ReactionSystem (Reaction[], iv, [], []; kwargs... )
163
+ end
164
+
165
+ function equations (sys:: ModelingToolkit.ReactionSystem )
166
+ eqs = get_eqs (sys)
167
+ systems = get_systems (sys)
168
+ if isempty (systems)
169
+ return eqs
170
+ else
171
+ eqs = [eqs;
172
+ reduce (vcat,
173
+ namespace_equations .(get_systems (sys));
174
+ init= [])]
175
+ return eqs
176
+ end
177
+ end
178
+
153
179
"""
154
180
oderatelaw(rx; combinatoric_ratelaw=true)
155
181
@@ -187,11 +213,11 @@ function oderatelaw(rx; combinatoric_ratelaw=true)
187
213
end
188
214
189
215
function assemble_oderhs (rs; combinatoric_ratelaws= true )
190
- sts = states (rs)
216
+ sts = get_states (rs)
191
217
species_to_idx = Dict ((x => i for (i,x) in enumerate (sts)))
192
218
rhsvec = Any[0 for i in eachindex (sts)]
193
219
194
- for rx in equations (rs)
220
+ for rx in get_eqs (rs)
195
221
rl = oderatelaw (rx; combinatoric_ratelaw= combinatoric_ratelaws)
196
222
for (spec,stoich) in rx. netstoich
197
223
i = species_to_idx[spec]
@@ -212,16 +238,16 @@ function assemble_drift(rs; combinatoric_ratelaws=true, as_odes=true)
212
238
rhsvec = assemble_oderhs (rs; combinatoric_ratelaws= combinatoric_ratelaws)
213
239
if as_odes
214
240
D = Differential (get_iv (rs))
215
- eqs = [Equation (D (x),rhs) for (x,rhs) in zip (states (rs),rhsvec)]
241
+ eqs = [Equation (D (x),rhs) for (x,rhs) in zip (get_states (rs),rhsvec) if ( ! _iszero (rhs) )]
216
242
else
217
- eqs = [Equation (0 ,rhs) for rhs in rhsvec]
243
+ eqs = [Equation (0 ,rhs) for rhs in rhsvec if ( ! _iszero (rhs)) ]
218
244
end
219
245
eqs
220
246
end
221
247
222
248
function assemble_diffusion (rs, noise_scaling; combinatoric_ratelaws= true )
223
- sts = states (rs)
224
- eqs = Matrix {Any} (undef, length (sts), length (equations (rs)))
249
+ sts = get_states (rs)
250
+ eqs = Matrix {Any} (undef, length (sts), length (get_eqs (rs)))
225
251
eqs .= 0
226
252
species_to_idx = Dict ((x => i for (i,x) in enumerate (sts)))
227
253
@@ -302,7 +328,7 @@ explicitly on the independent variable (usually time).
302
328
"""
303
329
function ismassaction (rx, rs; rxvars = get_variables (rx. rate),
304
330
haveivdep = any (var -> isequal (get_iv (rs),var), rxvars),
305
- stateset = Set (states (rs)))
331
+ stateset = Set (get_states (rs)))
306
332
# if no dependencies must be zero order
307
333
(length (rxvars)== 0 ) && return true
308
334
haveivdep && return false
331
357
332
358
function assemble_jumps (rs; combinatoric_ratelaws= true )
333
359
meqs = MassActionJump[]; ceqs = ConstantRateJump[]; veqs = VariableRateJump[]
334
- stateset = Set (states (rs))
360
+ stateset = Set (get_states (rs))
335
361
# rates = []; rstoich = []; nstoich = []
336
362
rxvars = []
337
363
ivname = nameof (get_iv (rs))
@@ -378,10 +404,11 @@ law, i.e. for `2S -> 0` at rate `k` the ratelaw would be `k*S^2/2!`. If
378
404
`combinatoric_ratelaws=false` then the ratelaw is `k*S^2`, i.e. the scaling factor is
379
405
ignored.
380
406
"""
381
- function Base. convert (:: Type{<:ODESystem} , rs:: ReactionSystem ; combinatoric_ratelaws= true )
382
- eqs = assemble_drift (rs; combinatoric_ratelaws= combinatoric_ratelaws)
383
- ODESystem (eqs,get_iv (rs),states (rs),get_ps (rs),name= nameof (rs),
384
- systems= convert .(ODESystem,get_systems (rs)))
407
+ function Base. convert (:: Type{<:ODESystem} , rs:: ReactionSystem ;
408
+ name= nameof (rs), combinatoric_ratelaws= true , kwargs... )
409
+ eqs = assemble_drift (rs; combinatoric_ratelaws= combinatoric_ratelaws)
410
+ systems = map (sys -> (sys isa ODESystem) ? sys : convert (ODESystem, sys), get_systems (rs))
411
+ ODESystem (eqs, get_iv (rs), get_states (rs), get_ps (rs), name= name, systems= systems)
385
412
end
386
413
387
414
"""
@@ -397,9 +424,11 @@ law, i.e. for `2S -> 0` at rate `k` the ratelaw would be `k*S^2/2!`. If
397
424
`combinatoric_ratelaws=false` then the ratelaw is `k*S^2`, i.e. the scaling factor is
398
425
ignored.
399
426
"""
400
- function Base. convert (:: Type{<:NonlinearSystem} ,rs:: ReactionSystem ; combinatoric_ratelaws= true )
401
- eqs = assemble_drift (rs; combinatoric_ratelaws= combinatoric_ratelaws, as_odes= false )
402
- NonlinearSystem (eqs,states (rs),get_ps (rs),name= nameof (rs),systems= convert .(NonlinearSystem,get_systems (rs)))
427
+ function Base. convert (:: Type{<:NonlinearSystem} ,rs:: ReactionSystem ;
428
+ name= nameof (rs), combinatoric_ratelaws= true , kwargs... )
429
+ eqs = assemble_drift (rs; combinatoric_ratelaws= combinatoric_ratelaws, as_odes= false )
430
+ systems = convert .(NonlinearSystem, get_systems (rs))
431
+ NonlinearSystem (eqs, get_states (rs), get_ps (rs), name= name, systems= systems)
403
432
end
404
433
405
434
"""
@@ -423,7 +452,8 @@ Finally, a `Vector{Operation}` can be provided (the length must be equal to the
423
452
Here the noise for each reaction is scaled by the corresponding parameter in the input vector.
424
453
This input may contain repeat parameters.
425
454
"""
426
- function Base. convert (:: Type{<:SDESystem} ,rs:: ReactionSystem , combinatoric_ratelaws= true ; noise_scaling= nothing )
455
+ function Base. convert (:: Type{<:SDESystem} , rs:: ReactionSystem ;
456
+ noise_scaling= nothing , name= nameof (rs), combinatoric_ratelaws= true , kwargs... )
427
457
428
458
if noise_scaling isa Vector
429
459
(length (noise_scaling)!= length (equations (rs))) &&
@@ -434,19 +464,14 @@ function Base.convert(::Type{<:SDESystem},rs::ReactionSystem, combinatoric_ratel
434
464
noise_scaling = fill (value (noise_scaling),length (equations (rs)))
435
465
end
436
466
437
- eqs = assemble_drift (rs; combinatoric_ratelaws= combinatoric_ratelaws)
438
-
467
+ eqs = assemble_drift (rs; combinatoric_ratelaws= combinatoric_ratelaws)
439
468
noiseeqs = assemble_diffusion (rs,noise_scaling;
440
469
combinatoric_ratelaws= combinatoric_ratelaws)
441
-
442
- SDESystem (eqs,
443
- noiseeqs,
444
- get_iv (rs),
445
- states (rs),
446
- (noise_scaling=== nothing ) ?
447
- get_ps (rs) :
448
- union (get_ps (rs),toparam .(noise_scaling)),
449
- name= nameof (rs),systems= convert .(SDESystem,get_systems (rs)))
470
+ systems = convert .(SDESystem, get_systems (rs))
471
+ SDESystem (eqs, noiseeqs, get_iv (rs), get_states (rs),
472
+ (noise_scaling=== nothing ) ? get_ps (rs) : union (get_ps (rs), toparam .(noise_scaling)),
473
+ name= name,
474
+ systems= systems)
450
475
end
451
476
452
477
"""
@@ -462,10 +487,11 @@ Notes:
462
487
the ratelaw is `k*S*(S-1)`, i.e. the rate law is not normalized by the scaling
463
488
factor.
464
489
"""
465
- function Base. convert (:: Type{<:JumpSystem} ,rs:: ReactionSystem ; combinatoric_ratelaws= true )
466
- eqs = assemble_jumps (rs; combinatoric_ratelaws= combinatoric_ratelaws)
467
- JumpSystem (eqs,get_iv (rs),states (rs),get_ps (rs),name= nameof (rs),
468
- systems= convert .(JumpSystem,get_systems (rs)))
490
+ function Base. convert (:: Type{<:JumpSystem} ,rs:: ReactionSystem ;
491
+ name= nameof (rs), combinatoric_ratelaws= true , kwargs... )
492
+ eqs = assemble_jumps (rs; combinatoric_ratelaws= combinatoric_ratelaws)
493
+ systems = convert .(JumpSystem, get_systems (rs))
494
+ JumpSystem (eqs, get_iv (rs), get_states (rs), get_ps (rs), name= name, systems= systems)
469
495
end
470
496
471
497
@@ -474,35 +500,35 @@ end
474
500
475
501
# ODEProblem from AbstractReactionNetwork
476
502
function DiffEqBase. ODEProblem (rs:: ReactionSystem , u0, tspan, p= DiffEqBase. NullParameters (), args... ; kwargs... )
477
- return ODEProblem (convert (ODESystem,rs),u0,tspan,p, args... ; kwargs... )
503
+ return ODEProblem (convert (ODESystem,rs; kwargs ... ),u0,tspan,p, args... ; kwargs... )
478
504
end
479
505
480
506
# NonlinearProblem from AbstractReactionNetwork
481
507
function DiffEqBase. NonlinearProblem (rs:: ReactionSystem , u0, p= DiffEqBase. NullParameters (), args... ; kwargs... )
482
- return NonlinearProblem (convert (NonlinearSystem,rs), u0, p, args... ; kwargs... )
508
+ return NonlinearProblem (convert (NonlinearSystem,rs; kwargs ... ), u0, p, args... ; kwargs... )
483
509
end
484
510
485
511
486
512
# SDEProblem from AbstractReactionNetwork
487
513
function DiffEqBase. SDEProblem (rs:: ReactionSystem , u0, tspan, p= DiffEqBase. NullParameters (), args... ; noise_scaling= nothing , kwargs... )
488
- sde_sys = convert (SDESystem,rs, noise_scaling= noise_scaling)
489
- p_matrix = zeros (length (states (rs)), length (equations (rs)))
514
+ sde_sys = convert (SDESystem,rs; noise_scaling= noise_scaling, kwargs ... )
515
+ p_matrix = zeros (length (get_states (rs)), length (get_eqs (rs)))
490
516
return SDEProblem (sde_sys,u0,tspan,p,args... ; noise_rate_prototype= p_matrix,kwargs... )
491
517
end
492
518
493
519
# DiscreteProblem from AbstractReactionNetwork
494
520
function DiffEqBase. DiscreteProblem (rs:: ReactionSystem , u0, tspan:: Tuple , p= DiffEqBase. NullParameters (), args... ; kwargs... )
495
- return DiscreteProblem (convert (JumpSystem,rs), u0,tspan,p, args... ; kwargs... )
521
+ return DiscreteProblem (convert (JumpSystem,rs; kwargs ... ), u0,tspan,p, args... ; kwargs... )
496
522
end
497
523
498
524
# JumpProblem from AbstractReactionNetwork
499
525
function DiffEqJump. JumpProblem (rs:: ReactionSystem , prob, aggregator, args... ; kwargs... )
500
- return JumpProblem (convert (JumpSystem,rs), prob, aggregator, args... ; kwargs... )
526
+ return JumpProblem (convert (JumpSystem,rs; kwargs ... ), prob, aggregator, args... ; kwargs... )
501
527
end
502
528
503
529
# SteadyStateProblem from AbstractReactionNetwork
504
530
function DiffEqBase. SteadyStateProblem (rs:: ReactionSystem , u0, p= DiffEqBase. NullParameters (), args... ; kwargs... )
505
- return SteadyStateProblem (ODEFunction (convert (ODESystem,rs)),u0,p, args... ; kwargs... )
531
+ return SteadyStateProblem (ODEFunction (convert (ODESystem,rs; kwargs ... )),u0,p, args... ; kwargs... )
506
532
end
507
533
508
534
# determine which species a reaction depends on
0 commit comments