Skip to content

Commit 6ccbc1f

Browse files
authored
Merge pull request #943 from SciML/fix_broken_doc_references
[WIP] Fix remaining doc issues
2 parents 389b4ca + 3c0c9aa commit 6ccbc1f

19 files changed

+103
-28
lines changed

docs/make.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ makedocs(sitename = "Catalyst.jl",
4141
clean = true,
4242
pages = pages,
4343
pagesonly = true,
44-
warnonly = true)
44+
warnonly = [:missing_docs])
4545

4646
deploydocs(repo = "github.com/SciML/Catalyst.jl.git";
4747
push_preview = true)

docs/src/api.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,7 @@ hillar
272272
```@docs
273273
Base.convert
274274
ModelingToolkit.structural_simplify
275+
set_default_noise_scaling
275276
```
276277

277278
## Chemistry-related functionalities

docs/src/faqs.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ plot(sol; idxs = [A, B])
5959
```
6060

6161
## How to disable rescaling of reaction rates in rate laws?
62-
As explained in the [Reaction rate laws used in simulations](@ref) section, for
62+
As explained in the [Reaction rate laws used in simulations](@ref introduction_to_catalyst_ratelaws) section, for
6363
a reaction such as `k, 2X --> 0`, the generated rate law will rescale the rate
6464
constant, giving `k*X^2/2` instead of `k*X^2` for ODEs and `k*X*(X-1)/2` instead
6565
of `k*X*(X-1)` for jumps. This can be disabled when directly `convert`ing a
@@ -96,7 +96,7 @@ Note, when using `convert(ODESystem, mixedsys; combinatoric_ratelaws=false)` the
9696
calling `ODEProblem(mixedsys,...; combinatoric_ratelaws=false)`. As described
9797
above, this disables Catalyst's standard rescaling of reaction rates when
9898
generating reaction rate laws, see also the [Reaction rate laws used in
99-
simulations](@ref) section. Leaving this keyword out for systems with floating
99+
simulations](@ref introduction_to_catalyst_ratelaws) section. Leaving this keyword out for systems with floating
100100
point stoichiometry will give an error message.
101101

102102
For a more extensive documentation of using non-integer stoichiometric
@@ -105,7 +105,7 @@ parametric_stoichiometry) section.
105105

106106
## How to set default values for initial conditions and parameters?
107107
How to set defaults when using the `@reaction_network` macro is described in
108-
more detail [here](@ref dsl_description_defaults). There are several ways to do
108+
more detail [here](@ref dsl_advanced_options_default_vals). There are several ways to do
109109
this. Using the DSL, one can use the `@species` and `@parameters` options:
110110
```@example faq3
111111
using Catalyst

docs/src/introduction_to_catalyst/introduction_to_catalyst.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# [Introduction to Catalyst](@id introduction_to_catalyst)
22
In this tutorial we provide an introduction to using Catalyst to specify
33
chemical reaction networks, and then to solve ODE, jump, and SDE models
4-
generated from them. At the end we show what mathematical rate laws and
4+
generated from them[1]. At the end we show what mathematical rate laws and
55
transition rate functions (i.e. intensities or propensities) are generated by
66
Catalyst for ODE, SDE and jump process models.
77

@@ -151,8 +151,7 @@ underlying problem.
151151
variable-based parameter mappings, `u₀symmap` and `psymmap`, while when
152152
directly passing `repressilator` we could use either those or the
153153
`Symbol`-based mappings, `u₀map` and `pmap`. `Symbol`-based mappings can
154-
always be converted to `symbolic` mappings using [`symmap_to_varmap`](@ref),
155-
see the [Basic Syntax](@ref basic_examples) section for more details.
154+
always be converted to `symbolic` mappings using [`symmap_to_varmap`](@ref).
156155

157156

158157
!!! note

docs/src/inverse_problems/behaviour_optimisation.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# [Optimization for non-data fitting purposes](@id behaviour_optimisation)
2-
In previous tutorials we have described how to use [PEtab.jl](@ref petab_parameter_fitting) and [Optimization.jl](@ref optimization_parameter_fitting) for parameter fitting. This involves solving an optimisation problem (to find the parameter set yielding the best model-to-data fit). There are, however, other situations that require solving optimisation problems. Typically, these involve the creation of a custom cost function, which optimum can then be found using Optimization.jl. In this tutorial we will describe this process, demonstrating how parameter space can be searched to find values that achieve a desired system behaviour. A more throughout description on how to solve these problems is provided by [Optimization.jl's documentation](https://docs.sciml.ai/Optimization/stable/) and the literature[^1].
2+
In previous tutorials we have described how to use PEtab.jl and [Optimization.jl](@ref optimization_parameter_fitting) for parameter fitting. This involves solving an optimisation problem (to find the parameter set yielding the best model-to-data fit). There are, however, other situations that require solving optimisation problems. Typically, these involve the creation of a custom cost function, which optimum can then be found using Optimization.jl. In this tutorial we will describe this process, demonstrating how parameter space can be searched to find values that achieve a desired system behaviour. A more throughout description on how to solve these problems is provided by [Optimization.jl's documentation](https://docs.sciml.ai/Optimization/stable/) and the literature[^1].
33

44
## [Maximising the pulse amplitude of an incoherent feed forward loop](@id behaviour_optimisation_IFFL_example)
55
Incoherent feedforward loops (network motifs where a single component both activates and deactivates a downstream component) are able to generate pulses in response to step inputs[^2]. In this tutorial we will consider such an incoherent feedforward loop, attempting to generate a system with as prominent a response pulse as possible.
@@ -38,7 +38,7 @@ function pulse_amplitude(p, _)
3838
SciMLBase.successful_retcode(sol) || return Inf
3939
return -(maximum(sol[:Z]) - sol[:Z][1])
4040
end
41-
nothing # here
41+
nothing # hide
4242
```
4343
This cost function takes two arguments (a parameter value `p`, and an additional one which we will ignore here but discuss later). It first calculates the new initial steady state concentration for the given parameter set. Next, it creates an updated `ODEProblem` using the steady state as initial conditions and the, to the cost function provided, input parameter set. While we could create a new `ODEProblem` within the cost function, cost functions are often called a large number of times during the optimisation process (making performance important). Here, using [`remake` on a previously created `ODEProblem`](@ref simulation_structure_interfacing_problems_remake) is more performant than creating a new one. Just like [when using Optimization.jl to fit parameters to data](@ref optimization_parameter_fitting), we use the `verbose = false` option to prevent unnecessary simulation printouts, and a reduced `maxiters` value to reduce time spent simulating (for the model) unsuitable parameter sets. We also use `SciMLBase.successful_retcode(sol)` to check whether the simulation return code indicates a successful simulation (and if it did not, returns a large cost function value). Finally, Optimization.jl finds the function's *minimum value*, so to find the *maximum* relative pulse amplitude, we make our cost function return the negative pulse amplitude.
4444

docs/src/inverse_problems/global_sensitivity_analysis.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# [Global Sensitivity Analysis](@id global_sensitivity_analysis)
22
*Global sensitivity analysis* (GSA) is used to study the sensitivity of a function's outputs with respect to its input[^1]. Within the context of chemical reaction network modelling it is primarily used for two purposes:
3-
- [When fitting a model's parameters to data](@ref petab_parameter_fitting), it can be applied to the cost function of the optimisation problem. Here, GSA helps determine which parameters do, and do not, affect the model's fit to the data. This can be used to identify parameters that are less relevant to the observed data.
3+
- When fitting a model's parameters to data, it can be applied to the cost function of the optimisation problem. Here, GSA helps determine which parameters do, and do not, affect the model's fit to the data. This can be used to identify parameters that are less relevant to the observed data.
44
- [When measuring some system behaviour or property](@ref behaviour_optimisation), it can help determine which parameters influence that property. E.g. for a model of a biofuel-producing circuit in a synthetic organism, GSA could determine which system parameters have the largest impact on the total rate of biofuel production.
55

66
GSA can be carried out using the [GlobalSensitivity.jl](https://github.com/SciML/GlobalSensitivity.jl) package. This tutorial contains a brief introduction of how to use it for GSA on Catalyst models, with [GlobalSensitivity providing a more complete documentation](https://docs.sciml.ai/GlobalSensitivity/stable/).
@@ -52,7 +52,7 @@ on the domain $10^β ∈ (-3.0,-1.0)$, $10^a ∈ (-2.0,0.0)$, $10^γ ∈ (-2.0,0
5252

5353
!!! note
5454
We should make a couple of notes about the example above:
55-
- Here, we write our parameters on the forms $10^β$, $10^a$, and $10^γ$, which transforms them into log-space. As [previously described](@ref optimization_parameter_fitting_logarithmic_scale), this is advantageous in the context of inverse problems such as this one.
55+
- Here, we write our parameters on the forms $10^β$, $10^a$, and $10^γ$, which transforms them into log-space. As [previously described](@ref optimization_parameter_fitting_log_scale), this is advantageous in the context of inverse problems such as this one.
5656
- For GSA, where a function is evaluated a large number of times, it is ideal to write it as performant as possible. Hence, we initially create a base `ODEProblem`, and then apply the [`remake`](@ref simulation_structure_interfacing_problems_remake) function to it in each evaluation of `peak_cases` to generate a problem which is solved for that specific parameter set.
5757
- Again, as [previously described in other inverse problem tutorials](@ref optimization_parameter_fitting_basics), when exploring a function over large parameter spaces, we will likely simulate our model for unsuitable parameter sets. To reduce time spent on these, and to avoid excessive warning messages, we provide the `maxiters = 100000` and `verbose = false` arguments to `solve`.
5858
- As we have encountered in [a few other cases](@ref optimization_parameter_fitting_basics), the `gsa` function is not able to take parameter inputs of the map form usually used for Catalyst. Hence, as a first step in `peak_cases` we convert the parameter vector to this form. Next, we remember that the order of the parameters when we e.g. evaluate the GSA output, or set the parameter bounds, corresponds to the order used in `ps = [:β => p[1], :a => p[2], :γ => p[3]]`.

docs/src/inverse_problems/optimization_ode_param_fitting.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,13 +129,13 @@ If we from previous knowledge know that $kD = 0.1$, and only want to fit the val
129129
fixed_p_prob_generator(prob, p) = remake(prob; p = vcat(p[1], 0.1, p[2]))
130130
nothing # hide
131131
```
132-
Here, it takes the `ODEProblem` (`prob`) we simulate, and the parameter set used, during the optimisation process (`p`), and creates a modified `ODEProblem` (by setting a customised parameter vector [using `remake`](@ref simulation_structure_interfacing_remake)). Now we create our modified loss function:
132+
Here, it takes the `ODEProblem` (`prob`) we simulate, and the parameter set used, during the optimisation process (`p`), and creates a modified `ODEProblem` (by setting a customised parameter vector [using `remake`](@ref simulation_structure_interfacing_problems_remake)). Now we create our modified loss function:
133133
```@example diffeq_param_estim_1
134134
loss_function_fixed_kD = build_loss_objective(oprob, Tsit5(), L2Loss(data_ts, data_vals), Optimization.AutoForwardDiff(); prob_generator = fixed_p_prob_generator, maxiters=10000, verbose=false, save_idxs=4)
135135
nothing # hide
136136
```
137137

138-
We can create an `OptimizationProblem` from this one like previously, but keep in mind that it (and its output results) only contains two parameter values ($k$* and $kP$):
138+
We can create an `OptimizationProblem` from this one like previously, but keep in mind that it (and its output results) only contains two parameter values ($k$ and $kP$):
139139
```@example diffeq_param_estim_1
140140
optprob_fixed_kD = OptimizationProblem(loss_function_fixed_kD, [1.0, 1.0])
141141
optsol_fixed_kD = solve(optprob_fixed_kD, Optim.NelderMead())
@@ -160,7 +160,7 @@ nothing # hide
160160
corresponds to the same true parameter values as used previously (`[:kB => 1.0, :kD => 0.1, :kP => 0.5]`).
161161

162162
## [Parameter fitting to multiple experiments](@id optimization_parameter_fitting_multiple_experiments)
163-
Say that we had measured our model for several different initial conditions, and would like to fit our model to all these measurements simultaneously. This can be done by first creating a [corresponding `EnsembleProblem`](@ref advanced_simulations_ensemble_problems). How to then create loss functions for these are described in more detail [here](https://docs.sciml.ai/DiffEqParamEstim/stable/tutorials/ensemble/).
163+
Say that we had measured our model for several different initial conditions, and would like to fit our model to all these measurements simultaneously. This can be done by first creating a [corresponding `EnsembleProblem`](@ref ensemble_simulations). How to then create loss functions for these are described in more detail [here](https://docs.sciml.ai/DiffEqParamEstim/stable/tutorials/ensemble/).
164164

165165
## [Optimisation solver options](@id optimization_parameter_fitting_solver_options)
166166
Optimization.jl supports various [optimisation solver options](https://docs.sciml.ai/Optimization/stable/API/solve/) that can be supplied to the `solve` command. For example, to set a maximum number of seconds (after which the optimisation process is terminated), you can use the `maxtime` argument:

docs/src/model_creation/compositional_modeling.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ nothing # hide
139139
Here we assume the user will pass in the repressor species as a ModelingToolkit
140140
variable, and specify a name for the network. We use Catalyst's interpolation
141141
ability to substitute the value of these variables into the DSL (see
142-
[Interpolation of Julia Variables](@ref dsl_description_interpolation_of_variables)). To make the repressilator we now make
142+
[Interpolation of Julia Variables](@ref dsl_advanced_options_symbolics_and_DSL_interpolation)). To make the repressilator we now make
143143
three genes, and then compose them together
144144
```@example ex1
145145
t = default_t()

docs/src/model_creation/constraint_equations.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ end
5252
Notice, here we interpolated the variable `V` with `$V` to ensure we use the
5353
same symbolic unknown variable in the `rn` as we used in building `osys`. See the
5454
doc section on [interpolation of variables](@ref
55-
dsl_description_interpolation_of_variables) for more information.
55+
dsl_advanced_options_symbolics_and_DSL_interpolation) for more information.
5656

5757
We can now merge the two systems into one complete `ReactionSystem` model using
5858
[`ModelingToolkit.extend`](@ref):

docs/src/model_creation/dsl_advanced.md

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ end
363363
nothing # hide
364364
```
365365
!!! note
366-
If only a single observable is declared, the `begin .. end` block is not required and the observable can be declared directly after the `@observables` option.
366+
If only a single observable is declared, the `begin ... end` block is not required and the observable can be declared directly after the `@observables` option.
367367

368368
[Metadata](@ref dsl_advanced_options_species_and_parameters_metadata) can be supplied to an observable directly after its declaration (but before its formula). If so, the metadata must be separated from the observable with a `,`, and the observable plus the metadata encapsulated by `()`. E.g. to add a [description metadata](@ref dsl_advanced_options_species_and_parameters_metadata) to our observable we can use
369369
```@example dsl_advanced_observables
@@ -463,3 +463,77 @@ A reaction's metadata can be accessed using specific functions, e.g. `Catalyst.h
463463
rx = @reaction p, 0 --> X, [description="A production reaction"]
464464
Catalyst.getdescription(rx)
465465
```
466+
467+
## [Working with symbolic variables and the DSL](@id dsl_advanced_options_symbolics_and_DSL)
468+
We have previously described how Catalyst represents its models symbolically (enabling e.g. symbolic differentiation of expressions stored in models). While Catalyst utilises this for many internal operation, these symbolic representations can also be accessed and harnessed by the user. Primarily, doing so is much easier during programmatic (as opposed to DSL-based) modelling. Indeed, the section on [programmatic modelling](@ref programmatic_CRN_construction) goes into more details about symbolic representation in models, and how these can be used. It is, however, also ways to utilise these methods during DSL-based modelling. Below we briefly describe two methods for doing so.
469+
470+
### [Using `@unpack` to extract symbolic variables from `ReactionSystem`s](@id dsl_advanced_options_symbolics_and_DSL_unpack)
471+
Let us consider a simple [birth-death process](@ref basic_CRN_library_bd) created using the DSL:
472+
```@example dsl_advanced_programmatic_unpack
473+
using Catalyst # hide
474+
bd_model = @reaction_network begin
475+
(p,d), 0 <--> X
476+
end
477+
nothing # hide
478+
```
479+
Since we have not explicitly declared `p`, `d`, and `X` using `@parameters` and `@species`, we cannot represent these symbolically (only using `Symbol`s). If we wish to do so, however, we can fetch these into our current scope using the `@unpack` macro:
480+
```@example dsl_advanced_programmatic_unpack
481+
@unpack p, d, X = bd_model
482+
nothing # hide
483+
```
484+
This lists first the quantities we wish to fetch (does not need to be the model's full set of parameters and species), then `=`, followed by the model variable. `p`, `d` and `X` are now symbolic variables in the current scope, just as if they had been declared using `@parameters` or `@species`. We can confirm this:
485+
```@example dsl_advanced_programmatic_unpack
486+
X
487+
```
488+
Next, we can now use these to e.g. designate initial conditions and parameter values for model simulations:
489+
```@example dsl_advanced_programmatic_unpack
490+
using OrdinaryDiffEq, Plots # hide
491+
u0 = [X => 0.1]
492+
tspan = (0.0, 10.0)
493+
ps = [p => 1.0, d => 0.2]
494+
oprob = ODEProblem(bd_model, u0, tspan, ps)
495+
sol = solve(oprob)
496+
plot(sol)
497+
```
498+
499+
!!! warn
500+
Just like when using `@parameters` and `@species`, `@unpack` will overwrite any variables in the current scope which share name with the imported quantities.
501+
502+
### [Interpolating variables into the DSL](@id dsl_advanced_options_symbolics_and_DSL_interpolation)
503+
Catalyst's DSL allows Julia variables to be interpolated for the network name, within rate constant expressions, or for species/stoichiometries within reactions. Using the lower-level symbolic interface we can then define symbolic variables and parameters outside of `@reaction_network`, which can then be used within expressions in the DSL.
504+
505+
Interpolation is carried out by pre-appending the interpolating variable with a `$`. For example, here we declare the parameters and species of a birth-death model, and interpolate these into the model:
506+
```@example dsl_advanced_programmatic_interpolation
507+
using Catalyst # hide
508+
t = default_t()
509+
@species X(t)
510+
@parameters p d
511+
bd_model = @reaction_network begin
512+
($p, $d), 0 <--> $X
513+
end
514+
```
515+
Additional information (such as default values or metadata) supplied to `p`, `d`, and `X` is carried through to the DSL. However, interpolation for this purpose is of limited value, as such information [can be declared within the DSL](@ref dsl_advanced_options_declaring_species_and_parameters). However, it is possible to interpolate larger algebraic expressions into the DSL, e.g. here
516+
```@example dsl_advanced_programmatic_interpolation
517+
@species X1(t) X2(t) X3(t) E(t)
518+
@parameters d
519+
d_rate = d/(1 + E)
520+
degradation_model = @reaction_network begin
521+
$d_rate, X1 --> 0
522+
$d_rate, X2 --> 0
523+
$d_rate, X3 --> 0
524+
end
525+
```
526+
we declare an expression `d_rate`, which then can be inserted into the DSL via interpolation.
527+
528+
It is also possible to use interpolation in combination with the `@reaction` macro. E.g. the reactions of the above network can be declared individually using
529+
```@example dsl_advanced_programmatic_interpolation
530+
rxs = [
531+
@reaction $d_rate, $X1 --> 0
532+
@reaction $d_rate, $X2 --> 0
533+
@reaction $d_rate, $X3 --> 0
534+
]
535+
nothing # hide
536+
```
537+
538+
!!! note
539+
When using interpolation, expressions like `2$spec` won't work; the multiplication symbol must be explicitly included like `2*$spec`.

0 commit comments

Comments
 (0)