Skip to content

[DISCUSS] differentiated masking within expressions #16

Description

@brynpickering

One of the hardest things we found in the implementation of the calliope math spec was how to handle application of macros/helpers in math when the expression's mask would mask out some of the data. Sometimes you want the mask to be applied to an expression before an operation is applied, sometimes you don't want the mask to be applied. Examples below.

The main questions I have are:

  • How can we best flag protection of an expression from the mask in a macro/helper? Calliope approach isn't particularly satisfactory.
  • Do we allow a mask macro/helper in the expressions to enable per sub-expression masking within a single larger expression? calliope doesn't yet allow full arbitrary where strings within the expression helper as it proved to be a pain to implement, but it does allow masking with a lookup.

You want a mask applied throughout

For instance, you might be summing over all technologies at nodes limited in a mask:

constraints:
  special_limit:
    foreach: [node]
    mask: special_nodes
    expression: sum(capacity, over=tech) < 5

In Calliope, if we now want to also mask the techs, we could mask or slice directly within the expression:

constraints:
  special_limit:
    foreach: [node]
    mask: special_nodes
    expression: sum(capacity[tech=special_techs], over=tech) < 5
constraints:
  special_limit:
    foreach: [node]
    mask: special_nodes
    expression: sum(mask(capacity, a_more_complex_lookup), over=tech) < 5

You don't want the mask applied

If you are shifting the timesteps or using a lookup to map between timesteps you want to do the shifting/mapping first and then apply the mask. E.g., if you are applying a constraint to the last timestep in each day, but it needs to take the value of the first timestep of that day in the applying the constraint, you can't mask with an input array final_ts_each_day as that would nullify the first timestep that we will ultimately map to.

Or, perhaps you want to apply a constraint over a subset of technologies and compare it to a sum of all technologies:

constraints:
  special_limit:
    foreach: [tech, node]
    mask: special_techs
    expression: capacity < sum(capacity, over=tech) * 0.5  # the sum will be limited to only `special_techs`, but we mean for it to be for _all_ techs

The way we circumvented it in calliope was to have a per-helper flag for whether it allowed pre-masking the array before applying the helper or not. Or, you create a separate expression with the operation applied, and then use that later:

expressions:
  capacity_sum_all:
    foreach: [node]
    expression: sum(capacity, over=tech)
constraints:
  special_limit:
    foreach: [tech, node]
    mask: special_techs
    expression: capacity < capacity_sum_all * 0.5

I never found either approach particularly satisfactory.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    design: declinedArgued against; closes as not planned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions