@@ -221,7 +221,7 @@ struct DSLReaction
221
221
subs = recursive_find_reactants! (sub_line, 1 , Vector {DSLReactant} (undef, 0 ))
222
222
prods = recursive_find_reactants! (prod_line, 1 , Vector {DSLReactant} (undef, 0 ))
223
223
metadata = extract_metadata (metadata_line)
224
- new (sub, prod , rate, metadata, rx_line)
224
+ new (subs, prods , rate, metadata, rx_line)
225
225
end
226
226
end
227
227
@@ -232,13 +232,13 @@ end
232
232
function recursive_find_reactants! (ex:: ExprValues , mult:: ExprValues ,
233
233
reactants:: Vector{DSLReactant} )
234
234
# We have reached the end of the expression tree and can finalise and return the reactants.
235
- if typeof (ex) != Expr || (ex. head == :escape ) || (ex. head == :ref )
235
+ if ( typeof (ex) != Expr) || (ex. head == :escape ) || (ex. head == :ref )
236
236
# The final bit of the expression is not a relevant reactant, no additions are required.
237
237
(ex == 0 || in (ex, empty_set)) && (return reactants)
238
238
239
239
# If the expression corresponds to a reactant on our list, increase its multiplicity.
240
- if any (ex == reactant . reactant for reactant in reactants)
241
- idx = findfirst (r . reactant == ex for r in reactants )
240
+ idx = findfirst (r . reactant == ex for r in reactants)
241
+ if ! isnothing (idx )
242
242
new_mult = processmult (+ , mult, reactants[idx]. stoichiometry)
243
243
reactants[idx] = DSLReactant (ex, new_mult)
244
244
@@ -324,12 +324,13 @@ function make_reaction_system(ex::Expr, name)
324
324
325
325
# Reads options (round 1, options which must be read before the reactions, e.g. because
326
326
# they might declare parameters/species/variables).
327
+ requiredec = haskey (options, :require_declaration )
327
328
compound_expr_init, compound_species = read_compound_options (options)
328
329
species_declared = [extract_syms (options, :species ); compound_species]
329
330
parameters_declared = extract_syms (options, :parameters )
330
331
variables_declared = extract_syms (options, :variables )
331
332
vars_extracted, add_default_diff, equations = read_equations_options (options,
332
- variables_declared)
333
+ variables_declared; requiredec )
333
334
334
335
# Extracts all reactions. Extracts all parameters, species, and variables of the system and
335
336
# creates lists with them.
@@ -338,31 +339,29 @@ function make_reaction_system(ex::Expr, name)
338
339
syms_declared = Set (Iterators. flatten ((parameters_declared, species_declared,
339
340
variables)))
340
341
species_extracted, parameters_extracted = extract_species_and_parameters (reactions,
341
- syms_declared)
342
+ syms_declared; requiredec )
342
343
species = vcat (species_declared, species_extracted)
343
344
parameters = vcat (parameters_declared, parameters_extracted)
344
345
345
346
# Reads options (round 2, options that either can, or must, be read after the reactions).
346
- tiv, sivs, ivs, ivexpr = read_ivs_option (options)
347
+ tiv, sivs, ivs, ivsexpr = read_ivs_option (options)
347
348
continuous_events_expr = read_events_option (options, :continuous_events )
348
349
discrete_events_expr = read_events_option (options, :discrete_events )
349
- observed_expr , observed_eqs, obs_syms = read_observed_options (options,
350
- [species_declared; variables], ivs)
350
+ obsexpr , observed_eqs, obs_syms = read_observed_options (options,
351
+ [species_declared; variables], ivs; requiredec )
351
352
diffexpr = create_differential_expr (options, add_default_diff,
352
353
[species; parameters; variables], tiv)
353
354
default_reaction_metadata = read_default_noise_scaling_option (options)
354
355
combinatoric_ratelaws = read_combinatoric_ratelaws_option (options)
355
356
356
357
# Checks for input errors.
357
- if (sum (length, [reaction_lines, option_lines]) != length (ex. args))
358
- error (" @reaction_network input contain $(length (ex. args) - sum (length .([reaction_lines,option_lines]))) malformed lines." )
359
- end
360
- if any (! in (opt_in, option_keys) for opt_in in keys (options))
361
- error (" The following unsupported options were used: $(filter (opt_in-> ! in (opt_in,option_keys), keys (options))) " )
362
- end
363
358
forbidden_symbol_check (union (species, parameters))
364
359
forbidden_variable_check (variables)
365
360
unique_symbol_check (vcat (species, parameters, variables, ivs))
361
+ (sum (length, [reaction_lines, option_lines]) != length (ex. args)) &&
362
+ error (" @reaction_network input contain $(length (ex. args) - sum (length .([reaction_lines,option_lines]))) malformed lines." )
363
+ any (! in (option_keys), keys (options)) &&
364
+ error (" The following unsupported options were used: $(filter (opt_in-> ! in (opt_in,option_keys), keys (options))) " )
366
365
367
366
# Creates expressions corresponding to actual code from the internal DSL representation.
368
367
psexpr_init = get_pexpr (parameters_extracted, options)
@@ -371,35 +370,37 @@ function make_reaction_system(ex::Expr, name)
371
370
psexpr, psvar = scalarize_macro (psexpr_init, " ps" )
372
371
spsexpr, spsvar = scalarize_macro (spsexpr_init, " specs" )
373
372
vsexpr, vsvar = scalarize_macro (vsexpr_init, " vars" )
374
- compound_expr, compsvar = scalarize_macro (compound_expr_init, " comps" )
373
+ cmpsexpr, cmpsvar = scalarize_macro (compound_expr_init, " comps" )
375
374
rxsexprs = make_rxsexprs (reactions, equations)
376
375
377
376
# Assemblies the full expression that declares all required symbolic variables, and
378
377
# then the output `ReactionSystem`.
379
- quote
378
+ MacroTools. flatten (striplines (quote
379
+ # Inserts the expressions which generates the `ReactionSystem` input.
380
+ $ ivsexpr
380
381
$ psexpr
381
- $ ivexpr
382
382
$ spsexpr
383
383
$ vsexpr
384
- $ observed_expr
385
- $ compound_expr
384
+ $ obsexpr
385
+ $ cmpsexpr
386
386
$ diffexpr
387
387
388
- sivs_vec = $ sivs
389
- rx_eq_vec = $ rxexprs
390
- vars = setdiff (union ($ spssym, $ varssym, $ compssym), $ obs_syms)
391
- obseqs = $ observed_eqs
392
- cevents = $ continuous_events_expr
393
- devents = $ discrete_events_expr
388
+ # Stores each kwarg in a variable. Not necessary but useful when inspecting code for debugging.
389
+ name = $ name
390
+ spatial_ivs = $ sivs
391
+ rx_eq_vec = $ rxsexprs
392
+ vars = setdiff (union ($ spsvar, $ vsvar, $ cmpsvar), $ obs_syms)
393
+ observed = $ observed_eqs
394
+ continuous_events = $ continuous_events_expr
395
+ discrete_events = $ discrete_events_expr
396
+ combinatoric_ratelaws = $ combinatoric_ratelaws
397
+ default_reaction_metadata = $ default_reaction_metadata
394
398
395
399
remake_ReactionSystem_internal (
396
- make_ReactionSystem_internal (
397
- rx_eq_vec, $ tiv, vars, $ pssym;
398
- name = $ name, spatial_ivs = sivs_vec, observed = obseqs,
399
- continuous_events = cevents, discrete_events = devents,
400
- combinatoric_ratelaws = $ combinatoric_ratelaws);
401
- default_reaction_metadata = $ default_reaction_metadata)
402
- end
400
+ make_ReactionSystem_internal (rx_eq_vec, $ tiv, vars, $ psvar; name, spatial_ivs,
401
+ observed, continuous_events, discrete_events, combinatoric_ratelaws);
402
+ default_reaction_metadata)
403
+ end ))
403
404
end
404
405
405
406
# ## DSL Reaction Reading Functions ###
@@ -451,7 +452,7 @@ function read_reaction_line(line::Expr)
451
452
452
453
# Handles metadata. If not provided, empty metadata is created.
453
454
if length (line. args) == 2
454
- in (arrow, double_arrows) ? :(([], [])) : :([])
455
+ metadata = in (arrow, double_arrows) ? :(([], [])) : :([])
455
456
elseif length (line. args) == 3
456
457
metadata = line. args[3 ]
457
458
else
511
512
512
513
# Function looping through all reactions, to find undeclared symbols (species or
513
514
# parameters) and assign them to the right category.
514
- function extract_species_and_parameters (reactions, excluded_syms)
515
+ function extract_species_and_parameters (reactions, excluded_syms; requiredec = false )
515
516
# Loops through all reactant, extract undeclared ones as species.
516
517
species = OrderedSet {Union{Symbol, Expr}} ()
517
518
for reaction in reactions
@@ -649,17 +650,17 @@ function read_ivs_option(options)
649
650
# Creates the independent variables expressions (depends on whether the `ivs` option was used).
650
651
if haskey (options, :ivs )
651
652
ivs = Tuple (extract_syms (options, :ivs ))
652
- ivexpr = copy (options[:ivs ])
653
- ivexpr . args[1 ] = Symbol (" @" , " parameters" )
653
+ ivsexpr = copy (options[:ivs ])
654
+ ivsexpr . args[1 ] = Symbol (" @" , " parameters" )
654
655
else
655
656
ivs = (DEFAULT_IV_SYM,)
656
- ivexpr = :($ (DEFAULT_IV_SYM) = default_t ())
657
+ ivsexpr = :($ (DEFAULT_IV_SYM) = default_t ())
657
658
end
658
659
659
660
# Extracts the independet variables symbols (time and spatial), and returns the output.
660
661
tiv = ivs[1 ]
661
662
sivs = (length (ivs) > 1 ) ? Expr (:vect , ivs[2 : end ]. .. ) : nothing
662
- return tiv, sivs, ivs, ivexpr
663
+ return tiv, sivs, ivs, ivsexpr
663
664
end
664
665
665
666
# Returns the `default_reaction_metadata` output. Technically Catalyst's code could have been made
977
978
# Reads a single line and creates the corresponding DSLReaction.
978
979
function get_reaction (line)
979
980
reaction = get_reactions ([line])
980
- if (length (reaction) != 1 )
981
+ (length (reaction) != 1 ) &&
981
982
error (" Malformed reaction. @reaction macro only creates a single reaction. E.g. double arrows, such as `<-->` are not supported." )
982
- end
983
983
return only (reaction)
984
984
end
985
985
0 commit comments