# ModelingToolkit, vars to varmap?

**URL:** <https://discourse.julialang.org/t/modelingtoolkit-vars-to-varmap/106904>\
**Category:** Modelling & Simulations\
**Tags:** modelingtoolkit\
**Created:** [November 29, 2023, 3:05pm UTC](https://discourse.julialang.org/t/modelingtoolkit-vars-to-varmap/106904 "2023-11-29T15:05:40Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![rpex](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rpex/32/204786_2.png) [@rpex](https://discourse.julialang.org/u/rpex)\
**Post date:** [November 29, 2023, 3:05pm UTC](https://discourse.julialang.org/t/modelingtoolkit-vars-to-varmap/106904/1 "2023-11-29T15:05:40Z")

</div>

Hello,  
Is there a function to get the index from variable names in ModelingToolkit.jl? Or a function that returns me a varmap (`Vector{Pair{Num, Float64}}`)?  
So the opposite of `ModelingToolkit.varmap_to_vars()`

> [@\[ModelingToolkit.jl\] varmap\_to\_vars function](https://discourse.julialang.org/t/modelingtoolkit-jl-varmap-to-vars-function/98207):
>
> Hello, I have a question about the ModelingToolkit package, and in particular about @parameters value maps. @parameters t k₁₂ k₂₁ α p = [k₁₂ =\> 0.0005 k₂₁ =\> 0.009 α =\> 0.09] I have an ODE system and I want to fit some data on it. As a test, I tried to generate fake data with the following code (from documentation of [DiffEqParamEstim.jl: Parameter Estimation for Differential Equations · DiffEqParamEstim.jl](https://docs.sciml.ai/DiffEqParamEstim/stable/)) without noise. begin using RecursiveArrayTools # for VectorOfArray randomized = Ve…

I’m currently using:

```julia
function varname_to_varmapindex(varname)
    states_sys = states(sys)
    length_states = size(states_sys, 1)
    index = findfirst(i -> (states_sys[i].metadata)[Symbolics.VariableSource][2] == varname, 1:length_states)
    return isnothing(index) ? -1 : index # Return -1 or another suitable value if not found
end

```

For example, in a callback I would like to call the variable by name and not by the index.

```julia
function affect!(integrator)
    index = varname_to_varmapindex(:varname)
    integrator.u[index] += 1.0
end

```

Or if I want the result at a specific timestep.

```julia
sol(timestep)[index]

```

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [November 29, 2023, 3:24pm UTC](https://discourse.julialang.org/t/modelingtoolkit-vars-to-varmap/106904/2 "2023-11-29T15:24:54Z")

</div>

You can index the solution object with symbols (and expressions) like so

```julia
sol(timestep, idxs = var) # Get the value at var at time timestep
sol(timestep, idxs = var^2 - 1) # Get the value of expression var^2 - 1

```

Otherwise you find the answer to your question here [Frequently Asked Questions · ModelingToolkit.jl](https://docs.sciml.ai/ModelingToolkit/dev/basics/FAQ/)

and may also find

```julia
ModelingToolkit.defaults(sys)

```

useful.

---

<div class="post-metadata">

**Author:** ![contradict](https://avatars.discourse-cdn.com/v4/letter/c/ac91a4/32.png) [@contradict](https://discourse.julialang.org/u/contradict)\
**Post date:** [November 29, 2023, 3:41pm UTC](https://discourse.julialang.org/t/modelingtoolkit-vars-to-varmap/106904/3 "2023-11-29T15:41:41Z")

</div>

The integrator struct doesn’t have provide a way to access the system, so the only way I have figured out to do this is to create the affect (or condition) in a closure. You should modify your `varname_to_varmapindex` function to accept an argument for `sys` as well, creating `sys` as a global variable can lead to performance problems.

```julia
function create_increment_affect(sys, varname)
    let index = varname_to_varmapindex(sys, varname)
        function affect!(integrator)
            integrator.u[index] += 1.0
        end
    end
end

```

---

<div class="post-metadata">

**Author:** ![rpex](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rpex/32/204786_2.png) [@rpex](https://discourse.julialang.org/u/rpex)\
**Post date:** [November 29, 2023, 3:52pm UTC](https://discourse.julialang.org/t/modelingtoolkit-vars-to-varmap/106904/4 "2023-11-29T15:52:17Z")

</div>

Thanks! Both answers are my solution!

---

<div class="post-metadata">

**Author:** ![contradict](https://avatars.discourse-cdn.com/v4/letter/c/ac91a4/32.png) [@contradict](https://discourse.julialang.org/u/contradict)\
**Post date:** [November 29, 2023, 3:56pm UTC](https://discourse.julialang.org/t/modelingtoolkit-vars-to-varmap/106904/5 "2023-11-29T15:56:03Z")

</div>

Another option, since you are already using ModelingToolkit, is to use the symbolic event handling [interface](https://docs.sciml.ai/ModelingToolkit/stable/basics/Events/). Most uses of callbacks can be fit into this framework, although you do need to occasionally mark a variable as [irreducible](https://github.com/SciML/ModelingToolkit.jl/issues/1896#issuecomment-1287445792) (tell the simplification code not to elminiate this variable as a state).

---

<div class="post-metadata">

**Author:** ![rpex](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rpex/32/204786_2.png) [@rpex](https://discourse.julialang.org/u/rpex)\
**Post date:** [November 29, 2023, 4:32pm UTC](https://discourse.julialang.org/t/modelingtoolkit-vars-to-varmap/106904/6 "2023-11-29T16:32:28Z")

</div>

Do I understand correctly that the difference between Event Handling and Callback Functions is that an event is symbolically added to the ODE system and, after simplification, is executed as a callback?

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [November 29, 2023, 4:37pm UTC](https://discourse.julialang.org/t/modelingtoolkit-vars-to-varmap/106904/7 "2023-11-29T16:37:37Z")

</div>

“Event” and “Callback” is used almost interchangeably. An “event” is something that happens (condition triggers) that triggers an action, the callback function.

When you use the symbolically specified events in MTK, those are translated internally into callbacks, similar to how you would write the callbacks yourself.
