Time Series Handlers

New in version 1.9.0: This module is new in version 1.9.0

The goal of this module is to allow some fine-grain manipulation over the generation of the “time series” data of the environment.

You might want to first read Input data of an environment to get familiar with what are these time series and how they are used.

With these “handlers” you can generate the data used by the environment independantly for each type. To use this you have to provide :

  • one handler for “load_p”

  • one handler for “load_q”

  • one handler for “prod_p”

  • one handler for “prod_v”

  • (optional) one handler for the “maintenance”

  • (optional) one handler for “load_p_forecasted”

  • (optional) one handler for “load_q_forecasted”

  • (optional) one handler for “prod_p_forecasted”

  • (optional) one handler for “prod_v_forecasted”

Warning

I will not write “with great power comes great …” (close enough, you got it) but not every handlers are compatible with every others and depending on the options that you set (e.g “chunk_size”) you might end up with different results.

If you use handlers you need at least to understand the basics of what you are doing.

Interests of “handlers”

The main interest (at time of writing) of handlers is to be able to use some “approximation” of “multi steps ahead forecasts” in already available environment.

You can do that by using the PerfectForecastHandler or NoisyForecastHandler for “load_p_forecasted”, “load_q_forecasted”, “prod_p_forecasted” or “prod_v_forecasted”.

For example, for the environment l2rpn_wcci_2022 this gives:

import grid2op
from grid2op.Chronics import FromHandlers
from grid2op.Chronics.handlers import PerfectForecastHandler, CSVHandler, DoNothingHandler
env_name = "l2rpn_wcci_2022"
forecasts_horizons = [5, 10, 15, 20, 25, 30]

env = grid2op.make(env_name,
                   data_feeding_kwargs={"gridvalueClass": FromHandlers,
                                        "gen_p_handler": CSVHandler("prod_p"),
                                        "load_p_handler": CSVHandler("load_p"),
                                        "gen_v_handler": DoNothingHandler("prod_v"),
                                        "load_q_handler": CSVHandler("load_q"),
                                        "h_forecast": forecasts_horizons,
                                        "gen_p_for_handler": PerfectForecastHandler("prod_p_forecasted"),
                                        "load_p_for_handler": PerfectForecastHandler("load_p_forecasted"),
                                        "load_q_for_handler": PerfectForecastHandler("load_q_forecasted"),
                                       }
                  )

obs = env.reset()

# all works
obs.simulate(env.action_space(), 1)
obs.simulate(env.action_space(), 2)
obs.simulate(env.action_space(), 6)

sim_obs1, *_ = obs.simulate(env.action_space())
sim_obs2, *_ = sim_obs1.simulate(env.action_space())
sim_obs3, *_ = sim_obs2.simulate(env.action_space())

# and even this
f_env = obs.get_forecast_env()
obs = f_env.reset()
obs.max_step == 7  # initial state + 6 steps ahead forecast

This was not possible with the intial environment (and its default data_feeding_kwargs)

Note

Above, the forecast are “perfect” meaning the agent sees what will be the exact load and geenration a few hours in advance. If you want to add some noise, you can use the NoisyForecastHandler

Standard data generation and equivalent handlers

For each type of data generation, you can use “handler” to retrieve the same results. It has little interest to make the handlers if you want to get the default behaviour of course (more verbose and slower) but it might allow to use different data (for example removing the maintenance, or increasing the forecast horizons etc.)

For example instead of having (imports are removed for clarity):

env = grid2op.make(env_name,
                   data_feeding_kwargs={"gridvalueClass": GridStateFromFileWithForecasts,}
                  )

You can write, to have similar results:

env = grid2op.make(env_name,
                   data_feeding_kwargs={"gridvalueClass": FromHandlers,
                                        "gen_p_handler": CSVHandler("prod_p"),
                                        "load_p_handler": CSVHandler("load_p"),
                                        "gen_v_handler": CSVHandler("prod_v"),
                                        "load_q_handler": CSVHandler("load_q"),
                                        "maintenance_handler": CSVMaintenanceHandler(),
                                        "gen_p_for_handler": CSVForecastHandler("prod_p_forecasted"),
                                        "load_p_for_handler": CSVForecastHandler("load_p_forecasted"),
                                        "load_q_for_handler": CSVForecastHandler("load_q_forecasted"),
                                       }
)

Warning

The behaviour is not exactly the same between the “GridStateFromFileXXX” and the “FromHandlers” especially in the case of stochastic maintenance (grid2op.Chronics.GridStateFromFileWithForecastsWithMaintenance). Indeed when you call env.seed(XXX) the maintenance generated by GridStateFromFileWithForecastsWithMaintenance will not be the same as the one generated by JSONMaintenanceHandler (because the underlying pseudo random number generator) will not be seeded the same way.

Use with standard environments

In this section we write the “handlers” version you can use to reproduce the behaviour of some grid2op environments.

l2rpn_case14_sandbox

The setting for the “l2rpn_case14_sandbox” is:

import grid2op
from grid2op.Chronics import FromHandlers
from grid2op.Chronics.handlers import CSVHandler, CSVForecastHandler

env_name = "l2rpn_case14_sandbox"
env = grid2op.make(env_name,
                    data_feeding_kwargs={"gridvalueClass": FromHandlers,
                                        "gen_p_handler": CSVHandler("prod_p"),
                                        "load_p_handler": CSVHandler("load_p"),
                                        "gen_v_handler": CSVHandler("prod_v"),
                                        "load_q_handler": CSVHandler("load_q"),
                                        "gen_p_for_handler": CSVForecastHandler("prod_p_forecasted"),
                                        "load_p_for_handler": CSVForecastHandler("load_p_forecasted"),
                                        "load_q_for_handler": CSVForecastHandler("load_q_forecasted"),
                                        }
                    )
obs = env.reset()
# continue like you would normally ...

You can now tweak it to add more forecast or add / remove some maintenance by modifying the XXX_for_handler or by adding the maintenance_handler for example.

l2rpn_wcci_2022

The setting for the “l2rpn_wcci_2022” is:

import grid2op
from grid2op.Chronics import FromHandlers
from grid2op.Chronics.handlers import CSVHandler, JSONMaintenanceHandler, CSVForecastHandler, DoNothingHandler

env_name = "l2rpn_wcci_2022"
env = grid2op.make(env_name,
                    data_feeding_kwargs={"gridvalueClass": FromHandlers,
                                        "gen_p_handler": CSVHandler("prod_p"),
                                        "load_p_handler": CSVHandler("load_p"),
                                        "gen_v_handler": DoNothingHandler("prod_v"),
                                        "load_q_handler": CSVHandler("load_q"),
                                        "maintenance_handler": JSONMaintenanceHandler(),
                                        "gen_p_for_handler": CSVForecastHandler("prod_p_forecasted"),
                                        "load_p_for_handler": CSVForecastHandler("load_p_forecasted"),
                                        "load_q_for_handler": CSVForecastHandler("load_q_forecasted"),
                                        }
                    )
obs = env.reset()
# continue like you would normally ...

You can now tweak it to add more forecast or add / remove some maintenance by modifying the XXX_for_handler or by removing the maintenance_handler for example.

l2rpn_icaps_2021

The setting for the “l2rpn_icaps_2021” is:

import grid2op
from grid2op.Chronics import FromHandlers
from grid2op.Chronics.handlers import CSVHandler, JSONMaintenanceHandler, CSVForecastHandler

env_name = "l2rpn_icaps_2021_small"  # or "l2rpn_icaps_2021_large"
env = grid2op.make(env_name,
                    data_feeding_kwargs={"gridvalueClass": FromHandlers,
                                        "gen_p_handler": CSVHandler("prod_p"),
                                        "load_p_handler": CSVHandler("load_p"),
                                        "gen_v_handler": CSVHandler("prod_v"),
                                        "load_q_handler": CSVHandler("load_q"),
                                        "maintenance_handler": JSONMaintenanceHandler(),
                                        "gen_p_for_handler": CSVForecastHandler("prod_p_forecasted"),
                                        "load_p_for_handler": CSVForecastHandler("load_p_forecasted"),
                                        "load_q_for_handler": CSVForecastHandler("load_q_forecasted"),
                                        }
                    )
obs = env.reset()
# continue like you would normally ...

You can now tweak it to add more forecast or add / remove some maintenance by modifying the XXX_for_handler or by removing the maintenance_handler for example.

l2rpn_neurips_2020_track1

The setting for the “l2rpn_neurips_2020_track1” is:

import grid2op
from grid2op.Chronics import FromHandlers
from grid2op.Chronics.handlers import CSVHandler, JSONMaintenanceHandler, CSVForecastHandler

env_name = "l2rpn_neurips_2020_track1_small"  # or "l2rpn_neurips_2020_track1_large"
env = grid2op.make(env_name,
                    data_feeding_kwargs={"gridvalueClass": FromHandlers,
                                        "gen_p_handler": CSVHandler("prod_p"),
                                        "load_p_handler": CSVHandler("load_p"),
                                        "gen_v_handler": CSVHandler("prod_v"),
                                        "load_q_handler": CSVHandler("load_q"),
                                        "maintenance_handler": JSONMaintenanceHandler(),
                                        "gen_p_for_handler": CSVForecastHandler("prod_p_forecasted"),
                                        "load_p_for_handler": CSVForecastHandler("load_p_forecasted"),
                                        "load_q_for_handler": CSVForecastHandler("load_q_forecasted"),
                                        }
                    )
obs = env.reset()
# continue like you would normally ...

You can now tweak it to add more forecast or add / remove some maintenance by modifying the XXX_for_handler or by removing the maintenance_handler for example.

l2rpn_neurips_2020_track1

The setting for the “l2rpn_neurips_2020_track2” is:

import grid2op
from grid2op.Chronics import FromHandlers
from grid2op.Chronics.handlers import CSVHandler, JSONMaintenanceHandler, CSVForecastHandler

env_name = "l2rpn_neurips_2020_track2_small"  # or "l2rpn_neurips_2020_track2_large"
env = grid2op.make(env_name,
                    data_feeding_kwargs={"gridvalueClass": FromHandlers,
                                        "gen_p_handler": CSVHandler("prod_p"),
                                        "load_p_handler": CSVHandler("load_p"),
                                        "gen_v_handler": CSVHandler("prod_v"),
                                        "load_q_handler": CSVHandler("load_q"),
                                        "maintenance_handler": JSONMaintenanceHandler(),
                                        "gen_p_for_handler": CSVForecastHandler("prod_p_forecasted"),
                                        "load_p_for_handler": CSVForecastHandler("load_p_forecasted"),
                                        "load_q_for_handler": CSVForecastHandler("load_q_forecasted"),
                                        }
                    )
obs = env.reset()
# continue like you would normally ...

You can now tweak it to add more forecast or add / remove some maintenance by modifying the XXX_for_handler or by removing the maintenance_handler for example.

Detailed Documentation by class

Classes:

BaseHandler(array_name[, max_iter, h_forecast])

This is the base class that represents a time series "handler".

CSVForecastHandler(array_name[, sep, ...])

Reads and produce time series if given by a csv file (possibly compressed).

CSVHandler(array_name[, sep, chunk_size, ...])

Reads and produce time series if given by a csv file (possibly compressed).

CSVMaintenanceHandler([array_name, sep, ...])

Reads and produce time series if given by a csv file (possibly compressed).

DoNothingHandler([array_name])

This is the specific types of handler that does nothing.

JSONMaintenanceHandler([array_name, ...])

This type of handlers will generate maintenance based on some json files.

LoadQFromPHandler([array_name, qp_ratio, ...])

This handler is specific for "load_q" type of data.

NoisyForecastHandler(array_name[, sigma, ...])

This class allows you to generate some noisy multiple steps ahead forecasts for a given environment.

PerfectForecastHandler(array_name[, ...])

This class is allows to generate "perfect forecast", with this class the agent will know what will be the exact production, loads etc for the near future.

PersistenceForecastHandler(array_name[, ...])

This type of handler will generate the "persitence" type of forecast: basically it will copy paste the last known data of the environment.

class grid2op.Chronics.handlers.BaseHandler(array_name, max_iter=-1, h_forecast=(5,))[source]

This is the base class that represents a time series “handler”.

New in version 1.9.0.

Each “handler” will be reponsible to produce the data for “one single type of elements” of the grid. For example you will have 1 handler for “load_p”, one for “load_q”, another one for “load_p_forecasted” etc. This allows some great flexibility to the way you want to retrieve data, but can be quite verbose as every type of data needs to be “handled”.

A “handler” will, for a certain type of data (eg load_p or maintenance etc.) handle the way this data type is generated.

To be a valid “handler” an class must first inherit from BaseHandler and implements (for all types of handlers):

If the data represents “real time” data (ie the data seen by the agent in real time in the observation) then it needs also to implement:

If the data represents “forecast data” (ie the data accessed by the agent when it uses grid2op.Observation.BaseObservation.simulate() or grid2op.simulator.Simulator or grid2op.Observation.BaseObservation.get_forecast_env()) then it needs to implement:

And if the “handler” represents maintenance data, then it needs to implement:

See also

grid2op.Chronics.FromHandlers which is the things that “consumes” the handlers to output the data read by the grid2op.Environment.Environment

Methods:

check_validity(backend)

INTERNAL

done()

INTERNAL

forecast(forecast_horizon_id, inj_dict_env, ...)

INTERNAL

get_available_horizons()

INTERNAL

get_future_data(horizon[, quiet_warnings])

INTERNAL

get_kwargs(dict_)

INTERNAL

get_max_iter()

INTERNAL

initialize(order_backend_arrays, ...)

INTERNAL

load_next(dict_)

INTERNAL

load_next_maintenance()

INTERNAL

next_chronics()

INTERNAL

set_chunk_size(chunk_size)

INTERNAL

set_h_forecast(h_forecast)

INTERNAL

set_max_episode_duration(max_episode_duration)

INTERNAL

set_max_iter(max_iter)

INTERNAL

set_path(path)

INTERNAL

set_times(init_datetime, time_interval)

INTERNAL

check_validity(backend)[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

This function is called by the grid2op.Chronics.FromHandlers after all the handlers have been initialized.

Its role is to make sure that every handlers can “handle” the data of the environment smoothly.

It is called after each “env.reset()” call.

Parameters:

backend (grid2op.Backend.Backend) – The backend used in the environment.

done() bool[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

Whether or not this handler has done generating the data. It can be “done” in the case it reads data from a csv and you are at the bottom line of the csv for example.

Returns:

Whether it is “done” or not.

Return type:

bool

forecast(forecast_horizon_id: int, inj_dict_env: dict, inj_dict_previous_forecast: dict, env_handler: BaseHandler, env_handlers: Tuple[BaseHandler, BaseHandler, BaseHandler, BaseHandler]) ndarray | None[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

This function is called by the grid2op.Chronics.FromHandlers only for the handlers responsible for some “forecasts”, which are “load_p_forecasted”, “load_q_forecasted”, “prod_p_forecasted”, “prod_v_forecasted”.

It is called exactly once per step and per horizon.

It’s similar to BaseHandler.load_next() with different inputs (because “forecast” are more complicated that just real time data)

Parameters:
  • forecast_horizon_id (int) – The id of the horizon concerns. The horizon id is the index of the current horizon in the list BaseHandler._h_forecast

  • inj_dict_env (dict) – The dictionnary containing the data of the environment (not the forecast) if data have been modified by the relevant handlers.

  • inj_dict_previous_forecast (dict) – Similar to the dict_ parameters of BaseHandler.load_next()

  • env_handler (BaseHandler) –

    The handler of the same type as this one, but for the environment.

    For example, if this handler deals with “load_q_forecasted” then env_handler will be the handler of load_q.

  • env_handlers (Tuple[BaseHandler, BaseHandler, BaseHandler, BaseHandler]) –

    In these you have all the environment handlers in a tuple.

    The order is: “load_p”, “load_q”, “prod_p”, “prod_v”.

Returns:

The forecast (in the shape of numpy array) or None if nothing should be returned.

Return type:

Optional[np.ndarray]

get_available_horizons() Tuple[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

This methods returns the available forecast horizons (in minutes) known by this handler.

Returns:

A tuple containing the different forecast horizons available. The horizons should be given in minutes, for example handler.set_h_forecast((5, 10)) tells this handler that forecasts are available for 5 and 10 minutes ahead.

Return type:

Tuple

get_future_data(horizon: int, quiet_warnings: bool = False) ndarray | None[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

This function is for example used in the grid2op.Chronics.handlers.PerfectForecastHandler: to generate a “perfect forecast” this class will use this function to “have a look” into the future through this function.

This function is for example implemented in grid2op.Chronics.handlers.CSVHandler

Parameters:
  • horizon (int) – The horizon (in minutes) to which we want the data.

  • quiet_warnings (bool) – Whether to issue a warning (default, if quiet_warnings is False) or not

Returns:

The data that will be generated in horizon minutes.

Return type:

Optional[np.ndarray]

get_kwargs(dict_: dict) None[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

If some extra parameters are needed to build your handler “from scratch” you should copy them here. This is used when creating a runner for example.

Parameters:

dict (dict) – The dictionnary to update with the parameters.

get_max_iter() int[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

The maximum number of iterations this particular handler can generate.

-1 means “forever” otherwise it should be a > 0 integers.

Returns:

The maximum number of iterations this particular handler can generate.

Return type:

int

initialize(order_backend_arrays, names_chronics_to_backend) None[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

This function is called by the grid2op.Chronics.FromHandlers after the current handler has been created. Its goal is to initialize it with the relevant data from the environment.

For example, if this handler represents “load_p” then order_backend_arrays will be the name of each load in the environment and names_chronics_to_backend is a dictionnary mapping the name in the data to the names as read by the grid simulator / the backend.

Parameters:
  • order_backend_arrays (np.ndarray) – numpy array representing the name of the element in the grid

  • names_chronics_to_backend (dict) – mapping between the names in order_backend_arrays and the names found in the data.

load_next(dict_: dict) ndarray | None[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

This function is called by the grid2op.Chronics.FromHandlers

Used by the environment handlers (“load_p”, “load_q”, “prod_p” and “prod_v” only). When this function is called, it should return the next state of the type of data it is responsible for. If the previous state should not be modified, then this function can returns “None”.

This is called exactly once per step.

Parameters:

dict (dict) –

A dictionnary representing the other “previous” data type. This function is always called in the same order:

  1. on “load_p”

  2. on “load_q”

  3. on “gen_p”

  4. on “gen_v”

So if your handler is reponsible for “gen_p” then this dictionnary might contain 2 items:

  • key: “load_p”, value: all the active loads for the environment at the same step (if the values are modified by the relevant handlers)

  • key: “load_q”, value: all the reactive laods for the environment at the same step (if the values are modified by the relevant handlers)

Returns:

The new values (if any)

Return type:

Optional[np.ndarray]

load_next_maintenance() Tuple[ndarray, ndarray][source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

This function is used only if the handler is reponsible for “maintenance”. It is called exactly once per step.

Returns:

maintenance time: np.ndarray

Time for next maintenance for each powerline

maintenance duration: np.ndarray

Duration of the next maintenance, for each powerline

Return type:

Tuple[np.ndarray, np.ndarray]

next_chronics() None[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

This function is called by the grid2op.Chronics.FromHandlers at the end of each episode when the next episode is loaded.

set_chunk_size(chunk_size: int | None) None[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

optional: when data are read from the hard drive (eg grid2op.Chronics.handlers.CSVHandler) this can inform the handler about the number of data to proceed at each ‘step’.

Note

Do not use this function directly, it should be used only from the environment.

See also

This can be set by a call to env.chronics_handler.set_chunk_size(chunk_size)

Parameters:

chunk_size (Optional[int]) – The desired chunk size

set_h_forecast(h_forecast: Tuple[int]) None[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

This method is used by the grid2op.Chronics.FromHandlers to inform this handler about the different forecast horizons available.

Parameters:

h_forecast (Tuple[int]) – A tuple containing the different forecast horizons available. The horizons should be given in minutes, for example handler.set_h_forecast((5, 10)) tells this handler that forecasts are available for 5 and 10 minutes ahead.

set_max_episode_duration(max_episode_duration: int | None) None[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

The the maximum number of iteration the environment will use. It is a way to synchronize all the handlers for the same environment

Parameters:

max_episode_duration (Optional[int]) – Maximum number of iterations for the current grid2op environment

set_max_iter(max_iter: int | None) None[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

The the maximum number of iteration this handler is able to produce.

-1 means “forever”. This is set by the grid2op.Chronics.FromHandlers

Parameters:

max_iter (Optional[int]) – Maximum number of iterations

set_path(path: PathLike) None[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

This method is used by the grid2op.Chronics.FromHandlers to inform this handler about the location where the required data for this handler could be located.

Parameters:

path (os.PathLike) – The path to look for the data

set_times(init_datetime: datetime, time_interval: timedelta) None[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

This method is used by the grid2op.Chronics.FromHandlers to inform this handler about the intial datetime of the episode and the duration between two steps.

Note

Do not use this function directly, it should be used only from the environment.

Parameters:
  • init_datetime (datetime) – The initial datetime.

  • time_interval (timedelta) – The time between two steps of the environment.

class grid2op.Chronics.handlers.CSVForecastHandler(array_name, sep=';', chunk_size=None, max_iter=-1)[source]

Reads and produce time series if given by a csv file (possibly compressed).

The separator used can be specified as input.

The file name should match the “array_name”: for example if the data you want to use for “load_p_forecasted” in the environment are in the file “my_load_p_forecast.csv.bz2” should name this handler “my_load_p_forecast” and not “load_p” nor “my_load_p_forecast.csv” nor “my_load_p_forecast.csv.bz2”

The csv should be structured as follow:

  • it should not have any “index” or anything, only data used directly by grid2op (so only “active loads” if this handler is responsible for the generation of “load_p”)

  • Each element (for example a load) is represented by a column.

  • It should have a header with the name of the elements it “handles” and this name should match the one in the environment. For example if “load_1_0” is the name of a load and you read data for “load_p” or “load_q” then one column of your csv should be named “load_1_0”.

  • only floating point numbers should be present in the data (no bool, string and integers will be casted to float)

The structuration of the rows are a bit different than for CSVHandler because this class can read “multiple steps ahead forecast”, provided that it knows for how many different horizons forecasts are made.

Let’s take the example that forecast are available for h = 5, 10 and 15 minutes ahead (so for the next, next next and next next next steps). In this case:

  • the first row (not counting the header) will be the forecast made for h = 5 at the first step: the forecasts available at t=0 for t=5mins

  • the second row will be the forecasts made for h = 10 at the first step: the forecasts available at t=0 for t=10mins

  • the third row will be the forecasts made for h = 15 at the first step: the forecasts available at t=0 for t=15mins

  • the fourth row will be the forecasts made for h = 5 at the second step: the forecasts available at t=5 for t=10mins

  • the fifth row will be the forecasts made for h = 10 at the second step: the forecasts available at t=5 for t=15mins

  • etc.

Warning

Use this class only for the FORECAST data (“load_p_forecasted”, “load_q_forecasted”, “prod_p_forecasted” or “prod_v_forecasted”) and not for maintenance (in this case use CSVMaintenanceHandler) nor for environment data (in this case use CSVHandler)

This is the default way to provide data to grid2op and its used for most l2rpn environments when forecasts are available.

Note

The current implementation heavily relies on the fact that the CSVForecastHandler.forecast() method is called exactly once per horizon and per step.

Methods:

forecast(forecast_horizon_id, inj_dict_env, ...)

INTERNAL

get_available_horizons()

INTERNAL

load_next(dict_)

INTERNAL

set_chunk_size(chunk_size)

INTERNAL

set_h_forecast(h_forecast)

INTERNAL

set_max_iter(max_iter)

INTERNAL

forecast(forecast_horizon_id: int, inj_dict_env: dict, inj_dict_previous_forecast: dict, env_handler: BaseHandler, env_handlers: Tuple[BaseHandler, BaseHandler, BaseHandler, BaseHandler])[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

This function is called by the grid2op.Chronics.FromHandlers only for the handlers responsible for some “forecasts”, which are “load_p_forecasted”, “load_q_forecasted”, “prod_p_forecasted”, “prod_v_forecasted”.

It is called exactly once per step and per horizon.

It’s similar to BaseHandler.load_next() with different inputs (because “forecast” are more complicated that just real time data)

Parameters:
  • forecast_horizon_id (int) – The id of the horizon concerns. The horizon id is the index of the current horizon in the list BaseHandler._h_forecast

  • inj_dict_env (dict) – The dictionnary containing the data of the environment (not the forecast) if data have been modified by the relevant handlers.

  • inj_dict_previous_forecast (dict) – Similar to the dict_ parameters of BaseHandler.load_next()

  • env_handler (BaseHandler) –

    The handler of the same type as this one, but for the environment.

    For example, if this handler deals with “load_q_forecasted” then env_handler will be the handler of load_q.

  • env_handlers (Tuple[BaseHandler, BaseHandler, BaseHandler, BaseHandler]) –

    In these you have all the environment handlers in a tuple.

    The order is: “load_p”, “load_q”, “prod_p”, “prod_v”.

Returns:

The forecast (in the shape of numpy array) or None if nothing should be returned.

Return type:

Optional[np.ndarray]

get_available_horizons()[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

This methods returns the available forecast horizons (in minutes) known by this handler.

Returns:

A tuple containing the different forecast horizons available. The horizons should be given in minutes, for example handler.set_h_forecast((5, 10)) tells this handler that forecasts are available for 5 and 10 minutes ahead.

Return type:

Tuple

load_next(dict_)[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

This function is called by the grid2op.Chronics.FromHandlers

Used by the environment handlers (“load_p”, “load_q”, “prod_p” and “prod_v” only). When this function is called, it should return the next state of the type of data it is responsible for. If the previous state should not be modified, then this function can returns “None”.

This is called exactly once per step.

Parameters:

dict (dict) –

A dictionnary representing the other “previous” data type. This function is always called in the same order:

  1. on “load_p”

  2. on “load_q”

  3. on “gen_p”

  4. on “gen_v”

So if your handler is reponsible for “gen_p” then this dictionnary might contain 2 items:

  • key: “load_p”, value: all the active loads for the environment at the same step (if the values are modified by the relevant handlers)

  • key: “load_q”, value: all the reactive laods for the environment at the same step (if the values are modified by the relevant handlers)

Returns:

The new values (if any)

Return type:

Optional[np.ndarray]

set_chunk_size(chunk_size)[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

optional: when data are read from the hard drive (eg grid2op.Chronics.handlers.CSVHandler) this can inform the handler about the number of data to proceed at each ‘step’.

Note

Do not use this function directly, it should be used only from the environment.

See also

This can be set by a call to env.chronics_handler.set_chunk_size(chunk_size)

Parameters:

chunk_size (Optional[int]) – The desired chunk size

set_h_forecast(h_forecast)[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

This method is used by the grid2op.Chronics.FromHandlers to inform this handler about the different forecast horizons available.

Parameters:

h_forecast (Tuple[int]) – A tuple containing the different forecast horizons available. The horizons should be given in minutes, for example handler.set_h_forecast((5, 10)) tells this handler that forecasts are available for 5 and 10 minutes ahead.

set_max_iter(max_iter)[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

The the maximum number of iteration this handler is able to produce.

-1 means “forever”. This is set by the grid2op.Chronics.FromHandlers

Parameters:

max_iter (Optional[int]) – Maximum number of iterations

class grid2op.Chronics.handlers.CSVHandler(array_name, sep=';', chunk_size=None, max_iter=-1)[source]

Reads and produce time series if given by a csv file (possibly compressed).

The separator used can be specified as input.

The file name should match the “array_name”: for example if the data you want to use for “load_p” in the environment are in the file “my_load_p_data.csv.bz2” should name this handler “my_load_p_data” and not “load_p” nor “my_load_p_data.csv” nor “my_load_p_data.csv.bz2”

The csv should be structured as follow:

  • it should not have any “index” or anything, only data used by grid2op will be used

  • Each element (for example a load) is represented by a column.

  • It should have a header with the name of the elements it “handles” and this name should match the one in the environment. For example if “load_1_0” is the name of a load and you read data for “load_p” or “load_q” then one column of your csv should be named “load_1_0”.

  • each time step is represented as a row and in order. For example (removing the header), row 1 (first row) will be step 1, row 2 will be step 2 etc.

  • only floating point numbers should be present in the data (no bool, string and integers will be casted to float)

Warning

Use this class only for the ENVIRONMENT data (“load_p”, “load_q”, “prod_p” or “prod_v”) and not for maintenance (in this case use CSVMaintenanceHandler) nor for forecast (in this case use CSVForecastHandler)

This is the default way to provide data to grid2op and its used for most l2rpn environments.

Methods:

check_validity(backend)

INTERNAL

done()

INTERNAL

forecast(forecast_horizon_id, inj_dict_env, ...)

INTERNAL

get_available_horizons()

INTERNAL

get_future_data(horizon[, quiet_warnings])

INTERNAL

get_max_iter()

INTERNAL

initialize(order_backend_arrays, ...)

INTERNAL

load_next(dict_)

INTERNAL

load_next_maintenance()

INTERNAL

next_chronics()

INTERNAL

set_chunk_size(chunk_size)

INTERNAL

set_path(path)

INTERNAL

check_validity(backend)[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

This function is called by the grid2op.Chronics.FromHandlers after all the handlers have been initialized.

Its role is to make sure that every handlers can “handle” the data of the environment smoothly.

It is called after each “env.reset()” call.

Parameters:

backend (grid2op.Backend.Backend) – The backend used in the environment.

done()[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

Compare to GridValue.done() an episode can be over for 2 main reasons:

  • GridValue.max_iter has been reached

  • There are no data in the csv.

The episode is done if one of the above condition is met.

Returns:

res – Whether the episode has reached its end or not.

Return type:

bool

forecast(forecast_horizon_id: int, inj_dict_env: dict, inj_dict_previous_forecast: dict, env_handler: BaseHandler, env_handlers: Tuple[BaseHandler, BaseHandler, BaseHandler, BaseHandler])[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

This function is called by the grid2op.Chronics.FromHandlers only for the handlers responsible for some “forecasts”, which are “load_p_forecasted”, “load_q_forecasted”, “prod_p_forecasted”, “prod_v_forecasted”.

It is called exactly once per step and per horizon.

It’s similar to BaseHandler.load_next() with different inputs (because “forecast” are more complicated that just real time data)

Parameters:
  • forecast_horizon_id (int) – The id of the horizon concerns. The horizon id is the index of the current horizon in the list BaseHandler._h_forecast

  • inj_dict_env (dict) – The dictionnary containing the data of the environment (not the forecast) if data have been modified by the relevant handlers.

  • inj_dict_previous_forecast (dict) – Similar to the dict_ parameters of BaseHandler.load_next()

  • env_handler (BaseHandler) –

    The handler of the same type as this one, but for the environment.

    For example, if this handler deals with “load_q_forecasted” then env_handler will be the handler of load_q.

  • env_handlers (Tuple[BaseHandler, BaseHandler, BaseHandler, BaseHandler]) –

    In these you have all the environment handlers in a tuple.

    The order is: “load_p”, “load_q”, “prod_p”, “prod_v”.

Returns:

The forecast (in the shape of numpy array) or None if nothing should be returned.

Return type:

Optional[np.ndarray]

get_available_horizons()[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

This methods returns the available forecast horizons (in minutes) known by this handler.

Returns:

A tuple containing the different forecast horizons available. The horizons should be given in minutes, for example handler.set_h_forecast((5, 10)) tells this handler that forecasts are available for 5 and 10 minutes ahead.

Return type:

Tuple

get_future_data(horizon: int, quiet_warnings: bool = False)[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

This function is for example used in the grid2op.Chronics.handlers.PerfectForecastHandler: to generate a “perfect forecast” this class will use this function to “have a look” into the future through this function.

This function is for example implemented in grid2op.Chronics.handlers.CSVHandler

Parameters:
  • horizon (int) – The horizon (in minutes) to which we want the data.

  • quiet_warnings (bool) – Whether to issue a warning (default, if quiet_warnings is False) or not

Returns:

The data that will be generated in horizon minutes.

Return type:

Optional[np.ndarray]

get_max_iter()[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

The maximum number of iterations this particular handler can generate.

-1 means “forever” otherwise it should be a > 0 integers.

Returns:

The maximum number of iterations this particular handler can generate.

Return type:

int

initialize(order_backend_arrays, names_chronics_to_backend)[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

This function is called by the grid2op.Chronics.FromHandlers after the current handler has been created. Its goal is to initialize it with the relevant data from the environment.

For example, if this handler represents “load_p” then order_backend_arrays will be the name of each load in the environment and names_chronics_to_backend is a dictionnary mapping the name in the data to the names as read by the grid simulator / the backend.

Parameters:
  • order_backend_arrays (np.ndarray) – numpy array representing the name of the element in the grid

  • names_chronics_to_backend (dict) – mapping between the names in order_backend_arrays and the names found in the data.

load_next(dict_)[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

This function is called by the grid2op.Chronics.FromHandlers

Used by the environment handlers (“load_p”, “load_q”, “prod_p” and “prod_v” only). When this function is called, it should return the next state of the type of data it is responsible for. If the previous state should not be modified, then this function can returns “None”.

This is called exactly once per step.

Parameters:

dict (dict) –

A dictionnary representing the other “previous” data type. This function is always called in the same order:

  1. on “load_p”

  2. on “load_q”

  3. on “gen_p”

  4. on “gen_v”

So if your handler is reponsible for “gen_p” then this dictionnary might contain 2 items:

  • key: “load_p”, value: all the active loads for the environment at the same step (if the values are modified by the relevant handlers)

  • key: “load_q”, value: all the reactive laods for the environment at the same step (if the values are modified by the relevant handlers)

Returns:

The new values (if any)

Return type:

Optional[np.ndarray]

load_next_maintenance()[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

This function is used only if the handler is reponsible for “maintenance”. It is called exactly once per step.

Returns:

maintenance time: np.ndarray

Time for next maintenance for each powerline

maintenance duration: np.ndarray

Duration of the next maintenance, for each powerline

Return type:

Tuple[np.ndarray, np.ndarray]

next_chronics()[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

This function is called by the grid2op.Chronics.FromHandlers at the end of each episode when the next episode is loaded.

set_chunk_size(chunk_size)[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

optional: when data are read from the hard drive (eg grid2op.Chronics.handlers.CSVHandler) this can inform the handler about the number of data to proceed at each ‘step’.

Note

Do not use this function directly, it should be used only from the environment.

See also

This can be set by a call to env.chronics_handler.set_chunk_size(chunk_size)

Parameters:

chunk_size (Optional[int]) – The desired chunk size

set_path(path)[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

This method is used by the grid2op.Chronics.FromHandlers to inform this handler about the location where the required data for this handler could be located.

Parameters:

path (os.PathLike) – The path to look for the data

class grid2op.Chronics.handlers.CSVMaintenanceHandler(array_name='maintenance', sep=';', max_iter=-1)[source]

Reads and produce time series if given by a csv file (possibly compressed).

The separator used can be specified as input.

The file name should match the “array_name”. If you want to use the maintenance file present in the file “my_maintenance_file.csv.gz” then you should create a CSVMaintenanceHandler with array_name=”my_maintenance_file”.

The csv should be structured as follow:

  • it should not have any “index” or anything, only data used by grid2op will be used

  • Each element powerline is represented by a column.

  • It should have a header with the name of the powerlines that should match the one in the environment. For example if “0_1_0” is the name of a powerline in your environment, then a column should be called “0_1_0”.

  • each time step is represented as a row and in order. For example (removing the header), row 1 (first row) will be step 1, row 2 will be step 2 etc.

  • only binary data (0 or 1) should be present in the file. No “bool”, no string etc.

Warning

Use this class only for the ENVIRONMENT data (“load_p”, “load_q”, “prod_p” or “prod_v”) and not for maintenance (in this case use CSVMaintenanceHandler) nor for forecast (in this case use CSVForecastHandler)

This is the default way to provide data to grid2op and its used for most l2rpn environments.

Methods:

load_next_maintenance()

INTERNAL

set_chunk_size(chunk_size)

INTERNAL

load_next_maintenance() Tuple[ndarray, ndarray][source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

This function is used only if the handler is reponsible for “maintenance”. It is called exactly once per step.

Returns:

maintenance time: np.ndarray

Time for next maintenance for each powerline

maintenance duration: np.ndarray

Duration of the next maintenance, for each powerline

Return type:

Tuple[np.ndarray, np.ndarray]

set_chunk_size(chunk_size)[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

optional: when data are read from the hard drive (eg grid2op.Chronics.handlers.CSVHandler) this can inform the handler about the number of data to proceed at each ‘step’.

Note

Do not use this function directly, it should be used only from the environment.

See also

This can be set by a call to env.chronics_handler.set_chunk_size(chunk_size)

Parameters:

chunk_size (Optional[int]) – The desired chunk size

class grid2op.Chronics.handlers.DoNothingHandler(array_name='do nothing')[source]

This is the specific types of handler that does nothing.

You can use if for any data type that you want.

Methods:

check_validity(backend)

INTERNAL

done()

INTERNAL

forecast(forecast_horizon_id, inj_dict_env, ...)

INTERNAL

initialize(order_backend_prods, ...)

INTERNAL

load_next(dict)

INTERNAL

load_next_maintenance()

INTERNAL

check_validity(backend)[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

This function is called by the grid2op.Chronics.FromHandlers after all the handlers have been initialized.

Its role is to make sure that every handlers can “handle” the data of the environment smoothly.

It is called after each “env.reset()” call.

Parameters:

backend (grid2op.Backend.Backend) – The backend used in the environment.

done()[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

Whether or not this handler has done generating the data. It can be “done” in the case it reads data from a csv and you are at the bottom line of the csv for example.

Returns:

Whether it is “done” or not.

Return type:

bool

forecast(forecast_horizon_id, inj_dict_env, inj_dict_previous_forecast, env_handler, env_handlers)[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

This function is called by the grid2op.Chronics.FromHandlers only for the handlers responsible for some “forecasts”, which are “load_p_forecasted”, “load_q_forecasted”, “prod_p_forecasted”, “prod_v_forecasted”.

It is called exactly once per step and per horizon.

It’s similar to BaseHandler.load_next() with different inputs (because “forecast” are more complicated that just real time data)

Parameters:
  • forecast_horizon_id (int) – The id of the horizon concerns. The horizon id is the index of the current horizon in the list BaseHandler._h_forecast

  • inj_dict_env (dict) – The dictionnary containing the data of the environment (not the forecast) if data have been modified by the relevant handlers.

  • inj_dict_previous_forecast (dict) – Similar to the dict_ parameters of BaseHandler.load_next()

  • env_handler (BaseHandler) –

    The handler of the same type as this one, but for the environment.

    For example, if this handler deals with “load_q_forecasted” then env_handler will be the handler of load_q.

  • env_handlers (Tuple[BaseHandler, BaseHandler, BaseHandler, BaseHandler]) –

    In these you have all the environment handlers in a tuple.

    The order is: “load_p”, “load_q”, “prod_p”, “prod_v”.

Returns:

The forecast (in the shape of numpy array) or None if nothing should be returned.

Return type:

Optional[np.ndarray]

initialize(order_backend_prods, names_chronics_to_backend)[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

This function is called by the grid2op.Chronics.FromHandlers after the current handler has been created. Its goal is to initialize it with the relevant data from the environment.

For example, if this handler represents “load_p” then order_backend_arrays will be the name of each load in the environment and names_chronics_to_backend is a dictionnary mapping the name in the data to the names as read by the grid simulator / the backend.

Parameters:
  • order_backend_arrays (np.ndarray) – numpy array representing the name of the element in the grid

  • names_chronics_to_backend (dict) – mapping between the names in order_backend_arrays and the names found in the data.

load_next(dict)[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

This function is called by the grid2op.Chronics.FromHandlers

Used by the environment handlers (“load_p”, “load_q”, “prod_p” and “prod_v” only). When this function is called, it should return the next state of the type of data it is responsible for. If the previous state should not be modified, then this function can returns “None”.

This is called exactly once per step.

Parameters:

dict (dict) –

A dictionnary representing the other “previous” data type. This function is always called in the same order:

  1. on “load_p”

  2. on “load_q”

  3. on “gen_p”

  4. on “gen_v”

So if your handler is reponsible for “gen_p” then this dictionnary might contain 2 items:

  • key: “load_p”, value: all the active loads for the environment at the same step (if the values are modified by the relevant handlers)

  • key: “load_q”, value: all the reactive laods for the environment at the same step (if the values are modified by the relevant handlers)

Returns:

The new values (if any)

Return type:

Optional[np.ndarray]

load_next_maintenance()[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

This function is used only if the handler is reponsible for “maintenance”. It is called exactly once per step.

Returns:

maintenance time: np.ndarray

Time for next maintenance for each powerline

maintenance duration: np.ndarray

Duration of the next maintenance, for each powerline

Return type:

Tuple[np.ndarray, np.ndarray]

class grid2op.Chronics.handlers.JSONMaintenanceHandler(array_name='maintenance', json_file_name='maintenance_meta.json', max_iter=-1, _duration_episode_default=288)[source]

This type of handlers will generate maintenance based on some json files.

Maintenance generated with this class will be stochastic: some different maintenance time / duration will be generated for each new episode (of course you can seed your environment for a purely deterministic process)

The json file it will read should be called json_file_name (by default “maintenance_meta.json”)

It should contain the data:

  • “line_to_maintenance”: the list of the name of the powerline that can be “in maintenance” for this episode

  • “maintenance_starting_hour” : the starting hour for all maintenance

  • “maintenance_ending_hour” : the hour at which each maintenance ends

  • “daily_proba_per_month_maintenance” : it’s a list having 12 elements (one for each month of the year) that gives, for each month the probability for any given line to be in maintenance. For example if daily_proba_per_month_maintenance[6] = 0.1 it means that for the 6th month of the year (june) there is a 10% for each powerline to be in maintenance

  • “max_daily_number_per_month_maintenance”: maximum number of powerlines allowed in maintenance at the same time.

Methods:

check_validity(backend)

INTERNAL

done()

INTERNAL

initialize(order_backend_arrays, ...)

INTERNAL

load_next(dict_)

INTERNAL

load_next_maintenance()

INTERNAL

check_validity(backend)[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

This function is called by the grid2op.Chronics.FromHandlers after all the handlers have been initialized.

Its role is to make sure that every handlers can “handle” the data of the environment smoothly.

It is called after each “env.reset()” call.

Parameters:

backend (grid2op.Backend.Backend) – The backend used in the environment.

done()[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

Whether or not this handler has done generating the data. It can be “done” in the case it reads data from a csv and you are at the bottom line of the csv for example.

Returns:

Whether it is “done” or not.

Return type:

bool

initialize(order_backend_arrays, names_chronics_to_backend)[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

This function is called by the grid2op.Chronics.FromHandlers after the current handler has been created. Its goal is to initialize it with the relevant data from the environment.

For example, if this handler represents “load_p” then order_backend_arrays will be the name of each load in the environment and names_chronics_to_backend is a dictionnary mapping the name in the data to the names as read by the grid simulator / the backend.

Parameters:
  • order_backend_arrays (np.ndarray) – numpy array representing the name of the element in the grid

  • names_chronics_to_backend (dict) – mapping between the names in order_backend_arrays and the names found in the data.

load_next(dict_)[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

This function is called by the grid2op.Chronics.FromHandlers

Used by the environment handlers (“load_p”, “load_q”, “prod_p” and “prod_v” only). When this function is called, it should return the next state of the type of data it is responsible for. If the previous state should not be modified, then this function can returns “None”.

This is called exactly once per step.

Parameters:

dict (dict) –

A dictionnary representing the other “previous” data type. This function is always called in the same order:

  1. on “load_p”

  2. on “load_q”

  3. on “gen_p”

  4. on “gen_v”

So if your handler is reponsible for “gen_p” then this dictionnary might contain 2 items:

  • key: “load_p”, value: all the active loads for the environment at the same step (if the values are modified by the relevant handlers)

  • key: “load_q”, value: all the reactive laods for the environment at the same step (if the values are modified by the relevant handlers)

Returns:

The new values (if any)

Return type:

Optional[np.ndarray]

load_next_maintenance()[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

This function is used only if the handler is reponsible for “maintenance”. It is called exactly once per step.

Returns:

maintenance time: np.ndarray

Time for next maintenance for each powerline

maintenance duration: np.ndarray

Duration of the next maintenance, for each powerline

Return type:

Tuple[np.ndarray, np.ndarray]

class grid2op.Chronics.handlers.LoadQFromPHandler(array_name='load_q', qp_ratio: float = 0.7, max_iter=-1)[source]

This handler is specific for “load_q” type of data.

You can use it for both “forecast” (“load_q_forecasted”) and for environment data (“load_q”).

It will generate load_q based on a “q over p” ratio provided as input. Basically, whenever called, it will return (when possible): load_q = ratio * load_p

Note

Its current implementation heavily relies on the fact that when the “load_q” / “load_q_forecasted” handlers are called the “load_p” / “load_p_forecasted” data are already computed and known.

Methods:

check_validity(backend)

INTERNAL

done()

INTERNAL

forecast(forecast_horizon_id, inj_dict_env, ...)

INTERNAL

initialize(order_backend_prods, ...)

INTERNAL

load_next(dict_)

INTERNAL

load_next_maintenance()

INTERNAL

check_validity(backend)[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

This function is called by the grid2op.Chronics.FromHandlers after all the handlers have been initialized.

Its role is to make sure that every handlers can “handle” the data of the environment smoothly.

It is called after each “env.reset()” call.

Parameters:

backend (grid2op.Backend.Backend) – The backend used in the environment.

done()[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

Whether or not this handler has done generating the data. It can be “done” in the case it reads data from a csv and you are at the bottom line of the csv for example.

Returns:

Whether it is “done” or not.

Return type:

bool

forecast(forecast_horizon_id, inj_dict_env, inj_dict_previous_forecast, env_handler, env_handlers)[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

This function is called by the grid2op.Chronics.FromHandlers only for the handlers responsible for some “forecasts”, which are “load_p_forecasted”, “load_q_forecasted”, “prod_p_forecasted”, “prod_v_forecasted”.

It is called exactly once per step and per horizon.

It’s similar to BaseHandler.load_next() with different inputs (because “forecast” are more complicated that just real time data)

Parameters:
  • forecast_horizon_id (int) – The id of the horizon concerns. The horizon id is the index of the current horizon in the list BaseHandler._h_forecast

  • inj_dict_env (dict) – The dictionnary containing the data of the environment (not the forecast) if data have been modified by the relevant handlers.

  • inj_dict_previous_forecast (dict) – Similar to the dict_ parameters of BaseHandler.load_next()

  • env_handler (BaseHandler) –

    The handler of the same type as this one, but for the environment.

    For example, if this handler deals with “load_q_forecasted” then env_handler will be the handler of load_q.

  • env_handlers (Tuple[BaseHandler, BaseHandler, BaseHandler, BaseHandler]) –

    In these you have all the environment handlers in a tuple.

    The order is: “load_p”, “load_q”, “prod_p”, “prod_v”.

Returns:

The forecast (in the shape of numpy array) or None if nothing should be returned.

Return type:

Optional[np.ndarray]

initialize(order_backend_prods, names_chronics_to_backend)[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

This function is called by the grid2op.Chronics.FromHandlers after the current handler has been created. Its goal is to initialize it with the relevant data from the environment.

For example, if this handler represents “load_p” then order_backend_arrays will be the name of each load in the environment and names_chronics_to_backend is a dictionnary mapping the name in the data to the names as read by the grid simulator / the backend.

Parameters:
  • order_backend_arrays (np.ndarray) – numpy array representing the name of the element in the grid

  • names_chronics_to_backend (dict) – mapping between the names in order_backend_arrays and the names found in the data.

load_next(dict_)[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

This function is called by the grid2op.Chronics.FromHandlers

Used by the environment handlers (“load_p”, “load_q”, “prod_p” and “prod_v” only). When this function is called, it should return the next state of the type of data it is responsible for. If the previous state should not be modified, then this function can returns “None”.

This is called exactly once per step.

Parameters:

dict (dict) –

A dictionnary representing the other “previous” data type. This function is always called in the same order:

  1. on “load_p”

  2. on “load_q”

  3. on “gen_p”

  4. on “gen_v”

So if your handler is reponsible for “gen_p” then this dictionnary might contain 2 items:

  • key: “load_p”, value: all the active loads for the environment at the same step (if the values are modified by the relevant handlers)

  • key: “load_q”, value: all the reactive laods for the environment at the same step (if the values are modified by the relevant handlers)

Returns:

The new values (if any)

Return type:

Optional[np.ndarray]

load_next_maintenance()[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

This function is used only if the handler is reponsible for “maintenance”. It is called exactly once per step.

Returns:

maintenance time: np.ndarray

Time for next maintenance for each powerline

maintenance duration: np.ndarray

Duration of the next maintenance, for each powerline

Return type:

Tuple[np.ndarray, np.ndarray]

class grid2op.Chronics.handlers.NoisyForecastHandler(array_name, sigma: Callable | Iterable | None = None, noise_type: Literal['mult'] = 'mult', quiet_warnings: bool = False, max_iter=-1)[source]

This class allows you to generate some noisy multiple steps ahead forecasts for a given environment.

To make “noisy” forecast, this class first retrieve the “perfect forecast” (see PerfectForecastHandler) and then it “adds” some noise to each individual component of this vector.

Noise is not “added” but “multiply” with the formula: output = lognormal(0., sigma) * input with sigma being the standard deviation of the noise that depends on the forecast horizons.

See also

The class PerfectForecastHandler

Warning

This class has the same limitation as the PerfectForecastHandler. It only works if the handlers of the environments supports the BaseHandler.get_future_data() is implemented for the environment handlers.

Notes

Independance of the noise:

The noise is applied independantly for each variable and each “horizon” and each “step”.

This means that:

  • the forecast noise applied at t0=0 for tf=5 for generator 1 is independant from the noise applied t0=0 for tf=5 for generator 2

  • the forecast noise applied at t0=0 for tf=5 is independant from the applied made at t0=5 for tf=5

  • the forecast noise applied at t0=0 for tf=5 is independant from the applied made at t0=0 for tf=10, or tf=15 etc.

In other words, there are no “correlation” between the noise of any kind.

If you want better quality forecast, you should use a dedicated tools to generate some. Among which is “chronix2grid”.

Noise depending on the forecast horizon:

For now, you can only use “multiplicative noise” that is applied by multiplyig the sampling of a LogNormal distribution with the “perfect forecast”.

The “standard deviation” of this lognormal can be parametrized: the “forecast error” can be dependant on the forecast horizon.

For that, you can input :

  • either a callable (=function) that takes as input a forecast horizon (in minutes) and return the std of the noise for this horizon

  • or an iterable that directly contains the std of the noise.

For example:

import grid2op
from grid2op.Chronics import FromHandlers
from grid2op.Chronics.handlers import CSVHandler, NoisyForecastHandler

env_name = "l2rpn_case14_sandbox"
hs_ = [5*(i+1) for i in range(12)]

# uses the default noise: sqrt(horizon) * 0.01 : error of 8% 1h ahead
env = grid2op.make(env_name,
                   data_feeding_kwargs={"gridvalueClass": FromHandlers,
                                        "gen_p_handler": CSVHandler("prod_p"),
                                        "load_p_handler": CSVHandler("load_p"),
                                        "gen_v_handler": CSVHandler("prod_v"),
                                        "load_q_handler": CSVHandler("load_q"),
                                        "h_forecast": hs_,
                                        "gen_p_for_handler": NoisyForecastHandler("prod_p_forecasted"),
                                        "load_p_for_handler": NoisyForecastHandler("load_p_forecasted"),
                                        "load_q_for_handler": NoisyForecastHandler("load_q_forecasted"),
                                       }
                    )

# uses the noise: `horizon -> 0.01 * horizon` : error of 6% 1h ahead
env = grid2op.make(env_name,
                   data_feeding_kwargs={"gridvalueClass": FromHandlers,
                                        "gen_p_handler": CSVHandler("prod_p"),
                                        "load_p_handler": CSVHandler("load_p"),
                                        "gen_v_handler": CSVHandler("prod_v"),
                                        "load_q_handler": CSVHandler("load_q"),
                                        "h_forecast": hs_,
                                        "gen_p_for_handler": NoisyForecastHandler("prod_p_forecasted",
                                                                                  sigma=lambda x: 0.01 * x),
                                        "load_p_for_handler": NoisyForecastHandler("load_p_forecasted",
                                                                                   sigma=lambda x: 0.01 * x),
                                        "load_q_for_handler": NoisyForecastHandler("load_q_forecasted",
                                                                                   sigma=lambda x: 0.01 * x),
                                       }
                    )

Caveats:

  1. Be carefull, the noise for “gen_p” / “prod_p” is not exactly the one given in input. This is because of the “first law of power system” (saying that total generation should be equal to todal demand and losses). To make sure this “first law” is “more met” we scale the generation to make sure that it is roughly 1.02 * total load (when possible) [to be really exhaustive, the ratio 1.02 is, whenever possible modified and computed from the real time data]

  2. There might be some pmin / pmax violation for the generated generators

  3. There will be some max_ramp_down / max_ramp_up violations for the generated generators

  4. The higher the noise, the higher the trouble you will encounter

To “get rid” of all these limitations, you can of course use an “offline” way to generate more realistic forecasts, for example using chronix2grid.

Methods:

forecast(forecast_horizon_id, inj_dict_env, ...)

INTERNAL

set_h_forecast(h_forecast)

INTERNAL

forecast(forecast_horizon_id: int, inj_dict_env: dict, inj_dict_previous_forecast: dict, env_handler: BaseHandler, env_handlers: Tuple[BaseHandler, BaseHandler, BaseHandler, BaseHandler])[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

This function is called by the grid2op.Chronics.FromHandlers only for the handlers responsible for some “forecasts”, which are “load_p_forecasted”, “load_q_forecasted”, “prod_p_forecasted”, “prod_v_forecasted”.

It is called exactly once per step and per horizon.

It’s similar to BaseHandler.load_next() with different inputs (because “forecast” are more complicated that just real time data)

Parameters:
  • forecast_horizon_id (int) – The id of the horizon concerns. The horizon id is the index of the current horizon in the list BaseHandler._h_forecast

  • inj_dict_env (dict) – The dictionnary containing the data of the environment (not the forecast) if data have been modified by the relevant handlers.

  • inj_dict_previous_forecast (dict) – Similar to the dict_ parameters of BaseHandler.load_next()

  • env_handler (BaseHandler) –

    The handler of the same type as this one, but for the environment.

    For example, if this handler deals with “load_q_forecasted” then env_handler will be the handler of load_q.

  • env_handlers (Tuple[BaseHandler, BaseHandler, BaseHandler, BaseHandler]) –

    In these you have all the environment handlers in a tuple.

    The order is: “load_p”, “load_q”, “prod_p”, “prod_v”.

Returns:

The forecast (in the shape of numpy array) or None if nothing should be returned.

Return type:

Optional[np.ndarray]

set_h_forecast(h_forecast)[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

This method is used by the grid2op.Chronics.FromHandlers to inform this handler about the different forecast horizons available.

Parameters:

h_forecast (Tuple[int]) – A tuple containing the different forecast horizons available. The horizons should be given in minutes, for example handler.set_h_forecast((5, 10)) tells this handler that forecasts are available for 5 and 10 minutes ahead.

class grid2op.Chronics.handlers.PerfectForecastHandler(array_name, max_iter=-1, quiet_warnings: bool = False)[source]

This class is allows to generate “perfect forecast”, with this class the agent will know what will be the exact production, loads etc for the near future.

This is a strong “assumption” and it is not realistic.

To have make things more realistic, you can use the NoisyForecastHandler but again, this class is far from perfect.

More “research” is needed in this area and any contribution is more than welcome !

As the name suggest, you should use this class only for the FORECAST data and not for environment or maintenance.

Warning

It only works if the handlers of the environments supports the BaseHandler.get_future_data() is implemented for the environment handlers.

Methods:

check_validity(backend)

INTERNAL

done()

INTERNAL

forecast(forecast_horizon_id, inj_dict_env, ...)

INTERNAL

initialize(order_backend_arrays, ...)

INTERNAL

load_next(dict_)

INTERNAL

load_next_maintenance()

INTERNAL

check_validity(backend)[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

This function is called by the grid2op.Chronics.FromHandlers after all the handlers have been initialized.

Its role is to make sure that every handlers can “handle” the data of the environment smoothly.

It is called after each “env.reset()” call.

Parameters:

backend (grid2op.Backend.Backend) – The backend used in the environment.

done()[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

Whether or not this handler has done generating the data. It can be “done” in the case it reads data from a csv and you are at the bottom line of the csv for example.

Returns:

Whether it is “done” or not.

Return type:

bool

forecast(forecast_horizon_id: int, inj_dict_env: dict, inj_dict_previous_forecast: dict, env_handler: BaseHandler, env_handlers: Tuple[BaseHandler, BaseHandler, BaseHandler, BaseHandler])[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

This function is called by the grid2op.Chronics.FromHandlers only for the handlers responsible for some “forecasts”, which are “load_p_forecasted”, “load_q_forecasted”, “prod_p_forecasted”, “prod_v_forecasted”.

It is called exactly once per step and per horizon.

It’s similar to BaseHandler.load_next() with different inputs (because “forecast” are more complicated that just real time data)

Parameters:
  • forecast_horizon_id (int) – The id of the horizon concerns. The horizon id is the index of the current horizon in the list BaseHandler._h_forecast

  • inj_dict_env (dict) – The dictionnary containing the data of the environment (not the forecast) if data have been modified by the relevant handlers.

  • inj_dict_previous_forecast (dict) – Similar to the dict_ parameters of BaseHandler.load_next()

  • env_handler (BaseHandler) –

    The handler of the same type as this one, but for the environment.

    For example, if this handler deals with “load_q_forecasted” then env_handler will be the handler of load_q.

  • env_handlers (Tuple[BaseHandler, BaseHandler, BaseHandler, BaseHandler]) –

    In these you have all the environment handlers in a tuple.

    The order is: “load_p”, “load_q”, “prod_p”, “prod_v”.

Returns:

The forecast (in the shape of numpy array) or None if nothing should be returned.

Return type:

Optional[np.ndarray]

initialize(order_backend_arrays, names_chronics_to_backend)[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

This function is called by the grid2op.Chronics.FromHandlers after the current handler has been created. Its goal is to initialize it with the relevant data from the environment.

For example, if this handler represents “load_p” then order_backend_arrays will be the name of each load in the environment and names_chronics_to_backend is a dictionnary mapping the name in the data to the names as read by the grid simulator / the backend.

Parameters:
  • order_backend_arrays (np.ndarray) – numpy array representing the name of the element in the grid

  • names_chronics_to_backend (dict) – mapping between the names in order_backend_arrays and the names found in the data.

load_next(dict_)[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

This function is called by the grid2op.Chronics.FromHandlers

Used by the environment handlers (“load_p”, “load_q”, “prod_p” and “prod_v” only). When this function is called, it should return the next state of the type of data it is responsible for. If the previous state should not be modified, then this function can returns “None”.

This is called exactly once per step.

Parameters:

dict (dict) –

A dictionnary representing the other “previous” data type. This function is always called in the same order:

  1. on “load_p”

  2. on “load_q”

  3. on “gen_p”

  4. on “gen_v”

So if your handler is reponsible for “gen_p” then this dictionnary might contain 2 items:

  • key: “load_p”, value: all the active loads for the environment at the same step (if the values are modified by the relevant handlers)

  • key: “load_q”, value: all the reactive laods for the environment at the same step (if the values are modified by the relevant handlers)

Returns:

The new values (if any)

Return type:

Optional[np.ndarray]

load_next_maintenance()[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

This function is used only if the handler is reponsible for “maintenance”. It is called exactly once per step.

Returns:

maintenance time: np.ndarray

Time for next maintenance for each powerline

maintenance duration: np.ndarray

Duration of the next maintenance, for each powerline

Return type:

Tuple[np.ndarray, np.ndarray]

class grid2op.Chronics.handlers.PersistenceForecastHandler(array_name, max_iter=-1)[source]

This type of handler will generate the “persitence” type of forecast: basically it will copy paste the last known data of the environment.

You should use it only for FORECAST data and not for environment data as the name suggest.

Methods:

check_validity(backend)

INTERNAL

done()

INTERNAL

forecast(forecast_horizon_id, inj_dict_env, ...)

INTERNAL

initialize(order_backend_arrays, ...)

INTERNAL

load_next(dict_)

INTERNAL

load_next_maintenance()

INTERNAL

check_validity(backend)[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

This function is called by the grid2op.Chronics.FromHandlers after all the handlers have been initialized.

Its role is to make sure that every handlers can “handle” the data of the environment smoothly.

It is called after each “env.reset()” call.

Parameters:

backend (grid2op.Backend.Backend) – The backend used in the environment.

done()[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

Whether or not this handler has done generating the data. It can be “done” in the case it reads data from a csv and you are at the bottom line of the csv for example.

Returns:

Whether it is “done” or not.

Return type:

bool

forecast(forecast_horizon_id: int, inj_dict_env: dict, inj_dict_previous_forecast: dict, env_handler: BaseHandler, env_handlers: Tuple[BaseHandler, BaseHandler, BaseHandler, BaseHandler])[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

This function is called by the grid2op.Chronics.FromHandlers only for the handlers responsible for some “forecasts”, which are “load_p_forecasted”, “load_q_forecasted”, “prod_p_forecasted”, “prod_v_forecasted”.

It is called exactly once per step and per horizon.

It’s similar to BaseHandler.load_next() with different inputs (because “forecast” are more complicated that just real time data)

Parameters:
  • forecast_horizon_id (int) – The id of the horizon concerns. The horizon id is the index of the current horizon in the list BaseHandler._h_forecast

  • inj_dict_env (dict) – The dictionnary containing the data of the environment (not the forecast) if data have been modified by the relevant handlers.

  • inj_dict_previous_forecast (dict) – Similar to the dict_ parameters of BaseHandler.load_next()

  • env_handler (BaseHandler) –

    The handler of the same type as this one, but for the environment.

    For example, if this handler deals with “load_q_forecasted” then env_handler will be the handler of load_q.

  • env_handlers (Tuple[BaseHandler, BaseHandler, BaseHandler, BaseHandler]) –

    In these you have all the environment handlers in a tuple.

    The order is: “load_p”, “load_q”, “prod_p”, “prod_v”.

Returns:

The forecast (in the shape of numpy array) or None if nothing should be returned.

Return type:

Optional[np.ndarray]

initialize(order_backend_arrays, names_chronics_to_backend)[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

This function is called by the grid2op.Chronics.FromHandlers after the current handler has been created. Its goal is to initialize it with the relevant data from the environment.

For example, if this handler represents “load_p” then order_backend_arrays will be the name of each load in the environment and names_chronics_to_backend is a dictionnary mapping the name in the data to the names as read by the grid simulator / the backend.

Parameters:
  • order_backend_arrays (np.ndarray) – numpy array representing the name of the element in the grid

  • names_chronics_to_backend (dict) – mapping between the names in order_backend_arrays and the names found in the data.

load_next(dict_)[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

This function is called by the grid2op.Chronics.FromHandlers

Used by the environment handlers (“load_p”, “load_q”, “prod_p” and “prod_v” only). When this function is called, it should return the next state of the type of data it is responsible for. If the previous state should not be modified, then this function can returns “None”.

This is called exactly once per step.

Parameters:

dict (dict) –

A dictionnary representing the other “previous” data type. This function is always called in the same order:

  1. on “load_p”

  2. on “load_q”

  3. on “gen_p”

  4. on “gen_v”

So if your handler is reponsible for “gen_p” then this dictionnary might contain 2 items:

  • key: “load_p”, value: all the active loads for the environment at the same step (if the values are modified by the relevant handlers)

  • key: “load_q”, value: all the reactive laods for the environment at the same step (if the values are modified by the relevant handlers)

Returns:

The new values (if any)

Return type:

Optional[np.ndarray]

load_next_maintenance()[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\

This function is used only if the handler is reponsible for “maintenance”. It is called exactly once per step.

Returns:

maintenance time: np.ndarray

Time for next maintenance for each powerline

maintenance duration: np.ndarray

Duration of the next maintenance, for each powerline

Return type:

Tuple[np.ndarray, np.ndarray]