Skip to content

Commit e231734

Browse files
committed
add additional tests, use argumenterror where appropriate
1 parent 5b6d6ec commit e231734

9 files changed

+181
-37
lines changed

src/spatial_reaction_systems/lattice_jump_systems.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ function JumpProcesses.JumpProblem(lrs::LatticeReactionSystem, dprob, aggregator
3030
combinatoric_ratelaws = get_combinatoric_ratelaws(reactionsystem(lrs)), kwargs...)
3131
# Error checks.
3232
if !isnothing(dprob.f.sys)
33-
error("Unexpected `DiscreteProblem` passed into `JumpProblem`. Was a `LatticeReactionSystem` used as input to the initial `DiscreteProblem`?")
33+
throw(ArgumentError("Unexpected `DiscreteProblem` passed into `JumpProblem`. Was a `LatticeReactionSystem` used as input to the initial `DiscreteProblem`?"))
3434
end
3535

3636
# Computes hopping constants and mass action jumps (requires some internal juggling).

src/spatial_reaction_systems/lattice_reaction_systems.jl

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -51,19 +51,22 @@ struct LatticeReactionSystem{Q,R,S,T} <: MT.AbstractTimeDependentSystem
5151
num_verts::Int64, num_edges::Int64, edge_iterator::T) where {Q,R,S,T}
5252
# Error checks.
5353
if !(R <: AbstractSpatialReaction)
54-
error("The second argument must be a vector of AbstractSpatialReaction subtypes.")
54+
throw(ArgumentError("The second argument must be a vector of AbstractSpatialReaction subtypes."))
55+
end
56+
if !iscomplete(rs)
57+
throw(ArgumentError("A non-complete `ReactionSystem` was used as input, this is not permitted."))
5558
end
5659
if !isempty(MT.get_systems(rs))
57-
error("A non-flattened (hierarchical) `ReactionSystem` was used as input. `LatticeReactionSystem`s can only be based on non-hierarchical `ReactionSystem`s.")
60+
throw(ArgumentError("A non-flattened (hierarchical) `ReactionSystem` was used as input. `LatticeReactionSystem`s can only be based on non-hierarchical `ReactionSystem`s."))
5861
end
5962
if length(species(rs)) != length(unknowns(rs))
60-
error("The `ReactionSystem` used as input contain variable unknowns (in addition to species unknowns). This is not permitted (the input `ReactionSystem` must contain species unknowns only).")
63+
throw(ArgumentError("The `ReactionSystem` used as input contain variable unknowns (in addition to species unknowns). This is not permitted (the input `ReactionSystem` must contain species unknowns only)."))
6164
end
6265
if length(reactions(rs)) != length(equations(rs))
63-
error("The `ReactionSystem` used as input contain equations (in addition to reactions). This is not permitted.")
66+
throw(ArgumentError("The `ReactionSystem` used as input contain equations (in addition to reactions). This is not permitted."))
6467
end
6568
if !isempty(MT.continuous_events(rs)) || !isempty(MT.discrete_events(rs))
66-
@warn "The `ReactionSystem` used as input to `LatticeReactionSystem contain events. These will be ignored in any simulations based on the created `LatticeReactionSystem`."
69+
throw(ArgumentError("The `ReactionSystem` used as input to `LatticeReactionSystem contain events. These will be ignored in any simulations based on the created `LatticeReactionSystem`."))
6770
end
6871
if !isempty(observed(rs))
6972
@warn "The `ReactionSystem` used as input to `LatticeReactionSystem contain observables. It will not be possible to access these from the created `LatticeReactionSystem`."
@@ -295,7 +298,7 @@ E.g. for a lattice `CartesianGrid(4,6)`, `(4,6)` is returned.
295298
grid_size(lrs::LatticeReactionSystem) = grid_size(lattice(lrs))
296299
grid_size(lattice::CartesianGridRej{N,T}) where {N,T} = lattice.dims
297300
grid_size(lattice::Array{Bool, N}) where {N} = size(lattice)
298-
grid_size(lattice::Graph) = error("Grid size is only defined for LatticeReactionSystems with grid-based lattices (not graph-based).")
301+
grid_size(lattice::Graphs.AbstractGraph) = throw(ArgumentError("Grid size is only defined for LatticeReactionSystems with grid-based lattices (not graph-based)."))
299302

300303
"""
301304
grid_dims(lrs::LatticeReactionSystem)
@@ -305,7 +308,7 @@ The output is either `1`, `2`, or `3`.
305308
"""
306309
grid_dims(lrs::LatticeReactionSystem) = grid_dims(lattice(lrs))
307310
grid_dims(lattice::GridLattice{N,T}) where {N,T} = return N
308-
grid_dims(lattice::Graph) = error("Grid dimensions is only defined for LatticeReactionSystems with grid-based lattices (not graph-based).")
311+
grid_dims(lattice::Graphs.AbstractGraph) = throw(ArgumentError("Grid dimensions is only defined for LatticeReactionSystems with grid-based lattices (not graph-based)."))
309312

310313
"""
311314
get_lattice_graph(lrs::LatticeReactionSystem)
@@ -333,7 +336,6 @@ reactions(lrs::LatticeReactionSystem) = reactions(reactionsystem(lrs))
333336
MT.nameof(lrs::LatticeReactionSystem) = MT.nameof(reactionsystem(lrs))
334337
MT.get_iv(lrs::LatticeReactionSystem) = MT.get_iv(reactionsystem(lrs))
335338
MT.equations(lrs::LatticeReactionSystem) = MT.equations(reactionsystem(lrs))
336-
MT.equations(lrs::LatticeReactionSystem) = MT.equations(reactionsystem(lrs))
337339
MT.unknowns(lrs::LatticeReactionSystem) = MT.unknowns(reactionsystem(lrs))
338340
MT.get_metadata(lrs::LatticeReactionSystem) = MT.get_metadata(reactionsystem(lrs))
339341

src/spatial_reaction_systems/spatial_ODE_systems.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ function build_odefunction(lrs::LatticeReactionSystem, vert_ps::Vector{Pair{R,Ve
208208
remove_conserved, checks) where {R,S,T}
209209
# Error check.
210210
if remove_conserved
211-
error("Removal of conserved quantities is currently not supported for `LatticeReactionSystem`s")
211+
throw(ArgumentError("Removal of conserved quantities is currently not supported for `LatticeReactionSystem`s"))
212212
end
213213

214214
# Prepares the inputs to the `LatticeTransportODEFunction` functor.

src/spatial_reaction_systems/spatial_reactions.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,5 +165,5 @@ function find_parameters_in_rate!(parameters, rateex::ExprValues)
165165
find_parameters_in_rate!(parameters, rateex.args[i])
166166
end
167167
end
168-
nothing
168+
return nothing
169169
end

src/spatial_reaction_systems/utility.jl

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,10 @@ end
5555
function lattice_process_input(input::Dict{<:Any, T}, syms::Vector) where {T}
5656
# Error checks
5757
if !isempty(setdiff(keys(input), syms))
58-
error("You have provided values for the following unrecognised parameters/initial conditions: $(setdiff(keys(input), syms)).")
58+
throw(ArgumentError("You have provided values for the following unrecognised parameters/initial conditions: $(setdiff(keys(input), syms))."))
5959
end
6060
if !isempty(setdiff(syms, keys(input)))
61-
error("You have not provided values for the following parameters/initial conditions: $(setdiff(syms, keys(input))).")
61+
throw(ArgumentError("You have not provided values for the following parameters/initial conditions: $(setdiff(syms, keys(input)))."))
6262
end
6363

6464
return [sym => input[sym] for sym in syms]
@@ -67,7 +67,7 @@ function lattice_process_input(input, syms::Vector)
6767
if ((input isa Vector) || (input isa Tuple)) && all(entry isa Pair for entry in input)
6868
return lattice_process_input(Dict(input), syms)
6969
end
70-
error("Input parameters/initial conditions have the wrong format ($(typeof(input))). These should either be a Dictionary, or a Tuple or a Vector (where each entry is a Pair taking a parameter/species to its value).")
70+
throw(ArgumentError("Input parameters/initial conditions have the wrong format ($(typeof(input))). These should either be a Dictionary, or a Tuple or a Vector (where each entry is a Pair taking a parameter/species to its value)."))
7171
end
7272

7373
# Splits parameters into vertex and edge parameters.
@@ -100,7 +100,7 @@ function vertex_value_form(values, lrs::LatticeReactionSystem, sym::BasicSymboli
100100
# For the case where the i'th value of the vector corresponds to the value in the i'th vertex.
101101
# This is the only (non-uniform) case possible for graph grids.
102102
if (length(values) != num_verts(lrs))
103-
error("You have provided ($(length(values))) values for $sym. This is not equal to the number of vertices ($(num_verts(lrs))).")
103+
throw(ArgumentError("You have provided ($(length(values))) values for $sym. This is not equal to the number of vertices ($(num_verts(lrs)))."))
104104
end
105105
return values
106106
end
@@ -113,10 +113,10 @@ end
113113
function vertex_value_form(values::AbstractArray, num_verts::Int64, lattice::CartesianGridRej{N,T},
114114
sym::BasicSymbolic) where {N,T}
115115
if size(values) != lattice.dims
116-
error("The values for $sym did not have the same format as the lattice. Expected a $(lattice.dims) array, got one of size $(size(values))")
116+
throw(ArgumentError("The values for $sym did not have the same format as the lattice. Expected a $(lattice.dims) array, got one of size $(size(values))"))
117117
end
118118
if (length(values) != num_verts)
119-
error("You have provided ($(length(values))) values for $sym. This is not equal to the number of vertices ($(num_verts)).")
119+
throw(ArgumentError("You have provided ($(length(values))) values for $sym. This is not equal to the number of vertices ($(num_verts))."))
120120
end
121121
return [values[flat_idx] for flat_idx in 1:num_verts]
122122
end
@@ -125,7 +125,7 @@ end
125125
function vertex_value_form(values::AbstractArray, num_verts::Int64, lattice::Array{Bool,T},
126126
sym::BasicSymbolic) where {T}
127127
if size(values) != size(lattice)
128-
error("The values for $sym did not have the same format as the lattice. Expected a $(size(lattice)) array, got one of size $(size(values))")
128+
throw(ArgumentError("The values for $sym did not have the same format as the lattice. Expected a $(size(lattice)) array, got one of size $(size(values))"))
129129
end
130130

131131
# Pre-declares a vector with the values in each vertex (return_values).
@@ -139,7 +139,7 @@ function vertex_value_form(values::AbstractArray, num_verts::Int64, lattice::Arr
139139

140140
# Checks that the correct number of values was provided, and returns the values.
141141
if (length(return_values) != num_verts)
142-
error("You have provided ($(length(return_values))) values for $sym. This is not equal to the number of vertices ($(num_verts)).")
142+
throw(ArgumentError("You have provided ($(length(return_values))) values for $sym. This is not equal to the number of vertices ($(num_verts))."))
143143
end
144144
return return_values
145145
end
@@ -158,10 +158,10 @@ function edge_value_form(values, lrs::LatticeReactionSystem, sym)
158158

159159
# Error checks.
160160
if nnz(values) != num_edges(lrs)
161-
error("You have provided ($(nnz(values))) values for $sym. This is not equal to the number of edges ($(num_edges(lrs))).")
161+
throw(ArgumentError("You have provided ($(nnz(values))) values for $sym. This is not equal to the number of edges ($(num_edges(lrs)))."))
162162
end
163163
if !all(Base.isstored(values, e[1], e[2]) for e in edge_iterator(lrs))
164-
error("Values was not provided for some edges for edge parameter $sym.")
164+
throw(ArgumentError("Values was not provided for some edges for edge parameter $sym."))
165165
end
166166

167167
# Unlike initial conditions/vertex parameters, (unless uniform) edge parameters' values are
@@ -296,7 +296,7 @@ function compute_edge_value(exp, lrs::LatticeReactionSystem, edge_ps)
296296
# Finds the symbols in the expression. Checks that all correspond to edge parameters.
297297
relevant_syms = Symbolics.get_variables(exp)
298298
if !all(any(isequal(sym, p) for p in edge_parameters(lrs)) for sym in relevant_syms)
299-
error("An non-edge parameter was encountered in expressions: $exp. Here, only edge parameters are expected.")
299+
throw(ArgumentError("An non-edge parameter was encountered in expressions: $exp. Here, only edge parameters are expected."))
300300
end
301301

302302
# Creates a Function tha computes the expressions value for a parameter set.
@@ -320,7 +320,7 @@ function compute_vertex_value(exp, lrs::LatticeReactionSystem; u = [], ps = [])
320320
# Finds the symbols in the expression. Checks that all correspond to unknowns or vertex parameters.
321321
relevant_syms = Symbolics.get_variables(exp)
322322
if any(any(isequal(sym) in edge_parameters(lrs)) for sym in relevant_syms)
323-
error("An edge parameter was encountered in expressions: $exp. Here, only vertex-based components are expected.")
323+
throw(ArgumentError("An edge parameter was encountered in expressions: $exp. Here, only vertex-based components are expected."))
324324
end
325325

326326
# Creates a Function that computes the expressions value for a parameter set.

test/spatial_modelling/lattice_reaction_systems.jl

Lines changed: 105 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,27 @@ include("../spatial_test_networks.jl")
99
# Pre declares a grid.
1010
grids = [very_small_2d_cartesian_grid, very_small_2d_masked_grid, very_small_2d_graph_grid]
1111

12+
### Test Spatial Reactions ###
13+
14+
# Test creation of TransportReaction with non-parameters in rate.
15+
# Tests that it works even when rate is highly nested.
16+
let
17+
@variables t
18+
@species X(t) Y(t)
19+
@parameters D1 D2 D3
20+
@test_throws ErrorException TransportReaction(D1 + D2*(D3 + Y), X)
21+
@test_throws ErrorException TransportReaction(Y, X)
22+
end
23+
24+
# Checks that the `hash` functions works for `TransportReaction`s.
25+
let
26+
tr1 = @transport_reaction D1 X
27+
tr2 = @transport_reaction D1 X
28+
tr3 = @transport_reaction D2 X
29+
hash(tr1, 0x0000000000000001) == hash(tr2, 0x0000000000000001)
30+
hash(tr2, 0x0000000000000001) != hash(tr3, 0x0000000000000001)
31+
end
32+
1233
### Tests LatticeReactionSystem Getters Correctness ###
1334

1435
# Test case 1.
@@ -127,6 +148,37 @@ let
127148
end
128149
end
129150

151+
# Tests using various more obscure types of getters.
152+
let
153+
# Create LatticeReactionsSystems.
154+
t = default_t()
155+
@parameters p d kB kD
156+
@species X(t) X2(t)
157+
rxs = [
158+
Reaction(p, [], [X])
159+
Reaction(d, [X], [])
160+
Reaction(kB, [X], [X2], [2], [1])
161+
Reaction(kD, [X2], [X], [1], [2])
162+
]
163+
@named rs = ReactionSystem(rxs, t; metadata = "Metadata string")
164+
rs = complete(rs)
165+
tr = @transport_reaction D X2
166+
lrs = LatticeReactionSystem(rs, [tr], small_2d_cartesian_grid)
167+
168+
# Generic ones (simply forwards call to the non-spatial system).
169+
@test isequal(reactions(lrs), rxs)
170+
@test isequal(nameof(lrs), :rs)
171+
@test isequal(ModelingToolkit.get_iv(lrs), t)
172+
@test isequal(equations(lrs), rxs)
173+
@test isequal(unknowns(lrs), [X, X2])
174+
@test isequal(ModelingToolkit.get_metadata(lrs), "Metadata string")
175+
@test isequal(ModelingToolkit.get_eqs(lrs), rxs)
176+
@test isequal(ModelingToolkit.get_unknowns(lrs), [X, X2])
177+
@test isequal(ModelingToolkit.get_ps(lrs), [p, d, kB, kD])
178+
@test isequal(ModelingToolkit.get_systems(lrs), [])
179+
@test isequal(independent_variables(lrs), [t])
180+
end
181+
130182
### Tests Spatial Reactions Getters Correctness ###
131183

132184
# Test case 1.
@@ -233,16 +285,6 @@ end
233285

234286
### Tests Error generation ###
235287

236-
# Test creation of TransportReaction with non-parameters in rate.
237-
# Tests that it works even when rate is highly nested.
238-
let
239-
@variables t
240-
@species X(t) Y(t)
241-
@parameters D1 D2 D3
242-
@test_throws ErrorException TransportReaction(D1 + D2*(D3 + Y), X)
243-
@test_throws ErrorException TransportReaction(Y, X)
244-
end
245-
246288
# Network where diffusion species is not declared in non-spatial network.
247289
let
248290
rs = @reaction_network begin
@@ -297,6 +339,59 @@ let
297339
end
298340
end
299341

342+
# Tests various networks with non-permitted content.
343+
let
344+
tr = @transport_reaction D X
345+
346+
# Variable unknowns.
347+
rs1 = @reaction_network begin
348+
@variables V(t)
349+
(p,d), 0 <--> X
350+
end
351+
@test_throws ArgumentError LatticeReactionSystem(rs1, [tr], short_path)
352+
353+
# Non-reaction equations.
354+
rs2 = @reaction_network begin
355+
@equations D(V) ~ X - V
356+
(p,d), 0 <--> X
357+
end
358+
@test_throws ArgumentError LatticeReactionSystem(rs2, [tr], short_path)
359+
360+
# Events.
361+
rs3 = @reaction_network begin
362+
@discrete_events [1.0] => [p ~ p + 1]
363+
(p,d), 0 <--> X
364+
end
365+
@test_throws ArgumentError LatticeReactionSystem(rs3, [tr], short_path)
366+
367+
# Observables (only generates a warning).
368+
rs4 = @reaction_network begin
369+
@observables X2 ~ 2X
370+
(p,d), 0 <--> X
371+
end
372+
@test_logs (:warn, r"The `ReactionSystem` used as input to `LatticeReactionSystem contain observables. It *") match_mode=:any LatticeReactionSystem(rs4, [tr], short_path)
373+
end
374+
375+
# Tests for hierarchical input system.
376+
let
377+
t = default_t()
378+
@parameters d
379+
@species X(t)
380+
rxs = [Reaction(d, [X], [])]
381+
@named rs1 = ReactionSystem(rxs, t)
382+
@named rs2 = ReactionSystem(rxs, t; systems = [rs1])
383+
rs2 = complete(rs2)
384+
@test_throws ArgumentError LatticeReactionSystem(rs2, [tr], short_path)
385+
end
386+
387+
# Tests for non-complete input `ReactionSystem`.
388+
let
389+
tr = @transport_reaction D X
390+
rs = @network_component begin
391+
(p,d), 0 <--> X
392+
end
393+
@test_throws ArgumentError LatticeReactionSystem(rs1, [tr], short_path)
394+
end
300395

301396
### Tests Grid Vertex and Edge Number Computation ###
302397

test/spatial_modelling/lattice_reaction_systems_ODEs.jl

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -547,7 +547,7 @@ let
547547
@test all(isequal.(ss_1, ss_2))
548548
end
549549

550-
### ODEProblem & Integrator Interfacing ###
550+
### ODEProblem & Integrator Interfacing ###
551551

552552
# Checks that basic interfacing with ODEProblem parameters (getting and setting) works.
553553
let
@@ -788,4 +788,41 @@ let
788788
end
789789
end
790790
end
791+
end
792+
793+
794+
### Error Tests ###
795+
796+
# Checks that attempting to remove conserved quantities yields an error.
797+
let
798+
lrs = LatticeReactionSystem(binding_system, binding_srs, very_small_2d_masked_grid)
799+
@test_throws ArgumentError ODEProblem(lrs, binding_u0, (0.0, 10.0), binding_p; remove_conserved = true)
800+
end
801+
802+
# Checks that various erroneous inputs to `ODEProblem` yields errors.
803+
let
804+
# Create `LatticeReactionSystem`.
805+
@parameters d1 d2 D [edgeparameter=true]
806+
@species X1(t) X2(t)
807+
rxs = [Reaction(d1, [X1], [])]
808+
@named rs = ReactionSystem(rxs, t)
809+
rs = complete(rs)
810+
lrs = LatticeReactionSystem(rs, [TransportReaction(D, X1)], CartesianGrid((4,)))
811+
812+
# Attempts to create `ODEProblem` using various faulty inputs.
813+
u0 = [X1 => 1.0]
814+
tspan = (0.0, 1.0)
815+
ps = [d1 => 1.0, D => 0.1]
816+
@test_throws ArgumentError ODEProblem(lrs, [1.0], tspan, ps)
817+
@test_throws ArgumentError ODEProblem(lrs, u0, tspan, [1.0, 0.1])
818+
@test_throws ArgumentError ODEProblem(lrs, [X1 => 1.0, X2 => 2.0], tspan, ps)
819+
@test_throws ArgumentError ODEProblem(lrs, u0, tspan, [d1 => 1.0, d2 => 0.2, D => 0.1])
820+
@test_throws ArgumentError ODEProblem(lrs, [X1 => [1.0, 2.0, 3.0]], tspan, ps)
821+
@test_throws ArgumentError ODEProblem(lrs, u0, tspan, [d1 => [1.0, 2.0, 3.0], D => 0.1])
822+
@test_throws ArgumentError ODEProblem(lrs, [X1 => [1.0 2.0; 3.0 4.0]], tspan, ps)
823+
@test_throws ArgumentError ODEProblem(lrs, u0, tspan, [d1 => [1.0 2.0; 3.0 4.0], D => 0.1])
824+
bad_D_vals_1 = sparse([0.0 1.0 0.0 1.0; 1.0 0.0 1.0 0.0; 0.0 1.0 0.0 1.0; 1.0 0.0 1.0 0.0])
825+
@test_throws ArgumentError ODEProblem(lrs, u0, tspan, [d1 => 1.0, D => bad_D_vals_1])
826+
bad_D_vals_2 = sparse([0.0 0.0 0.0 1.0; 1.0 0.0 1.0 0.0; 0.0 1.0 0.0 1.0; 1.0 0.0 0.0 0.0])
827+
@test_throws ArgumentError ODEProblem(lrs, u0, tspan, [d1 => 1.0, D => bad_D_vals_2])
791828
end

test/spatial_modelling/lattice_reaction_systems_jumps.jl

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,4 +203,14 @@ let
203203
end
204204

205205

206-
### JumpProblem & Integrator Interfacing ###
206+
### JumpProblem & Integrator Interfacing ###
207+
208+
209+
### Other Tests ###
210+
211+
# Checks that providing a non-spatial `DiscreteProblem` to a `JumpProblem` gives an error.
212+
let
213+
lrs = LatticeReactionSystem(binding_system, binding_srs, very_small_2d_masked_grid)
214+
dprob = DiscreteProblem(binding_system, binding_u0, (0.0, 10.0), binding_p[1:2])
215+
@test_throws ArgumentError JumpProblem(lrs, dprob, NSM())
216+
end

0 commit comments

Comments
 (0)