Episode

This page is organized as follow:

Objectives

Grid2op defines some special function that help with restoring agent that has run during some episode that has been saved by the runner.

Here are some basic usage.

First you run an episode:

import grid2op
from grid2op.Runner import Runner

# I create an environment
env = grid2op.make("rte_case5_example", test=True)

# I create the runner
runner = Runner(**env.get_params_for_runner())
path_save = "/I/SAVED/RESULTS/THERE"

# I start the runner and save the results in "/I/SAVED/RESULTS/THERE"
# I start the evaluation on 2 different episode
res = runner.run(path_save=path_save, nb_episode=2)

Second you can reload the data (here to plot the different productions active values):

import grid2op
from grid2op.Episode import EpisodeData

# I study only the first episode saved, because... why not
path_saved = "/I/SAVED/RESULTS/THERE"  # same path as before

li_episode = EpisodeData.list_episode(path_saved)
full_path, episode_studied = li_episode[0]
this_episode = EpisodeData.from_disk(path_agent, episode_studied)

# now the episode is loaded, and you can easily iterate through the observation, the actions etc.
for act in this_episode.actions:
    print(act)

for i, obs in enumerate(this_episode.observations):
    print("At step {} the active productions were {}".format(i, obs.prod_p))

# etc. etc.

Detailed Documentation by class

Classes:

EpisodeData([actions, env_actions, ...])

Warning

The attributes of this class are not up to date.

class grid2op.Episode.EpisodeData(actions=None, env_actions=None, observations=None, rewards=None, disc_lines=None, times=None, params=None, meta=None, episode_times=None, observation_space=None, action_space=None, helper_action_env=None, attack_space=None, path_save=None, disc_lines_templ=None, attack_templ=None, attack=None, logger=None, name='EpisodeData', get_dataframes=None, force_detail=False, other_rewards=[], legal=None, ambiguous=None, has_legal_ambiguous=False, _init_collections=False)[source]

Warning

The attributes of this class are not up to date. TODO be consistent with the real behaviour now.

This module provides a way to serialize on disk et deserialize one run episode along with some methods and utilities to ease its manipulation.

If enabled when usign the Runner, the EpisodeData will save the information in a structured way. For each episode there will be a folder with:

  • “episode_meta.json” that represents some meta information about:

    • “agent_seed”: the seed used to seed the agent (if any)

    • “backend_type”: the name of the grid2op.Backend.Backend class used

    • “chronics_max_timestep”: the maximum number of timestep for the chronics used

    • “chronics_path”: the path where the time dependant data (chronics) are located

    • “cumulative_reward”: the cumulative reward over all the episode

    • “env_seed”: the seed used to seed the environment (if any)

    • “env_type”: the name of the grid2op.Environment class used.

    • “grid_path”: the path where the powergrid has been loaded from

    • “nb_timestep_played”: number of time step the agent has succesfully managed

  • “episode_times.json”: gives some information about the total time spend in multiple part of the runner, mainly the grid2op.Agent.BaseAgent (and especially its method grid2op.BaseAgent.act()) and amount of time spent in the grid2op.Environment.Environment

  • “_parameters.json”: is a representation as json of a the grid2op.Parameters.Parameters used for this episode

  • “rewards.npz” is a numpy 1d array giving the rewards at each time step. We adopted the convention that the stored reward at index i is the one observed by the agent at time i and NOT the reward sent by the grid2op.Environment after the action has been implemented.

  • “exec_times.npy” is a numpy 1d array giving the execution time of each time step of the episode

  • “actions.npy” gives the actions that has been taken by the grid2op.BaseAgent.BaseAgent. At row i of “actions.npy” is a vectorized representation of the action performed by the agent at timestep i ie. after having observed the observation present at row i of “observation.npy” and the reward showed in row i of “rewards.npy”.

  • “disc_lines.npy” gives which lines have been disconnected during the simulation of the cascading failure at each time step. The same convention as for “rewards.npy” has been adopted. This means that the powerlines are disconnected when the grid2op.Agent.BaseAgent takes the grid2op.BaseAction at time step i.

  • “observations.npy” is a numpy 2d array representing the grid2op.BaseObservation.BaseObservation at the disposal of the grid2op.Agent.BaseAgent when he took his action.

  • “env_modifications.npy” is a 2d numpy array representing the modification of the powergrid from the environment. these modification usually concerns the hazards, maintenance, as well as modification of the generators production setpoint or the loads consumption.

All of the above should allow to read back, and better understand the behaviour of some grid2op.Agent.BaseAgent, even though such utility functions have not been coded yet.

actions

Stores the Agent actions as a collection of grid2op.BaseAction. The collection is stored the utility class grid2op.Episode.CollectionWrapper.

Type:

type

observations

Stores the Observations as a collection of grid2op.BaseObservation. The collection is stored the utility class grid2op.Episode.CollectionWrapper.

Type:

type

env_actions

Stores the Environment actions as a collection of grid2op.BaseAction. The collection is stored the utility class grid2op.Episode.CollectionWrapper.

Type:

type

attacks

Stores the Opponent actions as a collection of grid2op.BaseAction. The collection is stored the utility class grid2op.Episode.CollectionWrapper.

Type:

type

Examples

Here is an example on how to save the action your agent was doing by the grid2op.Runner.Runner of grid2op.

import grid2op
from grid2op.Runner import Runner

# I create an environment
env = grid2op.make("l2rpn_case14_sandbox", test=True)

# I create the runner
runner = Runner(**env.get_params_for_runner())

# I start the runner and save the results in "/I/SAVED/RESULTS/THERE"
# I start the evaluation on 2 different episode
res = runner.run(path_save="/I/SAVED/RESULTS/THERE", nb_episode=2)

And now i can reload the data easily with the EpisodeData class:

import grid2op
from grid2op.Episode import EpisodeData

path_agent = ... # path to a directory where a runner has been saved
# I study only the first episode saved, because... why not
li_episode = EpisodeData.list_episode(path_agent)
full_path, episode_studied = li_episode[0]
this_episode = EpisodeData.from_disk(full_path, episode_studied)

# now the episode is loaded, and you can easily iterate through the observation, the actions etc.
for act in this_episode.actions:
    print(act)

for i, obs in enumerate(this_episode.observations):
    print("At step {} the active productions were {}".format(i, obs.prod_p))

Methods:

from_disk(agent_path[, name])

This function allows you to reload an episode stored using the runner.

get_grid2op_version(path_episode)

Utility function to retrieve the grid2op version used to generate this episode serialized on disk.

incr_store(efficient_storing, time_step, ...)

INTERNAL

list_episode(path_agent)

From a given path where a runner is supposed to have run, it extracts the subdirectories that can store values from an episode.

make_serializable()

INTERNAL

reboot()

Do as if the data just got read from the hard drive (loop again from the initial observation and action)

set_episode_times(env, time_act, beg_, end_)

INTERNAL

set_meta(env, time_step, cum_reward, ...)

INTERNAL

set_parameters(env)

INTERNAL

to_disk()

INTERNAL

classmethod from_disk(agent_path, name='1')[source]

This function allows you to reload an episode stored using the runner.

See the example at the definition of the class for more information on how to use it.

Parameters:
  • agent_path (str) – Path pass at the “runner.run” method

  • name (str) – The name of the episode you want to reload.

Returns:

The data loaded properly in memory.

Return type:

res

staticmethod get_grid2op_version(path_episode)[source]

Utility function to retrieve the grid2op version used to generate this episode serialized on disk.

This is introduced in grid2op 1.5.0, with older runner version stored, this function will return “<=1.4.0” otherwise it returns the grid2op version, as a string.

incr_store(efficient_storing, time_step, time_step_duration, reward, env_act, act, obs, opp_attack, info)[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\ Used by he runner to serialize properly an episode

TODO

Parameters:
  • efficient_storing

  • time_step

  • time_step_duration

  • reward

  • env_act

  • act

  • obs

  • opp_attack

  • info

staticmethod list_episode(path_agent)[source]

From a given path where a runner is supposed to have run, it extracts the subdirectories that can store values from an episode.

Parameters:

path_agent (str) – The path where to look for data coming from “episode”

Returns:

res – A list of possible episodes. Each element of this list is a tuple: (full_path, episode_name)

Return type:

list

Examples

import grid2op
import os
import numpy as np
from grid2op.Runner import Runner
from grid2op.Episode import EpisodeData

################
# INTRO
# create a runner
env = grid2op.make("l2rpn_case14_sandbox")
# see the documentation of the Runner if you want to change the agent.
# in this case it will be "do nothing"
runner = Runner(**env.get_params_for_runner())

# execute it a given number of chronics
nb_episode = 2
path_save = "i_saved_the_runner_here"
res = runner.run(nb_episode=nb_episode, path_save=path_save)

# END INTRO
##################

li_episode = EpisodeData.list_episode(path_save)
# and now you can iterate through it:
for full_episode_path, episode_name in li_episode:
    this_episode = EpisodeData.from_disk(path_agent, episode_name)
    # you can do something with it now
make_serializable()[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\ Used by he runner to serialize properly an episode

Called in the _aux_run_one_episode (one of the Runner auxilliary function) to make sure the EpisodeData can be sent back to the main process withtout issue (otherwise there is a complain about the _ObsEnv)

reboot()[source]

Do as if the data just got read from the hard drive (loop again from the initial observation and action)

set_episode_times(env, time_act, beg_, end_)[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\ Used by he runner to serialize properly an episode

TODO

Parameters:
  • env

  • time_act

  • beg

  • end

set_meta(env, time_step, cum_reward, env_seed, agent_seed)[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\ Used by he runner to serialize properly an episode

TODO

Parameters:
  • env

  • time_step

  • cum_reward

  • env_seed

  • agent_seed

set_parameters(env)[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\ Used by the Runner to serialize properly an episode

TODO

Parameters:

env

to_disk()[source]

INTERNAL

Warning

/!\ Internal, do not use unless you know what you are doing /!\ Used by he runner to serialize properly an episode

TODO

If you still can’t find what you’re looking for, try in one of the following pages:

Still trouble finding the information ? Do not hesitate to send a github issue about the documentation at this link: Documentation issue template