Skip to content

Commit 8fbdc46

Browse files
authored
Merge pull request #931 from SciML/serialization_updates
`ReactionSystem` serialisation update
2 parents 59294a5 + e575fb5 commit 8fbdc46

File tree

5 files changed

+62
-7
lines changed

5 files changed

+62
-7
lines changed

src/reactionsystem_serialisation/serialisation_support.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,8 @@ end
247247
function make_strip_call_dict(syms)
248248
return Dict([sym => strip_call(Symbolics.unwrap(sym)) for sym in syms])
249249
end
250+
251+
# If the input is a `ReactionSystem`, extracts the unknowns (i.e. syms depending on another variable).
250252
function make_strip_call_dict(rn::ReactionSystem)
251253
return make_strip_call_dict(get_unknowns(rn))
252254
end

src/reactionsystem_serialisation/serialise_fields.jl

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ EQUATIONS_FS = (seri_has_equations, get_equations_string, get_equations_annotati
308308

309309
# Checks if the reaction system has any observables.
310310
function seri_has_observed(rn::ReactionSystem)
311-
return !isempty(observed(rn))
311+
return !isempty(get_observed(rn))
312312
end
313313

314314
# Extract a string which declares the system's observables.
@@ -354,6 +354,27 @@ end
354354
# Combines the 3 -related functions in a constant tuple.
355355
OBSERVED_FS = (seri_has_observed, get_observed_string, get_observed_annotation)
356356

357+
### Handles Observables ###
358+
359+
# Checks if the reaction system has any defaults.
360+
function seri_has_defaults(rn::ReactionSystem)
361+
return !isempty(get_defaults(rn))
362+
end
363+
364+
# Extract a string which declares the system's defaults.
365+
function get_defaults_string(rn::ReactionSystem)
366+
defaults_string = "defaults = " * x_2_string(get_defaults(rn))
367+
return defaults_string
368+
end
369+
370+
# Creates an annotation for the system's defaults.
371+
function get_defaults_annotation(rn::ReactionSystem)
372+
return "Defaults:"
373+
end
374+
375+
# Combines the 3 defaults-related functions in a constant tuple.
376+
DEFAULTS_FS = (seri_has_defaults, get_defaults_string, get_defaults_annotation)
377+
357378
### Handles Continuous Events ###
358379

359380
# Checks if the reaction system have has continuous events.

src/reactionsystem_serialisation/serialise_reactionsystem.jl

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,13 @@ Notes:
3434
"""
3535
function save_reactionsystem(filename::String, rn::ReactionSystem;
3636
annotate = true, safety_check = true)
37+
# Error and warning checks.
3738
reactionsystem_uptodate_check()
39+
if !isempty(get_networkproperties(rn))
40+
@warn "The serialised network has cached network properties (e.g. computed conservation laws). This will not be saved as part of the network, and must be recomputed when it is loaded."
41+
end
42+
43+
# Write model to file and performs a safety check.
3844
open(filename, "w") do file
3945
write(file, get_full_system_string(rn, annotate, true))
4046
end
@@ -65,6 +71,7 @@ function get_full_system_string(rn::ReactionSystem, annotate::Bool, top_level::B
6571
file_text, has_reactions = push_field(file_text, rn, annotate, top_level, REACTIONS_FS)
6672
file_text, has_equations = push_field(file_text, rn, annotate, top_level, EQUATIONS_FS)
6773
file_text, has_observed = push_field(file_text, rn, annotate, top_level, OBSERVED_FS)
74+
file_text, has_defaults = push_field(file_text, rn, annotate, top_level, DEFAULTS_FS)
6875
file_text, has_continuous_events = push_field(file_text, rn, annotate,
6976
top_level, CONTINUOUS_EVENTS_FS)
7077
file_text, has_discrete_events = push_field(file_text, rn, annotate,
@@ -78,7 +85,7 @@ function get_full_system_string(rn::ReactionSystem, annotate::Bool, top_level::B
7885
rs_creation_code = make_reaction_system_call(
7986
rn, annotate, top_level, has_sivs, has_species,
8087
has_variables, has_parameters, has_reactions,
81-
has_equations, has_observed, has_continuous_events,
88+
has_equations, has_observed, has_defaults, has_continuous_events,
8289
has_discrete_events, has_systems, has_connection_type)
8390
annotate || (@string_prepend! "\n" file_text)
8491
@string_prepend! "let" file_text
@@ -89,11 +96,10 @@ end
8996

9097
# Creates a ReactionSystem call for creating the model. Adds all the correct inputs to it. The input
9198
# `has_` `Bool`s described which inputs are used. If the model is `complete`, this is handled here.
92-
function make_reaction_system_call(
93-
rs::ReactionSystem, annotate, top_level, has_sivs, has_species,
94-
has_variables, has_parameters, has_reactions, has_equations,
95-
has_observed, has_continuous_events, has_discrete_events,
96-
has_systems, has_connection_type)
99+
function make_reaction_system_call(rs::ReactionSystem, annotate, top_level, has_sivs,
100+
has_species, has_variables, has_parameters, has_reactions, has_equations,
101+
has_observed, has_defaults, has_continuous_events, has_discrete_events, has_systems,
102+
has_connection_type)
97103

98104
# Gets the independent variable input.
99105
iv = x_2_string(get_iv(rs))
@@ -141,6 +147,7 @@ function make_reaction_system_call(
141147
# Goes through various fields that might exists, and if so, adds them to the string.
142148
has_sivs && (@string_append! reaction_system_string ", spatial_ivs")
143149
has_observed && (@string_append! reaction_system_string ", observed")
150+
has_defaults && (@string_append! reaction_system_string ", defaults")
144151
has_continuous_events && (@string_append! reaction_system_string ", continuous_events")
145152
has_discrete_events && (@string_append! reaction_system_string ", discrete_events")
146153
has_systems && (@string_append! reaction_system_string ", systems")

test/failed_serialisation.jl

Whitespace-only changes.

test/miscellaneous_tests/reactionsystem_serialisation.jl

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,30 @@ end
400400

401401
### Other Tests ###
402402

403+
# Checks that systems with cached network properties yields a warning.
404+
# Checks that default values as saved properly (even if they have different types).
405+
let
406+
# Prepares model inputs.
407+
@species X1(t) X2(t)
408+
@parameters k1 k2::Int64
409+
rxs = [
410+
Reaction(k1, [X1], [X2]),
411+
Reaction(k2, [X2], [X1])
412+
]
413+
defaults = Dict((X1 => 1.0, k2 => 2))
414+
415+
# Creates model and computes conservation laws.
416+
@named rs = ReactionSystem(rxs, t; defaults)
417+
conservationlaws(rs)
418+
419+
# Serialises model and then loads and checks it.
420+
@test_logs (:warn, ) match_mode=:any save_reactionsystem("serialised_rs.jl", rs)
421+
rs_loaded = include("../serialised_rs.jl")
422+
@test rs == rs_loaded
423+
@test ModelingToolkit.get_defaults(rs) == ModelingToolkit.get_defaults(rs_loaded)
424+
rm("serialised_rs.jl")
425+
end
426+
403427
# Tests that an error is generated when non-`ReactionSystem` subs-systems are used.
404428
let
405429
@variables V(t)
@@ -415,6 +439,7 @@ let
415439
@named osys = ODESystem([eq], t)
416440
@named rs = ReactionSystem(rxs, t; systems = [osys])
417441
@test_throws Exception save_reactionsystem("failed_serialisation.jl", rs)
442+
rm("failed_serialisation.jl")
418443
end
419444

420445
# Checks that completeness is recorded correctly.

0 commit comments

Comments
 (0)