Skip to content

Commit 543b1bf

Browse files
committed
up
1 parent c68c5c1 commit 543b1bf

File tree

1 file changed

+22
-8
lines changed

1 file changed

+22
-8
lines changed

src/reaction_network.jl

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -360,14 +360,16 @@ function make_reaction_system(ex::Expr; name = :(gensym(:ReactionSystem)))
360360

361361
# Reads options.
362362
compound_expr, compound_species = read_compound_options(options)
363-
observed_vars, observed_eqs = read_observed_options(options)
364363

365364
# Parses reactions, species, and parameters.
366365
reactions = get_reactions(reaction_lines)
367366
species_declared = [extract_syms(options, :species); compound_species]
368367
parameters_declared = extract_syms(options, :parameters)
369368
variables = extract_syms(options, :variables)
370369

370+
# Reads more options.
371+
observed_vars, observed_eqs = read_observed_options(options, [species_declared; variables])
372+
371373
# handle independent variables
372374
if haskey(options, :ivs)
373375
ivs = Tuple(extract_syms(options, :ivs))
@@ -688,19 +690,31 @@ end
688690
# Most options handled in previous sections, when code re-organised, these should ideally be moved to the same place.
689691

690692
# Reads the observables options. Outputs an expression ofr creating the obervable variables, and a vector of observable equations.
691-
function read_observed_options(options)
693+
function read_observed_options(options, species_declared)
692694
if haskey(options, :observables)
693695
# Gets list of observable equations and prepares variable declaration expression.
694696
# (`options[:observables]` inlucdes `@observables`, `.args[3]` removes this part)
695697
observed_eqs = make_observed_eqs(options[:observables].args[3])
696-
observed_vars = :(@variables)
698+
observed_vars = Expr(:block, :(@variables))
697699

698-
# For each observable, checks for errors and adds the variable to `observed_vars`.
699700
for obs_eq in observed_eqs.args
700-
(obs_eq.args[1] != :~) && error("Malformed observable formula :\"$(obs_eq)\". Formula should contain two expressions separated by a '~'.")
701-
(obs_eq.args[2] isa Symbol) || error("Malformed observable formula :\"$(obs_eq)\". Left hand side should be a single symbol.")
702-
in(obs_eq.args[2], forbidden_symbols_error) && error("A forbidden symbol ($(obs_eq.args[2])) was used as an observable name.")
703-
push!(observed_vars.args, obs_eq.args[2])
701+
# Extract the observable, checks errors, and continues the loop if the observable has been declared.
702+
obs_name, ivs, defaults, _ = find_varinfo_in_declaration(obs_eq.args[2])
703+
isempty(ivs) || error("An observable ($obs_name) was given independent variable(s). These should not be given, as they are inferred automatically.")
704+
isnothing(defaults) || error("An observable ($obs_name) was given a default value. This is forbidden.")
705+
in(obs_name, forbidden_symbols_error) && error("A forbidden symbol ($(obs_eq.args[2])) was used as an observable name.")
706+
(obs_name in species_declared) && continue
707+
708+
# Appends (..) to the observable (which is later replaced with the extracted ivs).
709+
# Adds the observable to the first line of the output expression (starting with `@variables`).
710+
obs_expr = insert_independent_variable(obs_eq.args[2], :(..))
711+
push!(observed_vars.args[1].args, obs_expr)
712+
713+
# Adds a line to the `observed_vars` expression, setting the ivs for this observable.
714+
dependants = [rs.reactant for rs in
715+
Catalyst.recursive_find_reactants!(obs_eq.args[3], 1, Vector{ReactantStruct}(undef, 0))]
716+
ivs_get_expr = :(unique(reduce(vcat,[arguments(ModelingToolkit.unwrap(dep)) for dep in $dependants])))
717+
push!(observed_vars.args, :($obs_name = $(obs_name)($(ivs_get_expr)...)))
704718
end
705719
else
706720
# If option is not used, return empty expression and vector.

0 commit comments

Comments
 (0)