Skip to content

Commit 6589937

Browse files
authored
Merge pull request #784 from SciML/reactionsystem_completeness
Handle test errors from MTKv9 update (including `ReactionSystem` completeness)
2 parents eaec868 + 9bbb8d8 commit 6589937

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+1304
-953
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ HomotopyContinuation = "2.9"
4444
LaTeXStrings = "1.3.0"
4545
Latexify = "0.14, 0.15, 0.16"
4646
MacroTools = "0.5.5"
47-
ModelingToolkit = "9.5"
47+
ModelingToolkit = "9.7.1"
4848
Parameters = "0.12"
4949
Reexport = "0.2, 1.0"
5050
Requires = "1.0"

docs/Project.toml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ OptimizationNLopt = "4e6fcdb7-1186-4e1f-a706-475e75c168bb"
1717
OptimizationOptimJL = "36348300-93cb-4f02-beb5-3c3902f8871e"
1818
OptimizationOptimisers = "42dfb2eb-d2b4-4451-abcd-913932933ac1"
1919
OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed"
20-
PEtab = "48d54b35-e43e-4a66-a5a1-dde6b987cf69"
2120
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
2221
QuasiMonteCarlo = "8a4e6c94-4038-4cdc-81c3-7e6ffdb2a71b"
2322
SciMLBase = "0bca4576-84f4-4d90-8ffe-ffa030f20462"
@@ -47,7 +46,6 @@ OptimizationNLopt = "0.1.8"
4746
OptimizationOptimJL = "0.1.14"
4847
OptimizationOptimisers = "0.1.1"
4948
OrdinaryDiffEq = "6"
50-
PEtab = "2"
5149
Plots = "1.36"
5250
SciMLBase = "2.13"
5351
SciMLSensitivity = "7.19"

docs/pages.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
pages = Any["Home" => "index.md",
22
"Introduction to Catalyst" => Any["introduction_to_catalyst/catalyst_for_new_julia_users.md",
3-
"introduction_to_catalyst/introduction_to_catalyst.md" ],
3+
"introduction_to_catalyst/introduction_to_catalyst.md"],
44
"Catalyst Functionality" => Any["catalyst_functionality/dsl_description.md",
55
"catalyst_functionality/programmatic_CRN_construction.md",
66
"catalyst_functionality/compositional_modeling.md",
@@ -17,7 +17,7 @@ pages = Any["Home" => "index.md",
1717
"catalyst_applications/nonlinear_solve.md",
1818
"catalyst_applications/bifurcation_diagrams.md"],
1919
"Inverse Problems" => Any["inverse_problems/optimization_ode_param_fitting.md",
20-
"inverse_problems/petab_ode_param_fitting.md",
20+
#"inverse_problems/petab_ode_param_fitting.md",
2121
"inverse_problems/structural_identifiability.md",
2222
"Inverse problem examples" => Any["inverse_problems/examples/ode_fitting_oscillation.md"]],
2323
"FAQs" => "faqs.md",

docs/src/catalyst_functionality/compositional_modeling.md

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,44 @@ can construct the earlier repressilator model by composing together three
55
identically repressed genes, and how to use compositional modeling to create
66
compartments.
77

8+
## [A note on *completeness*](@id completeness_note)
9+
Catalyst `ReactionSystem` can either be *complete* or *incomplete*. When created using the `@reaction_network` DSL they are *created as complete*. Here, only complete `ReactionSystem`s can be used to create the various problem types (e.g. `ODEProblem`). However, only incomplete `ReactionSystem`s can be composed using the features described below. Hence, for compositional modeling, `ReactionSystem` must be created as incomplete, and later set to complete before simulation.
10+
11+
To create a `ReactionSystem`s for use in compositional modeling via the DSL, simply use the `@network_component` macro instead of `@reaction_network`:
12+
```@example ex0
13+
using Catalyst
14+
degradation_component = @network_component begin
15+
d, X --> 0
16+
end
17+
```
18+
Alternatively one can just build the `ReactionSystem` via the symbolic interface.
19+
```@example ex0
20+
@parameters d
21+
@variable t
22+
@species X(t)
23+
rx = Reaction(d, [X], nothing)
24+
@named degradation_component = ReactionSystem([rs], t)
25+
```
26+
We can test whether a system is complete using the `ModelingToolkit.iscomplete` function:
27+
```@example ex0
28+
ModelingToolkit.iscomplete(degradation_component)
29+
```
30+
To mark a system as complete, after which is should be considered as representing a finalized model, use the `complete` function
31+
```@example ex0
32+
degradation_component_complete = complete(degradation_component)
33+
ModelingToolkit.iscomplete(degradation_component_complete)
34+
```
35+
836
## Compositional modeling tooling
937
Catalyst supports two ModelingToolkit interfaces for composing multiple
1038
[`ReactionSystem`](@ref)s together into a full model. The first mechanism for
1139
extending a system is the `extend` command
1240
```@example ex1
1341
using Catalyst
14-
basern = @reaction_network rn1 begin
42+
basern = @network_component rn1 begin
1543
k, A + B --> C
1644
end
17-
newrn = @reaction_network rn2 begin
45+
newrn = @network_component rn2 begin
1846
r, C --> A + B
1947
end
2048
@named rn = extend(newrn, basern)
@@ -27,9 +55,9 @@ The second main compositional modeling tool is the use of subsystems. Suppose we
2755
now add to `basern` two subsystems, `newrn` and `newestrn`, we get a
2856
different result:
2957
```@example ex1
30-
newestrn = @reaction_network rn3 begin
31-
v, A + D --> 2D
32-
end
58+
newestrn = @network_component rn3 begin
59+
v, A + D --> 2D
60+
end
3361
@named rn = compose(basern, [newrn, newestrn])
3462
```
3563
Here we have created a new `ReactionSystem` that adds `newrn` and `newestrn` as
@@ -99,7 +127,7 @@ modular fashion. We start by defining a function that creates a negatively
99127
repressed gene, taking the repressor as input
100128
```@example ex1
101129
function repressed_gene(; R, name)
102-
@reaction_network $name begin
130+
@network_component $name begin
103131
hillr($R,α,K,n), ∅ --> m
104132
(δ,γ), m <--> ∅
105133
β, m --> m + P
@@ -156,13 +184,13 @@ In our model we'll therefore add the conversions of the last column to properly
156184
account for compartment volumes:
157185
```@example ex1
158186
# transcription and regulation
159-
nuc = @reaction_network nuc begin
187+
nuc = @network_component nuc begin
160188
α, G --> G + M
161189
(κ₊/V,κ₋), D + G <--> DG
162190
end
163191
164192
# translation and dimerization
165-
cyto = @reaction_network cyto begin
193+
cyto = @network_component cyto begin
166194
β, M --> M + P
167195
(k₊/V,k₋), 2P <--> D
168196
σ, P --> 0
@@ -171,7 +199,7 @@ end
171199
172200
# export reactions,
173201
# γ,δ=probability per time to be exported/imported
174-
model = @reaction_network model begin
202+
model = @network_component model begin
175203
γ, $(nuc.M) --> $(cyto.M)
176204
δ, $(cyto.D) --> $(nuc.D)
177205
end

docs/src/catalyst_functionality/programmatic_CRN_construction.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ system to be the same as the name of the variable storing the system.
6161
Alternatively, one can use the `name = :repressilator` keyword argument to the
6262
`ReactionSystem` constructor.
6363

64+
!!! warn
65+
All `ReactionSystem`s created via the symbolic interface (i.e. by calling `ReactionSystem` with some input, rather than using `@reaction_network`) are not marked as complete. To simulate them, they must first be marked as *complete*, indicating to Catalyst and ModelingToolkit that they represent finalized models. This can be done using the `complete` function, i.e. by calling `repressilator = complete(repressilator)`. An expanded description on *completeness* can be found [here](@ref completeness_note).
66+
6467
We can check that this is the same model as the one we defined via the DSL as
6568
follows (this requires that we use the same names for rates, species and the
6669
system)

docs/src/introduction_to_catalyst/introduction_to_catalyst.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ Let's now use our `ReactionSystem` to generate and solve a corresponding mass
9696
action ODE model. We first convert the system to a `ModelingToolkit.ODESystem`
9797
by
9898
```@example tut1
99+
repressilator = complete(repressilator)
99100
odesys = convert(ODESystem, repressilator)
100101
```
101102
(Here Latexify is used automatically to display `odesys` in Latex within Markdown
@@ -138,6 +139,7 @@ By passing `repressilator` directly to the `ODEProblem`, Catalyst has to
138139
(internally) call `convert(ODESystem, repressilator)` again to generate the
139140
symbolic ODEs. We could instead pass `odesys` directly like
140141
```@example tut1
142+
odesys = complete(odesys)
141143
oprob2 = ODEProblem(odesys, u₀symmap, tspan, psymmap)
142144
nothing # hide
143145
```
@@ -152,6 +154,10 @@ underlying problem.
152154
always be converted to `symbolic` mappings using [`symmap_to_varmap`](@ref),
153155
see the [Basic Syntax](@ref basic_examples) section for more details.
154156

157+
158+
!!! note
159+
Above we have used `repressilator = complete(repressilator)` and `odesys = complete(odesys)` to mark these systems as *complete*, indicating to Catalyst and ModelingToolkit that these models are finalized. This must be done before any system is given as input to a `convert` call or some problem type. `ReactionSystem` models created through the @reaction_network` DSL (which is introduced elsewhere, and primarily used throughout these documentation) are always marked as complete when generated. Hence `complete` does not need to be called on them. Symbolically generated `ReactionSystem`s, `ReactionSystem`s generated via the `@network_component` macro, and any ModelingToolkit system generated by `convert` always needs to be manually marked as `complete` as we do for `odesys` above. An expanded description on *completeness* can be found [here](@ref completeness_note).
160+
155161
At this point we are all set to solve the ODEs. We can now use any ODE solver
156162
from within the
157163
[DifferentialEquations.jl](https://docs.sciml.ai/DiffEqDocs/stable/solvers/ode_solve/)

ext/CatalystBifurcationKitExtension/bifurcation_kit_extension.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ function BK.BifurcationProblem(rs::ReactionSystem, u0_bif, ps, bif_par, args...;
1313

1414
# Creates NonlinearSystem.
1515
Catalyst.conservationlaw_errorcheck(rs, vcat(ps, u0))
16-
nsys = convert(NonlinearSystem, rs; remove_conserved=true, defaults=Dict(u0))
16+
nsys = complete(convert(NonlinearSystem, rs; remove_conserved=true, defaults=Dict(u0)))
1717

1818
# Makes BifurcationProblem (this call goes through the ModelingToolkit-based BifurcationKit extension).
1919
return BK.BifurcationProblem(nsys, u0_bif, ps, bif_par, args...; plot_var=plot_var,

ext/CatalystHomotopyContinuationExtension/homotopy_continuation_extension.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ end
4545
# For a given reaction system, parameter values, and initial conditions, find the polynomial that HC solves to find steady states.
4646
function steady_state_polynomial(rs::ReactionSystem, ps, u0)
4747
rs = Catalyst.expand_registered_functions(rs)
48-
ns = convert(NonlinearSystem, rs; remove_conserved = true)
48+
ns = complete(convert(NonlinearSystem, rs; remove_conserved = true))
4949
pre_varmap = [symmap_to_varmap(rs,u0)..., symmap_to_varmap(rs,ps)...]
5050
Catalyst.conservationlaw_errorcheck(rs, pre_varmap)
5151
p_vals = ModelingToolkit.varmap_to_vars(pre_varmap, parameters(ns); defaults = ModelingToolkit.defaults(ns))

ext/CatalystStructuralIdentifiabilityExtension/structural_identifiability_extension.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,9 @@ end
157157
function make_osys(rs::ReactionSystem; remove_conserved=true)
158158
# Creates the ODESystem corresponding to the ReactionSystem (expanding functions and flattening it).
159159
# Creates a list of the systems all symbols (unknowns and parameters).
160-
rs = Catalyst.expand_registered_functions(flatten(rs))
161-
osys = convert(ODESystem, rs; remove_conserved)
160+
ModelingToolkit.iscomplete(rs) || error("Identifiability should only be computed for complete systems. A ReactionSystem can be marked as complete using the `complete` function.")
161+
rs = complete(Catalyst.expand_registered_functions(flatten(rs)))
162+
osys = complete(convert(ODESystem, rs; remove_conserved))
162163
vars = [unknowns(rs); parameters(rs)]
163164

164165
# Computes equations for system conservation laws.

src/Catalyst.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ import ModelingToolkit: get_variables, namespace_expr, namespace_equation, get_v
3333
# internal but needed ModelingToolkit functions
3434
import ModelingToolkit: check_variables,
3535
check_parameters, _iszero, _merge, check_units,
36-
get_unit, check_equations
36+
get_unit, check_equations, iscomplete
3737

3838
import Base: (==), hash, size, getindex, setindex, isless, Sort.defalg, length, show
3939
import MacroTools, Graphs
@@ -48,8 +48,8 @@ end
4848
function default_t()
4949
return ModelingToolkit.t_nounits
5050
end
51-
const DEFAULT_t = default_t()
52-
const DEFAULT_IV_SYM = Symbol(DEFAULT_t)
51+
const DEFAULT_IV = default_t()
52+
const DEFAULT_IV_SYM = Symbol(DEFAULT_IV)
5353
export default_t, default_time_deriv
5454

5555
# as used in Catlab
@@ -77,7 +77,7 @@ export ODEProblem,
7777
const ExprValues = Union{Expr, Symbol, Float64, Int, Bool}
7878
include("expression_utils.jl")
7979
include("reaction_network.jl")
80-
export @reaction_network, @add_reactions, @reaction, @species
80+
export @reaction_network, @network_component, @add_reactions, @reaction, @species
8181

8282
# registers CRN specific functions using Symbolics.jl
8383
include("registered_functions.jl")

0 commit comments

Comments
 (0)