Template the per-reference-year timeslice window patterns#121
Conversation
AEMO timeslice calendar (timeslice_RefYear5000.csv, shipped under templater/plexos/ with the other PLEXOS data-package extracts) marks hot day / typical summer / winter windows on absolute dates, with each planning year's dates derived from the weather of the reference year AEMO assigned to it. Templating the calendar as absolute windows would bake AEMO's reference-year sequence into every run regardless of the user's configured reference_year_cycle, so peak-day limits would fall on days that aren't peaks in the modelled traces. Instead the templater inverts the calendar: it assigns windows to the planning year they start in, labels them via Table 1 of the Draft 2026 ISP Market Model Instructions (transcribed as the manually extracted reference_year_sequence table, extended cyclically per AEMO's repeating sequence), and emits one month-day window pattern per reference year for the translator to re-sequence. Every occurrence of a reference year must carry an identical pattern — the check that proves the Table 1 decode against the data; it passes for all 33 usable planning years. Planning years truncated at the calendar horizon (windows that never turn off) are dropped whole: their reference years recur earlier with complete windows. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests.
🚀 New features to boost your workflow:
|
The templater attributes each calendar window to a reference year by its start date and emits one month-day pattern per reference year. That is only sound while a few structural invariants of AEMO's calendar hold, which were previously assumed silently. Make them fail loud: - partition: each reference year's windows must tile the year exactly (checked inline in _template_timeslices; boundary-based, so leap-safe) - attribution: only winter may cross the 1 July financial-year boundary, and winter must be identical across reference years, so a boundary-crossing window cannot blur reference years (standalone guards, run on the shipped calendar) Also declare the no-overlap and full-coverage rules in the timeslices schema for the future validation layer, and add tests: a shipped-calendar smoke test, focused guard tests, and a leap-day case pinning that the templater preserves 02-29 (clamping to 02-28 in non-leap model years is the translator's job). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
| return windows[["timeslice_id", "start_date", "end_date"]].reset_index(drop=True) | ||
|
|
||
|
|
||
| def _drop_horizon_truncated_planning_years(windows: pd.DataFrame) -> pd.DataFrame: |
There was a problem hiding this comment.
I think this is one of those moot questions (assuming we can know the templater input pretty confidently), but is there a chance that this drops a planning year that doesn't have a complete occurrence of the same ref year?
There was a problem hiding this comment.
Yep, it's relying on the templater input having at least one complete year for each reference year.
There was a problem hiding this comment.
Observation - This test structure seems a little different than others, testing the sub-functions just by calling the orchestrator with different input configurations, rather than testing each function explicitly. No comment really just noting in case there's a specific reasoning or preference behind this style!
AEMO's PLEXOS data package ships a timeslice calendar (
timeslice_RefYear5000.csv): one row per on/off event recording, on absolute dates across the whole model horizon, when each region's demand-condition timeslice — peak (hot day), typical-summer, or winter — switches on (-1) or off (0). The dates aren't arbitrary: AEMO assigns each planning financial year a reference (weather) year from a rolling 16-year sequence (Table 1 of the Draft 2026 ISP Market Model Instructions) and lays that year's conditions onto the calendar. So a given weather year recurs every 16 years, and the calendar is really one annual pattern per reference year, stamped repeatedly across the horizon.This PR adds the templater step that inverts that into one month-day window pattern per reference year. It pairs each on-event with its following off to form a window, labels the window by the financial year it starts in (and so by that year's reference year), checks every occurrence of a reference year carries the same pattern, and keeps one. The translator (a later PR) re-sequences these patterns onto the user's configured
reference_year_cycle.The decode stays this simple — pair an on with its own off, label by start year — because of how AEMO's data is shaped. Within a reference year the windows tile the year exactly, with peak and summer carrying the weather variation; winter is a fixed seasonal block (April–November on the mainland), identical across reference years, and the only timeslice whose window crosses the 1 July financial-year boundary. Peak and summer therefore sit wholly inside one reference year, so labelling them by start date is unambiguous; winter does straddle the boundary, but being invariant, which reference year "owns" its end can't change the result. So the decode needs no cross-reference-year or leap-day reconciliation — and tests fail if a future calendar breaks either property (a weather-varying window crossing 1 July, or winter differing between reference years).
Not wired into the templater orchestrator yet.