Skip to content

Make the new-format templater output set granularity-invariant#125

Open
nick-gorman wants to merge 6 commits into
mainfrom
granularity-invariant-templater-output
Open

Make the new-format templater output set granularity-invariant#125
nick-gorman wants to merge 6 commits into
mainfrom
granularity-invariant-templater-output

Conversation

@nick-gorman

@nick-gorman nick-gorman commented Jun 24, 2026

Copy link
Copy Markdown
Member

This PR containts a few small fixes aiming at making sure the templater output is consistent.

  • Wire in timeslices templating to create_template.py
  • Update create_template.py to emit empty custom constraint tables when granularity is not sub_regions.
  • Add costs_connection as an expected templater output
  • Update CLI test which check templater output tables
  • Updae create_template.py unit test for new granualrity behaviour
src/ispypsa/templater/
├── create_template.py                  → wire in timeslices + costs_connection;
│                                          emit header-only cc tables at coarse granularity
└── custom_constraints_from_plexos.py   → empty_custom_constraint_tables() helper
tests/
├── test_cli/test_create_ispypsa_inputs_new_table_formats.py  → output-list coverage
└── test_templater/test_create_ispypsa_inputs_template.py     → per-granularity tests

The new-format templater now emits the same table set at every
granularity: timeslices and costs_connection are wired in, and the
custom-constraint tables are emitted header-only at nem_regions /
single_region instead of being absent. This reverses the gating from
9366945 — the PLEXOS constraints are sub-regional export-group limits
with no meaningful representation once sub-regions are collapsed, but
writing "all columns, no rows" tables means list_templater_output_files
needs no granularity awareness and downstream consumers never check for
missing tables.

costs_connection is also now tracked in the output list — it was being
written but untracked, the same class of bug 9366945 fixed for the
constraint tables.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@codecov

codecov Bot commented Jun 24, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

Files with missing lines Coverage Δ
src/ispypsa/templater/create_template.py 92.94% <100.00%> (ø)
...spypsa/templater/custom_constraints_from_plexos.py 100.00% <100.00%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

nick-gorman and others added 5 commits June 24, 2026 13:08
The three _stub_* helpers built their DataFrames by hand (dict-of-lists),
the outliers in a file that otherwise uses the csv_str_to_df convention.
Convert them so the fixtures read as row-oriented tables — the timeslice
calendar especially, since test_timeslices.py already writes that exact
shape with csv_str_to_df. The helpers are module-level, so the fixture is
threaded in as a parameter rather than imported.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The nem_regions and single_region tests both assert the new-format output
at a collapsed granularity, but had diverged: single_region only checked
the custom-constraint tables had *some* columns where nem_regions pinned
the exact column set, and neither asserted timeslices at all. timeslices is
granularity-invariant (decoded from the calendar + reference_year_sequence,
independent of regional_granularity), so omitting it left the invariance
this PR establishes unchecked at the coarse granularities. Pin the exact
custom-constraint column sets in single_region and assert timeslices (two
patterns, same as sub_regions) in both.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The new-format CLI test pins a row count plus referential integrity for
every output table except custom_constraints, which only checked that the
LHS/RHS rows carried no orphan constraint_ids. Add a principled constraint
count (one per CONSTRAINT_NAMES in scripts/extract_plexos_constraints.py)
and a drift-detection count for the LHS coefficient rows, so a regression
in the populated sub_regions output is caught here rather than only in the
per-module tests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
empty_custom_constraint_tables() declared the three tables' column sets as
module constants, but the populated builders still hardcoded their own
copies of the same lists. Nothing coupled the two, so a future change to a
builder's output columns would silently diverge from the header-only tables
emitted at coarse granularities, breaking the granularity-invariance this
branch establishes. Project every builder onto the shared constants so the
populated and empty tables have one definition, and split the CLI test's
empty-case assertion so a failure names the offending table.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The same explanation now lives in empty_custom_constraint_tables()'s
docstring, which the else-branch calls.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant