Skip to content

Templated alias body: mixed bare-placeholder + bound-coord state subscripts collapse to per-cell names #113

@jc-macdonald

Description

@jc-macdonald

Summary

Inside a templated alias body, a state subscript that mixes bare LHS-template placeholders with =-bound apply_along coords is destructively rewritten to a per-cell name, dropping the bound parts.

Repro

Spec snippet (per-loc force-of-infection, no spatial coupling):

state:
  - X[age, vax, loc, imm]
  - I1[age, vax, loc]
  ...

aliases:
  foi[age, loc]: "apply_along(vax=v,
                    I1[loc, age=ap, vax=v]
                  + apply_along(imm=k, X[loc, age=ap, vax=v, imm=k]))"

transitions:
  - {from: "X[age, vax, loc, imm]", to: "E[age, vax, loc]",
     rate: "foi[age, loc] * theta[imm]"}

age is the templated LHS axis used as the bound apply_along coord (age=ap); loc is the LHS template wildcard. At alias expansion time the body's X[loc, age=ap, vax=v, imm=k] is fed to _apply_template_substitutions._inline_replacer:

phs = [p.strip() for p in inner.split(",") if p.strip() and "=" not in p]  # ["loc"]
...
return _render_template_name(inner_base, phs, assignment)                  # "X__loc_AK"

The =-bound parts (age=ap, vax=v, imm=k) are filtered out, then the bare placeholder collapses the whole subscript to X__loc_AK. Downstream this surfaces as a missing parameter, e.g. KeyError: "Required parameter 'X__age_age0to17__vax_unvaccinated__imm_x0__loc_AK' was requested but not configured."

Expected

The mixed-mode subscript should be rewritten to a canonical literal-cell selector that the regular apply_along/vectorize path already handles:

X[loc=AK, age=ap, vax=v, imm=k]

i.e. substitute each bare placeholder with its axis=coord binding from the LHS row assignment, preserve every =-bound entry verbatim, and let downstream resolve cell indices.

Scope

  • src/op_system/_templates.py::_apply_template_substitutions._inline_replacer — when bound entries are present alongside bare placeholders, switch to binding-rewrite instead of name-collapse.
  • Same path for shaped params is already correct (literal-index emission); leave shaped branch untouched.
  • Add a regression test in tests/op_system/test_op_system_specs.py covering the mixed case.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions