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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions