Skip to content

Commit

Permalink
finishing the class to loop through episode data
Browse files Browse the repository at this point in the history
  • Loading branch information
BDonnot committed Aug 25, 2023
1 parent 37fd31a commit 4345467
Show file tree
Hide file tree
Showing 28 changed files with 235 additions and 37 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ Change Log
- [FIXED] issue https://github.com/rte-france/Grid2Op/issues/511
- [FIXED] issue https://github.com/rte-france/Grid2Op/issues/508
- [ADDED] some classes that can be used to reproduce exactly what happened in a previously run environment
see `grid2op.Chronics.FromOneEpisodeData` and `grid2op.Opponent.FromEpisodeDataOpponent`
see `grid2op.Chronics.FromOneEpisodeData` and `grid2op.Opponent.FromEpisodeDataOpponent`
and `grid2op.Chronics.FromMultiEpisodeData`
- [ADDED] An helper function to get the kwargs to disable the opponent (see `grid2op.Opponent.get_kwargs_no_opponent()`)
- [IMPROVED] doc of `obs.to_dict` and `obs.to_json` (see https://github.com/rte-france/Grid2Op/issues/509)

Expand Down
2 changes: 1 addition & 1 deletion grid2op/Agent/recoPowerLinePerArea.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class RecoPowerlinePerArea(BaseAgent):
You can use it like:
.. code-block::
.. code-block:: python
import grid2op
from grid2op.Agent import RecoPowerlinePerArea
Expand Down
5 changes: 4 additions & 1 deletion grid2op/Chronics/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
"FromNPY",
"FromChronix2grid",
"FromHandlers",
"FromOneEpisodeData"
"FromOneEpisodeData",
"FromMultiEpisodeData"
]

from grid2op.Chronics.chronicsHandler import ChronicsHandler
Expand All @@ -31,4 +32,6 @@
from grid2op.Chronics.fromNPY import FromNPY
from grid2op.Chronics.fromChronix2grid import FromChronix2grid
from grid2op.Chronics.time_series_from_handlers import FromHandlers

from grid2op.Chronics.fromOneEpisodeData import FromOneEpisodeData
from grid2op.Chronics.fromMultiEpisodeData import FromMultiEpisodeData
87 changes: 83 additions & 4 deletions grid2op/Chronics/fromMultiEpisodeData.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,82 @@


class FromMultiEpisodeData(GridValue):
"""This class allows to redo some episode that have been previously run using a runner.
It is an extension of the class :class:`FromOneEpisodeData` but with multiple episodes.
.. seealso::
:class:`grid2op.Chronics.FromOneEpisodeData`if you want to use only one episode
.. warning::
It has the same limitation as :class:`grid2op.Chronics.FromOneEpisodeData`, including:
- forecasts are not saved so cannot be retrieved with this class. You can however
use `obs.simulate` and in this case it will lead perfect forecasts.
- to make sure you are running the exact same episode, you need to create the environment
with the :class:`grid2op.Opponent.FromEpisodeDataOpponent` opponent
Examples
---------
You can use this class this way:
First, you generate some data by running an episode with do nothing or reco powerline agent,
preferably episode that go until the end of your time series
.. code-block:: python
import grid2op
from grid2op.Runner import Runner
from grid2op.Agent import RecoPowerlineAgent
path_agent = ....
nb_episode = ...
env_name = "l2rpn_case14_sandbox" # or any other name
env = grid2op.make(env_name, etc.)
# optional (change the parameters to allow the )
param = env.parameters
param.NO_OVERFLOW_DISCONNECTION = True
env.change_parameters(param)
env.reset()
# end optional
runner = Runner(**env.get_params_for_runner(),
agentClass=RecoPowerlineAgent)
runner.run(nb_episode=nb_episode,
path_save=path_agent)
And then you can load it back and run the exact same environment with the same
time series, the same attacks etc. with:
.. code-block:: python
import grid2op
from grid2op.Chronics import FromMultiEpisodeData
from grid2op.Opponent import FromEpisodeDataOpponent
from grid2op.Episode import EpisodeData
path_agent = .... # same as above
env_name = .... # same as above
# path_agent is the path where data coming from a grid2op runner are stored
# NB it should come from a do nothing agent, or at least
# an agent that does not modify the injections (no redispatching, curtailment, storage)
li_episode = EpisodeData.list_episode(path_agent)
env = grid2op.make(env_name,
chronics_class=FromMultiEpisodeData,
data_feeding_kwargs={"li_ep_data": li_episode},
opponent_class=FromEpisodeDataOpponent,
opponent_attack_cooldown=1,
)
# li_ep_data in this case is a list of anything that is accepted by `FromOneEpisodeData`
obs = env.reset()
# and now you can use "env" as any grid2op environment.
"""
MULTI_CHRONICS = True
def __init__(self,
path, # can be None !
Expand All @@ -47,8 +123,9 @@ def __init__(self,
start_datetime=start_datetime)
for el in li_ep_data
]
self._prev_cache_id = 0
self.data = self.li_ep_data[0]
self._prev_cache_id = len(self.li_ep_data) - 1
self.data = self.li_ep_data[self._prev_cache_id]
self._episode_data = self.data._episode_data # used by the fromEpisodeDataOpponent

def next_chronics(self):
self._prev_cache_id += 1
Expand All @@ -74,6 +151,7 @@ def initialize(
order_backend_subs,
names_chronics_to_backend=names_chronics_to_backend,
)
self._episode_data = self.data._episode_data

def done(self):
return self.data.done()
Expand All @@ -88,6 +166,7 @@ def forecasts(self):
return self.data.forecasts()

def tell_id(self, id_num, previous=False):
id_num = int(id_num)
if not isinstance(id_num, (int, dt_int)):
raise ChronicsError("FromMultiEpisodeData can only be used with `tell_id` being an integer "
"at the moment. Feel free to write a feature request if you want more.")
Expand All @@ -99,8 +178,8 @@ def tell_id(self, id_num, previous=False):
self._prev_cache_id -= 1
self._prev_cache_id %= len(self.li_ep_data)

def get_id(self) -> int:
return self._prev_cache_id - 1 # TODO check
def get_id(self) -> str:
return f'{self._prev_cache_id }'

def max_timestep(self):
return self.data.max_timestep()
Expand Down
5 changes: 4 additions & 1 deletion grid2op/Chronics/fromOneEpisodeData.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ class FromOneEpisodeData(GridValue):
you to build this class with a complete episode (and not using an agent that games over after a
few steps), for example by using the "RecoPowerlineAgent" and the `NO_OVERFLOW_DISCONNECTION`
parameters (see example below)
.. seealso::
:class:`grid2op.Chronics.FromMultiEpisodeData`if you want to use multiple episode data
Examples
---------
Expand Down Expand Up @@ -128,7 +131,7 @@ class FromOneEpisodeData(GridValue):
If you want to include perfect forecast (unfortunately you cannot retrieve the original forecasts)
you can do:
.. code-block::
.. code-block:: python
# same as above
Expand Down
2 changes: 1 addition & 1 deletion grid2op/Environment/baseMultiProcessEnv.py
Original file line number Diff line number Diff line change
Expand Up @@ -616,7 +616,7 @@ def simulate(self, actions):
You can use this feature like:
.. code-block::
.. code-block:: python
import grid2op
from grid2op.Environment import BaseMultiProcessEnvironment
Expand Down
2 changes: 1 addition & 1 deletion grid2op/Opponent/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@
from grid2op.Opponent.geometricOpponent import GeometricOpponent
from grid2op.Opponent.geometricOpponentMultiArea import GeometricOpponentMultiArea
from grid2op.Opponent.fromEpisodeDataOpponent import FromEpisodeDataOpponent
from grid2op.Opponent.utils import get_kwargs_no_opponent
from grid2op.Opponent.utils import get_kwargs_no_opponent
4 changes: 2 additions & 2 deletions grid2op/Opponent/fromEpisodeDataOpponent.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import warnings

from grid2op.Opponent.baseOpponent import BaseOpponent
from grid2op.Chronics import FromOneEpisodeData
from grid2op.Chronics import FromOneEpisodeData, FromMultiEpisodeData
from grid2op.Exceptions import OpponentError


Expand Down Expand Up @@ -75,7 +75,7 @@ def __init__(self, action_space):
self._warning_cooldown_issued = False

def init(self, partial_env, **kwargs):
if not isinstance(partial_env.chronics_handler.real_data, FromOneEpisodeData):
if not isinstance(partial_env.chronics_handler.real_data, (FromOneEpisodeData, FromMultiEpisodeData)):
raise OpponentError("FromEpisodeDataOpponent can only be used with FromOneEpisodeData time series !")
self._ptr_env = partial_env
self._attacks = copy.deepcopy(self._ptr_env.chronics_handler.real_data._episode_data.attacks)
Expand Down
2 changes: 1 addition & 1 deletion grid2op/Opponent/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def get_kwargs_no_opponent() -> Dict:
You can use it like
.. code-block::
.. code-block:: python
import grid2op
env_name = "l2rpn_case14_sandbox" # or any other name
Expand Down
2 changes: 1 addition & 1 deletion grid2op/Reward/_alarmScore.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class _AlarmScore(AlarmReward):
---------
You can use this reward in any environment with:
.. code-block:
.. code-block:: python
import grid2op
from grid2op.Reward import AlarmReward
Expand Down
2 changes: 1 addition & 1 deletion grid2op/Reward/alarmReward.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class AlarmReward(BaseReward):
---------
You can use this reward in any environment with:
.. code-block:
.. code-block:: python
import grid2op
from grid2op.Reward import AlarmReward
Expand Down
2 changes: 1 addition & 1 deletion grid2op/Reward/alertReward.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class AlertReward(BaseReward):
---------
You can use this reward in any environment with:
.. code-block:
.. code-block:: python
import grid2op
from grid2op.Reward import AlertReward
Expand Down
2 changes: 1 addition & 1 deletion grid2op/Reward/baseReward.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class BaseReward(ABC):
If you want the environment to compute a reward that is the sum of the flow (this is not a good reward, but
we use it as an example on how to do it) you can achieve it with:
.. code-block:
.. code-block:: python
import grid2op
from grid2op.Reward import BaseReward
Expand Down
2 changes: 1 addition & 1 deletion grid2op/Reward/bridgeReward.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class BridgeReward(BaseReward):
---------
You can use this reward in any environment with:
.. code-block:
.. code-block:: python
import grid2op
from grid2op.Reward import BridgeReward
Expand Down
2 changes: 1 addition & 1 deletion grid2op/Reward/closeToOverflowReward.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class CloseToOverflowReward(BaseReward):
---------
You can use this reward in any environment with:
.. code-block:
.. code-block:: python
import grid2op
from grid2op.Reward import CloseToOverflowReward
Expand Down
2 changes: 1 addition & 1 deletion grid2op/Reward/constantReward.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class ConstantReward(BaseReward):
---------
You can use this reward in any environment with:
.. code-block:
.. code-block:: python
import grid2op
from grid2op.Reward import ConstantReward
Expand Down
2 changes: 1 addition & 1 deletion grid2op/Reward/distanceReward.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class DistanceReward(BaseReward):
---------
You can use this reward in any environment with:
.. code-block:
.. code-block:: python
import grid2op
from grid2op.Reward import DistanceReward
Expand Down
2 changes: 1 addition & 1 deletion grid2op/Reward/economicReward.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class EconomicReward(BaseReward):
---------
You can use this reward in any environment with:
.. code-block:
.. code-block:: python
import grid2op
from grid2op.Reward import EconomicReward
Expand Down
2 changes: 1 addition & 1 deletion grid2op/Reward/episodeDurationReward.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class EpisodeDurationReward(BaseReward):
---------
You can use this reward in any environment with:
.. code-block:
.. code-block:: python
import grid2op
from grid2op.Reward import EpisodeDurationReward
Expand Down
2 changes: 1 addition & 1 deletion grid2op/Reward/flatReward.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class FlatReward(BaseReward):
---------
You can use this reward in any environment with:
.. code-block:
.. code-block:: python
import grid2op
from grid2op.Reward import FlatReward
Expand Down
2 changes: 1 addition & 1 deletion grid2op/Reward/gameplayReward.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class GameplayReward(BaseReward):
---------
You can use this reward in any environment with:
.. code-block:
.. code-block:: python
import grid2op
from grid2op.Reward import GameplayReward
Expand Down
2 changes: 1 addition & 1 deletion grid2op/Reward/increasingFlatReward.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class IncreasingFlatReward(BaseReward):
---------
You can use this reward in any environment with:
.. code-block:
.. code-block:: python
import grid2op
from grid2op.Reward import IncreasingFlatReward
Expand Down
2 changes: 1 addition & 1 deletion grid2op/Reward/l2RPNReward.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class L2RPNReward(BaseReward):
---------
You can use this reward in any environment with:
.. code-block:
.. code-block:: python
import grid2op
from grid2op.Reward import L2RPNReward
Expand Down
2 changes: 1 addition & 1 deletion grid2op/Reward/linesCapacityReward.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class LinesCapacityReward(BaseReward):
---------
You can use this reward in any environment with:
.. code-block:
.. code-block:: python
import grid2op
from grid2op.Reward import LinesCapacityReward
Expand Down
2 changes: 1 addition & 1 deletion grid2op/Reward/linesReconnectedReward.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class LinesReconnectedReward(BaseReward):
---------
You can use this reward in any environment with:
.. code-block:
.. code-block:: python
import grid2op
from grid2op.Reward import LinesReconnectedReward
Expand Down
2 changes: 1 addition & 1 deletion grid2op/Reward/redispReward.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class RedispReward(BaseReward):
---------
You can use this reward in any environment with:
.. code-block:
.. code-block:: python
import grid2op
from grid2op.Reward import RedispReward
Expand Down
3 changes: 2 additions & 1 deletion grid2op/Rules/rulesByArea.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ class RulesByArea(BaseRules):
---------
If you want the environment to take into account the rules by area, you can achieve it with:
.. code-block:
.. code-block:: python
import grid2op
from grid2op.Rules.rulesByArea import RulesByArea
Expand Down
Loading

0 comments on commit 4345467

Please sign in to comment.