Skip to content

Commit

Permalink
up
Browse files Browse the repository at this point in the history
  • Loading branch information
TorkelE committed Mar 18, 2024
1 parent 99507e6 commit 7dbb02c
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 64 deletions.
2 changes: 1 addition & 1 deletion HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ rn = @reaction_network begin
@parameters η
k, 2X --> X2, [noise_scaling=η]
end
getnoisescaling(rn)
get_noise_scaling(rn)
```
- `SDEProblem` no longer takes the `noise_scaling` argument (she above for new approach to handle noise scaling).
- Changed fields of internal `Reaction` structure. `ReactionSystems`s saved using `serialize` on previous Catalyst versions cannot be loaded using this (or later) versions.
Expand Down
2 changes: 1 addition & 1 deletion src/reaction_network.jl
Original file line number Diff line number Diff line change
Expand Up @@ -644,7 +644,7 @@ end

# Takes a reaction line and creates reaction(s) from it and pushes those to the reaction array.
# Used to create multiple reactions from, for instance, `k, (X,Y) --> 0`.
# Handles metadata, e.g. `1.0, Z --> 0, [noisescaling=η]`.
# Handles metadata, e.g. `1.0, Z --> 0, [noise_scaling=η]`.
function push_reactions!(reactions::Vector{ReactionStruct}, sub_line::ExprValues, prod_line::ExprValues,
rate::ExprValues, metadata::ExprValues, arrow::Symbol; default_reaction_metadata::Expr)
# The rates, substrates, products, and metadata may be in a tupple form (e.g. `k, (X,Y) --> 0`).
Expand Down
68 changes: 43 additions & 25 deletions src/reactionsystem.jl
Original file line number Diff line number Diff line change
Expand Up @@ -864,29 +864,49 @@ end
######################## Other accessors ##############################

"""
getnoisescaling(reaction::Reaction)
has_noise_scaling(reaction::Reaction)
Returns the noise scaling associated with a specific reaction. If the `:noise_scaling` metadata has
set, returns that. Else, returns `1.0`.
Checks whether a specific reaction has the metadata field `noise_scaing`. If so, returns `true`, else
returns `false`.
Arguments:
- `reaction`: The reaction for which we wish to check.
Example:
```julia
reaction = @reaction k, 0 --> X, [noise_scaling=0.0]
has_noise_scaling(reaction)
"""
function has_noise_scaling(reaction::Reaction)
return hasmetadata(reaction, :noise_scaling)
end

"""
get_noise_scaling(reaction::Reaction)
Returns the noise_scaling metadata from a specific reaction.
Arguments:
- `reaction`: The reaction for which we wish to retrive all metadata.
Example:
```julia
reaction = @reaction k, 0 --> X, [noise_scaling=0.0]
getnoisescaling(reaction)
get_noise_scaling(reaction)
"""
function getnoisescaling(reaction::Reaction)
has_metadata(reaction, :noise_scaling) && (return get_metadata(reaction, :noise_scaling))
return 1.0
function get_noise_scaling(reaction::Reaction)
if has_noise_scaling(reaction)
return getmetadata(reaction, :noise_scaling)
else
error("Attempts to access noise_scaling metadata field for a reaction which does not have a value assigned for this metadata.")
end
end


# These are currently considered internal, but can be used by public accessor functions like getnoisescaling.
# These are currently considered internal, but can be used by public accessor functions like get_noise_scaling.

"""
get_metadata_dict(reaction::Reaction)
getmetadata_dict(reaction::Reaction)
Retrives the `ImmutableDict` containing all of the metadata associated with a specific reaction.
Expand All @@ -896,15 +916,15 @@ Arguments:
Example:
```julia
reaction = @reaction k, 0 --> X, [description="Production reaction"]
get_metadata_dict(reaction)
getmetadata_dict(reaction)
```
"""
function get_metadata_dict(reaction::Reaction)
function getmetadata_dict(reaction::Reaction)
return reaction.metadata
end

"""
has_metadata(reaction::Reaction, md_key::Symbol)
hasmetadata(reaction::Reaction, md_key::Symbol)
Checks if a `Reaction` have a certain metadata field. If it does, returns `true` (else returns `false`).
Expand All @@ -915,15 +935,15 @@ Arguments:
Example:
```julia
reaction = @reaction k, 0 --> X, [description="Production reaction"]
has_metadata(reaction, :description)
hasmetadata(reaction, :description)
```
"""
function has_metadata(reaction::Reaction, md_key::Symbol)
return any(isequal(md_key, entry[1]) for entry in get_metadata_dict(reaction))
function hasmetadata(reaction::Reaction, md_key::Symbol)
return any(isequal(md_key, entry[1]) for entry in getmetadata_dict(reaction))
end

"""
get_metadata(reaction::Reaction, md_key::Symbol)
getmetadata(reaction::Reaction, md_key::Symbol)
Retrives a certain metadata value from a `Reaction`. If the metadata does not exists, throws an error.
Expand All @@ -934,15 +954,15 @@ Arguments:
Example:
```julia
reaction = @reaction k, 0 --> X, [description="Production reaction"]
get_metadata(reaction, :description)
getmetadata(reaction, :description)
```
"""
function get_metadata(reaction::Reaction, md_key::Symbol)
if !has_metadata(reaction, md_key)
error("The reaction does not have a metadata field $md_key. It does have the following metadata fields: $(keys(get_metadata_dict(reaction))).")
function getmetadata(reaction::Reaction, md_key::Symbol)
if !hasmetadata(reaction, md_key)
error("The reaction does not have a metadata field $md_key. It does have the following metadata fields: $(keys(getmetadata_dict(reaction))).")
end
metadata = get_metadata_dict(reaction)
return metadata[findfirst(isequal(md_key, entry[1]) for entry in get_metadata_dict(reaction))][2]
metadata = getmetadata_dict(reaction)
return metadata[findfirst(isequal(md_key, entry[1]) for entry in getmetadata_dict(reaction))][2]
end


Expand Down Expand Up @@ -1065,7 +1085,7 @@ function assemble_diffusion(rs, sts, ispcs; combinatoric_ratelaws = true,

for (j, rx) in enumerate(get_rxs(rs))
rlsqrt = sqrt(abs(oderatelaw(rx; combinatoric_ratelaw = combinatoric_ratelaws)))
rlsqrt *= getnoisescaling(rx)
has_noise_scaling(rx) && (rlsqrt *= get_noise_scaling(rx))
remove_conserved && (rlsqrt = substitute(rlsqrt, depspec_submap))

for (spec, stoich) in rx.netstoich
Expand Down Expand Up @@ -1485,7 +1505,6 @@ function Base.convert(::Type{<:SDESystem}, rs::ReactionSystem;
name = nameof(rs), combinatoric_ratelaws = get_combinatoric_ratelaws(rs),
include_zero_odes = true, checks = false, remove_conserved = false,
default_u0 = Dict(), default_p = Dict(), defaults = _merge(Dict(default_u0), Dict(default_p)),
noise_scaling = nothing, # To be removed (used for deprication message only).
kwargs...)
spatial_convert_err(rs::ReactionSystem, SDESystem)

Expand Down Expand Up @@ -1535,7 +1554,6 @@ function Base.convert(::Type{<:JumpSystem}, rs::ReactionSystem; name = nameof(rs
combinatoric_ratelaws = get_combinatoric_ratelaws(rs),
remove_conserved = nothing, checks = false,
default_u0 = Dict(), default_p = Dict(), defaults = _merge(Dict(default_u0), Dict(default_p)),
noise_scaling = nothing, # To be removed (used for deprication message only).
kwargs...)
spatial_convert_err(rs::ReactionSystem, JumpSystem)

Expand Down
28 changes: 14 additions & 14 deletions test/dsl/dsl_basics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -169,30 +169,30 @@ let
# Checks DSL reactions are correct.
rxs = reactions(rs)
@test isequal([r1, r2, r3], rxs)
@test isequal(Catalyst.get_metadata_dict(r1), Catalyst.get_metadata_dict(rxs[1]))
@test isequal(Catalyst.get_metadata_dict(r2), Catalyst.get_metadata_dict(rxs[2]))
@test isequal(Catalyst.get_metadata_dict(r3), Catalyst.get_metadata_dict(rxs[3]))
@test isequal(Catalyst.getmetadata_dict(r1), Catalyst.getmetadata_dict(rxs[1]))
@test isequal(Catalyst.getmetadata_dict(r2), Catalyst.getmetadata_dict(rxs[2]))
@test isequal(Catalyst.getmetadata_dict(r3), Catalyst.getmetadata_dict(rxs[3]))

# Checks that accessor functions works on the DSL.
@test Catalyst.has_metadata(rxs[1], :noise_scaling)
@test !Catalyst.has_metadata(rxs[1], :md_1)
@test !Catalyst.has_metadata(rxs[2], :noise_scaling)
@test Catalyst.has_metadata(rxs[2], :md_1)
@test !Catalyst.has_metadata(rxs[3], :noise_scaling)
@test !Catalyst.has_metadata(rxs[3], :md_1)
@test Catalyst.hasmetadata(rxs[1], :noise_scaling)
@test !Catalyst.hasmetadata(rxs[1], :md_1)
@test !Catalyst.hasmetadata(rxs[2], :noise_scaling)
@test Catalyst.hasmetadata(rxs[2], :md_1)
@test !Catalyst.hasmetadata(rxs[3], :noise_scaling)
@test !Catalyst.hasmetadata(rxs[3], :md_1)

@test isequal(Catalyst.get_metadata(rxs[1], :noise_scaling), η)
@test isequal(Catalyst.get_metadata(rxs[2], :md_1), 1.0)
@test isequal(Catalyst.getmetadata(rxs[1], :noise_scaling), η)
@test isequal(Catalyst.getmetadata(rxs[2], :md_1), 1.0)

# Test that metadata works for @reaction macro.
rx1 = @reaction k, 2X --> X2, [noise_scaling=$η]
rx2 = @reaction k, 2X --> X2, [md_1=1.0, md_2=false, md_3="Hello world", md_4=:sym, md_5=X+X2^k-1, md_6=(0.1,2.0)]
rx3 = @reaction k, 2X --> X2

@test isequal([rx1, rx2, rx3], rxs)
@test isequal(Catalyst.get_metadata_dict(rx1), Catalyst.get_metadata_dict(rxs[1]))
@test isequal(Catalyst.get_metadata_dict(rx2), Catalyst.get_metadata_dict(rxs[2]))
@test isequal(Catalyst.get_metadata_dict(rx3), Catalyst.get_metadata_dict(rxs[3]))
@test isequal(Catalyst.getmetadata_dict(rx1), Catalyst.getmetadata_dict(rxs[1]))
@test isequal(Catalyst.getmetadata_dict(rx2), Catalyst.getmetadata_dict(rxs[2]))
@test isequal(Catalyst.getmetadata_dict(rx3), Catalyst.getmetadata_dict(rxs[3]))
end

# Checks that repeated metadata throws errors.
Expand Down
44 changes: 22 additions & 22 deletions test/reactionsystem_structure/reactions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ let
metadata = [:noise_scaling => 0.0]
r = Reaction(k, [X], [X2], [2], [1]; metadata=metadata)

@test Catalyst.get_metadata_dict(r) == [:noise_scaling => 0.0]
@test Catalyst.has_metadata(r, :noise_scaling)
@test !Catalyst.has_metadata(r, :nonexisting_metadata)
@test Catalyst.get_metadata(r, :noise_scaling) == 0.0
@test Catalyst.getmetadata_dict(r) == [:noise_scaling => 0.0]
@test Catalyst.hasmetadata(r, :noise_scaling)
@test !Catalyst.hasmetadata(r, :nonexisting_metadata)
@test Catalyst.getmetadata(r, :noise_scaling) == 0.0

metadata_repeated = [:noise_scaling => 0.0, :noise_scaling => 1.0, :metadata_entry => "unused"]
@test_throws Exception Reaction(k, [X], [X2], [2], [1]; metadata=metadata_repeated)
Expand All @@ -36,8 +36,8 @@ let
r2 = Reaction(k, [X], [X2], [2], [1]; metadata=metadata)

@test isequal(r1, r2)
@test Catalyst.get_metadata_dict(r1) == Pair{Symbol,Any}[]
@test !Catalyst.has_metadata(r1, :md)
@test Catalyst.getmetadata_dict(r1) == Pair{Symbol,Any}[]
@test !Catalyst.hasmetadata(r1, :md)
end

# Tests creation.
Expand All @@ -57,21 +57,21 @@ let
push!(metadata, :md_6 => (0.1, 2.0))
r = Reaction(k, [X], [X2], [2], [1]; metadata=metadata)

@test Catalyst.get_metadata_dict(r) isa Vector{Pair{Symbol,Any}}
@test Catalyst.has_metadata(r, :md_1)
@test Catalyst.has_metadata(r, :md_2)
@test Catalyst.has_metadata(r, :md_3)
@test Catalyst.has_metadata(r, :md_4)
@test Catalyst.has_metadata(r, :md_5)
@test Catalyst.has_metadata(r, :md_6)
@test !Catalyst.has_metadata(r, :md_8)
@test Catalyst.getmetadata_dict(r) isa Vector{Pair{Symbol,Any}}
@test Catalyst.hasmetadata(r, :md_1)
@test Catalyst.hasmetadata(r, :md_2)
@test Catalyst.hasmetadata(r, :md_3)
@test Catalyst.hasmetadata(r, :md_4)
@test Catalyst.hasmetadata(r, :md_5)
@test Catalyst.hasmetadata(r, :md_6)
@test !Catalyst.hasmetadata(r, :md_8)

@test isequal(Catalyst.get_metadata(r, :md_1), 1.0)
@test isequal(Catalyst.get_metadata(r, :md_2), false)
@test isequal(Catalyst.get_metadata(r, :md_3), "Hello world")
@test isequal(Catalyst.get_metadata(r, :md_4), :sym)
@test isequal(Catalyst.get_metadata(r, :md_5), X + X2^k -1)
@test isequal(Catalyst.get_metadata(r, :md_6), (0.1, 2.0))
@test isequal(Catalyst.getmetadata(r, :md_1), 1.0)
@test isequal(Catalyst.getmetadata(r, :md_2), false)
@test isequal(Catalyst.getmetadata(r, :md_3), "Hello world")
@test isequal(Catalyst.getmetadata(r, :md_4), :sym)
@test isequal(Catalyst.getmetadata(r, :md_5), X + X2^k -1)
@test isequal(Catalyst.getmetadata(r, :md_6), (0.1, 2.0))
end

# Noise scaling metadata.
Expand All @@ -85,6 +85,6 @@ let
r1 = Reaction(k, [X], [X2], [2], [1])
r2 = Reaction(k, [X], [X2], [2], [1]; metadata=metadata)

@test isequal(Catalyst.getnoisescaling(r1), 1.0)
@test isequal(Catalyst.getnoisescaling(r2), η)
@test isequal(Catalyst.get_noise_scaling(r1), 1.0)
@test isequal(Catalyst.get_noise_scaling(r2), η)
end
2 changes: 1 addition & 1 deletion test/reactionsystem_structure/reactionsystem.jl
Original file line number Diff line number Diff line change
Expand Up @@ -707,6 +707,6 @@ end

# Tests metadata.
let
@test isnothing(ModelingToolkit.get_metadata(rs))
@test isnothing(ModelingToolkit.getmetadata(rs))
end

0 comments on commit 7dbb02c

Please sign in to comment.