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 @dynamics
part 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