Observation
This page is organized as follow:
Table of Contents
Objectives
In a “reinforcement learning” framework, an grid2op.Agent
receive two information before taking
any action on
the grid2op.Environment.Environment
. One of them is the grid2op.Reward.BaseReward
that tells it
how well the past action
performed. The second main input received from the environment is the BaseObservation
. This is gives the BaseAgent
partial, noisy, or complete information about the current state of the environment. This module implement a generic
BaseObservation
class and an example of a complete observation in the case of the Learning
To Run a Power Network (l2RPN ) competition.
Compared to other Reinforcement Learning problems the L2PRN competition allows another flexibility. Today, when operating a powergrid, operators have “forecasts” at their disposal. We wanted to make them available in the L2PRN competition too. In the first edition of the L2PRN competition, was offered the functionality to simulate the effect of an action on a forecasted powergrid. This forecasted powergrid used:
the topology of the powergrid of the last know time step
all the injections of given in files.
This functionality was originally attached to the Environment and could only be used to simulate the effect of an action on this unique time step. We wanted in this recoding to change that:
in an RL setting, an
grid2op.Agent.BaseAgent
should not be able to look directly at thegrid2op.Environment.Environment
. The only information about the Environment the BaseAgent should have is through thegrid2op.Observation.BaseObservation
and thegrid2op.Reward.BaseReward
. Having this principle implemented will help enforcing this principle.In some wider context, it is relevant to have these forecasts available in multiple way, or modified by the
grid2op.Agent.BaseAgent
itself (for example having forecast available for the next 2 or 3 hours, with the Agent able not only to change the topology of the powergrid with actions, but also the injections if he’s able to provide more accurate predictions for example.
The BaseObservation
class implement the two above principles and is more flexible to other kind of forecasts,
or other methods to build a power grid based on the forecasts of injections.
Main observation attributes
In general, observations have the following attributes (if an attributes has name XXX [eg rho] it can be accessed with obs.XXX [eg obs.rho])
Name(s) 
Type 
Size (each) 

int 
1 

float 

load_p, load_q, load_v , load_theta 
float 

float 

float 

float 

int 

bool 

int 

int 

int 

int 

int 

float 

float 

float 

float 

float 

float 

float 

float 

float 

bool 
1 

int 
1 

int 

int 
1 

int 
1 

float 
1 
(NB for concision, if a coma (”,”) is present in the “Name(s)” part of the column, it means multiple attributes are present. If we take the example of the first row, it means that obs.year, obs.month, etc. are all valid attributes of the observation, they are all integers and each is of size 1.)
But where is the graph ?
A powergrid can be represented as (at least) a graph (here: a mathematical object with nodes / vertices are connected by edges).
Grid2op is made in a way that the observation and action do not explicitly represents such graph. This is motivated first by performance reasons, but also because multiple “graphs” can represent equally well a powergrid.
The first one that come to mind is the graph where the nodes / vertices are the buses and the edges are
the powerline. We will call this graph the “bus graph”. It can be accessed in grid2op using the
grid2op.Observation.BaseObservation.bus_connectivity_matrix()
for example. This will return a matrix
with 1 when 2 buses are connected and 0 otherwise, with the convention that a bus is always connected to
itself. You can think of the environments in grid2op as an environment that allows you to manipulate
this graph: split some bus in sub buses by changing at which busbar some elements are connected, or removing
some edges from this graph when powerlines are connected / disconnected. An important feature of this
graph is that its size changes: it can have a different number of nodes at different steps!
Some methods allow to retrieve these graphs, for example:
For more information, you can consult the A grid, a graph: grid2op representation of the powergrid page.
Detailed Documentation by class
Classes:

Basic class representing an observation. 

This class represent a complete observation, where everything on the powergrid can be observed without any noise. 

This class represent a complete observation (in the sens that all attributes of an 

Helper that provides useful functions to manipulate 
 class grid2op.Observation.BaseObservation(obs_env=None, action_helper=None, random_prng=None)[source]
Basic class representing an observation.
All observation must derive from this class and implement all its abstract methods.
 action_helper
A representation of the possible action space.
 year
The current year
 Type
int
 month
The current month (1 = january, 12 = december)
 Type
int
 day
The current day of the month (1 = first day of the month)
 Type
int
 hour_of_day
The current hour of the day (from O to 23)
 Type
int
 minute_of_hour
The current minute of the current hour (from 0 to 59)
 Type
int
 day_of_week
The current day of the week (monday = 0 and sunday = 6)
 Type
int
 support_theta
This flag indicates whether the backend supports the retrieval of the voltage angle. If so (which is the case for most backend) then some supplementary attributes are available, such as
BaseObservation.gen_theta
,BaseObservation.load_theta
,BaseObservation.storage_theta
,BaseObservation.theta_or
orBaseObservation.theta_ex
. Type
bool
 gen_p
The active production value of each generator (expressed in MW). (the old name “prod_p” is still usable)
 Type
numpy.ndarray
, dtype:float
 gen_q
The reactive production value of each generator (expressed in MVar). (the old name “prod_q” is still usable)
 Type
numpy.ndarray
, dtype:float
 gen_v
The voltage magnitude of the bus to which each generator is connected (expressed in kV). (the old name “prod_v” is still usable)
 Type
numpy.ndarray
, dtype:float
 gen_theta
The voltage angle (in degree) of the bus to which each generator is connected. Only availble if the backend supports the retrieval of voltage angles (see
BaseObservation.support_theta
). Type
numpy.ndarray
, dtype:float
 load_p
The active load value of each consumption (expressed in MW).
 Type
numpy.ndarray
, dtype:float
 load_q
The reactive load value of each consumption (expressed in MVar).
 Type
numpy.ndarray
, dtype:float
 load_v
The voltage magnitude of the bus to which each consumption is connected (expressed in kV).
 Type
numpy.ndarray
, dtype:float
 load_theta
The voltage angle (in degree) of the bus to which each consumption is connected. Only availble if the backend supports the retrieval of voltage angles (see
BaseObservation.support_theta
). Type
numpy.ndarray
, dtype:float
 p_or
The active power flow at the origin end of each powerline (expressed in MW).
 Type
numpy.ndarray
, dtype:float
 q_or
The reactive power flow at the origin end of each powerline (expressed in MVar).
 Type
numpy.ndarray
, dtype:float
 v_or
The voltage magnitude at the bus to which the origin end of each powerline is connected (expressed in kV).
 Type
numpy.ndarray
, dtype:float
 theta_or
The voltage angle at the bus to which the origin end of each powerline is connected (expressed in degree). Only availble if the backend supports the retrieval of voltage angles (see
BaseObservation.support_theta
). Type
numpy.ndarray
, dtype:float
 a_or
The current flow at the origin end of each powerline (expressed in A).
 Type
numpy.ndarray
, dtype:float
 p_ex
The active power flow at the extremity end of each powerline (expressed in MW).
 Type
numpy.ndarray
, dtype:float
 q_ex
The reactive power flow at the extremity end of each powerline (expressed in MVar).
 Type
numpy.ndarray
, dtype:float
 v_ex
The voltage magnitude at the bus to which the extremity end of each powerline is connected (expressed in kV).
 Type
numpy.ndarray
, dtype:float
 theta_ex
The voltage angle at the bus to which the extremity end of each powerline is connected (expressed in degree). Only availble if the backend supports the retrieval of voltage angles (see
BaseObservation.support_theta
). Type
numpy.ndarray
, dtype:float
 a_ex
The current flow at the extremity end of each powerline (expressed in A).
 Type
numpy.ndarray
, dtype:float
 rho
The capacity of each powerline. It is defined at the observed current flow divided by the thermal limit of each powerline (no unit)
 Type
numpy.ndarray
, dtype:float
 topo_vect
For each object (load, generator, ends of a powerline) it gives on which bus this object is connected in its substation. See
grid2op.Backend.Backend.get_topo_vect()
for more information. Type
numpy.ndarray
, dtype:int
 line_status
Gives the status (connected / disconnected) for every powerline (
True
at position i means the powerline i is connected) Type
numpy.ndarray
, dtype:bool
 timestep_overflow
Gives the number of time steps since a powerline is in overflow.
 Type
numpy.ndarray
, dtype:int
 time_before_cooldown_line
For each powerline, it gives the number of time step the powerline is unavailable due to “cooldown” (see
grid2op.Parameters.NB_TIMESTEP_COOLDOWN_LINE
for more information). 0 means the an action will be able to act on this same powerline, a number > 0 (eg 1) means that an action at this time step cannot act on this powerline (in the example the agent have to wait 1 time step) Type
numpy.ndarray
, dtype:int
 time_before_cooldown_sub
Same as
BaseObservation.time_before_cooldown_line
but for substations. For each substation, it gives the number of timesteps to wait before acting on this substation (see seegrid2op.Parameters.NB_TIMESTEP_COOLDOWN_SUB
for more information). Type
numpy.ndarray
, dtype:int
 time_next_maintenance
For each powerline, it gives the time of the next planned maintenance. For example if there is:
1 at position i it means that the powerline i will be disconnected for maintenance operation at the next time step.
0 at position i means that powerline i is disconnected from the powergrid for maintenance operation at the current time step.
1 at position i means that powerline i will not be disconnected for maintenance reason for this episode.
k > 1 at position i it means that the powerline i will be disconnected for maintenance operation at in k time steps
When a powerline is “in maintenance”, it cannot be reconnected by the Agent before the end of this maintenance.
 Type
numpy.ndarray
, dtype:int
 duration_next_maintenance
For each powerline, it gives the number of time step that the maintenance will last (if any). This means that, if at position i of this vector:
there is a 0: the powerline is not disconnected from the grid for maintenance
there is a 1, 2, … the powerline will be disconnected for at least 1, 2, … timestep (NB in all case, the powerline will stay disconnected until a
grid2op.BaseAgent.BaseAgent
performs the propergrid2op.BaseAction.BaseAction
to reconnect it).
When a powerline is “in maintenance”, it cannot be reconnected by the Agent before the end of this maintenance.
 Type
numpy.ndarray
, dtype:int
 target_dispatch
For each generators, it gives the target redispatching, asked by the agent. This is the sum of all redispatching asked by the agent for during all the episode. It for each generator it is a number between:  pmax and pmax. Note that there is information about all generators there, even the one that are not dispatchable.
 Type
numpy.ndarray
, dtype:float
 actual_dispatch
For each generators, it gives the redispatching currently implemented by the environment. Indeed, the environment tries to implement at best the
BaseObservation.target_dispatch
, but sometimes, due to physical limitation (pmin, pmax, ramp min and ramp max) it cannot. In this case, only the best possible redispatching is implemented at the current time step, and this is what this vector stores. Note that there is information about all generators there, even the one that are not dispatchable. Type
numpy.ndarray
, dtype:float
 storage_charge
The actual ‘state of charge’ of each storage unit, expressed in MWh.
 Type
numpy.ndarray
, dtype:float
 storage_power_target
For each storage units, give the setpoint of production / consumption as given by the agent
 Type
numpy.ndarray
, dtype:float
 storage_power
Give the actual storage production / loads at the given state.
 Type
numpy.ndarray
, dtype:float
 storage_theta
The voltage angle (in degree) of the bus to which each storage units is connected. Only availble if the backend supports the retrieval of voltage angles (see
BaseObservation.support_theta
). Type
numpy.ndarray
, dtype:float
 gen_p_before_curtail
Give the production of renewable generator there would have been if no curtailment were applied (NB it returns 0.0 for non renewable generators that cannot be curtailed)
 Type
numpy.ndarray
, dtype:float
 curtailment_limit
Limit (in ratio of gen_pmax) imposed on each renewable generator as set by the agent.
It is always 1. if no curtailment actions is acting on the generator.
This is the “curtailment” given in the action by the agent.
 Type
numpy.ndarray
, dtype:float
 curtailment_limit_effective
Limit (in ratio of gen_pmax) imposed on each renewable generator effectively imposed by the environment.
It matches
BaseObservation.curtailment_limit
if param.LIMIT_INFEASIBLE_CURTAILMENT_STORAGE_ACTION isFalse
(default) otherwise the environment is able to limit the curtailment actions if too much power would be needed to compensate the “loss” of generation due to renewables.It is always 1. if no curtailment actions is acting on the generator.
 Type
numpy.ndarray
, dtype:float
 curtailment_mw
Gives the amount of power curtailed for each generator (it is 0. for all non renewable generators)
This is NOT the “curtailment” given in the action by the agent.
 Type
numpy.ndarray
, dtype:float
 curtailment
Give the power curtailed for each generator. It is expressed in ratio of gen_pmax (so between 0.  meaning no curtailment in effect for this generator  to 1.0  meaning this generator should have produced pmax, but a curtailment action limits it to 0.)
This is NOT the “curtailment” given in the action by the agent.
 Type
numpy.ndarray
, dtype:float
 current_step
Current number of step performed up until this observation (NB this is not given in the observation if it is transformed into a vector)
 Type
int
 max_step
Maximum number of steps possible for this episode
 Type
int
 delta_time
Time (in minutes) between the last step and the current step (usually constant in an episode, even in an environment)
 Type
float
 is_alarm_illegal
whether the last alarm has been illegal (due to budget constraint). It can only be
True
if an alarm was raised by the agent on the previous step. Otherwise it is alwaysFalse
 Type
bool
 time_since_last_alarm
Number of steps since the last successful alarm has been raised. It is 1 if no alarm has been raised yet.
 Type
int
 last_alarm
For each zones, gives how many steps since the last alarm was raised successfully for this zone
 Type
numpy.ndarray
, dtype:int
 attention_budget
The current attention budget
 Type
int
 was_alarm_used_after_game_over
Was the last alarm used to compute anything related to the attention budget when there was a game over (can only be set to
True
if the observation corresponds to a game over, but not necessarily) Type
bool
 gen_margin_up
From how much can you increase each generators production between this step and the next.
It is always 0. for non renewable generators. For the others it is defined as np.minimum(type(self).gen_pmax  self.gen_p, self.gen_max_ramp_up)
 Type
numpy.ndarray
, dtype:float
 gen_margin_down
From how much can you decrease each generators production between this step and the next.
It is always 0. for non renewable generators. For the others it is defined as np.minimum(self.gen_p  type(self).gen_pmin, self.gen_max_ramp_down)
 Type
numpy.ndarray
, dtype:float
 _shunt_p
Shunt active value (only available if shunts are available) (in MW)
 Type
numpy.ndarray
, dtype:float
 _shunt_q
Shunt reactive value (only available if shunts are available) (in MVAr)
 Type
numpy.ndarray
, dtype:float
 _shunt_v
Shunt voltage (only available if shunts are available) (in kV)
 Type
numpy.ndarray
, dtype:float
 _shunt_bus
Bus (1 disconnected, 1 for bus 1, 2 for bus 2) at which each shunt is connected (only available if shunts are available)
 Type
numpy.ndarray
, dtype:float
Methods:
__eq__
(other)INTERNAL
__init__
([obs_env, action_helper, random_prng])__sub__
(other)computes the difference between two observation, and return an observation corresponding to this difference.
add_act
(act[, issue_warn])Easier access to the impact on the observation if an action were applied.
Convert this observation as a networkx graph.
bus_connectivity_matrix
([as_csr_matrix, ...])If we denote by nb_bus the total number bus of the powergrid (you can think of a "bus" being a "node" if you represent a powergrid as a graph [mathematical object, not a plot] with the lines being the "edges"].
connectivity_matrix
([as_csr_matrix])Computes and return the "connectivity matrix" con_mat.
copy
()INTERNAL
flow_bus_matrix
([active_flow, as_csr_matrix])A matrix of size "nb bus" "nb bus".
from_vect
(vect[, check_legit])INTERNAL
get_forecasted_inj
([time_step])This function allows you to retrieve directly the "forecast" injections for the step time_step.
This function allows to retrieve a valid and properly initialized "Simulator"
Get the time stamp of the current observation as a datetime.datetime object
This function can be overloaded.
remove possible shunts data from the classes, if shunts are deactivated
reset
()INTERNAL
set_game_over
([env])Set the observation to the "game over" state:
simulate
(action[, time_step])This method is used to simulate the effect of an action on a forecast powergrid state.
state_of
([_sentinel, load_id, gen_id, ...])Return the state of this action on a give unique load, generator unit, powerline of substation.
sub_topology
(sub_id)Returns the topology of the given substation
to_dict
()Transform this observation as a dictionary.
update
(env[, with_forecast])INTERNAL
where_different
(other)Returns the difference between two observation.
Attributes:
return the limit of production of a generator in MW rather in ratio
return the curtailment, expressed in MW rather than in ratio of pmax.
Retrieve the busbar at which each generator is connected.
Retrieve the busbar at which each extremity end of powerline is connected.
Retrieve the busbar at which each origin end of powerline is connected.
Retrieve the busbar at which each load is connected.
As of grid2op version 1.5.0, for better consistency, the "prod_p" attribute has been renamed "gen_p".
As of grid2op version 1.5.0, for better consistency, the "prod_q" attribute has been renamed "gen_q".
As of grid2op version 1.5.0, for better consistency, the "prod_v" attribute has been renamed "gen_v".
Retrieve the busbar at which each storage unit is connected.
Return the thermal limit of the powergrid, given in Amps (A)
 __eq__(other)[source]
INTERNAL
Warning
/!\ Internal, do not use unless you know what you are doing /!\
Test the equality of two observations.
2 actions are said to be identical if the have the same impact on the powergrid. This is unlrelated to their respective class. For example, if an BaseAction is of class
BaseAction
and doesn’t act on the _injection, it can be equal to a an BaseAction of derived classTopologyAction
(if the topological modification are the same of course).This implies that the attributes
BaseAction.authorized_keys
is not checked in this method.Note that if 2 actions doesn’t act on the same powergrid, or on the same backend (eg number of loads, or generators is not the same in self and other, or they are not in the same order) then action will be declared as different.
Known issue if two backend are different, but the description of the _grid are identical (ie all n_gen, n_load, n_line, sub_info, dim_topo, all vectors *_to_subid, and *_pos_topo_vect are identical) then this method will not detect the backend are different, and the action could be declared as identical. For now, this is only a theoretical behaviour: if everything is the same, then probably, up to the naming convention, then the powergrid are identical too.
 Parameters
other (
BaseObservation
) – An instance of class BaseAction to which “self” will be compared. Return type
True
if the action are equal,False
otherwise.
 __hash__ = None
 __sub__(other)[source]
computes the difference between two observation, and return an observation corresponding to this difference.
This can be used to easily plot the difference between two observations at different step for example.
 add_act(act, issue_warn=True)[source]
Easier access to the impact on the observation if an action were applied.
This is for now only useful to get a topology in which the grid would be without doing an expensive obs.simuulate
Notes
This will not give the real topology of the grid in all cases for many reasons amongst:
past topologies are not known by the observation. If you reconnect a powerline in the action without having specified on which bus, it has no way to know (but the environment does!) on which bus it should be reconnected (which is the last known bus)
some “protections” are emulated in the environment. This means that the environment can disconnect some powerline under certain conditions. This is absolutely not taken into account here.
the environment is stochastic, for example there can be maintenance or attacks (hazards) and the generators and loads change each step. This is not taken into account in this function.
no checks are performed to see if the action meets the rules of the game (number of elements you can modify in the action, cooldowns etc.) This method supposes that the action is legal and non ambiguous.
It do not check for possible “game over”, for example due to isolated elements or nonconnected grid (grid with 2 or more connex components)
If these issues are important for you, you will need to use the
grid2op.Observation.BaseObservation.simulate()
method. It can be used like obs.simulate(act, time_step=0) but it is much more expensive. Parameters
act (
grid2op.Action.BaseAction
) – The action you want to add to the observationissue_warn (
bool
) – Issue a warning when this method might not compute the proper resulting topologies. Default toTrue
: it issues warning when something not supported is done in the action.
 Returns
res – The resulting observation. Note that this observation is not initialized with everything. It is only relevant when you want to study the resulting topology after you applied an action. Lots of res attributes are empty.
 Return type
grid2op.Observation.Observation
Examples
You can use it this way, for example if you want to retrieve the topology you would get (see the restriction in the above description) after applying an action:
import grid2op # create the environment env_name = ... env = grid2op.make(env_name) # generate the first observation obs = env.reset() # make some action act = ... # see the dedicated page # have a look at the impact on the action on the topology partial_obs = obs + act # or `partial_obs = obs.add_act(act, issue_warn=False)` if you want to silence the warnings # and now you can inspect the topology with any method you want: partial_obs.topo_vect partial_obs.load_bus bus_mat = partial_obs.bus_connectivity_matrix() # or even elem_mat = partial_obs.connectivity_matrix() # but you cannot use partial_obs.prod_p # or partial_obs.load_q etc.
 as_networkx()[source]
Convert this observation as a networkx graph.
Notes
The resulting graph is “frozen” this means that you cannot add / remove attribute on nodes or edges, nor add / remove edges or nodes.
This graphs has the following properties:
it counts as many nodes as the number of buses of the grid
it counts less edges than the number of lines of the grid (two lines connecting the same buses are “merged” into one single edge  this is the case for parallel line, that are hence “merged” into the same edge)
nodes have attributes:
p: the active power produced at this node (negative means the sum of power produce minus power absorbed is negative)
q: the reactive power produced at this node
v: the voltage magnitude at this node
cooldown: how much longer you need to wait before being able to merge / split or change this node
edges have attributes too:
rho: the relative flow on this powerline
cooldown: the number of step you need to wait before being able to act on this powerline
status: whether this powerline is connected or not
thermal_limit: maximum flow allowed on the the powerline (this is the “a_or” flow)
timestep_overflow: number of time steps during which the powerline is on overflow
p_or: active power injected at this node at the “origin side”.
p_ex: active power injected at this node at the “extremity side”.
q_or: reactive power injected at this node at the “origin side”.
q_ex: reactive power injected at this node at the “extremity side”.
a_or: current flow injected at this node at the “origin side”.
a_ex: current flow injected at this node at the “extremity side”.
Danger
IMPORTANT NOTE the “origin” and “extremity” of the networkx graph is not necessarily the same as the one in grid2op. The “origin” side will always be the nodes with the lowest id. For example, if an edges connects the bus 6 to the bus 8, then the “origin” of this powerline is bus 6 (eg the active power injected at node 6 from this edge will be p_or) and the “extremity” side is bus 8 (eg the active power injected at node 8 from this edge will be p_ex).
Warning
The graph returned by this function has not a fixed size. Its number of nodes and edges can change depending on the state of the grid. See How to retrieve “the” graph in grid2op for more information.
Also, note that when “done=True” this graph has only one node and no edge.
Note
The graph returned by this function is “frozen” to prevent its modification. If you really want to modify it you can “unfroze” it.
 Returns
graph – A possible representation of the observation as a networkx graph
 Return type
networkx graph
Examples
The following code explains how to check that a grid meet the kirchoffs law (conservation of energy)
# create an environment and get the observation import grid2op env_name = ... env = grid2op.make(env_name) obs = env.reset() # retrieve the networkx graph graph = obs.as_networkx() # perform the check for every nodes for node_id in graph.nodes: # retrieve power (active and reactive) produced at this node p_ = graph.nodes[node_id]["p"] q_ = graph.nodes[node_id]["q"] # get the edges edges = graph.edges(node_id) p_lines = 0 q_lines = 0 # get the power that is "evacuated" at each nodes on all the edges connecting it to the other nodes # of the network for (k1, k2) in edges: # now retrieve the active / reactive power injected at this node (looking at either *_or or *_ex # depending on the direction of the powerline: remember that the "origin" is always the lowest # bus id. if k1 < k2: # the current inspected node is the lowest, so on the "origin" side p_lines += graph.edges[(k1, k2)]["p_or"] q_lines += graph.edges[(k1, k2)]["q_or"] else: # the current node is the largest, so on the "extremity" side p_lines += graph.edges[(k1, k2)]["p_ex"] q_lines += graph.edges[(k1, k2)]["q_ex"] assert abs(p_line  p_) <= 1e5, "error for kirchoff's law for graph for P" assert abs(q_line  q_) <= 1e5, "error for kirchoff's law for graph for Q"
 bus_connectivity_matrix(as_csr_matrix=False, return_lines_index=False)[source]
If we denote by nb_bus the total number bus of the powergrid (you can think of a “bus” being a “node” if you represent a powergrid as a graph [mathematical object, not a plot] with the lines being the “edges”].
The bus_connectivity_matrix will have a size nb_bus, nb_bus and will be made of 0 and 1.
If bus_connectivity_matrix[i,j] = 1 then at least a power line connects bus i and bus j. Otherwise, nothing connects it.
Warning
The matrix returned by this function has not a fixed size. Its number of nodes and edges can change depending on the state of the grid. See How to retrieve “the” graph in grid2op for more information.
Also, note that when “done=True” this matrix has size (1, 1) and contains only 0.
 Parameters
as_csr_matrix (
bool
) – Whether to return the bus connectivity matrix as a sparse matrix (csr format) or as a dense matrix. By default it’sFalse
meaning a dense matrix is returned.return_lines_index (
bool
) – Whether to also return the bus index associated to both side of each powerline.
 Returns
res – The bus connectivity matrix defined above.
 Return type
numpy.ndarray
, shape: (nb_bus, nb_bus) dtype:float
Notes
By convention we say that a bus is connected to itself. So the diagonal of this matrix is 1.
Examples
Here is how you can use this function:
bus_bus_graph, (line_or_bus, line_ex_bus) = obs.bus_connectivity_matrix(return_lines_index=True) # bus_bus_graph is the matrix described above. # line_or_bus[0] give the id of the bus to which the origin side of powerline 0 is connected # line_ex_bus[0] give the id of the bus to which the extremity side of powerline 0 is connected # (NB: if the powerline is disconnected, both are 1) # this means that if line 0 is connected: bus_bus_graph[line_or_bus[0], line_ex_bus[0]] = 1 # and bus_bus_graph[line_ex_bus[0], line_or_bus[0]] = 1 # (of course you can replace 0 with any integer `0 <= l_id < obs.n_line`
 connectivity_matrix(as_csr_matrix=False)[source]
Computes and return the “connectivity matrix” con_mat. Let “dim_topo := 2 * n_line + n_prod + n_conso + n_storage” (the total number of elements on the grid)
It is a matrix of size dim_topo, dim_topo, with values 0 or 1. For two objects (lines extremity, generator unit, load) i,j :
 if i and j are connected on the same substation:
if conn_mat[i,j] = 0 it means the objects id’ed i and j are not connected to the same bus.
if conn_mat[i,j] = 1 it means the objects id’ed i and j are connected to the same bus
if i and j are not connected on the same substation then`conn_mat[i,j] = 0` except if i and j are the two extremities of the same power line, in this case conn_mat[i,j] = 1 (if the powerline is in service or 0 otherwise).
By definition, the diagonal is made of 0.
 Returns
res – The connectivity matrix, as defined above
 Return type
numpy.ndarray
, shape:dim_topo,dim_topo, dtype:float
Notes
Matrix can be either a sparse matrix or a dense matrix depending on the argument as_csr_matrix
An object, is not disconnected, is always connected to itself.
Examples
If you want to know if powerline 0 is connected at its “extremity” side with the load of id 0 you can do
import grid2op env = grid2op.make() obs = env.reset() # retrieve the id of extremity of powerline 1: id_lineex_0 = obs.line_ex_pos_topo_vect[0] id_load_1 = obs.load_pos_topo_vect[0] # get the connectivity matrix connectivity_matrix = obs.connectivity_matrix() # know if the objects are connected or not are_connected = connectivity_matrix[id_lineex_0, id_load_1] # as `are_connected` is 1.0 then these objects are indeed connected
And now, supposes we do an action that changes the topology of the substation to which these two objects are connected, then we get (same example continues)
topo_action = env.action_space({"set_bus": {"substations_id": [(1, [1,1,1,2,2,2])]}}) print(topo_action) # This action will: #  NOT change anything to the injections #  NOT perform any redispatching action #  NOT force any line status #  NOT switch any line status #  NOT switch anything in the topology #  Set the bus of the following element: #  assign bus 1 to line (extremity) 0 [on substation 1] #  assign bus 1 to line (origin) 2 [on substation 1] #  assign bus 1 to line (origin) 3 [on substation 1] #  assign bus 2 to line (origin) 4 [on substation 1] #  assign bus 2 to generator 0 [on substation 1] #  assign bus 2 to load 0 [on substation 1] obs, reward, done, info = env.step(topo_action) # and now retrieve the matrix connectivity_matrix = obs.connectivity_matrix() # know if the objects are connected or not are_connected = connectivity_matrix[id_lineex_0, id_load_1] # as `are_connected` is 0.0 then these objects are not connected anymore # this is visible when you "print" the action (see above) in the two following lines: #  assign bus 1 to line (extremity) 0 [on substation 1] #  assign bus 2 to load 0 [on substation 1] # > one of them is on bus 1 [line (extremity) 0] and the other on bus 2 [load 0]
 copy()[source]
INTERNAL
Warning
/!\ Internal, do not use unless you know what you are doing /!\
Make a copy of the observation.
 Returns
res – The deep copy of the observation
 Return type
Notes
The “obs_env” attributes
 property curtailment_limit_mw
return the limit of production of a generator in MW rather in ratio
Examples
import grid2op env_name = ... env = grid2op.make(env_name) obs = env.reset() curtailment_limit_mw = obs.curtailment_limit_mw
 property curtailment_mw
return the curtailment, expressed in MW rather than in ratio of pmax.
Examples
import grid2op env_name = ... env = grid2op.make(env_name) obs = env.reset() curtailment_mw = obs.curtailment_mw
 flow_bus_matrix(active_flow=True, as_csr_matrix=False)[source]
A matrix of size “nb bus” “nb bus”. Each row and columns represent a “bus” of the grid (“bus” is a power system word that for computer scientist means “nodes” if the powergrid is represented as a graph). See the note in case of a grid in “game over” mode.
The diagonal will sum the power produced and consumed at each bus.
The other element of each row of this matrix will be the flow of power from the bus represented by the line i to the bus represented by column j.
Warning
The matrix returned by this function has not a fixed size. Its number of nodes and edges can change depending on the state of the grid. See How to retrieve “the” graph in grid2op for more information.
Also, note that when “done=True” this matrix has size (1, 1) and contains only 0.
Notes
When the observation is in a “done” state (eg there has been a game over) then this function returns a “matrix” of dimension (1,1) [yes, yes it’s a scalar] with only one element that is 0.
In this case, load_bus, prod_bus, stor_bus, lor_bus and lex_bus are vectors full of 0.
 Parameters
active_flow (
bool
) – Whether to get the active flow (in MW) or the reactive flow (in MVAr). Defaults to active flow.as_csr_matrix (
bool
) – Whether to retrieve the results as a scipy csr sparse matrix or as a dense matrix (default)
 Returns
res (
matrix
) – Which can either be a sparse matrix or a dense matrix depending on the value of the argument “as_csr_matrix”.mappings (
tuple
) – The mapping that makes the correspondence between each object and the bus to which it is connected. It is made of 4 elements: (load_bus, prod_bus, stor_bus, lor_bus, lex_bus).For example if load_bus[i] = 14 it means that the load with id i is connected to the bus 14. If load_bus[i] = 1 then the object is disconnected.
Examples
Here is how you can use this function:
flow_mat, (load, prod, stor, ind_lor, ind_lex) = obs.flow_bus_matrix() # flow_mat is the matrix described above.
Lots of information can be deduce from this matrix. For example if you want to know how much power goes from one bus say bus i to another bus (say bus j ) you can look at the associated coefficient flow_mat[i,j] which will also be related to the flow on the origin (or extremity) side of the powerline connecting bus i to bus j
You can also know how much power (total generation + total storage discharging  total load  total storage charging  ) is injected at each bus i by looking at the i th diagonal coefficient.
Another use would be to check if the current powergrid state (as seen by grid2op) meet the Kirchhoff circuit laws (conservation of energy), by doing the sum (row by row) of this matrix. flow_mat.sum(axis=1)
 from_vect(vect, check_legit=True)[source]
INTERNAL
Warning
/!\ Internal, do not use unless you know what you are doing /!\
To reload an observation from a vector, use the “env.observation_space.from_vect()”.
Convert back an observation represented as a vector into a proper observation.
Some conversion are done silently from float to the type of the corresponding observation attribute.
 Parameters
vect (
numpy.ndarray
) – A representation of an BaseObservation in the form of a vector that is used to convert back the current observation to be equal to the vect.
 property gen_bus
Retrieve the busbar at which each generator is connected.
The result follow grid2op convention:
1 means the generator is disconnected
1 means it is generator to busbar 1
2 means it is connected to busbar 2
etc.
Notes
In a same substation, two objects are connected together if (and only if) they are connected to the same busbar.
 get_forecasted_inj(time_step=1)[source]
This function allows you to retrieve directly the “forecast” injections for the step time_step.
We remind that the environment, under some conditions, can produce these forecasts automatically. This function allows to retrieve what has been forecast.
 Parameters
time_step (
int
) – The horizon of the forecast (given in number of time steps) Returns
gen_p_f (
numpy.ndarray
) – The forecast generators active valuesgen_v_f (
numpy.ndarray
) – The forecast generators voltage setpoinsload_p_f (
numpy.ndarray
) – The forecast load active consumptionload_q_f (
numpy.ndarray
) – The forecast load reactive consumption
 get_simulator() Simulator [source]
This function allows to retrieve a valid and properly initialized “Simulator”
A
grid2op.simulator.Simulator
can be used to simulate the impact of multiple consecutive actions, without taking into account any kind of rules.It can also be use with forecast of the productions / consumption to predict whether or not a given state is “robust” to variation of the injections for example.
You can find more information about simulator on the dedicated page of the documentation.
 get_time_stamp()[source]
Get the time stamp of the current observation as a datetime.datetime object
 property line_ex_bus
Retrieve the busbar at which each extremity end of powerline is connected.
The result follow grid2op convention:
1 means the powerline is disconnected
1 means it is connected to busbar 1
2 means it is connected to busbar 2
etc.
Notes
In a same substation, two objects are connected together if (and only if) they are connected to the same busbar.
 property line_or_bus
Retrieve the busbar at which each origin end of powerline is connected.
The result follow grid2op convention:
1 means the powerline is disconnected
1 means it is connected to busbar 1
2 means it is connected to busbar 2
etc.
Notes
In a same substation, two objects are connected together if (and only if) they are connected to the same busbar.
 property load_bus
Retrieve the busbar at which each load is connected.
The result follow grid2op convention:
1 means the load is disconnected
1 means it is load to busbar 1
2 means it is load to busbar 2
etc.
Notes
In a same substation, two objects are connected together if (and only if) they are connected to the same busbar.
 classmethod process_grid2op_compat()[source]
This function can be overloaded.
This is called when the class is initialized, with init_grid to broadcast grid2op compatibility feature.
 classmethod process_shunt_satic_data()[source]
remove possible shunts data from the classes, if shunts are deactivated
 property prod_p
As of grid2op version 1.5.0, for better consistency, the “prod_p” attribute has been renamed “gen_p”.
This property is present to maintain the backward compatibility.
 Return type
 property prod_q
As of grid2op version 1.5.0, for better consistency, the “prod_q” attribute has been renamed “gen_q”.
This property is present to maintain the backward compatibility.
 Return type
 property prod_v
As of grid2op version 1.5.0, for better consistency, the “prod_v” attribute has been renamed “gen_v”.
This property is present to maintain the backward compatibility.
 Return type
 reset()[source]
INTERNAL
Warning
/!\ Internal, do not use unless you know what you are doing /!\
Resetting a single observation is unlikely to do what you want to do.
Reset the
BaseObservation
to a blank state, where everything is set to eitherNone
or to its default value.
 set_game_over(env=None)[source]
Set the observation to the “game over” state:
all powerlines are disconnected
all loads are 0.
all prods are 0.
etc.
Notes
As some attributes are initialized with np.empty it is recommended to reset here all attributes to avoid non deterministic behaviour.
 simulate(action, time_step=1)[source]
This method is used to simulate the effect of an action on a forecast powergrid state. This forecast state is built upon the current observation.
The forecast are pre computed by the environment.
More concretely, if not deactivated by the environment (see
grid2op.Environment.BaseEnv.deactivate_forecast()
) and the environment has the capacity to generate these forecasts (which is the case in most grid2op environments) this function will simulate the effect of doing an action now and return the “next state” (often the state you would get at time t + 5 mins) if you were to do the action at this step.It has the same return value as the
grid2op.Environment.Environment.step()
function. Parameters
action (
grid2op.Action.Action
) – The action to simulatetime_step (
int
) – The time step of the forecasted grid to perform the action on. If no forecast are available for this time step, agrid2op.Exceptions.NoForecastAvailable
is thrown.
 Raises
grid2op.Exceptions.NoForecastAvailable – if no forecast are available for the time_step querried.
 Returns
simulated_observation (
grid2op.Observation.Observation
) – agent’s observation of the current environment after the application of the action “act” on the the current state.reward (
float
) – amount of reward returned after previous actiondone (
bool
) – whether the episode has ended, in which case further step() calls will return undefined resultsinfo (
dict
) – contains auxiliary diagnostic information (helpful for debugging, and sometimes learning)
Notes
This is a simulation in the sense that the “next grid state” is not the real grid state you will get. As you don’t know the future, the “injections you forecast for the next step” will not be the real injection you will get in the next step.
Also, in some circumstances, the “Backend” (ie the powerflow) used to do the simulation may not be the same one as the one used by the environment. This is to model a real fact: as accurate your powerflow is, it does not model all the reality (“all models are wrong”). Having a different solver for the environment ( “the reality”) than the one used to anticipate the impact of the action (this “simulate” function) is a way to represent this fact.
Examples
To simulate what would be the effect of the action “act” if you were to take this action at this step you can do the following:
import grid2op # retrieve an environment env = grid2op.make() # retrieve an observation, this is the same for all observations obs = env.reset() # and now you can simulate the effect of doing nothing in the next time step act = env.action_space() # this can be any action that grid2op understands simulated_obs, simulated_reward, simulated_done, simulated_info = obs.simulate(act) # `simulated_obs` will be the "observation" after the application of action `act` on the # " forecast of the grid state (it will be the "forecast state at time t+5mins usually) # `simulated_reward` will be the reward for the same action on the same forecast state # `simulated_done` will indicate whether or not the simulation ended up in a "game over" # `simulated_info` gives extra information on this forecast state
 state_of(_sentinel=None, load_id=None, gen_id=None, line_id=None, storage_id=None, substation_id=None)[source]
Return the state of this action on a give unique load, generator unit, powerline of substation. Only one of load, gen, line or substation should be filled.
The querry of these objects can only be done by id here (ie by giving the integer of the object in the backed). The
ActionSpace
has some utilities to access them by name too. Parameters
_sentinel (
None
) – Used to prevent positional parameters. Internal, do not use.load_id (
int
) – ID of the load we want to inspectgen_id (
int
) – ID of the generator we want to inspectline_id (
int
) – ID of the powerline we want to inspectline_id – ID of the powerline we want to inspect
storage_id (
int
) – ID of the storage unit we want to inspectsubstation_id (
int
) – ID of the substation unit we want to inspect
 Returns
res – A dictionary with keys and value depending on which object needs to be inspected:
if a load is inspected, then the keys are:
”p” the active value consumed by the load
”q” the reactive value consumed by the load
”v” the voltage magnitude of the bus to which the load is connected
”theta” (optional) the voltage angle (in degree) of the bus to which the load is connected
”bus” on which bus the load is connected in the substation
”sub_id” the id of the substation to which the load is connected
if a generator is inspected, then the keys are:
”p” the active value produced by the generator
”q” the reactive value consumed by the generator
”v” the voltage magnitude of the bus to which the generator is connected
”theta” (optional) the voltage angle (in degree) of the bus to which the gen. is connected
”bus” on which bus the generator is connected in the substation
”sub_id” the id of the substation to which the generator is connected
”actual_dispatch” the actual dispatch implemented for this generator
”target_dispatch” the target dispatch (cumulation of all previously asked dispatch by the agent) for this generator
if a powerline is inspected then the keys are “origin” and “extremity” each being dictionary with keys:
”p” the active flow on line side (extremity or origin)
”q” the reactive flow on line side (extremity or origin)
”v” the voltage magnitude of the bus to which the line side (extremity or origin) is connected
 ”theta” (optional) the voltage angle (in degree) of the bus to which line side (extremity or origin)
is connected
”bus” on which bus the line side (extremity or origin) is connected in the substation
”sub_id” the id of the substation to which the line side is connected
”a” the current flow on the line side (extremity or origin)
In the case of a powerline, additional information are:
”maintenance”: information about the maintenance operation (time of the next maintenance and duration of this next maintenance.
”cooldown_time”: for how many timestep i am not supposed to act on the powerline due to cooldown (see
grid2op.Parameters.Parameters.NB_TIMESTEP_COOLDOWN_LINE
for more information)
if a storage unit is inspected, information are:
”storage_power”: the power the unit actually produced / absorbed
”storage_charge”: the state of the charge of the storage unit
”storage_power_target”: the power production / absorbtion targer
”storage_theta”: (optional) the voltage angle of the bus at which the storage unit is connected
”bus”: the bus (1 or 2) to which the storage unit is connected
”sub_id” : the id of the substation to which the sotrage unit is connected
if a substation is inspected, it returns the topology to this substation in a dictionary with keys:
”topo_vect”: the representation of which object is connected where
”nb_bus”: number of active buses in this substations
”cooldown_time”: for how many timestep i am not supposed to act on the substation due to cooldown (see
grid2op.Parameters.Parameters.NB_TIMESTEP_COOLDOWN_SUB
for more information)
 Return type
dict
Notes
This function can only be used to retrieve the state of the element of the grid, and not the alarm sent or not, to the operator.
 Raises
Grid2OpException – If _sentinel is modified, or if None of the arguments are set or alternatively if 2 or more of the parameters are being set.
 property storage_bus
Retrieve the busbar at which each storage unit is connected.
The result follow grid2op convention:
1 means the storage unit is disconnected
1 means it is storage unit to busbar 1
2 means it is connected to busbar 2
etc.
Notes
In a same substation, two objects are connected together if (and only if) they are connected to the same busbar.
 property thermal_limit
Return the thermal limit of the powergrid, given in Amps (A)
Examples
import grid2op env_name = ... env = grid2op.make(env_name) obs = env.reset() thermal_limit = obs.thermal_limit
 to_dict()[source]
Transform this observation as a dictionary. This dictionary allows you to inspect the state of this observation and is simply a shortcut of the class instance.
 Return type
A dictionary representing the observation.
Notes
The returned dictionary is not necessarily json serializable. To have a grid2op observation that you can serialize in a json fashion, please use the
grid2op.Space.GridObjects.to_json()
function.
 abstractmethod update(env, with_forecast=True)[source]
INTERNAL
Warning
/!\ Internal, do not use unless you know what you are doing /!\ This is carried out automatically by the environment in env.step
Update the actual instance of BaseObservation with the new received value from the environment.
An observation is a description of the powergrid perceived by an agent. The agent takes his decision based on the current observation and the past rewards.
This method update receive complete detailed information about the powergrid, but that does not mean an agent sees everything. For example, it is possible to derive this class to implement some noise in the generator or load, or flows to mimic sensor inaccuracy.
It is also possible to give fake information about the topology, the line status etc.
In the Grid2Op framework it’s also through the observation that the agent has access to some forecast (the way forecast are handled depends are implemented in this class). For example, forecast data (retrieved thanks to chronics_handler) are processed, but can be processed differently. One can apply load / production forecast to each _grid state, or to make forecast for one “reference” _grid state valid a whole day and update this one only etc. All these different mechanisms can be implemented in Grid2Op framework by overloading the update observation method.
This class is really what a dispatcher observes from it environment. It can also include some temperatures, nebulosity, wind etc. can also be included in this class.
Notes
We strongly recommend to call
BaseObservation.reset
when implementing this function.
 where_different(other)[source]
Returns the difference between two observation.
 Parameters
other – Other action to compare
 Returns
diff_ (
grid2op.Observation.BaseObservation
) – The observation showing the difference between self and otherattr_nm (
list
) – List of string representing the names of the different attributes. It’s [] if the two observations are identical.
 class grid2op.Observation.CompleteObservation(obs_env=None, action_helper=None, random_prng=None)[source]
This class represent a complete observation, where everything on the powergrid can be observed without any noise.
This is the only
BaseObservation
implemented (and used) in Grid2Op. Other type of observation, for other usage can of course be implemented following this example.It has the same attributes as the
BaseObservation
class. Only one is added here.For a
CompleteObservation
the unique representation as a vector is:BaseObservation.year
the year [1 element]BaseObservation.month
the month [1 element]BaseObservation.day
the day [1 element]BaseObservation.hour_of_day
the hour of the day [1 element]BaseObservation.minute_of_hour
minute of the hour [1 element]BaseObservation.day_of_week
the day of the week. Monday = 0, Sunday = 6 [1 element]BaseObservation.gen_p
the active value of the productions [grid2op.Space.GridObjects.n_gen
elements]BaseObservation.gen_q
the reactive value of the productions [grid2op.Space.GridObjects.n_gen
elements]BaseObservation.gen_v
the voltage setpoint of the productions [grid2op.Space.GridObjects.n_gen
elements]BaseObservation.load_p
the active value of the loads [grid2op.Space.GridObjects.n_load
elements]BaseObservation.load_q
the reactive value of the loads [grid2op.Space.GridObjects.n_load
elements]BaseObservation.load_v
the voltage setpoint of the loads [grid2op.Space.GridObjects.n_load
elements]BaseObservation.p_or
active flow at origin of powerlines [grid2op.Space.GridObjects.n_line
elements]BaseObservation.q_or
reactive flow at origin of powerlines [grid2op.Space.GridObjects.n_line
elements]BaseObservation.v_or
voltage at origin of powerlines [grid2op.Space.GridObjects.n_line
elements]BaseObservation.a_or
current flow at origin of powerlines [grid2op.Space.GridObjects.n_line
elements]BaseObservation.p_ex
active flow at extremity of powerlines [grid2op.Space.GridObjects.n_line
elements]BaseObservation.q_ex
reactive flow at extremity of powerlines [grid2op.Space.GridObjects.n_line
elements]BaseObservation.v_ex
voltage at extremity of powerlines [grid2op.Space.GridObjects.n_line
elements]BaseObservation.a_ex
current flow at extremity of powerlines [grid2op.Space.GridObjects.n_line
elements]BaseObservation.rho
line capacity used (current flow / thermal limit) [grid2op.Space.GridObjects.n_line
elements]BaseObservation.line_status
line status [grid2op.Space.GridObjects.n_line
elements]BaseObservation.timestep_overflow
number of timestep since the powerline was on overflow (0 if the line is not on overflow)[grid2op.Space.GridObjects.n_line
elements]BaseObservation.topo_vect
representation as a vector of the topology [for each element it gives its bus]. Seegrid2op.Backend.Backend.get_topo_vect()
for more information.BaseObservation.time_before_cooldown_line
representation of the cooldown time on the powerlines [grid2op.Space.GridObjects.n_line
elements]BaseObservation.time_before_cooldown_sub
representation of the cooldown time on the substations [grid2op.Space.GridObjects.n_sub
elements]BaseObservation.time_next_maintenance
number of timestep before the next maintenance (1 means no maintenance are planned, 0 a maintenance is in operation) [BaseObservation.n_line
elements]BaseObservation.duration_next_maintenance
duration of the next maintenance. If a maintenance is taking place, this is the number of timestep before it ends. [BaseObservation.n_line
elements]BaseObservation.target_dispatch
the target dispatch for each generator [grid2op.Space.GridObjects.n_gen
elements]BaseObservation.actual_dispatch
the actual dispatch for each generator [grid2op.Space.GridObjects.n_gen
elements]BaseObservation.storage_charge
the actual state of charge of each storage unit [grid2op.Space.GridObjects.n_storage
elements]BaseObservation.storage_power_target
the production / consumption of setpoint of each storage unit [grid2op.Space.GridObjects.n_storage
elements]BaseObservation.storage_power
the realized production / consumption of each storage unit [grid2op.Space.GridObjects.n_storage
elements]BaseObservation.gen_p_before_curtail
: the theoretical generation that would have happened if no generator from renewable energy sources have been performed (in MW) [grid2op.Space.GridObjects.n_gen
elements]BaseObservation.curtailment
: the current curtailment applied [grid2op.Space.GridObjects.n_gen
elements]BaseObservation.is_alarm_illegal
whether the last alarm has been illegal (due to budget constraint) [bool
]BaseObservation.curtailment_limit
: the current curtailment limit (if any) [grid2op.Space.GridObjects.n_gen
elements]BaseObservation.time_since_last_alarm
number of step since the last alarm has been raised successfully [int
]BaseObservation.last_alarm
: for each alarm zone, gives the last step at which an alarm has been successfully raised at this zone [grid2op.Space.GridObjects.dim_alarms
elements]BaseObservation.attention_budget
: the current attention budget [int
]BaseObservation.was_alarm_used_after_game_over
: was the last alarm used to compute anything related to the attention budget when there was a game over (can only be set toTrue
if the observation corresponds to a game over) [bool
]
Methods:
__init__
([obs_env, action_helper, random_prng])update
(env[, with_forecast])INTERNAL
 update(env, with_forecast=True)[source]
INTERNAL
Warning
/!\ Internal, do not use unless you know what you are doing /!\ This is carried out automatically by the environment in env.step
Update the actual instance of BaseObservation with the new received value from the environment.
An observation is a description of the powergrid perceived by an agent. The agent takes his decision based on the current observation and the past rewards.
This method update receive complete detailed information about the powergrid, but that does not mean an agent sees everything. For example, it is possible to derive this class to implement some noise in the generator or load, or flows to mimic sensor inaccuracy.
It is also possible to give fake information about the topology, the line status etc.
In the Grid2Op framework it’s also through the observation that the agent has access to some forecast (the way forecast are handled depends are implemented in this class). For example, forecast data (retrieved thanks to chronics_handler) are processed, but can be processed differently. One can apply load / production forecast to each _grid state, or to make forecast for one “reference” _grid state valid a whole day and update this one only etc. All these different mechanisms can be implemented in Grid2Op framework by overloading the update observation method.
This class is really what a dispatcher observes from it environment. It can also include some temperatures, nebulosity, wind etc. can also be included in this class.
Notes
We strongly recommend to call
BaseObservation.reset
when implementing this function.
 class grid2op.Observation.NoisyObservation(obs_env=None, action_helper=None, random_prng=None, sigma_load_p=0.01, sigma_load_q=0.01, sigma_gen_p=0.01, sigma_gen_q=0.01, sigma_a=0.01, sigma_p=0.1, sigma_q=0.1, sigma_storage=0.1)[source]
This class represent a complete observation (in the sens that all attributes of an
CompleteObservation
are accessible) but some of them are “noisy”.That is, the observation that the agent has access to is not exactly the same as the environment internal values.
The affected attributes are :
load_p: *= lognormal (to keep the sign)
load_q: *= lognormal (to keep the sign)
gen_p: *= lognormal (to keep the sign)
gen_q: *= lognormal (to keep the sign)
p_or += normal
p_ex += normal
q_or += normal
q_ex += normal
a_or: *= lognormal (to keep the sign)
a_ex: *= lognormal (to keep the sign)
rho: same noise as a_or (because rho is not “physical” it’s the result of a computation)
storage_power += normal
It can be used to emuate the acquisition of data coming from noisy sensors for example.
Examples
It can be used as follow:
import grid2op env_name = ... # for example "l2rpn_case14_sandbox" kwargs_observation = {"sigma_load_p": 0.1, "sigma_gen_p": 1.0} # noise of the observation env = grid2op.make(env_name, observation_class=NoisyObservation, kwargs_observation=kwargs_observation) # do whatever you want with env !
Methods:
__init__
([obs_env, action_helper, ...])update
(env[, with_forecast])INTERNAL
 __init__(obs_env=None, action_helper=None, random_prng=None, sigma_load_p=0.01, sigma_load_q=0.01, sigma_gen_p=0.01, sigma_gen_q=0.01, sigma_a=0.01, sigma_p=0.1, sigma_q=0.1, sigma_storage=0.1)[source]
 update(env, with_forecast=True)[source]
INTERNAL
Warning
/!\ Internal, do not use unless you know what you are doing /!\ This is carried out automatically by the environment in env.step
Update the actual instance of BaseObservation with the new received value from the environment.
An observation is a description of the powergrid perceived by an agent. The agent takes his decision based on the current observation and the past rewards.
This method update receive complete detailed information about the powergrid, but that does not mean an agent sees everything. For example, it is possible to derive this class to implement some noise in the generator or load, or flows to mimic sensor inaccuracy.
It is also possible to give fake information about the topology, the line status etc.
In the Grid2Op framework it’s also through the observation that the agent has access to some forecast (the way forecast are handled depends are implemented in this class). For example, forecast data (retrieved thanks to chronics_handler) are processed, but can be processed differently. One can apply load / production forecast to each _grid state, or to make forecast for one “reference” _grid state valid a whole day and update this one only etc. All these different mechanisms can be implemented in Grid2Op framework by overloading the update observation method.
This class is really what a dispatcher observes from it environment. It can also include some temperatures, nebulosity, wind etc. can also be included in this class.
Notes
We strongly recommend to call
BaseObservation.reset
when implementing this function.
 class grid2op.Observation.ObservationSpace(gridobj, env, rewardClass=None, observationClass=<class 'grid2op.Observation.completeObservation.CompleteObservation'>, actionClass=None, with_forecast=True, kwargs_observation=None, logger=None)[source]
Helper that provides useful functions to manipulate
BaseObservation
.BaseObservation should only be built using this Helper. It is absolutely not recommended to make an observation directly form its constructor.
This class represents the same concept as the “BaseObservation Space” in the OpenAI gym framework.
 with_forecast
If
True
theBaseObservation.simulate()
will be available. IfFalse
it will deactivate this possibility. If simulate function is not used, setting it toFalse
can lead to non neglectible speedups. Type
bool
 observationClass
Class used to build the observations. It defaults to
CompleteObservation
 Type
type
 _simulate_parameters
Type of Parameters used to compute powerflow for the forecast.
 rewardClass
Class used by the
grid2op.Environment.Environment
to send information about its state to thegrid2op.BaseAgent.BaseAgent
. You can change this class to differentiate between the reward of output ofBaseObservation.simulate()
and the reward used to train the BaseAgent. Type
type
 action_helper_env
BaseAction space used to create action during the
BaseObservation.simulate()
 reward_helper
BaseReward function used by the the
BaseObservation.simulate()
function. Type
grid2op.Reward.HelperReward
 obs_env
Instance of the environment used by the BaseObservation Helper to provide forcecast of the grid state.
 Type
_ObsEnv
 _empty_obs
An instance of the observation with appropriate dimensions. It is updated and will be sent to he BaseAgent.
 Type
Methods:
__call__
(env[, _update_state])Call self as a function.
__init__
(gridobj, env[, rewardClass, ...])INTERNAL
This checks on the rules if the agent has not made too many calls to "obs.simulate" this step
change_other_rewards
(dict_reward)this function is used to change the "other rewards" used when you perform simulate.
copy
([copy_backend])INTERNAL
INTERNAL
reset
(real_env)reset the observation space with the new values of the environment
INTERNAL
size_obs
()Size if the observation vector would be flatten :return:
 __init__(gridobj, env, rewardClass=None, observationClass=<class 'grid2op.Observation.completeObservation.CompleteObservation'>, actionClass=None, with_forecast=True, kwargs_observation=None, logger=None)[source]
INTERNAL
Warning
/!\ Internal, do not use unless you know what you are doing /!\
Env: requires
grid2op.Environment.parameters
andgrid2op.Environment.backend
to be valid
 can_use_simulate() bool [source]
This checks on the rules if the agent has not made too many calls to “obs.simulate” this step
 change_other_rewards(dict_reward)[source]
this function is used to change the “other rewards” used when you perform simulate.
This can be used, for example, when you want to do faster call to “simulate”. In this case you can remove all the “other_rewards” that will be used by the simulate function.
 Parameters
dict_reward (
dict
) – see description ofgrid2op.Environment.BaseEnv.other_rewards
Examples
If you want to deactivate the reward in the simulate function, you can do as following:
import grid2op from grid2op.Reward import CloseToOverflowReward, L2RPNReward, RedispReward env_name = "l2rpn_case14_sandbox" other_rewards = {"close_overflow": CloseToOverflowReward, "l2rpn": L2RPNReward, "redisp": RedispReward} env = grid2op.make(env_name, other_rewards=other_rewards) env.observation_space.change_other_rewards({})
 copy(copy_backend=False)[source]
INTERNAL
Warning
/!\ Internal, do not use unless you know what you are doing /!\
Perform a deep copy of the Observation space.
 get_empty_observation()[source]
INTERNAL
Warning
/!\ Internal, do not use unless you know what you are doing /!\
return an empty observation, for internal use only.
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