Hello,
First of all, many thanks to Pumas team for this package as well as the environment provided to work with it.
I have started using Pumas recently to deal with NLME models. I followed some tutorials and I am now trying to make modifications to meet my needs.
Briefly, I have tried to implement a simple model for the fluorescence of individuals (e.g. cells) and to keep it simple fluorescence level will increase or decrease depending on the state of an activation function (see the @dynamicspart of the code).
So far, I have been able to simulate and estimate parameters (logκ,logγ,σ²κ,σ²γ,σ²f) of the model when giving/fixing an initial state for the fluorescence (f=0 in the @init part and commenting all f0 related lines) and it worked great.
However, I will be confronted to data where the starting value of the fluorescence is unknown, so I am now trying to take that into account in my model definition.
In the code below I am able to simulate data with, as far as I understand, random values for f0. The issue arrises when I am using the fit function.
First I get some warnings of dt set as NaN and then when the minimization starts an error (see below code). One of the parameter, logκ, is not identified.
Unfortunately, I do not really know what I can do to change that, it seems to me that I should do something to prevent the dt to be set to NaN but I do not know how (nor if) I can do that.
As already told, this estimation problem worked when considering only parameters κ and γ and it also works when estimating κ, γ and f0 when there is no activation function (commenting it in the @dynamics macro). Also, in all cases I was able to simulate data with the simobs function.
I am thus a bit puzzled and was wondering if they were things to check, first to know whether my problem is theoretically identifiable, and to make the estimation work in Pumas (I have tried other algorithms from Optim). Am I doing something wrong in the model macro?
Also, I might have to re-write this as an @emmodel later, is there more chances for this kind of estimation to work then?
Thanks for the help/advise you can give!
Working example:
using Pumas
using Random
using PumasUtilities
using CairoMakie
## Defining Pumas model with macro
fluo_model = @model begin
@param begin
logκ ∈ RealDomain()
logγ ∈ RealDomain()
logf0 ∈ RealDomain() #
σ²κ ∈ RealDomain(lower=0.0001)
σ²γ ∈ RealDomain(lower=0.0001)
σ²f0 ∈ RealDomain(lower=0.0) #
σ²f ∈ RealDomain(lower=0.0001, upper=20.0)
end
@random begin
ηκ ~ Normal(0.0,sqrt(σ²κ))
ηγ ~ Normal(0.0,sqrt(σ²γ))
ηf0 ~ Normal(0.0,sqrt(σ²f0)) #
end
@pre begin
log_κ = logκ + ηκ
log_γ = logγ + ηγ
log_f0 = logf0 + ηf0 #
end
@init begin
f = exp(log_f0) # f = 0
end
@dynamics begin
f' = - exp(log_γ)*f + exp(log_κ)*1/(1+exp(-(mod(t,40)-30)))
end
@derived begin
Fluo = @. Normal(f,sqrt(σ²f))
end
end
params = (logκ=log(0.31),logγ=log(0.21),logf0=0.01,σ²κ=0.1^2,σ²γ=0.1^2,σ²f=0.1^2,σ²f0=0.1^2)
#params = (logκ=log(0.31),logγ=log(0.21),σ²κ=0.1^2,σ²γ=0.1^2,σ²f=0.1^2)
## For simulations
reg = DosageRegimen(0.01,cmt=1,time=0)
# subject = Subject(id=1,events=reg)
pop = Population(map(i -> Subject(id=i,events=reg),1:5))
obstime = [i for i=1:300];
sim = simobs(fluo_model,pop,params,obstimes=obstime)
sim_plot(fluo_model,sim,observations=[:Fluo])
### Estimates from simulated data
result = fit(fluo_model,Subject.(sim),params, Pumas.FOCEI())
┌ Warning: Automatic dt set the starting dt as NaN, causing instability.
└ @ OrdinaryDiffEq /builds/PumasAI/PumasSystemImages-jl/.julia/packages/OrdinaryDiffEq/UcJTX/src/solve.jl:510
┌ Warning: NaN dt detected. Likely a NaN value in the state, parameters, or derivative value caused this outcome.
└ @ SciMLBase /builds/PumasAI/PumasSystemImages-jl/.julia/packages/SciMLBase/LK7N9/src/integrator_interface.jl:325
(The warning messages appear several time)
Iter Function value Gradient norm
0 Inf 0.000000e+00
* time: 2.002716064453125e-5
ERROR: LoadError: gradient is exactly zero in logκ. This indicates that logκ isn't identified.
Stacktrace:
[1] _unindentified_exception(#unused#::Float64, i::Int64, j::Int64, d::Int64, k::Symbol)
@ Pumas /builds/PumasAI/PumasSystemImages-jl/.julia/packages/Pumas/XHa5R/src/estimation/likelihoods.jl:2242
[2] _check_zero_gradient(vparam::Vector{Float64}, g::Vector{Float64}, fixedtrf::TransformVariables.TransformTuple{NamedTuple{(:logκ, :logγ, :logf0, :σ²κ, :σ²γ, :σ²f0, :σ²f), Tuple{TransformVariables.Identity, TransformVariables.Identity, TransformVariables.Identity, TransformVariables.ShiftedExp{true, Float64}, TransformVariables.ShiftedExp{true, Float64}, TransformVariables.ShiftedExp{true, Float64}, TransformVariables.ScaledShiftedLogistic{Float64}}}})
@ Pumas /builds/PumasAI/PumasSystemImages-jl/.julia/packages/Pumas/XHa5R/src/estimation/likelihoods.jl:2233
[3] (::Pumas.var"#442#447"{Pumas.FOCE, Bool, NLSolversBase.OnceDifferentiable{Float64, Vector{Float64}, Vector{Float64}}, TransformVariables.TransformTuple{NamedTuple{(:logκ, :logγ, :logf0, :σ²κ, :σ²γ, :σ²f0, :σ²f), Tuple{TransformVariables.Identity, TransformVariables.Identity, TransformVariables.Identity, TransformVariables.ShiftedExp{true, Float64}, TransformVariables.ShiftedExp{true, Float64}, TransformVariables.ShiftedExp{true, Float64}, TransformVariables.ScaledShiftedLogistic{Float64}}}}})(state::Vector{Optim.OptimizationState{Float64, Optim.BFGS{LineSearches.InitialStatic{Float64}, LineSearches.BackTracking{Float64, Int64}, Nothing, Float64, Optim.Flat}}})
@ Pumas /builds/PumasAI/PumasSystemImages-jl/.julia/packages/Pumas/XHa5R/src/estimation/likelihoods.jl:2531
[4] #426
@ /builds/PumasAI/PumasSystemImages-jl/.julia/packages/Pumas/XHa5R/src/estimation/likelihoods.jl:1980 [inlined]
[5] update!(tr::Vector{Optim.OptimizationState{Float64, Optim.BFGS{LineSearches.InitialStatic{Float64}, LineSearches.BackTracking{Float64, Int64}, Nothing, Float64, Optim.Flat}}}, iteration::Int64, f_x::Float64, grnorm::Float64, dt::Dict{Any, Any}, store_trace::Bool, show_trace::Bool, show_every::Int64, callback::Pumas.var"#426#428"{Pumas.DefaultOptimizeFN{Nothing, NamedTuple{(:show_trace, :store_trace, :extended_trace, :g_tol, :allow_f_increases), Tuple{Bool, Bool, Bool, Float64, Bool}}}, Pumas.var"#442#447"{Pumas.FOCE, Bool, NLSolversBase.OnceDifferentiable{Float64, Vector{Float64}, Vector{Float64}}, TransformVariables.TransformTuple{NamedTuple{(:logκ, :logγ, :logf0, :σ²κ, :σ²γ, :σ²f0, :σ²f), Tuple{TransformVariables.Identity, TransformVariables.Identity, TransformVariables.Identity, TransformVariables.ShiftedExp{true, Float64}, TransformVariables.ShiftedExp{true, Float64}, TransformVariables.ShiftedExp{true, Float64}, TransformVariables.ScaledShiftedLogistic{Float64}}}}}}, trace_simplex::Bool)
@ Optim /builds/PumasAI/PumasSystemImages-jl/.julia/packages/Optim/uwNqi/src/utilities/update.jl:23
[6] update!
@ /builds/PumasAI/PumasSystemImages-jl/.julia/packages/Optim/uwNqi/src/utilities/update.jl:11 [inlined]
[7] trace!(tr::Vector{Optim.OptimizationState{Float64, Optim.BFGS{LineSearches.InitialStatic{Float64}, LineSearches.BackTracking{Float64, Int64}, Nothing, Float64, Optim.Flat}}}, d::NLSolversBase.OnceDifferentiable{Float64, Vector{Float64}, Vector{Float64}}, state::Optim.BFGSState{Vector{Float64}, Matrix{Float64}, Float64, Vector{Float64}}, iteration::Int64, method::Optim.BFGS{LineSearches.InitialStatic{Float64}, LineSearches.BackTracking{Float64, Int64}, Nothing, Float64, Optim.Flat}, options::Optim.Options{Float64, Pumas.var"#426#428"{Pumas.DefaultOptimizeFN{Nothing, NamedTuple{(:show_trace, :store_trace, :extended_trace, :g_tol, :allow_f_increases), Tuple{Bool, Bool, Bool, Float64, Bool}}}, Pumas.var"#442#447"{Pumas.FOCE, Bool, NLSolversBase.OnceDifferentiable{Float64, Vector{Float64}, Vector{Float64}}, TransformVariables.TransformTuple{NamedTuple{(:logκ, :logγ, :logf0, :σ²κ, :σ²γ, :σ²f0, :σ²f), Tuple{TransformVariables.Identity, TransformVariables.Identity, TransformVariables.Identity, TransformVariables.ShiftedExp{true, Float64}, TransformVariables.ShiftedExp{true, Float64}, TransformVariables.ShiftedExp{true, Float64}, TransformVariables.ScaledShiftedLogistic{Float64}}}}}}}, curr_time::Float64)
@ Optim /builds/PumasAI/PumasSystemImages-jl/.julia/packages/Optim/uwNqi/src/multivariate/solvers/first_order/bfgs.jl:172
[8] optimize(d::NLSolversBase.OnceDifferentiable{Float64, Vector{Float64}, Vector{Float64}}, initial_x::Vector{Float64}, method::Optim.BFGS{LineSearches.InitialStatic{Float64}, LineSearches.BackTracking{Float64, Int64}, Nothing, Float64, Optim.Flat}, options::Optim.Options{Float64, Pumas.var"#426#428"{Pumas.DefaultOptimizeFN{Nothing, NamedTuple{(:show_trace, :store_trace, :extended_trace, :g_tol, :allow_f_increases), Tuple{Bool, Bool, Bool, Float64, Bool}}}, Pumas.var"#442#447"{Pumas.FOCE, Bool, NLSolversBase.OnceDifferentiable{Float64, Vector{Float64}, Vector{Float64}}, TransformVariables.TransformTuple{NamedTuple{(:logκ, :logγ, :logf0, :σ²κ, :σ²γ, :σ²f0, :σ²f), Tuple{TransformVariables.Identity, TransformVariables.Identity, TransformVariables.Identity, TransformVariables.ShiftedExp{true, Float64}, TransformVariables.ShiftedExp{true, Float64}, TransformVariables.ShiftedExp{true, Float64}, TransformVariables.ScaledShiftedLogistic{Float64}}}}}}}, state::Optim.BFGSState{Vector{Float64}, Matrix{Float64}, Float64, Vector{Float64}})
@ Optim /builds/PumasAI/PumasSystemImages-jl/.julia/packages/Optim/uwNqi/src/multivariate/optimize/optimize.jl:53
[9] optimize
@ /builds/PumasAI/PumasSystemImages-jl/.julia/packages/Optim/uwNqi/src/multivariate/optimize/optimize.jl:35 [inlined]
[10] (::Pumas.DefaultOptimizeFN{Nothing, NamedTuple{(:show_trace, :store_trace, :extended_trace, :g_tol, :allow_f_increases), Tuple{Bool, Bool, Bool, Float64, Bool}}})(cost::NLSolversBase.OnceDifferentiable{Float64, Vector{Float64}, Vector{Float64}}, p::Vector{Float64}, callback::Pumas.var"#442#447"{Pumas.FOCE, Bool, NLSolversBase.OnceDifferentiable{Float64, Vector{Float64}, Vector{Float64}}, TransformVariables.TransformTuple{NamedTuple{(:logκ, :logγ, :logf0, :σ²κ, :σ²γ, :σ²f0, :σ²f), Tuple{TransformVariables.Identity, TransformVariables.Identity, TransformVariables.Identity, TransformVariables.ShiftedExp{true, Float64}, TransformVariables.ShiftedExp{true, Float64}, TransformVariables.ShiftedExp{true, Float64}, TransformVariables.ScaledShiftedLogistic{Float64}}}}})
@ Pumas /builds/PumasAI/PumasSystemImages-jl/.julia/packages/Pumas/XHa5R/src/estimation/likelihoods.jl:1973
[11] _fit(m::PumasModel{ParamSet{NamedTuple{(:logκ, :logγ, :logf0, :σ²κ, :σ²γ, :σ²f0, :σ²f), Tuple{RealDomain{TransformVariables.Infinity{false}, TransformVariables.Infinity{true}, Float64}, RealDomain{TransformVariables.Infinity{false}, TransformVariables.Infinity{true}, Float64}, RealDomain{TransformVariables.Infinity{false}, TransformVariables.Infinity{true}, Float64}, RealDomain{Float64, TransformVariables.Infinity{true}, Float64}, RealDomain{Float64, TransformVariables.Infinity{true}, Float64}, RealDomain{Float64, TransformVariables.Infinity{true}, Float64}, RealDomain{Float64, Float64, Float64}}}}, var"#39#55", var"#40#56", var"#42#58", var"#44#60", ODEProblem{Nothing, Tuple{Nothing, Nothing}, false, Nothing, ODEFunction{false, ModelingToolkit.ODEFunctionClosure{var"#45#61", var"#46#62"}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Vector{Symbol}, Symbol, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing}, Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, SciMLBase.StandardODEProblem}, var"#47#63", var"#51#67", ModelingToolkit.ODESystem}, population::Vector{Subject{NamedTuple{(:Fluo,), Tuple{Vector{Float64}}}, Pumas.ConstantCovar{NamedTuple{(), Tuple{}}}, Vector{Pumas.Event{Float64, Float64, Float64, Float64, Float64, Float64, Int64}}, Vector{Int64}}}, param::NamedTuple{(:logκ, :logγ, :logf0, :σ²κ, :σ²γ, :σ²f0, :σ²f), NTuple{7, Float64}}, approx::Pumas.FOCE, ensemblealg::EnsembleThreads, optimize_fn::Pumas.DefaultOptimizeFN{Nothing, NamedTuple{(:show_trace, :store_trace, :extended_trace, :g_tol, :allow_f_increases), Tuple{Bool, Bool, Bool, Float64, Bool}}}, fixedparamset::ParamSet{NamedTuple{(:logκ, :logγ, :logf0, :σ²κ, :σ²γ, :σ²f0, :σ²f), Tuple{RealDomain{TransformVariables.Infinity{false}, TransformVariables.Infinity{true}, Float64}, RealDomain{TransformVariables.Infinity{false}, TransformVariables.Infinity{true}, Float64}, RealDomain{TransformVariables.Infinity{false}, TransformVariables.Infinity{true}, Float64}, RealDomain{Float64, TransformVariables.Infinity{true}, Float64}, RealDomain{Float64, TransformVariables.Infinity{true}, Float64}, RealDomain{Float64, TransformVariables.Infinity{true}, Float64}, RealDomain{Float64, Float64, Float64}}}}, fixedparam::NamedTuple{(:logκ, :logγ, :logf0, :σ²κ, :σ²γ, :σ²f0, :σ²f), NTuple{7, Float64}}, checkidentification::Bool, diffeq_options::NamedTuple{(), Tuple{}})
@ Pumas /builds/PumasAI/PumasSystemImages-jl/.julia/packages/Pumas/XHa5R/src/estimation/likelihoods.jl:2548
[12] fit(m::PumasModel{ParamSet{NamedTuple{(:logκ, :logγ, :logf0, :σ²κ, :σ²γ, :σ²f0, :σ²f), Tuple{RealDomain{TransformVariables.Infinity{false}, TransformVariables.Infinity{true}, Float64}, RealDomain{TransformVariables.Infinity{false}, TransformVariables.Infinity{true}, Float64}, RealDomain{TransformVariables.Infinity{false}, TransformVariables.Infinity{true}, Float64}, RealDomain{Float64, TransformVariables.Infinity{true}, Float64}, RealDomain{Float64, TransformVariables.Infinity{true}, Float64}, RealDomain{Float64, TransformVariables.Infinity{true}, Float64}, RealDomain{Float64, Float64, Float64}}}}, var"#39#55", var"#40#56", var"#42#58", var"#44#60", ODEProblem{Nothing, Tuple{Nothing, Nothing}, false, Nothing, ODEFunction{false, ModelingToolkit.ODEFunctionClosure{var"#45#61", var"#46#62"}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Vector{Symbol}, Symbol, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing}, Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, SciMLBase.StandardODEProblem}, var"#47#63", var"#51#67", ModelingToolkit.ODESystem}, population::Vector{Subject{NamedTuple{(:Fluo,), Tuple{Vector{Float64}}}, Pumas.ConstantCovar{NamedTuple{(), Tuple{}}}, Vector{Pumas.Event{Float64, Float64, Float64, Float64, Float64, Float64, Int64}}, Vector{Int64}}}, param::NamedTuple{(:logκ, :logγ, :logf0, :σ²κ, :σ²γ, :σ²f0, :σ²f), NTuple{7, Float64}}, approx::Pumas.FOCE; optimize_fn::Pumas.DefaultOptimizeFN{Nothing, NamedTuple{(:show_trace, :store_trace, :extended_trace, :g_tol, :allow_f_increases), Tuple{Bool, Bool, Bool, Float64, Bool}}}, constantcoef::NamedTuple{(), Tuple{}}, omegas::Tuple{}, ensemblealg::EnsembleThreads, checkidentification::Bool, diffeq_options::NamedTuple{(), Tuple{}})
@ Pumas /builds/PumasAI/PumasSystemImages-jl/.julia/packages/Pumas/XHa5R/src/estimation/likelihoods.jl:2409
[13] fit(m::PumasModel{ParamSet{NamedTuple{(:logκ, :logγ, :logf0, :σ²κ, :σ²γ, :σ²f0, :σ²f), Tuple{RealDomain{TransformVariables.Infinity{false}, TransformVariables.Infinity{true}, Float64}, RealDomain{TransformVariables.Infinity{false}, TransformVariables.Infinity{true}, Float64}, RealDomain{TransformVariables.Infinity{false}, TransformVariables.Infinity{true}, Float64}, RealDomain{Float64, TransformVariables.Infinity{true}, Float64}, RealDomain{Float64, TransformVariables.Infinity{true}, Float64}, RealDomain{Float64, TransformVariables.Infinity{true}, Float64}, RealDomain{Float64, Float64, Float64}}}}, var"#39#55", var"#40#56", var"#42#58", var"#44#60", ODEProblem{Nothing, Tuple{Nothing, Nothing}, false, Nothing, ODEFunction{false, ModelingToolkit.ODEFunctionClosure{var"#45#61", var"#46#62"}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Vector{Symbol}, Symbol, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing}, Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, SciMLBase.StandardODEProblem}, var"#47#63", var"#51#67", ModelingToolkit.ODESystem}, population::Vector{Subject{NamedTuple{(:Fluo,), Tuple{Vector{Float64}}}, Pumas.ConstantCovar{NamedTuple{(), Tuple{}}}, Vector{Pumas.Event{Float64, Float64, Float64, Float64, Float64, Float64, Int64}}, Vector{Int64}}}, param::NamedTuple{(:logκ, :logγ, :logf0, :σ²κ, :σ²γ, :σ²f0, :σ²f), NTuple{7, Float64}}, approx::Pumas.FOCE)
@ Pumas /builds/PumasAI/PumasSystemImages-jl/.julia/packages/Pumas/XHa5R/src/estimation/likelihoods.jl:2392
[14] top-level scope
@ ~/data/code/testing nlme/Test_define_model.jl:72
in expression starting at /home/jrun/data/code/testing nlme/Test_define_model.jl:72