Skip to content

Commit 54ea053

Browse files
committed
add reaction/equation printing
1 parent 3aa68ad commit 54ea053

File tree

3 files changed

+17
-17
lines changed

3 files changed

+17
-17
lines changed

src/Catalyst.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,8 @@ export symmap_to_varmap
122122
# reaction_network macro
123123
include("expression_utils.jl")
124124
include("dsl.jl")
125-
export @reaction_network, @network_component, @reaction, @species, UndeclaredSymbolicError
125+
export @reaction_network, @network_component, @reaction, @species
126+
126127

127128
# Network analysis functionality.
128129
include("network_analysis.jl")

src/dsl.jl

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -220,19 +220,17 @@ struct ReactionStruct
220220
products::Vector{ReactantStruct}
221221
rate::ExprValues
222222
metadata::Expr
223+
rxexpr::Expr
223224

224225
function ReactionStruct(sub_line::ExprValues, prod_line::ExprValues, rate::ExprValues,
225-
metadata_line::ExprValues)
226+
metadata_line::ExprValues, rx_line::Expr)
226227
sub = recursive_find_reactants!(sub_line, 1, Vector{ReactantStruct}(undef, 0))
227228
prod = recursive_find_reactants!(prod_line, 1, Vector{ReactantStruct}(undef, 0))
228229
metadata = extract_metadata(metadata_line)
229-
new(sub, prod, rate, metadata)
230+
new(sub, prod, rate, metadata, rx_line)
230231
end
231232
end
232233

233-
#function Base.show(io::IO, rx::ReactionStruct) #
234-
#end
235-
236234
# Recursive function that loops through the reaction line and finds the reactants and their
237235
# stoichiometry. Recursion makes it able to handle weird cases like 2(X+Y+3(Z+XY)).
238236
function recursive_find_reactants!(ex::ExprValues, mult::ExprValues,
@@ -440,15 +438,15 @@ function get_reactions(exprs::Vector{Expr}, reactions = Vector{ReactionStruct}(u
440438
error("Error: Must provide a tuple of reaction rates when declaring a bi-directional reaction.")
441439
end
442440
push_reactions!(reactions, reaction.args[2], reaction.args[3],
443-
rate.args[1], metadata.args[1], arrow)
441+
rate.args[1], metadata.args[1], arrow, line)
444442
push_reactions!(reactions, reaction.args[3], reaction.args[2],
445-
rate.args[2], metadata.args[2], arrow)
443+
rate.args[2], metadata.args[2], arrow, line)
446444
elseif in(arrow, fwd_arrows)
447445
push_reactions!(reactions, reaction.args[2], reaction.args[3],
448-
rate, metadata, arrow)
446+
rate, metadata, arrow, line)
449447
elseif in(arrow, bwd_arrows)
450448
push_reactions!(reactions, reaction.args[3], reaction.args[2],
451-
rate, metadata, arrow)
449+
rate, metadata, arrow, line)
452450
else
453451
throw("Malformed reaction, invalid arrow type used in: $(MacroTools.striplines(line))")
454452
end
@@ -482,7 +480,7 @@ end
482480
# Takes a reaction line and creates reaction(s) from it and pushes those to the reaction array.
483481
# Used to create multiple reactions from, for instance, `k, (X,Y) --> 0`.
484482
function push_reactions!(reactions::Vector{ReactionStruct}, sub_line::ExprValues,
485-
prod_line::ExprValues, rate::ExprValues, metadata::ExprValues, arrow::Symbol)
483+
prod_line::ExprValues, rate::ExprValues, metadata::ExprValues, arrow::Symbol, line::Expr)
486484
# The rates, substrates, products, and metadata may be in a tupple form (e.g. `k, (X,Y) --> 0`).
487485
# This finds the length of these tuples (or 1 if not in tuple forms). Errors if lengs inconsistent.
488486
lengs = (tup_leng(sub_line), tup_leng(prod_line), tup_leng(rate), tup_leng(metadata))
@@ -505,7 +503,7 @@ function push_reactions!(reactions::Vector{ReactionStruct}, sub_line::ExprValues
505503

506504
push!(reactions,
507505
ReactionStruct(get_tup_arg(sub_line, i),
508-
get_tup_arg(prod_line, i), get_tup_arg(rate, i), metadata_i))
506+
get_tup_arg(prod_line, i), get_tup_arg(rate, i), metadata_i, line))
509507
end
510508
end
511509

@@ -532,7 +530,7 @@ function extract_species_and_parameters!(reactions, excluded_syms; requiredec =
532530
for reactant in Iterators.flatten((reaction.substrates, reaction.products))
533531
add_syms_from_expr!(species, reactant.reactant, excluded_syms)
534532
(!isempty(species) && requiredec) && throw(UndeclaredSymbolicError(
535-
"Unrecognized variables $(species[1]) detected in reaction expression. Since the flag @require_declaration is declared, all species must be explicitly declared with the @species macro."))
533+
"Unrecognized variables $(join(species, ", ")) detected in reaction expression: \"$(string(reaction.rxexpr))\". Since the flag @require_declaration is declared, all species must be explicitly declared with the @species macro."))
536534
end
537535
end
538536

@@ -541,11 +539,11 @@ function extract_species_and_parameters!(reactions, excluded_syms; requiredec =
541539
for reaction in reactions
542540
add_syms_from_expr!(parameters, reaction.rate, excluded_syms)
543541
(!isempty(parameters) && requiredec) && throw(UndeclaredSymbolicError(
544-
"Unrecognized parameter $(parameters[1]) detected in rate expression $(reaction.rate). Since the flag @require_declaration is declared, all parameters must be explicitly declared with the @parameters macro."))
542+
"Unrecognized parameter $(join(parameters, ", ")) detected in rate expression: $(reaction.rate) for the following reaction expression: \"$(string(reaction.rxexpr))\". Since the flag @require_declaration is declared, all parameters must be explicitly declared with the @parameters macro."))
545543
for reactant in Iterators.flatten((reaction.substrates, reaction.products))
546544
add_syms_from_expr!(parameters, reactant.stoichiometry, excluded_syms)
547545
(!isempty(parameters) && requiredec) && throw(UndeclaredSymbolicError(
548-
"Unrecognized parameters $(parameters[1]) detected in the stoichiometry for reactant $(reactant.reactant). Since the flag @require_declaration is declared, all parameters must be explicitly declared with the @parameters macro."))
546+
"Unrecognized parameters $(join(parameters, ", ")) detected in the stoichiometry for reactant $(reactant.reactant) in the following reaction expression: \"$(string(reaction.rxpexpr))\". Since the flag @require_declaration is declared, all parameters must be explicitly declared with the @parameters macro."))
549547
end
550548
end
551549

@@ -734,7 +732,7 @@ function read_equations_options(options, variables_declared; requiredec = false)
734732
error("A forbidden symbol ($(diff_var)) was used as an variable in this differential equation: $eq")
735733
elseif (!in(diff_var, variables_declared)) && requiredec
736734
throw(UndeclaredSymbolicError(
737-
"Unrecognized symbol $(diff_var) was used as a variable in an equation. Since the @require_declaration flag is set, all variables in equations must be explicitly declared via @variables, @species, or @parameters."))
735+
"Unrecognized symbol $(diff_var) was used as a variable in an equation: \"$eq\". Since the @require_declaration flag is set, all variables in equations must be explicitly declared via @variables, @species, or @parameters."))
738736
else
739737
add_default_diff = true
740738
in(diff_var, variables_declared) || push!(vars_extracted, diff_var)
@@ -790,7 +788,7 @@ function read_observed_options(options, species_n_vars_declared, ivs_sorted; req
790788
obs_name, ivs, defaults, metadata = find_varinfo_in_declaration(obs_eq.args[2])
791789
if (requiredec && !in(obs_name, species_n_vars_declared))
792790
throw(UndeclaredSymbolicError(
793-
"An undeclared variable ($obs_name) was declared as an observable. Since the flag @require_declaration is set, all variables must be declared with the @species, @parameters, or @variables macros."))
791+
"An undeclared variable ($obs_name) was declared as an observable in the following observable equation: \"$obs_eq\". Since the flag @require_declaration is set, all variables must be declared with the @species, @parameters, or @variables macros."))
794792
end
795793
isempty(ivs) ||
796794
error("An observable ($obs_name) was given independent variable(s). These should not be given, as they are inferred automatically.")

test/dsl/dsl_options.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1025,6 +1025,7 @@ end
10251025

10261026
### test that @no_infer properly throws errors when undeclared variables are written
10271027

1028+
import Catalyst: UndeclaredSymbolicError
10281029
let
10291030
# Test error when species are inferred
10301031
@test_throws UndeclaredSymbolicError @macroexpand rn = @reaction_network begin

0 commit comments

Comments
 (0)