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

**URL:** <https://discourse.julialang.org/t/passing-a-variable-that-isnt-integrated-by-mtk-to-diffeqparamestim-objective-function/128308>\
**Category:** Modelling & Simulations\
**Tags:** optimization, sciml, modelingtoolkit\
**Created:** [April 22, 2025, 5:48pm UTC](https://discourse.julialang.org/t/passing-a-variable-that-isnt-integrated-by-mtk-to-diffeqparamestim-objective-function/128308 "2025-04-22T17:48:58Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jarrod-Angove](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jarrod-angove/32/42663_2.png) [@Jarrod-Angove](https://discourse.julialang.org/u/Jarrod-Angove)\
**Post date:** [April 22, 2025, 5:48pm UTC](https://discourse.julialang.org/t/passing-a-variable-that-isnt-integrated-by-mtk-to-diffeqparamestim-objective-function/128308/1 "2025-04-22T17:48:58Z")

</div>

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:

```julia
@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:

```julia
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:

```julia
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!

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [April 22, 2025, 5:58pm UTC](https://discourse.julialang.org/t/passing-a-variable-that-isnt-integrated-by-mtk-to-diffeqparamestim-objective-function/128308/2 "2025-04-22T17:58:41Z")

</div>

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

> **[Optimizing through an ODE solve and re-creating MTK Problems ·...](https://docs.sciml.ai/ModelingToolkit/stable/examples/remake/)**
>
> Documentation for ModelingToolkit.jl.

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

> **[Getting Started with JuliaSimModelOptimizer · JuliaSimModelOptimizer](https://help.juliahub.com/jsmo/stable/getting_started/)**
>
> Documentation for JuliaSimModelOptimizer.

---

<div class="post-metadata">

**Author:** ![Jarrod-Angove](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jarrod-angove/32/42663_2.png) [@Jarrod-Angove](https://discourse.julialang.org/u/Jarrod-Angove)\
**Post date:** [April 22, 2025, 10:46pm UTC](https://discourse.julialang.org/t/passing-a-variable-that-isnt-integrated-by-mtk-to-diffeqparamestim-objective-function/128308/3 "2025-04-22T22:46:01Z")

</div>

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