Skip to content

Commit

Permalink
constants, records and switchers rename
Browse files Browse the repository at this point in the history
  • Loading branch information
ivborissov committed Nov 14, 2023
1 parent 4adb937 commit 3be48fa
Show file tree
Hide file tree
Showing 13 changed files with 52 additions and 52 deletions.
4 changes: 2 additions & 2 deletions docs/src/basics/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ There are three main problem types that can currently be solved with HetaSimulat

- [__Simulation__](#Simulation) of time-dependence for selected observables for one or several scenarios using [`sim`](@ref) method.
- [__Monte-Carlo__](#Monte-Carlo) type simulations that performs repeated simulations based on pre-set parameters distributions with [`mc`](@ref) method.
- [__Fitting__](#Fitting) or parameter identification problem that optimizes values of selected model constants to reach the minimal discrepancy between simulations and experimental values which is solved by [`fit`](@ref) method.
- [__Fitting__](#Fitting) or parameter identification problem that optimizes values of selected model-level parameters (`@Const`) to reach the minimal discrepancy between simulations and experimental values which is solved by [`fit`](@ref) method.

Each method returns the solution of its specific type: `SimResult`, `MCResult` and `FitResult` or other types that include them.

Expand Down Expand Up @@ -514,7 +514,7 @@ To run optimization problem you need to do three steps:

- Be sure that you measurement points are loaded in a proper way: referred `Scenario`s exists, proper error model is chosen.
- If required add parameters responsible for noise distribution into a model code, like `sigma` etc.
- Select a set of constants which will be fitted and set initial values for them.
- Select a set of parameters which will be fitted and set initial values for them.

For the presented example we uses normal distribution of measurement error with unknown variance parameter `sigma1`, `sigma2`, `sigma3` for doses 1, 10 and 100.

Expand Down
4 changes: 2 additions & 2 deletions docs/src/table-formats/parameters.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ The content of the table can be loaded into Julia environment as a `DataFrame` t

The first row is intended for headers which clarify the columns meaning. The sequence of columns is not important.

- `parameter` : a `String` representing unique identifier of constant. The corresponding constant must be declared in `Model`'s namespace (`@Const` component).
- `parameter` : a `String` representing unique identifier of model-level parameter. The corresponding parameter must be declared in `Model`'s namespace (`@Const` component).

- `nominal` (optional): a `Float64` nominal value which will be used as an initial value for the parameter. If it is skipped than the default constant value from model will be used.
- `nominal` (optional): a `Float64` nominal value which will be used as an initial value for the parameter. If it is skipped than the default value from the model will be used.

- `lower` (optional): a `Float64` value that declares the lower bound of the parameter. If skipped than the parameter value will not be limited.

Expand Down
4 changes: 2 additions & 2 deletions docs/src/table-formats/scenario.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ The first row is intended for headers which clarify the columns meaning. The seq

- `saveat[]` (* optional) : a set of `Float64` values separated by semicolons. The values states the time points for simulated output.

- `observables[]` (optional) : a set of `String` separated by semicolon. They state the model records that will be saved as simulation results. If not set the default observables will be used (`output: true` property in Heta notation).
- `observables[]` (optional) : a set of `String` separated by semicolon. Model Records that will be saved as simulation results. If not set the default observables will be used (`output: true` property in Heta notation).

- `events_active.<id>` (optional) : a `Bool` value which updates turns on and off events in model. The `id` is switcher identifier in the Heta. If it is not set the `switcher.active` state from Heta model will be used.
- `events_active.<id>` (optional) : a `Bool` value which updates turns on and off events in model. The `id` is switcher identifier in the Heta file. If it is not set the `switcher.active` state from Heta model will be used.

- `events_save.<id>` (optional, experimental) : a pair of `Bool` values divided by semicolon. This value set if it is required to save the output value before and after the event. If not set both: before and after values will be saved.

Expand Down
4 changes: 2 additions & 2 deletions docs/src/tutorial/intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ This object stores `Model`s, `Scenario`s and `Measurement`s.

## Architecture

[`Model`](@ref) type represents one concrete namespace imported from [Heta-compiler](https://hetalang.github.io/#/heta-compiler/). It stores information about ODE system, initialization of initial values, events as well as default values of constants. The HetaSimulator approach imply multi-model usage so simulations and optimizations can be done for several models simultaneously without specific preparations.
[`Model`](@ref) type represents one concrete namespace imported from [Heta-compiler](https://hetalang.github.io/#/heta-compiler/). It stores information about ODE system, initial values, events as well as default model-level parameters values. The HetaSimulator approach imply multi-model usage so simulations and optimizations can be done for several models simultaneously without specific preparations.

[`Scenario`](@ref) type stores additional setting for running ODE solution and tasks. For example the same model can be run with or without some events, or differ by some specific constant values like doses and others, or has some specific output variables (observables). Each `Scenario` is associated with a specific `Model`. Each model may be referenced by any number of scenarios.
[`Scenario`](@ref) type stores additional setting for running ODE solution and tasks. For example the same model can be run with or without some events, or differ by some specific parameters values like doses and others, or has some specific output variables (observables). Each `Scenario` is associated with a specific `Model`. Each model may be referenced by any number of scenarios.

Additionally `Scenario` instance is a container for the `Measurement` objects which describe experimental datasets. They can be used for identification of model parameters or some specific tasks like identifiability analysis and visualization.

Expand Down
4 changes: 2 additions & 2 deletions docs/src/tutorial/mc.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ model = platform.models[:nameless]

```
Model contains 3 constant(s), 8 record(s), 1 switcher(s).
Constants: k1, k2, k3
Records: comp1, comp2, a, b, c, d, r1, r2
Constants (model-level parameters): k1, k2, k3
Records (observables): comp1, comp2, a, b, c, d, r1, r2
Switchers (events): sw1
```

Expand Down
8 changes: 4 additions & 4 deletions docs/src/tutorial/sim.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ model = models(p)[:nameless]

```
Model contains 4 constant(s), 9 record(s), 2 switcher(s).
Constants: dose, kabs, kel, Q
Records: Vol0, Vol1, Vol2, A0, C1, C2, v_abs, v_el, v_distr
Constants (model-level parameters): dose, kabs, kel, Q
Records (observables): Vol0, Vol1, Vol2, A0, C1, C2, v_abs, v_el, v_distr
Switchers (events): sw1, sw2
```

Expand All @@ -93,7 +93,7 @@ The next code will create a `Scenario` for simulating the default model with tim

- output records (observables) will be taken from records marked with `{output: true}` in heta code.
- all switchers (events) will be active if `{active: true}` is not set.
- constant values (parameters) will be the same as they stated in the heta file.
- constant values (model-level parameters) will be the same as stated in the heta file.

```julia
# minimal scenario
Expand All @@ -118,7 +118,7 @@ plot(res0)
Creating scenario we can also update some of the model default options.
The next example is the case when we want to update the simulation conditions:

- Update value of constant `dose = 100`.
- Update value of parameter `dose = 100`.
- Use multiple dose event `sw2` instead of single dose.
- simulation time is from `0` to `1000`.
- we need to observe all species: `C1`, `C2`, and reactions `v_el`.
Expand Down
10 changes: 5 additions & 5 deletions src/estimator.jl
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
- `scenario_pairs` : vector of pairs containing names and scenarios of type [`Scenario`](@ref)
- `parameters_fitted` : parameters and their nominal values that will be used as default
- `parameters` : constants, which overwrite both `Model` and `Scenario` constants. Default is `nothing`
- `parameters` : paramters, which overwrite both `Model` and `Scenario` parameters. Default is `nothing`
- `alg` : ODE solver. See SciML docs for details. Default is AutoTsit5(Rosenbrock23())
- `reltol` : relative tolerance. Default is 1e-6
- `abstol` : relative tolerance. Default is 1e-8
Expand Down Expand Up @@ -69,8 +69,8 @@ function estimator(
prob_i = remake_saveat(prob_i, scen.measurements)
#=
prob_i = if !isnothing(parameters)
constants_total_i = merge_strict(scen.parameters, NamedTuple(parameters))
u0, p0 = scen.init_func(constants_total_i)
params_total_i = merge_strict(scen.parameters, NamedTuple(parameters))
u0, p0 = scen.init_func(params_total_i)
remake(prob_i; u0=u0, p=p0)
else
prob_i
Expand All @@ -83,8 +83,8 @@ function estimator(
function(prob,i,repeat) # internal_prob_func
#update_init_values(selected_prob[i], last(selected_scenario_pairs[i]).init_func, x)
scn = last(selected_scenario_pairs[i])
constants_total = merge_strict(scn.parameters, x)
u0, p0 = scn.init_func(constants_total)
params_total = merge_strict(scn.parameters, x)
u0, p0 = scn.init_func(params_total)
remake(deepcopy(selected_prob[i]); u0=u0, p=p0) # tmp fix, waiting for general solution
end
end
Expand Down
2 changes: 1 addition & 1 deletion src/fit.jl
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const DEFAULT_FITTING_ABSTOL = 1e-8
- `scenario_pairs` : vector of pairs containing names and scenarios of type [`Scenario`](@ref)
- `parameters_fitted` : optimization parameters and their initial values
- `parameters` : constants, which overwrite both `Model` and `Scenario` constants. Default is `nothing`
- `parameters` : parameters, which overwrite both `Model` and `Scenario` parameters. Default is `nothing`
- `alg` : ODE solver. See SciML docs for details. Default is AutoTsit5(Rosenbrock23())
- `reltol` : relative tolerance. Default is 1e-6
- `abstol` : relative tolerance. Default is 1e-8
Expand Down
24 changes: 12 additions & 12 deletions src/monte_carlo.jl
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,10 @@ function mc(
verbose && println("Processing iteration $i")
progress_bar && (parallel_type != EnsembleDistributed() ? next!(p) : put!(progch, true))

prob_i = remake_prob(scenario, generate_cons(parameters_variation_nt, i); safetycopy=true)
prob_i = remake_prob(scenario, generate_params(parameters_variation_nt, i); safetycopy=true)
return prob_i
#=
constants_total_i = merge_strict(scenario.parameters, generate_cons(parameters_variation_nt, i))
constants_total_i = merge_strict(scenario.parameters, generate_params(parameters_variation_nt, i))
u0, p0 = scenario.init_func(constants_total_i)
return remake(scenario.prob; u0=u0, p=p0)
Expand All @@ -78,10 +78,10 @@ function mc(
function _output(sol, i)
# take numbers from p
values_i = sol.prob.p[y_indexes]
constants_i = NamedTuple(zip(first.(parameters_variation), values_i))
params_i = NamedTuple(zip(first.(parameters_variation), values_i))
# take simulated values from solution
sv = sol.prob.kwargs[:callback].discrete_callbacks[1].affect!.saved_values
simulation = Simulation(sv, constants_i, sol.retcode)
simulation = Simulation(sv, params_i, sol.retcode)

return (output_func(simulation, i), false)
end
Expand Down Expand Up @@ -220,7 +220,7 @@ function mc(
end

parameters_variation_nt = NamedTuple(parameters_variation)
parameters_pregenerated = [generate_cons(parameters_variation_nt, i) for i in 1:num_iter]
parameters_pregenerated = [generate_params(parameters_variation_nt, i) for i in 1:num_iter]
lp = length(parameters_pregenerated)
lc = length(scenario_pairs)
iter = collect(Iterators.product(1:lp,1:lc))
Expand Down Expand Up @@ -248,10 +248,10 @@ function mc(
function _output(sol, i)
iter_i = iter[i]
# takes parameters_variation from pre-generated
constants_i = parameters_pregenerated[iter_i[1]]
params_i = parameters_pregenerated[iter_i[1]]
# take simulated values from solution
sv = sol.prob.kwargs[:callback].discrete_callbacks[1].affect!.saved_values
simulation = Simulation(sv, constants_i, sol.retcode)
simulation = Simulation(sv, params_i, sol.retcode)

return (output_func(simulation, i), false)
end
Expand Down Expand Up @@ -459,11 +459,11 @@ function DiffEqBase.EnsembleAnalysis.EnsembleSummary(
end


generate_cons(vp::AbstractVector{P},i) where P<:Pair = NamedTuple([k=>generate_cons(v,i) for (k,v) in vp])
generate_cons(nt::NamedTuple,i) = NamedTuple{keys(nt)}([generate_cons(v,i) for v in nt])
generate_cons(v::Distribution,i) = rand(v)
generate_cons(v::Real,i) = v
generate_cons(v::AbstractVector{R},i) where R<:Real = v[i]
generate_params(vp::AbstractVector{P},i) where P<:Pair = NamedTuple([k=>generate_params(v,i) for (k,v) in vp])
generate_params(nt::NamedTuple,i) = NamedTuple{keys(nt)}([generate_params(v,i) for v in nt])
generate_params(v::Distribution,i) = rand(v)
generate_params(v::Real,i) = v
generate_params(v::AbstractVector{R},i) where R<:Real = v[i]

"""
read_mcvecs(filepath::String)
Expand Down
8 changes: 4 additions & 4 deletions src/ode_problem.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
function build_ode_problem( # used in Scenario constructor only
model::Model,
tspan;
constants::NamedTuple,
params::NamedTuple,
events_active::Union{Nothing, Vector{Pair{Symbol,Bool}}} = Pair{Symbol,Bool}[],
events_save::Union{Tuple,Vector{Pair{Symbol, Tuple{Bool, Bool}}}} = (true,true),
observables_::Union{Nothing,Vector{Symbol}} = nothing,
Expand All @@ -12,7 +12,7 @@ function build_ode_problem( # used in Scenario constructor only
_saveat = isnothing(saveat) ? time_type[] : saveat

# init
u0, p0 = model.init_func(constants)
u0, p0 = model.init_func(params)

# check observables
if !isnothing(observables_)
Expand Down Expand Up @@ -74,8 +74,8 @@ collect_saveat(saveat::AbstractRange{S}) where S<:Real = Float64.(saveat)
function remake_prob(scen::Scenario, params::NamedTuple; safetycopy=true)
prob0 = safetycopy ? deepcopy(scen.prob) : scen.prob
if length(params) > 0
constants_total = merge_strict(scen.parameters, params)
u0, p0 = scen.init_func(constants_total)
params_total = merge_strict(scen.parameters, params)
u0, p0 = scen.init_func(params_total)
prob0.u0 .= u0
prob0.p .= p0
return prob0
Expand Down
20 changes: 10 additions & 10 deletions src/scenario.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const CONSTANT_PREFIX = "parameters"
const SWITCHER_PREFIX = "events_active"
const SWITCHER_SAVE_PREFIX = "events_save"
const PARAMETERS_PREFIX = "parameters"
const EVENT_PREFIX = "events_active"
const EVENT_SAVE_PREFIX = "events_save"
const SAVEAT_HEADER = Symbol("saveat[]")

const TSPAN_HEADER = Symbol("tspan")
Expand Down Expand Up @@ -35,7 +35,7 @@ Arguments:
- `observables` : names of output observables. Overwrites default model's values. Default is `nothing`
- `tags` :
- `group` :
- `parameters` : `Vector` of `Pair`s containing constants' names and values. Overwrites default model's values. Default is empty vector.
- `parameters` : `Vector` of `Pair`s containing parameters' names and values. Overwrites default model's values. Default is empty vector.
- `events_active` : `Vector` of `Pair`s containing events' names and true/false values. Overwrites default model's values. Default is empty `Vector{Pair}`
- `events_save` : `Tuple` or `Vector{Tuple}` marking whether to save solution before and after event. Default is `(true,true)` for all events
- `saveat` : time points, where solution should be saved. Default `nothing` values stands for saving solution at timepoints reached by the solver
Expand All @@ -52,18 +52,18 @@ function Scenario(
parameters::Vector{Pair{Symbol,Float64}} = Pair{Symbol,Float64}[],
kwargs... # all arguments of build_ode_problem()
)
constants_total = merge_strict(model.constants, NamedTuple(parameters))
params_total = merge_strict(model.constants, NamedTuple(parameters))

# ODE problem
prob = build_ode_problem(
model,
tspan;
observables_ = observables,
constants = constants_total,
params = params_total,
kwargs...
)

return Scenario(model.init_func, prob, measurements, tags, group, constants_total)
return Scenario(model.init_func, prob, measurements, tags, group, params_total)
end

# Scenario struct method
Expand Down Expand Up @@ -131,11 +131,11 @@ function _add_scenario!(platform::Platform, row::Any) # maybe not any
for key in keys(row)
if !ismissing(row[key])
splitted_key = split(string(key), ".")
if splitted_key[1] == CONSTANT_PREFIX
if splitted_key[1] == PARAMETERS_PREFIX
push!(_parameters, Symbol(splitted_key[2]) => row[key])
elseif splitted_key[1] == SWITCHER_PREFIX
elseif splitted_key[1] == EVENT_PREFIX
push!(_events_active, Symbol(splitted_key[2]) => bool(row[key]))
elseif splitted_key[1] == SWITCHER_SAVE_PREFIX
elseif splitted_key[1] == EVENT_SAVE_PREFIX
save_evt_vec = split(row[key], ";")
@assert length(save_evt_vec) == 2 "Events saving setup accepts two values (e.g. true;false). Check the scenarios table."
push!(_events_save, Symbol(splitted_key[2]) => (bool(save_evt_vec[1]), bool(save_evt_vec[2])))
Expand Down
4 changes: 2 additions & 2 deletions src/simulate.jl
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Example: `Scenario(model, (0., 200.); saveat = [0.0, 150.]) |> sim`
Arguments:
- `scenario` : simulation scenario of type [`Scenario`](@ref)
- `parameters` : constants, which overwrite both `Model` and `Scenario` constants. Default is empty vector.
- `parameters` : parameters overwrite both `Model` and `Scenario` parameters. Default is empty vector.
- `alg` : ODE solver. See SciML docs for details. Default is AutoTsit5(Rosenbrock23())
- `reltol` : relative tolerance. Default is 1e-3
- `abstol` : relative tolerance. Default is 1e-6
Expand Down Expand Up @@ -86,7 +86,7 @@ Example: `sim([:x => scn1, :y=>scn2, :z=>scn3])`
Arguments:
- `scenario_pairs` : vector of pairs containing names and scenarios of type [`Scenario`](@ref)
- `parameters` : constants, which overwrite both `Model` and `Scenario` constants. Default is empty vector.
- `parameters` : parameters, which overwrite both `Model` and `Scenario` parameters. Default is empty vector.
- `alg` : ODE solver. See SciML docs for details. Default is AutoTsit5(Rosenbrock23())
- `reltol` : relative tolerance. Default is 1e-3
- `abstol` : relative tolerance. Default is 1e-6
Expand Down
8 changes: 4 additions & 4 deletions src/types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,8 @@ function Base.show(io::IO, mime::MIME"text/plain", m::AbstractModel)
switchers_str = print_lim(switchers(m), 10)

println(io, "Model contains $(length(m.constants)) constant(s), $(length(m.records_output)) record(s), $(length(m.events)) switcher(s).")
println(io, " Constants: $const_str")
println(io, " Records: $record_str")
println(io, " Constants (model-level parameters): $const_str")
println(io, " Records (observables): $record_str")
println(io, " Switchers (events): $switchers_str")
end

Expand Down Expand Up @@ -156,7 +156,7 @@ abstract type AbstractScenario end
parameters::NamedTuple
end
Type representing simulation conditions, i.e. model variant with updated constants and outputs.
Type representing simulation conditions, i.e. model variant with updated parameters and outputs.
To get the internal properties use methods: `tspan(scenario)`, `parameters(scenario)`, `measurements(scenario)`
"""
Expand All @@ -173,9 +173,9 @@ saveat(scn::Scenario) = scn.prob.kwargs[:callback].discrete_callbacks[1].affect!
tspan(scn::Scenario) = scn.prob.tspan
parameters(scn::Scenario) = scn.parameters # scn.prob.p
measurements(scn::Scenario) = scn.measurements
observables(scn::Scenario) = LabelledArrays.symnames(eltype(scn.prob.kwargs[:callback].discrete_callbacks[1].affect!.saved_values.u))
# events_active(scn::Scenario)
# events_save(scn::Scenario)
# observables(scn::Scenario)

function Base.show(io::IO, mime::MIME"text/plain", scn::Scenario)
parameters_str = print_lim(
Expand Down

0 comments on commit 3be48fa

Please sign in to comment.