You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/src/catalyst_functionality/dsl_description.md
+66Lines changed: 66 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -567,3 +567,69 @@ species(rn)
567
567
!!! note
568
568
When using interpolation, expressions like `2$spec` won't work; the
569
569
multiplication symbol must be explicitly included like `2*$spec`.
570
+
571
+
## Including observables
572
+
Sometimes, one might want to include observable variables. These are variables that can be computed directly from the other system variables (rather than having their values implicitly given through some differential equation). These can be introduced through the `@observables` option.
573
+
574
+
Let us consider a simple example where two species ($X$ and $Y$) are produced and degraded at constant rates. They can also bind, forming a complex ($XY$). If we want to access the total amount of $X$ in the system we can create an observable that denotes this quantity ($Xtot = X + XY$). Here, we create observables for the total amount of $X$ and $Y$:
575
+
```@example obs1
576
+
using Catalyst # hide
577
+
rn = @reaction_network begin
578
+
@observables begin
579
+
Xtot ~ X + XY
580
+
Ytot ~ Y + XY
581
+
end
582
+
(pX,dX), 0 <--> X
583
+
(pY,dY), 0 <--> Y
584
+
(kB,kD), X + Y <--> XY
585
+
end
586
+
```
587
+
The `@observables` option is followed by one line for each observable formula (enclosed by a `begin ... end` block). The left-hand sides indicate the observables' names, and the right-hand sides how their values are computed. The two sides are separated by a `~`.
we can index the solution using our observables (just like for [other variables](@ref simulation_structure_interfacing_solutions)). E.g. we can receive a vector with all $Xtot$ values using
600
+
```@example obs1
601
+
sol[:Xtot]
602
+
```
603
+
similarly, we can plot the values of $Xtot$ and $Ytot$ using
If we only wish to provide a single observable, the `begin ... end` block is note required. E.g., to record only the total amount of $X$ we can use:
609
+
```@example obs1
610
+
using Catalyst # hide
611
+
rn = @reaction_network begin
612
+
@observables Xtot ~ X + XY
613
+
(pX,dX), 0 <--> X
614
+
(pY,dY), 0 <--> Y
615
+
(kB,kD), X + Y <--> XY
616
+
end
617
+
```
618
+
619
+
Finally, some general rules for creating observables:
620
+
- Observables can depend on any species, parameters, or variables, but not on other observables.
621
+
- All observables components appearing on the right side of the `~` must be declared somewhere (i.e., they cannot only appear as a part of the observables formula).
622
+
- Only a single `@observables` option block can be used in each `@reaction_network` call.
623
+
- The left-hand side of the observables expression must be a single symbol, indicating the observable's name.
624
+
- Metadata can, however, be provided, e.g through `@observables (Xtot, [description="Total amount of X"]) ~ X + XY`.
625
+
- The right-hand side of the observables expression can be any valid algebraic expression.
626
+
- Observables are (by default, but this can be changed) considered `variables` (and not `species`). This can be changed by e.g. pre-declaring them using the `@species` option:
isempty(ivs) ||error("An observable ($obs_name) was given independent variable(s). These should not be given, as they are inferred automatically.")
706
+
isnothing(defaults) ||error("An observable ($obs_name) was given a default value. This is forbidden.")
707
+
in(obs_name, forbidden_symbols_error) &&error("A forbidden symbol ($(obs_eq.args[2])) was used as an observable name.")
708
+
709
+
# Error checks.
710
+
if (obs_name in species_n_vars_declared) &&is_escaped_expr(obs_eq.args[2])
711
+
error("An interpoalted observable have been used, which has also been explicitly delcared within the system using eitehr @species or @variables. This is not permited.")
712
+
end
713
+
if ((obs_name in species_n_vars_declared) ||is_escaped_expr(obs_eq.args[2])) &&!isnothing(metadata)
714
+
error("Metadata was provided to observable $obs_name in the `@observables` macro. However, the obervable was also declared separately (using either @species or @variables). When this is done, metadata should instead be provided within the original @species or @variable declaration.")
715
+
end
716
+
717
+
# This bits adds the observables to the @variables vector which is given as output.
718
+
# For Observables that have already been declared using @species/@variables,
719
+
# or are interpolated, this parts should not be carried out.
720
+
if!((obs_name in species_n_vars_declared) ||is_escaped_expr(obs_eq.args[2]))
721
+
# Appends (..) to the observable (which is later replaced with the extracted ivs).
722
+
# Adds the observable to the first line of the output expression (starting with `@variables`).
0 commit comments