From 38797736a4f1bb2b55e1795d83d0fe525ffd9218 Mon Sep 17 00:00:00 2001 From: Mannu Date: Sat, 16 May 2026 12:56:31 +0530 Subject: [PATCH] fix: correct hourly index calculation for 25-year data - Reset index per year caused out-of-bounds error - Simplified loop using sequential hour_idx 0-8759 per year Co-Authored-By: Claude Opus 4.7 --- .../src/remodel_engine/scenarios/runner.py | 49 ++++++++++++------- 1 file changed, 30 insertions(+), 19 deletions(-) diff --git a/packages/engine/src/remodel_engine/scenarios/runner.py b/packages/engine/src/remodel_engine/scenarios/runner.py index 38f4615..9839774 100644 --- a/packages/engine/src/remodel_engine/scenarios/runner.py +++ b/packages/engine/src/remodel_engine/scenarios/runner.py @@ -508,26 +508,37 @@ def run_scenario(inputs: ScenarioInput) -> ScenarioResult: fy_start = cod_year + year fy_label = f"{fy_start}-{str(fy_start + 1)[-2:]}" - # Generate timestamps for this year - hour_idx = 0 - for month in range(12): - month_len = month_lengths[month] - for day in range(1, month_len + 1): - for hour in range(24): - # ISO timestamp - month_num = month + 4 if month < 8 else month - 8 - year_adj = fy_start + 1 if month >= 8 else fy_start - dt = f"{year_adj:04d}-{month_num:02d}-{day:02d}T{hour:02d}:00:00" - hourly_timestamps.append(dt) - hourly_fy.append(fy_label) - hourly_proj_year.append(proj_year) + # Run through each hour sequentially (0 to 8759) + for hour_idx in range(8760): + # Map hour_idx to month/day/hour + hour_of_year = hour_idx + # Find month by cumulative hours + cum_hours = 0 + for m in range(12): + month_len = month_lengths[m] + if hour_of_year < cum_hours + month_len * 24: + month = m + day_of_month = (hour_of_year - cum_hours) // 24 + 1 + hour_of_day = (hour_of_year - cum_hours) % 24 + break + cum_hours += month_len * 24 - idx = year * 8760 + hour_idx - total_re = pipe.solar_hourly[idx] + pipe.wind_hourly[idx] - hourly_total_re.append(total_re) - hourly_client_end.append(total_re * loss_factor) - hourly_load.append(client_load_mw) - hour_idx += 1 + # ISO timestamp + month_num = month + 4 if month < 8 else month - 8 + year_adj = fy_start + 1 if month >= 8 else fy_start + dt = f"{year_adj:04d}-{month_num:02d}-{day_of_month:02d}T{hour_of_day:02d}:00:00" + hourly_timestamps.append(dt) + hourly_fy.append(fy_label) + hourly_proj_year.append(proj_year) + + # Use full index into hourly arrays + idx = year * 8760 + hour_idx + solar_val = pipe.solar_hourly[idx] if pipe.solar_hourly and idx < len(pipe.solar_hourly) else 0.0 + wind_val = pipe.wind_hourly[idx] if pipe.wind_hourly and idx < len(pipe.wind_hourly) else 0.0 + total_re = solar_val + wind_val + hourly_total_re.append(total_re) + hourly_client_end.append(total_re * loss_factor) + hourly_load.append(client_load_mw) return ScenarioResult( inputs=inputs,