calliope-project / calliope

A multi-scale energy systems modelling framework
https://www.callio.pe
Apache License 2.0
276 stars 89 forks source link

Invalid configuration showing for un-activated modes due to schema defaults #626

Open irm-codebase opened 5 days ago

irm-codebase commented 5 days ago

What happened?

This issue came up during debugging for #625.

Our current approach to the model schema introduces potential confusions for users, since schema defaults for modes that are not even present in the "activated" math show up.

In this case, I am debugging the example urban model in "operate" mode. A bunch of parameters related to SPORES show up!

image

This is caused by our current approach to schemas: we use a single model schema file, instead of extending it. I have the following suggestions:

Which operating systems have you used?

Version

v0.7

Relevant log output

No response

brynpickering commented 3 days ago

Hmm. I tend to think that it's going to be impossible to decide on-the-fly what config options from the schema to extract for a given model build/solve. We could scan the math for references but in the case of different run modes, we might only reference those configuration options in the Python implementation (operate_window and operate_horizon do not appear in the math, same for some spores config options).

Further complicating things is that we can load a model and build it in one mode, solve it, then re-build it and solve it in another mode (e.g. if we want to use plan mode results to initialise capacities in operate mode). So we have to be able to switch config options in and out.

Maybe you're right though that we could have operate and spores mode schema elements that are stored in separate files and then added to the config schema at the model.build/solve step. The only issue is how to enable a user to inspect the config that will be sent to e.g. the model.build step before running model.build (if they are added only on calling build(), they won't be visible in model.config.build, same for solve options).

irm-codebase commented 3 days ago

@brynpickering wouldn't it be possible if the MODEL_SCHEMA was constructed inside the Model class instead of a global? We already have the update_model_schema function, meaning that it is def. possible to combine schemas if they meet some specs.

With some added logic (a "compatible_base_math" value?) we could even mix and match our own math and avoid conflicts without adding a lot of logic on our end (i.e., telling our matcher that operate mode and storage_inter_cluster are incompatible).

As for the config: that's why I think the added logic to model.attrs is necessary. If we hold a .config_kwargs["init"/"build"/"solve"] it should be possible...

brynpickering commented 2 days ago

Yes, I suppose in theory it would be possible. Although we're talking here about the CONFIG_SCHEMA and update_model_schema doesn't relate to it. This is because we don't want the configuration schema to be editable in any way. Many of the spores options may well move to the model definition (as parameters), It's then a question of how to handle those which stay such that they only appear if spores math is being used in the build.

One option would be to filter the config at build/solve stages using parameters defined in the schema. E.g. a x-mode parameter (x- signifies custom params in JSON schema) that is used to trigger spores or operate mode config on build.

irm-codebase commented 2 days ago

You are right on that! Sorry, the MODEL_SCHEMA bit was wrong on my end.

But yeah, the general idea is to maybe have some step were we combine stuff into a schema (CONFIG_SCHEMA in this case). Just having separate .yaml files with the specifics of each mode, and combining them on build.

This would come with some added maintainability benefits, too. If someone comes up with new functionality that requires another mode and is incompatible with other modes (or at least where compatibility is unknown), we would be able to define it.