Passing a variable that isn't integrated by MTK to DiffEqParamEstim objective function

I’m still a bit new to MTK, please excuse me if I’m missing something simple here.

I have an ODE model that integrates over two variables, V_a and V_b. However, I can only measure the total volume, V_tot, so I have constructed my model to be:

@parameters begin
p_a = ...
p_b = ...
end
@variables begin
V_a(t) = 0.0
V_b(t) = 0.0
f_a(t) = ...
f_b(t) = ...
V_tot(t)
end

eqs = [
D(V_a) ~ (1 - (V_a + V_b)) * f_a(t; p_a...)
D(V_b) ~ (1 - (V_a + V_b)) * f_b(t; p_b...)
V_tot ~ V_a + V_b
]

Where f_a and f_b contain the parameters I am trying to optimize. I know that the build_loss_objective function in DiffEqParamEstim can be passed solver kwargs, but the kwarg save_idxs only appears to return integrated variables, so I can’t do something like save_idxs = [V_tot].

I have even tried to build my own loss function by following the documentation:

function loss(sol)
	tot_loss = 0.0
    if any((!SciMLBase.successful_retcode(s.retcode) for s in sol))
        tot_loss = Inf
    else
        tot_loss = sum((V_tot_train .- sol[Vtot]).^2)/length(V_tot_train)
    end
	tot_loss
end

But when I try to run the solver using this, it causes the solver to throw an error:

ArgumentError: invalid index: ModelingToolkit.ParameterIndex{SciMLStructures.Tunable, Int64}(SciMLStructures.Tunable(), 1, false) of type ModelingToolkit.ParameterIndex{SciMLStructures.Tunable, Int64}

Which I’m really struggling to understand… The loss function runs without throwing an error, and the build_loss_objective function runs without an error.

Any hints would be a huge help!

DiffEqParamEstim.jl won’t be able to do this. The MTK docs explain how to write cost functions in a good way here:

Or if you use the JuliaSimModelOptimizer that has this setup for a bunch of forms.

Thanks for taking the time to clear this up @ChrisRackauckas.