From f43ad4c7e7d1a34273d14cacda5d807064d709f1 Mon Sep 17 00:00:00 2001 From: DONNOT Benjamin Date: Tue, 30 Apr 2024 15:18:17 +0200 Subject: [PATCH 01/11] adding possibility to set the grid to a certain state, not fully tested yet --- CHANGELOG.rst | 15 +- docs/conf.py | 2 +- grid2op/Chronics/chronicsHandler.py | 8 + grid2op/Chronics/fromMultiEpisodeData.py | 6 + grid2op/Chronics/fromNPY.py | 20 +- grid2op/Chronics/fromOneEpisodeData.py | 5 + grid2op/Chronics/gridStateFromFile.py | 34 ++ grid2op/Chronics/gridValue.py | 30 +- grid2op/Chronics/handlers/__init__.py | 2 + grid2op/Chronics/handlers/baseHandler.py | 19 +- .../Chronics/handlers/csvForecastHandler.py | 2 + grid2op/Chronics/handlers/csvHandler.py | 2 + .../handlers/csvMaintenanceHandler.py | 7 +- .../Chronics/handlers/do_nothing_handler.py | 5 +- .../Chronics/handlers/jsonInitStateHandler.py | 52 +++ .../handlers/jsonMaintenanceHandler.py | 7 + grid2op/Chronics/multiFolder.py | 6 + grid2op/Chronics/multifolderWithCache.py | 2 + grid2op/Chronics/time_series_from_handlers.py | 43 ++- grid2op/Environment/baseEnv.py | 12 +- grid2op/Environment/environment.py | 4 +- grid2op/Runner/aux_fun.py | 15 +- grid2op/Runner/runner.py | 32 +- grid2op/__init__.py | 2 +- grid2op/tests/test_Action_iadd.py | 9 + grid2op/tests/test_EpisodeData.py | 4 +- grid2op/tests/test_Runner.py | 3 +- grid2op/tests/test_RunnerFast.py | 125 ------- grid2op/tests/test_action_set_orig_state.py | 313 ++++++++++++++++++ grid2op/tests/test_alert_trust_score.py | 62 ++-- 30 files changed, 635 insertions(+), 213 deletions(-) create mode 100644 grid2op/Chronics/handlers/jsonInitStateHandler.py create mode 100644 grid2op/tests/test_action_set_orig_state.py diff --git a/CHANGELOG.rst b/CHANGELOG.rst index f958fb1eb..e6cca5019 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -33,6 +33,12 @@ Change Log [1.10.2] - 2024-xx-yy ------------------------- +- [BREAKING] the `runner.run_one_episode` now returns an extra first argument: + `chron_id, chron_name, cum_reward, timestep, max_ts = runner.run_one_episode()` which + is consistant with `runner.run(...)` (previously it returned only + `chron_name, cum_reward, timestep, max_ts = runner.run_one_episode()`) +- [BREAKING] the runner now has no `chronics_handler` attribute (`runner.chronics_handler` + is not defined) - [ADDED] it is now possible to call `change_reward` directly from an observation (no need to do it from the Observation Space) - [ADDED] method to change the reward from the observation (observation_space @@ -40,10 +46,15 @@ Change Log - [ADDED] a way to automatically set the `experimental_read_from_local_dir` flags (with automatic class creation). For now it is disable by default, but you can activate it transparently (see doc) -- [ADDED] TODO the possibility to set the grid in an initial state (using an action) TODO +- [ADDED] possibility to set the grid to an initial state (using an action) when using the + "time series" classes. The supported classes are `GridStateFromFile` - and all its derivative, + `FromOneEpisodeData`, `FromMultiEpisodeData`, `FromNPY` and `FromHandlers`. The classes `ChangeNothing` + and `FromChronix2grid` are not supported at the moment. +- [ADDED] an "Handler" (`JSONInitStateHandler`) that can set the grid to an initial state (so as to make + compatible the `FromHandlers` time series class with this new feature) - [FIXED] a small issue that could lead to having "redispatching_unit_commitment_availble" flag set even if the redispatching - data was not loded correctly + data was not loaded correctly - [FIXED] EducPandaPowerBackend now properly sends numpy array in the class attributes (instead of pandas series) - [FIXED] an issue when loading back data (with `EpisodeData`): when there were no storage units diff --git a/docs/conf.py b/docs/conf.py index 9e0cf8fa7..55664ee2b 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -22,7 +22,7 @@ author = 'Benjamin Donnot' # The full version, including alpha/beta/rc tags -release = '1.10.2.dev1' +release = '1.10.2.dev2' version = '1.10' diff --git a/grid2op/Chronics/chronicsHandler.py b/grid2op/Chronics/chronicsHandler.py index a1b66bce7..000a33d68 100644 --- a/grid2op/Chronics/chronicsHandler.py +++ b/grid2op/Chronics/chronicsHandler.py @@ -87,6 +87,14 @@ def __init__( "{}".format(chronicsClass, self.kwargs) ) from exc_ + @property + def action_space(self): + return self._real_data.action_space + + @action_space.setter + def action_space(self, values): + self._real_data.action_space = values + @property def kwargs(self): res = copy.deepcopy(self._kwargs) diff --git a/grid2op/Chronics/fromMultiEpisodeData.py b/grid2op/Chronics/fromMultiEpisodeData.py index 309f990e6..c130263dd 100644 --- a/grid2op/Chronics/fromMultiEpisodeData.py +++ b/grid2op/Chronics/fromMultiEpisodeData.py @@ -152,6 +152,9 @@ def initialize( names_chronics_to_backend=names_chronics_to_backend, ) self._episode_data = self.data._episode_data + if self.action_space is not None: + if self.data.action_space is None: + self.data.action_space = self.action_space def done(self): return self.data.done() @@ -186,3 +189,6 @@ def max_timestep(self): def fast_forward(self, nb_timestep): self.data.fast_forward(nb_timestep) + + def get_init_action(self) -> Union["grid2op.Action.playableAction.PlayableAction", None]: + return self.data.get_init_action() diff --git a/grid2op/Chronics/fromNPY.py b/grid2op/Chronics/fromNPY.py index 983d10ebd..fc006eeed 100644 --- a/grid2op/Chronics/fromNPY.py +++ b/grid2op/Chronics/fromNPY.py @@ -68,12 +68,13 @@ class FromNPY(GridValue): "load_q": load_q, "prod_p": prod_p, "prod_v": prod_v - # other parameters includes + ## other parameters includes # maintenance # load_p_forecast # load_q_forecast # prod_p_forecast # prod_v_forecast + # init_state # new in 1.10.2 }) # you can use env normally, including in runners @@ -129,6 +130,7 @@ def __init__( chunk_size: Optional[int] = None, i_start: Optional[int] = None, i_end: Optional[int] = None, # excluded, as always in python + init_state: Optional["grid2op.Action.BaseAction"] = None, **kwargs ): GridValue.__init__( @@ -193,17 +195,6 @@ def __init__( "This feature is not available at the moment. Fill a github issue at " "https://github.com/rte-france/Grid2Op/issues/new?assignees=&labels=enhancement&template=feature_request.md&title=" ) - # self.has_hazards = True - # if self.n_line is None: - # self.n_line = hazards.shape[1] - # else: - # assert self.n_line == hazards.shape[1] - # assert load_p.shape[0] == hazards.shape[0] - - # self.hazards = hazards # TODO copy ! - # self.hazard_duration = np.zeros(shape=(self.hazards.shape[0], self.n_line), dtype=dt_int) - # for line_id in range(self.n_line): - # self.hazard_duration[:, line_id] = self.get_hazard_duration_1d(self.hazards[:, line_id]) self._forecasts = None if load_p_forecast is not None: @@ -229,6 +220,8 @@ def __init__( raise ChronicsError( "if prod_p_forecast is not None, then load_p_forecast should not be None" ) + + self._init_state = init_state def initialize( self, @@ -700,3 +693,6 @@ def change_i_end(self, new_i_end: Union[int, None]): self.__new_iend = int(new_i_end) else: self.__new_iend = None + + def get_init_action(self) -> Union["grid2op.Action.playableAction.PlayableAction", None]: + return self._init_state diff --git a/grid2op/Chronics/fromOneEpisodeData.py b/grid2op/Chronics/fromOneEpisodeData.py index e3214b5b7..09ce4840f 100644 --- a/grid2op/Chronics/fromOneEpisodeData.py +++ b/grid2op/Chronics/fromOneEpisodeData.py @@ -25,6 +25,7 @@ TYPE_EP_DATA_INGESTED = Union[str, Path, EpisodeData, Tuple[str, str]] + class FromOneEpisodeData(GridValue): """This class allows to use the :class:`grid2op.Chronics.handlers.BaseHandler` to read back data stored in :class:`grid2op.Episode.EpisodeData` @@ -422,3 +423,7 @@ def fast_forward(self, nb_timestep): self.load_next() # for this class I suppose the real data AND the forecast are read each step self.forecasts() + + def get_init_action(self) -> Union["grid2op.Action.playableAction.PlayableAction", None]: + obs = self._episode_data.observations[0] + return self.action_space({"set_bus": obs.topo_vect}) diff --git a/grid2op/Chronics/gridStateFromFile.py b/grid2op/Chronics/gridStateFromFile.py index d9824637f..6507dbe88 100644 --- a/grid2op/Chronics/gridStateFromFile.py +++ b/grid2op/Chronics/gridStateFromFile.py @@ -6,13 +6,17 @@ # SPDX-License-Identifier: MPL-2.0 # This file is part of Grid2Op, Grid2Op a testbed platform to model sequential decision making in power systems. +import json import os import copy +from typing import Union import numpy as np import pandas as pd import warnings from datetime import datetime, timedelta +import grid2op +from grid2op.Exceptions import Grid2OpException from grid2op.dtypes import dt_int, dt_float, dt_bool from grid2op.Exceptions import ( IncorrectNumberOfElements, @@ -1225,3 +1229,33 @@ def split_and_save(self, datetime_beg, datetime_end, path_out): ) with open(os.path.join(path_out, "time_interval.info"), "w") as f: f.write("{:%H:%M}\n".format(tmp_for_time_delta)) + + def get_init_action(self) -> Union["grid2op.Action.playableAction.PlayableAction", None]: + from grid2op.Action import BaseAction + maybe_path = os.path.join(self.path, "init_state.json") + if not os.path.exists(maybe_path): + return None + if self.action_space is None: + raise Grid2OpException(f"We detected an action to set the intial state of the grid " + f"but we cannot build it because the 'action_space' of the time" + f"serie is not set.") + try: + with open(maybe_path, "r", encoding="utf-8") as f: + maybe_act_dict = json.load(f) + except Exception as exc_: + raise Grid2OpException(f"Invalid action provided to initialize the powergrid (not readable by json)." + f"Check file located at {maybe_path}") from exc_ + + try: + act : BaseAction = self.action_space(maybe_act_dict) + except Grid2OpException as exc_: + raise Grid2OpException(f"Impossible to build the action to set the grid. Please fix the " + f"file located at {maybe_path}.") from exc_ + + # TODO check change bus, redispatching, change status etc. + # TODO basically anything that would be suspicious here + error, reason = act.is_ambiguous() + if error: + raise Grid2OpException(f"The action to set the grid to its original configuration " + f"is ambiguous. Please check {maybe_path}") from reason + return act diff --git a/grid2op/Chronics/gridValue.py b/grid2op/Chronics/gridValue.py index 4e7bc9e2a..7b8edbf30 100644 --- a/grid2op/Chronics/gridValue.py +++ b/grid2op/Chronics/gridValue.py @@ -9,11 +9,12 @@ import warnings from datetime import datetime, timedelta from abc import ABC, abstractmethod +from typing import Union import grid2op from grid2op.dtypes import dt_int from grid2op.Space import RandomObject -from grid2op.Exceptions import EnvError +from grid2op.Exceptions import EnvError, Grid2OpException # TODO sous echantillonner ou sur echantilloner les scenario: need to modify everything that affect the number # TODO of time steps there, for example "Space.gen_min_time_on" or "params.NB_TIMESTEP_POWERFLOW_ALLOWED" for @@ -107,6 +108,23 @@ def __init__( self.maintenance_time = None self.maintenance_duration = None self.hazard_duration = None + + # complete action space set by the environment + self.__action_space : Union["grid2op.Action.SerializableActionSpace", None] = None + + @property + def action_space(self)-> Union["grid2op.Action.SerializableActionSpace", None]: + return self.__action_space + + @action_space.setter + def action_space(self, values): + from grid2op.Action import SerializableActionSpace + if not isinstance(values, SerializableActionSpace): + raise EnvError(f"Impossible to set the action space with a value of type {type(values)}") + if self.__action_space is not None: + raise EnvError(f"Impossible to change the action space once initialized.") + # TODO maybe raise a warning if the underlying action class is not CompleteAction + self.__action_space = values def get_kwargs(self, dict_): """ @@ -116,7 +134,7 @@ def get_kwargs(self, dict_): pass @property - def max_iter(self): + def max_iter(self) -> int: return self._max_iter @max_iter.setter @@ -131,7 +149,7 @@ def initialize( order_backend_lines, order_backend_subs, names_chronics_to_backend, - ): + ) -> None: """ This function is used to initialize the data generator. It can be use to load scenarios, or to initialize noise if scenarios are generated on the fly. It must also @@ -802,13 +820,13 @@ def fast_forward(self, nb_timestep): for _ in range(nb_timestep): self.load_next() - def get_init_action(self) -> "grid2op.Action.playableAction.PlayableAction": + def get_init_action(self) -> Union["grid2op.Action.playableAction.PlayableAction", None]: """ - .. versionadded 1.10.2 - It is used when the environment is reset (*ie* when :func:`grid2op.Environment.Environment.reset` is called) to set the grid in its "original" state. + .. versionadded 1.10.2 + Before grid2op 1.10.2 the original state is necessarily "everything connected together". For later version, we let the possibility to set, in the "time series folder" (or time series generators) diff --git a/grid2op/Chronics/handlers/__init__.py b/grid2op/Chronics/handlers/__init__.py index f665ea896..bbd51d7f6 100644 --- a/grid2op/Chronics/handlers/__init__.py +++ b/grid2op/Chronics/handlers/__init__.py @@ -16,6 +16,7 @@ "PerfectForecastHandler", "NoisyForecastHandler", "LoadQFromPHandler", + "JSONInitStateHandler" ] from .baseHandler import BaseHandler @@ -28,3 +29,4 @@ from .perfectForecastHandler import PerfectForecastHandler from .noisyForecastHandler import NoisyForecastHandler from .load_q_from_p_handler import LoadQFromPHandler +from .jsonInitStateHandler import JSONInitStateHandler diff --git a/grid2op/Chronics/handlers/baseHandler.py b/grid2op/Chronics/handlers/baseHandler.py index 6de083e78..8bcd24ce2 100644 --- a/grid2op/Chronics/handlers/baseHandler.py +++ b/grid2op/Chronics/handlers/baseHandler.py @@ -9,7 +9,8 @@ import copy import os import numpy as np -from typing import Optional, Tuple +from typing import Optional, Tuple, Union +import grid2op from grid2op.Space import RandomObject from datetime import timedelta, datetime @@ -341,7 +342,7 @@ def load_next(self, dict_: dict) -> Optional[np.ndarray]: """ raise NotImplementedError() - def check_validity(self, backend): + def check_validity(self, backend) -> None: """ INTERNAL @@ -479,3 +480,17 @@ def next_chronics(self) -> None: end of each episode when the next episode is loaded. """ return None + + def get_init_dict_action(self) -> Union[dict, None]: + """ + INTERNAL + + .. warning:: /!\\\\ Internal, do not use unless you know what you are doing /!\\\\ + + This function is called by the :class:`grid2op.Chronics.FromHandlers` only for the handlers responsible + for setting the "initial state" of the grid, for example :class:`JSONInitStateHandler`. + + If overidden, it is expected to return a dictionnary which can be converted to an action with an + action space. + """ + raise NotImplementedError() \ No newline at end of file diff --git a/grid2op/Chronics/handlers/csvForecastHandler.py b/grid2op/Chronics/handlers/csvForecastHandler.py index a8c8285d7..046ac8704 100644 --- a/grid2op/Chronics/handlers/csvForecastHandler.py +++ b/grid2op/Chronics/handlers/csvForecastHandler.py @@ -64,6 +64,8 @@ class CSVForecastHandler(CSVHandler): not for maintenance (in this case use :class:`CSVMaintenanceHandler`) nor for environment data (in this case use :class:`CSVHandler`) + nor for setting the initial state state (in this case use + :class:`JSONInitStateHandler`) This is the default way to provide data to grid2op and its used for most l2rpn environments when forecasts are available. diff --git a/grid2op/Chronics/handlers/csvHandler.py b/grid2op/Chronics/handlers/csvHandler.py index b1ef18765..ae16f8e89 100644 --- a/grid2op/Chronics/handlers/csvHandler.py +++ b/grid2op/Chronics/handlers/csvHandler.py @@ -52,6 +52,8 @@ class CSVHandler(BaseHandler): "prod_p" or "prod_v") and not for maintenance (in this case use :class:`CSVMaintenanceHandler`) nor for forecast (in this case use :class:`CSVForecastHandler`) + nor for setting the initial state state (in this case use + :class:`JSONInitStateHandler`) This is the default way to provide data to grid2op and its used for most l2rpn environments. diff --git a/grid2op/Chronics/handlers/csvMaintenanceHandler.py b/grid2op/Chronics/handlers/csvMaintenanceHandler.py index 2c47c510f..6efc3eea4 100644 --- a/grid2op/Chronics/handlers/csvMaintenanceHandler.py +++ b/grid2op/Chronics/handlers/csvMaintenanceHandler.py @@ -41,10 +41,11 @@ class CSVMaintenanceHandler(CSVHandler): no string etc. .. warning:: - Use this class only for the ENVIRONMENT data ("load_p", "load_q", - "prod_p" or "prod_v") and not for maintenance (in this case - use :class:`CSVMaintenanceHandler`) nor for + Use this class only for the MAINTENANCE and not for environment + data ("load_p", "load_q", "prod_p" or "prod_v") nor for forecast (in this case use :class:`CSVForecastHandler`) + nor for setting the initial state state (in this case use + :class:`JSONInitStateHandler`) This is the default way to provide data to grid2op and its used for most l2rpn environments. diff --git a/grid2op/Chronics/handlers/do_nothing_handler.py b/grid2op/Chronics/handlers/do_nothing_handler.py index bcfa98bdc..bd21c8ef0 100644 --- a/grid2op/Chronics/handlers/do_nothing_handler.py +++ b/grid2op/Chronics/handlers/do_nothing_handler.py @@ -6,6 +6,7 @@ # SPDX-License-Identifier: MPL-2.0 # This file is part of Grid2Op, Grid2Op a testbed platform to model sequential decision making in power systems. +from typing import Union from grid2op.Chronics.handlers.baseHandler import BaseHandler @@ -50,4 +51,6 @@ def load_next_maintenance(self): def load_next_hazard(self): return None - \ No newline at end of file + + def get_init_dict_action(self) -> Union[dict, None]: + return None \ No newline at end of file diff --git a/grid2op/Chronics/handlers/jsonInitStateHandler.py b/grid2op/Chronics/handlers/jsonInitStateHandler.py new file mode 100644 index 000000000..b7740746b --- /dev/null +++ b/grid2op/Chronics/handlers/jsonInitStateHandler.py @@ -0,0 +1,52 @@ +# Copyright (c) 2024, RTE (https://www.rte-france.com) +# See AUTHORS.txt +# This Source Code Form is subject to the terms of the Mozilla Public License, version 2.0. +# If a copy of the Mozilla Public License, version 2.0 was not distributed with this file, +# you can obtain one at http://mozilla.org/MPL/2.0/. +# SPDX-License-Identifier: MPL-2.0 +# This file is part of Grid2Op, Grid2Op a testbed platform to model sequential decision making in power systems. + +from typing import Union +import json +import os + +import grid2op +from grid2op.Exceptions import Grid2OpException +from grid2op.Chronics.handlers.baseHandler import BaseHandler + + +class JSONInitStateHandler(BaseHandler): + """Base class to initialize the grid state using a method in the time series. + + .. versionadded:: 1.10.2 + + This class will look for a file named "init_state.json" (located at `self.path`) which should be a valid + json file (you can load it with the `json` module) representing a valid + action on the grid. + + This action should preferably be using only the `set` (*eg* `set_bus` and `set_status`) + keyword arguments and set only the topology of the grid (and not the injection or + the redispatching.) + + If no "init_state.json" file is found, then nothing is done. + + """ + + def check_validity(self, backend) -> None: + """This type of handler is always valid.""" + pass + + def done(self) -> bool: + return False + + def get_init_dict_action(self) -> Union[dict, None]: + maybe_path = os.path.join(self.path, "init_state.json") + if not os.path.exists(maybe_path): + return None + try: + with open(maybe_path, "r", encoding="utf-8") as f: + maybe_act_dict = json.load(f) + except Exception as exc_: + raise Grid2OpException(f"Invalid action provided to initialize the powergrid (not readable by json)." + f"Check file located at {maybe_path}") from exc_ + return maybe_act_dict diff --git a/grid2op/Chronics/handlers/jsonMaintenanceHandler.py b/grid2op/Chronics/handlers/jsonMaintenanceHandler.py index 779c877ba..27d2eef7f 100644 --- a/grid2op/Chronics/handlers/jsonMaintenanceHandler.py +++ b/grid2op/Chronics/handlers/jsonMaintenanceHandler.py @@ -40,6 +40,13 @@ class JSONMaintenanceHandler(BaseHandler): - "max_daily_number_per_month_maintenance": maximum number of powerlines allowed in maintenance at the same time. + .. warning:: + Use this class only for the MAINTENANCE and not for environment + data ("load_p", "load_q", "prod_p" or "prod_v") nor for + forecast (in this case use :class:`CSVForecastHandler`) + nor for setting the initial state state (in this case use + :class:`JSONInitStateHandler`) + """ def __init__(self, array_name="maintenance", diff --git a/grid2op/Chronics/multiFolder.py b/grid2op/Chronics/multiFolder.py index 57b4bd3ac..87b95bafb 100644 --- a/grid2op/Chronics/multiFolder.py +++ b/grid2op/Chronics/multiFolder.py @@ -8,6 +8,7 @@ import os import json +from typing import Union import warnings import numpy as np from datetime import timedelta, datetime @@ -437,6 +438,8 @@ def initialize( order_backend_subs, names_chronics_to_backend=names_chronics_to_backend, ) + if self.action_space is not None: + self.data.action_space = self.action_space def done(self): """ @@ -777,3 +780,6 @@ def split_and_save(self, datetime_beg, datetime_end, path_out): def fast_forward(self, nb_timestep): self.data.fast_forward(nb_timestep) + + def get_init_action(self) -> Union["grid2op.Action.playableAction.PlayableAction", None]: + return self.data.get_init_action() diff --git a/grid2op/Chronics/multifolderWithCache.py b/grid2op/Chronics/multifolderWithCache.py index 02b0c5e46..6a6cc6362 100644 --- a/grid2op/Chronics/multifolderWithCache.py +++ b/grid2op/Chronics/multifolderWithCache.py @@ -200,6 +200,8 @@ def reset(self): ) self._cached_data[i] = data self.cache_size += 1 + if self.action_space is not None: + data.action_space = self.action_space if self.cache_size == 0: raise RuntimeError("Impossible to initialize the new cache.") diff --git a/grid2op/Chronics/time_series_from_handlers.py b/grid2op/Chronics/time_series_from_handlers.py index 2d4510685..521e254af 100644 --- a/grid2op/Chronics/time_series_from_handlers.py +++ b/grid2op/Chronics/time_series_from_handlers.py @@ -10,8 +10,9 @@ import os import numpy as np import copy -from typing import Optional +from typing import Optional, Union +import grid2op from grid2op.Exceptions import ( ChronicsNotFoundError, HandlerError ) @@ -19,6 +20,7 @@ from grid2op.Chronics.gridValue import GridValue from grid2op.Chronics.handlers import BaseHandler +from grid2op.Exceptions.grid2OpException import Grid2OpException from grid2op.dtypes import dt_int, dt_float @@ -131,6 +133,7 @@ def __init__( load_q_for_handler=None, gen_p_for_handler=None, gen_v_for_handler=None, + init_state_handler=None, time_interval=timedelta(minutes=5), sep=";", # here for compatibility with grid2op, but not used max_iter=-1, @@ -161,6 +164,7 @@ def __init__( self.gen_v_for_handler : Optional[BaseHandler] = copy.deepcopy(gen_v_for_handler) self.load_p_for_handler : Optional[BaseHandler] = copy.deepcopy(load_p_for_handler) self.load_q_for_handler : Optional[BaseHandler] = copy.deepcopy(load_q_for_handler) + self.init_state_handler : Optional[BaseHandler] = copy.deepcopy(init_state_handler) # when there are no maintenance / hazards, build this only once self._no_mh_time = None @@ -185,6 +189,8 @@ def __init__( if self.load_q_for_handler is not None: self._active_handlers.append(self.load_q_for_handler) self._forcast_handlers.append(self.load_q_for_handler) + if self.init_state_handler is not None: + self._active_handlers.append(self.init_state_handler) self._check_types() # now synch all handlers @@ -395,7 +401,7 @@ def init_datetime(self): def seed(self, seed): super().seed(seed) max_seed = np.iinfo(dt_int).max - seeds = self.space_prng.randint(max_seed, size=10) + seeds = self.space_prng.randint(max_seed, size=11) # this way of doing ensure the same seed given by the environment is # used even if some "handlers" are missing # (if env.seed(0) is called, then regardless of maintenance_handler or not, @@ -422,9 +428,12 @@ def seed(self, seed): gvf_seed = None if self.gen_v_for_handler is not None: gvf_seed = self.gen_v_for_handler.seed(seeds[9]) + init_state_seed = None + if self.init_state_handler is not None: + init_state_seed = self.init_state_handler.seed(seeds[10]) return (seed, gp_seed, gv_seed, lp_seed, lq_seed, maint_seed, haz_seed, gpf_seed, gvf_seed, - lpf_seed, lqf_seed) + lpf_seed, lqf_seed, init_state_seed) def _set_path(self, path): """tell the handler where this chronics is located""" @@ -521,3 +530,31 @@ def fast_forward(self, nb_timestep): self.load_next() # for this class I suppose the real data AND the forecast are read each step self.forecasts() + + def get_init_action(self) -> Union["grid2op.Action.playableAction.PlayableAction", None]: + from grid2op.Action import BaseAction + if self.init_state_handler is None: + return None + + act_as_dict = self.init_state_handler.get_init_dict_action() + if act_as_dict is None: + return None + + if self.action_space is None: + raise Grid2OpException(f"We detected an action to set the intial state of the grid " + f"but we cannot build it because the 'action_space' of the time" + f"serie is not set.") + + try: + act : BaseAction = self.action_space(act_as_dict) + except Grid2OpException as exc_: + raise Grid2OpException(f"Impossible to build the action to set the grid. Please fix the " + f"file located at {self.init_state_handler.path}.") from exc_ + + # TODO check change bus, redispatching, change status etc. + # TODO basically anything that would be suspicious here + error, reason = act.is_ambiguous() + if error: + raise Grid2OpException(f"The action to set the grid to its original configuration " + f"is ambiguous. Please check {self.init_state_handler.path}") from reason + return act diff --git a/grid2op/Environment/baseEnv.py b/grid2op/Environment/baseEnv.py index b687899c4..c5ccb5f6b 100644 --- a/grid2op/Environment/baseEnv.py +++ b/grid2op/Environment/baseEnv.py @@ -742,13 +742,19 @@ def _custom_deepcopy_for_copy(self, new_obj, dict_=None): new_obj._hazards = copy.deepcopy(self._hazards) new_obj._env_modification = copy.deepcopy(self._env_modification) + # action space used by the environment + new_obj._game_rules = copy.deepcopy(self._game_rules) + new_obj._helper_action_env = self._helper_action_env.copy() + new_obj._helper_action_env.legal_action = new_obj._game_rules.legal_action + # to use the data new_obj.done = self.done new_obj.current_reward = copy.deepcopy(self.current_reward) new_obj.chronics_handler = copy.deepcopy(self.chronics_handler) - new_obj._game_rules = copy.deepcopy(self._game_rules) - new_obj._helper_action_env = self._helper_action_env.copy() - new_obj._helper_action_env.legal_action = new_obj._game_rules.legal_action + # retrieve the "pointer" to the new_obj action space (for initializing the grid) + new_obj.chronics_handler._real_data._GridValue__action_space = None + new_obj.chronics_handler.action_space = new_obj._helper_action_env + # action space new_obj._action_space = self._action_space.copy() new_obj._action_space.legal_action = new_obj._game_rules.legal_action diff --git a/grid2op/Environment/environment.py b/grid2op/Environment/environment.py index 530d9de43..9e4283d74 100644 --- a/grid2op/Environment/environment.py +++ b/grid2op/Environment/environment.py @@ -379,6 +379,8 @@ def _init_backend( self.name_sub, names_chronics_to_backend=names_chronics_to_backend, ) + # new in grdi2op 1.10.2: used + self.chronics_handler.action_space = self._helper_action_env self._names_chronics_to_backend = names_chronics_to_backend self.delta_time_seconds = dt_float(self.chronics_handler.time_interval.seconds) @@ -1799,7 +1801,7 @@ def init_obj_from_kwargs(cls, observation_bk_kwargs, _raw_backend_class, _read_from_local_dir, - n_busbar=DEFAULT_N_BUSBAR_PER_SUB): + n_busbar=DEFAULT_N_BUSBAR_PER_SUB): res = cls(init_env_path=init_env_path, init_grid_path=init_grid_path, chronics_handler=chronics_handler, diff --git a/grid2op/Runner/aux_fun.py b/grid2op/Runner/aux_fun.py index db8b4ba68..bfaba142b 100644 --- a/grid2op/Runner/aux_fun.py +++ b/grid2op/Runner/aux_fun.py @@ -48,19 +48,18 @@ def _aux_one_process_parrallel( add_nb_highres_sim=False, ): """this is out of the runner, otherwise it does not work on windows / macos""" - chronics_handler = ChronicsHandler( - chronicsClass=runner.gridStateclass, - path=runner.path_chron, - **runner.gridStateclass_kwargs - ) + # chronics_handler = ChronicsHandler( + # chronicsClass=runner.gridStateclass, + # path=runner.path_chron, + # **runner.gridStateclass_kwargs + # ) parameters = copy.deepcopy(runner.parameters) nb_episode_this_process = len(episode_this_process) res = [(None, None, None) for _ in range(nb_episode_this_process)] for i, ep_id in enumerate(episode_this_process): # `ep_id`: grid2op id of the episode i want to play # `i`: my id of the episode played (0, 1, ... episode_this_process) - env, agent = runner._new_env( - chronics_handler=chronics_handler, parameters=parameters + env, agent = runner._new_env(parameters=parameters ) try: env_seed = None @@ -82,7 +81,7 @@ def _aux_one_process_parrallel( use_compact_episode_data=runner.use_compact_episode_data, ) (name_chron, cum_reward, nb_time_step, max_ts, episode_data, nb_highres_sim) = tmp_ - id_chron = chronics_handler.get_id() + id_chron = env.chronics_handler.get_id() res[i] = (id_chron, name_chron, float(cum_reward), nb_time_step, max_ts) if add_detailed_output: diff --git a/grid2op/Runner/runner.py b/grid2op/Runner/runner.py index 21d2f3f8d..f0c0e9cec 100644 --- a/grid2op/Runner/runner.py +++ b/grid2op/Runner/runner.py @@ -538,11 +538,11 @@ def __init__( self.max_iter = max_iter if max_iter > 0: self.gridStateclass_kwargs["max_iter"] = max_iter - self.chronics_handler = ChronicsHandler( - chronicsClass=self.gridStateclass, - path=self.path_chron, - **self.gridStateclass_kwargs - ) + # self.chronics_handler = ChronicsHandler( + # chronicsClass=self.gridStateclass, + # path=self.path_chron, + # **self.gridStateclass_kwargs + # ) self.verbose = verbose self.thermal_limit_a = thermal_limit_a @@ -634,12 +634,18 @@ def _make_new_backend(self): res = self.backendClass(**this_kwargs) return res - def _new_env(self, chronics_handler, parameters) -> Tuple[BaseEnv, BaseAgent]: + def _new_env(self, parameters) -> Tuple[BaseEnv, BaseAgent]: # the same chronics_handler is used for all the environments. # make sure to "reset" it properly # (this is handled elsewhere in case of "multi chronics") - if not self.chronics_handler.chronicsClass.MULTI_CHRONICS: - self.chronics_handler.next_chronics() + # ch_used = copy.deepcopy(chronics_handler) + # if not ch_used.chronicsClass.MULTI_CHRONICS: + # ch_used.next_chronics() + chronics_handler = ChronicsHandler( + chronicsClass=self.gridStateclass, + path=self.path_chron, + **self.gridStateclass_kwargs + ) backend = self._make_new_backend() with warnings.catch_warnings(): warnings.filterwarnings("ignore") @@ -704,7 +710,7 @@ def init_env(self) -> BaseEnv: Function used to initialized the environment and the agent. It is called by :func:`Runner.reset`. """ - env, self.agent = self._new_env(self.chronics_handler, self.parameters) + env, self.agent = self._new_env(self.parameters) return env def reset(self): @@ -781,12 +787,16 @@ def run_one_episode( ) if max_iter is not None: env.chronics_handler.set_max_iter(-1) - + + id_chron = env.chronics_handler.get_id() # `res` here necessarily contains detailed_output and nb_highres_call if not add_nb_highres_sim: res = res[:-1] if not detailed_output: res = res[:-1] + + # new in 1.10.2: id_chron is computed from here + res = (id_chron, *res) return res def _run_sequential( @@ -869,6 +879,7 @@ def _run_sequential( if episode_id is not None: ep_id = episode_id[i] # otherwise i use the provided one ( + id_chron, name_chron, cum_reward, nb_time_step, @@ -885,7 +896,6 @@ def _run_sequential( detailed_output=True, add_nb_highres_sim=True ) - id_chron = self.chronics_handler.get_id() res[i] = (id_chron, name_chron, float(cum_reward), diff --git a/grid2op/__init__.py b/grid2op/__init__.py index d42010787..c2dac6cad 100644 --- a/grid2op/__init__.py +++ b/grid2op/__init__.py @@ -11,7 +11,7 @@ Grid2Op """ -__version__ = '1.10.2.dev1' +__version__ = '1.10.2.dev2' __all__ = [ "Action", diff --git a/grid2op/tests/test_Action_iadd.py b/grid2op/tests/test_Action_iadd.py index 10f203cab..1de5fe8fa 100644 --- a/grid2op/tests/test_Action_iadd.py +++ b/grid2op/tests/test_Action_iadd.py @@ -1,3 +1,12 @@ +# Copyright (c) 2024, RTE (https://www.rte-france.com) +# See AUTHORS.txt +# This Source Code Form is subject to the terms of the Mozilla Public License, version 2.0. +# If a copy of the Mozilla Public License, version 2.0 was not distributed with this file, +# you can obtain one at http://mozilla.org/MPL/2.0/. +# SPDX-License-Identifier: MPL-2.0 +# This file is part of Grid2Op, Grid2Op a testbed platform to model sequential decision making in power systems. + + import unittest import warnings from abc import ABC, abstractmethod diff --git a/grid2op/tests/test_EpisodeData.py b/grid2op/tests/test_EpisodeData.py index 15f231979..1b1e29535 100644 --- a/grid2op/tests/test_EpisodeData.py +++ b/grid2op/tests/test_EpisodeData.py @@ -143,6 +143,7 @@ def act(self, observation, reward, done=False): def test_one_episode_with_saving(self): f = tempfile.mkdtemp() ( + ep_id, episode_name, cum_reward, timestep, @@ -176,7 +177,7 @@ def test_collection_wrapper_after_run(self): name_env="test_episodedata_env", agentClass=OneChange, ) - _, cum_reward, timestep, max_ts, episode_data = runner.run_one_episode( + _, _, cum_reward, timestep, max_ts, episode_data = runner.run_one_episode( max_iter=self.max_iter, detailed_output=True ) # Check that the type of first action is set bus @@ -186,6 +187,7 @@ def test_len(self): """test i can use the function "len" of the episode data""" f = tempfile.mkdtemp() ( + ep_id, episode_name, cum_reward, timestep, diff --git a/grid2op/tests/test_Runner.py b/grid2op/tests/test_Runner.py index 6ce3d6ffe..71446f2ba 100644 --- a/grid2op/tests/test_Runner.py +++ b/grid2op/tests/test_Runner.py @@ -401,9 +401,8 @@ def test_nomaxiter(self): with warnings.catch_warnings(): warnings.filterwarnings("ignore") with grid2op.make("rte_case14_test", test=True, _add_to_name=type(self).__name__) as env: + env.set_max_iter(2 * self.max_iter) runner = Runner(**env.get_params_for_runner()) - runner.gridStateclass_kwargs["max_iter"] = 2 * self.max_iter - runner.chronics_handler.set_max_iter(2 * self.max_iter) res = runner.run(nb_episode=1) for i, _, cum_reward, timestep, total_ts in res: assert int(timestep) == 2 * self.max_iter diff --git a/grid2op/tests/test_RunnerFast.py b/grid2op/tests/test_RunnerFast.py index 1da9d05f4..e69de29bb 100644 --- a/grid2op/tests/test_RunnerFast.py +++ b/grid2op/tests/test_RunnerFast.py @@ -1,125 +0,0 @@ -# Copyright (c) 2019-2020, RTE (https://www.rte-france.com) -# See AUTHORS.txt -# This Source Code Form is subject to the terms of the Mozilla Public License, version 2.0. -# If a copy of the Mozilla Public License, version 2.0 was not distributed with this file, -# you can obtain one at http://mozilla.org/MPL/2.0/. -# SPDX-License-Identifier: MPL-2.0 -# This file is part of Grid2Op, Grid2Op a testbed platform to model sequential decision making in power systems. - -import warnings -import unittest - -from grid2op.tests.helper_path_test import * - -PATH_ADN_CHRONICS_FOLDER = os.path.abspath( - os.path.join(PATH_CHRONICS, "test_multi_chronics") -) -PATH_PREVIOUS_RUNNER = os.path.join(data_test_dir, "runner_data") - -import grid2op -from grid2op.Runner import Runner -from grid2op.dtypes import dt_float - -warnings.simplefilter("error") - - -class TestRunner(HelperTests, unittest.TestCase): - def setUp(self): - super().setUp() - self.init_grid_path = os.path.join(PATH_DATA_TEST_PP, "test_case14.json") - self.path_chron = PATH_ADN_CHRONICS_FOLDER - self.parameters_path = None - self.max_iter = 10 - self.real_reward = dt_float(7748.425 / 12.) - self.real_reward_li = [self.real_reward, dt_float(7786.8955 / 12.)] # 7786.89599609375 - - self.all_real_rewards = [ - dt_float(el / 12.) - for el in [ - 761.3295, - 768.10144, - 770.2673, - 767.767, - 768.69, - 768.71246, - 779.1029, - 783.2737, - 788.7833, - 792.39764, - ] - ] - with warnings.catch_warnings(): - warnings.filterwarnings("ignore") - self.env = grid2op.make("l2rpn_case14_sandbox", test=True, _add_to_name=type(self).__name__) - self.runner = Runner(**self.env.get_params_for_runner()) - - def test_one_episode(self): - with warnings.catch_warnings(): - warnings.filterwarnings("ignore") - _, cum_reward, timestep, max_ts = self.runner.run_one_episode( - max_iter=self.max_iter - ) - assert int(timestep) == self.max_iter - assert np.abs(cum_reward - self.real_reward) <= self.tol_one, f"{cum_reward} != {self.real_reward}" - - def test_one_episode_detailed(self): - with warnings.catch_warnings(): - warnings.filterwarnings("ignore") - _, cum_reward, timestep, max_ts, episode_data = self.runner.run_one_episode( - max_iter=self.max_iter, detailed_output=True - ) - assert int(timestep) == self.max_iter - assert np.abs(cum_reward - self.real_reward) <= self.tol_one - for j in range(len(self.all_real_rewards)): - assert ( - np.abs(episode_data.rewards[j] - self.all_real_rewards[j]) - <= self.tol_one - ), f"{episode_data.rewards[j]} != {self.all_real_rewards[j]}" - - def test_2episode(self): - with warnings.catch_warnings(): - warnings.filterwarnings("ignore") - res = self.runner._run_sequential(nb_episode=2, max_iter=self.max_iter) - assert len(res) == 2 - for i, (stuff, _, cum_reward, timestep, total_ts) in enumerate(res): - assert int(timestep) == self.max_iter - assert np.abs(cum_reward - self.real_reward_li[i]) <= self.tol_one, f"for iter {i}: {cum_reward} != {self.real_reward_li[i]}" - - def test_init_from_env(self): - with warnings.catch_warnings(): - warnings.filterwarnings("ignore") - with grid2op.make("rte_case14_test", test=True, _add_to_name=type(self).__name__) as env: - runner = Runner(**env.get_params_for_runner()) - res = runner.run(nb_episode=1, max_iter=self.max_iter) - for i, _, cum_reward, timestep, total_ts in res: - assert int(timestep) == self.max_iter, f"{timestep} != {self.max_iter}" - - def test_seed_seq(self): - with warnings.catch_warnings(): - warnings.filterwarnings("ignore") - with grid2op.make("rte_case14_test", test=True, _add_to_name=type(self).__name__) as env: - runner = Runner(**env.get_params_for_runner()) - res = runner.run( - nb_episode=1, max_iter=self.max_iter, env_seeds=[1], agent_seeds=[2] - ) - for i, _, cum_reward, timestep, total_ts in res: - assert int(timestep) == self.max_iter, f"{timestep} != {self.max_iter}" - - def test_seed_par(self): - with warnings.catch_warnings(): - warnings.filterwarnings("ignore") - with grid2op.make("rte_case14_test", test=True, _add_to_name=type(self).__name__) as env: - runner = Runner(**env.get_params_for_runner()) - res = runner.run( - nb_episode=2, - nb_process=2, - max_iter=self.max_iter, - env_seeds=[1, 2], - agent_seeds=[3, 4], - ) - for i, _, cum_reward, timestep, total_ts in res: - assert int(timestep) == self.max_iter - - -if __name__ == "__main__": - unittest.main() diff --git a/grid2op/tests/test_action_set_orig_state.py b/grid2op/tests/test_action_set_orig_state.py new file mode 100644 index 000000000..8e8996676 --- /dev/null +++ b/grid2op/tests/test_action_set_orig_state.py @@ -0,0 +1,313 @@ +# Copyright (c) 2019-2020, RTE (https://www.rte-france.com) +# See AUTHORS.txt +# This Source Code Form is subject to the terms of the Mozilla Public License, version 2.0. +# If a copy of the Mozilla Public License, version 2.0 was not distributed with this file, +# you can obtain one at http://mozilla.org/MPL/2.0/. +# SPDX-License-Identifier: MPL-2.0 +# This file is part of Grid2Op, Grid2Op a testbed platform to model sequential decision making in power systems. + + +import tempfile +import numpy as np +import warnings +import unittest + +import grid2op +from grid2op.Episode import EpisodeData +from grid2op.Opponent import FromEpisodeDataOpponent +from grid2op.Runner import Runner +from grid2op.Action import TopologyAction, DispatchAction +from grid2op.tests.helper_path_test import * +from grid2op.Chronics import (FromHandlers, + Multifolder, + MultifolderWithCache, + GridStateFromFileWithForecasts, + GridStateFromFile, + GridStateFromFileWithForecastsWithMaintenance, + GridStateFromFileWithForecastsWithoutMaintenance, + FromOneEpisodeData, + FromMultiEpisodeData, + FromNPY) +from grid2op.Chronics.handlers import CSVHandler, JSONInitStateHandler + +# TODO test forecast env +# TODO test with and without shunt +# TODO test grid2Op compat mode (storage units) +# TODO test with "names_orig_to_backend" +# TODO test with lightsimbackend +# TODO test with Runner +# TODO test other type of environment (multimix, masked etc.) + + +class TestSetActOrigDefault(unittest.TestCase): + def _get_act_cls(self): + return TopologyAction + + def _get_ch_cls(self): + return Multifolder + + def _get_c_cls(self): + return GridStateFromFileWithForecasts + + def _env_path(self): + return os.path.join( + PATH_DATA_TEST, "5bus_example_act_topo_set_init" + ) + + def setUp(self) -> None: + self.env_nm = self._env_path() + with warnings.catch_warnings(): + warnings.filterwarnings("ignore") + self.env = grid2op.make(self.env_nm, + test=True, + action_class=self._get_act_cls(), + chronics_class=self._get_ch_cls(), + data_feeding_kwargs={"gridvalueClass": self._get_c_cls()} + ) + if issubclass(self._get_ch_cls(), MultifolderWithCache): + self.env.chronics_handler.set_filter(lambda x: True) + self.env.chronics_handler.reset() + # some test to make sure the tests are correct + assert issubclass(self.env.action_space.subtype, self._get_act_cls()) + assert isinstance(self.env.chronics_handler.real_data, self._get_ch_cls()) + assert isinstance(self.env.chronics_handler.real_data.data, self._get_c_cls()) + + def tearDown(self) -> None: + self.env.close() + return super().tearDown() + + def test_working_setbus(self): + # ts id 0 => set_bus + self.obs = self.env.reset(seed=0, options={"time serie id": 0}) + + assert self.obs.topo_vect[self.obs.line_or_pos_topo_vect[1]] == 2 + assert self.obs.topo_vect[self.obs.load_pos_topo_vect[0]] == 2 + assert (self.obs.time_before_cooldown_line == 0).all() + assert (self.obs.time_before_cooldown_sub == 0).all() + obs, reward, done, info = self.env.step(self.env.action_space()) + assert not done + assert obs.topo_vect[self.obs.line_or_pos_topo_vect[1]] == 2 + assert obs.topo_vect[self.obs.load_pos_topo_vect[0]] == 2 + assert (obs.time_before_cooldown_line == 0).all() + assert (obs.time_before_cooldown_sub == 0).all() + + + def test_working_setstatus(self): + # ts id 1 => set_status + self.obs = self.env.reset(seed=0, options={"time serie id": 1}) + + assert self.obs.topo_vect[self.obs.line_or_pos_topo_vect[1]] == -1 + assert self.obs.topo_vect[self.obs.line_ex_pos_topo_vect[1]] == -1 + assert not self.obs.line_status[1] + assert (self.obs.time_before_cooldown_line == 0).all() + assert (self.obs.time_before_cooldown_sub == 0).all() + obs, reward, done, info = self.env.step(self.env.action_space()) + assert not done + assert obs.topo_vect[self.obs.line_or_pos_topo_vect[1]] == -1 + assert obs.topo_vect[self.obs.line_ex_pos_topo_vect[1]] == -1 + assert not obs.line_status[1] + assert (obs.time_before_cooldown_line == 0).all() + assert (obs.time_before_cooldown_sub == 0).all() + + def test_rules_ok(self): + """test that even if the action to set is illegal, it works (case of ts id 2)""" + self.obs = self.env.reset(seed=0, options={"time serie id": 2}) + + assert self.obs.topo_vect[self.obs.line_or_pos_topo_vect[1]] == 2 + assert self.obs.topo_vect[self.obs.line_ex_pos_topo_vect[5]] == 2 + assert (self.obs.time_before_cooldown_line == 0).all() + assert (self.obs.time_before_cooldown_sub == 0).all() + act_init = self.env.chronics_handler.get_init_action() + obs, reward, done, info = self.env.step(act_init) + assert info["exception"] is not None + assert info["is_illegal"] + assert obs.topo_vect[self.obs.line_or_pos_topo_vect[1]] == 2 + assert obs.topo_vect[self.obs.line_ex_pos_topo_vect[5]] == 2 + assert (obs.time_before_cooldown_line == 0).all() + assert (obs.time_before_cooldown_sub == 0).all() + + +class TestSetActOrigDifferentActionCLS(TestSetActOrigDefault): + def _get_act_cls(self): + return DispatchAction + + +class TestSetAcOrigtMultiFolderWithCache(TestSetActOrigDefault): + def _get_ch_cls(self): + return MultifolderWithCache + + def test_two_reset_same(self): + """test it does not crash when the same time series is used twice""" + self.test_working_setstatus() + obs, reward, done, info = self.env.step(self.env.action_space()) + self.test_working_setstatus() + obs, reward, done, info = self.env.step(self.env.action_space()) + + +class TestSetActOrigGridStateFromFile(TestSetActOrigDefault): + def _get_c_cls(self): + return GridStateFromFile + + +class TestSetActOrigGSFFWFWM(TestSetActOrigDefault): + def _get_c_cls(self): + return GridStateFromFileWithForecastsWithMaintenance + + +class TestSetActOrigGSFFWFWoM(TestSetActOrigDefault): + def _get_c_cls(self): + return GridStateFromFileWithForecastsWithoutMaintenance + + +class TestSetActOrigFromOneEpisodeData(TestSetActOrigDefault): + def _aux_make_ep_data(self, ep_id): + runner = Runner(**self.env.get_params_for_runner()) + runner.run(nb_episode=1, + episode_id=[ep_id], + path_save=self.fn.name, + max_iter=10) + self.env.close() + + li_episode = EpisodeData.list_episode(self.fn.name) + ep_data = li_episode[0] + with warnings.catch_warnings(): + warnings.filterwarnings("ignore") + self.env = grid2op.make(self._env_path(), + chronics_class=FromOneEpisodeData, + data_feeding_kwargs={"ep_data": ep_data}, + opponent_class=FromEpisodeDataOpponent, + opponent_attack_cooldown=1, + ) + + def setUp(self) -> None: + self.fn = tempfile.TemporaryDirectory() + super().setUp() + + def tearDown(self) -> None: + self.fn.cleanup() + return super().tearDown() + + def test_working_setbus(self): + self._aux_make_ep_data(0) # episode id 0 is used for this test + with warnings.catch_warnings(): + warnings.filterwarnings("ignore") + super().test_working_setbus() + + def test_working_setstatus(self): + self._aux_make_ep_data(1) # episode id 1 is used for this test + with warnings.catch_warnings(): + warnings.filterwarnings("ignore") + super().test_working_setstatus() + + def test_rules_ok(self): + self._aux_make_ep_data(2) # episode id 2 is used for this test + with warnings.catch_warnings(): + warnings.filterwarnings("ignore") + super().test_rules_ok() + + +class TestSetActOrigFromMultiEpisodeData(TestSetActOrigDefault): + def setUp(self) -> None: + super().setUp() + self.fn = tempfile.TemporaryDirectory() + runner = Runner(**self.env.get_params_for_runner()) + runner.run(nb_episode=3, + episode_id=[0, 1, 2], + path_save=self.fn.name, + max_iter=10) + self.env.close() + + li_episode = EpisodeData.list_episode(self.fn.name) + with warnings.catch_warnings(): + warnings.filterwarnings("ignore") + self.env = grid2op.make(self._env_path(), + chronics_class=FromMultiEpisodeData, + data_feeding_kwargs={"li_ep_data": li_episode}, + opponent_class=FromEpisodeDataOpponent, + opponent_attack_cooldown=1, + ) + + + def tearDown(self) -> None: + self.fn.cleanup() + return super().tearDown() + + def test_two_reset_same(self): + """test it does not crash when the same time series is used twice""" + self.test_working_setstatus() + obs, reward, done, info = self.env.step(self.env.action_space()) + self.test_working_setstatus() + obs, reward, done, info = self.env.step(self.env.action_space()) + + +class TestSetActOrigFromNPY(TestSetActOrigDefault): + def _aux_make_env(self, ch_id): + self.obs = self.env.reset(seed=0, options={"time serie id": ch_id}) + load_p = 1.0 * self.env.chronics_handler._real_data.data.load_p[:self.max_iter,:] + load_q = 1.0 * self.env.chronics_handler._real_data.data.load_q[:self.max_iter,:] + gen_p = 1.0 * self.env.chronics_handler._real_data.data.prod_p[:self.max_iter,:] + gen_v = np.repeat(self.obs.gen_v.reshape(1, -1), self.max_iter, axis=0) + act = self.env.action_space({"set_bus": self.obs.topo_vect}) + self.env.close() + + with warnings.catch_warnings(): + warnings.filterwarnings("ignore") + self.env = grid2op.make(self._env_path(), + chronics_class=FromNPY, + data_feeding_kwargs={"load_p": load_p, + "load_q": load_q, + "prod_p": gen_p, + "prod_v": gen_v, + "init_state": act + }) + def setUp(self) -> None: + self.max_iter = 5 + super().setUp() + + def tearDown(self) -> None: + return super().tearDown() + + def test_working_setbus(self): + self._aux_make_env(0) # episode id 0 is used for this test + with warnings.catch_warnings(): + warnings.filterwarnings("ignore") + super().test_working_setbus() + + def test_working_setstatus(self): + self._aux_make_env(1) # episode id 1 is used for this test + with warnings.catch_warnings(): + warnings.filterwarnings("ignore") + super().test_working_setstatus() + + def test_rules_ok(self): + self._aux_make_env(2) # episode id 2 is used for this test + with warnings.catch_warnings(): + warnings.filterwarnings("ignore") + super().test_rules_ok() + + +class TestSetActOrigEnvCopy(TestSetActOrigDefault): + def setUp(self) -> None: + super().setUp() + env_cpy = self.env.copy() + self.env.close() + self.env = env_cpy + + +class TestSetActOrigFromHandlers(TestSetActOrigDefault): + def setUp(self) -> None: + with warnings.catch_warnings(): + warnings.filterwarnings("ignore") + self.env = grid2op.make(self._env_path(), + data_feeding_kwargs={"gridvalueClass": FromHandlers, + "gen_p_handler": CSVHandler("prod_p"), + "load_p_handler": CSVHandler("load_p"), + "gen_v_handler": CSVHandler("prod_v"), + "load_q_handler": CSVHandler("load_q"), + "init_state_handler": JSONInitStateHandler("init_state_handler") + } + ) + + +if __name__ == "__main__": + unittest.main() diff --git a/grid2op/tests/test_alert_trust_score.py b/grid2op/tests/test_alert_trust_score.py index 58a18e48d..32e0494f1 100644 --- a/grid2op/tests/test_alert_trust_score.py +++ b/grid2op/tests/test_alert_trust_score.py @@ -14,7 +14,7 @@ from grid2op.Observation import BaseObservation from grid2op.tests.helper_path_test import * -from grid2op import make +import grid2op from grid2op.Reward import _AlertTrustScore from grid2op.Parameters import Parameters from grid2op.Exceptions import Grid2OpException @@ -68,7 +68,7 @@ def test_assistant_trust_score_no_blackout_no_attack_no_alert(self) -> None : Raises: Grid2OpException: raise an exception if an attack occur """ - with make( + with grid2op.make( self.env_nm, test=True, difficulty="1", @@ -111,7 +111,7 @@ def test_assistant_trust_score_no_blackout_attack_alert(self) -> None : kwargs_opponent = dict(lines_attacked=[ATTACKED_LINE], duration=3, steps_attack=[2]) - with make(self.env_nm, + with grid2op.make(self.env_nm, test=True, difficulty="1", opponent_attack_cooldown=0, @@ -173,7 +173,7 @@ def test_assistant_trust_score_no_blackout_2_attack_same_time_1_alert(self) -> N kwargs_opponent = dict(lines_attacked=[ATTACKED_LINE] + ['48_53_141'], duration=3, steps_attack=[2]) - with make(self.env_nm, + with grid2op.make(self.env_nm, test=True, difficulty="1", reward_class=_AlertTrustScore(**DEFAULT_PARAMS_TRUSTSCORE), @@ -237,7 +237,7 @@ def test_assistant_trust_score_no_blackout_no_attack_alert(self) -> None: Raises: Grid2OpException: raise an exception if an attack occur """ - with make( + with grid2op.make( self.env_nm, test=True, difficulty="1", @@ -289,7 +289,7 @@ def test_assistant_trust_score_no_blackout_attack_no_alert(self) -> None: kwargs_opponent = dict(lines_attacked=[ATTACKED_LINE], duration=3, steps_attack=[1]) - with make(self.env_nm, + with grid2op.make(self.env_nm, test=True, difficulty="1", opponent_attack_cooldown=0, @@ -342,7 +342,7 @@ def test_assistant_trust_score_no_blackout_attack_alert_too_late(self) -> None : kwargs_opponent = dict(lines_attacked=[ATTACKED_LINE], duration=3, steps_attack=[2]) - with make(self.env_nm, + with grid2op.make(self.env_nm, test=True, difficulty="1", reward_class=_AlertTrustScore(**DEFAULT_PARAMS_TRUSTSCORE), @@ -398,7 +398,7 @@ def test_assistant_trust_score_no_blackout_attack_alert_too_early(self)-> None : kwargs_opponent = dict(lines_attacked=[ATTACKED_LINE], duration=3, steps_attack=[2]) - with make(self.env_nm, + with grid2op.make(self.env_nm, test=True, difficulty="1", reward_class=_AlertTrustScore(**DEFAULT_PARAMS_TRUSTSCORE), @@ -458,7 +458,7 @@ def test_assistant_trust_score_no_blackout_2_attack_same_time_no_alert(self) -> kwargs_opponent = dict(lines_attacked=[ATTACKED_LINE]+['48_53_141'], duration=3, steps_attack=[1]) - with make(self.env_nm, + with grid2op.make(self.env_nm, test=True, difficulty="1", opponent_attack_cooldown=0, @@ -512,7 +512,7 @@ def test_assistant_trust_score_no_blackout_2_attack_same_time_2_alert(self) -> N kwargs_opponent = dict(lines_attacked=[ATTACKED_LINE]+['48_53_141'], duration=3, steps_attack=[2]) - with make(self.env_nm, + with grid2op.make(self.env_nm, test=True, difficulty="1", reward_class=_AlertTrustScore(**DEFAULT_PARAMS_TRUSTSCORE), @@ -575,7 +575,7 @@ def test_assistant_trust_score_no_blackout_2_attack_diff_time_no_alert(self) -> kwargs_opponent = dict(lines_attacked=[ATTACKED_LINE]+['48_53_141'], duration=[1, 1], steps_attack=[1, 2]) - with make(self.env_nm, + with grid2op.make(self.env_nm, test=True, difficulty="1", opponent_attack_cooldown=0, @@ -629,7 +629,7 @@ def test_assistant_trust_score_no_blackout_2_attack_diff_time_2_alert(self) -> N kwargs_opponent = dict(lines_attacked=[ATTACKED_LINE]+['48_53_141'], duration=[1,1], steps_attack=[2, 3]) - with make(self.env_nm, + with grid2op.make(self.env_nm, test=True, difficulty="1", opponent_attack_cooldown=0, @@ -693,7 +693,7 @@ def test_assistant_trust_score_no_blackout_2_attack_diff_time_alert_first_attack kwargs_opponent = dict(lines_attacked=[ATTACKED_LINE]+['48_53_141'], duration=[1,1], steps_attack=[2, 3]) - with make(self.env_nm, + with grid2op.make(self.env_nm, test=True, difficulty="1", opponent_attack_cooldown=0, @@ -760,7 +760,7 @@ def test_assistant_trust_score_no_blackout_2_attack_diff_time_alert_second_attac kwargs_opponent = dict(lines_attacked=[ATTACKED_LINE]+['48_53_141'], duration=[1,1], steps_attack=[2, 3]) - with make(self.env_nm, + with grid2op.make(self.env_nm, test=True, difficulty="1", opponent_attack_cooldown=0, @@ -842,7 +842,7 @@ def test_assistant_trust_score_blackout_attack_nocause_blackout_no_alert(self) - kwargs_opponent = dict(lines_attacked=[ATTACKED_LINE], duration=3, steps_attack=[3]) - with make(self.env_nm, + with grid2op.make(self.env_nm, test=True, difficulty="1", opponent_attack_cooldown=0, @@ -904,7 +904,7 @@ def test_assistant_trust_score_blackout_attack_nocause_blackout_raise_alert(self kwargs_opponent = dict(lines_attacked=[ATTACKED_LINE], duration=3, steps_attack=[3]) - with make(self.env_nm, + with grid2op.make(self.env_nm, test=True, difficulty="1", opponent_attack_cooldown=0, @@ -966,7 +966,7 @@ def test_assistant_trust_score_blackout_no_attack_alert(self) -> None: """Even if there is a blackout, an we raise an alert we expect a score of 0 because there is no attack and we don't finish the scenario""" - with make( + with grid2op.make( self.env_nm, test=True, difficulty="1", @@ -1012,7 +1012,7 @@ def test_assistant_trust_score_blackout_no_attack_alert(self) -> None: def test_assistant_trust_score_blackout_no_attack_no_alert(self) -> None: """Even if there is a blackout, an we don't raise an alert we expect a score of 0 because there is no attack and we don't finish the scenario""" - with make( + with grid2op.make( self.env_nm, test=True, difficulty="1", @@ -1056,7 +1056,7 @@ def test_assistant_trust_score_blackout_no_attack_no_alert(self) -> None: def test_assistant_trust_score_blackout_no_attack_before_window_alert(self) -> None: """Even if there is a blackout, an we raise an alert too early we expect a score of 0 because there is no attack and we don't finish the scenario""" - with make( + with grid2op.make( self.env_nm, test=True, difficulty="1", @@ -1102,7 +1102,7 @@ def test_assistant_trust_score_blackout_no_attack_before_window_alert(self) -> N def test_assistant_trust_score_blackout_no_attack_before_window_no_alert(self) -> None: """Even if there is a blackout, an we raise an alert too late we expect a score of 0 because there is no attack and we don't finish the scenario""" - with make( + with grid2op.make( self.env_nm, test=True, difficulty="1", @@ -1174,7 +1174,7 @@ def test_assistant_trust_score_blackout_attack_raise_good_alert(self) -> None : kwargs_opponent = dict(lines_attacked=[ATTACKED_LINE], duration=3, steps_attack=[3]) - with make(self.env_nm, + with grid2op.make(self.env_nm, test=True, difficulty="1", opponent_attack_cooldown=0, @@ -1239,7 +1239,7 @@ def test_assistant_trust_score_blackout_attack_raise_alert_just_before_blackout( kwargs_opponent = dict(lines_attacked=[ATTACKED_LINE], duration=3, steps_attack=[3]) - with make(self.env_nm, + with grid2op.make(self.env_nm, test=True, difficulty="1", opponent_attack_cooldown=0, @@ -1304,7 +1304,7 @@ def test_assistant_trust_score_blackout_2_lines_attacked_simulaneous_only_1_aler kwargs_opponent = dict(lines_attacked=[ATTACKED_LINE] + ['48_53_141'], duration=3, steps_attack=[3, 3]) - with make(self.env_nm, + with grid2op.make(self.env_nm, test=True, difficulty="1", reward_class=_AlertTrustScore(**DEFAULT_PARAMS_TRUSTSCORE), @@ -1376,7 +1376,7 @@ def test_assistant_trust_score_blackout_attack_no_alert(self) -> None: kwargs_opponent = dict(lines_attacked=[ATTACKED_LINE], duration=3, steps_attack=[3]) - with make(self.env_nm, + with grid2op.make(self.env_nm, test=True, difficulty="1", opponent_attack_cooldown=0, @@ -1437,7 +1437,7 @@ def test_assistant_trust_score_blackout_attack_raise_alert_too_early(self) -> No kwargs_opponent = dict(lines_attacked=[ATTACKED_LINE], duration=3, steps_attack=[3]) - with make(self.env_nm, + with grid2op.make(self.env_nm, test=True, difficulty="1", opponent_attack_cooldown=0, @@ -1502,7 +1502,7 @@ def test_assistant_trust_score_blackout_2_lines_same_step_in_window_good_alerts kwargs_opponent = dict(lines_attacked=[ATTACKED_LINE]+['48_53_141'], duration=3, steps_attack=[3, 3]) - with make(self.env_nm, + with grid2op.make(self.env_nm, test=True, difficulty="1", opponent_attack_cooldown=0, @@ -1570,7 +1570,7 @@ def test_assistant_trust_score_blackout_2_lines_different_step_in_window_good_a kwargs_opponent = dict(lines_attacked=[ATTACKED_LINE]+['48_53_141'], duration=[1,1], steps_attack=[3, 4]) - with make(self.env_nm, + with grid2op.make(self.env_nm, test=True, difficulty="1", opponent_attack_cooldown=0, @@ -1641,7 +1641,7 @@ def test_assistant_trust_score_blackout_2_lines_attacked_different_step_in_windo kwargs_opponent = dict(lines_attacked=[ATTACKED_LINE]+['48_53_141'], duration=[1,1], steps_attack=[3, 4]) - with make(self.env_nm, + with grid2op.make(self.env_nm, test=True, difficulty="1", opponent_attack_cooldown=0, @@ -1706,7 +1706,7 @@ def test_assistant_trust_score_blackout_2_lines_attacked_different_step_in_windo kwargs_opponent = dict(lines_attacked=[ATTACKED_LINE]+['48_53_141'], duration=[1,1], steps_attack=[3, 4]) - with make(self.env_nm, + with grid2op.make(self.env_nm, test=True, difficulty="1", opponent_attack_cooldown=0, @@ -1770,7 +1770,7 @@ def test_assistant_trust_score_blackout_2_lines_attacked_different_1_in_window_1 kwargs_opponent = dict(lines_attacked=[ATTACKED_LINE]+['48_53_141'], duration=[1, 1], steps_attack=[3, 6]) - with make(self.env_nm, + with grid2op.make(self.env_nm, test=True, difficulty="1", opponent_attack_cooldown=0, @@ -1831,7 +1831,7 @@ def setUp(self) -> None: self.env_nm = os.path.join( PATH_DATA_TEST, "l2rpn_idf_2023_with_alert" ) - self.env = make(self.env_nm, test=True, difficulty="1", + self.env = grid2op.make(self.env_nm, test=True, difficulty="1", reward_class=_AlertTrustScore(**DEFAULT_PARAMS_TRUSTSCORE)) self.env.seed(0) return super().setUp() From 98c41e678f2f05062b6b182d44f94d9216a76899 Mon Sep 17 00:00:00 2001 From: DONNOT Benjamin Date: Tue, 30 Apr 2024 17:26:00 +0200 Subject: [PATCH 02/11] fixing tests and adding coverage for init action --- CHANGELOG.rst | 1 + grid2op/Chronics/chronicsHandler.py | 19 +- grid2op/Chronics/fromMultiEpisodeData.py | 4 + grid2op/Chronics/gridValue.py | 12 + grid2op/Chronics/multiFolder.py | 4 + grid2op/Chronics/multifolderWithCache.py | 7 + grid2op/Environment/baseEnv.py | 3 +- grid2op/Environment/baseMultiProcessEnv.py | 1 + grid2op/Environment/environment.py | 1 + grid2op/MakeEnv/MakeFromPath.py | 5 + .../5bus_example.json | 1339 +++++++++++++ .../chronics/0/hazards.csv.bz2 | Bin 0 -> 84 bytes .../chronics/0/init_state.json | 3 + .../chronics/0/load_p.csv.bz2 | Bin 0 -> 2599 bytes .../chronics/0/load_p_forecasted.csv.bz2 | Bin 0 -> 1073 bytes .../chronics/0/load_q.csv.bz2 | Bin 0 -> 2023 bytes .../chronics/0/load_q_forecasted.csv.bz2 | Bin 0 -> 912 bytes .../chronics/0/maintenance.csv.bz2 | Bin 0 -> 84 bytes .../chronics/0/maintenance_forecasted.csv.bz2 | Bin 0 -> 84 bytes .../chronics/0/maintenance_meta.json | 7 + .../chronics/0/prod_p.csv.bz2 | Bin 0 -> 3326 bytes .../chronics/0/prod_p_forecasted.csv.bz2 | Bin 0 -> 3095 bytes .../chronics/0/prod_v.csv.bz2 | Bin 0 -> 78 bytes .../chronics/0/prod_v_forecasted.csv.bz2 | Bin 0 -> 83 bytes .../chronics/1/hazards.csv.bz2 | Bin 0 -> 84 bytes .../chronics/1/init_state.json | 3 + .../chronics/1/load_p.csv.bz2 | Bin 0 -> 2512 bytes .../chronics/1/load_p_forecasted.csv.bz2 | Bin 0 -> 1077 bytes .../chronics/1/load_q.csv.bz2 | Bin 0 -> 1965 bytes .../chronics/1/load_q_forecasted.csv.bz2 | Bin 0 -> 896 bytes .../chronics/1/maintenance.csv.bz2 | Bin 0 -> 84 bytes .../chronics/1/maintenance_forecasted.csv.bz2 | Bin 0 -> 84 bytes .../chronics/1/maintenance_meta.json | 7 + .../chronics/1/prod_p.csv.bz2 | Bin 0 -> 3271 bytes .../chronics/1/prod_p_forecasted.csv.bz2 | Bin 0 -> 3001 bytes .../chronics/1/prod_v.csv.bz2 | Bin 0 -> 78 bytes .../chronics/1/prod_v_forecasted.csv.bz2 | Bin 0 -> 83 bytes .../chronics/2/hazards.csv.bz2 | Bin 0 -> 84 bytes .../chronics/2/init_state.json | 3 + .../chronics/2/load_p.csv.bz2 | Bin 0 -> 2593 bytes .../chronics/2/load_p_forecasted.csv.bz2 | Bin 0 -> 1059 bytes .../chronics/2/load_q.csv.bz2 | Bin 0 -> 2082 bytes .../chronics/2/load_q_forecasted.csv.bz2 | Bin 0 -> 876 bytes .../chronics/2/maintenance.csv.bz2 | Bin 0 -> 84 bytes .../chronics/2/maintenance_forecasted.csv.bz2 | Bin 0 -> 84 bytes .../chronics/2/maintenance_meta.json | 7 + .../chronics/2/prod_p.csv.bz2 | Bin 0 -> 3071 bytes .../chronics/2/prod_p_forecasted.csv.bz2 | Bin 0 -> 2771 bytes .../chronics/2/prod_v.csv.bz2 | Bin 0 -> 78 bytes .../chronics/2/prod_v_forecasted.csv.bz2 | Bin 0 -> 83 bytes .../chronics/2/start_datetime.info | 1 + .../chronics/2/time_interval.info | 1 + .../5bus_example_act_topo_set_init/config.py | 19 + .../5bus_example_act_topo_set_init/grid.json | 1772 +++++++++++++++++ .../prods_charac.csv | 3 + grid2op/tests/test_Environment.py | 4 +- grid2op/tests/test_action_set_orig_state.py | 174 +- 57 files changed, 3383 insertions(+), 17 deletions(-) create mode 100644 grid2op/data_test/5bus_example_act_topo_set_init/5bus_example.json create mode 100644 grid2op/data_test/5bus_example_act_topo_set_init/chronics/0/hazards.csv.bz2 create mode 100644 grid2op/data_test/5bus_example_act_topo_set_init/chronics/0/init_state.json create mode 100644 grid2op/data_test/5bus_example_act_topo_set_init/chronics/0/load_p.csv.bz2 create mode 100644 grid2op/data_test/5bus_example_act_topo_set_init/chronics/0/load_p_forecasted.csv.bz2 create mode 100644 grid2op/data_test/5bus_example_act_topo_set_init/chronics/0/load_q.csv.bz2 create mode 100644 grid2op/data_test/5bus_example_act_topo_set_init/chronics/0/load_q_forecasted.csv.bz2 create mode 100644 grid2op/data_test/5bus_example_act_topo_set_init/chronics/0/maintenance.csv.bz2 create mode 100644 grid2op/data_test/5bus_example_act_topo_set_init/chronics/0/maintenance_forecasted.csv.bz2 create mode 100644 grid2op/data_test/5bus_example_act_topo_set_init/chronics/0/maintenance_meta.json create mode 100644 grid2op/data_test/5bus_example_act_topo_set_init/chronics/0/prod_p.csv.bz2 create mode 100644 grid2op/data_test/5bus_example_act_topo_set_init/chronics/0/prod_p_forecasted.csv.bz2 create mode 100644 grid2op/data_test/5bus_example_act_topo_set_init/chronics/0/prod_v.csv.bz2 create mode 100644 grid2op/data_test/5bus_example_act_topo_set_init/chronics/0/prod_v_forecasted.csv.bz2 create mode 100644 grid2op/data_test/5bus_example_act_topo_set_init/chronics/1/hazards.csv.bz2 create mode 100644 grid2op/data_test/5bus_example_act_topo_set_init/chronics/1/init_state.json create mode 100644 grid2op/data_test/5bus_example_act_topo_set_init/chronics/1/load_p.csv.bz2 create mode 100644 grid2op/data_test/5bus_example_act_topo_set_init/chronics/1/load_p_forecasted.csv.bz2 create mode 100644 grid2op/data_test/5bus_example_act_topo_set_init/chronics/1/load_q.csv.bz2 create mode 100644 grid2op/data_test/5bus_example_act_topo_set_init/chronics/1/load_q_forecasted.csv.bz2 create mode 100644 grid2op/data_test/5bus_example_act_topo_set_init/chronics/1/maintenance.csv.bz2 create mode 100644 grid2op/data_test/5bus_example_act_topo_set_init/chronics/1/maintenance_forecasted.csv.bz2 create mode 100644 grid2op/data_test/5bus_example_act_topo_set_init/chronics/1/maintenance_meta.json create mode 100644 grid2op/data_test/5bus_example_act_topo_set_init/chronics/1/prod_p.csv.bz2 create mode 100644 grid2op/data_test/5bus_example_act_topo_set_init/chronics/1/prod_p_forecasted.csv.bz2 create mode 100644 grid2op/data_test/5bus_example_act_topo_set_init/chronics/1/prod_v.csv.bz2 create mode 100644 grid2op/data_test/5bus_example_act_topo_set_init/chronics/1/prod_v_forecasted.csv.bz2 create mode 100644 grid2op/data_test/5bus_example_act_topo_set_init/chronics/2/hazards.csv.bz2 create mode 100644 grid2op/data_test/5bus_example_act_topo_set_init/chronics/2/init_state.json create mode 100644 grid2op/data_test/5bus_example_act_topo_set_init/chronics/2/load_p.csv.bz2 create mode 100644 grid2op/data_test/5bus_example_act_topo_set_init/chronics/2/load_p_forecasted.csv.bz2 create mode 100644 grid2op/data_test/5bus_example_act_topo_set_init/chronics/2/load_q.csv.bz2 create mode 100644 grid2op/data_test/5bus_example_act_topo_set_init/chronics/2/load_q_forecasted.csv.bz2 create mode 100644 grid2op/data_test/5bus_example_act_topo_set_init/chronics/2/maintenance.csv.bz2 create mode 100644 grid2op/data_test/5bus_example_act_topo_set_init/chronics/2/maintenance_forecasted.csv.bz2 create mode 100644 grid2op/data_test/5bus_example_act_topo_set_init/chronics/2/maintenance_meta.json create mode 100644 grid2op/data_test/5bus_example_act_topo_set_init/chronics/2/prod_p.csv.bz2 create mode 100644 grid2op/data_test/5bus_example_act_topo_set_init/chronics/2/prod_p_forecasted.csv.bz2 create mode 100644 grid2op/data_test/5bus_example_act_topo_set_init/chronics/2/prod_v.csv.bz2 create mode 100644 grid2op/data_test/5bus_example_act_topo_set_init/chronics/2/prod_v_forecasted.csv.bz2 create mode 100644 grid2op/data_test/5bus_example_act_topo_set_init/chronics/2/start_datetime.info create mode 100644 grid2op/data_test/5bus_example_act_topo_set_init/chronics/2/time_interval.info create mode 100644 grid2op/data_test/5bus_example_act_topo_set_init/config.py create mode 100644 grid2op/data_test/5bus_example_act_topo_set_init/grid.json create mode 100644 grid2op/data_test/5bus_example_act_topo_set_init/prods_charac.csv diff --git a/CHANGELOG.rst b/CHANGELOG.rst index e6cca5019..6a26ce63a 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -63,6 +63,7 @@ Change Log grid layout was set - [FIXED] notebook 5 on loading back data with `EpisodeData`. - [FIXED] converter between backends (could not handle more than 2 busbars) +- [FIXED] a bug in `BaseMultiProcessEnvironment`: set_filter had no impact - [IMPROVED] documentation about `obs.simulate` to make it clearer the difference between env.step and obs.simulate on some cases - [IMPROVED] type hints on some methods of `GridObjects` diff --git a/grid2op/Chronics/chronicsHandler.py b/grid2op/Chronics/chronicsHandler.py index 000a33d68..44ad9256f 100644 --- a/grid2op/Chronics/chronicsHandler.py +++ b/grid2op/Chronics/chronicsHandler.py @@ -11,6 +11,7 @@ import numpy as np from datetime import timedelta +from grid2op.Exceptions.envExceptions import EnvError from grid2op.dtypes import dt_int from grid2op.Exceptions import Grid2OpException, ChronicsError from grid2op.Space import RandomObject @@ -93,8 +94,15 @@ def action_space(self): @action_space.setter def action_space(self, values): - self._real_data.action_space = values - + try: + self._real_data.action_space = values + except EnvError as exc_: + raise EnvError("Impossible to set the action_space for this 'chronics_handler'. " + f"It appears they have already been set previously. Do you try to use " + "The same 'chronics_handler' for two different environment ? " + "If so, you probably should not. \n" + "If you deep copied a 'chronics_handler', you can call `cpy.cleanup_action_space()` " + "on the copy to solve this issue.") from exc_ @property def kwargs(self): res = copy.deepcopy(self._kwargs) @@ -214,3 +222,10 @@ def __getattr__(self, name): # https://github.com/matplotlib/matplotlib/issues/7852/ return object.__getattr__(self, name) return getattr(self._real_data, name) + + def cleanup_action_space(self): + """INTERNAL, used to forget the "old" action_space when the + chronics_handler is copied for example. + """ + self._real_data.cleanup_action_space() + \ No newline at end of file diff --git a/grid2op/Chronics/fromMultiEpisodeData.py b/grid2op/Chronics/fromMultiEpisodeData.py index c130263dd..7f948f196 100644 --- a/grid2op/Chronics/fromMultiEpisodeData.py +++ b/grid2op/Chronics/fromMultiEpisodeData.py @@ -192,3 +192,7 @@ def fast_forward(self, nb_timestep): def get_init_action(self) -> Union["grid2op.Action.playableAction.PlayableAction", None]: return self.data.get_init_action() + + def cleanup_action_space(self): + super().cleanup_action_space() + self.data.cleanup_action_space() diff --git a/grid2op/Chronics/gridValue.py b/grid2op/Chronics/gridValue.py index 7b8edbf30..26a7f42e6 100644 --- a/grid2op/Chronics/gridValue.py +++ b/grid2op/Chronics/gridValue.py @@ -838,3 +838,15 @@ def get_init_action(self) -> Union["grid2op.Action.playableAction.PlayableAction The desired intial configuration of the grid """ return None + + def cleanup_action_space(self): + """ + INTERNAL + + Used internally, do not overide + + It is for example used when making a deepcopy of a `chronics_handler` to make sure + the new copy references the proper action space of the new environment. + """ + self.__action_space = None + # NB the action space is not closed as it is NOT own by this class diff --git a/grid2op/Chronics/multiFolder.py b/grid2op/Chronics/multiFolder.py index 87b95bafb..2d92805f7 100644 --- a/grid2op/Chronics/multiFolder.py +++ b/grid2op/Chronics/multiFolder.py @@ -783,3 +783,7 @@ def fast_forward(self, nb_timestep): def get_init_action(self) -> Union["grid2op.Action.playableAction.PlayableAction", None]: return self.data.get_init_action() + + def cleanup_action_space(self): + super().cleanup_action_space() + self.data.cleanup_action_space() diff --git a/grid2op/Chronics/multifolderWithCache.py b/grid2op/Chronics/multifolderWithCache.py index 6a6cc6362..e5a5755bd 100644 --- a/grid2op/Chronics/multifolderWithCache.py +++ b/grid2op/Chronics/multifolderWithCache.py @@ -294,3 +294,10 @@ def get_kwargs(self, dict_): dict_["_DONTUSE_nb_step_called"] = self.__nb_step_called dict_["_DONTUSE_nb_init_called"] = self.__nb_init_called return super().get_kwargs(dict_) + + def cleanup_action_space(self): + super().cleanup_action_space() + for el in self._cached_data: + if el is None: + continue + el.cleanup_action_space() diff --git a/grid2op/Environment/baseEnv.py b/grid2op/Environment/baseEnv.py index c5ccb5f6b..d97b21221 100644 --- a/grid2op/Environment/baseEnv.py +++ b/grid2op/Environment/baseEnv.py @@ -752,8 +752,9 @@ def _custom_deepcopy_for_copy(self, new_obj, dict_=None): new_obj.current_reward = copy.deepcopy(self.current_reward) new_obj.chronics_handler = copy.deepcopy(self.chronics_handler) # retrieve the "pointer" to the new_obj action space (for initializing the grid) - new_obj.chronics_handler._real_data._GridValue__action_space = None + new_obj.chronics_handler.cleanup_action_space() new_obj.chronics_handler.action_space = new_obj._helper_action_env + # action space new_obj._action_space = self._action_space.copy() new_obj._action_space.legal_action = new_obj._game_rules.legal_action diff --git a/grid2op/Environment/baseMultiProcessEnv.py b/grid2op/Environment/baseMultiProcessEnv.py index 37d571702..2ab2bafce 100644 --- a/grid2op/Environment/baseMultiProcessEnv.py +++ b/grid2op/Environment/baseMultiProcessEnv.py @@ -206,6 +206,7 @@ def run(self): self.remote.send(self.env._time_step) elif cmd == "set_filter": self.env.chronics_handler.set_filter(data) + self.env.chronics_handler.reset() self.remote.send(None) elif cmd == "set_id": self.env.set_id(data) diff --git a/grid2op/Environment/environment.py b/grid2op/Environment/environment.py index 9e4283d74..59def73dd 100644 --- a/grid2op/Environment/environment.py +++ b/grid2op/Environment/environment.py @@ -1107,6 +1107,7 @@ def get_kwargs(self, with_backend=True, with_chronics_handler=True): res["init_grid_path"] = self._init_grid_path if with_chronics_handler: res["chronics_handler"] = copy.deepcopy(self.chronics_handler) + res["chronics_handler"].cleanup_action_space() if with_backend: if not self.backend._can_be_copied: raise RuntimeError("Impossible to get the kwargs for this " diff --git a/grid2op/MakeEnv/MakeFromPath.py b/grid2op/MakeEnv/MakeFromPath.py index 7da732c52..5d200c71a 100644 --- a/grid2op/MakeEnv/MakeFromPath.py +++ b/grid2op/MakeEnv/MakeFromPath.py @@ -905,6 +905,11 @@ def make_from_dataset_path( # TODO: explain in doc new behaviour with regards to "class in file" # TODO: basic CI for this "new" mode + + # TODO: use the tempfile.TemporaryDirectory() to hold the classes, and in the (real) env copy, runner , env.get_kwargs() + # or whatever + # reference this "tempfile.TemporaryDirectory()" which will be deleted automatically + # when every "pointer" to it are deleted, this sounds more reasonable if not experimental_read_from_local_dir: init_env = Environment(init_env_path=os.path.abspath(dataset_path), init_grid_path=grid_path_abs, diff --git a/grid2op/data_test/5bus_example_act_topo_set_init/5bus_example.json b/grid2op/data_test/5bus_example_act_topo_set_init/5bus_example.json new file mode 100644 index 000000000..2e9dd0c79 --- /dev/null +++ b/grid2op/data_test/5bus_example_act_topo_set_init/5bus_example.json @@ -0,0 +1,1339 @@ +{ + "_module": "pandapower.auxiliary", + "_class": "pandapowerNet", + "_object": { + "bus": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"vn_kv\",\"type\",\"zone\",\"in_service\"],\"index\":[0,1,2,3,4],\"data\":[[\"substation_1\",100.0,\"b\",null,true],[\"substation_2\",100.0,\"b\",null,true],[\"substation_3\",100.0,\"b\",null,true],[\"substation_4\",100.0,\"b\",null,true],[\"substation_5\",100.0,\"b\",null,true]]}", + "dtype": { + "name": "object", + "vn_kv": "float64", + "type": "object", + "zone": "object", + "in_service": "bool" + }, + "orient": "split" + }, + "load": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"bus\",\"p_mw\",\"q_mvar\",\"const_z_percent\",\"const_i_percent\",\"sn_mva\",\"scaling\",\"in_service\",\"type\"],\"index\":[0,1,2],\"data\":[[\"load_0_0\",0,10.0,7.0,0.0,0.0,null,1.0,true,null],[\"load_3_1\",3,10.0,7.0,0.0,0.0,null,1.0,true,null],[\"load_4_2\",4,10.0,7.0,0.0,0.0,null,1.0,true,null]]}", + "dtype": { + "name": "object", + "bus": "uint32", + "p_mw": "float64", + "q_mvar": "float64", + "const_z_percent": "float64", + "const_i_percent": "float64", + "sn_mva": "float64", + "scaling": "float64", + "in_service": "bool", + "type": "object" + }, + "orient": "split" + }, + "sgen": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"bus\",\"p_mw\",\"q_mvar\",\"sn_mva\",\"scaling\",\"in_service\",\"type\",\"current_source\"],\"index\":[],\"data\":[]}", + "dtype": { + "name": "object", + "bus": "int64", + "p_mw": "float64", + "q_mvar": "float64", + "sn_mva": "float64", + "scaling": "float64", + "in_service": "bool", + "type": "object", + "current_source": "bool" + }, + "orient": "split" + }, + "storage": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"bus\",\"p_mw\",\"q_mvar\",\"sn_mva\",\"soc_percent\",\"min_e_mwh\",\"max_e_mwh\",\"scaling\",\"in_service\",\"type\"],\"index\":[],\"data\":[]}", + "dtype": { + "name": "object", + "bus": "int64", + "p_mw": "float64", + "q_mvar": "float64", + "sn_mva": "float64", + "soc_percent": "float64", + "min_e_mwh": "float64", + "max_e_mwh": "float64", + "scaling": "float64", + "in_service": "bool", + "type": "object" + }, + "orient": "split" + }, + "gen": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"bus\",\"p_mw\",\"vm_pu\",\"sn_mva\",\"min_q_mvar\",\"max_q_mvar\",\"scaling\",\"slack\",\"in_service\",\"type\"],\"index\":[0,1],\"data\":[[\"gen_0_0\",0,10.0,1.02,null,null,null,1.0,false,true,null],[\"gen_1_1\",1,20.0,1.02,null,null,null,1.0,true,true,null]]}", + "dtype": { + "name": "object", + "bus": "uint32", + "p_mw": "float64", + "vm_pu": "float64", + "sn_mva": "float64", + "min_q_mvar": "float64", + "max_q_mvar": "float64", + "scaling": "float64", + "slack": "bool", + "in_service": "bool", + "type": "object" + }, + "orient": "split" + }, + "switch": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"bus\",\"element\",\"et\",\"type\",\"closed\",\"name\",\"z_ohm\"],\"index\":[],\"data\":[]}", + "dtype": { + "bus": "int64", + "element": "int64", + "et": "object", + "type": "object", + "closed": "bool", + "name": "object", + "z_ohm": "float64" + }, + "orient": "split" + }, + "shunt": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"bus\",\"name\",\"q_mvar\",\"p_mw\",\"vn_kv\",\"step\",\"max_step\",\"in_service\"],\"index\":[],\"data\":[]}", + "dtype": { + "bus": "uint32", + "name": "object", + "q_mvar": "float64", + "p_mw": "float64", + "vn_kv": "float64", + "step": "uint32", + "max_step": "uint32", + "in_service": "bool" + }, + "orient": "split" + }, + "ext_grid": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"bus\",\"vm_pu\",\"va_degree\",\"in_service\"],\"index\":[],\"data\":[]}", + "dtype": { + "name": "object", + "bus": "uint32", + "vm_pu": "float64", + "va_degree": "float64", + "in_service": "bool" + }, + "orient": "split" + }, + "line": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"std_type\",\"from_bus\",\"to_bus\",\"length_km\",\"r_ohm_per_km\",\"x_ohm_per_km\",\"c_nf_per_km\",\"g_us_per_km\",\"max_i_ka\",\"df\",\"parallel\",\"type\",\"in_service\"],\"index\":[0,1,2,3,4,5,6,7],\"data\":[[null,\"NAYY 4x50 SE\",0,1,4.0,0.642,0.083,210.0,0.0,0.6,1.0,1,\"cs\",true],[\"0_2_2\",\"NAYY 4x50 SE\",0,2,4.47,0.642,0.083,210.0,0.0,0.22,1.0,1,\"cs\",true],[\"0_3_3\",\"NAYY 4x50 SE\",0,3,5.65,0.642,0.083,210.0,0.0,0.16,1.0,1,\"cs\",true],[\"0_4_4\",\"NAYY 4x50 SE\",0,4,4.0,0.642,0.083,210.0,0.0,0.16,1.0,1,\"cs\",true],[\"1_2_5\",\"NAYY 4x50 SE\",1,2,2.0,0.642,0.083,210.0,0.0,0.6,1.0,1,\"cs\",true],[\"2_3_6\",\"NAYY 4x50 SE\",2,3,2.0,0.642,0.083,210.0,0.0,0.3,1.0,1,\"cs\",true],[\"2_3_7\",\"NAYY 4x50 SE\",2,3,2.0,0.642,0.083,210.0,0.0,0.3,1.0,1,\"cs\",true],[\"3_4_8\",\"NAYY 4x50 SE\",3,4,4.0,0.642,0.083,210.0,0.0,0.16,1.0,1,\"cs\",true]]}", + "dtype": { + "name": "object", + "std_type": "object", + "from_bus": "uint32", + "to_bus": "uint32", + "length_km": "float64", + "r_ohm_per_km": "float64", + "x_ohm_per_km": "float64", + "c_nf_per_km": "float64", + "g_us_per_km": "float64", + "max_i_ka": "float64", + "df": "float64", + "parallel": "uint32", + "type": "object", + "in_service": "bool" + }, + "orient": "split" + }, + "trafo": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"std_type\",\"hv_bus\",\"lv_bus\",\"sn_mva\",\"vn_hv_kv\",\"vn_lv_kv\",\"vk_percent\",\"vkr_percent\",\"pfe_kw\",\"i0_percent\",\"shift_degree\",\"tap_side\",\"tap_neutral\",\"tap_min\",\"tap_max\",\"tap_step_percent\",\"tap_step_degree\",\"tap_pos\",\"tap_phase_shifter\",\"parallel\",\"df\",\"in_service\"],\"index\":[],\"data\":[]}", + "dtype": { + "name": "object", + "std_type": "object", + "hv_bus": "uint32", + "lv_bus": "uint32", + "sn_mva": "float64", + "vn_hv_kv": "float64", + "vn_lv_kv": "float64", + "vk_percent": "float64", + "vkr_percent": "float64", + "pfe_kw": "float64", + "i0_percent": "float64", + "shift_degree": "float64", + "tap_side": "object", + "tap_neutral": "int32", + "tap_min": "int32", + "tap_max": "int32", + "tap_step_percent": "float64", + "tap_step_degree": "float64", + "tap_pos": "int32", + "tap_phase_shifter": "bool", + "parallel": "uint32", + "df": "float64", + "in_service": "bool" + }, + "orient": "split" + }, + "trafo3w": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"std_type\",\"hv_bus\",\"mv_bus\",\"lv_bus\",\"sn_hv_mva\",\"sn_mv_mva\",\"sn_lv_mva\",\"vn_hv_kv\",\"vn_mv_kv\",\"vn_lv_kv\",\"vk_hv_percent\",\"vk_mv_percent\",\"vk_lv_percent\",\"vkr_hv_percent\",\"vkr_mv_percent\",\"vkr_lv_percent\",\"pfe_kw\",\"i0_percent\",\"shift_mv_degree\",\"shift_lv_degree\",\"tap_side\",\"tap_neutral\",\"tap_min\",\"tap_max\",\"tap_step_percent\",\"tap_step_degree\",\"tap_pos\",\"tap_at_star_point\",\"in_service\"],\"index\":[],\"data\":[]}", + "dtype": { + "name": "object", + "std_type": "object", + "hv_bus": "uint32", + "mv_bus": "uint32", + "lv_bus": "uint32", + "sn_hv_mva": "float64", + "sn_mv_mva": "float64", + "sn_lv_mva": "float64", + "vn_hv_kv": "float64", + "vn_mv_kv": "float64", + "vn_lv_kv": "float64", + "vk_hv_percent": "float64", + "vk_mv_percent": "float64", + "vk_lv_percent": "float64", + "vkr_hv_percent": "float64", + "vkr_mv_percent": "float64", + "vkr_lv_percent": "float64", + "pfe_kw": "float64", + "i0_percent": "float64", + "shift_mv_degree": "float64", + "shift_lv_degree": "float64", + "tap_side": "object", + "tap_neutral": "int32", + "tap_min": "int32", + "tap_max": "int32", + "tap_step_percent": "float64", + "tap_step_degree": "float64", + "tap_pos": "int32", + "tap_at_star_point": "bool", + "in_service": "bool" + }, + "orient": "split" + }, + "impedance": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"from_bus\",\"to_bus\",\"rft_pu\",\"xft_pu\",\"rtf_pu\",\"xtf_pu\",\"sn_mva\",\"in_service\"],\"index\":[],\"data\":[]}", + "dtype": { + "name": "object", + "from_bus": "uint32", + "to_bus": "uint32", + "rft_pu": "float64", + "xft_pu": "float64", + "rtf_pu": "float64", + "xtf_pu": "float64", + "sn_mva": "float64", + "in_service": "bool" + }, + "orient": "split" + }, + "dcline": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"from_bus\",\"to_bus\",\"p_mw\",\"loss_percent\",\"loss_mw\",\"vm_from_pu\",\"vm_to_pu\",\"max_p_mw\",\"min_q_from_mvar\",\"min_q_to_mvar\",\"max_q_from_mvar\",\"max_q_to_mvar\",\"in_service\"],\"index\":[],\"data\":[]}", + "dtype": { + "name": "object", + "from_bus": "uint32", + "to_bus": "uint32", + "p_mw": "float64", + "loss_percent": "float64", + "loss_mw": "float64", + "vm_from_pu": "float64", + "vm_to_pu": "float64", + "max_p_mw": "float64", + "min_q_from_mvar": "float64", + "min_q_to_mvar": "float64", + "max_q_from_mvar": "float64", + "max_q_to_mvar": "float64", + "in_service": "bool" + }, + "orient": "split" + }, + "ward": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"bus\",\"ps_mw\",\"qs_mvar\",\"qz_mvar\",\"pz_mw\",\"in_service\"],\"index\":[],\"data\":[]}", + "dtype": { + "name": "object", + "bus": "uint32", + "ps_mw": "float64", + "qs_mvar": "float64", + "qz_mvar": "float64", + "pz_mw": "float64", + "in_service": "bool" + }, + "orient": "split" + }, + "xward": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"bus\",\"ps_mw\",\"qs_mvar\",\"qz_mvar\",\"pz_mw\",\"r_ohm\",\"x_ohm\",\"vm_pu\",\"in_service\"],\"index\":[],\"data\":[]}", + "dtype": { + "name": "object", + "bus": "uint32", + "ps_mw": "float64", + "qs_mvar": "float64", + "qz_mvar": "float64", + "pz_mw": "float64", + "r_ohm": "float64", + "x_ohm": "float64", + "vm_pu": "float64", + "in_service": "bool" + }, + "orient": "split" + }, + "measurement": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"measurement_type\",\"element_type\",\"element\",\"value\",\"std_dev\",\"side\"],\"index\":[],\"data\":[]}", + "dtype": { + "name": "object", + "measurement_type": "object", + "element_type": "object", + "element": "uint32", + "value": "float64", + "std_dev": "float64", + "side": "object" + }, + "orient": "split" + }, + "pwl_cost": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"power_type\",\"element\",\"et\",\"points\"],\"index\":[],\"data\":[]}", + "dtype": { + "power_type": "object", + "element": "object", + "et": "object", + "points": "object" + }, + "orient": "split" + }, + "poly_cost": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"element\",\"et\",\"cp0_eur\",\"cp1_eur_per_mw\",\"cp2_eur_per_mw2\",\"cq0_eur\",\"cq1_eur_per_mvar\",\"cq2_eur_per_mvar2\"],\"index\":[],\"data\":[]}", + "dtype": { + "element": "object", + "et": "object", + "cp0_eur": "float64", + "cp1_eur_per_mw": "float64", + "cp2_eur_per_mw2": "float64", + "cq0_eur": "float64", + "cq1_eur_per_mvar": "float64", + "cq2_eur_per_mvar2": "float64" + }, + "orient": "split" + }, + "line_geodata": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"coords\"],\"index\":[0,1,2,3,4,5,6,7],\"data\":[[[[0,0],[0,4]]],[[[0,0],[2,4]]],[[[0,0],[4,4]]],[[[0,0],[4,0]]],[[[0,4],[2,4]]],[[[2,4],[3,4.2],[4,4]]],[[[2,4],[3,3.8],[4,4]]],[[[4,4],[4,0]]]]}", + "dtype": { + "coords": "object" + }, + "orient": "split" + }, + "bus_geodata": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"x\",\"y\",\"coords\"],\"index\":[0,1,2,3,4],\"data\":[[0.0,0.0,null],[0.0,4.0,null],[2.0,4.0,null],[4.0,4.0,null],[4.0,0.0,null]]}", + "dtype": { + "x": "float64", + "y": "float64", + "coords": "object" + }, + "orient": "split" + }, + "version": "2.1.0", + "converged": true, + "name": "5bus", + "f_hz": 50.0, + "sn_mva": 1, + "std_types": { + "line": { + "NAYY 4x50 SE": { + "c_nf_per_km": 210, + "r_ohm_per_km": 0.642, + "x_ohm_per_km": 0.083, + "max_i_ka": 0.142, + "type": "cs", + "q_mm2": 50, + "alpha": 0.00403 + }, + "NAYY 4x120 SE": { + "c_nf_per_km": 264, + "r_ohm_per_km": 0.225, + "x_ohm_per_km": 0.08, + "max_i_ka": 0.242, + "type": "cs", + "q_mm2": 120, + "alpha": 0.00403 + }, + "NAYY 4x150 SE": { + "c_nf_per_km": 261, + "r_ohm_per_km": 0.208, + "x_ohm_per_km": 0.08, + "max_i_ka": 0.27, + "type": "cs", + "q_mm2": 150, + "alpha": 0.00403 + }, + "NA2XS2Y 1x95 RM/25 12/20 kV": { + "c_nf_per_km": 216, + "r_ohm_per_km": 0.313, + "x_ohm_per_km": 0.132, + "max_i_ka": 0.252, + "type": "cs", + "q_mm2": 95, + "alpha": 0.00403 + }, + "NA2XS2Y 1x185 RM/25 12/20 kV": { + "c_nf_per_km": 273, + "r_ohm_per_km": 0.161, + "x_ohm_per_km": 0.117, + "max_i_ka": 0.362, + "type": "cs", + "q_mm2": 185, + "alpha": 0.00403 + }, + "NA2XS2Y 1x240 RM/25 12/20 kV": { + "c_nf_per_km": 304, + "r_ohm_per_km": 0.122, + "x_ohm_per_km": 0.112, + "max_i_ka": 0.421, + "type": "cs", + "q_mm2": 240, + "alpha": 0.00403 + }, + "NA2XS2Y 1x95 RM/25 6/10 kV": { + "c_nf_per_km": 315, + "r_ohm_per_km": 0.313, + "x_ohm_per_km": 0.123, + "max_i_ka": 0.249, + "type": "cs", + "q_mm2": 95, + "alpha": 0.00403 + }, + "NA2XS2Y 1x185 RM/25 6/10 kV": { + "c_nf_per_km": 406, + "r_ohm_per_km": 0.161, + "x_ohm_per_km": 0.11, + "max_i_ka": 0.358, + "type": "cs", + "q_mm2": 185, + "alpha": 0.00403 + }, + "NA2XS2Y 1x240 RM/25 6/10 kV": { + "c_nf_per_km": 456, + "r_ohm_per_km": 0.122, + "x_ohm_per_km": 0.105, + "max_i_ka": 0.416, + "type": "cs", + "q_mm2": 240, + "alpha": 0.00403 + }, + "NA2XS2Y 1x150 RM/25 12/20 kV": { + "c_nf_per_km": 250, + "r_ohm_per_km": 0.206, + "x_ohm_per_km": 0.116, + "max_i_ka": 0.319, + "type": "cs", + "q_mm2": 150, + "alpha": 0.00403 + }, + "NA2XS2Y 1x120 RM/25 12/20 kV": { + "c_nf_per_km": 230, + "r_ohm_per_km": 0.253, + "x_ohm_per_km": 0.119, + "max_i_ka": 0.283, + "type": "cs", + "q_mm2": 120, + "alpha": 0.00403 + }, + "NA2XS2Y 1x70 RM/25 12/20 kV": { + "c_nf_per_km": 190, + "r_ohm_per_km": 0.443, + "x_ohm_per_km": 0.132, + "max_i_ka": 0.22, + "type": "cs", + "q_mm2": 70, + "alpha": 0.00403 + }, + "NA2XS2Y 1x150 RM/25 6/10 kV": { + "c_nf_per_km": 360, + "r_ohm_per_km": 0.206, + "x_ohm_per_km": 0.11, + "max_i_ka": 0.315, + "type": "cs", + "q_mm2": 150, + "alpha": 0.00403 + }, + "NA2XS2Y 1x120 RM/25 6/10 kV": { + "c_nf_per_km": 340, + "r_ohm_per_km": 0.253, + "x_ohm_per_km": 0.113, + "max_i_ka": 0.28, + "type": "cs", + "q_mm2": 120, + "alpha": 0.00403 + }, + "NA2XS2Y 1x70 RM/25 6/10 kV": { + "c_nf_per_km": 280, + "r_ohm_per_km": 0.443, + "x_ohm_per_km": 0.123, + "max_i_ka": 0.217, + "type": "cs", + "q_mm2": 70, + "alpha": 0.00403 + }, + "N2XS(FL)2Y 1x120 RM/35 64/110 kV": { + "c_nf_per_km": 112, + "r_ohm_per_km": 0.153, + "x_ohm_per_km": 0.166, + "max_i_ka": 0.366, + "type": "cs", + "q_mm2": 120, + "alpha": 0.00393 + }, + "N2XS(FL)2Y 1x185 RM/35 64/110 kV": { + "c_nf_per_km": 125, + "r_ohm_per_km": 0.099, + "x_ohm_per_km": 0.156, + "max_i_ka": 0.457, + "type": "cs", + "q_mm2": 185, + "alpha": 0.00393 + }, + "N2XS(FL)2Y 1x240 RM/35 64/110 kV": { + "c_nf_per_km": 135, + "r_ohm_per_km": 0.075, + "x_ohm_per_km": 0.149, + "max_i_ka": 0.526, + "type": "cs", + "q_mm2": 240, + "alpha": 0.00393 + }, + "N2XS(FL)2Y 1x300 RM/35 64/110 kV": { + "c_nf_per_km": 144, + "r_ohm_per_km": 0.06, + "x_ohm_per_km": 0.144, + "max_i_ka": 0.588, + "type": "cs", + "q_mm2": 300, + "alpha": 0.00393 + }, + "15-AL1/3-ST1A 0.4": { + "c_nf_per_km": 11, + "r_ohm_per_km": 1.8769, + "x_ohm_per_km": 0.35, + "max_i_ka": 0.105, + "type": "ol", + "q_mm2": 16, + "alpha": 0.00403 + }, + "24-AL1/4-ST1A 0.4": { + "c_nf_per_km": 11.25, + "r_ohm_per_km": 1.2012, + "x_ohm_per_km": 0.335, + "max_i_ka": 0.14, + "type": "ol", + "q_mm2": 24, + "alpha": 0.00403 + }, + "48-AL1/8-ST1A 0.4": { + "c_nf_per_km": 12.2, + "r_ohm_per_km": 0.5939, + "x_ohm_per_km": 0.3, + "max_i_ka": 0.21, + "type": "ol", + "q_mm2": 48, + "alpha": 0.00403 + }, + "94-AL1/15-ST1A 0.4": { + "c_nf_per_km": 13.2, + "r_ohm_per_km": 0.306, + "x_ohm_per_km": 0.29, + "max_i_ka": 0.35, + "type": "ol", + "q_mm2": 94, + "alpha": 0.00403 + }, + "34-AL1/6-ST1A 10.0": { + "c_nf_per_km": 9.7, + "r_ohm_per_km": 0.8342, + "x_ohm_per_km": 0.36, + "max_i_ka": 0.17, + "type": "ol", + "q_mm2": 34, + "alpha": 0.00403 + }, + "48-AL1/8-ST1A 10.0": { + "c_nf_per_km": 10.1, + "r_ohm_per_km": 0.5939, + "x_ohm_per_km": 0.35, + "max_i_ka": 0.21, + "type": "ol", + "q_mm2": 48, + "alpha": 0.00403 + }, + "70-AL1/11-ST1A 10.0": { + "c_nf_per_km": 10.4, + "r_ohm_per_km": 0.4132, + "x_ohm_per_km": 0.339, + "max_i_ka": 0.29, + "type": "ol", + "q_mm2": 70, + "alpha": 0.00403 + }, + "94-AL1/15-ST1A 10.0": { + "c_nf_per_km": 10.75, + "r_ohm_per_km": 0.306, + "x_ohm_per_km": 0.33, + "max_i_ka": 0.35, + "type": "ol", + "q_mm2": 94, + "alpha": 0.00403 + }, + "122-AL1/20-ST1A 10.0": { + "c_nf_per_km": 11.1, + "r_ohm_per_km": 0.2376, + "x_ohm_per_km": 0.323, + "max_i_ka": 0.41, + "type": "ol", + "q_mm2": 122, + "alpha": 0.00403 + }, + "149-AL1/24-ST1A 10.0": { + "c_nf_per_km": 11.25, + "r_ohm_per_km": 0.194, + "x_ohm_per_km": 0.315, + "max_i_ka": 0.47, + "type": "ol", + "q_mm2": 149, + "alpha": 0.00403 + }, + "34-AL1/6-ST1A 20.0": { + "c_nf_per_km": 9.15, + "r_ohm_per_km": 0.8342, + "x_ohm_per_km": 0.382, + "max_i_ka": 0.17, + "type": "ol", + "q_mm2": 34, + "alpha": 0.00403 + }, + "48-AL1/8-ST1A 20.0": { + "c_nf_per_km": 9.5, + "r_ohm_per_km": 0.5939, + "x_ohm_per_km": 0.372, + "max_i_ka": 0.21, + "type": "ol", + "q_mm2": 48, + "alpha": 0.00403 + }, + "70-AL1/11-ST1A 20.0": { + "c_nf_per_km": 9.7, + "r_ohm_per_km": 0.4132, + "x_ohm_per_km": 0.36, + "max_i_ka": 0.29, + "type": "ol", + "q_mm2": 70, + "alpha": 0.00403 + }, + "94-AL1/15-ST1A 20.0": { + "c_nf_per_km": 10, + "r_ohm_per_km": 0.306, + "x_ohm_per_km": 0.35, + "max_i_ka": 0.35, + "type": "ol", + "q_mm2": 94, + "alpha": 0.00403 + }, + "122-AL1/20-ST1A 20.0": { + "c_nf_per_km": 10.3, + "r_ohm_per_km": 0.2376, + "x_ohm_per_km": 0.344, + "max_i_ka": 0.41, + "type": "ol", + "q_mm2": 122, + "alpha": 0.00403 + }, + "149-AL1/24-ST1A 20.0": { + "c_nf_per_km": 10.5, + "r_ohm_per_km": 0.194, + "x_ohm_per_km": 0.337, + "max_i_ka": 0.47, + "type": "ol", + "q_mm2": 149, + "alpha": 0.00403 + }, + "184-AL1/30-ST1A 20.0": { + "c_nf_per_km": 10.75, + "r_ohm_per_km": 0.1571, + "x_ohm_per_km": 0.33, + "max_i_ka": 0.535, + "type": "ol", + "q_mm2": 184, + "alpha": 0.00403 + }, + "243-AL1/39-ST1A 20.0": { + "c_nf_per_km": 11, + "r_ohm_per_km": 0.1188, + "x_ohm_per_km": 0.32, + "max_i_ka": 0.645, + "type": "ol", + "q_mm2": 243, + "alpha": 0.00403 + }, + "48-AL1/8-ST1A 110.0": { + "c_nf_per_km": 8, + "r_ohm_per_km": 0.5939, + "x_ohm_per_km": 0.46, + "max_i_ka": 0.21, + "type": "ol", + "q_mm2": 48, + "alpha": 0.00403 + }, + "70-AL1/11-ST1A 110.0": { + "c_nf_per_km": 8.4, + "r_ohm_per_km": 0.4132, + "x_ohm_per_km": 0.45, + "max_i_ka": 0.29, + "type": "ol", + "q_mm2": 70, + "alpha": 0.00403 + }, + "94-AL1/15-ST1A 110.0": { + "c_nf_per_km": 8.65, + "r_ohm_per_km": 0.306, + "x_ohm_per_km": 0.44, + "max_i_ka": 0.35, + "type": "ol", + "q_mm2": 94, + "alpha": 0.00403 + }, + "122-AL1/20-ST1A 110.0": { + "c_nf_per_km": 8.5, + "r_ohm_per_km": 0.2376, + "x_ohm_per_km": 0.43, + "max_i_ka": 0.41, + "type": "ol", + "q_mm2": 122, + "alpha": 0.00403 + }, + "149-AL1/24-ST1A 110.0": { + "c_nf_per_km": 8.75, + "r_ohm_per_km": 0.194, + "x_ohm_per_km": 0.41, + "max_i_ka": 0.47, + "type": "ol", + "q_mm2": 149, + "alpha": 0.00403 + }, + "184-AL1/30-ST1A 110.0": { + "c_nf_per_km": 8.8, + "r_ohm_per_km": 0.1571, + "x_ohm_per_km": 0.4, + "max_i_ka": 0.535, + "type": "ol", + "q_mm2": 184, + "alpha": 0.00403 + }, + "243-AL1/39-ST1A 110.0": { + "c_nf_per_km": 9, + "r_ohm_per_km": 0.1188, + "x_ohm_per_km": 0.39, + "max_i_ka": 0.645, + "type": "ol", + "q_mm2": 243, + "alpha": 0.00403 + }, + "305-AL1/39-ST1A 110.0": { + "c_nf_per_km": 9.2, + "r_ohm_per_km": 0.0949, + "x_ohm_per_km": 0.38, + "max_i_ka": 0.74, + "type": "ol", + "q_mm2": 305, + "alpha": 0.00403 + }, + "490-AL1/64-ST1A 110.0": { + "c_nf_per_km": 9.75, + "r_ohm_per_km": 0.059, + "x_ohm_per_km": 0.37, + "max_i_ka": 0.96, + "type": "ol", + "q_mm2": 490, + "alpha": 0.00403 + }, + "679-AL1/86-ST1A 110.0": { + "c_nf_per_km": 9.95, + "r_ohm_per_km": 0.042, + "x_ohm_per_km": 0.36, + "max_i_ka": 0.115, + "type": "ol", + "q_mm2": 679, + "alpha": 0.00403 + }, + "490-AL1/64-ST1A 220.0": { + "c_nf_per_km": 10, + "r_ohm_per_km": 0.059, + "x_ohm_per_km": 0.285, + "max_i_ka": 0.96, + "type": "ol", + "q_mm2": 490, + "alpha": 0.00403 + }, + "679-AL1/86-ST1A 220.0": { + "c_nf_per_km": 11.7, + "r_ohm_per_km": 0.042, + "x_ohm_per_km": 0.275, + "max_i_ka": 0.115, + "type": "ol", + "q_mm2": 679, + "alpha": 0.00403 + }, + "490-AL1/64-ST1A 380.0": { + "c_nf_per_km": 11, + "r_ohm_per_km": 0.059, + "x_ohm_per_km": 0.253, + "max_i_ka": 0.96, + "type": "ol", + "q_mm2": 490, + "alpha": 0.00403 + }, + "679-AL1/86-ST1A 380.0": { + "c_nf_per_km": 14.6, + "r_ohm_per_km": 0.042, + "x_ohm_per_km": 0.25, + "max_i_ka": 0.115, + "type": "ol", + "q_mm2": 679, + "alpha": 0.00403 + } + }, + "trafo": { + "160 MVA 380/110 kV": { + "i0_percent": 0.06, + "pfe_kw": 60, + "vkr_percent": 0.25, + "sn_mva": 160, + "vn_lv_kv": 110.0, + "vn_hv_kv": 380.0, + "vk_percent": 12.2, + "shift_degree": 0, + "vector_group": "Yy0", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -9, + "tap_max": 9, + "tap_step_degree": 0, + "tap_step_percent": 1.5, + "tap_phase_shifter": false + }, + "100 MVA 220/110 kV": { + "i0_percent": 0.06, + "pfe_kw": 55, + "vkr_percent": 0.26, + "sn_mva": 100, + "vn_lv_kv": 110.0, + "vn_hv_kv": 220.0, + "vk_percent": 12.0, + "shift_degree": 0, + "vector_group": "Yy0", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -9, + "tap_max": 9, + "tap_step_degree": 0, + "tap_step_percent": 1.5, + "tap_phase_shifter": false + }, + "63 MVA 110/20 kV": { + "i0_percent": 0.04, + "pfe_kw": 22, + "vkr_percent": 0.32, + "sn_mva": 63, + "vn_lv_kv": 20.0, + "vn_hv_kv": 110.0, + "vk_percent": 18, + "shift_degree": 150, + "vector_group": "YNd5", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -9, + "tap_max": 9, + "tap_step_degree": 0, + "tap_step_percent": 1.5, + "tap_phase_shifter": false + }, + "40 MVA 110/20 kV": { + "i0_percent": 0.05, + "pfe_kw": 18, + "vkr_percent": 0.34, + "sn_mva": 40, + "vn_lv_kv": 20.0, + "vn_hv_kv": 110.0, + "vk_percent": 16.2, + "shift_degree": 150, + "vector_group": "YNd5", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -9, + "tap_max": 9, + "tap_step_degree": 0, + "tap_step_percent": 1.5, + "tap_phase_shifter": false + }, + "25 MVA 110/20 kV": { + "i0_percent": 0.07, + "pfe_kw": 14, + "vkr_percent": 0.41, + "sn_mva": 25, + "vn_lv_kv": 20.0, + "vn_hv_kv": 110.0, + "vk_percent": 12, + "shift_degree": 150, + "vector_group": "YNd5", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -9, + "tap_max": 9, + "tap_step_degree": 0, + "tap_step_percent": 1.5, + "tap_phase_shifter": false + }, + "63 MVA 110/10 kV": { + "sn_mva": 63, + "vn_hv_kv": 110, + "vn_lv_kv": 10, + "vk_percent": 18, + "vkr_percent": 0.32, + "pfe_kw": 22, + "i0_percent": 0.04, + "shift_degree": 150, + "vector_group": "YNd5", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -9, + "tap_max": 9, + "tap_step_degree": 0, + "tap_step_percent": 1.5, + "tap_phase_shifter": false + }, + "40 MVA 110/10 kV": { + "sn_mva": 40, + "vn_hv_kv": 110, + "vn_lv_kv": 10, + "vk_percent": 16.2, + "vkr_percent": 0.34, + "pfe_kw": 18, + "i0_percent": 0.05, + "shift_degree": 150, + "vector_group": "YNd5", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -9, + "tap_max": 9, + "tap_step_degree": 0, + "tap_step_percent": 1.5, + "tap_phase_shifter": false + }, + "25 MVA 110/10 kV": { + "sn_mva": 25, + "vn_hv_kv": 110, + "vn_lv_kv": 10, + "vk_percent": 12, + "vkr_percent": 0.41, + "pfe_kw": 14, + "i0_percent": 0.07, + "shift_degree": 150, + "vector_group": "YNd5", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -9, + "tap_max": 9, + "tap_step_degree": 0, + "tap_step_percent": 1.5, + "tap_phase_shifter": false + }, + "0.25 MVA 20/0.4 kV": { + "sn_mva": 0.25, + "vn_hv_kv": 20, + "vn_lv_kv": 0.4, + "vk_percent": 6, + "vkr_percent": 1.44, + "pfe_kw": 0.8, + "i0_percent": 0.32, + "shift_degree": 150, + "vector_group": "Yzn5", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -2, + "tap_max": 2, + "tap_step_degree": 0, + "tap_step_percent": 2.5, + "tap_phase_shifter": false + }, + "0.4 MVA 20/0.4 kV": { + "sn_mva": 0.4, + "vn_hv_kv": 20, + "vn_lv_kv": 0.4, + "vk_percent": 6, + "vkr_percent": 1.425, + "pfe_kw": 1.35, + "i0_percent": 0.3375, + "shift_degree": 150, + "vector_group": "Dyn5", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -2, + "tap_max": 2, + "tap_step_degree": 0, + "tap_step_percent": 2.5, + "tap_phase_shifter": false + }, + "0.63 MVA 20/0.4 kV": { + "sn_mva": 0.63, + "vn_hv_kv": 20, + "vn_lv_kv": 0.4, + "vk_percent": 6, + "vkr_percent": 1.206, + "pfe_kw": 1.65, + "i0_percent": 0.2619, + "shift_degree": 150, + "vector_group": "Dyn5", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -2, + "tap_max": 2, + "tap_step_degree": 0, + "tap_step_percent": 2.5, + "tap_phase_shifter": false + }, + "0.25 MVA 10/0.4 kV": { + "sn_mva": 0.25, + "vn_hv_kv": 10, + "vn_lv_kv": 0.4, + "vk_percent": 4, + "vkr_percent": 1.2, + "pfe_kw": 0.6, + "i0_percent": 0.24, + "shift_degree": 150, + "vector_group": "Dyn5", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -2, + "tap_max": 2, + "tap_step_degree": 0, + "tap_step_percent": 2.5, + "tap_phase_shifter": false + }, + "0.4 MVA 10/0.4 kV": { + "sn_mva": 0.4, + "vn_hv_kv": 10, + "vn_lv_kv": 0.4, + "vk_percent": 4, + "vkr_percent": 1.325, + "pfe_kw": 0.95, + "i0_percent": 0.2375, + "shift_degree": 150, + "vector_group": "Dyn5", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -2, + "tap_max": 2, + "tap_step_degree": 0, + "tap_step_percent": 2.5, + "tap_phase_shifter": false + }, + "0.63 MVA 10/0.4 kV": { + "sn_mva": 0.63, + "vn_hv_kv": 10, + "vn_lv_kv": 0.4, + "vk_percent": 4, + "vkr_percent": 1.0794, + "pfe_kw": 1.18, + "i0_percent": 0.1873, + "shift_degree": 150, + "vector_group": "Dyn5", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -2, + "tap_max": 2, + "tap_step_degree": 0, + "tap_step_percent": 2.5, + "tap_phase_shifter": false + } + }, + "trafo3w": { + "63/25/38 MVA 110/20/10 kV": { + "sn_hv_mva": 63, + "sn_mv_mva": 25, + "sn_lv_mva": 38, + "vn_hv_kv": 110, + "vn_mv_kv": 20, + "vn_lv_kv": 10, + "vk_hv_percent": 10.4, + "vk_mv_percent": 10.4, + "vk_lv_percent": 10.4, + "vkr_hv_percent": 0.28, + "vkr_mv_percent": 0.32, + "vkr_lv_percent": 0.35, + "pfe_kw": 35, + "i0_percent": 0.89, + "shift_mv_degree": 0, + "shift_lv_degree": 0, + "vector_group": "YN0yn0yn0", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -10, + "tap_max": 10, + "tap_step_percent": 1.2 + }, + "63/25/38 MVA 110/10/10 kV": { + "sn_hv_mva": 63, + "sn_mv_mva": 25, + "sn_lv_mva": 38, + "vn_hv_kv": 110, + "vn_mv_kv": 10, + "vn_lv_kv": 10, + "vk_hv_percent": 10.4, + "vk_mv_percent": 10.4, + "vk_lv_percent": 10.4, + "vkr_hv_percent": 0.28, + "vkr_mv_percent": 0.32, + "vkr_lv_percent": 0.35, + "pfe_kw": 35, + "i0_percent": 0.89, + "shift_mv_degree": 0, + "shift_lv_degree": 0, + "vector_group": "YN0yn0yn0", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -10, + "tap_max": 10, + "tap_step_percent": 1.2 + } + } + }, + "res_bus": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"vm_pu\",\"va_degree\",\"p_mw\",\"q_mvar\"],\"index\":[0,1,2,3,4],\"data\":[[1.02,-0.845445168673926,0.0,-111.791243672370911],[1.02,0.0,-21.729831330858325,116.839935541152954],[1.019214100496144,-0.409103297622625,0.0,0.0],[1.018637116919488,-0.503470352662766,10.0,7.0],[1.017983079721402,-0.653497665026562,10.0,7.0]]}", + "dtype": { + "vm_pu": "float64", + "va_degree": "float64", + "p_mw": "float64", + "q_mvar": "float64" + }, + "orient": "split" + }, + "res_line": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_from_mw\",\"q_from_mvar\",\"p_to_mw\",\"q_to_mvar\",\"pl_mw\",\"ql_mvar\",\"i_from_ka\",\"i_to_ka\",\"i_ka\",\"vm_from_pu\",\"va_from_degree\",\"vm_to_pu\",\"va_to_degree\",\"loading_percent\"],\"index\":[0,1,2,3,4,5,6,7],\"data\":[[-7.167647147657727,57.480079867900443,8.03525639977348,-60.113463233922118,0.867609252115754,-2.633383366021676,0.327874112511858,0.343286326507116,0.343286326507116,1.02,-0.845445168673926,1.02,0.0,57.214387751185988],[-0.657313913963437,25.969126903729045,0.866078469150186,-29.007927174007612,0.208764555186749,-3.038800270278568,0.147040043868819,0.164393305610081,0.164393305610081,1.02,-0.845445168673926,1.019214100496144,-0.409103297622625,74.724229822763931],[1.64566972119938,15.370129751576128,-1.540268914180618,-19.229415550834709,0.105400807018762,-3.859285799258581,0.087496748884432,0.109338903896103,0.109338903896103,1.02,-0.845445168673926,1.018637116919488,-0.503470352662766,68.336814935064211],[6.179291340421495,12.971907266349552,-6.119076735247816,-15.70424981919658,0.060214605173678,-2.732342552847028,0.081330018729726,0.095589209712924,0.095589209712924,1.02,-0.845445168673926,1.017983079721402,-0.653497665026562,59.743256070577175],[13.694574931085771,-56.726472302863066,-13.283848894885464,55.407854241119566,0.410726036200307,-1.3186180617435,0.330312825878128,0.322760996590474,0.330312825878128,1.02,0.0,1.019214100496144,-0.409103297622625,55.052137646354595],[6.208885212872048,-13.199963533555254,-6.184761786109662,11.833197159642042,0.024123426762386,-1.366766373913212,0.082632108556076,0.075677384410291,0.082632108556076,1.019214100496144,-0.409103297622625,1.018637116919488,-0.503470352662766,27.544036185358689],[6.208885212872048,-13.199963533555254,-6.184761786109662,11.833197159642042,0.024123426762386,-1.366766373913212,0.082632108556076,0.075677384410291,0.082632108556076,1.019214100496144,-0.409103297622625,1.018637116919488,-0.503470352662766,27.544036185358689],[3.909792486391969,-11.436978768449999,-3.88092326475316,8.704249819196738,0.028869221638809,-2.732728949253261,0.068506463438984,0.054050881891821,0.068506463438984,1.018637116919488,-0.503470352662766,1.017983079721402,-0.653497665026562,42.816539649365005]]}", + "dtype": { + "p_from_mw": "float64", + "q_from_mvar": "float64", + "p_to_mw": "float64", + "q_to_mvar": "float64", + "pl_mw": "float64", + "ql_mvar": "float64", + "i_from_ka": "float64", + "i_to_ka": "float64", + "i_ka": "float64", + "vm_from_pu": "float64", + "va_from_degree": "float64", + "vm_to_pu": "float64", + "va_to_degree": "float64", + "loading_percent": "float64" + }, + "orient": "split" + }, + "res_trafo": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_hv_mw\",\"q_hv_mvar\",\"p_lv_mw\",\"q_lv_mvar\",\"pl_mw\",\"ql_mvar\",\"i_hv_ka\",\"i_lv_ka\",\"vm_hv_pu\",\"va_hv_degree\",\"vm_lv_pu\",\"va_lv_degree\",\"loading_percent\"],\"index\":[],\"data\":[]}", + "dtype": { + "p_hv_mw": "float64", + "q_hv_mvar": "float64", + "p_lv_mw": "float64", + "q_lv_mvar": "float64", + "pl_mw": "float64", + "ql_mvar": "float64", + "i_hv_ka": "float64", + "i_lv_ka": "float64", + "vm_hv_pu": "float64", + "va_hv_degree": "float64", + "vm_lv_pu": "float64", + "va_lv_degree": "float64", + "loading_percent": "float64" + }, + "orient": "split" + }, + "res_trafo3w": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_hv_mw\",\"q_hv_mvar\",\"p_mv_mw\",\"q_mv_mvar\",\"p_lv_mw\",\"q_lv_mvar\",\"pl_mw\",\"ql_mvar\",\"i_hv_ka\",\"i_mv_ka\",\"i_lv_ka\",\"vm_hv_pu\",\"va_hv_degree\",\"vm_mv_pu\",\"va_mv_degree\",\"vm_lv_pu\",\"va_lv_degree\",\"va_internal_degree\",\"vm_internal_pu\",\"loading_percent\"],\"index\":[],\"data\":[]}", + "dtype": { + "p_hv_mw": "float64", + "q_hv_mvar": "float64", + "p_mv_mw": "float64", + "q_mv_mvar": "float64", + "p_lv_mw": "float64", + "q_lv_mvar": "float64", + "pl_mw": "float64", + "ql_mvar": "float64", + "i_hv_ka": "float64", + "i_mv_ka": "float64", + "i_lv_ka": "float64", + "vm_hv_pu": "float64", + "va_hv_degree": "float64", + "vm_mv_pu": "float64", + "va_mv_degree": "float64", + "vm_lv_pu": "float64", + "va_lv_degree": "float64", + "va_internal_degree": "float64", + "vm_internal_pu": "float64", + "loading_percent": "float64" + }, + "orient": "split" + }, + "res_impedance": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_from_mw\",\"q_from_mvar\",\"p_to_mw\",\"q_to_mvar\",\"pl_mw\",\"ql_mvar\",\"i_from_ka\",\"i_to_ka\"],\"index\":[],\"data\":[]}", + "dtype": { + "p_from_mw": "float64", + "q_from_mvar": "float64", + "p_to_mw": "float64", + "q_to_mvar": "float64", + "pl_mw": "float64", + "ql_mvar": "float64", + "i_from_ka": "float64", + "i_to_ka": "float64" + }, + "orient": "split" + }, + "res_ext_grid": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_mw\",\"q_mvar\"],\"index\":[],\"data\":[]}", + "dtype": { + "p_mw": "float64", + "q_mvar": "float64" + }, + "orient": "split" + }, + "res_load": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_mw\",\"q_mvar\"],\"index\":[0,1,2],\"data\":[[10.0,7.0],[10.0,7.0],[10.0,7.0]]}", + "dtype": { + "p_mw": "float64", + "q_mvar": "float64" + }, + "orient": "split" + }, + "res_sgen": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_mw\",\"q_mvar\"],\"index\":[],\"data\":[]}", + "dtype": { + "p_mw": "float64", + "q_mvar": "float64" + }, + "orient": "split" + }, + "res_storage": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_mw\",\"q_mvar\"],\"index\":[],\"data\":[]}", + "dtype": { + "p_mw": "float64", + "q_mvar": "float64" + }, + "orient": "split" + }, + "res_shunt": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_mw\",\"q_mvar\",\"vm_pu\"],\"index\":[],\"data\":[]}", + "dtype": { + "p_mw": "float64", + "q_mvar": "float64", + "vm_pu": "float64" + }, + "orient": "split" + }, + "res_gen": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_mw\",\"q_mvar\",\"va_degree\",\"vm_pu\"],\"index\":[0,1],\"data\":[[10.0,118.791243672370911,-0.845445168673926,1.02],[21.729831330858325,-116.839935541152954,0.0,1.02]]}", + "dtype": { + "p_mw": "float64", + "q_mvar": "float64", + "va_degree": "float64", + "vm_pu": "float64" + }, + "orient": "split" + }, + "res_ward": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_mw\",\"q_mvar\",\"vm_pu\"],\"index\":[],\"data\":[]}", + "dtype": { + "p_mw": "float64", + "q_mvar": "float64", + "vm_pu": "float64" + }, + "orient": "split" + }, + "res_xward": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_mw\",\"q_mvar\",\"vm_pu\",\"va_internal_degree\",\"vm_internal_pu\"],\"index\":[],\"data\":[]}", + "dtype": { + "p_mw": "float64", + "q_mvar": "float64", + "vm_pu": "float64", + "va_internal_degree": "float64", + "vm_internal_pu": "float64" + }, + "orient": "split" + }, + "res_dcline": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_from_mw\",\"q_from_mvar\",\"p_to_mw\",\"q_to_mvar\",\"pl_mw\",\"vm_from_pu\",\"va_from_degree\",\"vm_to_pu\",\"va_to_degree\"],\"index\":[],\"data\":[]}", + "dtype": { + "p_from_mw": "float64", + "q_from_mvar": "float64", + "p_to_mw": "float64", + "q_to_mvar": "float64", + "pl_mw": "float64", + "vm_from_pu": "float64", + "va_from_degree": "float64", + "vm_to_pu": "float64", + "va_to_degree": "float64" + }, + "orient": "split" + }, + "user_pf_options": {}, + "OPF_converged": false + } +} diff --git a/grid2op/data_test/5bus_example_act_topo_set_init/chronics/0/hazards.csv.bz2 b/grid2op/data_test/5bus_example_act_topo_set_init/chronics/0/hazards.csv.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..5257b64d87924cf39779885383b1eb28f134ca3a GIT binary patch literal 84 zcmV-a0IUB(T4*^jL0KkKSwFUueE?#8+5i9$00Do9005u>av`A50&0+m$n$DKD%z+X qicp+Y145K1?QN?v%Ndn&q@g?cdA%}7a?qj`{9VZu;X*+E+D-H;Z6nG6 literal 0 HcmV?d00001 diff --git a/grid2op/data_test/5bus_example_act_topo_set_init/chronics/0/init_state.json b/grid2op/data_test/5bus_example_act_topo_set_init/chronics/0/init_state.json new file mode 100644 index 000000000..4442bc19e --- /dev/null +++ b/grid2op/data_test/5bus_example_act_topo_set_init/chronics/0/init_state.json @@ -0,0 +1,3 @@ +{ + "set_bus": {"lines_or_id": [["0_2_1", 2]], "loads_id": [["load_0_0", 2]]} +} \ No newline at end of file diff --git a/grid2op/data_test/5bus_example_act_topo_set_init/chronics/0/load_p.csv.bz2 b/grid2op/data_test/5bus_example_act_topo_set_init/chronics/0/load_p.csv.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..df894b76b6a8bc1b70bb1463c061ab7a664af71d GIT binary patch literal 2599 zcmV+?3fT2RT4*^jL0KkKSvLQAQvfh2+W-I%00DpK005)};1hE}#;G;5)rMj5@&Kg( z3Z+uRy=a!3R*hfzUZ1`migH0M}H9sO!N>dO9o=B8R9-s|8k|k6BRRl0i zN=gBmfE1ESlRyJc^~v=9{iY3nqfV)LR7-p%i%l04p8pA@8O?&*0G*>|w5G`{n*m_4 zF*yWBER|bni~=x1|IxOb$JTCk7y-Nyl;aeP5Ynf+X|fs*KsY1};Prpk(Y@GiNqP85 z+I5ek9|QI4stE`CIMuaAD$j{xkxMgbf&i-s;&~%lV#`T=eVMEIop79L!Z?(pS#i6g zq<{e^w5Nn5=NJ;=T8cto2t%3Iz*Yim0fr>C2u@pMMG_TAxSqROp1daDB#MFvY)OCum^gfNyv zYh^K-c-@41Q@dg{8a|rKhe>Od*iF~=y=4udRty(o$+R0%(WVaYEUROX7 zMj!zqA)^d3e9~264|zwz|H7e=5?~&AWBgR&byuN9ci1sl^u#e`)7LelZFJETZt1b zA#6$Jl8N%x;1Qf1BzBUVcMG|8IDl~z0vw4PSPZu3LKqrFe+Crv9dPeYbPEi5A75Q0 zD09a1PJ)rP{co3hAr=wqQ43skMSU3dIo372!%(|c4KQkVyIR@Z&fR_=kIJvf4^VM- zt5#Mm7&W2GQznKiu*_$>Hkx8;nGB|urKT;LCrVvV;#I)rix`?TYHc>0R!plEqS2F0 zt?DtP!I6r{#cLM8@>i;ylX6y>8jQ5Iry9|zk(AKImN%xuEUQVSiqk2KQR;`4I3KO) zjJ7AOEm;^fVAyTr8d@5blUAb^Sl7bj$Yfw?T4=V3eEOyJE6Vll7|f4lhNcXbizbsW zc-4y)q|stwiw)>&D$`2D(89(Qd_JmuA;rv?W=o8kv^1DBvema%#;Zk>6D6f#hNfrN zYGxT~)n*0tPmz2hld@@;uEtm}WU(<|*0;M1m{?dDMyZt5lW(1xZLu$f@UNme?OP04 zVmlU1CYDPhD<+w}+L>fxvYA$b_IqA5|`=3^8UV$mUwIHCZgISTxhd)X{?# zqSRo-!ws)g@Q#snU0AYMWNRy#HDJY}%F(M@ZyajXk)@Qd#&^jcoO1O(j zGL{s+SH_n^4KLLbv@mhSUOL5Pqhy^LSmBZ#Nx-<{S^r^dS&F-TyzgNzTLz+ik*Sy%%1 zPKy&UQ`xm)>^d5C#3WTfB={ByB8+Ap6MH%-_sqM1_fraya2HE1ZMHCwtxR$R?MN(Z z5DPx2$HA<#QiBpo#}Wi5zR#y%08YZz+fJJ;Ef_&fu8Rav93#;Q@sid#2#_L679)zt zv@Tfy_jvX8C6Tp*Y$)R)&z4aJ7JO-ib`-2p+hJ|m%@oDh+7YjZoddlQ3?-^r?bN9+ zGS&mVU_x12^PyoCkt`@45Wu*Sn|Ka!dnu_d##~pFGdwVa z3iw$|+YN7+>jaEoX=iQh07f3hs6@w_vZWYQJsE1@6i~Eij3I+5m+RfkiUBx}%V8LZ zk>Wn3;1RgP4AreAV;=>uxSVNlR3I$k;Ve*6Gp!q~zKBRh2AHXkVA!J{J`>g}44TA_ zj$F2WG)BW(ELmh0Y%*HFeNxjJm|#lMRbdA=fSb^ZfV|v`)hNfrstX%f*&6|-FioYf zC1Qvtgei=cwW&W>_jo{Ij017BJy~ihe9UcaIUa1=2fIzBmbs;tOFcw6dWnP^a4v zn*bC##{)Htoquz;d4VtIz1?K0)s=kC*1=O&d}vrcdUtN3cT0tu76*%4Z96q^_<>$a z=fx>Y0z$DhQvu$7w8bpY@`Jujk(a+O; zcHp<-pG-=>!z$^2thNzxN`zPOO9E^*9x>uUX(g4#l&9mn5?I1LiGJK*IFT&uCHaWA z#S#PvKWz!6Uu?Ux>+9_K^Csjj*;+5cJDUNVPS}!kdb4e)WtD{*Hq^t`@v6WN%<5+S zQuy)yb|cN5*6lhThVzu z7@j%Bgv$YCi&sM%H2ZYVx6#nQ-+r*qTj*HUL}$r!j)7v%l&yfINK|^3FjQkdSzV!( z;&wU@G?o84?fl+mB(Rp8<9L}0cI@bTl-un7%+I%bQ6LH{tlDP4n+ZxA_tD<={J2=n z`)!H}tX6q4lWkW~qzL{Hr7nExO|qk^Y;sHKu_?*MKgE>K#PKSJnvWYH(Y zr9Bv{mSgvN?(HGtAC!7hegb?Q>Eb86-R8m+hylb&QH~!56@&WmWTPVWO*;3$LDJ4Y zS&4m{V&GOFF;0M%6-LWf;zwN@8zAc_N%P8_deGft;@reF#I(c*K8)F?oZVAP82zzo z7d958wx?|@{ZKng_QctUW`sWGJ*7%g6FMF&SF1A+$T($Xveg;AAy%SKk6=moyOJrw Jgn_sF(wGWx#)<#{ literal 0 HcmV?d00001 diff --git a/grid2op/data_test/5bus_example_act_topo_set_init/chronics/0/load_p_forecasted.csv.bz2 b/grid2op/data_test/5bus_example_act_topo_set_init/chronics/0/load_p_forecasted.csv.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..d91236226918e0815e81240016e95d5edfffe5b9 GIT binary patch literal 1073 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∋VQUW#<KY0%#-w%Dra`GJ9NLd-7L{<0Qs`5N-(MA&|j!aJ_MN+8B z#mfq-T8*e)DdOk7C{ml(RCIA#9o{5|5oRBr>0I3r(pX(olI6O>BTSRC=TD6LZ1=Vm zP|L1{u9#P7$wqrB>#DV!OrnW=6;Tl$_n=kez4OeO^HkQ^3hO1ps*A2}$hei26=tH3 zPai0|uDaK&=Nm&ou2faoEZMdDv};_~Q8L3{ z$5a|Mw=7&UDQptUURKvDr6goX+Eo(D^KH5(8KjvSoAg_yEb`UYa|Uh8cCn_OYpb_J z32dmTEQ)IN4H(2$HKwr`l-|OFMKUdPHFdT#WwEXHYa=QthTNlW)|EB0ExgGl$zw$b zn`@Tcs8qFyG#cKZ6%tjH%TfV?tJI1zTFIMODonD~=#>_!3pT8#B9m8|*%?!6H5iKx zn@M}+u$qmVOV5EGAv)>@M6Uv_k#GzpijGL-E2vhAVx`EAA<9;O$y21AMCz%OEL3QW zgV?L8sl<*Bs+^(0(pAYvN_2+>I!7ouNZhL`xQ?O0PDybbg@rUJ#9uNi>iX!R>d8rL zrENf~X$!(CycR`u3V6j1sa_F@Od3+Os|aK=DX1|@)GaESgA_GYlo%#KWGzW@g)}D- zX#+%PiqtX_C0c~ZEI`VpP%$e(84-li7f6#;6{HE~^qOps zRY(b1?O#?YBO1oTZQAjzl2a9~+kH`qD#{XBYjxl;8*E}3t9Gxls3{qu*;yFM4Q<|R zr2=KO8zmDpqPJ~*(_=(QrKSl=YTf8rG-i_48A+-ucKej1Y{F(*uJq9~l9tUaCM|XM zNK{2L8r9nLr7Rhw)M$%c_L+=YF}60>=(QI7-jvK{T3ITh45qi_9@etbvdqUz%GI`G z6}14RSLLl=6jNqXW};Iav`A50&0+m$n$DKD%z+X qicp+Y145K1?QN?v%Ndn&q@g?cdA%}7a?qj`{9VZu;X*+E+D-H;Z6nG6 literal 0 HcmV?d00001 diff --git a/grid2op/data_test/5bus_example_act_topo_set_init/chronics/0/maintenance_forecasted.csv.bz2 b/grid2op/data_test/5bus_example_act_topo_set_init/chronics/0/maintenance_forecasted.csv.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..5257b64d87924cf39779885383b1eb28f134ca3a GIT binary patch literal 84 zcmV-a0IUB(T4*^jL0KkKSwFUueE?#8+5i9$00Do9005u>av`A50&0+m$n$DKD%z+X qicp+Y145K1?QN?v%Ndn&q@g?cdA%}7a?qj`{9VZu;X*+E+D-H;Z6nG6 literal 0 HcmV?d00001 diff --git a/grid2op/data_test/5bus_example_act_topo_set_init/chronics/0/maintenance_meta.json b/grid2op/data_test/5bus_example_act_topo_set_init/chronics/0/maintenance_meta.json new file mode 100644 index 000000000..e6faa8ec2 --- /dev/null +++ b/grid2op/data_test/5bus_example_act_topo_set_init/chronics/0/maintenance_meta.json @@ -0,0 +1,7 @@ +{ + "maintenance_starting_hour": 9 , + "maintenance_ending_hour": 17, + "line_to_maintenance": ["0_1_0", "2_3_5"], + "daily_proba_per_month_maintenance": [0.0, 0.0, 0.0, 0.02, 0.02, 0.03, 0.05, 0.06, 0.03, 0.02, 0.0, 0.0], + "max_daily_number_per_month_maintenance": [0, 0, 0, 1, 1, 2, 2, 2, 1, 1, 0, 0] +} diff --git a/grid2op/data_test/5bus_example_act_topo_set_init/chronics/0/prod_p.csv.bz2 b/grid2op/data_test/5bus_example_act_topo_set_init/chronics/0/prod_p.csv.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..45ae98a8e29e7001d8c2f7e8e9160f77b69fe6ab GIT binary patch literal 3326 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�YLhgZXuB@Kp%x6=LPYcl zQC6dq9J*;46uB~HQ+U!&8FP1bE|-F28pFWJUDB7l!G?C$T{W1k8p=Fz`e-4%a(KlF zuD9#asYkO66`v3gn5Do%Rp5b^s_P5P60ZslQWOxZWK8lE!7cp*cXmv}N*z;r%kW-Ar8vC46MV( lUKnAOQsklu38eY`PcCNfB%R0UC9*TLO>U~ZHQi?+w}kd literal 0 HcmV?d00001 diff --git a/grid2op/data_test/5bus_example_act_topo_set_init/chronics/0/prod_v.csv.bz2 b/grid2op/data_test/5bus_example_act_topo_set_init/chronics/0/prod_v.csv.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..9fde13d8afbe1db215c8c51ccead2bcb59bc25b0 GIT binary patch literal 78 zcmV-U0I~luTcBmuHbT0jyk9CrW! literal 0 HcmV?d00001 diff --git a/grid2op/data_test/5bus_example_act_topo_set_init/chronics/1/hazards.csv.bz2 b/grid2op/data_test/5bus_example_act_topo_set_init/chronics/1/hazards.csv.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..5257b64d87924cf39779885383b1eb28f134ca3a GIT binary patch literal 84 zcmV-a0IUB(T4*^jL0KkKSwFUueE?#8+5i9$00Do9005u>av`A50&0+m$n$DKD%z+X qicp+Y145K1?QN?v%Ndn&q@g?cdA%}7a?qj`{9VZu;X*+E+D-H;Z6nG6 literal 0 HcmV?d00001 diff --git a/grid2op/data_test/5bus_example_act_topo_set_init/chronics/1/init_state.json b/grid2op/data_test/5bus_example_act_topo_set_init/chronics/1/init_state.json new file mode 100644 index 000000000..9a4c0b72f --- /dev/null +++ b/grid2op/data_test/5bus_example_act_topo_set_init/chronics/1/init_state.json @@ -0,0 +1,3 @@ +{ + "set_line_status": [["0_2_1", -1]] +} diff --git a/grid2op/data_test/5bus_example_act_topo_set_init/chronics/1/load_p.csv.bz2 b/grid2op/data_test/5bus_example_act_topo_set_init/chronics/1/load_p.csv.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..99b3b13ccd6961ad6e2b63a8a0ea6d67ac25808d GIT binary patch literal 2512 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 literal 0 HcmV?d00001 diff --git a/grid2op/data_test/5bus_example_act_topo_set_init/chronics/1/load_q.csv.bz2 b/grid2op/data_test/5bus_example_act_topo_set_init/chronics/1/load_q.csv.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..baa7808696708c00d1811f07aba1a590542d3dc4 GIT binary patch literal 1965 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 W-E#hZzdcuav`A50&0+m$n$DKD%z+X qicp+Y145K1?QN?v%Ndn&q@g?cdA%}7a?qj`{9VZu;X*+E+D-H;Z6nG6 literal 0 HcmV?d00001 diff --git a/grid2op/data_test/5bus_example_act_topo_set_init/chronics/1/maintenance_forecasted.csv.bz2 b/grid2op/data_test/5bus_example_act_topo_set_init/chronics/1/maintenance_forecasted.csv.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..5257b64d87924cf39779885383b1eb28f134ca3a GIT binary patch literal 84 zcmV-a0IUB(T4*^jL0KkKSwFUueE?#8+5i9$00Do9005u>av`A50&0+m$n$DKD%z+X qicp+Y145K1?QN?v%Ndn&q@g?cdA%}7a?qj`{9VZu;X*+E+D-H;Z6nG6 literal 0 HcmV?d00001 diff --git a/grid2op/data_test/5bus_example_act_topo_set_init/chronics/1/maintenance_meta.json b/grid2op/data_test/5bus_example_act_topo_set_init/chronics/1/maintenance_meta.json new file mode 100644 index 000000000..e6faa8ec2 --- /dev/null +++ b/grid2op/data_test/5bus_example_act_topo_set_init/chronics/1/maintenance_meta.json @@ -0,0 +1,7 @@ +{ + "maintenance_starting_hour": 9 , + "maintenance_ending_hour": 17, + "line_to_maintenance": ["0_1_0", "2_3_5"], + "daily_proba_per_month_maintenance": [0.0, 0.0, 0.0, 0.02, 0.02, 0.03, 0.05, 0.06, 0.03, 0.02, 0.0, 0.0], + "max_daily_number_per_month_maintenance": [0, 0, 0, 1, 1, 2, 2, 2, 1, 1, 0, 0] +} diff --git a/grid2op/data_test/5bus_example_act_topo_set_init/chronics/1/prod_p.csv.bz2 b/grid2op/data_test/5bus_example_act_topo_set_init/chronics/1/prod_p.csv.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..180acf18edd3f15fcba99cd8f4ef6d8dcc9f4d1e GIT binary patch literal 3271 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 FY!E%^ACLe5 literal 0 HcmV?d00001 diff --git a/grid2op/data_test/5bus_example_act_topo_set_init/chronics/1/prod_p_forecasted.csv.bz2 b/grid2op/data_test/5bus_example_act_topo_set_init/chronics/1/prod_p_forecasted.csv.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..5cb7f768c00d8590ce6f5c5d6d967d91870b9b69 GIT binary patch literal 3001 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 literal 0 HcmV?d00001 diff --git a/grid2op/data_test/5bus_example_act_topo_set_init/chronics/1/prod_v.csv.bz2 b/grid2op/data_test/5bus_example_act_topo_set_init/chronics/1/prod_v.csv.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..9fde13d8afbe1db215c8c51ccead2bcb59bc25b0 GIT binary patch literal 78 zcmV-U0I~luTcBmuHbT0jyk9CrW! literal 0 HcmV?d00001 diff --git a/grid2op/data_test/5bus_example_act_topo_set_init/chronics/2/hazards.csv.bz2 b/grid2op/data_test/5bus_example_act_topo_set_init/chronics/2/hazards.csv.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..5257b64d87924cf39779885383b1eb28f134ca3a GIT binary patch literal 84 zcmV-a0IUB(T4*^jL0KkKSwFUueE?#8+5i9$00Do9005u>av`A50&0+m$n$DKD%z+X qicp+Y145K1?QN?v%Ndn&q@g?cdA%}7a?qj`{9VZu;X*+E+D-H;Z6nG6 literal 0 HcmV?d00001 diff --git a/grid2op/data_test/5bus_example_act_topo_set_init/chronics/2/init_state.json b/grid2op/data_test/5bus_example_act_topo_set_init/chronics/2/init_state.json new file mode 100644 index 000000000..f244dbf6f --- /dev/null +++ b/grid2op/data_test/5bus_example_act_topo_set_init/chronics/2/init_state.json @@ -0,0 +1,3 @@ +{ + "set_bus": {"lines_or_id": [["0_2_1", 2]], "lines_ex_id": [["2_3_5", 2]]} +} diff --git a/grid2op/data_test/5bus_example_act_topo_set_init/chronics/2/load_p.csv.bz2 b/grid2op/data_test/5bus_example_act_topo_set_init/chronics/2/load_p.csv.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..36a5a5db2ad1fb8675c0e4bbe12ecd9c4ff214f7 GIT binary patch literal 2593 zcmV++3f}cXT4*^jL0KkKSwJrU{s1qd+W-I%00DpK005)};1gZcbrh6Z8rWid`Uy}_ zRD~&C??%kUY{ijnX2y-1YPOX&)YfgPd`6~*jTlV^r{qyWsfmEo$r6ROHvZLk%sht=I!;~^nx zRty)JZSK5Bt;LWyVM{HRmO$oPz>WKxs7|GJ1htAM9w1RCWhl1%-V=-#0SUt+i=1V~ z->U1XXlhWzgm{ryRuItQU)xiJ#6cTsR+o~Dh9V|xDgp?8qaSuNu->R*n1PJ4z*3d= z&Di2)QW<8O2z=dnhYc-?DHzJI=xD;*uA(inQWhaJ{NnEIYQqjGVMqzqYLS4)gC(?< z#txZ7ADrk@r!KGDY~JL9HGP2!OAVL0>?bP9l~JvV^bdzK7hGB+ zsDd$sI#^z}l;l*RSAk+fHO(6l(Xgy!S^Hp@JjxV*J=pl#r@2e(%djL7Hx(e-L>OCa zGsoPSDU27#8v4?*+_0CFA~=<4g8I@}?Y4a7xy>bE@uhRfU(xXk-DZ+*5h#ISfCM(n zSUG6bBqSsH$!)*9@w#;0d_GCM%VZ~1va#Oo(1cte80gIl7)JYQU`tCYU=Z`|+gVP{ zSVxE&4c2|Oe#qIXpzsNq17@9Te+wi;`Xx zc&DU1k?AAVQ_7RnuPS(k!|dTMsJfzh2b6lE;^8hxbyRfdT}tXhl{qERR}?t7rzLSC zl5~rTS8Y*oTt`8{I;F)`$Sz03r1XkeN}mixd{RC!n{9yFn_d-8)J>8G$V%A|ye_er zX|*ubhS1TmVXRq=iI&x)EjFI2QIhm+8J4SJVX)PiW-X{{W(>4tW(J!^YO-L&%NEeJ zwHawxnyU*|641cpA%S&RWt%F#xYHG7a(J_-@c;xdaE+t}# zR}ze5BmpEL5g`?ol9Pz*gqoxQgzxImozvBZ01(j}@G(ediMxhtOhN_$0ALtt0U1yE zU%5HcHqHeuUbhwMo5Qzd($Qm6FZ6z+*Wo>p@Ve>R8*AD$SSP(SJ zVpS!qdfXt7REv=@L{r7Yl!GDxk$-c+?paJ&Bqx?G1}BOF%_#^#u<+&LKC1Y*jTV|fDHw>F$wU5Fqu?~Yb~S#pSpX{io{?uiZ>9f zXu?$|GS+S|Fu;zfC##IIT>9IsAqp_XDh;ut!is0y>>zZA81~wN^NG7-eHm!Mb$)B!VTzLpaX$B&&a7>vFV~D&5(XYpJ4-B58-ZC%Yhl3T z6#Vmj)6n|c^Siaj3qb-CtRV6V;vv%A(knFE?z2q2dq!#2*M>M-3-ZfQO4uSwLbB&* ztVmAIIbLeM+F`p`B-|#JL^aBAQ>^9NZWq=}Zo6tVORcLdewn1>QI?CA+Jp@gw;B!* zHVgtntf~0h5S;NnAaRGRur!-@T(}slaR5+Y!13(v0=WaGuWmPz!4YFw6pW?w>ZdCp z64AQG;Ig5JS!}Q4CH%wp-+Wna1{M|eiaIHH%PoRLTVk+-_0`;Hnlc8fcda*!AOW6o ze8pl|>hkDqwkpCUXnBql2eZWZ{JzZ`^49ppLyfNs1FXe_sECkhE?TuA1JH@NZHZtw zh^%6W3Lfedfbi?lH^L+cJYfS7{WNoEtGAtQoC2zDW1LDWukUQJXno{gz zY)NVZWqU5h2Hm1VGW%MFD591hetifZV4kt8tMW(HumvPBY}vpNm-XUHdcwy$6l_WS z?}t>+XCJ#7M-{aBu?dyJd5&Z8<9H@QQp9LKdU|yTKU6Fu#5LQOS|k>Ewm2|&^58Ow z<~BHf{ZF79k7+3GmyDJH-n2W`su|pxkDjpFfL*nj8rwS4X1>hgR DU|Y%4 literal 0 HcmV?d00001 diff --git a/grid2op/data_test/5bus_example_act_topo_set_init/chronics/2/load_p_forecasted.csv.bz2 b/grid2op/data_test/5bus_example_act_topo_set_init/chronics/2/load_p_forecasted.csv.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..c639bd5287556a14d8bacab05375d0a07777395b GIT binary patch literal 1059 zcmV+;1l;>VT4*^jL0KkKS?TK_9{?|nX0+LZwXQ*j3-=Ds(;j=|=(AcZ> znpf<(7bU+Ha~qgfle&o9U%aitE3&1(7}GV)7?W2sYxqXNnQG-p5L=Shnu8&oxrWZ; zD)vE}xRTSguz1AAnYLC%6U%hzM9|h+lw&HrWMI`QikVF-dPyWkD@~2FFi|D9 zrXbN`(`?YFt?g1`HpR3JlVet+<~E6ywAmZlo{IL8$yJhKOHiFv)f|e#v@D9WMablr zNjQg6T@d9shaq(p$xaCA9ZKp)QjUspit0`apyWI>Y8@|Qxsaim!Wpn%C#01Y9*m!j8wH$)U+)VB(zoo1hT&sQnrwd zh!?BDg^FsLlM^F~p{jB`OVvD6(D5E4$X6yG7AvZ6I3xH5@3xgX-TS#rC2LM zSQe6K>J<3<)%V)bYX*&*VM^P68h5PQb{OT`ZCrTD*GshB9_5`UIegnoX51W4roxR=WJ#%8GK zUnbLL$2}u!8oO$*WI*43G?ijBMXuJjr2ucgF-;kzswhh)*UMV+P;UChlxW*QMk21Y zUV%RRlM#ukN}09RtH_DpVrgR1CM|WXdm1A(_v1{oYGyU^*1a^LPWz@9sUu?=?X`Jj zBHew;Wr(7hEr^u0^0mDn*q|}G`f-$6-yIbsKX2fi;GcA0ruQ82gP^Rs#x?-88%wi?4n^y5LjFzPm?QfvgSZQe_ z8d~{lUdk?Dtixgwk>NObj(4}f!R`y>DW literal 0 HcmV?d00001 diff --git a/grid2op/data_test/5bus_example_act_topo_set_init/chronics/2/load_q.csv.bz2 b/grid2op/data_test/5bus_example_act_topo_set_init/chronics/2/load_q.csv.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..ad307afafacdbdcc24d57a333f0589eb61ed3479 GIT binary patch literal 2082 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 literal 0 HcmV?d00001 diff --git a/grid2op/data_test/5bus_example_act_topo_set_init/chronics/2/maintenance_forecasted.csv.bz2 b/grid2op/data_test/5bus_example_act_topo_set_init/chronics/2/maintenance_forecasted.csv.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..5257b64d87924cf39779885383b1eb28f134ca3a GIT binary patch literal 84 zcmV-a0IUB(T4*^jL0KkKSwFUueE?#8+5i9$00Do9005u>av`A50&0+m$n$DKD%z+X qicp+Y145K1?QN?v%Ndn&q@g?cdA%}7a?qj`{9VZu;X*+E+D-H;Z6nG6 literal 0 HcmV?d00001 diff --git a/grid2op/data_test/5bus_example_act_topo_set_init/chronics/2/maintenance_meta.json b/grid2op/data_test/5bus_example_act_topo_set_init/chronics/2/maintenance_meta.json new file mode 100644 index 000000000..e6faa8ec2 --- /dev/null +++ b/grid2op/data_test/5bus_example_act_topo_set_init/chronics/2/maintenance_meta.json @@ -0,0 +1,7 @@ +{ + "maintenance_starting_hour": 9 , + "maintenance_ending_hour": 17, + "line_to_maintenance": ["0_1_0", "2_3_5"], + "daily_proba_per_month_maintenance": [0.0, 0.0, 0.0, 0.02, 0.02, 0.03, 0.05, 0.06, 0.03, 0.02, 0.0, 0.0], + "max_daily_number_per_month_maintenance": [0, 0, 0, 1, 1, 2, 2, 2, 1, 1, 0, 0] +} diff --git a/grid2op/data_test/5bus_example_act_topo_set_init/chronics/2/prod_p.csv.bz2 b/grid2op/data_test/5bus_example_act_topo_set_init/chronics/2/prod_p.csv.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..ce04dcfee155b60b6f4bc7ec731b9da65bd3422d GIT binary patch literal 3071 zcmV*% zO0}8R@=f5aA-OgwbZDIyY}D!HL>@^zON>juQ?iT52%a?}X z#OtPQR&jmVSJ2>Vcyk6>Aq^XK!?)6;Qf$My6h|$JZyKJ~(Q=$s5xS=yy z3bQDzOD~n?#WQB&EYhWfn~d^Di^O(rLOI2Fyvz~5i!!Ar)i#TDs=4IF^M!LIUn=;|#^IsB9IV58(RnjoR zl(>B;&YoW%rCz%UE3uJIod*Uxm^hMQo6~G<-Mx~7+tM$nBfE+P4J%uxu!<7AJrRgR~^X&!V;_ZGLD3h#S%D0`+nDp>Fl8kv$a?9FMc6k2G(yz1^sLv0o^ZE_lhABGt#Y!FK!^qDbQn%%% zoA1878H*s*Dn25Cyd1f7ghV4?NjUlO+qQ09ijRZM=PaI{21Dk$`hm5K%*pY~;HJi% z@|-?S}y?J*T)cw^M5k>#65Qj0+1EX__^s-!1wu zaX{@b#@04xHncf(jhpiOD!%og&P~IyW8&yc@8~| zD72+1WtLe>>@dk?DM@9_m{g=eL}nm1$e=6@+X#pv1!9X93ILR{+ft>r+ak$`4J?H% zB`qbEm6TI%lP+}r1qa7PL&r4rS#HYTWA5I3>z~vZ|@+_M{M!(xNnSJ4|!p7Eg%rzzV2;8BkWjW`LNSh)8PB>kB_+K!@3ni zqc71+PNoF5pSjZK-BZ;3z0eWf5_mrnZvepKC15Bj#h#O9V2nfs0Rt@*w4kAFB7!oO zgMZ!qW0*@P1zI98Vvts~YAmb@%F2pc zXe4bZX<1`wXo|HJMl{`-;qmtm%|8Y`_7{*bW$ptFs-p~Cw9}Es>t^ne5Yu!t)O1J4 zz3+qb5#_b8mi@SXWDp?|_1^+ORtwvM%1)PlO!VfCEuIq!HG6R2EEd>;iin`t+eEaY z*-SGvz6XJsY$=#wuCsgI>1-*pG9Gqx_?j)wTz$t4^5)IlMq|M4T5^GytzCNNN8%Eb z-eUn89dABj^HV-#c-CzxIhyvqs-fpQ4CgK!GH>p8Q7yBwELBz_#jQ&%iWUo4C2dwU zM$)NRD!?cw-*ee0SGt)Bg9JEK}1PJfh;hyF8$O> zRkQ6*n+^SAzVCckU!h?PEVCQVTyi^?Vlxa_j5#(P!6?Ns?t@b^vzq$ihu!A>uszv^ zL+fR>pL<)@r;b{7b)7rGAACHRRxFW;1oj&>n>nLuTU#@2Z42Q_dE&klVTCZs7|}Aa zqXwfURcf*g3{vb=`exLn+Pg}!TA^w(lF-Es455Qi($ut?t3y$tqJ049r1KEGmx5ww zjSWet!ewZzTB}j2V8v);WiWUOS7{O2I}Jvqg9f8ZLq?`kRfdZ-TFBRWkzJ>BHj`L0 zLt@rO)NM_XoK&Y2<_(Fot&z1Ep_p4mwKIZKia6CaD>SW=wTjIKYK?Iea9pr8qSjMs zRP^kkaFdu>iKa#}TF`35+h(jx*m4BqIhwT?Wn|LQ5Ds-_<`a?=$Vt zgkHAApS##6-14w_dv;%}71iSUVOQ@^QcquQ*kEn$>$^Uw!m;>9jZjN+)497dOEOcn z;mV^+lJfoJ!`X`_8k-#X5uFO09_N}HG9C3=XJqjpP=&4GYw!&$di_HtTJ0xU9Ku{1UUP=?oErcxqh2{*XWtu`;ULf0$o zcyc)ran3?rDxyG*k{@?&VQLmYF?_3bnDWwV8(4I2r5q~NG0@)xPXbb;l%&| literal 0 HcmV?d00001 diff --git a/grid2op/data_test/5bus_example_act_topo_set_init/chronics/2/prod_p_forecasted.csv.bz2 b/grid2op/data_test/5bus_example_act_topo_set_init/chronics/2/prod_p_forecasted.csv.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..b191b116d97574312cb148266074c4e330592a89 GIT binary patch literal 2771 zcmV;^3M}mh>ZHg9JAMMH^8@^~R~)+{t*Yac{-bLp=L>d(!i>Y^&EaQ1(kF zWRrKuC)+)B-R#;b9bJ40uZwCXoV#8vKIpwscc}^90PkK>(a&JAD=?n8PZ#r{MFFa1 zvmeJh<;ydj@xy-NVK~cg;alvrhlgj?TyKtdh$ctXU|+imSC)>eKFel&S)A}0;z<{8 zaw<}4S-)ZsgKCIkjc=R6D^>=YgZnE0D zT@NN_e0Y`1HeyNlKXdm{&|#HMe)Sce|hfNhfz5-CUDa{`z-GCry%0*}QjlqMi6X>uWgsvaey@1iQV( z(bO?vB}b+hi2k#zqE)_XBy4P%o=dgGbwixu93bjD`C2t0Cu` zbFldP#uM@B_IP^m>^LeSA<&YPLz>Dt%4NctRM|mAHk>Jxz={ZhY{ zE!0jiX(XD{)FQMkSOgS`NOv5LX8aX6hLza4cBYDtlt+QC}Y zqfOkluFGPcW@{>Dn$|AKCB8i#=nk^W(N$UROh_Oz5v*v9Y#7L4q7oD!G+GBZZ-I>H zQo2mkbCC8Hr>NvlrrlX~V=#U9`$HnOKe%w{9AEn$vH z)k&*&<$ip06R(Znft(y#5kq5XrO7gzZz^GOxKL3XI89coZAvZKWfh4T6z_|xqECkL z#4_suV36?$6bnevK#>TIT7Xc5L9e<3?Iq6jwerSk73Na0esayS*Lmjzf-tfYdHNa(agRjR5>3SwbOs{owFby+Trw zti#8IM4?fT7onm-y0t7J6kY|qe0;Z7EM8vw-VVEE#z3S{T;t%jhNcVDvXx0bAEVr3 zjOc#$uJ=gp85JT_RmzH!RZb{$=%8xp&$&HxWv_RJjS)SORaFuytWeM)8yew`7&RG@ zgj^dPqEUg&Xm8!RFvuJ33?WB>kG8xR+&nqF_ki?NOU<$hi*ZY*M@@ zlB**Sv@s>B(2T1nVqj@vw3-a8jZBl(2Zc%QL3$p@)oMmY6B9(p)U2$ACaHr92BS+= z>QYyULFG><%4Jy^nJ{3+si|mbg{=)_YlSPR%%)`7S&KC`4AE^ZiJXCQyCtx*OJLb8 ziLx_8WNuWaDa}i2HmfpQP|Xu*S*o*8&Y~R$T9%kv(u<;_QlEQCtd?mr7HYJzTCrMi ziNxbV%T&Oc8bS(4LNj~uSy}kcKio_AgdL;ROZS|gkd%A^k}|0ysu1e+dv&{Y;$Ol= z;droI))|H&V!c?e9x>)UZ#{WhUvRu+9-F^vHDk+El;%-m0*yY5Tb+nE$G8AP}m!uP76->_a2d17Nu9U zwSw&}QYA`?pRX!u=S`Yr`Qb$16AQ7|6KoUUEx{Z^wvl z&z08dqL&<=2R+V<7h`uj-Dh&f!-G3EU)SO2L}|4}2-14%t4qHvXww)mYa1Hf_jkOG zT=Sb;j=Ob*`5S$!jOHD~4YQw;qV*fNn_7&bvb7#Nmp2ilZ0j!h@@qqL&Ezvkd&8)# z?)m+O8S&N8c~K^txL~_zpt%jrH!?huW)@ylOCIJxg`xy#gbU1|r>5#`@MKs~P+W@= zEyzo9O}5)(sF;|kmfPLk?-nI|(M$>(AywVlX772494Rw*V?-fr5k+q9f)X7;R8wPP zgbHDm6x)bwL?MzA*x`&o*fuiY@#D+e0EBRoBp8%Lj!i}*4`9XaWKlMv5fK_Gg&r4` ZfnsQ9`ycrG{Qf`1+>uTcBr4-Tu0V$@PtyPZ literal 0 HcmV?d00001 diff --git a/grid2op/data_test/5bus_example_act_topo_set_init/chronics/2/prod_v.csv.bz2 b/grid2op/data_test/5bus_example_act_topo_set_init/chronics/2/prod_v.csv.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..9fde13d8afbe1db215c8c51ccead2bcb59bc25b0 GIT binary patch literal 78 zcmV-U0I~luTcBmuHbT0jyk9CrW! literal 0 HcmV?d00001 diff --git a/grid2op/data_test/5bus_example_act_topo_set_init/chronics/2/start_datetime.info b/grid2op/data_test/5bus_example_act_topo_set_init/chronics/2/start_datetime.info new file mode 100644 index 000000000..bd8d52ab4 --- /dev/null +++ b/grid2op/data_test/5bus_example_act_topo_set_init/chronics/2/start_datetime.info @@ -0,0 +1 @@ +2019-01-05 23:55 diff --git a/grid2op/data_test/5bus_example_act_topo_set_init/chronics/2/time_interval.info b/grid2op/data_test/5bus_example_act_topo_set_init/chronics/2/time_interval.info new file mode 100644 index 000000000..beb9b9011 --- /dev/null +++ b/grid2op/data_test/5bus_example_act_topo_set_init/chronics/2/time_interval.info @@ -0,0 +1 @@ +00:05 diff --git a/grid2op/data_test/5bus_example_act_topo_set_init/config.py b/grid2op/data_test/5bus_example_act_topo_set_init/config.py new file mode 100644 index 000000000..1ec901a06 --- /dev/null +++ b/grid2op/data_test/5bus_example_act_topo_set_init/config.py @@ -0,0 +1,19 @@ +from grid2op.Action import TopologyAction +from grid2op.Reward import L2RPNReward +from grid2op.Rules import DefaultRules +from grid2op.Chronics import Multifolder +from grid2op.Chronics import GridStateFromFileWithForecasts +from grid2op.Backend import PandaPowerBackend + +config = { + "backend": PandaPowerBackend, + "action_class": TopologyAction, + "observation_class": None, + "reward_class": L2RPNReward, + "gamerules_class": DefaultRules, + "chronics_class": Multifolder, + "grid_value_class": GridStateFromFileWithForecasts, + "volagecontroler_class": None, + "thermal_limits": None, + "names_chronics_to_grid": None, +} diff --git a/grid2op/data_test/5bus_example_act_topo_set_init/grid.json b/grid2op/data_test/5bus_example_act_topo_set_init/grid.json new file mode 100644 index 000000000..b94667b9c --- /dev/null +++ b/grid2op/data_test/5bus_example_act_topo_set_init/grid.json @@ -0,0 +1,1772 @@ +{ + "_module": "pandapower.auxiliary", + "_class": "pandapowerNet", + "_object": { + "bus": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"vn_kv\",\"type\",\"zone\",\"in_service\"],\"index\":[0,1,2,3,4],\"data\":[[\"substation_1\",100.0,\"b\",null,true],[\"substation_2\",100.0,\"b\",null,true],[\"substation_3\",100.0,\"b\",null,true],[\"substation_4\",100.0,\"b\",null,true],[\"substation_5\",100.0,\"b\",null,true]]}", + "orient": "split", + "dtype": { + "name": "object", + "vn_kv": "float64", + "type": "object", + "zone": "object", + "in_service": "bool" + } + }, + "load": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"bus\",\"p_mw\",\"q_mvar\",\"const_z_percent\",\"const_i_percent\",\"sn_mva\",\"scaling\",\"in_service\",\"type\"],\"index\":[0,1,2],\"data\":[[\"load_0_0\",0,10.0,7.0,0.0,0.0,null,1.0,true,null],[\"load_3_1\",3,10.0,7.0,0.0,0.0,null,1.0,true,null],[\"load_4_2\",4,10.0,7.0,0.0,0.0,null,1.0,true,null]]}", + "orient": "split", + "dtype": { + "name": "object", + "bus": "uint32", + "p_mw": "float64", + "q_mvar": "float64", + "const_z_percent": "float64", + "const_i_percent": "float64", + "sn_mva": "float64", + "scaling": "float64", + "in_service": "bool", + "type": "object" + } + }, + "sgen": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"bus\",\"p_mw\",\"q_mvar\",\"sn_mva\",\"scaling\",\"in_service\",\"type\",\"current_source\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "name": "object", + "bus": "int64", + "p_mw": "float64", + "q_mvar": "float64", + "sn_mva": "float64", + "scaling": "float64", + "in_service": "bool", + "type": "object", + "current_source": "bool" + } + }, + "motor": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"bus\",\"pn_mech_mw\",\"loading_percent\",\"cos_phi\",\"cos_phi_n\",\"efficiency_percent\",\"efficiency_n_percent\",\"lrc_pu\",\"vn_kv\",\"scaling\",\"in_service\",\"rx\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "name": "object", + "bus": "int64", + "pn_mech_mw": "float64", + "loading_percent": "float64", + "cos_phi": "float64", + "cos_phi_n": "float64", + "efficiency_percent": "float64", + "efficiency_n_percent": "float64", + "lrc_pu": "float64", + "vn_kv": "float64", + "scaling": "float64", + "in_service": "bool", + "rx": "float64" + } + }, + "asymmetric_load": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"bus\",\"p_a_mw\",\"q_a_mvar\",\"p_b_mw\",\"q_b_mvar\",\"p_c_mw\",\"q_c_mvar\",\"sn_mva\",\"scaling\",\"in_service\",\"type\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "name": "object", + "bus": "uint32", + "p_a_mw": "float64", + "q_a_mvar": "float64", + "p_b_mw": "float64", + "q_b_mvar": "float64", + "p_c_mw": "float64", + "q_c_mvar": "float64", + "sn_mva": "float64", + "scaling": "float64", + "in_service": "bool", + "type": "object" + } + }, + "asymmetric_sgen": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"bus\",\"p_a_mw\",\"q_a_mvar\",\"p_b_mw\",\"q_b_mvar\",\"p_c_mw\",\"q_c_mvar\",\"sn_mva\",\"scaling\",\"in_service\",\"type\",\"current_source\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "name": "object", + "bus": "int64", + "p_a_mw": "float64", + "q_a_mvar": "float64", + "p_b_mw": "float64", + "q_b_mvar": "float64", + "p_c_mw": "float64", + "q_c_mvar": "float64", + "sn_mva": "float64", + "scaling": "float64", + "in_service": "bool", + "type": "object", + "current_source": "bool" + } + }, + "storage": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"bus\",\"p_mw\",\"q_mvar\",\"sn_mva\",\"soc_percent\",\"min_e_mwh\",\"max_e_mwh\",\"scaling\",\"in_service\",\"type\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "name": "object", + "bus": "int64", + "p_mw": "float64", + "q_mvar": "float64", + "sn_mva": "float64", + "soc_percent": "float64", + "min_e_mwh": "float64", + "max_e_mwh": "float64", + "scaling": "float64", + "in_service": "bool", + "type": "object" + } + }, + "gen": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"bus\",\"p_mw\",\"vm_pu\",\"sn_mva\",\"min_q_mvar\",\"max_q_mvar\",\"scaling\",\"slack\",\"in_service\",\"type\",\"slack_weight\"],\"index\":[0,1],\"data\":[[\"gen_0_0\",0,10.0,1.02,null,null,null,1.0,false,true,null,0.0],[\"gen_1_1\",1,20.0,1.02,null,null,null,1.0,true,true,null,1.0]]}", + "orient": "split", + "dtype": { + "name": "object", + "bus": "uint32", + "p_mw": "float64", + "vm_pu": "float64", + "sn_mva": "float64", + "min_q_mvar": "float64", + "max_q_mvar": "float64", + "scaling": "float64", + "slack": "bool", + "in_service": "bool", + "type": "object", + "slack_weight": "float64" + } + }, + "switch": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"bus\",\"element\",\"et\",\"type\",\"closed\",\"name\",\"z_ohm\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "bus": "int64", + "element": "int64", + "et": "object", + "type": "object", + "closed": "bool", + "name": "object", + "z_ohm": "float64" + } + }, + "shunt": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"bus\",\"name\",\"q_mvar\",\"p_mw\",\"vn_kv\",\"step\",\"max_step\",\"in_service\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "bus": "uint32", + "name": "object", + "q_mvar": "float64", + "p_mw": "float64", + "vn_kv": "float64", + "step": "uint32", + "max_step": "uint32", + "in_service": "bool" + } + }, + "ext_grid": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"bus\",\"vm_pu\",\"va_degree\",\"in_service\",\"slack_weight\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "name": "object", + "bus": "uint32", + "vm_pu": "float64", + "va_degree": "float64", + "in_service": "bool", + "slack_weight": "float64" + } + }, + "line": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"std_type\",\"from_bus\",\"to_bus\",\"length_km\",\"r_ohm_per_km\",\"x_ohm_per_km\",\"c_nf_per_km\",\"g_us_per_km\",\"max_i_ka\",\"df\",\"parallel\",\"type\",\"in_service\"],\"index\":[0,1,2,3,4,5,6,7],\"data\":[[null,\"NAYY 4x50 SE\",0,1,4.0,0.642,0.083,210.0,0.0,0.6,1.0,1,\"cs\",true],[\"0_2_2\",\"NAYY 4x50 SE\",0,2,4.47,0.642,0.083,210.0,0.0,0.22,1.0,1,\"cs\",true],[\"0_3_3\",\"NAYY 4x50 SE\",0,3,5.65,0.642,0.083,210.0,0.0,0.16,1.0,1,\"cs\",true],[\"0_4_4\",\"NAYY 4x50 SE\",0,4,4.0,0.642,0.083,210.0,0.0,0.16,1.0,1,\"cs\",true],[\"1_2_5\",\"NAYY 4x50 SE\",1,2,2.0,0.642,0.083,210.0,0.0,0.6,1.0,1,\"cs\",true],[\"2_3_6\",\"NAYY 4x50 SE\",2,3,2.0,0.642,0.083,210.0,0.0,0.3,1.0,1,\"cs\",true],[\"2_3_7\",\"NAYY 4x50 SE\",2,3,2.0,0.642,0.083,210.0,0.0,0.3,1.0,1,\"cs\",true],[\"3_4_8\",\"NAYY 4x50 SE\",3,4,4.0,0.642,0.083,210.0,0.0,0.16,1.0,1,\"cs\",true]]}", + "orient": "split", + "dtype": { + "name": "object", + "std_type": "object", + "from_bus": "uint32", + "to_bus": "uint32", + "length_km": "float64", + "r_ohm_per_km": "float64", + "x_ohm_per_km": "float64", + "c_nf_per_km": "float64", + "g_us_per_km": "float64", + "max_i_ka": "float64", + "df": "float64", + "parallel": "uint32", + "type": "object", + "in_service": "bool" + } + }, + "trafo": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"std_type\",\"hv_bus\",\"lv_bus\",\"sn_mva\",\"vn_hv_kv\",\"vn_lv_kv\",\"vk_percent\",\"vkr_percent\",\"pfe_kw\",\"i0_percent\",\"shift_degree\",\"tap_side\",\"tap_neutral\",\"tap_min\",\"tap_max\",\"tap_step_percent\",\"tap_step_degree\",\"tap_pos\",\"tap_phase_shifter\",\"parallel\",\"df\",\"in_service\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "name": "object", + "std_type": "object", + "hv_bus": "uint32", + "lv_bus": "uint32", + "sn_mva": "float64", + "vn_hv_kv": "float64", + "vn_lv_kv": "float64", + "vk_percent": "float64", + "vkr_percent": "float64", + "pfe_kw": "float64", + "i0_percent": "float64", + "shift_degree": "float64", + "tap_side": "object", + "tap_neutral": "int32", + "tap_min": "int32", + "tap_max": "int32", + "tap_step_percent": "float64", + "tap_step_degree": "float64", + "tap_pos": "int32", + "tap_phase_shifter": "bool", + "parallel": "uint32", + "df": "float64", + "in_service": "bool" + } + }, + "trafo3w": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"std_type\",\"hv_bus\",\"mv_bus\",\"lv_bus\",\"sn_hv_mva\",\"sn_mv_mva\",\"sn_lv_mva\",\"vn_hv_kv\",\"vn_mv_kv\",\"vn_lv_kv\",\"vk_hv_percent\",\"vk_mv_percent\",\"vk_lv_percent\",\"vkr_hv_percent\",\"vkr_mv_percent\",\"vkr_lv_percent\",\"pfe_kw\",\"i0_percent\",\"shift_mv_degree\",\"shift_lv_degree\",\"tap_side\",\"tap_neutral\",\"tap_min\",\"tap_max\",\"tap_step_percent\",\"tap_step_degree\",\"tap_pos\",\"tap_at_star_point\",\"in_service\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "name": "object", + "std_type": "object", + "hv_bus": "uint32", + "mv_bus": "uint32", + "lv_bus": "uint32", + "sn_hv_mva": "float64", + "sn_mv_mva": "float64", + "sn_lv_mva": "float64", + "vn_hv_kv": "float64", + "vn_mv_kv": "float64", + "vn_lv_kv": "float64", + "vk_hv_percent": "float64", + "vk_mv_percent": "float64", + "vk_lv_percent": "float64", + "vkr_hv_percent": "float64", + "vkr_mv_percent": "float64", + "vkr_lv_percent": "float64", + "pfe_kw": "float64", + "i0_percent": "float64", + "shift_mv_degree": "float64", + "shift_lv_degree": "float64", + "tap_side": "object", + "tap_neutral": "int32", + "tap_min": "int32", + "tap_max": "int32", + "tap_step_percent": "float64", + "tap_step_degree": "float64", + "tap_pos": "int32", + "tap_at_star_point": "bool", + "in_service": "bool" + } + }, + "impedance": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"from_bus\",\"to_bus\",\"rft_pu\",\"xft_pu\",\"rtf_pu\",\"xtf_pu\",\"sn_mva\",\"in_service\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "name": "object", + "from_bus": "uint32", + "to_bus": "uint32", + "rft_pu": "float64", + "xft_pu": "float64", + "rtf_pu": "float64", + "xtf_pu": "float64", + "sn_mva": "float64", + "in_service": "bool" + } + }, + "dcline": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"from_bus\",\"to_bus\",\"p_mw\",\"loss_percent\",\"loss_mw\",\"vm_from_pu\",\"vm_to_pu\",\"max_p_mw\",\"min_q_from_mvar\",\"min_q_to_mvar\",\"max_q_from_mvar\",\"max_q_to_mvar\",\"in_service\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "name": "object", + "from_bus": "uint32", + "to_bus": "uint32", + "p_mw": "float64", + "loss_percent": "float64", + "loss_mw": "float64", + "vm_from_pu": "float64", + "vm_to_pu": "float64", + "max_p_mw": "float64", + "min_q_from_mvar": "float64", + "min_q_to_mvar": "float64", + "max_q_from_mvar": "float64", + "max_q_to_mvar": "float64", + "in_service": "bool" + } + }, + "ward": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"bus\",\"ps_mw\",\"qs_mvar\",\"qz_mvar\",\"pz_mw\",\"in_service\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "name": "object", + "bus": "uint32", + "ps_mw": "float64", + "qs_mvar": "float64", + "qz_mvar": "float64", + "pz_mw": "float64", + "in_service": "bool" + } + }, + "xward": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"bus\",\"ps_mw\",\"qs_mvar\",\"qz_mvar\",\"pz_mw\",\"r_ohm\",\"x_ohm\",\"vm_pu\",\"in_service\",\"slack_weight\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "name": "object", + "bus": "uint32", + "ps_mw": "float64", + "qs_mvar": "float64", + "qz_mvar": "float64", + "pz_mw": "float64", + "r_ohm": "float64", + "x_ohm": "float64", + "vm_pu": "float64", + "in_service": "bool", + "slack_weight": "float64" + } + }, + "measurement": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"name\",\"measurement_type\",\"element_type\",\"element\",\"value\",\"std_dev\",\"side\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "name": "object", + "measurement_type": "object", + "element_type": "object", + "element": "uint32", + "value": "float64", + "std_dev": "float64", + "side": "object" + } + }, + "pwl_cost": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"power_type\",\"element\",\"et\",\"points\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "power_type": "object", + "element": "uint32", + "et": "object", + "points": "object" + } + }, + "poly_cost": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"element\",\"et\",\"cp0_eur\",\"cp1_eur_per_mw\",\"cp2_eur_per_mw2\",\"cq0_eur\",\"cq1_eur_per_mvar\",\"cq2_eur_per_mvar2\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "element": "uint32", + "et": "object", + "cp0_eur": "float64", + "cp1_eur_per_mw": "float64", + "cp2_eur_per_mw2": "float64", + "cq0_eur": "float64", + "cq1_eur_per_mvar": "float64", + "cq2_eur_per_mvar2": "float64" + } + }, + "characteristic": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"object\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "object": "object" + } + }, + "controller": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"object\",\"in_service\",\"order\",\"level\",\"initial_run\",\"recycle\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "object": "object", + "in_service": "bool", + "order": "float64", + "level": "object", + "initial_run": "bool", + "recycle": "object" + } + }, + "line_geodata": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"coords\"],\"index\":[0,1,2,3,4,5,6,7],\"data\":[[[[0,0],[0,4]]],[[[0,0],[2,4]]],[[[0,0],[4,4]]],[[[0,0],[4,0]]],[[[0,4],[2,4]]],[[[2,4],[3,4.2],[4,4]]],[[[2,4],[3,3.8],[4,4]]],[[[4,4],[4,0]]]]}", + "orient": "split", + "dtype": { + "coords": "object" + } + }, + "bus_geodata": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"x\",\"y\",\"coords\"],\"index\":[0,1,2,3,4],\"data\":[[0.0,0.0,null],[0.0,4.0,null],[2.0,4.0,null],[4.0,4.0,null],[4.0,0.0,null]]}", + "orient": "split", + "dtype": { + "x": "float64", + "y": "float64", + "coords": "object" + } + }, + "version": "2.8.0", + "converged": true, + "name": "5bus", + "f_hz": 50.0, + "sn_mva": 1, + "std_types": { + "line": { + "NAYY 4x50 SE": { + "c_nf_per_km": 210, + "r_ohm_per_km": 0.642, + "x_ohm_per_km": 0.083, + "max_i_ka": 0.142, + "type": "cs", + "q_mm2": 50, + "alpha": 0.00403 + }, + "NAYY 4x120 SE": { + "c_nf_per_km": 264, + "r_ohm_per_km": 0.225, + "x_ohm_per_km": 0.08, + "max_i_ka": 0.242, + "type": "cs", + "q_mm2": 120, + "alpha": 0.00403 + }, + "NAYY 4x150 SE": { + "c_nf_per_km": 261, + "r_ohm_per_km": 0.208, + "x_ohm_per_km": 0.08, + "max_i_ka": 0.27, + "type": "cs", + "q_mm2": 150, + "alpha": 0.00403 + }, + "NA2XS2Y 1x95 RM/25 12/20 kV": { + "c_nf_per_km": 216, + "r_ohm_per_km": 0.313, + "x_ohm_per_km": 0.132, + "max_i_ka": 0.252, + "type": "cs", + "q_mm2": 95, + "alpha": 0.00403 + }, + "NA2XS2Y 1x185 RM/25 12/20 kV": { + "c_nf_per_km": 273, + "r_ohm_per_km": 0.161, + "x_ohm_per_km": 0.117, + "max_i_ka": 0.362, + "type": "cs", + "q_mm2": 185, + "alpha": 0.00403 + }, + "NA2XS2Y 1x240 RM/25 12/20 kV": { + "c_nf_per_km": 304, + "r_ohm_per_km": 0.122, + "x_ohm_per_km": 0.112, + "max_i_ka": 0.421, + "type": "cs", + "q_mm2": 240, + "alpha": 0.00403 + }, + "NA2XS2Y 1x95 RM/25 6/10 kV": { + "c_nf_per_km": 315, + "r_ohm_per_km": 0.313, + "x_ohm_per_km": 0.123, + "max_i_ka": 0.249, + "type": "cs", + "q_mm2": 95, + "alpha": 0.00403 + }, + "NA2XS2Y 1x185 RM/25 6/10 kV": { + "c_nf_per_km": 406, + "r_ohm_per_km": 0.161, + "x_ohm_per_km": 0.11, + "max_i_ka": 0.358, + "type": "cs", + "q_mm2": 185, + "alpha": 0.00403 + }, + "NA2XS2Y 1x240 RM/25 6/10 kV": { + "c_nf_per_km": 456, + "r_ohm_per_km": 0.122, + "x_ohm_per_km": 0.105, + "max_i_ka": 0.416, + "type": "cs", + "q_mm2": 240, + "alpha": 0.00403 + }, + "NA2XS2Y 1x150 RM/25 12/20 kV": { + "c_nf_per_km": 250, + "r_ohm_per_km": 0.206, + "x_ohm_per_km": 0.116, + "max_i_ka": 0.319, + "type": "cs", + "q_mm2": 150, + "alpha": 0.00403 + }, + "NA2XS2Y 1x120 RM/25 12/20 kV": { + "c_nf_per_km": 230, + "r_ohm_per_km": 0.253, + "x_ohm_per_km": 0.119, + "max_i_ka": 0.283, + "type": "cs", + "q_mm2": 120, + "alpha": 0.00403 + }, + "NA2XS2Y 1x70 RM/25 12/20 kV": { + "c_nf_per_km": 190, + "r_ohm_per_km": 0.443, + "x_ohm_per_km": 0.132, + "max_i_ka": 0.22, + "type": "cs", + "q_mm2": 70, + "alpha": 0.00403 + }, + "NA2XS2Y 1x150 RM/25 6/10 kV": { + "c_nf_per_km": 360, + "r_ohm_per_km": 0.206, + "x_ohm_per_km": 0.11, + "max_i_ka": 0.315, + "type": "cs", + "q_mm2": 150, + "alpha": 0.00403 + }, + "NA2XS2Y 1x120 RM/25 6/10 kV": { + "c_nf_per_km": 340, + "r_ohm_per_km": 0.253, + "x_ohm_per_km": 0.113, + "max_i_ka": 0.28, + "type": "cs", + "q_mm2": 120, + "alpha": 0.00403 + }, + "NA2XS2Y 1x70 RM/25 6/10 kV": { + "c_nf_per_km": 280, + "r_ohm_per_km": 0.443, + "x_ohm_per_km": 0.123, + "max_i_ka": 0.217, + "type": "cs", + "q_mm2": 70, + "alpha": 0.00403 + }, + "N2XS(FL)2Y 1x120 RM/35 64/110 kV": { + "c_nf_per_km": 112, + "r_ohm_per_km": 0.153, + "x_ohm_per_km": 0.166, + "max_i_ka": 0.366, + "type": "cs", + "q_mm2": 120, + "alpha": 0.00393 + }, + "N2XS(FL)2Y 1x185 RM/35 64/110 kV": { + "c_nf_per_km": 125, + "r_ohm_per_km": 0.099, + "x_ohm_per_km": 0.156, + "max_i_ka": 0.457, + "type": "cs", + "q_mm2": 185, + "alpha": 0.00393 + }, + "N2XS(FL)2Y 1x240 RM/35 64/110 kV": { + "c_nf_per_km": 135, + "r_ohm_per_km": 0.075, + "x_ohm_per_km": 0.149, + "max_i_ka": 0.526, + "type": "cs", + "q_mm2": 240, + "alpha": 0.00393 + }, + "N2XS(FL)2Y 1x300 RM/35 64/110 kV": { + "c_nf_per_km": 144, + "r_ohm_per_km": 0.06, + "x_ohm_per_km": 0.144, + "max_i_ka": 0.588, + "type": "cs", + "q_mm2": 300, + "alpha": 0.00393 + }, + "15-AL1/3-ST1A 0.4": { + "c_nf_per_km": 11, + "r_ohm_per_km": 1.8769, + "x_ohm_per_km": 0.35, + "max_i_ka": 0.105, + "type": "ol", + "q_mm2": 16, + "alpha": 0.00403 + }, + "24-AL1/4-ST1A 0.4": { + "c_nf_per_km": 11.25, + "r_ohm_per_km": 1.2012, + "x_ohm_per_km": 0.335, + "max_i_ka": 0.14, + "type": "ol", + "q_mm2": 24, + "alpha": 0.00403 + }, + "48-AL1/8-ST1A 0.4": { + "c_nf_per_km": 12.2, + "r_ohm_per_km": 0.5939, + "x_ohm_per_km": 0.3, + "max_i_ka": 0.21, + "type": "ol", + "q_mm2": 48, + "alpha": 0.00403 + }, + "94-AL1/15-ST1A 0.4": { + "c_nf_per_km": 13.2, + "r_ohm_per_km": 0.306, + "x_ohm_per_km": 0.29, + "max_i_ka": 0.35, + "type": "ol", + "q_mm2": 94, + "alpha": 0.00403 + }, + "34-AL1/6-ST1A 10.0": { + "c_nf_per_km": 9.7, + "r_ohm_per_km": 0.8342, + "x_ohm_per_km": 0.36, + "max_i_ka": 0.17, + "type": "ol", + "q_mm2": 34, + "alpha": 0.00403 + }, + "48-AL1/8-ST1A 10.0": { + "c_nf_per_km": 10.1, + "r_ohm_per_km": 0.5939, + "x_ohm_per_km": 0.35, + "max_i_ka": 0.21, + "type": "ol", + "q_mm2": 48, + "alpha": 0.00403 + }, + "70-AL1/11-ST1A 10.0": { + "c_nf_per_km": 10.4, + "r_ohm_per_km": 0.4132, + "x_ohm_per_km": 0.339, + "max_i_ka": 0.29, + "type": "ol", + "q_mm2": 70, + "alpha": 0.00403 + }, + "94-AL1/15-ST1A 10.0": { + "c_nf_per_km": 10.75, + "r_ohm_per_km": 0.306, + "x_ohm_per_km": 0.33, + "max_i_ka": 0.35, + "type": "ol", + "q_mm2": 94, + "alpha": 0.00403 + }, + "122-AL1/20-ST1A 10.0": { + "c_nf_per_km": 11.1, + "r_ohm_per_km": 0.2376, + "x_ohm_per_km": 0.323, + "max_i_ka": 0.41, + "type": "ol", + "q_mm2": 122, + "alpha": 0.00403 + }, + "149-AL1/24-ST1A 10.0": { + "c_nf_per_km": 11.25, + "r_ohm_per_km": 0.194, + "x_ohm_per_km": 0.315, + "max_i_ka": 0.47, + "type": "ol", + "q_mm2": 149, + "alpha": 0.00403 + }, + "34-AL1/6-ST1A 20.0": { + "c_nf_per_km": 9.15, + "r_ohm_per_km": 0.8342, + "x_ohm_per_km": 0.382, + "max_i_ka": 0.17, + "type": "ol", + "q_mm2": 34, + "alpha": 0.00403 + }, + "48-AL1/8-ST1A 20.0": { + "c_nf_per_km": 9.5, + "r_ohm_per_km": 0.5939, + "x_ohm_per_km": 0.372, + "max_i_ka": 0.21, + "type": "ol", + "q_mm2": 48, + "alpha": 0.00403 + }, + "70-AL1/11-ST1A 20.0": { + "c_nf_per_km": 9.7, + "r_ohm_per_km": 0.4132, + "x_ohm_per_km": 0.36, + "max_i_ka": 0.29, + "type": "ol", + "q_mm2": 70, + "alpha": 0.00403 + }, + "94-AL1/15-ST1A 20.0": { + "c_nf_per_km": 10, + "r_ohm_per_km": 0.306, + "x_ohm_per_km": 0.35, + "max_i_ka": 0.35, + "type": "ol", + "q_mm2": 94, + "alpha": 0.00403 + }, + "122-AL1/20-ST1A 20.0": { + "c_nf_per_km": 10.3, + "r_ohm_per_km": 0.2376, + "x_ohm_per_km": 0.344, + "max_i_ka": 0.41, + "type": "ol", + "q_mm2": 122, + "alpha": 0.00403 + }, + "149-AL1/24-ST1A 20.0": { + "c_nf_per_km": 10.5, + "r_ohm_per_km": 0.194, + "x_ohm_per_km": 0.337, + "max_i_ka": 0.47, + "type": "ol", + "q_mm2": 149, + "alpha": 0.00403 + }, + "184-AL1/30-ST1A 20.0": { + "c_nf_per_km": 10.75, + "r_ohm_per_km": 0.1571, + "x_ohm_per_km": 0.33, + "max_i_ka": 0.535, + "type": "ol", + "q_mm2": 184, + "alpha": 0.00403 + }, + "243-AL1/39-ST1A 20.0": { + "c_nf_per_km": 11, + "r_ohm_per_km": 0.1188, + "x_ohm_per_km": 0.32, + "max_i_ka": 0.645, + "type": "ol", + "q_mm2": 243, + "alpha": 0.00403 + }, + "48-AL1/8-ST1A 110.0": { + "c_nf_per_km": 8, + "r_ohm_per_km": 0.5939, + "x_ohm_per_km": 0.46, + "max_i_ka": 0.21, + "type": "ol", + "q_mm2": 48, + "alpha": 0.00403 + }, + "70-AL1/11-ST1A 110.0": { + "c_nf_per_km": 8.4, + "r_ohm_per_km": 0.4132, + "x_ohm_per_km": 0.45, + "max_i_ka": 0.29, + "type": "ol", + "q_mm2": 70, + "alpha": 0.00403 + }, + "94-AL1/15-ST1A 110.0": { + "c_nf_per_km": 8.65, + "r_ohm_per_km": 0.306, + "x_ohm_per_km": 0.44, + "max_i_ka": 0.35, + "type": "ol", + "q_mm2": 94, + "alpha": 0.00403 + }, + "122-AL1/20-ST1A 110.0": { + "c_nf_per_km": 8.5, + "r_ohm_per_km": 0.2376, + "x_ohm_per_km": 0.43, + "max_i_ka": 0.41, + "type": "ol", + "q_mm2": 122, + "alpha": 0.00403 + }, + "149-AL1/24-ST1A 110.0": { + "c_nf_per_km": 8.75, + "r_ohm_per_km": 0.194, + "x_ohm_per_km": 0.41, + "max_i_ka": 0.47, + "type": "ol", + "q_mm2": 149, + "alpha": 0.00403 + }, + "184-AL1/30-ST1A 110.0": { + "c_nf_per_km": 8.8, + "r_ohm_per_km": 0.1571, + "x_ohm_per_km": 0.4, + "max_i_ka": 0.535, + "type": "ol", + "q_mm2": 184, + "alpha": 0.00403 + }, + "243-AL1/39-ST1A 110.0": { + "c_nf_per_km": 9, + "r_ohm_per_km": 0.1188, + "x_ohm_per_km": 0.39, + "max_i_ka": 0.645, + "type": "ol", + "q_mm2": 243, + "alpha": 0.00403 + }, + "305-AL1/39-ST1A 110.0": { + "c_nf_per_km": 9.2, + "r_ohm_per_km": 0.0949, + "x_ohm_per_km": 0.38, + "max_i_ka": 0.74, + "type": "ol", + "q_mm2": 305, + "alpha": 0.00403 + }, + "490-AL1/64-ST1A 110.0": { + "c_nf_per_km": 9.75, + "r_ohm_per_km": 0.059, + "x_ohm_per_km": 0.37, + "max_i_ka": 0.96, + "type": "ol", + "q_mm2": 490, + "alpha": 0.00403 + }, + "679-AL1/86-ST1A 110.0": { + "c_nf_per_km": 9.95, + "r_ohm_per_km": 0.042, + "x_ohm_per_km": 0.36, + "max_i_ka": 0.115, + "type": "ol", + "q_mm2": 679, + "alpha": 0.00403 + }, + "490-AL1/64-ST1A 220.0": { + "c_nf_per_km": 10, + "r_ohm_per_km": 0.059, + "x_ohm_per_km": 0.285, + "max_i_ka": 0.96, + "type": "ol", + "q_mm2": 490, + "alpha": 0.00403 + }, + "679-AL1/86-ST1A 220.0": { + "c_nf_per_km": 11.7, + "r_ohm_per_km": 0.042, + "x_ohm_per_km": 0.275, + "max_i_ka": 0.115, + "type": "ol", + "q_mm2": 679, + "alpha": 0.00403 + }, + "490-AL1/64-ST1A 380.0": { + "c_nf_per_km": 11, + "r_ohm_per_km": 0.059, + "x_ohm_per_km": 0.253, + "max_i_ka": 0.96, + "type": "ol", + "q_mm2": 490, + "alpha": 0.00403 + }, + "679-AL1/86-ST1A 380.0": { + "c_nf_per_km": 14.6, + "r_ohm_per_km": 0.042, + "x_ohm_per_km": 0.25, + "max_i_ka": 0.115, + "type": "ol", + "q_mm2": 679, + "alpha": 0.00403 + } + }, + "trafo": { + "160 MVA 380/110 kV": { + "i0_percent": 0.06, + "pfe_kw": 60, + "vkr_percent": 0.25, + "sn_mva": 160, + "vn_lv_kv": 110.0, + "vn_hv_kv": 380.0, + "vk_percent": 12.2, + "shift_degree": 0, + "vector_group": "Yy0", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -9, + "tap_max": 9, + "tap_step_degree": 0, + "tap_step_percent": 1.5, + "tap_phase_shifter": false + }, + "100 MVA 220/110 kV": { + "i0_percent": 0.06, + "pfe_kw": 55, + "vkr_percent": 0.26, + "sn_mva": 100, + "vn_lv_kv": 110.0, + "vn_hv_kv": 220.0, + "vk_percent": 12.0, + "shift_degree": 0, + "vector_group": "Yy0", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -9, + "tap_max": 9, + "tap_step_degree": 0, + "tap_step_percent": 1.5, + "tap_phase_shifter": false + }, + "63 MVA 110/20 kV": { + "i0_percent": 0.04, + "pfe_kw": 22, + "vkr_percent": 0.32, + "sn_mva": 63, + "vn_lv_kv": 20.0, + "vn_hv_kv": 110.0, + "vk_percent": 18, + "shift_degree": 150, + "vector_group": "YNd5", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -9, + "tap_max": 9, + "tap_step_degree": 0, + "tap_step_percent": 1.5, + "tap_phase_shifter": false + }, + "40 MVA 110/20 kV": { + "i0_percent": 0.05, + "pfe_kw": 18, + "vkr_percent": 0.34, + "sn_mva": 40, + "vn_lv_kv": 20.0, + "vn_hv_kv": 110.0, + "vk_percent": 16.2, + "shift_degree": 150, + "vector_group": "YNd5", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -9, + "tap_max": 9, + "tap_step_degree": 0, + "tap_step_percent": 1.5, + "tap_phase_shifter": false + }, + "25 MVA 110/20 kV": { + "i0_percent": 0.07, + "pfe_kw": 14, + "vkr_percent": 0.41, + "sn_mva": 25, + "vn_lv_kv": 20.0, + "vn_hv_kv": 110.0, + "vk_percent": 12, + "shift_degree": 150, + "vector_group": "YNd5", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -9, + "tap_max": 9, + "tap_step_degree": 0, + "tap_step_percent": 1.5, + "tap_phase_shifter": false + }, + "63 MVA 110/10 kV": { + "sn_mva": 63, + "vn_hv_kv": 110, + "vn_lv_kv": 10, + "vk_percent": 18, + "vkr_percent": 0.32, + "pfe_kw": 22, + "i0_percent": 0.04, + "shift_degree": 150, + "vector_group": "YNd5", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -9, + "tap_max": 9, + "tap_step_degree": 0, + "tap_step_percent": 1.5, + "tap_phase_shifter": false + }, + "40 MVA 110/10 kV": { + "sn_mva": 40, + "vn_hv_kv": 110, + "vn_lv_kv": 10, + "vk_percent": 16.2, + "vkr_percent": 0.34, + "pfe_kw": 18, + "i0_percent": 0.05, + "shift_degree": 150, + "vector_group": "YNd5", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -9, + "tap_max": 9, + "tap_step_degree": 0, + "tap_step_percent": 1.5, + "tap_phase_shifter": false + }, + "25 MVA 110/10 kV": { + "sn_mva": 25, + "vn_hv_kv": 110, + "vn_lv_kv": 10, + "vk_percent": 12, + "vkr_percent": 0.41, + "pfe_kw": 14, + "i0_percent": 0.07, + "shift_degree": 150, + "vector_group": "YNd5", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -9, + "tap_max": 9, + "tap_step_degree": 0, + "tap_step_percent": 1.5, + "tap_phase_shifter": false + }, + "0.25 MVA 20/0.4 kV": { + "sn_mva": 0.25, + "vn_hv_kv": 20, + "vn_lv_kv": 0.4, + "vk_percent": 6, + "vkr_percent": 1.44, + "pfe_kw": 0.8, + "i0_percent": 0.32, + "shift_degree": 150, + "vector_group": "Yzn5", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -2, + "tap_max": 2, + "tap_step_degree": 0, + "tap_step_percent": 2.5, + "tap_phase_shifter": false + }, + "0.4 MVA 20/0.4 kV": { + "sn_mva": 0.4, + "vn_hv_kv": 20, + "vn_lv_kv": 0.4, + "vk_percent": 6, + "vkr_percent": 1.425, + "pfe_kw": 1.35, + "i0_percent": 0.3375, + "shift_degree": 150, + "vector_group": "Dyn5", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -2, + "tap_max": 2, + "tap_step_degree": 0, + "tap_step_percent": 2.5, + "tap_phase_shifter": false + }, + "0.63 MVA 20/0.4 kV": { + "sn_mva": 0.63, + "vn_hv_kv": 20, + "vn_lv_kv": 0.4, + "vk_percent": 6, + "vkr_percent": 1.206, + "pfe_kw": 1.65, + "i0_percent": 0.2619, + "shift_degree": 150, + "vector_group": "Dyn5", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -2, + "tap_max": 2, + "tap_step_degree": 0, + "tap_step_percent": 2.5, + "tap_phase_shifter": false + }, + "0.25 MVA 10/0.4 kV": { + "sn_mva": 0.25, + "vn_hv_kv": 10, + "vn_lv_kv": 0.4, + "vk_percent": 4, + "vkr_percent": 1.2, + "pfe_kw": 0.6, + "i0_percent": 0.24, + "shift_degree": 150, + "vector_group": "Dyn5", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -2, + "tap_max": 2, + "tap_step_degree": 0, + "tap_step_percent": 2.5, + "tap_phase_shifter": false + }, + "0.4 MVA 10/0.4 kV": { + "sn_mva": 0.4, + "vn_hv_kv": 10, + "vn_lv_kv": 0.4, + "vk_percent": 4, + "vkr_percent": 1.325, + "pfe_kw": 0.95, + "i0_percent": 0.2375, + "shift_degree": 150, + "vector_group": "Dyn5", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -2, + "tap_max": 2, + "tap_step_degree": 0, + "tap_step_percent": 2.5, + "tap_phase_shifter": false + }, + "0.63 MVA 10/0.4 kV": { + "sn_mva": 0.63, + "vn_hv_kv": 10, + "vn_lv_kv": 0.4, + "vk_percent": 4, + "vkr_percent": 1.0794, + "pfe_kw": 1.18, + "i0_percent": 0.1873, + "shift_degree": 150, + "vector_group": "Dyn5", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -2, + "tap_max": 2, + "tap_step_degree": 0, + "tap_step_percent": 2.5, + "tap_phase_shifter": false + } + }, + "trafo3w": { + "63/25/38 MVA 110/20/10 kV": { + "sn_hv_mva": 63, + "sn_mv_mva": 25, + "sn_lv_mva": 38, + "vn_hv_kv": 110, + "vn_mv_kv": 20, + "vn_lv_kv": 10, + "vk_hv_percent": 10.4, + "vk_mv_percent": 10.4, + "vk_lv_percent": 10.4, + "vkr_hv_percent": 0.28, + "vkr_mv_percent": 0.32, + "vkr_lv_percent": 0.35, + "pfe_kw": 35, + "i0_percent": 0.89, + "shift_mv_degree": 0, + "shift_lv_degree": 0, + "vector_group": "YN0yn0yn0", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -10, + "tap_max": 10, + "tap_step_percent": 1.2 + }, + "63/25/38 MVA 110/10/10 kV": { + "sn_hv_mva": 63, + "sn_mv_mva": 25, + "sn_lv_mva": 38, + "vn_hv_kv": 110, + "vn_mv_kv": 10, + "vn_lv_kv": 10, + "vk_hv_percent": 10.4, + "vk_mv_percent": 10.4, + "vk_lv_percent": 10.4, + "vkr_hv_percent": 0.28, + "vkr_mv_percent": 0.32, + "vkr_lv_percent": 0.35, + "pfe_kw": 35, + "i0_percent": 0.89, + "shift_mv_degree": 0, + "shift_lv_degree": 0, + "vector_group": "YN0yn0yn0", + "tap_side": "hv", + "tap_neutral": 0, + "tap_min": -10, + "tap_max": 10, + "tap_step_percent": 1.2 + } + } + }, + "res_bus": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"vm_pu\",\"va_degree\",\"p_mw\",\"q_mvar\"],\"index\":[0,1,2,3,4],\"data\":[[1.02,-0.845445168673926,0.0,-111.791243672370911],[1.02,0.0,-21.729831330858325,116.839935541152954],[1.019214100496144,-0.409103297622625,0.0,0.0],[1.018637116919488,-0.503470352662766,10.0,7.0],[1.017983079721402,-0.653497665026562,10.0,7.0]]}", + "orient": "split", + "dtype": { + "vm_pu": "float64", + "va_degree": "float64", + "p_mw": "float64", + "q_mvar": "float64" + } + }, + "res_line": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_from_mw\",\"q_from_mvar\",\"p_to_mw\",\"q_to_mvar\",\"pl_mw\",\"ql_mvar\",\"i_from_ka\",\"i_to_ka\",\"i_ka\",\"vm_from_pu\",\"va_from_degree\",\"vm_to_pu\",\"va_to_degree\",\"loading_percent\"],\"index\":[0,1,2,3,4,5,6,7],\"data\":[[-7.167647147657727,57.480079867900443,8.03525639977348,-60.113463233922118,0.867609252115754,-2.633383366021676,0.327874112511858,0.343286326507116,0.343286326507116,1.02,-0.845445168673926,1.02,0.0,57.214387751185988],[-0.657313913963437,25.969126903729045,0.866078469150186,-29.007927174007612,0.208764555186749,-3.038800270278568,0.147040043868819,0.164393305610081,0.164393305610081,1.02,-0.845445168673926,1.019214100496144,-0.409103297622625,74.724229822763931],[1.64566972119938,15.370129751576128,-1.540268914180618,-19.229415550834709,0.105400807018762,-3.859285799258581,0.087496748884432,0.109338903896103,0.109338903896103,1.02,-0.845445168673926,1.018637116919488,-0.503470352662766,68.336814935064211],[6.179291340421495,12.971907266349552,-6.119076735247816,-15.70424981919658,0.060214605173678,-2.732342552847028,0.081330018729726,0.095589209712924,0.095589209712924,1.02,-0.845445168673926,1.017983079721402,-0.653497665026562,59.743256070577175],[13.694574931085771,-56.726472302863066,-13.283848894885464,55.407854241119566,0.410726036200307,-1.3186180617435,0.330312825878128,0.322760996590474,0.330312825878128,1.02,0.0,1.019214100496144,-0.409103297622625,55.052137646354595],[6.208885212872048,-13.199963533555254,-6.184761786109662,11.833197159642042,0.024123426762386,-1.366766373913212,0.082632108556076,0.075677384410291,0.082632108556076,1.019214100496144,-0.409103297622625,1.018637116919488,-0.503470352662766,27.544036185358689],[6.208885212872048,-13.199963533555254,-6.184761786109662,11.833197159642042,0.024123426762386,-1.366766373913212,0.082632108556076,0.075677384410291,0.082632108556076,1.019214100496144,-0.409103297622625,1.018637116919488,-0.503470352662766,27.544036185358689],[3.909792486391969,-11.436978768449999,-3.88092326475316,8.704249819196738,0.028869221638809,-2.732728949253261,0.068506463438984,0.054050881891821,0.068506463438984,1.018637116919488,-0.503470352662766,1.017983079721402,-0.653497665026562,42.816539649365005]]}", + "orient": "split", + "dtype": { + "p_from_mw": "float64", + "q_from_mvar": "float64", + "p_to_mw": "float64", + "q_to_mvar": "float64", + "pl_mw": "float64", + "ql_mvar": "float64", + "i_from_ka": "float64", + "i_to_ka": "float64", + "i_ka": "float64", + "vm_from_pu": "float64", + "va_from_degree": "float64", + "vm_to_pu": "float64", + "va_to_degree": "float64", + "loading_percent": "float64" + } + }, + "res_trafo": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_hv_mw\",\"q_hv_mvar\",\"p_lv_mw\",\"q_lv_mvar\",\"pl_mw\",\"ql_mvar\",\"i_hv_ka\",\"i_lv_ka\",\"vm_hv_pu\",\"va_hv_degree\",\"vm_lv_pu\",\"va_lv_degree\",\"loading_percent\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "p_hv_mw": "float64", + "q_hv_mvar": "float64", + "p_lv_mw": "float64", + "q_lv_mvar": "float64", + "pl_mw": "float64", + "ql_mvar": "float64", + "i_hv_ka": "float64", + "i_lv_ka": "float64", + "vm_hv_pu": "float64", + "va_hv_degree": "float64", + "vm_lv_pu": "float64", + "va_lv_degree": "float64", + "loading_percent": "float64" + } + }, + "res_trafo3w": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_hv_mw\",\"q_hv_mvar\",\"p_mv_mw\",\"q_mv_mvar\",\"p_lv_mw\",\"q_lv_mvar\",\"pl_mw\",\"ql_mvar\",\"i_hv_ka\",\"i_mv_ka\",\"i_lv_ka\",\"vm_hv_pu\",\"va_hv_degree\",\"vm_mv_pu\",\"va_mv_degree\",\"vm_lv_pu\",\"va_lv_degree\",\"va_internal_degree\",\"vm_internal_pu\",\"loading_percent\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "p_hv_mw": "float64", + "q_hv_mvar": "float64", + "p_mv_mw": "float64", + "q_mv_mvar": "float64", + "p_lv_mw": "float64", + "q_lv_mvar": "float64", + "pl_mw": "float64", + "ql_mvar": "float64", + "i_hv_ka": "float64", + "i_mv_ka": "float64", + "i_lv_ka": "float64", + "vm_hv_pu": "float64", + "va_hv_degree": "float64", + "vm_mv_pu": "float64", + "va_mv_degree": "float64", + "vm_lv_pu": "float64", + "va_lv_degree": "float64", + "va_internal_degree": "float64", + "vm_internal_pu": "float64", + "loading_percent": "float64" + } + }, + "res_impedance": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_from_mw\",\"q_from_mvar\",\"p_to_mw\",\"q_to_mvar\",\"pl_mw\",\"ql_mvar\",\"i_from_ka\",\"i_to_ka\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "p_from_mw": "float64", + "q_from_mvar": "float64", + "p_to_mw": "float64", + "q_to_mvar": "float64", + "pl_mw": "float64", + "ql_mvar": "float64", + "i_from_ka": "float64", + "i_to_ka": "float64" + } + }, + "res_ext_grid": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_mw\",\"q_mvar\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "p_mw": "float64", + "q_mvar": "float64" + } + }, + "res_load": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_mw\",\"q_mvar\"],\"index\":[0,1,2],\"data\":[[10.0,7.0],[10.0,7.0],[10.0,7.0]]}", + "orient": "split", + "dtype": { + "p_mw": "float64", + "q_mvar": "float64" + } + }, + "res_motor": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_mw\",\"q_mvar\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "p_mw": "float64", + "q_mvar": "float64" + } + }, + "res_sgen": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_mw\",\"q_mvar\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "p_mw": "float64", + "q_mvar": "float64" + } + }, + "res_storage": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_mw\",\"q_mvar\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "p_mw": "float64", + "q_mvar": "float64" + } + }, + "res_shunt": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_mw\",\"q_mvar\",\"vm_pu\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "p_mw": "float64", + "q_mvar": "float64", + "vm_pu": "float64" + } + }, + "res_gen": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_mw\",\"q_mvar\",\"va_degree\",\"vm_pu\"],\"index\":[0,1],\"data\":[[10.0,118.791243672370911,-0.845445168673926,1.02],[21.729831330858325,-116.839935541152954,0.0,1.02]]}", + "orient": "split", + "dtype": { + "p_mw": "float64", + "q_mvar": "float64", + "va_degree": "float64", + "vm_pu": "float64" + } + }, + "res_ward": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_mw\",\"q_mvar\",\"vm_pu\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "p_mw": "float64", + "q_mvar": "float64", + "vm_pu": "float64" + } + }, + "res_xward": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_mw\",\"q_mvar\",\"vm_pu\",\"va_internal_degree\",\"vm_internal_pu\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "p_mw": "float64", + "q_mvar": "float64", + "vm_pu": "float64", + "va_internal_degree": "float64", + "vm_internal_pu": "float64" + } + }, + "res_dcline": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_from_mw\",\"q_from_mvar\",\"p_to_mw\",\"q_to_mvar\",\"pl_mw\",\"vm_from_pu\",\"va_from_degree\",\"vm_to_pu\",\"va_to_degree\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "p_from_mw": "float64", + "q_from_mvar": "float64", + "p_to_mw": "float64", + "q_to_mvar": "float64", + "pl_mw": "float64", + "vm_from_pu": "float64", + "va_from_degree": "float64", + "vm_to_pu": "float64", + "va_to_degree": "float64" + } + }, + "res_asymmetric_load": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_mw\",\"q_mvar\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "p_mw": "float64", + "q_mvar": "float64" + } + }, + "res_asymmetric_sgen": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_mw\",\"q_mvar\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "p_mw": "float64", + "q_mvar": "float64" + } + }, + "res_bus_est": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"vm_pu\",\"va_degree\",\"p_mw\",\"q_mvar\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "vm_pu": "float64", + "va_degree": "float64", + "p_mw": "float64", + "q_mvar": "float64" + } + }, + "res_line_est": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_from_mw\",\"q_from_mvar\",\"p_to_mw\",\"q_to_mvar\",\"pl_mw\",\"ql_mvar\",\"i_from_ka\",\"i_to_ka\",\"i_ka\",\"vm_from_pu\",\"va_from_degree\",\"vm_to_pu\",\"va_to_degree\",\"loading_percent\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "p_from_mw": "float64", + "q_from_mvar": "float64", + "p_to_mw": "float64", + "q_to_mvar": "float64", + "pl_mw": "float64", + "ql_mvar": "float64", + "i_from_ka": "float64", + "i_to_ka": "float64", + "i_ka": "float64", + "vm_from_pu": "float64", + "va_from_degree": "float64", + "vm_to_pu": "float64", + "va_to_degree": "float64", + "loading_percent": "float64" + } + }, + "res_trafo_est": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_hv_mw\",\"q_hv_mvar\",\"p_lv_mw\",\"q_lv_mvar\",\"pl_mw\",\"ql_mvar\",\"i_hv_ka\",\"i_lv_ka\",\"vm_hv_pu\",\"va_hv_degree\",\"vm_lv_pu\",\"va_lv_degree\",\"loading_percent\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "p_hv_mw": "float64", + "q_hv_mvar": "float64", + "p_lv_mw": "float64", + "q_lv_mvar": "float64", + "pl_mw": "float64", + "ql_mvar": "float64", + "i_hv_ka": "float64", + "i_lv_ka": "float64", + "vm_hv_pu": "float64", + "va_hv_degree": "float64", + "vm_lv_pu": "float64", + "va_lv_degree": "float64", + "loading_percent": "float64" + } + }, + "res_trafo3w_est": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_hv_mw\",\"q_hv_mvar\",\"p_mv_mw\",\"q_mv_mvar\",\"p_lv_mw\",\"q_lv_mvar\",\"pl_mw\",\"ql_mvar\",\"i_hv_ka\",\"i_mv_ka\",\"i_lv_ka\",\"vm_hv_pu\",\"va_hv_degree\",\"vm_mv_pu\",\"va_mv_degree\",\"vm_lv_pu\",\"va_lv_degree\",\"va_internal_degree\",\"vm_internal_pu\",\"loading_percent\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "p_hv_mw": "float64", + "q_hv_mvar": "float64", + "p_mv_mw": "float64", + "q_mv_mvar": "float64", + "p_lv_mw": "float64", + "q_lv_mvar": "float64", + "pl_mw": "float64", + "ql_mvar": "float64", + "i_hv_ka": "float64", + "i_mv_ka": "float64", + "i_lv_ka": "float64", + "vm_hv_pu": "float64", + "va_hv_degree": "float64", + "vm_mv_pu": "float64", + "va_mv_degree": "float64", + "vm_lv_pu": "float64", + "va_lv_degree": "float64", + "va_internal_degree": "float64", + "vm_internal_pu": "float64", + "loading_percent": "float64" + } + }, + "res_impedance_est": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_from_mw\",\"q_from_mvar\",\"p_to_mw\",\"q_to_mvar\",\"pl_mw\",\"ql_mvar\",\"i_from_ka\",\"i_to_ka\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "p_from_mw": "float64", + "q_from_mvar": "float64", + "p_to_mw": "float64", + "q_to_mvar": "float64", + "pl_mw": "float64", + "ql_mvar": "float64", + "i_from_ka": "float64", + "i_to_ka": "float64" + } + }, + "res_bus_sc": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[],\"index\":[],\"data\":[]}", + "orient": "split" + }, + "res_line_sc": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[],\"index\":[],\"data\":[]}", + "orient": "split" + }, + "res_trafo_sc": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[],\"index\":[],\"data\":[]}", + "orient": "split" + }, + "res_trafo3w_sc": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[],\"index\":[],\"data\":[]}", + "orient": "split" + }, + "res_ext_grid_sc": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[],\"index\":[],\"data\":[]}", + "orient": "split" + }, + "res_gen_sc": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[],\"index\":[],\"data\":[]}", + "orient": "split" + }, + "res_sgen_sc": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[],\"index\":[],\"data\":[]}", + "orient": "split" + }, + "res_bus_3ph": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"vm_a_pu\",\"va_a_degree\",\"vm_b_pu\",\"va_b_degree\",\"vm_c_pu\",\"va_c_degree\",\"p_a_mw\",\"q_a_mvar\",\"p_b_mw\",\"q_b_mvar\",\"p_c_mw\",\"q_c_mvar\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "vm_a_pu": "float64", + "va_a_degree": "float64", + "vm_b_pu": "float64", + "va_b_degree": "float64", + "vm_c_pu": "float64", + "va_c_degree": "float64", + "p_a_mw": "float64", + "q_a_mvar": "float64", + "p_b_mw": "float64", + "q_b_mvar": "float64", + "p_c_mw": "float64", + "q_c_mvar": "float64" + } + }, + "res_line_3ph": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_a_from_mw\",\"q_a_from_mvar\",\"p_b_from_mw\",\"q_b_from_mvar\",\"q_c_from_mvar\",\"p_a_to_mw\",\"q_a_to_mvar\",\"p_b_to_mw\",\"q_b_to_mvar\",\"p_c_to_mw\",\"q_c_to_mvar\",\"p_a_l_mw\",\"q_a_l_mvar\",\"p_b_l_mw\",\"q_b_l_mvar\",\"p_c_l_mw\",\"q_c_l_mvar\",\"i_a_from_ka\",\"i_a_to_ka\",\"i_b_from_ka\",\"i_b_to_ka\",\"i_c_from_ka\",\"i_c_to_ka\",\"i_a_ka\",\"i_b_ka\",\"i_c_ka\",\"i_n_from_ka\",\"i_n_to_ka\",\"i_n_ka\",\"loading_a_percent\",\"loading_b_percent\",\"loading_c_percent\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "p_a_from_mw": "float64", + "q_a_from_mvar": "float64", + "p_b_from_mw": "float64", + "q_b_from_mvar": "float64", + "q_c_from_mvar": "float64", + "p_a_to_mw": "float64", + "q_a_to_mvar": "float64", + "p_b_to_mw": "float64", + "q_b_to_mvar": "float64", + "p_c_to_mw": "float64", + "q_c_to_mvar": "float64", + "p_a_l_mw": "float64", + "q_a_l_mvar": "float64", + "p_b_l_mw": "float64", + "q_b_l_mvar": "float64", + "p_c_l_mw": "float64", + "q_c_l_mvar": "float64", + "i_a_from_ka": "float64", + "i_a_to_ka": "float64", + "i_b_from_ka": "float64", + "i_b_to_ka": "float64", + "i_c_from_ka": "float64", + "i_c_to_ka": "float64", + "i_a_ka": "float64", + "i_b_ka": "float64", + "i_c_ka": "float64", + "i_n_from_ka": "float64", + "i_n_to_ka": "float64", + "i_n_ka": "float64", + "loading_a_percent": "float64", + "loading_b_percent": "float64", + "loading_c_percent": "float64" + } + }, + "res_trafo_3ph": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_a_hv_mw\",\"q_a_hv_mvar\",\"p_b_hv_mw\",\"q_b_hv_mvar\",\"p_c_hv_mw\",\"q_c_hv_mvar\",\"p_a_lv_mw\",\"q_a_lv_mvar\",\"p_b_lv_mw\",\"q_b_lv_mvar\",\"p_c_lv_mw\",\"q_c_lv_mvar\",\"p_a_l_mw\",\"q_a_l_mvar\",\"p_b_l_mw\",\"q_b_l_mvar\",\"p_c_l_mw\",\"q_c_l_mvar\",\"i_a_hv_ka\",\"i_a_lv_ka\",\"i_b_hv_ka\",\"i_b_lv_ka\",\"i_c_hv_ka\",\"i_c_lv_ka\",\"loading_a_percent\",\"loading_b_percent\",\"loading_c_percent\",\"loading_percent\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "p_a_hv_mw": "float64", + "q_a_hv_mvar": "float64", + "p_b_hv_mw": "float64", + "q_b_hv_mvar": "float64", + "p_c_hv_mw": "float64", + "q_c_hv_mvar": "float64", + "p_a_lv_mw": "float64", + "q_a_lv_mvar": "float64", + "p_b_lv_mw": "float64", + "q_b_lv_mvar": "float64", + "p_c_lv_mw": "float64", + "q_c_lv_mvar": "float64", + "p_a_l_mw": "float64", + "q_a_l_mvar": "float64", + "p_b_l_mw": "float64", + "q_b_l_mvar": "float64", + "p_c_l_mw": "float64", + "q_c_l_mvar": "float64", + "i_a_hv_ka": "float64", + "i_a_lv_ka": "float64", + "i_b_hv_ka": "float64", + "i_b_lv_ka": "float64", + "i_c_hv_ka": "float64", + "i_c_lv_ka": "float64", + "loading_a_percent": "float64", + "loading_b_percent": "float64", + "loading_c_percent": "float64", + "loading_percent": "float64" + } + }, + "res_ext_grid_3ph": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_a_mw\",\"q_a_mvar\",\"p_b_mw\",\"q_b_mvar\",\"p_c_mw\",\"q_c_mvar\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "p_a_mw": "float64", + "q_a_mvar": "float64", + "p_b_mw": "float64", + "q_b_mvar": "float64", + "p_c_mw": "float64", + "q_c_mvar": "float64" + } + }, + "res_shunt_3ph": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[],\"index\":[],\"data\":[]}", + "orient": "split" + }, + "res_load_3ph": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_mw\",\"q_mvar\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "p_mw": "float64", + "q_mvar": "float64" + } + }, + "res_sgen_3ph": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_mw\",\"q_mvar\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "p_mw": "float64", + "q_mvar": "float64" + } + }, + "res_storage_3ph": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_mw\",\"q_mvar\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "p_mw": "float64", + "q_mvar": "float64" + } + }, + "res_asymmetric_load_3ph": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_a_mw\",\"q_a_mvar\",\"p_b_mw\",\"q_b_mvar\",\"p_c_mw\",\"q_c_mvar\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "p_a_mw": "float64", + "q_a_mvar": "float64", + "p_b_mw": "float64", + "q_b_mvar": "float64", + "p_c_mw": "float64", + "q_c_mvar": "float64" + } + }, + "res_asymmetric_sgen_3ph": { + "_module": "pandas.core.frame", + "_class": "DataFrame", + "_object": "{\"columns\":[\"p_a_mw\",\"q_a_mvar\",\"p_b_mw\",\"q_b_mvar\",\"p_c_mw\",\"q_c_mvar\"],\"index\":[],\"data\":[]}", + "orient": "split", + "dtype": { + "p_a_mw": "float64", + "q_a_mvar": "float64", + "p_b_mw": "float64", + "q_b_mvar": "float64", + "p_c_mw": "float64", + "q_c_mvar": "float64" + } + }, + "user_pf_options": {}, + "OPF_converged": false + } +} \ No newline at end of file diff --git a/grid2op/data_test/5bus_example_act_topo_set_init/prods_charac.csv b/grid2op/data_test/5bus_example_act_topo_set_init/prods_charac.csv new file mode 100644 index 000000000..f47a90595 --- /dev/null +++ b/grid2op/data_test/5bus_example_act_topo_set_init/prods_charac.csv @@ -0,0 +1,3 @@ +Pmax,Pmin,name,type,bus,max_ramp_up,max_ramp_down,min_up_time,min_down_time,marginal_cost,shut_down_cost,start_cost,x,y,V +15,0.0,gen_0_0,wind,5,0,0,0,0,0,0,0,0,0,102. +35,0.0,gen_1_1,thermal,0,15,15,4,4,70,1,2,0,400,102. \ No newline at end of file diff --git a/grid2op/tests/test_Environment.py b/grid2op/tests/test_Environment.py index 055f3e865..61106baae 100644 --- a/grid2op/tests/test_Environment.py +++ b/grid2op/tests/test_Environment.py @@ -266,13 +266,15 @@ def test_reward(self): i = 0 self.chronics_handler.next_chronics() + ch = copy.deepcopy(self.chronics_handler) + ch.cleanup_action_space() with warnings.catch_warnings(): warnings.filterwarnings("ignore") self.env = Environment( init_grid_path=os.path.join(self.path_matpower, self.case_file), backend=self.get_backend(), init_env_path=os.path.join(self.path_matpower, self.case_file), - chronics_handler=self.chronics_handler, + chronics_handler=ch, parameters=self.env_params, rewardClass=L2RPNReward, names_chronics_to_backend=self.names_chronics_to_backend, diff --git a/grid2op/tests/test_action_set_orig_state.py b/grid2op/tests/test_action_set_orig_state.py index 8e8996676..7c8715de2 100644 --- a/grid2op/tests/test_action_set_orig_state.py +++ b/grid2op/tests/test_action_set_orig_state.py @@ -11,8 +11,15 @@ import numpy as np import warnings import unittest - +try: + from lightsim2grid import LightSimBackend + LS_AVAIL = True +except ImportError: + LS_AVAIL = False + import grid2op +from grid2op.Environment import TimedOutEnvironment, MaskedEnvironment, SingleEnvMultiProcess +from grid2op.Backend import PandaPowerBackend from grid2op.Episode import EpisodeData from grid2op.Opponent import FromEpisodeDataOpponent from grid2op.Runner import Runner @@ -30,13 +37,10 @@ FromNPY) from grid2op.Chronics.handlers import CSVHandler, JSONInitStateHandler -# TODO test forecast env + # TODO test with and without shunt # TODO test grid2Op compat mode (storage units) # TODO test with "names_orig_to_backend" -# TODO test with lightsimbackend -# TODO test with Runner -# TODO test other type of environment (multimix, masked etc.) class TestSetActOrigDefault(unittest.TestCase): @@ -54,12 +58,16 @@ def _env_path(self): PATH_DATA_TEST, "5bus_example_act_topo_set_init" ) + def _get_backend(self): + return PandaPowerBackend() + def setUp(self) -> None: self.env_nm = self._env_path() with warnings.catch_warnings(): warnings.filterwarnings("ignore") self.env = grid2op.make(self.env_nm, test=True, + backend=self._get_backend(), action_class=self._get_act_cls(), chronics_class=self._get_ch_cls(), data_feeding_kwargs={"gridvalueClass": self._get_c_cls()} @@ -71,37 +79,51 @@ def setUp(self) -> None: assert issubclass(self.env.action_space.subtype, self._get_act_cls()) assert isinstance(self.env.chronics_handler.real_data, self._get_ch_cls()) assert isinstance(self.env.chronics_handler.real_data.data, self._get_c_cls()) + assert isinstance(self.env.backend, type(self._get_backend())) def tearDown(self) -> None: self.env.close() return super().tearDown() + def _aux_reset_env(self, seed, ep_id): + obs = self.env.reset(seed=seed, options={"time serie id": ep_id}) + return obs + + def _aux_make_step(self, act=None): + if act is None: + act = self.env.action_space() + return self.env.step(act) + + def _aux_get_init_act(self): + return self.env.chronics_handler.get_init_action() + def test_working_setbus(self): # ts id 0 => set_bus - self.obs = self.env.reset(seed=0, options={"time serie id": 0}) + self.obs = self._aux_reset_env(seed=0, ep_id=0) assert self.obs.topo_vect[self.obs.line_or_pos_topo_vect[1]] == 2 assert self.obs.topo_vect[self.obs.load_pos_topo_vect[0]] == 2 assert (self.obs.time_before_cooldown_line == 0).all() assert (self.obs.time_before_cooldown_sub == 0).all() - obs, reward, done, info = self.env.step(self.env.action_space()) + + obs, reward, done, info = self._aux_make_step() assert not done assert obs.topo_vect[self.obs.line_or_pos_topo_vect[1]] == 2 assert obs.topo_vect[self.obs.load_pos_topo_vect[0]] == 2 assert (obs.time_before_cooldown_line == 0).all() assert (obs.time_before_cooldown_sub == 0).all() - def test_working_setstatus(self): # ts id 1 => set_status - self.obs = self.env.reset(seed=0, options={"time serie id": 1}) + self.obs = self._aux_reset_env(seed=0, ep_id=1) assert self.obs.topo_vect[self.obs.line_or_pos_topo_vect[1]] == -1 assert self.obs.topo_vect[self.obs.line_ex_pos_topo_vect[1]] == -1 assert not self.obs.line_status[1] assert (self.obs.time_before_cooldown_line == 0).all() assert (self.obs.time_before_cooldown_sub == 0).all() - obs, reward, done, info = self.env.step(self.env.action_space()) + + obs, reward, done, info = self._aux_make_step() assert not done assert obs.topo_vect[self.obs.line_or_pos_topo_vect[1]] == -1 assert obs.topo_vect[self.obs.line_ex_pos_topo_vect[1]] == -1 @@ -111,14 +133,17 @@ def test_working_setstatus(self): def test_rules_ok(self): """test that even if the action to set is illegal, it works (case of ts id 2)""" - self.obs = self.env.reset(seed=0, options={"time serie id": 2}) + self.obs = self._aux_reset_env(seed=0, ep_id=2) assert self.obs.topo_vect[self.obs.line_or_pos_topo_vect[1]] == 2 assert self.obs.topo_vect[self.obs.line_ex_pos_topo_vect[5]] == 2 assert (self.obs.time_before_cooldown_line == 0).all() assert (self.obs.time_before_cooldown_sub == 0).all() - act_init = self.env.chronics_handler.get_init_action() - obs, reward, done, info = self.env.step(act_init) + act_init = self._aux_get_init_act() + if act_init is None: + # test not correct for multiprocessing, I stop here + return + obs, reward, done, info = self._aux_make_step(act_init) assert info["exception"] is not None assert info["is_illegal"] assert obs.topo_vect[self.obs.line_or_pos_topo_vect[1]] == 2 @@ -307,7 +332,130 @@ def setUp(self) -> None: "init_state_handler": JSONInitStateHandler("init_state_handler") } ) + + +class TestSetActOrigLightsim(TestSetActOrigDefault): + def _get_backend(self): + if not LS_AVAIL: + self.skipTest("LightSimBackend is not available") + return LightSimBackend() + + +class TestSetActOrigTOEnv(TestSetActOrigDefault): + def setUp(self) -> None: + super().setUp() + env_init = self.env + with warnings.catch_warnings(): + warnings.filterwarnings("ignore") + self.env = TimedOutEnvironment(self.env) + env_init.close() + return LightSimBackend() + + +class TestSetActOrigMaskedEnv(TestSetActOrigDefault): + def setUp(self) -> None: + super().setUp() + env_init = self.env + with warnings.catch_warnings(): + warnings.filterwarnings("ignore") + self.env = MaskedEnvironment(self.env, + lines_of_interest=np.array([1, 1, 1, 1, 0, 0, 0, 0])) + env_init.close() + + +def always_true(x): + # I can't use lambda in set_filter (lambda cannot be pickled) + return True + + +class TestSetActOrigMultiProcEnv(TestSetActOrigDefault): + def _aux_reset_env(self, seed, ep_id): + # self.env.seed(seed) + self.env.set_id(ep_id) + obs = self.env.reset() + return obs[0] + + def _aux_get_init_act(self): + return None + def _aux_make_step(self): + obs, reward, done, info = self.env.step([self.env_init.action_space(), self.env_init.action_space()]) + return obs[0], reward[0], done[0], info[0] + + def setUp(self) -> None: + super().setUp() + self.env_init = self.env + with warnings.catch_warnings(): + warnings.filterwarnings("ignore") + self.env = SingleEnvMultiProcess(self.env, 2) + self.env.set_filter(always_true) + + def tearDown(self) -> None: + self.env_init.close() + return super().tearDown() + + +class TestSetActOrigForcastEnv(TestSetActOrigDefault): + def test_working_setbus(self): + super().test_working_setbus() + for_env = self.env.get_obs().get_forecast_env() + obs, reward, done, info = for_env.step(self.env.action_space()) + + def test_working_setstatus(self): + super().test_working_setstatus() + for_env = self.env.get_obs().get_forecast_env() + obs, reward, done, info = for_env.step(self.env.action_space()) + + def test_rules_ok(self): + super().test_rules_ok() + for_env = self.env.get_obs().get_forecast_env() + obs, reward, done, info = for_env.step(self.env.action_space()) + + +class TestSetActOrigRunner(unittest.TestCase): + def _env_path(self): + return TestSetActOrigDefault._env_path(self) + def setUp(self) -> None: + self.env_nm = self._env_path() + with warnings.catch_warnings(): + warnings.filterwarnings("ignore") + self.env = grid2op.make(self.env_nm, + test=True + ) + def tearDown(self) -> None: + self.env.close() + return super().tearDown() + + def test_right_init_act(self): + runner = Runner(**self.env.get_params_for_runner()) + res = runner.run(nb_episode=3, + episode_id=[0, 1, 2], + max_iter=10, + add_detailed_output=True) + for i, el in enumerate(res): + ep_data = el[-1] + init_obs = ep_data.observations[0] + if i == 0: + assert init_obs.topo_vect[init_obs.line_or_pos_topo_vect[1]] == 2 + assert init_obs.topo_vect[init_obs.load_pos_topo_vect[0]] == 2 + assert (init_obs.time_before_cooldown_line == 0).all() + assert (init_obs.time_before_cooldown_sub == 0).all() + elif i == 1: + assert init_obs.topo_vect[init_obs.line_or_pos_topo_vect[1]] == -1 + assert init_obs.topo_vect[init_obs.line_ex_pos_topo_vect[1]] == -1 + assert not init_obs.line_status[1] + assert (init_obs.time_before_cooldown_line == 0).all() + assert (init_obs.time_before_cooldown_sub == 0).all() + elif i == 2: + assert init_obs.topo_vect[init_obs.line_or_pos_topo_vect[1]] == 2 + assert init_obs.topo_vect[init_obs.line_ex_pos_topo_vect[5]] == 2 + assert (init_obs.time_before_cooldown_line == 0).all() + assert (init_obs.time_before_cooldown_sub == 0).all() + else: + raise RuntimeError("Test is coded correctly") + + + if __name__ == "__main__": unittest.main() From 00b2cb23e73cbf696c25b1605c15c8e38977300c Mon Sep 17 00:00:00 2001 From: DONNOT Benjamin Date: Thu, 2 May 2024 17:37:56 +0200 Subject: [PATCH 03/11] adding a function to set the original grid state when calling reset, need testing [skip ci] --- CHANGELOG.rst | 4 + grid2op/Action/actionSpace.py | 1 + grid2op/Action/baseAction.py | 55 +++- grid2op/Environment/baseEnv.py | 2 +- grid2op/Environment/baseMultiProcessEnv.py | 2 +- grid2op/Environment/environment.py | 99 +++++++- .../chronics/0/init_state.json | 2 +- grid2op/tests/test_action_set_orig_state.py | 1 + .../test_action_set_orig_state_options.py | 236 ++++++++++++++++++ grid2op/typing_variables.py | 2 +- 10 files changed, 393 insertions(+), 11 deletions(-) create mode 100644 grid2op/tests/test_action_set_orig_state_options.py diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 6a26ce63a..7b97ede2e 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -64,6 +64,10 @@ Change Log - [FIXED] notebook 5 on loading back data with `EpisodeData`. - [FIXED] converter between backends (could not handle more than 2 busbars) - [FIXED] a bug in `BaseMultiProcessEnvironment`: set_filter had no impact +- [FIXED] an issue in the `Runner` (`self.chronics_handler` was sometimes used, sometimes not + and most of the time incorrectly) +- [FIXED] on `RemoteEnv` class (impact all multi process environment): the kwargs used to build then backend + where not used which could lead to"wrong" backends being used in the sub processes. - [IMPROVED] documentation about `obs.simulate` to make it clearer the difference between env.step and obs.simulate on some cases - [IMPROVED] type hints on some methods of `GridObjects` diff --git a/grid2op/Action/actionSpace.py b/grid2op/Action/actionSpace.py index b8f870062..63e68614c 100644 --- a/grid2op/Action/actionSpace.py +++ b/grid2op/Action/actionSpace.py @@ -10,6 +10,7 @@ import copy from typing import Dict, List, Any, Literal +import grid2op from grid2op.Action.baseAction import BaseAction from grid2op.Action.serializableActionSpace import SerializableActionSpace diff --git a/grid2op/Action/baseAction.py b/grid2op/Action/baseAction.py index 780f81ea4..ac34da73e 100644 --- a/grid2op/Action/baseAction.py +++ b/grid2op/Action/baseAction.py @@ -624,6 +624,7 @@ def as_serializable_dict(self) -> dict: """ res = {} + cls = type(self) # bool elements if self._modif_alert: res["raise_alert"] = [ @@ -645,7 +646,7 @@ def as_serializable_dict(self) -> dict: self._aux_serialize_add_key_change("gen_change_bus", "generators_id", res["change_bus"]) self._aux_serialize_add_key_change("line_or_change_bus", "lines_or_id", res["change_bus"]) self._aux_serialize_add_key_change("line_ex_change_bus", "lines_ex_id", res["change_bus"]) - if hasattr(type(self), "n_storage") and type(self).n_storage: + if hasattr(cls, "n_storage") and cls.n_storage: self._aux_serialize_add_key_change("storage_change_bus", "storages_id", res["change_bus"]) if not res["change_bus"]: del res["change_bus"] @@ -664,7 +665,7 @@ def as_serializable_dict(self) -> dict: self._aux_serialize_add_key_set("gen_set_bus", "generators_id", res["set_bus"]) self._aux_serialize_add_key_set("line_or_set_bus", "lines_or_id", res["set_bus"]) self._aux_serialize_add_key_set("line_ex_set_bus", "lines_ex_id", res["set_bus"]) - if hasattr(type(self), "n_storage") and type(self).n_storage: + if hasattr(cls, "n_storage") and cls.n_storage: self._aux_serialize_add_key_set("storage_set_bus", "storages_id", res["set_bus"]) if not res["set_bus"]: del res["set_bus"] @@ -715,7 +716,7 @@ def as_serializable_dict(self) -> dict: if not res["injection"]: del res["injection"] - if type(self).shunts_data_available: + if cls.shunts_data_available: res["shunt"] = {} if np.isfinite(self.shunt_p).any(): res["shunt"]["shunt_p"] = [ @@ -6473,3 +6474,51 @@ def decompose_as_unary_actions(self, if self._modif_curtailment: self._aux_decompose_as_unary_actions_curtail(cls, group_curtail, res) return res + + def _add_act_and_remove_line_status_only_set(self, other: "BaseAction"): + """INTERNAL + + This is used by the environment when combining action in the "set state" in env.reset. + + It supposes both self and other are only "set" actions + """ + self += other + cls = type(self) + # switch off in self the element disconnected in other + switched_off = other._set_line_status == -1 + switched_off |= self._set_topo_vect[cls.line_or_pos_topo_vect] == -1 + switched_off |= self._set_topo_vect[cls.line_ex_pos_topo_vect] == -1 + self._set_topo_vect[cls.line_or_pos_topo_vect[switched_off]] = -1 + self._set_topo_vect[cls.line_ex_pos_topo_vect[switched_off]] = -1 + self._set_line_status[switched_off] = -1 + + # switch on in self the element reconnected in other + switched_on = other._set_line_status == 1 + switched_on |= self._set_topo_vect[cls.line_or_pos_topo_vect] > 0 + switched_on |= self._set_topo_vect[cls.line_ex_pos_topo_vect] > 0 + self._set_topo_vect[cls.line_or_pos_topo_vect[switched_on]] = np.maximum(other._set_topo_vect[cls.line_or_pos_topo_vect[switched_on]], + 0) + self._set_topo_vect[cls.line_ex_pos_topo_vect[switched_on]] = np.maximum(other._set_topo_vect[cls.line_ex_pos_topo_vect[switched_on]], + 0) + self._set_line_status[switched_on] = 1 + + if (self._set_line_status != 0).any(): + self._modif_set_status = True + if (self._set_topo_vect != 0).any(): + self._modif_set_bus = True + + def remove_change(self) -> "BaseAction": + """This function will modify 'self' and remove all "change" action type. + + It is mainly used in the environment, when removing the "change" type for setting the original + state of the grid. + + """ + if self._change_bus_vect.any(): + warnings.warn("This action modified the buses with `change_bus` ") + self._change_bus_vect[:] = False + self._modif_change_bus = False + if self._switch_line_status.any(): + self._switch_line_status[:] = False + self._modif_change_status = False + return self \ No newline at end of file diff --git a/grid2op/Environment/baseEnv.py b/grid2op/Environment/baseEnv.py index d97b21221..b62d31c10 100644 --- a/grid2op/Environment/baseEnv.py +++ b/grid2op/Environment/baseEnv.py @@ -299,7 +299,7 @@ def foo(manager): #: this are the keys of the dictionnary `options` #: that can be used when calling `env.reset(..., options={})` - KEYS_RESET_OPTIONS = {"time serie id"} + KEYS_RESET_OPTIONS = {"time serie id", "init state"} def __init__( diff --git a/grid2op/Environment/baseMultiProcessEnv.py b/grid2op/Environment/baseMultiProcessEnv.py index 2ab2bafce..22f9f182c 100644 --- a/grid2op/Environment/baseMultiProcessEnv.py +++ b/grid2op/Environment/baseMultiProcessEnv.py @@ -87,7 +87,7 @@ def init_env(self): """ self.space_prng = np.random.RandomState() self.space_prng.seed(seed=self.seed_used) - self.backend = self.env_params["_raw_backend_class"]() + self.backend = self.env_params["_raw_backend_class"](**self.env_params["_backend_kwargs"]) with warnings.catch_warnings(): # warnings have bee already sent in the main process, no need to resend them warnings.filterwarnings("ignore") diff --git a/grid2op/Environment/environment.py b/grid2op/Environment/environment.py index 59def73dd..c296daa8f 100644 --- a/grid2op/Environment/environment.py +++ b/grid2op/Environment/environment.py @@ -33,6 +33,7 @@ from grid2op.Opponent import BaseOpponent, NeverAttackBudget from grid2op.operator_attention import LinearAttentionBudget from grid2op.Space import DEFAULT_N_BUSBAR_PER_SUB +from grid2op.typing_variables import RESET_OPTIONS_TYPING class Environment(BaseEnv): @@ -807,7 +808,7 @@ def __str__(self): return "<{} instance named {}>".format(type(self).__name__, self.name) # TODO be closer to original gym implementation - def reset_grid(self): + def reset_grid(self, init_state_dict=None, method="combine"): """ INTERNAL @@ -831,10 +832,23 @@ def reset_grid(self): self._backend_action = self._backend_action_class() self.nb_time_step = -1 # to have init obs at step 1 (and to prevent 'setting to proper state' "action" to be illegal) - init_action = self.chronics_handler.get_init_action() + init_action : BaseAction = self.chronics_handler.get_init_action() if init_action is None: # default behaviour for grid2op < 1.10.2 init_action = self._helper_action_env({}) + else: + init_action.remove_change() + + if init_state_dict is not None: + init_act_opt : BaseAction = self._helper_action_env(init_state_dict) + if method == "combine": + init_action._add_act_and_remove_line_status_only_set(init_act_opt) + elif method == "ignore": + init_action = init_act_opt + else: + raise Grid2OpException(f"kwargs `method` used to set the initial state of the grid " + f"is not understood (use one of `combine` or `ignore` and " + f"not `{method}`)") *_, fail_to_start, info = self.step(init_action) if fail_to_start: raise Grid2OpException( @@ -863,7 +877,7 @@ def add_text_logger(self, logger=None): def reset(self, *, seed: Union[int, None] = None, - options: Union[Dict[Union[str, Literal["time serie id"]], Union[int, str]], None] = None) -> BaseObservation: + options: RESET_OPTIONS_TYPING = None) -> BaseObservation: """ Reset the environment to a clean state. It will reload the next chronics if any. And reset the grid to a clean state. @@ -932,6 +946,65 @@ def reset(self, obs = env.reset(options={"time serie id": time_serie_id}) ... + Another feature has been added in version 1.10.2, which is the possibility to set the + grid to a given "topological" state at the first observation (before this version, + you could only retrieve an observation with everything connected together). + + In grid2op 1.10.2, you can do that by using the keys `"init state"` in the "options" kwargs of + the reset function. The value associated to this key should be dictionnary that can be + converted to a non ambiguous grid2op action using an "action space". + + .. notes:: + The "action space" used here is not the action space of the agent. It's an "action + space" that uses a :grid2op:`Action.Action.BaseAction` class meaning you can do any + type of action, on shunts, on topology, on line status etc. even if the agent is not + allowed to. + + Likewise, nothing check if this action is legal or not. + + You can use it like this: + + .. code-block:: python + + # to start an episode with a line disconnected, you can do: + init_state_dict = {"set_line_status": [(0, -1)]} + obs = env.reset(options={"init state": init_state_dict}) + obs.line_status[0] is False + + # to start an episode with a different topolovy + init_state_dict = {"set_bus": {"lines_or_id": [(0, 2)], "lines_ex_id": [(3, 2)]}} + obs = env.reset(options={"init state": init_state_dict}) + + .. note:: + Since grid2op version 1.10.2, there is also the possibility to set the "initial state" + of the grid directly in the time series. The priority is always given to the + argument passed in the "options" value. + + Concretely if, in the "time series" (formelly called "chronics") provides an action would change + the topology of substation 1 and 2 (for example) and you provide an action that disable the + line 6, then the initial state will see substation 1 and 2 changed (as in the time series) + and line 6 disconnected. + + Another example in this case: if the action you provide would change topology of substation 2 and 4 + then the initial state (after `env.reset`) will give: + - substation 1 as in the time serie + - substation 2 as in "options" + - substation 4 as in "options" + + .. note:: + Concerning the previously described behaviour, if you want to ignore the data in the + time series, you can add : `"method": "ignore"` in the dictionary describing the action. + In this case the action in the time series will be totally ignored and the initial + state will be fully set by the action passed in the "options" dict. + + An example is: + + .. code-block:: python + + init_state_dict = {"set_line_status": [(0, -1)], "method": "force"} + obs = env.reset(options={"init state": init_state_dict}) + obs.line_status[0] is False + """ super().reset(seed=seed, options=options) @@ -947,7 +1020,20 @@ def reset(self, self._reset_maintenance() self._reset_redispatching() self._reset_vectors_and_timings() # it need to be done BEFORE to prevent cascading failure when there has been - self.reset_grid() + method = "combine" + act_as_dict = None + if "init state" in options: + act_as_dict = options["init state"] + if "method" in act_as_dict: + method = act_as_dict["method"] + del act_as_dict["method"] + init_state : BaseAction = self._helper_action_env(act_as_dict) + ambiguous, except_tmp = init_state.is_ambiguous() + if ambiguous: + raise Grid2OpException("You provided an invalid (ambiguous) action to set the 'init state'") from except_tmp + init_state.remove_change() + + self.reset_grid(act_as_dict, method) if self.viewer_fig is not None: del self.viewer_fig self.viewer_fig = None @@ -1108,12 +1194,17 @@ def get_kwargs(self, with_backend=True, with_chronics_handler=True): if with_chronics_handler: res["chronics_handler"] = copy.deepcopy(self.chronics_handler) res["chronics_handler"].cleanup_action_space() + + # deals with the backend if with_backend: if not self.backend._can_be_copied: raise RuntimeError("Impossible to get the kwargs for this " "environment, the backend cannot be copied.") res["backend"] = self.backend.copy() res["backend"]._is_loaded = False # i can reload a copy of an environment + else: + res["_backend_kwargs"] = self.backend._my_kwargs + res["parameters"] = copy.deepcopy(self._parameters) res["names_chronics_to_backend"] = copy.deepcopy( self._names_chronics_to_backend diff --git a/grid2op/data_test/5bus_example_act_topo_set_init/chronics/0/init_state.json b/grid2op/data_test/5bus_example_act_topo_set_init/chronics/0/init_state.json index 4442bc19e..e822a78b8 100644 --- a/grid2op/data_test/5bus_example_act_topo_set_init/chronics/0/init_state.json +++ b/grid2op/data_test/5bus_example_act_topo_set_init/chronics/0/init_state.json @@ -1,3 +1,3 @@ { - "set_bus": {"lines_or_id": [["0_2_1", 2]], "loads_id": [["load_0_0", 2]]} + "set_bus": {"lines_or_id": [["0_2_1", 2], ["0_3_2", 1]], "loads_id": [["load_0_0", 2]]} } \ No newline at end of file diff --git a/grid2op/tests/test_action_set_orig_state.py b/grid2op/tests/test_action_set_orig_state.py index 7c8715de2..63a8aa1fa 100644 --- a/grid2op/tests/test_action_set_orig_state.py +++ b/grid2op/tests/test_action_set_orig_state.py @@ -38,6 +38,7 @@ from grid2op.Chronics.handlers import CSVHandler, JSONInitStateHandler +# TODO test "change" is deactivated # TODO test with and without shunt # TODO test grid2Op compat mode (storage units) # TODO test with "names_orig_to_backend" diff --git a/grid2op/tests/test_action_set_orig_state_options.py b/grid2op/tests/test_action_set_orig_state_options.py new file mode 100644 index 000000000..f84fcd76a --- /dev/null +++ b/grid2op/tests/test_action_set_orig_state_options.py @@ -0,0 +1,236 @@ +# Copyright (c) 2019-2020, RTE (https://www.rte-france.com) +# See AUTHORS.txt +# This Source Code Form is subject to the terms of the Mozilla Public License, version 2.0. +# If a copy of the Mozilla Public License, version 2.0 was not distributed with this file, +# you can obtain one at http://mozilla.org/MPL/2.0/. +# SPDX-License-Identifier: MPL-2.0 +# This file is part of Grid2Op, Grid2Op a testbed platform to model sequential decision making in power systems. + + +import warnings +import unittest + +import grid2op +from grid2op.tests.helper_path_test import * + + +class TestSetActOptionDefault(unittest.TestCase): + def _env_path(self): + return os.path.join( + PATH_DATA_TEST, "5bus_example_act_topo_set_init" + ) + + def setUp(self) -> None: + self.env_nm = self._env_path() + with warnings.catch_warnings(): + warnings.filterwarnings("ignore") + self.env = grid2op.make(self.env_nm, + test=True + ) + + def tearDown(self) -> None: + self.env.close() + return super().tearDown() + + def _aux_reset_env(self, seed, ep_id, init_state): + obs = self.env.reset(seed=seed, options={"time serie id": ep_id, + "init state": init_state}) + return obs + + def _aux_make_step(self, act=None): + if act is None: + act = self.env.action_space() + return self.env.step(act) + + def _aux_get_init_act(self): + return self.env.chronics_handler.get_init_action() + + def test_combine_ts_set_bus_opt_setbus_nopb(self): + # ts id 0 => set_bus (in the time series) + self.obs = self._aux_reset_env(seed=0, ep_id=0, init_state={"set_bus": {"lines_or_id": [(5, 2)]}}) + + # in the time series + assert self.obs.topo_vect[self.obs.line_or_pos_topo_vect[1]] == 2 + assert self.obs.topo_vect[self.obs.load_pos_topo_vect[0]] == 2 + # in the action + assert self.obs.topo_vect[self.obs.line_or_pos_topo_vect[5]] == 2 + + def test_combine_ts_set_bus_opt_setbus_collision(self): + # ts id 0 => set_bus (in the time series) + self.obs = self._aux_reset_env(seed=0, ep_id=0, init_state={"set_bus": {"lines_or_id": [(1, 1)], + "loads_id": [(0, 1)]}}) + + # in the option (totally erase the time series) + assert self.obs.topo_vect[self.obs.line_or_pos_topo_vect[1]] == 1 + assert self.obs.topo_vect[self.obs.load_pos_topo_vect[0]] == 1 + + def test_combine_ts_set_bus_opt_setstat_nopb(self): + # ts id 0 => set_bus (in the time series) + self.obs = self._aux_reset_env(seed=0, ep_id=0, + init_state={"set_line_status": [(5, -1)]}) + + # in the time series + assert self.obs.topo_vect[self.obs.line_or_pos_topo_vect[1]] == 2 + assert self.obs.topo_vect[self.obs.load_pos_topo_vect[0]] == 2 + # in the action + assert self.obs.topo_vect[self.obs.line_or_pos_topo_vect[5]] == -1 + + def test_combine_ts_set_bus_opt_setstat_collision(self): + # ts id 0 => set_bus (in the time series) + self.obs = self._aux_reset_env(seed=0, ep_id=0, + init_state={"set_bus": {"loads_id": [(0, 1)]}, + "set_line_status": [(1, -1)]}) + # in the act + assert self.obs.topo_vect[self.obs.line_or_pos_topo_vect[1]] == -1 + assert self.obs.topo_vect[self.obs.line_ex_pos_topo_vect[1]] == -1 + assert not self.obs.line_status[1] + # in the time series + assert self.obs.topo_vect[self.obs.load_pos_topo_vect[0]] == 1 + + def test_combine_ts_set_status_opt_setbus_nopb(self): + # ts id 1 => set_status + self.obs = self._aux_reset_env(seed=0, ep_id=1, init_state={"set_bus": {"lines_or_id": [(5, 2)]}}) + + # in the time series + assert self.obs.topo_vect[self.obs.line_or_pos_topo_vect[1]] == -1 + assert self.obs.topo_vect[self.obs.line_ex_pos_topo_vect[1]] == -1 + assert not self.obs.line_status[1] + # in the action + assert self.obs.topo_vect[self.obs.line_or_pos_topo_vect[5]] == 2 + + def test_combine_ts_set_status_opt_setbus_collision(self): + # ts id 1 => set_status + self.obs = self._aux_reset_env(seed=0, ep_id=1, init_state={"set_bus": {"lines_or_id": [(1, 1)]}}) + # in the time series (erased by the action, or side) + assert self.obs.topo_vect[self.obs.line_or_pos_topo_vect[1]] == 1 + assert self.obs.topo_vect[self.obs.line_ex_pos_topo_vect[1]] == 1 + assert self.obs.line_status[1] + + # ts id 1 => set_status + self.obs = self._aux_reset_env(seed=0, ep_id=1, init_state={"set_bus": {"lines_ex_id": [(1, 2)]}}) + # in the time series (erased by the action, ex side) + assert self.obs.topo_vect[self.obs.line_or_pos_topo_vect[1]] == 1 + assert self.obs.topo_vect[self.obs.line_ex_pos_topo_vect[1]] == 2 + assert self.obs.line_status[1] + + def test_combine_ts_set_status_opt_setstat_nopb(self): + # ts id 1 => set_status + self.obs = self._aux_reset_env(seed=0, ep_id=1, init_state={"set_line_status": [(5, -1)]}) + + # in the time series + assert self.obs.topo_vect[self.obs.line_or_pos_topo_vect[1]] == -1 + assert self.obs.topo_vect[self.obs.line_ex_pos_topo_vect[1]] == -1 + assert not self.obs.line_status[1] + # in the action + assert self.obs.topo_vect[self.obs.line_or_pos_topo_vect[5]] == -1 + assert self.obs.topo_vect[self.obs.line_ex_pos_topo_vect[5]] == -1 + assert not self.obs.line_status[5] + + def test_combine_ts_set_status_opt_setstat_nopb(self): + # ts id 1 => set_status + self.obs = self._aux_reset_env(seed=0, ep_id=1, init_state={"set_line_status": [(1, 1)]}) + + # in the time series (bus overriden by the action) + assert self.obs.topo_vect[self.obs.line_or_pos_topo_vect[1]] == 1 + assert self.obs.topo_vect[self.obs.line_ex_pos_topo_vect[1]] == 1 + assert self.obs.line_status[1] + return self.env.chronics_handler.get_init_action() + + # TODO none of the "ignore" tests are coded + def test_ignore_ts_set_bus_opt_setbus_nopb(self): + # ts id 0 => set_bus (in the time series) + self.obs = self._aux_reset_env(seed=0, ep_id=0, init_state={"set_bus": {"lines_or_id": [(5, 2)]}, "method": "ignore"}) + + # in the time series + assert self.obs.topo_vect[self.obs.line_or_pos_topo_vect[1]] == 1 + assert self.obs.topo_vect[self.obs.load_pos_topo_vect[0]] == 1 + # in the action + assert self.obs.topo_vect[self.obs.line_or_pos_topo_vect[5]] == 2 + + def test_ignore_ts_set_bus_opt_setbus_collision(self): + # ts id 0 => set_bus (in the time series) + self.obs = self._aux_reset_env(seed=0, ep_id=0, init_state={"set_bus": {"lines_or_id": [(1, 1)], + "loads_id": [(0, 1)]}, + "method": "ignore"}) + + # in the option (totally erase the time series) + assert self.obs.topo_vect[self.obs.line_or_pos_topo_vect[1]] == 1 + assert self.obs.topo_vect[self.obs.load_pos_topo_vect[0]] == 1 + + def test_ignore_ts_set_bus_opt_setstat_nopb(self): + # ts id 0 => set_bus (in the time series) + self.obs = self._aux_reset_env(seed=0, ep_id=0, + init_state={"set_line_status": [(5, -1)], + "method": "ignore"}) + + # in the time series + assert self.obs.topo_vect[self.obs.line_or_pos_topo_vect[1]] == 2 + assert self.obs.topo_vect[self.obs.load_pos_topo_vect[0]] == 2 + # in the action + assert self.obs.topo_vect[self.obs.line_or_pos_topo_vect[5]] == -1 + + def test_ignore_ts_set_bus_opt_setstat_collision(self): + # ts id 0 => set_bus (in the time series) + self.obs = self._aux_reset_env(seed=0, ep_id=0, + init_state={"set_bus": {"loads_id": [(0, 1)]}, + "set_line_status": [(1, -1)], + "method": "ignore"}) + # in the act + assert self.obs.topo_vect[self.obs.line_or_pos_topo_vect[1]] == -1 + assert self.obs.topo_vect[self.obs.line_ex_pos_topo_vect[1]] == -1 + assert not self.obs.line_status[1] + # in the time series + assert self.obs.topo_vect[self.obs.load_pos_topo_vect[0]] == 1 + + def test_ignore_ts_set_status_opt_setbus_nopb(self): + # ts id 1 => set_status + self.obs = self._aux_reset_env(seed=0, ep_id=1, init_state={"set_bus": {"lines_or_id": [(5, 2)]}, + "method": "ignore"}) + + # in the time series + assert self.obs.topo_vect[self.obs.line_or_pos_topo_vect[1]] == -1 + assert self.obs.topo_vect[self.obs.line_ex_pos_topo_vect[1]] == -1 + assert not self.obs.line_status[1] + # in the action + assert self.obs.topo_vect[self.obs.line_or_pos_topo_vect[5]] == 2 + + def test_ignore_ts_set_status_opt_setbus_collision(self): + # ts id 1 => set_status + self.obs = self._aux_reset_env(seed=0, ep_id=1, init_state={"set_bus": {"lines_or_id": [(1, 1)]}, + "method": "ignore"}) + # in the time series (erased by the action, or side) + assert self.obs.topo_vect[self.obs.line_or_pos_topo_vect[1]] == 1 + assert self.obs.topo_vect[self.obs.line_ex_pos_topo_vect[1]] == 1 + assert self.obs.line_status[1] + + # ts id 1 => set_status + self.obs = self._aux_reset_env(seed=0, ep_id=1, init_state={"set_bus": {"lines_ex_id": [(1, 2)]}, + "method": "ignore"}) + # in the time series (erased by the action, ex side) + assert self.obs.topo_vect[self.obs.line_or_pos_topo_vect[1]] == 1 + assert self.obs.topo_vect[self.obs.line_ex_pos_topo_vect[1]] == 2 + assert self.obs.line_status[1] + + def test_ignore_ts_set_status_opt_setstat_nopb(self): + # ts id 1 => set_status + self.obs = self._aux_reset_env(seed=0, ep_id=1, init_state={"set_line_status": [(5, -1)], + "method": "ignore"}) + + # in the time series + assert self.obs.topo_vect[self.obs.line_or_pos_topo_vect[1]] == -1 + assert self.obs.topo_vect[self.obs.line_ex_pos_topo_vect[1]] == -1 + assert not self.obs.line_status[1] + # in the action + assert self.obs.topo_vect[self.obs.line_or_pos_topo_vect[5]] == -1 + assert self.obs.topo_vect[self.obs.line_ex_pos_topo_vect[5]] == -1 + assert not self.obs.line_status[5] + + def test_ignore_ts_set_status_opt_setstat_nopb(self): + # ts id 1 => set_status + self.obs = self._aux_reset_env(seed=0, ep_id=1, init_state={"set_line_status": [(1, 1)], + "method": "ignore"}) + + # in the time series (bus overriden by the action) + assert self.obs.topo_vect[self.obs.line_or_pos_topo_vect[1]] == 1 + assert self.obs.topo_vect[self.obs.line_ex_pos_topo_vect[1]] == 1 + assert self.obs.line_status[1] diff --git a/grid2op/typing_variables.py b/grid2op/typing_variables.py index aa5c55c4d..a438a8224 100644 --- a/grid2op/typing_variables.py +++ b/grid2op/typing_variables.py @@ -25,4 +25,4 @@ Any] #: type hints for the "options" flag of reset function -RESET_OPTIONS_TYPING = Union[Dict[Union[str, Literal["time serie id"]], Union[int, str]], None] +RESET_OPTIONS_TYPING = Union[Dict[Union[Literal["time serie id", "init state"], str], Union[int, str]], None] From e869ab0d97057ce9ef3d8e41b7ea9a75ed0121e0 Mon Sep 17 00:00:00 2001 From: DONNOT Benjamin Date: Fri, 3 May 2024 09:21:14 +0200 Subject: [PATCH 04/11] add feature to set the intial state in 'reset' and fix broken tests --- .circleci/config.yml | 2 +- grid2op/Environment/environment.py | 28 ++++++++++++++---------- grid2op/tests/test_CompactEpisodeData.py | 4 +++- grid2op/typing_variables.py | 4 +++- 4 files changed, 23 insertions(+), 15 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index c912c12fd..e8c4d2eab 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -164,7 +164,7 @@ jobs: grid2op.testinstall legacy_lightsim: - executor: python38 + executor: python310 resource_class: small steps: - checkout diff --git a/grid2op/Environment/environment.py b/grid2op/Environment/environment.py index c296daa8f..ef1d27493 100644 --- a/grid2op/Environment/environment.py +++ b/grid2op/Environment/environment.py @@ -1006,6 +1006,22 @@ def reset(self, obs.line_status[0] is False """ + # process the "options" kwargs + # (if there is an init state then I need to process it to remove the + # some keys) + method = "combine" + act_as_dict = None + if options is not None and "init state" in options: + act_as_dict = options["init state"] + if "method" in act_as_dict: + method = act_as_dict["method"] + del act_as_dict["method"] + init_state : BaseAction = self._helper_action_env(act_as_dict) + ambiguous, except_tmp = init_state.is_ambiguous() + if ambiguous: + raise Grid2OpException("You provided an invalid (ambiguous) action to set the 'init state'") from except_tmp + init_state.remove_change() + super().reset(seed=seed, options=options) self.chronics_handler.next_chronics() @@ -1020,18 +1036,6 @@ def reset(self, self._reset_maintenance() self._reset_redispatching() self._reset_vectors_and_timings() # it need to be done BEFORE to prevent cascading failure when there has been - method = "combine" - act_as_dict = None - if "init state" in options: - act_as_dict = options["init state"] - if "method" in act_as_dict: - method = act_as_dict["method"] - del act_as_dict["method"] - init_state : BaseAction = self._helper_action_env(act_as_dict) - ambiguous, except_tmp = init_state.is_ambiguous() - if ambiguous: - raise Grid2OpException("You provided an invalid (ambiguous) action to set the 'init state'") from except_tmp - init_state.remove_change() self.reset_grid(act_as_dict, method) if self.viewer_fig is not None: diff --git a/grid2op/tests/test_CompactEpisodeData.py b/grid2op/tests/test_CompactEpisodeData.py index d37286c75..5fcdeeeae 100644 --- a/grid2op/tests/test_CompactEpisodeData.py +++ b/grid2op/tests/test_CompactEpisodeData.py @@ -144,6 +144,7 @@ def act(self, observation, reward, done=False): def test_one_episode_with_saving(self): f = tempfile.mkdtemp() ( + ep_id, episode_name, cum_reward, timestep, @@ -177,7 +178,7 @@ def test_collection_wrapper_after_run(self): agentClass=OneChange, use_compact_episode_data=True, ) - _, cum_reward, timestep, max_ts, episode_data = runner.run_one_episode( + ep_id, ep_name, cum_reward, timestep, max_ts, episode_data = runner.run_one_episode( max_iter=self.max_iter, detailed_output=True ) # Check that the type of first action is set bus @@ -187,6 +188,7 @@ def test_len(self): """test i can use the function "len" of the episode data""" f = tempfile.mkdtemp() ( + ep_id, episode_name, cum_reward, timestep, diff --git a/grid2op/typing_variables.py b/grid2op/typing_variables.py index a438a8224..3fa3f1541 100644 --- a/grid2op/typing_variables.py +++ b/grid2op/typing_variables.py @@ -25,4 +25,6 @@ Any] #: type hints for the "options" flag of reset function -RESET_OPTIONS_TYPING = Union[Dict[Union[Literal["time serie id", "init state"], str], Union[int, str]], None] +RESET_OPTIONS_TYPING = Union[Dict[Literal["time serie id", "init state"], str], + Dict[Union[int, str]], + None] From ff02fbe459c8b6ea58accf6769d19f272d1fd833 Mon Sep 17 00:00:00 2001 From: DONNOT Benjamin Date: Fri, 3 May 2024 09:39:49 +0200 Subject: [PATCH 05/11] fix tests - wrong typing variables defined --- .github/workflows/main.yml | 4 ++-- grid2op/Action/actionSpace.py | 26 ++++++++++---------------- grid2op/Action/baseAction.py | 6 +++++- grid2op/typing_variables.py | 20 ++++++++++++++++++-- 4 files changed, 35 insertions(+), 21 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b6815131a..a41c23e11 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -64,7 +64,7 @@ jobs: - name: Install wheel run: | - pip3 install dist/*.whl --user + pip3 install dist/*.whl pip freeze - name: Check package can be imported @@ -72,7 +72,7 @@ jobs: python3 -c "import grid2op" python3 -c "from grid2op import *" python3 -c "from grid2op.Action._backendAction import _BackendAction" - + - name: Upload wheel uses: actions/upload-artifact@v2 with: diff --git a/grid2op/Action/actionSpace.py b/grid2op/Action/actionSpace.py index 63e68614c..031756844 100644 --- a/grid2op/Action/actionSpace.py +++ b/grid2op/Action/actionSpace.py @@ -11,6 +11,7 @@ from typing import Dict, List, Any, Literal import grid2op +from grid2op.typing_variables import DICT_ACT_TYPING from grid2op.Action.baseAction import BaseAction from grid2op.Action.serializableActionSpace import SerializableActionSpace @@ -75,22 +76,9 @@ def __init__( def __call__( self, - dict_: Dict[Literal["injection", - "hazards", - "maintenance", - "set_line_status", - "change_line_status", - "set_bus", - "change_bus", - "redispatch", - "set_storage", - "curtail", - "raise_alarm", - "raise_alert"], Any] = None, + dict_: DICT_ACT_TYPING = None, check_legal: bool = False, - env: "grid2op.Environment.BaseEnv" = None, - *, - injection=None, + env: "grid2op.Environment.BaseEnv" = None ) -> BaseAction: """ This utility allows you to build a valid action, with the proper sizes if you provide it with a valid @@ -133,9 +121,15 @@ def __call__( An action that is valid and corresponds to what the agent want to do with the formalism defined in see :func:`Action.udpate`. + Notes + ----- + + This function is not in the "SerializableActionSpace" because the + "legal_action" is not serialized. TODO ? + """ # build the action - res = self.actionClass() + res : BaseAction = self.actionClass() # update the action res.update(dict_) diff --git a/grid2op/Action/baseAction.py b/grid2op/Action/baseAction.py index ac34da73e..52d4df015 100644 --- a/grid2op/Action/baseAction.py +++ b/grid2op/Action/baseAction.py @@ -10,6 +10,8 @@ import numpy as np import warnings from typing import Tuple, Dict, Literal, Any, List + + try: from typing import Self except ImportError: @@ -17,6 +19,8 @@ from packaging import version +import grid2op +from grid2op.typing_variables import DICT_ACT_TYPING from grid2op.dtypes import dt_int, dt_bool, dt_float from grid2op.Exceptions import * from grid2op.Space import GridObjects @@ -2126,7 +2130,7 @@ def _reset_vect(self): self._subs_impacted = None self._lines_impacted = None - def update(self, dict_): + def update(self, dict_: DICT_ACT_TYPING): """ Update the action with a comprehensible format specified by a dictionary. diff --git a/grid2op/typing_variables.py b/grid2op/typing_variables.py index 3fa3f1541..e350e7d0f 100644 --- a/grid2op/typing_variables.py +++ b/grid2op/typing_variables.py @@ -24,7 +24,23 @@ "time_series_id"], Any] +#: Dict representing an action +DICT_ACT_TYPING = Dict[Literal["injection", + "hazards", + "maintenance", + "set_line_status", + "change_line_status", + "set_bus", + "change_bus", + "redispatch", + "set_storage", + "curtail", + "raise_alarm", + "raise_alert"], + Any] +# TODO improve that (especially the Any part) + #: type hints for the "options" flag of reset function -RESET_OPTIONS_TYPING = Union[Dict[Literal["time serie id", "init state"], str], - Dict[Union[int, str]], +RESET_OPTIONS_TYPING = Union[Dict[Literal["time serie id", "init state"], + Union[int, DICT_ACT_TYPING]], None] From 4a6895718311b7a35b49f2a24852857e10b35725 Mon Sep 17 00:00:00 2001 From: DONNOT Benjamin Date: Fri, 3 May 2024 10:09:25 +0200 Subject: [PATCH 06/11] fixing yet again some broken tests --- .circleci/config.yml | 2 +- grid2op/Environment/baseMultiProcessEnv.py | 4 +++- grid2op/Environment/environment.py | 14 +++++++++++--- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index e8c4d2eab..d5ebb5d59 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -164,7 +164,7 @@ jobs: grid2op.testinstall legacy_lightsim: - executor: python310 + executor: python38 # needs to be 38: whl of lightsim were not released for 3.10 at the time resource_class: small steps: - checkout diff --git a/grid2op/Environment/baseMultiProcessEnv.py b/grid2op/Environment/baseMultiProcessEnv.py index 22f9f182c..0f76ca9d9 100644 --- a/grid2op/Environment/baseMultiProcessEnv.py +++ b/grid2op/Environment/baseMultiProcessEnv.py @@ -88,6 +88,8 @@ def init_env(self): self.space_prng = np.random.RandomState() self.space_prng.seed(seed=self.seed_used) self.backend = self.env_params["_raw_backend_class"](**self.env_params["_backend_kwargs"]) + del self.env_params["_backend_kwargs"] + with warnings.catch_warnings(): # warnings have bee already sent in the main process, no need to resend them warnings.filterwarnings("ignore") @@ -289,7 +291,7 @@ def __init__(self, envs, obs_as_class=True, return_info=True, logger=None): max_int = np.iinfo(dt_int).max _remotes, _work_remotes = zip(*[Pipe() for _ in range(self.nb_env)]) - env_params = [sub_env.get_kwargs(with_backend=False) for sub_env in envs] + env_params = [sub_env.get_kwargs(with_backend=False, with_backend_kwargs=True) for sub_env in envs] self._ps = [ RemoteEnv( env_params=env_, diff --git a/grid2op/Environment/environment.py b/grid2op/Environment/environment.py index ef1d27493..c5c1b9f34 100644 --- a/grid2op/Environment/environment.py +++ b/grid2op/Environment/environment.py @@ -1156,7 +1156,10 @@ def copy(self) -> "Environment": self._custom_deepcopy_for_copy(res) return res - def get_kwargs(self, with_backend=True, with_chronics_handler=True): + def get_kwargs(self, + with_backend=True, + with_chronics_handler=True, + with_backend_kwargs=False): """ This function allows to make another Environment with the same parameters as the one that have been used to make this one. @@ -1206,8 +1209,6 @@ def get_kwargs(self, with_backend=True, with_chronics_handler=True): "environment, the backend cannot be copied.") res["backend"] = self.backend.copy() res["backend"]._is_loaded = False # i can reload a copy of an environment - else: - res["_backend_kwargs"] = self.backend._my_kwargs res["parameters"] = copy.deepcopy(self._parameters) res["names_chronics_to_backend"] = copy.deepcopy( @@ -1223,7 +1224,14 @@ def get_kwargs(self, with_backend=True, with_chronics_handler=True): res["voltagecontrolerClass"] = self._voltagecontrolerClass res["other_rewards"] = {k: v.rewardClass for k, v in self.other_rewards.items()} res["name"] = self.name + res["_raw_backend_class"] = self._raw_backend_class + if with_backend_kwargs: + # used for multi processing, to pass exactly the + # right things when building the backends + # in each sub process + res["_backend_kwargs"] = self.backend._my_kwargs + res["with_forecast"] = self.with_forecast res["opponent_space_type"] = self._opponent_space_type From 738e5b47d0fc1cb1974a2da99395fdab6781d69a Mon Sep 17 00:00:00 2001 From: DONNOT Benjamin Date: Fri, 3 May 2024 12:06:05 +0200 Subject: [PATCH 07/11] adding some tests for the new feature 'init state' --- grid2op/Action/baseAction.py | 26 ++++++++- grid2op/Agent/oneChangeThenNothing.py | 27 +++++++++ grid2op/Backend/pandaPowerBackend.py | 30 +++++----- grid2op/Environment/baseEnv.py | 13 +++-- grid2op/Environment/environment.py | 1 + grid2op/tests/test_action_set_orig_state.py | 58 ++++++++++++++++++- .../test_action_set_orig_state_options.py | 37 +++++++----- grid2op/typing_variables.py | 11 ++-- 8 files changed, 163 insertions(+), 40 deletions(-) diff --git a/grid2op/Action/baseAction.py b/grid2op/Action/baseAction.py index 52d4df015..32650bd43 100644 --- a/grid2op/Action/baseAction.py +++ b/grid2op/Action/baseAction.py @@ -2099,11 +2099,31 @@ def _digest_redispatching(self, dict_): def _digest_storage(self, dict_): if "set_storage" in dict_: - self.storage_p = dict_["set_storage"] - + try: + self.storage_p = dict_["set_storage"] + except IllegalAction as exc_: + cls = type(self) + # only raise the error if I am not in compat mode + if cls.glop_version == grid2op.__version__: + raise exc_ + else: + # TODO be more specific on the version + warnings.warn(f"Ignored error on storage units, because " + f"you are in a backward compatibility mode.") + def _digest_curtailment(self, dict_): if "curtail" in dict_: - self.curtail = dict_["curtail"] + try: + self.curtail = dict_["curtail"] + except IllegalAction as exc_: + cls = type(self) + # only raise the error if I am not in compat mode + if cls.glop_version == grid2op.__version__: + raise exc_ + else: + # TODO be more specific on the version + warnings.warn(f"Ignored error on curtailment, because " + f"you are in a backward compatibility mode.") def _digest_alarm(self, dict_): """ diff --git a/grid2op/Agent/oneChangeThenNothing.py b/grid2op/Agent/oneChangeThenNothing.py index 49f8e6df8..c93b2e84e 100644 --- a/grid2op/Agent/oneChangeThenNothing.py +++ b/grid2op/Agent/oneChangeThenNothing.py @@ -29,6 +29,11 @@ class OneChangeThenNothing(BaseAgent): .. code-block:: python + # This class has been deprecated, please use the env.reset() + # with proper options instead + + + DEPRECATED ! import grid2op from grid2op.Agent import OneChangeThenNothing acts_dict_ = [{}, {"set_line_status": [(0,-1)]}] # list of dictionaries. Each dictionary @@ -44,12 +49,34 @@ class OneChangeThenNothing(BaseAgent): # run 2 episode with it res_2 = runner.run(nb_episode=2) + Notes: + ------ + + After grid2op 1.10.2, this class has been deprecated. A cleaner alternative + to use it is to set the initial state of grid when calling `env.reset` like this: + + .. code-block:: python + + import grid2op + + env = grid2op.make("l2rpn_case14_sandbox") # create an environment + dict_act_json = ... # dict representing an action + obs = env.reset(options={"init state": dict_act_json}) + + This way of doing offers: + + - more flexibility: rules are not checked + - more flexibility: any type of actions acting on anything can be performed + (even if the action would be illegal for the agent) + - less trouble: cooldown are not affected + """ my_dict = {} def __init__(self, action_space): BaseAgent.__init__(self, action_space) + warnings.warn(f"Deprecated class, please use `env.reset(options={'init state': {self._get_dict_act().to_json()}})` instead") self.has_changed = False self.do_nothing_action = self.action_space({}) diff --git a/grid2op/Backend/pandaPowerBackend.py b/grid2op/Backend/pandaPowerBackend.py index db7acf1ac..d86088d5a 100644 --- a/grid2op/Backend/pandaPowerBackend.py +++ b/grid2op/Backend/pandaPowerBackend.py @@ -553,8 +553,11 @@ def load_grid(self, self.name_sub = ["sub_{}".format(i) for i, row in self._grid.bus.iterrows()] self.name_sub = np.array(self.name_sub) - self.n_shunt = self._grid.shunt.shape[0] - + if type(self).shunts_data_available: + self.n_shunt = self._grid.shunt.shape[0] + else: + self.n_shunt = 0 + # "hack" to handle topological changes, for now only 2 buses per substation add_topo = copy.deepcopy(self._grid.bus) # TODO n_busbar: what if non contiguous indexing ??? @@ -656,17 +659,18 @@ def _init_private_attrs(self) -> None: self.dim_topo = self.sub_info.sum() # shunts data - self.shunt_to_subid = np.zeros(self.n_shunt, dtype=dt_int) - 1 - name_shunt = [] - # TODO read name from the grid if provided - for i, (_, row) in enumerate(self._grid.shunt.iterrows()): - bus = int(row["bus"]) - name_shunt.append("shunt_{bus}_{index_shunt}".format(**row, index_shunt=i)) - self.shunt_to_subid[i] = bus - self.name_shunt = np.array(name_shunt).astype(str) - self._sh_vnkv = self._grid.bus["vn_kv"][self.shunt_to_subid].values.astype( - dt_float - ) + if type(self).shunts_data_available: + self.shunt_to_subid = np.zeros(self.n_shunt, dtype=dt_int) - 1 + name_shunt = [] + # TODO read name from the grid if provided + for i, (_, row) in enumerate(self._grid.shunt.iterrows()): + bus = int(row["bus"]) + name_shunt.append("shunt_{bus}_{index_shunt}".format(**row, index_shunt=i)) + self.shunt_to_subid[i] = bus + self.name_shunt = np.array(name_shunt).astype(str) + self._sh_vnkv = self._grid.bus["vn_kv"][self.shunt_to_subid].values.astype( + dt_float + ) self._compute_pos_big_topo() diff --git a/grid2op/Environment/baseEnv.py b/grid2op/Environment/baseEnv.py index b62d31c10..8dca86a37 100644 --- a/grid2op/Environment/baseEnv.py +++ b/grid2op/Environment/baseEnv.py @@ -1925,6 +1925,13 @@ def _make_redisp(self, already_modified_gen, new_p): def _compute_dispatch_vect(self, already_modified_gen, new_p): except_ = None + + # handle the case where there are storage or redispatching + # action or curtailment action on the "init state" + # of the grid + if self.nb_time_step == 0: + self._gen_activeprod_t_redisp[:] = new_p + # first i define the participating generators # these are the generators that will be adjusted for redispatching gen_participating = ( @@ -2893,7 +2900,7 @@ def _aux_apply_redisp(self, action, new_p, new_p_th, gen_curtailed, except_): is_illegal_redisp = True except_.append(except_tmp) - if self.n_storage > 0: + if type(self).n_storage > 0: # TODO curtailment: cancel it here too ! self._storage_current_charge[:] = self._storage_previous_charge self._amount_storage -= self._amount_storage_prev @@ -2915,7 +2922,6 @@ def _aux_apply_redisp(self, action, new_p, new_p_th, gen_curtailed, except_): self._storage_power_prev[:] = self._storage_power # case where the action modifies load (TODO maybe make a different env for that...) self._aux_handle_act_inj(action) - valid_disp, except_tmp = self._make_redisp(already_modified_gen, new_p) if not valid_disp or except_tmp is not None: @@ -3161,11 +3167,10 @@ def step(self, action: BaseAction) -> Tuple[BaseObservation, the simulation of the "cascading failures". - "rewards": dictionary of all "other_rewards" provided when the env was built. - "time_series_id": id of the time series used (if any, similar to a call to `env.chronics_handler.get_id()`) - Examples --------- - As any openAI gym environment, this is used like: + This is used like: .. code-block:: python diff --git a/grid2op/Environment/environment.py b/grid2op/Environment/environment.py index c5c1b9f34..9a428a2b1 100644 --- a/grid2op/Environment/environment.py +++ b/grid2op/Environment/environment.py @@ -841,6 +841,7 @@ def reset_grid(self, init_state_dict=None, method="combine"): if init_state_dict is not None: init_act_opt : BaseAction = self._helper_action_env(init_state_dict) + init_act_opt.remove_change() if method == "combine": init_action._add_act_and_remove_line_status_only_set(init_act_opt) elif method == "ignore": diff --git a/grid2op/tests/test_action_set_orig_state.py b/grid2op/tests/test_action_set_orig_state.py index 63a8aa1fa..ba10b8bfc 100644 --- a/grid2op/tests/test_action_set_orig_state.py +++ b/grid2op/tests/test_action_set_orig_state.py @@ -7,7 +7,9 @@ # This file is part of Grid2Op, Grid2Op a testbed platform to model sequential decision making in power systems. +from os import PathLike import tempfile +from typing import Union import numpy as np import warnings import unittest @@ -39,8 +41,8 @@ # TODO test "change" is deactivated -# TODO test with and without shunt # TODO test grid2Op compat mode (storage units) +# TODO test with redispatching and curtailment actions # TODO test with "names_orig_to_backend" @@ -457,6 +459,60 @@ def test_right_init_act(self): raise RuntimeError("Test is coded correctly") +class _PPNoShunt_Test(PandaPowerBackend): + shunts_data_available = False + +class TestSetSuntState(unittest.TestCase): + def _env_path(self): + return os.path.join( + PATH_DATA_TEST, "educ_case14_storage_init_state" + ) + + def _get_backend(self): + return PandaPowerBackend() + + def setUp(self) -> None: + self.env_nm = self._env_path() + with warnings.catch_warnings(): + warnings.filterwarnings("ignore") + self.env = grid2op.make(self.env_nm, + test=True + ) + self.env_noshunt = grid2op.make(self.env_nm, + test=True, + backend=_PPNoShunt_Test() + ) + self.env_nostor = grid2op.make(self.env_nm, + test=True, + _compat_glop_version="neurips_2020_compat" + ) + assert type(self.env_noshunt).shunts_data_available is False + assert type(self.env_nostor).n_storage == 0 + assert type(self.env).n_storage == 2 + + def test_set_shunt_state(self): + """test that the action that acts on the shunt works (when shunt are supported) + or has no impact if the backend does not support shunts""" + obs_shunt = self.env.reset(seed=0, options={"time serie id": 0}) + obs_noshunt = self.env_noshunt.reset(seed=0, options={"time serie id": 0}) + assert obs_shunt._shunt_q[0] == 0. # the action put the shunt to 0. + # in the backend with no shunt, the shunt is active and generator + # does not produce same q + assert abs(obs_shunt.gen_q[4] - obs_noshunt.gen_q[4]) > 5. + + def test_set_storage_state(self): + obs_stor = self.env.reset(seed=0, options={"time serie id": 1}) + obs_nostor = self.env_nostor.reset(seed=0, options={"time serie id": 1}) + slack_id = -1 + # the storage action is taken into account + assert obs_stor.storage_power[0] == 5. # the action set this + + # the original grid (withtout storage) + # and the grid with storage action have the same "gen_p" + # if I remove the impact of the storage unit + deltagen_p_th = ((obs_stor.gen_p - obs_stor.actual_dispatch) - obs_nostor.gen_p) + assert (np.abs(deltagen_p_th[:slack_id]) <= 1e-6).all() + if __name__ == "__main__": unittest.main() diff --git a/grid2op/tests/test_action_set_orig_state_options.py b/grid2op/tests/test_action_set_orig_state_options.py index f84fcd76a..eabcb502e 100644 --- a/grid2op/tests/test_action_set_orig_state_options.py +++ b/grid2op/tests/test_action_set_orig_state_options.py @@ -14,6 +14,10 @@ from grid2op.tests.helper_path_test import * +# TODO test with redispatching, curtailment or storage +# TODO in the runner too + + class TestSetActOptionDefault(unittest.TestCase): def _env_path(self): return os.path.join( @@ -126,7 +130,7 @@ def test_combine_ts_set_status_opt_setstat_nopb(self): assert self.obs.topo_vect[self.obs.line_ex_pos_topo_vect[5]] == -1 assert not self.obs.line_status[5] - def test_combine_ts_set_status_opt_setstat_nopb(self): + def test_combine_ts_set_status_opt_setstat_collision(self): # ts id 1 => set_status self.obs = self._aux_reset_env(seed=0, ep_id=1, init_state={"set_line_status": [(1, 1)]}) @@ -136,7 +140,6 @@ def test_combine_ts_set_status_opt_setstat_nopb(self): assert self.obs.line_status[1] return self.env.chronics_handler.get_init_action() - # TODO none of the "ignore" tests are coded def test_ignore_ts_set_bus_opt_setbus_nopb(self): # ts id 0 => set_bus (in the time series) self.obs = self._aux_reset_env(seed=0, ep_id=0, init_state={"set_bus": {"lines_or_id": [(5, 2)]}, "method": "ignore"}) @@ -148,6 +151,7 @@ def test_ignore_ts_set_bus_opt_setbus_nopb(self): assert self.obs.topo_vect[self.obs.line_or_pos_topo_vect[5]] == 2 def test_ignore_ts_set_bus_opt_setbus_collision(self): + # TODO not tested for method = ignore (because action here totally erased action in ts) # ts id 0 => set_bus (in the time series) self.obs = self._aux_reset_env(seed=0, ep_id=0, init_state={"set_bus": {"lines_or_id": [(1, 1)], "loads_id": [(0, 1)]}, @@ -164,10 +168,12 @@ def test_ignore_ts_set_bus_opt_setstat_nopb(self): "method": "ignore"}) # in the time series - assert self.obs.topo_vect[self.obs.line_or_pos_topo_vect[1]] == 2 - assert self.obs.topo_vect[self.obs.load_pos_topo_vect[0]] == 2 + assert self.obs.topo_vect[self.obs.line_or_pos_topo_vect[1]] == 1 + assert self.obs.topo_vect[self.obs.load_pos_topo_vect[0]] == 1 # in the action assert self.obs.topo_vect[self.obs.line_or_pos_topo_vect[5]] == -1 + assert self.obs.topo_vect[self.obs.line_ex_pos_topo_vect[5]] == -1 + assert not self.obs.line_status[5] def test_ignore_ts_set_bus_opt_setstat_collision(self): # ts id 0 => set_bus (in the time series) @@ -179,7 +185,7 @@ def test_ignore_ts_set_bus_opt_setstat_collision(self): assert self.obs.topo_vect[self.obs.line_or_pos_topo_vect[1]] == -1 assert self.obs.topo_vect[self.obs.line_ex_pos_topo_vect[1]] == -1 assert not self.obs.line_status[1] - # in the time series + # in the time series (ignored) assert self.obs.topo_vect[self.obs.load_pos_topo_vect[0]] == 1 def test_ignore_ts_set_status_opt_setbus_nopb(self): @@ -187,14 +193,15 @@ def test_ignore_ts_set_status_opt_setbus_nopb(self): self.obs = self._aux_reset_env(seed=0, ep_id=1, init_state={"set_bus": {"lines_or_id": [(5, 2)]}, "method": "ignore"}) - # in the time series - assert self.obs.topo_vect[self.obs.line_or_pos_topo_vect[1]] == -1 - assert self.obs.topo_vect[self.obs.line_ex_pos_topo_vect[1]] == -1 - assert not self.obs.line_status[1] + # in the time series (ignored) + assert self.obs.topo_vect[self.obs.line_or_pos_topo_vect[1]] == 1 + assert self.obs.topo_vect[self.obs.line_ex_pos_topo_vect[1]] == 1 + assert self.obs.line_status[1] # in the action assert self.obs.topo_vect[self.obs.line_or_pos_topo_vect[5]] == 2 def test_ignore_ts_set_status_opt_setbus_collision(self): + # TODO not tested for method = ignore (because action here totally erased action in ts) # ts id 1 => set_status self.obs = self._aux_reset_env(seed=0, ep_id=1, init_state={"set_bus": {"lines_or_id": [(1, 1)]}, "method": "ignore"}) @@ -216,16 +223,18 @@ def test_ignore_ts_set_status_opt_setstat_nopb(self): self.obs = self._aux_reset_env(seed=0, ep_id=1, init_state={"set_line_status": [(5, -1)], "method": "ignore"}) - # in the time series - assert self.obs.topo_vect[self.obs.line_or_pos_topo_vect[1]] == -1 - assert self.obs.topo_vect[self.obs.line_ex_pos_topo_vect[1]] == -1 - assert not self.obs.line_status[1] + # in the time series (ignored) + assert self.obs.topo_vect[self.obs.line_or_pos_topo_vect[1]] == 1 + assert self.obs.topo_vect[self.obs.line_ex_pos_topo_vect[1]] == 1 + assert self.obs.line_status[1] # in the action assert self.obs.topo_vect[self.obs.line_or_pos_topo_vect[5]] == -1 assert self.obs.topo_vect[self.obs.line_ex_pos_topo_vect[5]] == -1 assert not self.obs.line_status[5] - def test_ignore_ts_set_status_opt_setstat_nopb(self): + def test_ignore_ts_set_status_opt_setstat_collision(self): + # TODO not tested for method = ignore (because action here totally erased action in ts) + # ts id 1 => set_status self.obs = self._aux_reset_env(seed=0, ep_id=1, init_state={"set_line_status": [(1, 1)], "method": "ignore"}) diff --git a/grid2op/typing_variables.py b/grid2op/typing_variables.py index e350e7d0f..2fa1f6fed 100644 --- a/grid2op/typing_variables.py +++ b/grid2op/typing_variables.py @@ -25,10 +25,7 @@ Any] #: Dict representing an action -DICT_ACT_TYPING = Dict[Literal["injection", - "hazards", - "maintenance", - "set_line_status", +DICT_ACT_TYPING = Dict[Literal["set_line_status", "change_line_status", "set_bus", "change_bus", @@ -36,7 +33,11 @@ "set_storage", "curtail", "raise_alarm", - "raise_alert"], + "raise_alert", + "injection", + "hazards", + "maintenance", + "shunt"], Any] # TODO improve that (especially the Any part) From f19374d9684e44afe90f925bbd45d16ba4260b80 Mon Sep 17 00:00:00 2001 From: DONNOT Benjamin Date: Fri, 3 May 2024 14:53:39 +0200 Subject: [PATCH 08/11] fixing broken tests, again ? --- grid2op/Action/baseAction.py | 18 ++++++++++-------- grid2op/Agent/oneChangeThenNothing.py | 3 ++- .../test_action_set_orig_state_options.py | 5 ++--- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/grid2op/Action/baseAction.py b/grid2op/Action/baseAction.py index 32650bd43..a08e21f2d 100644 --- a/grid2op/Action/baseAction.py +++ b/grid2op/Action/baseAction.py @@ -6510,21 +6510,23 @@ def _add_act_and_remove_line_status_only_set(self, other: "BaseAction"): cls = type(self) # switch off in self the element disconnected in other switched_off = other._set_line_status == -1 - switched_off |= self._set_topo_vect[cls.line_or_pos_topo_vect] == -1 - switched_off |= self._set_topo_vect[cls.line_ex_pos_topo_vect] == -1 + switched_off |= other._set_topo_vect[cls.line_or_pos_topo_vect] == -1 + switched_off |= other._set_topo_vect[cls.line_ex_pos_topo_vect] == -1 self._set_topo_vect[cls.line_or_pos_topo_vect[switched_off]] = -1 self._set_topo_vect[cls.line_ex_pos_topo_vect[switched_off]] = -1 self._set_line_status[switched_off] = -1 # switch on in self the element reconnected in other switched_on = other._set_line_status == 1 - switched_on |= self._set_topo_vect[cls.line_or_pos_topo_vect] > 0 - switched_on |= self._set_topo_vect[cls.line_ex_pos_topo_vect] > 0 - self._set_topo_vect[cls.line_or_pos_topo_vect[switched_on]] = np.maximum(other._set_topo_vect[cls.line_or_pos_topo_vect[switched_on]], - 0) - self._set_topo_vect[cls.line_ex_pos_topo_vect[switched_on]] = np.maximum(other._set_topo_vect[cls.line_ex_pos_topo_vect[switched_on]], - 0) + switched_on |= other._set_topo_vect[cls.line_or_pos_topo_vect] > 0 + switched_on |= other._set_topo_vect[cls.line_ex_pos_topo_vect] > 0 self._set_line_status[switched_on] = 1 + # "reconnect" object through topo vect + or_topo_vect = other._set_topo_vect > 0 + self._set_topo_vect[or_topo_vect] = other._set_topo_vect[or_topo_vect] + # "reconnect" object through topo vect + ex_topo_vect = other._set_topo_vect > 0 + self._set_topo_vect[or_topo_vect] = other._set_topo_vect[ex_topo_vect] if (self._set_line_status != 0).any(): self._modif_set_status = True diff --git a/grid2op/Agent/oneChangeThenNothing.py b/grid2op/Agent/oneChangeThenNothing.py index c93b2e84e..788add49d 100644 --- a/grid2op/Agent/oneChangeThenNothing.py +++ b/grid2op/Agent/oneChangeThenNothing.py @@ -6,6 +6,7 @@ # SPDX-License-Identifier: MPL-2.0 # This file is part of Grid2Op, Grid2Op a testbed platform to model sequential decision making in power systems. +import warnings from grid2op.Agent.baseAgent import BaseAgent @@ -76,7 +77,7 @@ class OneChangeThenNothing(BaseAgent): def __init__(self, action_space): BaseAgent.__init__(self, action_space) - warnings.warn(f"Deprecated class, please use `env.reset(options={'init state': {self._get_dict_act().to_json()}})` instead") + warnings.warn(f"Deprecated class, please use `env.reset(options={'init state': {env.action_space(acts_dict_[0]).to_json()}})` instead") self.has_changed = False self.do_nothing_action = self.action_space({}) diff --git a/grid2op/tests/test_action_set_orig_state_options.py b/grid2op/tests/test_action_set_orig_state_options.py index eabcb502e..bd490e008 100644 --- a/grid2op/tests/test_action_set_orig_state_options.py +++ b/grid2op/tests/test_action_set_orig_state_options.py @@ -51,13 +51,12 @@ def _aux_get_init_act(self): def test_combine_ts_set_bus_opt_setbus_nopb(self): # ts id 0 => set_bus (in the time series) - self.obs = self._aux_reset_env(seed=0, ep_id=0, init_state={"set_bus": {"lines_or_id": [(5, 2)]}}) - + self.obs = self._aux_reset_env(seed=0, ep_id=0, init_state={"set_bus": {"lines_or_id": [(0, 2)]}}) # in the time series assert self.obs.topo_vect[self.obs.line_or_pos_topo_vect[1]] == 2 assert self.obs.topo_vect[self.obs.load_pos_topo_vect[0]] == 2 # in the action - assert self.obs.topo_vect[self.obs.line_or_pos_topo_vect[5]] == 2 + assert self.obs.topo_vect[self.obs.line_or_pos_topo_vect[0]] == 2 def test_combine_ts_set_bus_opt_setbus_collision(self): # ts id 0 => set_bus (in the time series) From 93e204215979ed327761d82e1eb3bc95050dfd77 Mon Sep 17 00:00:00 2001 From: DONNOT Benjamin Date: Fri, 3 May 2024 15:22:25 +0200 Subject: [PATCH 09/11] fixing broken tests, again ? --- grid2op/Action/baseAction.py | 7 +- grid2op/Agent/oneChangeThenNothing.py | 3 +- .../chronics/2019-01-12/init_state.json | 4 + .../chronics/2019-01-12/load_p.csv.bz2 | Bin 0 -> 2729 bytes .../2019-01-12/load_p_forecasted.csv.bz2 | Bin 0 -> 2396 bytes .../chronics/2019-01-12/load_q.csv.bz2 | Bin 0 -> 2412 bytes .../2019-01-12/load_q_forecasted.csv.bz2 | Bin 0 -> 1987 bytes .../chronics/2019-01-12/prod_p.csv.bz2 | Bin 0 -> 1912 bytes .../2019-01-12/prod_p_forecasted.csv.bz2 | Bin 0 -> 1787 bytes .../chronics/2019-01-12/prod_v.csv.bz2 | Bin 0 -> 116 bytes .../2019-01-12/prod_v_forecasted.csv.bz2 | Bin 0 -> 116 bytes .../chronics/2019-01-12/start_datetime.info | 1 + .../chronics/2019-01-12/time_interval.info | 1 + .../chronics/2019-01-13/init_state.json | 4 + .../chronics/2019-01-13/load_p.csv.bz2 | Bin 0 -> 2645 bytes .../2019-01-13/load_p_forecasted.csv.bz2 | Bin 0 -> 2221 bytes .../chronics/2019-01-13/load_q.csv.bz2 | Bin 0 -> 2311 bytes .../2019-01-13/load_q_forecasted.csv.bz2 | Bin 0 -> 1884 bytes .../chronics/2019-01-13/prod_p.csv.bz2 | Bin 0 -> 1867 bytes .../2019-01-13/prod_p_forecasted.csv.bz2 | Bin 0 -> 1710 bytes .../chronics/2019-01-13/prod_v.csv.bz2 | Bin 0 -> 116 bytes .../2019-01-13/prod_v_forecasted.csv.bz2 | Bin 0 -> 116 bytes .../chronics/2019-01-13/start_datetime.info | 1 + .../chronics/2019-01-13/time_interval.info | 1 + .../educ_case14_storage_init_state/config.py | 40 + .../difficulty_levels.json | 58 + .../educ_case14_storage_init_state/grid.json | 1766 +++++++++++++++++ .../grid_layout.json | 58 + .../prods_charac.csv | 7 + .../storage_units_charac.csv | 3 + 30 files changed, 1948 insertions(+), 6 deletions(-) create mode 100644 grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-12/init_state.json create mode 100644 grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-12/load_p.csv.bz2 create mode 100644 grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-12/load_p_forecasted.csv.bz2 create mode 100644 grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-12/load_q.csv.bz2 create mode 100644 grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-12/load_q_forecasted.csv.bz2 create mode 100644 grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-12/prod_p.csv.bz2 create mode 100644 grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-12/prod_p_forecasted.csv.bz2 create mode 100644 grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-12/prod_v.csv.bz2 create mode 100644 grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-12/prod_v_forecasted.csv.bz2 create mode 100644 grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-12/start_datetime.info create mode 100644 grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-12/time_interval.info create mode 100644 grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-13/init_state.json create mode 100644 grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-13/load_p.csv.bz2 create mode 100644 grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-13/load_p_forecasted.csv.bz2 create mode 100644 grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-13/load_q.csv.bz2 create mode 100644 grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-13/load_q_forecasted.csv.bz2 create mode 100644 grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-13/prod_p.csv.bz2 create mode 100644 grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-13/prod_p_forecasted.csv.bz2 create mode 100644 grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-13/prod_v.csv.bz2 create mode 100644 grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-13/prod_v_forecasted.csv.bz2 create mode 100644 grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-13/start_datetime.info create mode 100644 grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-13/time_interval.info create mode 100644 grid2op/data_test/educ_case14_storage_init_state/config.py create mode 100644 grid2op/data_test/educ_case14_storage_init_state/difficulty_levels.json create mode 100644 grid2op/data_test/educ_case14_storage_init_state/grid.json create mode 100644 grid2op/data_test/educ_case14_storage_init_state/grid_layout.json create mode 100644 grid2op/data_test/educ_case14_storage_init_state/prods_charac.csv create mode 100644 grid2op/data_test/educ_case14_storage_init_state/storage_units_charac.csv diff --git a/grid2op/Action/baseAction.py b/grid2op/Action/baseAction.py index a08e21f2d..7dd8f9d90 100644 --- a/grid2op/Action/baseAction.py +++ b/grid2op/Action/baseAction.py @@ -6522,11 +6522,8 @@ def _add_act_and_remove_line_status_only_set(self, other: "BaseAction"): switched_on |= other._set_topo_vect[cls.line_ex_pos_topo_vect] > 0 self._set_line_status[switched_on] = 1 # "reconnect" object through topo vect - or_topo_vect = other._set_topo_vect > 0 - self._set_topo_vect[or_topo_vect] = other._set_topo_vect[or_topo_vect] - # "reconnect" object through topo vect - ex_topo_vect = other._set_topo_vect > 0 - self._set_topo_vect[or_topo_vect] = other._set_topo_vect[ex_topo_vect] + topo_vect = other._set_topo_vect > 0 + self._set_topo_vect[topo_vect] = other._set_topo_vect[topo_vect] if (self._set_line_status != 0).any(): self._modif_set_status = True diff --git a/grid2op/Agent/oneChangeThenNothing.py b/grid2op/Agent/oneChangeThenNothing.py index 788add49d..3b8aa2299 100644 --- a/grid2op/Agent/oneChangeThenNothing.py +++ b/grid2op/Agent/oneChangeThenNothing.py @@ -77,7 +77,8 @@ class OneChangeThenNothing(BaseAgent): def __init__(self, action_space): BaseAgent.__init__(self, action_space) - warnings.warn(f"Deprecated class, please use `env.reset(options={'init state': {env.action_space(acts_dict_[0]).to_json()}})` instead") + cls = type(self) + warnings.warn(f"Deprecated class, please use `env.reset(options={{'init state': {self.action_space(cls.my_dict).to_json()}, 'method': 'ignore' }})` instead") self.has_changed = False self.do_nothing_action = self.action_space({}) diff --git a/grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-12/init_state.json b/grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-12/init_state.json new file mode 100644 index 000000000..3b9b42ef9 --- /dev/null +++ b/grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-12/init_state.json @@ -0,0 +1,4 @@ +{ + "shunt": {"shunt_q": [[0, 0.0]]} +} + diff --git a/grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-12/load_p.csv.bz2 b/grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-12/load_p.csv.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..cb68d027506b1bad8e60a550c63e8e8e417ad1ea GIT binary patch literal 2729 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 literal 0 HcmV?d00001 diff --git a/grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-12/load_p_forecasted.csv.bz2 b/grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-12/load_p_forecasted.csv.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..19c21de8bee86689649d464db037c90b59dc0b44 GIT binary patch literal 2396 zcmV-i38VHxT4*^jL0KkKSx(&28UP&1TL1tM00DpK005)};13;{_iI!VyJu|aZL@8f zpJ5~dYDZbNuY0}EGYgwQ>X|Oy8lHiQs$yUylVpumF)%5nMkXd8lS&$yRWUFTC#s4~ z0MH^q2}*51-r33|ZXZ=Ta(XBHzlwf3zVYSph{}sDnE3Uha(RwFU=xE2>k?&4bgA7iYgPpa`Y{U=#2`Wta1R?5 zM1Yo!T5|N@AjJ5X09c(gSKiCa%kO(UkFrt;r0-z^fQ0f01_bO`4Z?4zz(|537M#~`K_d^KWGNoUG5g);uetZ%Ie7EC?ejX`$+LF@ zCyEGt^Xh<{G*CIfx;t7-h}m1&gwO?&b%-Ak^dREQHDd-02-!tLd>mMvP~zRGM~pjt z%x-g#na+Z)O-{skt2~6u4Ba_C>U%K7<3Q;Rq~TOhQa2jYu96 zJOZ_83ll55uw0#;+wRKeyk&dWT@P!Y9x}n}6TPVRVZCs)R&rFM#-s9`28NgD#6I)z zL4y&IVupl>YJ?`3A0ANnTWni-&97g6>BZ6-hzEl30l#^9djdf~K`?^IFrO@_`!?v! z4j7s@CWTsLEvU=s6M#m*ihU$4Iti$Gk!gx?gkd#Cc=EgpiNG)k14m5uT+?p5ho`1y z>$YHnHt8B)Oh>6|)3jB4$gtKogeY;5l{|&pO?JcTy&UZX@m&RwkxmOZFvX1DQT3QpV7|#4#~L2E%bo0mJY$ z!NFQ-ia|tzC`2$A0~o?UhzXo{8oCH;hCI>eDu?fBM1UuI)4fDMD4_`wfRsIiA|e2T zSTQsv+G#LD2AdGT9!7-F4PAi?L;29SvYYB+6)#N1;_o#cZ%FEkIpBK;Z;v zT{ShZDJh|Cw#W{7!#?DhM~Iaf?}Km1nF<^J4I9Ao(PrvZ2qAW428IU zX#TDlW*D?4M*nl^kbx&C%xDbSbH?0+zza_Sv*$s~iql+yuwr;H$6=UB!Rv63A)GV} zAVO7fI_ep?!imd>(P_T*RwJj8M@-x>(w2g*odNOF8qU_Ne8Nvf7NjDX*WMEYBRYxI9!@sg^zDpmlH5YcPc2 zbX*l7czE9ZZxoW(2gULj^X}#|w8C(rV`fo-S){OaQFaC{Ly1@qc=8Ht%$9(^CqeCb zYqT`)nCw^CvCi@g7w>o=Mo+Pf9}tp|PTBizK6O0sM1+^=*(Qaw(9+s@*`}tK^>S3E z;7AI<(L8D%r4MMQ64|Ro;`??i^`T@-rRm`niX41cmv$?w1qLPEirRCISh}ZtXij44 z_ZHT63j`aNV)CwOp$*%yOSNGFM zP*(Q?VrrYcEi_aTQ&a12O7z#n=(01c$|uKS9-e%i?C;rzVUys%Reing2d|J^x^h^D z4uQn^;lXP=nwH$A9dON>k2OLibD~5ouQV@n2D8-{Bx)meMpMY4MpCWk(Ts>Y#T7xp zZJxZm*{RyD9N#6nEIXJI3bwU%!>+OA%+neU{+v}e9-Lg)oii_zOf=tDGCBG26 z6Hvg#wB(Kj!w;^52PM=p5W&2TIOS1w0u)#kRFejak>l4xspqTN)E(}enXANxCP8Ea zoV)o%L*9vzw^~HeG?225k!0y1@y`K-k6;dIspt|Bk|gtxI9mvH+sCO)gDm?As5E!F zy;KK#+(C%Qi_Ei+lQbZ74T=^*te4X22^@{{E0i$H^qIFCoi3}EsgxT^bw1%s*S*7W z?oRF(!!t1S+Sjy2OS(zu-ObnBk_{CD%*o_h0 zmTsC;$wy7!8ndP3GX0|AxrVy0!o{9sU<6QZU5jHzWN|!aazi)Vei^g2E3djq z&hqyWoVo3~DC&LE;ZW?S+AdmD+CN$CeXVNy<5y<%Rqo2Dd&ym_)1gLDJ(TL!8@bs= z`!?0#Z@;XlP~NIG<4}@w{L%x`cwKJSbxfY O#oUoj6eJV3G=_jk@?`M< literal 0 HcmV?d00001 diff --git a/grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-12/load_q.csv.bz2 b/grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-12/load_q.csv.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..35d398131afc5122e48cffd2ceb6fdc0f2b119d3 GIT binary patch literal 2412 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 literal 0 HcmV?d00001 diff --git a/grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-12/prod_p_forecasted.csv.bz2 b/grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-12/prod_p_forecasted.csv.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..c793514416cc7ad3304d210c8a16df098d4bf58b GIT binary patch literal 1787 zcmV%7s-OS?2_+Om)Bz@$l_?7K;t(|>HcaGCqIO@xcN}^*h z$zAKTj#FT*FBhHWgwphS&NFV5+#+LOtYdtgOqDQ z+||o=s_2*Lv@zkC=d%qGct@azo`~Vzu^dOGX_bRKlsyL9d}Ibj7NZF$^^6?0j}I_# z?6!3-<~V~CLp`?MfMO=i#DM3oe5(!ZH{2aq_l4H8$VP^-VR#@Q(hh_j+8Qg;^HF+G zlHg*7_H<}ZiWJO&uZpPi=%*WQGkblW8x=|o4TE@Zk3|#*F(}9-Br1L%I@1d^hW2`>e48o5j1O!=-Z8nxi!~^#3U%&+}ax0`o?oI=XC+xWKfU)Df zFRt?&7|o90jos)YFQK|M%Y-gd7{XC$g}BmiV~lgB5j)=mL4UFZ_Ml$9xE zEYzr`TV`t|CQ~y~nRTQG|aP0HdKtv%!xLV%p|5IGc=Ji zBM{j#h@~isNP}XMh_x6Kp4zuY+juvKQJ6%c0Skw`<0Gae6B`grV*!n4Xu@VQA4s67 zkur>siVGVNsRBg!2#36QbA#r`CNpI08RSE21U+{`k=HR7ZElETw_ItGXuCEXbmyNU zE&BY$@{i{IQT!L@$@p@aPFt3n_al}d=_cr7Tg;T|aPFhPmP1JsODvWyla@^!29A=o z6p&pCjmjE3n$0Xt2-_)QGaX?x6w7joCIEz@5&|L`q23;N$?dz|p5I_lvik0qUQ><} zI-a}s*g}sc#Wu>cs%fi*?2d-tCx}}iLb?~z9V{8d*_P_g_TqtZYr6(@4x^K8(VI6i zCsMAhXFbG43sm;bbuIuwjeH9jS>T4>>Fba4=nWn};l3RlY!kgplqn;z`>Y z^#$dyeqNX~Xiuwmh7hjmVbSb{Hm^dOOEk8sc}nqEns+VsYr{`xIiphI6rG8uv@~$J zG|>(RAtGs}nmAm!Mz15&EowZ5K22`Am?jSsVql&VgCUWb(75JgvR7?jRjQf7vk4)U zdy|F2dLCAd=`>imMXW<}4iVuDL81>DmrS*pTsvbJ+1ppbZ*?)kD(hnH@Tw;%B5mB; dnVZS`OOk%5`bW>|52Sy^+>uTcBoh^?qX1ekR`>t_ literal 0 HcmV?d00001 diff --git a/grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-12/prod_v.csv.bz2 b/grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-12/prod_v.csv.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..79c31540fdacc2a4b4da66b1b35572beebe0e697 GIT binary patch literal 116 zcmV-)0E_=ZT4*^jL0KkKS@H-gP5=_KTL1tM00Dl8004r4FaWqiO*I+~JwgBg1u8~O zOpP~~BT^+gf;56WVhHgBZV1E?!U*N05#0(|K^cNF+!2gWrHR}T)Dg@P#1V)hrdH*n W(r%P77vcjE@pmLsg$WNJg0$e-SSMBh literal 0 HcmV?d00001 diff --git a/grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-12/prod_v_forecasted.csv.bz2 b/grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-12/prod_v_forecasted.csv.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..79c31540fdacc2a4b4da66b1b35572beebe0e697 GIT binary patch literal 116 zcmV-)0E_=ZT4*^jL0KkKS@H-gP5=_KTL1tM00Dl8004r4FaWqiO*I+~JwgBg1u8~O zOpP~~BT^+gf;56WVhHgBZV1E?!U*N05#0(|K^cNF+!2gWrHR}T)Dg@P#1V)hrdH*n W(r%P77vcjE@pmLsg$WNJg0$e-SSMBh literal 0 HcmV?d00001 diff --git a/grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-12/start_datetime.info b/grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-12/start_datetime.info new file mode 100644 index 000000000..5e520426f --- /dev/null +++ b/grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-12/start_datetime.info @@ -0,0 +1 @@ +2019-01-11 23:55 diff --git a/grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-12/time_interval.info b/grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-12/time_interval.info new file mode 100644 index 000000000..beb9b9011 --- /dev/null +++ b/grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-12/time_interval.info @@ -0,0 +1 @@ +00:05 diff --git a/grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-13/init_state.json b/grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-13/init_state.json new file mode 100644 index 000000000..1993de4f4 --- /dev/null +++ b/grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-13/init_state.json @@ -0,0 +1,4 @@ +{ + "set_storage": [[0, 5]] +} + diff --git a/grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-13/load_p.csv.bz2 b/grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-13/load_p.csv.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..488a31b2a6bc45530b0558582ef23207e2360991 GIT binary patch literal 2645 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 DhZ7Z6 literal 0 HcmV?d00001 diff --git a/grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-13/load_p_forecasted.csv.bz2 b/grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-13/load_p_forecasted.csv.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..8e341212e850a9d8610c1a7cd293d6dee6f528d3 GIT binary patch literal 2221 zcmV;e2vYY#T4*^jL0KkKS<1~5%>W$mTL1tM00DpK005)};0|8iGwa)XZH*qay=8X3 z2D*3IAZR;2pE*9fUiNZ{+30gItTf3nl~OPSkkrDeVqg@iKT$;?wE#(^l6k7CVqhXj z$WcuIM5alys+gE~50Q-e%v^U*1E6n43cXj89d&_ zb+;RL9A>*U_NZ%_)x&b-R{EwJc^`0CZR9yl2e<~AC1tmpDS>aJjJx{iyWB?&k#_Ti zKQ`fKQv)Kxat@3M0s{oGIUsTnN>rgdiSE1P_h18ZdxmMUVYaY+(~;5?R3tKI!ANlO z8+wNTFhe9mz<9`#F-aoe86fzC0)Z$UE8rg;akDCg4(#Tm=I+9@ob}vUS3<*38xX7Q zR~#7ZA;@V7bz==j#&?tI`NdV%90qjyEi-YMTT2e#}2PAf*G`r+>OasR5tj*s* z%M)!n=|u2tH!~H9`tWN?ZuehwRmU zx%AWYWmy$IZh#au)_ptTvdG&f9XHAubq8kcvqs#4BaPuWfXo^&uB*U%-q*_V`$an|QBnT&!EKOlF zj6+nRDMN{%o1Xg)=e?Ed`!=r*;m)FwVsO&5qf4&T2XNuZUwTg-g_)?zEatP|JWi;x z2T}x65ViP>H6%zy&?s6LiK-mVUHduhbDEfHX>o{IM;}epPjQsMKf)Yg0NVoFrS~9H0t0}dm zg}qbQvFyEzS(6pDtB^z| zrFr62=Zc5qq4r8M=cMwT@jh8#QkFqsEwU7{z!3;i(4UIT(^AI1{UmY-_<;KR=%i0r z13W%L)Gb7?jfJI&OOF-9mnDIgWZ}siIdVC~T$daia5%YgILWO`V;TqJu-b0LQv?J# z$x4&~#}f(>OBkCF(8e*KV+K+d2@R&bS7_?H-t_9amw4gIaV|RRw^OQh*Lymvw7Pe$ z*C;QPp%_3VDJ#2Hh9ua=h9uh>XhUooViRo)8c1woXd4<}(32ZDaE#c&#~F5tK0H&h z=M&M^wKW-<$ZJ?&&6u+>i)Ph(dc9LIrjygv#X;X7;yc%E2GcAJjc9s$J&R_THfg1` zmKVOs>TLY3ONq`oIGiPRlm2 zyJkz6vxAbU5Hx27f-=JFdh*&%6P@9wG)_Z9Z-G*@+N7dPE(Ltn*mRXt6{T_Ox3qY` z%?(+w@}Gn7dG=|C4a~`dmvY&+?9Mu)Y4()AVe_JF&)gh08!BhgQ=Ugsa9fgU^Q~o< z3Pz4f)-FZhP6~ixz{QiW>=BFF*R@{aFL3po6f&=_!Xt4gg7w%MBFh$@8EquDT)IgI z5Zi$8%Tzo9eQ=7gWI!dVd{C8b3MMwJfjh_uh?_4w8N)4R`e)hrI0a_Qw44eZKXAC6 z3^M2IMiqerP>r~m5<#GL6!0o~P-65f*l^lPgM%ePI_XYHu+rSN7G5E%zIWikdr!s> z=?|s281y+FO2wUIRQn82$QUdTW~hubW3$pfRgY>>6f)7ayk@2AW&cfL{c(CVgmtUJ!D2iVL9h8)7$TFhE0$#T#P;h_j2Af%cZ$} zC|O-yot$y&7T3M)zhw_sdv6(jxsE40wdYIq<_G8PFP_aY#goEkFApK)-X+-j6Vn&l z`!4hMyO}iLoZEYv|G=6%CKGIo0*w53l(C;i%Q^fJ-~Cs!Fdkq`g-)g zdGpPz*lvA>H{M>*V=jtJ30unQ=Rq&DA`L0%3p=i>mcfnmEd%PHcun=XVhJVQF6o=- zJ3)<%b+=gQ- zo@l^}f-VEsFJLCnV|FHz4oHoVwo6;CV=H2)M~gPq)Ju(zQRF;t-+js=@VVxikFYD3 vP;t{4ShJ`M%*=Y+_5Fc`95`8R+ds8K@~C}*_(guCe+#)HoG3_TW{Kv2nEx+F literal 0 HcmV?d00001 diff --git a/grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-13/load_q.csv.bz2 b/grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-13/load_q.csv.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..887ff90b5c5059820a46bc975d3ecdf6c0037e26 GIT binary patch literal 2311 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 literal 0 HcmV?d00001 diff --git a/grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-13/load_q_forecasted.csv.bz2 b/grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-13/load_q_forecasted.csv.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..74f6595f6bffd4c371ba1cd3ada710da571c2040 GIT binary patch literal 1884 zcmV-i2c!5xT4*^jL0KkKS#<)>PXHTu+W-I%00DpK005)};0#@-udrEm?XtUWxgteS z19#TFx5P%JRw?(f9Prab*)>!~0VFg@`l^#A14@3d)9K*y zVeP(hQ40 z>L*DjWAUfE+V%J#Z4SH;N5)KFGJF|JMS}K93zuM`TWq>6hzsCuHQwio(V0JzhiQT1$jU(1+VI!}k`x z@7@9zwlTU+O$U;=2Tq9aFj8f$ZTS zZJBVlRK7Nix@cH<>O7N@Bf(%F6IDecDisLWM1sVOSrx@_aTujk=!Z|Z_U-kVynwd~ zlC=WWLgbBEwsJ>KN0MOhfuX9b8f21@Mlpme9B>$=Md~k4xbM4@-0huh`0^Y&k>Lx+ z&K3#HhSDacq1Ui$RVadkAY_J2fC&PCHbQzkYgm`O!t&Fpq$cJ8ny}L$7k)kywK=J7 zS&5Xr98Xl*KSIp;WA2`}*=M&r6daS_I^1S@Dc z76Abwl8I-`uYJs4ch4>o>0VtmO<}DxxSHvqgS~qPwLAh;Y?IXdN5c8x_Bl>DY@4;U zX`@tWsf?yrSYXMOlM@sLKQf}?;6a3pNWu_|2>zQ^v?^7pUHnlPehA2bvI>ogA4Mt8 zy_EaBBk0!3zTMqL&9qIl)h)AG4P>opk710CqMn5xPSAMTm_$rPwF)ar1w<%NY5_{6 z5v@XsMToScKnqr=f#Qhsvq^a6c#A28ZkD53G{VASW)=~xskCm(Xv#88Xw_T0D}qlM zEs>d33I(W*N>mD!sI*`NSxXG1h6@%H!IX=sK*9r2d?Lpbgcv}C2z;e!Yiz8wsji&q zbCjM$uW}6szOQa0x^-NKanqG`$4->fV^np=4vDK)((A4`t(!I{I&sP3se6RkJw1B4 zM@~Armrfk6M$Ju=j&yW7>CRU=>C$oBIZorNlIxCMDOaqa>Uw(~j;^@j!tNbi4t3GW z>#i3|yQt#pjxK|{t|vI<$m^XRN~_o7^XKEUd*|}cKaOS6GfYuk`E&evzs_MvhhDXQ za(s(Q#MCkzM4t3yM4BQxDNfT(n#e@}P-$L?VFD#f-4jElQT6l=>T$%(8N5jv+!?^Z&F;Brp3J>%zS#XUqFFfX7>+MV z5E?N(2d9DJ3x4n4cRt^`_ul6E0BIPIg^Ys;i6Mgl1}MUOF+pNMREUDGWSS`zkU-vd zbGBjLZTxfLzMp;9JTG)!zA9cwInB5*d(b<8K{(xQj$O&MjqAGJwcwy(h6G|$tbo>n zYe@uvHU?-=w`nV6je3q7BQYSfx9UArk8$I+TC{+>(uL7SE@N$`tI(A`w7Jz zw;dOo)sJ%V-e=W>Qd#bBBrCkQmeLf(vpx_ zfMO-*#eA0>=P`^JuAfal@;;2TPCnPbh9d>Tcg!M@c}oKyyfBpnV#KJ3%a>qvL>e%6 z6fAP5rWQEFcBH(S;h6J-4aiI4KOCW#D5=RT;K0vyJ8LVpGk{^98POs{&@eYBY0oH; z;V|1@4Aj6e$(4L0V_@2pxf8*skA;g7@h@jvWwSiwk;&})15KSec=vX3{i+|8 WL+lU2EB2^=3%MekC`dYiXQzP4OppQq literal 0 HcmV?d00001 diff --git a/grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-13/prod_p.csv.bz2 b/grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-13/prod_p.csv.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..a8f9567a0e415f8a0936aba62e2649f08d4cca1e GIT binary patch literal 1867 zcmV-R2ekM?T4*^jL0KkKSz#ifWB?DuTL1tM00DpK004r4U<;)u3}jM;Qr`lVP>2wx z-teM^gC#{YFx2pYQ~*%ZOaKT`5;Z^r5Fs;Bppz*ms0<4}ef##HUv&gaUk&|v ztXB5i_4ic=yR{iB-I0g5@0x>Y(Y@S?H>+`BsnszCdhSdFF14qc;a68jw^J1ms?K@Q zF;K0WW?pWi#l6yjtm?^R-i zhK}xK$;q68_HyP#VDcqf8Npn(mHCVIk_7?p4+Q*f{LYzK(b(?nTf*OlcxZch%KMJa zlS9dIli0}v*fQC4w=VgoC^;kSi{EfPov12+r?51RN*Ra1^EZR@Eb-(`S1T%E_6_N3*<$5os4^34~EPxh)%aWH>=O@UG5um~8cd0m3rI zBKkuajx7hsuP+lo;q<4h?5L_~l{M2uBi5mU_~ON>e8We)Bcheqoi<>dqv%^yUV zMQ-VIM-mAnA6g`m0f2#4CTjMGtN_7W@(c?E3RIy%D#5ldEXwBC*;+$XJA^1|AfHq8 z2}y8wpFz}?_>!rNqRXX(k|FXH>ls5+99VW*K`^)=f+xUBeFKs-u7#4J%^;dKFc?A<(e>&Z zQ_pcB894?$p`%hHl(1X(F&!8jL81f%0u9l7S{Ji+@K?EIS)pi9O+F|b2rNy9UJV5i zRHtz}0goG{oEd&teL&hVAQhl2kV@icP$ZIkQ4J3-QHcVzQ_8vMIMLI(;KNAdRtWJ?$KEdvV-JK5^J#&~fPQMLp5;0gb-`ZLT+%`9P==190x!lk2!l za!FgmxW{;|4<{R<6NopC@*a1vb?1>p+qP-P2Q@(+qA!F4!Q>po^LE`KX)mqhAoN`q zIjoZrvGW19(F}3I# z8OdS9Md<<>aNz|8cEH;bV4|fm)B-K35f)B%<&Hul3kh{KQQMwK?Fi1f=DJwDS`-!DT-zZs)7lLBA}XxnJ6kC zrh+1fnxQBPVu@lRpqZ(nN??$pfQTxZ3L-)!C7MWz0Ej3kB1nn~7>J0bj-W4)fxz!+ z$!HO_R0O{EwsFp5bP#Y^Io+~=iY_|AIWm)h3uB(*!35z5B^OT3*12{_ZYv$2uH$y( zoJEl}hPA$_OA^vORb37oOv4;U2xA8)YNExoIrzMAbDXw-mD%QUa>bGEvBQ*LmC+3u zOCY4dBv?Tp1H7(ys^D^|*<8cBR7S)q$DL|_8;o`6$JPscwWoD{ido*TGB?z$w8QI^ z^J=wKHY+q&E}64(b2^mgbR>MF6{KkzXquv_r<6HRO<@DTpL@f=a%X|^qH4Gv8*mp` z!KUtJmg}y`kS@&Z+%WYAT`xl$kS97*a2nu6MV`W>yh4)D6od(!8D&VDFCR;4j z)Y;8eA)Ip1%n}HuSmk(!7l9`7S1`M{Z(7H7)p>Go+;mOo<|>A6nDL_yUdPumtBqB+ zRX3GRdEK=GxcM&S0)cd~Df8^q;36E$ z7ds)gL8(L*s+H#F8C6}7X+VnBWv$b-vBjX19y-ILheWmu8J>N)J!C>BE+a3PqvUR) ze0>PcL$;r*X^bJeW7vH)iWAuTcBp67j FSpeJUU9JEC literal 0 HcmV?d00001 diff --git a/grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-13/prod_p_forecasted.csv.bz2 b/grid2op/data_test/educ_case14_storage_init_state/chronics/2019-01-13/prod_p_forecasted.csv.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..8a51198581e1d45d07188d2ed11b4e0c2347e795 GIT binary patch literal 1710 zcmV;f22uG!T4*^jL0KkKS?B#m_y7;Y+W-I%00DpK004r4U<%P67R_p^Oi#K1e1s4U z>)6GZ+3q{xriqxUrY6v7geIt_hA3&K00f?@sL=eR076MAKxhP-ki{whj9^Q{PtN)E z2X8RF!|QQt_UD81`?2{YLt0OivP!hgpgoH_&sJs*Bq_sJU$`T%1u?-mdGhV!cwW5A z_bl84lscHh1pk1`jwHI9OhdDpoAfbs*9X5^`hZb`x{cMSwhLlj^C` zj^$t#mcX}2$lzFqhY5oQ;1_P!=wN06p8X%Px-x1S+L6eMU6$&qccn@y2C>iLK1Q8x%xSeagn* z(D)Ho+pg@Y4GYD@a||r7vWoR9K^bFS!mBeP7=hGN4?7rGsw<(2qO(Aa?(E&6A6wzd z=AG?W(ZVo0IXiCPZtl%Z1Vw3g4S-Dr>8vt0ShzTBhe+me|^3#DmCL zRw9KUDLStUG&I97$weke8YNy*IFmB_$;=Y6={fRRdG||7n1yie74Dl1((v7!=-q)G zLcP_MLhC7S1iOG%3}-JF8>=B8Ia(0;`=7M1qOSv!DqnyKjiILX;P%&h1i78Sk5Q}x z2RI}_Q6Le(4li!KW;>KIzEhN?Hw&rj(&VDL-@9C=zaHO??oYlw=rwW*CKgEejpy^JqFPj3=^iN8Vqa{6;BF}p&jC4Jt|^j zZc!gdG?){h@Ieq;7`aq@K!@)7d~9ae!34z`-%F=Ms^?(q71P|}?UpQvpP{2_HKtaR zQk9x&WtnW6r8bhJ%%+txibD*nkjxTEEE15&OC+)If*hVXEn_Chv-Wo;+Z;}4<1A*y zCq_6e5yXZdI*qyqaA!hNIP517$2Esp-qfi|5lm@`Fr^umDJ0TmB+`_VMv}%XZIX#2 zW|}0V%`#Dq8Wg0AnVL+S7@1>587&r)EL5S0qJ|-$Ao&%4C0`HUIomFhakXG`Mn4Q2 zi?HwqVeZQ@*ra0vq>~avkYsxX4l6@BHqjV6ZZt`Q7|zFR@>?w6*z1Ra*zd&y;YII1 zEY6_VDahgpr)6;kUvtaR8wQdNQOQQ>s+dr8e%_a#)I!kf4_>AL`e4_p-$RP+_%GKop>>y^NEG2R2I)zO*HjaOBq zTu4$^&bTm(?|VEJzd6qYk&)gTCIYj(@3!svW!MC;fgX3HkQ-wo$UGp+9mlb4q8L6S z74jMg{aA;>8VLPb>#jD1f?w5%f@jr9@R~T|iGwY)(ZsR0Qw7<_7iSxp#d23ExtAwf zxx1WesMitPiLM-gAW4SqApHlpd93E`YP%cPlziOX8^RT)Q}$*_Z-tEZIeD^a551v! z%Ts#qG4x^f&cy3@13d Date: Fri, 3 May 2024 15:50:21 +0200 Subject: [PATCH 10/11] ready to merge with dev_1.10.2 --- .gitignore | 5 + grid2op/Action/baseAction.py | 11 +- grid2op/tests/test_RunnerFast.py | 125 ++++++++++++++++++++ grid2op/tests/test_action_set_orig_state.py | 2 - 4 files changed, 138 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index e950fdba4..ce5f54dd4 100644 --- a/.gitignore +++ b/.gitignore @@ -403,6 +403,11 @@ grid2op/tests/requirements.txt grid2op/tests/venv_test_311/ issue_577/ junk.py +grid2op/tests/20240429_failed_tests.txt +grid2op/tests/20240429_failed_tests_small.txt +grid2op/tests/20240429_teq_test.txt +grid2op/tests/req_38_np121 +test_make_2_envs.py # profiling files **.prof diff --git a/grid2op/Action/baseAction.py b/grid2op/Action/baseAction.py index 7dd8f9d90..fe92e5a5e 100644 --- a/grid2op/Action/baseAction.py +++ b/grid2op/Action/baseAction.py @@ -6435,7 +6435,6 @@ def decompose_as_unary_actions(self, tmp += a assert tmp == act - Parameters ---------- group_topo : bool, optional @@ -6499,12 +6498,15 @@ def decompose_as_unary_actions(self, self._aux_decompose_as_unary_actions_curtail(cls, group_curtail, res) return res - def _add_act_and_remove_line_status_only_set(self, other: "BaseAction"): + def _add_act_and_remove_line_status_only_set(self, other: "BaseAction") -> "BaseAction": """INTERNAL This is used by the environment when combining action in the "set state" in env.reset. It supposes both self and other are only "set" actions + + .. versionadded:: 1.10.2 + """ self += other cls = type(self) @@ -6529,6 +6531,7 @@ def _add_act_and_remove_line_status_only_set(self, other: "BaseAction"): self._modif_set_status = True if (self._set_topo_vect != 0).any(): self._modif_set_bus = True + return self def remove_change(self) -> "BaseAction": """This function will modify 'self' and remove all "change" action type. @@ -6536,6 +6539,8 @@ def remove_change(self) -> "BaseAction": It is mainly used in the environment, when removing the "change" type for setting the original state of the grid. + .. versionadded:: 1.10.2 + """ if self._change_bus_vect.any(): warnings.warn("This action modified the buses with `change_bus` ") @@ -6544,4 +6549,4 @@ def remove_change(self) -> "BaseAction": if self._switch_line_status.any(): self._switch_line_status[:] = False self._modif_change_status = False - return self \ No newline at end of file + return self diff --git a/grid2op/tests/test_RunnerFast.py b/grid2op/tests/test_RunnerFast.py index e69de29bb..1da9d05f4 100644 --- a/grid2op/tests/test_RunnerFast.py +++ b/grid2op/tests/test_RunnerFast.py @@ -0,0 +1,125 @@ +# Copyright (c) 2019-2020, RTE (https://www.rte-france.com) +# See AUTHORS.txt +# This Source Code Form is subject to the terms of the Mozilla Public License, version 2.0. +# If a copy of the Mozilla Public License, version 2.0 was not distributed with this file, +# you can obtain one at http://mozilla.org/MPL/2.0/. +# SPDX-License-Identifier: MPL-2.0 +# This file is part of Grid2Op, Grid2Op a testbed platform to model sequential decision making in power systems. + +import warnings +import unittest + +from grid2op.tests.helper_path_test import * + +PATH_ADN_CHRONICS_FOLDER = os.path.abspath( + os.path.join(PATH_CHRONICS, "test_multi_chronics") +) +PATH_PREVIOUS_RUNNER = os.path.join(data_test_dir, "runner_data") + +import grid2op +from grid2op.Runner import Runner +from grid2op.dtypes import dt_float + +warnings.simplefilter("error") + + +class TestRunner(HelperTests, unittest.TestCase): + def setUp(self): + super().setUp() + self.init_grid_path = os.path.join(PATH_DATA_TEST_PP, "test_case14.json") + self.path_chron = PATH_ADN_CHRONICS_FOLDER + self.parameters_path = None + self.max_iter = 10 + self.real_reward = dt_float(7748.425 / 12.) + self.real_reward_li = [self.real_reward, dt_float(7786.8955 / 12.)] # 7786.89599609375 + + self.all_real_rewards = [ + dt_float(el / 12.) + for el in [ + 761.3295, + 768.10144, + 770.2673, + 767.767, + 768.69, + 768.71246, + 779.1029, + 783.2737, + 788.7833, + 792.39764, + ] + ] + with warnings.catch_warnings(): + warnings.filterwarnings("ignore") + self.env = grid2op.make("l2rpn_case14_sandbox", test=True, _add_to_name=type(self).__name__) + self.runner = Runner(**self.env.get_params_for_runner()) + + def test_one_episode(self): + with warnings.catch_warnings(): + warnings.filterwarnings("ignore") + _, cum_reward, timestep, max_ts = self.runner.run_one_episode( + max_iter=self.max_iter + ) + assert int(timestep) == self.max_iter + assert np.abs(cum_reward - self.real_reward) <= self.tol_one, f"{cum_reward} != {self.real_reward}" + + def test_one_episode_detailed(self): + with warnings.catch_warnings(): + warnings.filterwarnings("ignore") + _, cum_reward, timestep, max_ts, episode_data = self.runner.run_one_episode( + max_iter=self.max_iter, detailed_output=True + ) + assert int(timestep) == self.max_iter + assert np.abs(cum_reward - self.real_reward) <= self.tol_one + for j in range(len(self.all_real_rewards)): + assert ( + np.abs(episode_data.rewards[j] - self.all_real_rewards[j]) + <= self.tol_one + ), f"{episode_data.rewards[j]} != {self.all_real_rewards[j]}" + + def test_2episode(self): + with warnings.catch_warnings(): + warnings.filterwarnings("ignore") + res = self.runner._run_sequential(nb_episode=2, max_iter=self.max_iter) + assert len(res) == 2 + for i, (stuff, _, cum_reward, timestep, total_ts) in enumerate(res): + assert int(timestep) == self.max_iter + assert np.abs(cum_reward - self.real_reward_li[i]) <= self.tol_one, f"for iter {i}: {cum_reward} != {self.real_reward_li[i]}" + + def test_init_from_env(self): + with warnings.catch_warnings(): + warnings.filterwarnings("ignore") + with grid2op.make("rte_case14_test", test=True, _add_to_name=type(self).__name__) as env: + runner = Runner(**env.get_params_for_runner()) + res = runner.run(nb_episode=1, max_iter=self.max_iter) + for i, _, cum_reward, timestep, total_ts in res: + assert int(timestep) == self.max_iter, f"{timestep} != {self.max_iter}" + + def test_seed_seq(self): + with warnings.catch_warnings(): + warnings.filterwarnings("ignore") + with grid2op.make("rte_case14_test", test=True, _add_to_name=type(self).__name__) as env: + runner = Runner(**env.get_params_for_runner()) + res = runner.run( + nb_episode=1, max_iter=self.max_iter, env_seeds=[1], agent_seeds=[2] + ) + for i, _, cum_reward, timestep, total_ts in res: + assert int(timestep) == self.max_iter, f"{timestep} != {self.max_iter}" + + def test_seed_par(self): + with warnings.catch_warnings(): + warnings.filterwarnings("ignore") + with grid2op.make("rte_case14_test", test=True, _add_to_name=type(self).__name__) as env: + runner = Runner(**env.get_params_for_runner()) + res = runner.run( + nb_episode=2, + nb_process=2, + max_iter=self.max_iter, + env_seeds=[1, 2], + agent_seeds=[3, 4], + ) + for i, _, cum_reward, timestep, total_ts in res: + assert int(timestep) == self.max_iter + + +if __name__ == "__main__": + unittest.main() diff --git a/grid2op/tests/test_action_set_orig_state.py b/grid2op/tests/test_action_set_orig_state.py index ba10b8bfc..ee8f8ec13 100644 --- a/grid2op/tests/test_action_set_orig_state.py +++ b/grid2op/tests/test_action_set_orig_state.py @@ -41,8 +41,6 @@ # TODO test "change" is deactivated -# TODO test grid2Op compat mode (storage units) -# TODO test with redispatching and curtailment actions # TODO test with "names_orig_to_backend" From cc9fd623c82c2b6cd94ef24bd953e8ec0b659e9c Mon Sep 17 00:00:00 2001 From: DONNOT Benjamin Date: Fri, 3 May 2024 16:02:35 +0200 Subject: [PATCH 11/11] fixing broken tests again (-: --- grid2op/tests/test_RunnerFast.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/grid2op/tests/test_RunnerFast.py b/grid2op/tests/test_RunnerFast.py index 1da9d05f4..b82a2017a 100644 --- a/grid2op/tests/test_RunnerFast.py +++ b/grid2op/tests/test_RunnerFast.py @@ -20,8 +20,6 @@ from grid2op.Runner import Runner from grid2op.dtypes import dt_float -warnings.simplefilter("error") - class TestRunner(HelperTests, unittest.TestCase): def setUp(self): @@ -56,7 +54,7 @@ def setUp(self): def test_one_episode(self): with warnings.catch_warnings(): warnings.filterwarnings("ignore") - _, cum_reward, timestep, max_ts = self.runner.run_one_episode( + _, _, cum_reward, timestep, max_ts = self.runner.run_one_episode( max_iter=self.max_iter ) assert int(timestep) == self.max_iter @@ -65,7 +63,7 @@ def test_one_episode(self): def test_one_episode_detailed(self): with warnings.catch_warnings(): warnings.filterwarnings("ignore") - _, cum_reward, timestep, max_ts, episode_data = self.runner.run_one_episode( + _, _, cum_reward, timestep, max_ts, episode_data = self.runner.run_one_episode( max_iter=self.max_iter, detailed_output=True ) assert int(timestep) == self.max_iter