Skip to content

[Feature Request] Enable n-Step Ahead Forecasts in FromNPY Chronics Handler #741

@RalfCortes

Description

@RalfCortes

Environment

  • Grid2op version: 1.12.1
  • System: linux

Summary

Extend the FromNPY chronics handler to support multi-step (n-th step ahead) forecasts, instead of being limited to 1-step ahead forecasts.

This would significantly improve compatibility with modern forecasting pipelines and reinforcement learning setups that rely on multi-horizon predictions.

Current Behavior

Using grid2op, it is currently possible to inject custom time series dynamically through the FromNPY chronics handler:

import grid2op
import numpy as np
from lightsim2grid import LightSimBackend
from datetime import timedelta
from grid2op.Chronics import FromNPY

env = grid2op.make(
    "l2rpn_case14_sandbox",
    backend=LightSimBackend(),
)

init_obs = env.reset()

# Artificially create a timeseries :
load_p, load_q, prod_p, prod_v = (
    init_obs.load_p,
    init_obs.load_q,
    init_obs.prod_p,
    init_obs.prod_v,
)

load_p = np.concatenate([[load_p] * 48], axis=0)
load_q = np.concatenate([[load_q] * 48], axis=0)
prod_p = np.concatenate([[prod_p] * 48], axis=0)
prod_v = np.concatenate([[prod_v] * 48], axis=0)

load_p_fc = load_p
load_q_fc = load_q
prod_p_fc = prod_p
prod_v_fc = prod_v

# Now create the env with custom timeseries data

env = grid2op.make(
    "l2rpn_case14_sandbox",
    backend=LightSimBackend(),
    chronics_class=FromNPY,
    data_feeding_kwargs={
        "i_start": 0,
        "i_end": 48,
        "load_p": load_p,
        "load_q": load_q,
        "prod_p": prod_p,
        "prod_v": prod_v,
        # "gen_p_for_handler": PerfectForecastHandler("prod_p_forecasted"),
        # "gen_v_for_handler": PerfectForecastHandler("prod_v_forecasted"),
        # "load_p_for_handler": PerfectForecastHandler("load_p_forecasted"),
        # "load_q_for_handler": PerfectForecastHandler("load_q_forecasted"),
        "load_p_forecast": load_p_fc,
        "load_q_forecast": load_q_fc,
        "prod_p_forecast": prod_p_fc,
        "prod_v_forecast": prod_v_fc,
        "h_forecast": [i * 30 for i in range(1, 48)],
        "time_interval": timedelta(minutes=30),
    },
)

It is also straightforward to update chronics dynamically:

env.chronics_handler.change_chronics(
    new_load_p=timeserie.load_p,
    new_load_q=timeserie.load_q,
    new_prod_p=timeserie.gen_p,
    new_prod_v=timeserie.gen_v,
)


env.chronics_handler.change_forecasts(
    new_load_p=load_p_fc,
    new_load_q=load_q_fc,
    new_prod_p=gen_p_fc,
    new_prod_v=gen_v_fc,
)

Limitation

Unfortunately as specified around line 460 in Chronics/FromNPY.py, the current implementation only supports 1-step ahead forecasts.

I think internally, forecasts are expected to match the shape: (n_timesteps, n_elements)

For my application I would like to use n-th step ahead forecasts.

Possible implementation :

To allow FromNPY to support multi-step forecasts :

  • Change the default forecasts with shape (n_timesteps, n_horizons, n_elements) or (n_horizons, n_timesteps, , n_elements)
  • Keep backwards compatibility with n=1 by converting originals (n_timesteps, n_elements) to (n_timesteps, 1, n_elements) automatically

Near the end of the time series, higher-horizon forecasts will not have valid targets. Possible approaches:

  • Allow zero-padding (simplest)
  • Allow NaNs

Given the presence of i_end, zero-padding is likely acceptable and consistent with current behavior.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions