Re-sequence new-format timeslice patterns onto snapshots - #130
Conversation
The translator assigns a reference year to each model financial year with the identical construct_reference_year_mapping call the trace pipeline makes, so timeslice windows and demand/VRE traces always come from the same weather years — the binding interaction between hot-day limits and hot-day demand survives any configured cycle. The year before the first model year also gets a pattern (the cycle's last reference year, cycle-consistent) because winter windows run April-October and must cover the first model year's July-September snapshots. Month-day boundaries of 29 February (reference year 2024 carries them) clamp to 28 February in non-leap model years. The wrap decision for exclusive ends compares the month-day strings rather than the placed dates, so clamping a one-day 02-28..02-29 window collapses it to empty instead of stretching it out a year. A configured cycle requesting reference years the timeslices table has no patterns for raises rather than silently never binding. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests.
... and 9 files with indirect coverage changes 🚀 New features to boost your workflow:
|
…ed windows The first cut re-sequenced patterns by placing each month-day window into absolute dates within its financial year and joining snapshots onto the result. That needed a prior-year pattern to cover the first model year's July-October (winter starts in the previous financial year), a rule for which calendar year a start lands in, leap-day clamping for 29 February boundaries landing in non-leap years, and a subtle string-vs-date wrap comparison to keep the clamp from stretching a one-day window out a year. It also relied on the boundary-crossing window (winter) being identical across reference years so the seams between model years tiled cleanly. Comparing each snapshot's month-day directly against its model year's pattern removes all of that. A snapshot is in a window when its month-day lies in the window's range (an end at or before its start wraps past New Year), so no dates are constructed, 29 February simply never matches in a non-leap year, and each model year is self-contained: it takes every one of its dates from its own reference year's pattern, so switching pattern at the model-year boundary can never leave a gap or an overlap whatever the two patterns look like. That also drops the fy-only restriction — the only year_type-specific step is which calendar year a snapshot's model year is. Snapshots are stamped with their interval's end time, so model year and month-day are read off the interval's last instant (one second before the stamp): the snapshot stamped 1 July 00:00 is the last interval of the financial year just ended, and one stamped 1 November 00:00 falls in the window ending 1 November rather than the one starting there. The schema's column descriptions lose the placement and clamping rules, and gain a config-to-table validation entry recording that the configured reference_year_cycle must have patterns (enforced by the translator). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Whether every reference year in the configured reference_year_cycle has a timeslice pattern is a config-to-table check, which belongs in the validation layer once it has the model config in hand. The schema entry now specifies it (skipped when the table is absent or empty, since no patterns at all is a valid configuration) and the translator no longer raises. A reference year with no pattern simply tags none of its model year's snapshots; tagging is now a cross join of each model year's snapshots with its pattern filtered by a vectorised month-day mask, so an empty pattern falls out naturally. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…cstring Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Series.where reads back to front (self is the true branch); naming the two cases and combining them with plain boolean algebra reads as the sentence the docstring states. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… config The mapping was built inside the function from the capacity-expansion reference_year_cycle, which silently diverged from the trace pipeline for operational-phase snapshots (that pipeline picks the cycle by model phase). Taking reference_year_mapping and year_type directly — the same arguments the trace timeseries functions take — lets the caller pass the one mapping it built for the traces, so timeslices and traces come from the same weather years by construction. The module no longer depends on the config or isp_trace_parser, and the tests pass a literal mapping instead of mutating the fixture config. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
EllieKallmier
left a comment
There was a problem hiding this comment.
Yeah this all seems pretty buttoned up to me :)
A general translator-related thought comes up - that I think we've discussed before but I can't remember the conclusion/if there was one - around validating/checking translator outputs and whether we're going to adopt the same approach here as for the templater outputs. Or even just whether there's value in writing up translator output schemas in a similar way as a mid-term reference or something?
But no notes on this PR from me, happy to go with this as is :)
@ellie, sorry forgot to reply to this. Yep, I think translator output schema make a lot of sense and once we build the infrastructure for running validation on the templater output, re-using it for the translator would be pretty easy. So yeah, I think we could be writing those schema going forward if we wanted to. |
Adds the translator-side timeslice module. It maps each templated timeslice window pattern onto the model's snapshots, producing a
timeslice_snapshotstable (timeslice_id, investment_periods, snapshots) that later functionality will use to apply per-timeslice link limits and to scope the temporal custom constraints.🤖 Generated with Claude Code