Best way to get dimension keys within run_timestep

I would like to get information from the Model within run_timestep and init. In particular, I want to call dim_keys. Is this information available in the d object? Or what is the accepted way to get model information within these functions?

In the past, I have been set up things up outside of these functions, but I now have a case where the relevant work needs to be done differently for each Monte Carlo. I like to avoid storing the relevant information in a parameter (regionnames = Parameter{String}()) since these functions should know what model they are being called on.

Hi @jrising sorry for the long delay on this! This is something that I have been frustrated with as well with the current implementation, in models like MimiGIVE and MimiSSPs we did as you said and stored relevant information in a parameter, but as you suggest this is a bit fragile since if one changes the other roan’t automatically change, necessitating extra checks.

I opened this issue a while ago focused on exactly this (Add access to time information in the `init` function; Add Dimensions keys to `d` · Issue #948 · mimiframework/Mimi.jl · GitHub) and will put this at the top of the todo stack! @davidanthoff let us know if you have any thoughts on this though.

@jrising I’m going to start working on this now. My goals are to first allow access to dimension information, and second (longer term) to allow indexing directly with the dim keys instead of integers, though that might have some performance issues.

Issue is here: Add access to time information in the `init` function; Add Dimensions keys to `d` · Issue #948 · mimiframework/Mimi.jl · GitHub and will open a PR soon

That’s great to hear. An alternative would be to just provide a function like thismodel() that can be called in both init and run_timestep, and returns the model that a given component is being run within. That’s effectively my current solution.

Ah interesting, I like that idea too, gives you access to all the information you could need. Since the ModelInstance is being built as you run, I assume it’s really the ModelDefinition that you are accessing? I’m curious how you do that, either passing a function from outside or taking advantage of the fact that the component “knows” what model it is running in? If you have some code I can look at I will, since collaborating on solutions is always good.

I don’t want to break any compatibility, so I can’t modify p of (p,v,d,t) too much but was considering adding keys to the p NamedTuple like country_labels so you’d have a _labels version of each dimension — but wasn’t loving that approach.

My current solution is to set the model as a parameter on the component. I use that in a bunch of components of the national-level version of MimiPAGE, since I often need to match up the region and national dimensions. e.g., here:

A simple option for you would be to have model be a preset parameter. It wouldn’t break any code as long as any explicitly defined model parameter overrides this implicit one. The thismodel() function is the same idea. It’s not a real function and gets translated in the macro parser into the model variable.

@jrising wonderful thank you! Yes, I like the thismodel() idea in the macro, what I realized though is that at the time of parsing @defcomp you don’t necessarily have a model yet – in fact you certainly don’t – but I like the idea of a default thismodel() function along those lines and we could add thismodel as a field in the ComponentInstance struct and fill it in upon build!ing the model, or even adding the component to a model. So we could have something like thismodel() that returns your ComponentInstance’s my model` field.

That makes sense. There’s probably a broader design question about how to provide this kind of model-scope information within the component-scope, but I don’t have any useful input on that.

1 Like