Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle test errors from MTKv9 update (including ReactionSystem completeness) #784

Merged
merged 51 commits into from
Apr 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
267c351
init
TorkelE Feb 13, 2024
e67d20d
up
TorkelE Feb 13, 2024
e23c72f
up
TorkelE Mar 18, 2024
3aff3b0
tests shoudl start passing
TorkelE Mar 19, 2024
6f89a06
update tests
TorkelE Mar 20, 2024
e06d903
test up
TorkelE Mar 20, 2024
2de81e0
up
TorkelE Mar 20, 2024
a187b31
revert broken tests to normal tests
TorkelE Mar 20, 2024
c1a60ff
update
TorkelE Mar 22, 2024
fcc4bd2
up
TorkelE Mar 22, 2024
c146f08
a test is no longer broken due to mtk update
TorkelE Mar 22, 2024
3f61438
remove PEtab from docs (add back once it works for MTK v9)
TorkelE Mar 22, 2024
4843a26
up
TorkelE Mar 22, 2024
9e6e74e
broken test
TorkelE Mar 22, 2024
eca9e9d
update
TorkelE Mar 23, 2024
03c7380
unmark broken test, no longer broken
TorkelE Mar 23, 2024
cfa6b25
save changes
TorkelE Mar 24, 2024
a569190
rewors
TorkelE Mar 25, 2024
4832dfe
up
TorkelE Mar 25, 2024
f4deb3a
updates with working conservation laws
TorkelE Mar 26, 2024
68c22c1
update with new completeness handling
TorkelE Mar 29, 2024
45ad1d8
updates test
TorkelE Mar 29, 2024
bedc463
make @reaction_network go through @network_component
TorkelE Mar 29, 2024
c077cd6
format fix
TorkelE Mar 29, 2024
7fcc82b
revert reaction_network reroute through network_component
TorkelE Mar 29, 2024
d62424b
format fix
TorkelE Mar 29, 2024
4772d96
update
TorkelE Mar 29, 2024
a9371d5
up
TorkelE Mar 29, 2024
b42bb62
Improve documentation on completeness.
TorkelE Mar 29, 2024
adb2d29
up
TorkelE Mar 29, 2024
2f0b81c
Move thing that was unnecessarily moved, should make diff easier to read
TorkelE Mar 29, 2024
b52449a
fix more old sde sims without seeds
TorkelE Mar 29, 2024
211baf7
up
TorkelE Mar 29, 2024
89c5cf8
rework higher order reactions test so that works with MTKv9
TorkelE Mar 30, 2024
5896adb
prefer `using Package: function` over `import Package: function`
TorkelE Mar 30, 2024
233b850
up
TorkelE Mar 30, 2024
b818657
Update docs/src/catalyst_functionality/compositional_modeling.md
TorkelE Apr 2, 2024
9b4b003
Update docs/src/catalyst_functionality/compositional_modeling.md
TorkelE Apr 2, 2024
889380b
Update docs/src/catalyst_functionality/compositional_modeling.md
TorkelE Apr 2, 2024
5768ec0
Update docs/src/catalyst_functionality/programmatic_CRN_construction.md
TorkelE Apr 2, 2024
337d263
Update docs/src/introduction_to_catalyst/introduction_to_catalyst.md
TorkelE Apr 2, 2024
5633b72
Update src/reactionsystem.jl
TorkelE Apr 2, 2024
0c6ddd5
Update test/programmatic_model_creation/programmatic_model_expansion.jl
TorkelE Apr 2, 2024
b8d66aa
updates
TorkelE Apr 3, 2024
36ad7dd
fix tolerances in tests
TorkelE Apr 3, 2024
62802eb
add Catalyst.has_noise_scaling test
TorkelE Apr 3, 2024
f28ec30
update compeltness tests for extensions
TorkelE Apr 3, 2024
34ab871
compelteness error for SI
TorkelE Apr 3, 2024
d103525
bettter completeness error
TorkelE Apr 3, 2024
c9297ac
imrpvoe extension compeleness handling
TorkelE Apr 3, 2024
9bbb8d8
up
TorkelE Apr 3, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ HomotopyContinuation = "2.9"
LaTeXStrings = "1.3.0"
Latexify = "0.14, 0.15, 0.16"
MacroTools = "0.5.5"
ModelingToolkit = "9.5"
ModelingToolkit = "9.7.1"
Parameters = "0.12"
Reexport = "0.2, 1.0"
Requires = "1.0"
Expand Down
2 changes: 0 additions & 2 deletions docs/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ OptimizationNLopt = "4e6fcdb7-1186-4e1f-a706-475e75c168bb"
OptimizationOptimJL = "36348300-93cb-4f02-beb5-3c3902f8871e"
OptimizationOptimisers = "42dfb2eb-d2b4-4451-abcd-913932933ac1"
OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed"
PEtab = "48d54b35-e43e-4a66-a5a1-dde6b987cf69"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
QuasiMonteCarlo = "8a4e6c94-4038-4cdc-81c3-7e6ffdb2a71b"
SciMLBase = "0bca4576-84f4-4d90-8ffe-ffa030f20462"
Expand Down Expand Up @@ -47,7 +46,6 @@ OptimizationNLopt = "0.1.8"
OptimizationOptimJL = "0.1.14"
OptimizationOptimisers = "0.1.1"
OrdinaryDiffEq = "6"
PEtab = "2"
Plots = "1.36"
SciMLBase = "2.13"
SciMLSensitivity = "7.19"
Expand Down
4 changes: 2 additions & 2 deletions docs/pages.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
pages = Any["Home" => "index.md",
"Introduction to Catalyst" => Any["introduction_to_catalyst/catalyst_for_new_julia_users.md",
"introduction_to_catalyst/introduction_to_catalyst.md" ],
"introduction_to_catalyst/introduction_to_catalyst.md"],
"Catalyst Functionality" => Any["catalyst_functionality/dsl_description.md",
"catalyst_functionality/programmatic_CRN_construction.md",
"catalyst_functionality/compositional_modeling.md",
Expand All @@ -17,7 +17,7 @@ pages = Any["Home" => "index.md",
"catalyst_applications/nonlinear_solve.md",
"catalyst_applications/bifurcation_diagrams.md"],
"Inverse Problems" => Any["inverse_problems/optimization_ode_param_fitting.md",
"inverse_problems/petab_ode_param_fitting.md",
#"inverse_problems/petab_ode_param_fitting.md",
isaacsas marked this conversation as resolved.
Show resolved Hide resolved
"inverse_problems/structural_identifiability.md",
"Inverse problem examples" => Any["inverse_problems/examples/ode_fitting_oscillation.md"]],
"FAQs" => "faqs.md",
Expand Down
46 changes: 37 additions & 9 deletions docs/src/catalyst_functionality/compositional_modeling.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,44 @@ can construct the earlier repressilator model by composing together three
identically repressed genes, and how to use compositional modeling to create
compartments.

## [A note on *completeness*](@id completeness_note)
TorkelE marked this conversation as resolved.
Show resolved Hide resolved
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.

To create a `ReactionSystem`s for use in compositional modeling via the DSL, simply use the `@network_component` macro instead of `@reaction_network`:
```@example ex0
using Catalyst
degradation_component = @network_component begin
d, X --> 0
end
```
Alternatively one can just build the `ReactionSystem` via the symbolic interface.
```@example ex0
@parameters d
@variable t
@species X(t)
rx = Reaction(d, [X], nothing)
@named degradation_component = ReactionSystem([rs], t)
```
We can test whether a system is complete using the `ModelingToolkit.iscomplete` function:
```@example ex0
ModelingToolkit.iscomplete(degradation_component)
```
To mark a system as complete, after which is should be considered as representing a finalized model, use the `complete` function
```@example ex0
degradation_component_complete = complete(degradation_component)
ModelingToolkit.iscomplete(degradation_component_complete)
```

TorkelE marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Post v14 I would like to revisit this an write an improved description. I already have some write-up in local branches. For now, I figured it would be best to simple describe what is required. Next, we can look at the best way to actually document everything.

## Compositional modeling tooling
Catalyst supports two ModelingToolkit interfaces for composing multiple
[`ReactionSystem`](@ref)s together into a full model. The first mechanism for
extending a system is the `extend` command
```@example ex1
using Catalyst
basern = @reaction_network rn1 begin
basern = @network_component rn1 begin
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For now, I went with @network_component as the non-complete version of the macro.

k, A + B --> C
end
newrn = @reaction_network rn2 begin
newrn = @network_component rn2 begin
r, C --> A + B
end
@named rn = extend(newrn, basern)
Expand All @@ -27,9 +55,9 @@ The second main compositional modeling tool is the use of subsystems. Suppose we
now add to `basern` two subsystems, `newrn` and `newestrn`, we get a
different result:
```@example ex1
newestrn = @reaction_network rn3 begin
v, A + D --> 2D
end
newestrn = @network_component rn3 begin
v, A + D --> 2D
end
@named rn = compose(basern, [newrn, newestrn])
```
Here we have created a new `ReactionSystem` that adds `newrn` and `newestrn` as
Expand Down Expand Up @@ -99,7 +127,7 @@ modular fashion. We start by defining a function that creates a negatively
repressed gene, taking the repressor as input
```@example ex1
function repressed_gene(; R, name)
@reaction_network $name begin
@network_component $name begin
hillr($R,α,K,n), ∅ --> m
(δ,γ), m <--> ∅
β, m --> m + P
Expand Down Expand Up @@ -156,13 +184,13 @@ In our model we'll therefore add the conversions of the last column to properly
account for compartment volumes:
```@example ex1
# transcription and regulation
nuc = @reaction_network nuc begin
nuc = @network_component nuc begin
α, G --> G + M
(κ₊/V,κ₋), D + G <--> DG
end

# translation and dimerization
cyto = @reaction_network cyto begin
cyto = @network_component cyto begin
β, M --> M + P
(k₊/V,k₋), 2P <--> D
σ, P --> 0
Expand All @@ -171,7 +199,7 @@ end

# export reactions,
# γ,δ=probability per time to be exported/imported
model = @reaction_network model begin
model = @network_component model begin
γ, $(nuc.M) --> $(cyto.M)
δ, $(cyto.D) --> $(nuc.D)
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ system to be the same as the name of the variable storing the system.
Alternatively, one can use the `name = :repressilator` keyword argument to the
`ReactionSystem` constructor.

!!! warn
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).

isaacsas marked this conversation as resolved.
Show resolved Hide resolved
We can check that this is the same model as the one we defined via the DSL as
follows (this requires that we use the same names for rates, species and the
system)
Expand Down
6 changes: 6 additions & 0 deletions docs/src/introduction_to_catalyst/introduction_to_catalyst.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ Let's now use our `ReactionSystem` to generate and solve a corresponding mass
action ODE model. We first convert the system to a `ModelingToolkit.ODESystem`
by
```@example tut1
repressilator = complete(repressilator)
odesys = convert(ODESystem, repressilator)
```
(Here Latexify is used automatically to display `odesys` in Latex within Markdown
Expand Down Expand Up @@ -138,6 +139,7 @@ By passing `repressilator` directly to the `ODEProblem`, Catalyst has to
(internally) call `convert(ODESystem, repressilator)` again to generate the
symbolic ODEs. We could instead pass `odesys` directly like
```@example tut1
odesys = complete(odesys)
oprob2 = ODEProblem(odesys, u₀symmap, tspan, psymmap)
nothing # hide
```
Expand All @@ -152,6 +154,10 @@ underlying problem.
always be converted to `symbolic` mappings using [`symmap_to_varmap`](@ref),
see the [Basic Syntax](@ref basic_examples) section for more details.


!!! note
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).

At this point we are all set to solve the ODEs. We can now use any ODE solver
from within the
[DifferentialEquations.jl](https://docs.sciml.ai/DiffEqDocs/stable/solvers/ode_solve/)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ function BK.BifurcationProblem(rs::ReactionSystem, u0_bif, ps, bif_par, args...;

# Creates NonlinearSystem.
Catalyst.conservationlaw_errorcheck(rs, vcat(ps, u0))
nsys = convert(NonlinearSystem, rs; remove_conserved=true, defaults=Dict(u0))
nsys = complete(convert(NonlinearSystem, rs; remove_conserved=true, defaults=Dict(u0)))
TorkelE marked this conversation as resolved.
Show resolved Hide resolved

# Makes BifurcationProblem (this call goes through the ModelingToolkit-based BifurcationKit extension).
return BK.BifurcationProblem(nsys, u0_bif, ps, bif_par, args...; plot_var=plot_var,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ end
# For a given reaction system, parameter values, and initial conditions, find the polynomial that HC solves to find steady states.
function steady_state_polynomial(rs::ReactionSystem, ps, u0)
TorkelE marked this conversation as resolved.
Show resolved Hide resolved
rs = Catalyst.expand_registered_functions(rs)
ns = convert(NonlinearSystem, rs; remove_conserved = true)
ns = complete(convert(NonlinearSystem, rs; remove_conserved = true))
pre_varmap = [symmap_to_varmap(rs,u0)..., symmap_to_varmap(rs,ps)...]
Catalyst.conservationlaw_errorcheck(rs, pre_varmap)
p_vals = ModelingToolkit.varmap_to_vars(pre_varmap, parameters(ns); defaults = ModelingToolkit.defaults(ns))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,9 @@ end
function make_osys(rs::ReactionSystem; remove_conserved=true)
# Creates the ODESystem corresponding to the ReactionSystem (expanding functions and flattening it).
# Creates a list of the systems all symbols (unknowns and parameters).
rs = Catalyst.expand_registered_functions(flatten(rs))
osys = convert(ODESystem, rs; remove_conserved)
ModelingToolkit.iscomplete(rs) || error("Identifiability should only be computed for complete systems. A ReactionSystem can be marked as complete using the `complete` function.")
rs = complete(Catalyst.expand_registered_functions(flatten(rs)))
osys = complete(convert(ODESystem, rs; remove_conserved))
vars = [unknowns(rs); parameters(rs)]

# Computes equations for system conservation laws.
Expand Down
8 changes: 4 additions & 4 deletions src/Catalyst.jl
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import ModelingToolkit: get_variables, namespace_expr, namespace_equation, get_v
# internal but needed ModelingToolkit functions
import ModelingToolkit: check_variables,
check_parameters, _iszero, _merge, check_units,
get_unit, check_equations
get_unit, check_equations, iscomplete

import Base: (==), hash, size, getindex, setindex, isless, Sort.defalg, length, show
import MacroTools, Graphs
Expand All @@ -48,8 +48,8 @@ end
function default_t()
return ModelingToolkit.t_nounits
end
const DEFAULT_t = default_t()
const DEFAULT_IV_SYM = Symbol(DEFAULT_t)
const DEFAULT_IV = default_t()
const DEFAULT_IV_SYM = Symbol(DEFAULT_IV)
isaacsas marked this conversation as resolved.
Show resolved Hide resolved
export default_t, default_time_deriv

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

# registers CRN specific functions using Symbolics.jl
include("registered_functions.jl")
Expand Down
12 changes: 0 additions & 12 deletions src/expression_utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -94,18 +94,6 @@ function is_escaped_expr(expr)
end


### Generic Expression Handling ###

# Convert an expression that is a vector with symbols that have values assigned using `=`
# (e.g. :([a=1.0, b=2.0])) to a vector where the assignment instead uses symbols and pairs
# (e.g. :([a=>1.0, b=>2.0])). Used to e.g. convert default reaction metadata to a form that can be
# evaluated as actual code.
function expr_equal_vector_to_pairs(expr_vec)
pair_vector = :([])
foreach(arg -> push!(pair_vector.args, arg.args[1] => arg.args[2]), expr_vec.args)
return pair_vector
end

### Old Stuff ###
isaacsas marked this conversation as resolved.
Show resolved Hide resolved

#This will be called whenever a function stored in funcdict is called.
Expand Down
2 changes: 1 addition & 1 deletion src/networkapi.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1624,7 +1624,7 @@ function validate(rs::ReactionSystem, info::String = "")
rxunits *= get_unit(sub)^rx.substoich[i]
end

if rxunits != rateunits
if !isequal(rxunits, rateunits)
TorkelE marked this conversation as resolved.
Show resolved Hide resolved
validated = false
@warn(string("Reaction rate laws are expected to have units of ", rateunits,
" however, ", rx, " has units of ", rxunits, "."))
Expand Down
Loading
Loading