diff --git a/.circleci/config.yml b/.circleci/config.yml index f54f17919..6dca4b27b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -3,27 +3,27 @@ version: 2.1 executors: grid2op-executor: docker: - - image: python:3.10-buster + - image: python:3.10 working_directory: /Grid2Op python37: docker: - - image: python:3.7-buster + - image: python:3.7 python38: docker: - - image: python:3.8-buster + - image: python:3.8 python39: docker: - - image: python:3.9-buster + - image: python:3.9 python310: docker: - - image: python:3.10-buster + - image: python:3.10 python311: docker: - - image: python:3.11-buster + - image: python:3.11 python312: docker: - - image: cimg/python:3.12.0 + - image: cimg/python:3.12 jobs: test: @@ -140,27 +140,27 @@ jobs: python -m pip install -U .[test] export _GRID2OP_FORCE_TEST=1 grid2op.testinstall - - run: - command: | - source venv_test/bin/activate - python -m pip install -U "numpy>=1.21,<1.22" - python -m pip install -U .[test] - export _GRID2OP_FORCE_TEST=1 - grid2op.testinstall - - run: - command: | - source venv_test/bin/activate - python -m pip install -U "numpy>=1.22,<1.23" - python -m pip install -U .[test] - export _GRID2OP_FORCE_TEST=1 - grid2op.testinstall - - run: - command: | - source venv_test/bin/activate - python -m pip install -U "numpy>=1.23,<1.24" - python -m pip install -U .[test] - export _GRID2OP_FORCE_TEST=1 - grid2op.testinstall + # - run: + # command: | + # source venv_test/bin/activate + # python -m pip install -U "numpy>=1.21,<1.22" + # python -m pip install -U .[test] + # export _GRID2OP_FORCE_TEST=1 + # grid2op.testinstall + # - run: + # command: | + # source venv_test/bin/activate + # python -m pip install -U "numpy>=1.22,<1.23" + # python -m pip install -U .[test] + # export _GRID2OP_FORCE_TEST=1 + # grid2op.testinstall + # - run: + # command: | + # source venv_test/bin/activate + # python -m pip install -U "numpy>=1.23,<1.24" + # python -m pip install -U .[test] + # export _GRID2OP_FORCE_TEST=1 + # grid2op.testinstall - run: command: | source venv_test/bin/activate @@ -187,53 +187,53 @@ jobs: python -m pip install -U pip setuptools wheel python -m pip install chronix2grid>="1.1.0.post1" python -m pip uninstall -y grid2op - - run: - command: | - source venv_test/bin/activate - python -m pip install -U numba - python -m pip install -U .[test] - - run: - command: | - source venv_test/bin/activate - python -m pip install -U "numpy>=1.20,<1.21" - python -m pip install -U .[test] - export _GRID2OP_FORCE_TEST=1 - grid2op.testinstall - - run: - command: | - source venv_test/bin/activate - python -m pip install -U "numpy>=1.21,<1.22" - python -m pip install -U .[test] - export _GRID2OP_FORCE_TEST=1 - grid2op.testinstall - - run: - command: | - source venv_test/bin/activate - python -m pip install -U "numpy>=1.22,<1.23" - python -m pip install -U .[test] - export _GRID2OP_FORCE_TEST=1 - grid2op.testinstall - - run: - command: | - source venv_test/bin/activate - python -m pip install -U "numpy>=1.23,<1.24" - python -m pip install -U .[test] - export _GRID2OP_FORCE_TEST=1 - grid2op.testinstall - - run: - command: | - source venv_test/bin/activate - python -m pip install -U "numpy>=1.24,<1.25" - python -m pip install -U .[test] - export _GRID2OP_FORCE_TEST=1 - grid2op.testinstall - - run: - command: | - source venv_test/bin/activate - python -m pip install -U "numpy>=1.25,<1.26" - python -m pip install -U .[test] - export _GRID2OP_FORCE_TEST=1 - grid2op.testinstall + # - run: + # command: | + # source venv_test/bin/activate + # python -m pip install -U numba + # python -m pip install -U .[test] + # - run: + # command: | + # source venv_test/bin/activate + # python -m pip install -U "numpy>=1.20,<1.21" + # python -m pip install -U .[test] + # export _GRID2OP_FORCE_TEST=1 + # grid2op.testinstall + # - run: + # command: | + # source venv_test/bin/activate + # python -m pip install -U "numpy>=1.21,<1.22" + # python -m pip install -U .[test] + # export _GRID2OP_FORCE_TEST=1 + # grid2op.testinstall + # - run: + # command: | + # source venv_test/bin/activate + # python -m pip install -U "numpy>=1.22,<1.23" + # python -m pip install -U .[test] + # export _GRID2OP_FORCE_TEST=1 + # grid2op.testinstall + # - run: + # command: | + # source venv_test/bin/activate + # python -m pip install -U "numpy>=1.23,<1.24" + # python -m pip install -U .[test] + # export _GRID2OP_FORCE_TEST=1 + # grid2op.testinstall + # - run: + # command: | + # source venv_test/bin/activate + # python -m pip install -U "numpy>=1.24,<1.25" + # python -m pip install -U .[test] + # export _GRID2OP_FORCE_TEST=1 + # grid2op.testinstall + # - run: + # command: | + # source venv_test/bin/activate + # python -m pip install -U "numpy>=1.25,<1.26" + # python -m pip install -U .[test] + # export _GRID2OP_FORCE_TEST=1 + # grid2op.testinstall - run: command: | source venv_test/bin/activate @@ -265,34 +265,34 @@ jobs: python -m pip install -U .[test] export _GRID2OP_FORCE_TEST=1 grid2op.testinstall - - run: - command: | - source venv_test/bin/activate - python -m pip install -U "numpy>=1.22,<1.23" - python -m pip install -U .[test] - export _GRID2OP_FORCE_TEST=1 - grid2op.testinstall - - run: - command: | - source venv_test/bin/activate - python -m pip install -U "numpy>=1.23,<1.24" - python -m pip install -U .[test] - export _GRID2OP_FORCE_TEST=1 - grid2op.testinstall - - run: - command: | - source venv_test/bin/activate - python -m pip install -U "numpy>=1.24,<1.25" - python -m pip install -U .[test] - export _GRID2OP_FORCE_TEST=1 - grid2op.testinstall - - run: - command: | - source venv_test/bin/activate - python -m pip install -U "numpy>=1.25,<1.26" - python -m pip install -U .[test] - export _GRID2OP_FORCE_TEST=1 - grid2op.testinstall + # - run: + # command: | + # source venv_test/bin/activate + # python -m pip install -U "numpy>=1.22,<1.23" + # python -m pip install -U .[test] + # export _GRID2OP_FORCE_TEST=1 + # grid2op.testinstall + # - run: + # command: | + # source venv_test/bin/activate + # python -m pip install -U "numpy>=1.23,<1.24" + # python -m pip install -U .[test] + # export _GRID2OP_FORCE_TEST=1 + # grid2op.testinstall + # - run: + # command: | + # source venv_test/bin/activate + # python -m pip install -U "numpy>=1.24,<1.25" + # python -m pip install -U .[test] + # export _GRID2OP_FORCE_TEST=1 + # grid2op.testinstall + # - run: + # command: | + # source venv_test/bin/activate + # python -m pip install -U "numpy>=1.25,<1.26" + # python -m pip install -U .[test] + # export _GRID2OP_FORCE_TEST=1 + # grid2op.testinstall - run: command: | source venv_test/bin/activate @@ -324,20 +324,20 @@ jobs: python -m pip install -U .[test] export _GRID2OP_FORCE_TEST=1 grid2op.testinstall - - run: - command: | - source venv_test/bin/activate - python -m pip install -U "numpy>=1.24,<1.25" - python -m pip install -U .[test] - export _GRID2OP_FORCE_TEST=1 - grid2op.testinstall - - run: - command: | - source venv_test/bin/activate - python -m pip install -U "numpy>=1.25,<1.26" - python -m pip install -U .[test] - export _GRID2OP_FORCE_TEST=1 - grid2op.testinstall + # - run: + # command: | + # source venv_test/bin/activate + # python -m pip install -U "numpy>=1.24,<1.25" + # python -m pip install -U .[test] + # export _GRID2OP_FORCE_TEST=1 + # grid2op.testinstall + # - run: + # command: | + # source venv_test/bin/activate + # python -m pip install -U "numpy>=1.25,<1.26" + # python -m pip install -U .[test] + # export _GRID2OP_FORCE_TEST=1 + # grid2op.testinstall - run: command: | source venv_test/bin/activate @@ -380,4 +380,4 @@ workflows: - install39 - install310 - install311 - # - install312 # failing because of dependencies of numba, torch etc. Tired of it so ignoring it ! + - install312 # failing because of dependencies of numba, torch etc. Tired of it so ignoring it ! diff --git a/.gitignore b/.gitignore index 2a03d9711..84e7e7bd5 100644 --- a/.gitignore +++ b/.gitignore @@ -397,6 +397,8 @@ grid2op/tests/test_failing_simulator.txt old_pyproject.toml pp_bug_gen_alone.py test_dunder.py +grid2op/tests/test_fail_ci.txt +saved_multiepisode_agent_36bus_DN_4/ # profiling files **.prof diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 28b8ddfa2..f492ba4a1 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -31,6 +31,40 @@ Change Log - [???] "asynch" multienv - [???] properly model interconnecting powerlines + +[1.9.8] - 20xx-yy-zz +---------------------- +- [IMPROVED] the CI speed: by not testing every possible numpy version but only most ancient and most recent +- [IMPROVED] Runner now test grid2op version 1.9.6 and 1.9.7 +- [IMPROVED] refacto `gridobj_cls._clear_class_attribute` and `gridobj_cls._clear_grid_dependant_class_attributes` +- [IMPROVED] the bahviour of the generic class `MakeBackend` used for the test suite. +- [IMPROVED] re introducing python 12 testing + +[1.9.7] - 2023-12-01 +---------------------- +- [BREAKING] removal of the `grid2op/Exceptions/PowerflowExceptions.py` file and move the + `DivergingPowerflow` as part of the BackendException. If you imported (to be avoided) + with `from grid2op.Exceptions.PowerflowExceptions import PowerflowExceptions` + simply do `from grid2op.Exceptions import PowerflowExceptions` and nothing + will change. +- [BREAKING] rename with filename starting with lowercase all the files in the "`Exceptions`", + module. This is both consistent with python practice but allows also to make the + difference between the files in the + module and the class imported. This should have little to no impact on all codes but to "upgrade" + instead of `from grid2op.Exceptions.XXX import PowerflowExceptions` (which you should not have done in the first place) + just do `from grid2op.Exceptions import PowerflowExceptions`. Expect other changes like this for other grid2op modules + in the near future. +- [BREAKING] change the `gridobj_cls.shape()` and `gridobj_cls.dtype()` to `gridobj_cls.shapes()` and `gridobj_cls.dtypes()` + to be more clear when dealing with action_space and observation_space (where `shape` and `dtype` are attribute and not functions) + This change means you can still use `act.shape()` and `act.dtype()` but that `act_space.shape` and `act_space.dtype` are now + clearly properties (and NOT attribute). For the old function `gridobj_cls.dtype()` you can now use `gridobj_cls.dtypes()` +- [FIXED] issue https://github.com/rte-france/Grid2Op/issues/561 (indent issue) +- [FIXED] issue https://github.com/rte-france/Grid2Op/issues/550 : issue with `shunts_data_available` now better handled +- [IMPROVED] the function to check the backend interface now also check that + the `topo_vect` returns value between 1 and 2. +- [IMPROVED] the function to check backend now also check the `topo_vect` + for each type of elements. + [1.9.6] - 2023-10-26 ---------------------- - [BREAKING] when a storage is connected alone on a bus, even if it produces / absorbs 0.0 MW it diff --git a/Dockerfile b/Dockerfile index a771938ac..9d0271a0a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -35,7 +35,7 @@ WORKDIR /Grid2Op RUN git pull RUN git remote update RUN git fetch --all --tags -RUN git checkout "tags/v1.9.5" -b "v1.9.5-branch" +RUN git checkout "tags/v1.9.7" -b "v1.9.7-branch" # Install Dependencies RUN pip3 install .[optional,challenge] WORKDIR / diff --git a/docs/conf.py b/docs/conf.py index 2bdb031f9..b9cbbc67d 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.9.5' +release = '1.9.8.dev0' version = '1.9' diff --git a/grid2op/Action/_backendAction.py b/grid2op/Action/_backendAction.py index f211da14e..718d63a1a 100644 --- a/grid2op/Action/_backendAction.py +++ b/grid2op/Action/_backendAction.py @@ -238,7 +238,8 @@ def __init__(self): ) # shunts - if type(self).shunts_data_available: + cls = type(self) + if cls.shunts_data_available: self.shunt_p = ValueStore(self.n_shunt, dtype=dt_float) self.shunt_q = ValueStore(self.n_shunt, dtype=dt_float) self.shunt_bus = ValueStore(self.n_shunt, dtype=dt_int) @@ -270,7 +271,8 @@ def __deepcopy__(self, memodict={}): res.storage_power.copy(self.storage_power) res.activated_bus[:, :] = self.activated_bus # res.big_topo_to_subid[:] = self.big_topo_to_subid # cste - if type(self).shunts_data_available: + cls = type(self) + if cls.shunts_data_available: res.shunt_p.copy(self.shunt_p) res.shunt_q.copy(self.shunt_q) res.shunt_bus.copy(self.shunt_bus) @@ -313,7 +315,8 @@ def reorder(self, no_load, no_gen, no_topo, no_storage, no_shunt): self.storage_power.reorder(no_storage) - if type(self).shunts_data_available: + cls = type(self) + if cls.shunts_data_available: self.shunt_p.reorder(no_shunt) self.shunt_q.reorder(no_shunt) self.shunt_bus.reorder(no_shunt) @@ -340,7 +343,8 @@ def reset(self): self.storage_power.values[:] = 0.0 # shunts - if type(self).shunts_data_available: + cls = type(self) + if cls.shunts_data_available: self.shunt_p.reset() self.shunt_q.reset() self.shunt_bus.reset() diff --git a/grid2op/Action/baseAction.py b/grid2op/Action/baseAction.py index f7d574b87..ac7321a55 100644 --- a/grid2op/Action/baseAction.py +++ b/grid2op/Action/baseAction.py @@ -440,7 +440,7 @@ def __init__(self): self._subs_impacted = None # shunts - if self.shunts_data_available: + if type(self).shunts_data_available: self.shunt_p = np.full( shape=self.n_shunt, fill_value=np.NaN, dtype=dt_float ) @@ -495,6 +495,12 @@ def copy(self) -> "BaseAction": # sometimes this method is used... return self.__deepcopy__() + def shape(self): + return type(self).shapes() + + def dtype(self): + return type(self).dtypes() + def _aux_copy(self, other): attr_simple = [ "_modif_inj", @@ -1050,7 +1056,7 @@ def __eq__(self, other) -> bool: return False # shunts are the same - if self.shunts_data_available: + if type(self).shunts_data_available: if self.n_shunt != other.n_shunt: return False is_ok_me = np.isfinite(self.shunt_p) @@ -1631,7 +1637,7 @@ def __iadd__(self, other): self._assign_iadd_or_warn("_change_bus_vect", me_change) # shunts - if self.shunts_data_available: + if type(self).shunts_data_available: val = other.shunt_p ok_ind = np.isfinite(val) shunt_p = 1.0 * self.shunt_p @@ -2664,7 +2670,7 @@ def _check_for_ambiguity(self): "which it is connected. This is ambiguous. You must *set* this bus instead." ) - if self.shunts_data_available: + if type(self).shunts_data_available: if self.shunt_p.shape[0] != self.n_shunt: raise IncorrectNumberOfElements( "Incorrect number of shunt (for shunt_p) in your action." @@ -3396,7 +3402,7 @@ def get_types(self) -> Tuple[bool, bool, bool, bool, bool, bool, bool]: """ injection = "load_p" in self._dict_inj or "prod_p" in self._dict_inj voltage = "prod_v" in self._dict_inj - if self.shunts_data_available: + if type(self).shunts_data_available: voltage = voltage or np.isfinite(self.shunt_p).any() voltage = voltage or np.isfinite(self.shunt_q).any() voltage = voltage or (self.shunt_bus != 0).any() diff --git a/grid2op/Action/voltageOnlyAction.py b/grid2op/Action/voltageOnlyAction.py index 637d87871..996be38e9 100644 --- a/grid2op/Action/voltageOnlyAction.py +++ b/grid2op/Action/voltageOnlyAction.py @@ -40,7 +40,7 @@ def __init__(self): """ BaseAction.__init__(self) - if VoltageOnlyAction._shunt_added is False and self.shunts_data_available: + if VoltageOnlyAction._shunt_added is False and type(self).shunts_data_available: VoltageOnlyAction.attr_list_vect += ["shunt_p", "shunt_q", "shunt_bus"] VoltageOnlyAction.authorized_keys.add("shunt") VoltageOnlyAction._shunt_added = True @@ -61,7 +61,7 @@ def _check_dict(self): """ if self._dict_inj: for el in self._dict_inj: - if el not in self.attr_list_vect: + if el not in type(self).attr_list_vect: raise AmbiguousAction( 'Impossible to modify something different than "prod_v" using ' '"VoltageOnlyAction" action.' diff --git a/grid2op/Backend/backend.py b/grid2op/Backend/backend.py index ba29e5e28..bf291aaf3 100644 --- a/grid2op/Backend/backend.py +++ b/grid2op/Backend/backend.py @@ -25,17 +25,15 @@ from grid2op.dtypes import dt_int, dt_float, dt_bool from grid2op.Exceptions import ( EnvError, - DivergingPowerFlow, IncorrectNumberOfElements, IncorrectNumberOfLoads, -) -from grid2op.Exceptions import ( IncorrectNumberOfGenerators, BackendError, IncorrectNumberOfLines, + DivergingPowerflow, + Grid2OpException, ) from grid2op.Space import GridObjects -from grid2op.Exceptions import Grid2OpException # TODO method to get V and theta at each bus, could be in the same shape as check_kirchoff @@ -941,7 +939,7 @@ def _runpf_with_diverging_exception(self, is_dc : bool) -> Optional[Exception]: Raises ------ - exc_: :class:`grid2op.Exceptions.DivergingPowerFlow` + exc_: :class:`grid2op.Exceptions.DivergingPowerflow` In case of divergence of the powerflow """ @@ -952,13 +950,13 @@ def _runpf_with_diverging_exception(self, is_dc : bool) -> Optional[Exception]: except Grid2OpException as exc_: exc_me = exc_ except Exception as exc_: - exc_me = DivergingPowerFlow( + exc_me = DivergingPowerflow( f" An unexpected error occurred during the computation of the powerflow." f"The error is: \n {exc_} \n. This is game over" ) if not conv and exc_me is None: - exc_me = DivergingPowerFlow( + exc_me = DivergingPowerflow( "GAME OVER: Powerflow has diverged during computation " "or a load has been disconnected or a generator has been disconnected." ) @@ -1820,7 +1818,9 @@ def update_from_obs(self, sh_q[~shunt_co] = np.NaN dict_["shunt"]["shunt_p"] = sh_p dict_["shunt"]["shunt_q"] = sh_q - act.update(dict_) + elif type(self).shunts_data_available and not type(obs).shunts_data_available: + warnings.warn("Backend supports shunt but not the observation. This behaviour is non standard.") + act.update(dict_) backend_action += act self.apply_action(backend_action) @@ -1854,8 +1854,9 @@ def assert_grid_correct(self) -> None: ) # reset the attribute of the grid2op.Backend.Backend class # that can be messed up with depending on the initialization of the backend - Backend._clear_class_attribute() - orig_type._clear_class_attribute() + Backend._clear_class_attribute() # reset totally the grid2op Backend type + # orig_type._clear_class_attribute() + orig_type._clear_grid_dependant_class_attributes() # only reset the attributes that could be modified by user my_cls = type(self) my_cls.my_bk_act_class = _BackendAction.init_grid(my_cls) diff --git a/grid2op/Backend/pandaPowerBackend.py b/grid2op/Backend/pandaPowerBackend.py index a2a296eac..3dcef1d6c 100644 --- a/grid2op/Backend/pandaPowerBackend.py +++ b/grid2op/Backend/pandaPowerBackend.py @@ -107,7 +107,8 @@ class PandaPowerBackend(Backend): # and use "env" as "any open ai gym" environment. """ - + shunts_data_available = True + def __init__( self, detailed_infos_for_cascading_failures : bool=False, @@ -713,7 +714,7 @@ def _init_private_attrs(self) -> None: self._sh_vnkv = self._grid.bus["vn_kv"][self.shunt_to_subid].values.astype( dt_float ) - self.shunts_data_available = True + # self.shunts_data_available = True # TODO shunts_data_available # store the topoid -> objid self._big_topo_to_obj = [(None, None) for _ in range(self.dim_topo)] diff --git a/grid2op/Chronics/fromOneEpisodeData.py b/grid2op/Chronics/fromOneEpisodeData.py index 556736a09..46e155a09 100644 --- a/grid2op/Chronics/fromOneEpisodeData.py +++ b/grid2op/Chronics/fromOneEpisodeData.py @@ -137,10 +137,10 @@ class FromOneEpisodeData(GridValue): env = grid2op.make(env_name, chronics_class=FromOneEpisodeData, - data_feeding_kwargs={"ep_data": ep_data}, + data_feeding_kwargs={"ep_data": ep_data, + "list_perfect_forecasts": (5, 10, 15)}, opponent_class=FromEpisodeDataOpponent, opponent_attack_cooldown=1, - list_perfect_forecasts=(5, 10, 15) ) # it creates an environment with perfect forecasts available for the next step (5), # the step afterwards (10) and again the following one (15) @@ -327,7 +327,6 @@ def forecasts(self): """ if not self.list_perfect_forecasts: return [] - res = [] for h_id, h in enumerate(self.list_perfect_forecasts): res_d = {} @@ -342,6 +341,7 @@ def forecasts(self): def get_kwargs(self, dict_): dict_["ep_data"] = copy.deepcopy(self._episode_data) + # dict_["list_perfect_forecasts"] = copy.deepcopy(self.list_perfect_forecasts) return dict_ def get_id(self) -> str: diff --git a/grid2op/Chronics/gridStateFromFile.py b/grid2op/Chronics/gridStateFromFile.py index 19c7f3f83..1cc53a725 100644 --- a/grid2op/Chronics/gridStateFromFile.py +++ b/grid2op/Chronics/gridStateFromFile.py @@ -234,8 +234,6 @@ def _assert_correct(self, dict_convert, order_backend): lend_dict_values = len(vals) if len_dict_keys != len_backend: - import pdb - pdb.set_trace() err_msg = "Conversion mismatch between backend data {} elements and converter data {} (keys)" raise IncorrectNumberOfElements(err_msg.format(len_backend, len_dict_keys)) if lend_dict_values != len_backend: diff --git a/grid2op/Converter/BackendConverter.py b/grid2op/Converter/BackendConverter.py index f3ca3868d..44b381a23 100644 --- a/grid2op/Converter/BackendConverter.py +++ b/grid2op/Converter/BackendConverter.py @@ -268,12 +268,18 @@ def _init_myself(self): nm="storage", ) + if type(self.source_backend).shunts_data_available and not type(self.target_backend).shunts_data_available: + raise Grid2OpException("Source backend supports shunts and not target backend. This is not handled") + elif type(self.target_backend).shunts_data_available and not type(self.source_backend).shunts_data_available: + raise Grid2OpException("Target backend supports shunts and not source backend. This is not handled") + + # TODO shunts data available # shunt are available if both source and target provide it - self.shunts_data_available = ( - self.source_backend.shunts_data_available - and self.target_backend.shunts_data_available + type(self).shunts_data_available = ( + type(self.source_backend).shunts_data_available + and type(self.target_backend).shunts_data_available ) - if self.shunts_data_available: + if type(self).shunts_data_available: self._shunt_tg2sr = np.full(self.n_shunt, fill_value=-1, dtype=dt_int) self._shunt_sr2tg = np.full(self.n_shunt, fill_value=-1, dtype=dt_int) # automatic mode @@ -408,11 +414,17 @@ def assert_grid_correct(self): sr_cls.set_env_name(env_name) # handle specifc case of shunt data: - if not self.target_backend.shunts_data_available: + if not type(self.target_backend).shunts_data_available: + if type(self.source_backend).shunts_data_available: + raise Grid2OpException("Impossible to use a converter when one of the backend " + "supports shunt and the other not at the moment.") + # TODO shunts_data_available: you need ideally to create a different class + # for the backend that does not support it. + # disable the shunt data in grid2op. - self.source_backend.shunts_data_available = False - self.source_backend.n_shunt = None - self.source_backend.name_shunt = np.empty(0, dtype=str) + # type(self.source_backend).shunts_data_available = False + # type(self.source_backend).n_shunt = None + # type(self.source_backend).name_shunt = np.empty(0, dtype=str) self._init_class_attr(obj=self.source_backend) if self.path_redisp is not None: @@ -494,7 +506,7 @@ def assert_grid_correct(self): assert np.all(sorted(self._topo_tg2sr[topo_sr2tg_without_storage]) == target_without_storage) self._topo_sr2tg = topo_sr2tg_without_storage - if self.shunts_data_available: + if type(self).shunts_data_available: self._check_both_consistent(self._shunt_tg2sr, self._shunt_sr2tg) # finally check that powergrids are identical (up to the env name) @@ -716,7 +728,7 @@ def get_action_to_set(self): act._set_line_status[:] = act._set_line_status[line_vect] act._switch_line_status[:] = act._switch_line_status[line_vect] - if act.shunt_added and act.shunts_data_available: + if act.shunt_added and type(act).shunts_data_available: shunt_vect = self._shunt_sr2tg act.shunt_p[:] = act.shunt_p[shunt_vect] act.shunt_q[:] = act.shunt_q[shunt_vect] diff --git a/grid2op/Converter/IdToAct.py b/grid2op/Converter/IdToAct.py index 895d6f20d..c1ffd241b 100644 --- a/grid2op/Converter/IdToAct.py +++ b/grid2op/Converter/IdToAct.py @@ -11,7 +11,7 @@ from grid2op.Action import BaseAction from grid2op.Converter.Converters import Converter -from grid2op.Exceptions.Grid2OpException import Grid2OpException +from grid2op.Exceptions import Grid2OpException from grid2op.dtypes import dt_float, dt_int, int_types @@ -172,7 +172,8 @@ def init_converter(self, all_actions=None, **kwargs): self.all_actions = [] # add the do nothing action, always self.all_actions.append(super().__call__()) - if "_set_line_status" in self._template_act.attr_list_vect: + tmp_act_cls = type(self._template_act) + if "_set_line_status" in tmp_act_cls.attr_list_vect: # lines 'set' include_ = True if "set_line_status" in kwargs: @@ -180,7 +181,7 @@ def init_converter(self, all_actions=None, **kwargs): if include_: self.all_actions += self.get_all_unitary_line_set(self) - if "_switch_line_status" in self._template_act.attr_list_vect: + if "_switch_line_status" in tmp_act_cls.attr_list_vect: # lines 'change' include_ = True if "change_line_status" in kwargs: @@ -188,7 +189,7 @@ def init_converter(self, all_actions=None, **kwargs): if include_: self.all_actions += self.get_all_unitary_line_change(self) - if "_set_topo_vect" in self._template_act.attr_list_vect: + if "_set_topo_vect" in tmp_act_cls.attr_list_vect: # topologies 'set' include_ = True if "set_topo_vect" in kwargs: @@ -196,7 +197,7 @@ def init_converter(self, all_actions=None, **kwargs): if include_: self.all_actions += self.get_all_unitary_topologies_set(self) - if "_change_bus_vect" in self._template_act.attr_list_vect: + if "_change_bus_vect" in tmp_act_cls.attr_list_vect: # topologies 'change' include_ = True if "change_bus_vect" in kwargs: @@ -204,7 +205,7 @@ def init_converter(self, all_actions=None, **kwargs): if include_: self.all_actions += self.get_all_unitary_topologies_change(self) - if "_redispatch" in self._template_act.attr_list_vect: + if "_redispatch" in tmp_act_cls.attr_list_vect: # redispatch (transformed to discrete variables) include_ = True if "redispatch" in kwargs: @@ -212,7 +213,7 @@ def init_converter(self, all_actions=None, **kwargs): if include_: self.all_actions += self.get_all_unitary_redispatch(self) - if "_curtail" in self._template_act.attr_list_vect: + if "_curtail" in tmp_act_cls.attr_list_vect: # redispatch (transformed to discrete variables) include_ = True if "curtail" in kwargs: @@ -220,7 +221,7 @@ def init_converter(self, all_actions=None, **kwargs): if include_: self.all_actions += self.get_all_unitary_curtail(self) - if "_storage_power" in self._template_act.attr_list_vect: + if "_storage_power" in tmp_act_cls.attr_list_vect: # redispatch (transformed to discrete variables) include_ = True if "storage" in kwargs: diff --git a/grid2op/Environment/_obsEnv.py b/grid2op/Environment/_obsEnv.py index 421ba2490..347aaeaa9 100644 --- a/grid2op/Environment/_obsEnv.py +++ b/grid2op/Environment/_obsEnv.py @@ -9,7 +9,7 @@ import copy import numpy as np import warnings -from grid2op.Exceptions.EnvExceptions import EnvError +from grid2op.Exceptions.envExceptions import EnvError from grid2op.dtypes import dt_int, dt_float, dt_bool from grid2op.Environment.baseEnv import BaseEnv diff --git a/grid2op/Episode/EpisodeReboot.py b/grid2op/Episode/EpisodeReboot.py index 383ae2348..bda5218dd 100644 --- a/grid2op/Episode/EpisodeReboot.py +++ b/grid2op/Episode/EpisodeReboot.py @@ -302,7 +302,7 @@ def _update_bk_act_topo(self, obs): """update the "previous topological state" to the right value""" self.env._backend_action.current_topo.values[:] = obs.topo_vect self.env._backend_action.current_topo.changed[:] = True - if obs.shunts_data_available: + if type(obs).shunts_data_available: self.env._backend_action.shunt_bus.values[:] = obs._shunt_bus self.env._backend_action.shunt_bus.changed[:] = True # TODO previous update self.env._backend_action.last_topo_registered too ! diff --git a/grid2op/Exceptions/PowerflowExceptions.py b/grid2op/Exceptions/PowerflowExceptions.py deleted file mode 100644 index 6575037c4..000000000 --- a/grid2op/Exceptions/PowerflowExceptions.py +++ /dev/null @@ -1,27 +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. - -from grid2op.Exceptions.Grid2OpException import Grid2OpException - - -# powerflow exception -class DivergingPowerFlow(Grid2OpException): - """ - This exception indicate that the :class:`grid2op.Backend.Backend` is not able to find a valid solution to the - physical _grid it represents. - - This divergence can be due to: - - - the system is not feasible: there is no solution to Kirchhoff's law given the state - - the powergrid is not connex - - there is a "voltage collapse" : the voltages are ill conditioned making the _grid un realistic. - - the method to solve the powerflow fails to find a valid solution. In this case, adopting a different - :class:`grid2op.Backend.Backend` might solve the problem. - """ - - pass diff --git a/grid2op/Exceptions/__init__.py b/grid2op/Exceptions/__init__.py index 2fec308a1..f25ca1d26 100644 --- a/grid2op/Exceptions/__init__.py +++ b/grid2op/Exceptions/__init__.py @@ -38,7 +38,6 @@ "AmbiguousAction", "NonFiniteElement", "AmbiguousActionRaiseAlert", - "DivergingPowerFlow", "BaseObservationError", "NoForecastAvailable", "SimulateError", @@ -62,9 +61,9 @@ "HandlerError" ] -from grid2op.Exceptions.Grid2OpException import Grid2OpException +from grid2op.Exceptions.grid2OpException import Grid2OpException -from grid2op.Exceptions.EnvExceptions import (EnvError, +from grid2op.Exceptions.envExceptions import (EnvError, IncorrectNumberOfLoads, IncorrectNumberOfGenerators, IncorrectNumberOfLines, @@ -78,7 +77,7 @@ UnknownEnv, MultiEnvException) -from grid2op.Exceptions.IllegalActionExceptions import (IllegalAction, +from grid2op.Exceptions.illegalActionExceptions import (IllegalAction, OnProduction, VSetpointModified, ActiveSetPointAbovePmax, @@ -89,7 +88,7 @@ UnitCommitorRedispachingNotAvailable, ) -from grid2op.Exceptions.AmbiguousActionExceptions import (NotEnoughGenerators, +from grid2op.Exceptions.ambiguousActionExceptions import (NotEnoughGenerators, GeneratorTurnedOffTooSoon, GeneratorTurnedOnTooSoon, InvalidRedispatching, @@ -106,36 +105,36 @@ NonFiniteElement, AmbiguousActionRaiseAlert) -from grid2op.Exceptions.PowerflowExceptions import DivergingPowerFlow - -from grid2op.Exceptions.ObservationExceptions import (BaseObservationError, +from grid2op.Exceptions.observationExceptions import (BaseObservationError, NoForecastAvailable, SimulateError, SimulateUsedTooMuchThisStep, SimulateUsedTooMuchThisEpisode) -from grid2op.Exceptions.ChronicsExceptions import (ChronicsError, +from grid2op.Exceptions.chronicsExceptions import (ChronicsError, ChronicsNotFoundError, InsufficientData, ) from grid2op.Exceptions.handlers_exceptions import (HandlerError, ) -from grid2op.Exceptions.BackendExceptions import (BackendError, +from grid2op.Exceptions.backendExceptions import (BackendError, DivergingPowerflow, IslandedGrid, IsolatedElement, DisconnectedLoad, DisconnectedGenerator, ) +DivergingPowerFlow = DivergingPowerflow # for compatibility with lightsim2grid + -from grid2op.Exceptions.PlotExceptions import PlotError +from grid2op.Exceptions.plotExceptions import PlotError -from grid2op.Exceptions.OpponentError import OpponentError +from grid2op.Exceptions.opponentError import OpponentError -from grid2op.Exceptions.RunnerError import UsedRunnerError +from grid2op.Exceptions.runnerError import UsedRunnerError -from grid2op.Exceptions.AttentionBudgetExceptions import NotEnoughAttentionBudget +from grid2op.Exceptions.attentionBudgetExceptions import NotEnoughAttentionBudget from grid2op.Exceptions.agentError import AgentError diff --git a/grid2op/Exceptions/agentError.py b/grid2op/Exceptions/agentError.py index ac3afb2db..93f2f65b3 100644 --- a/grid2op/Exceptions/agentError.py +++ b/grid2op/Exceptions/agentError.py @@ -1,4 +1,12 @@ -from grid2op.Exceptions.Grid2OpException import Grid2OpException +# 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. + +from grid2op.Exceptions.grid2OpException import Grid2OpException # Exception Runner is used twice, not possible on windows / macos due to the way multiprocessing works diff --git a/grid2op/Exceptions/AmbiguousActionExceptions.py b/grid2op/Exceptions/ambiguousActionExceptions.py similarity index 98% rename from grid2op/Exceptions/AmbiguousActionExceptions.py rename to grid2op/Exceptions/ambiguousActionExceptions.py index 608881c61..119627e41 100644 --- a/grid2op/Exceptions/AmbiguousActionExceptions.py +++ b/grid2op/Exceptions/ambiguousActionExceptions.py @@ -6,7 +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 grid2op.Exceptions.Grid2OpException import Grid2OpException +from grid2op.Exceptions.grid2OpException import Grid2OpException # ambiguous action diff --git a/grid2op/Exceptions/AttentionBudgetExceptions.py b/grid2op/Exceptions/attentionBudgetExceptions.py similarity index 91% rename from grid2op/Exceptions/AttentionBudgetExceptions.py rename to grid2op/Exceptions/attentionBudgetExceptions.py index 5f442a2bb..e4d4563e8 100644 --- a/grid2op/Exceptions/AttentionBudgetExceptions.py +++ b/grid2op/Exceptions/attentionBudgetExceptions.py @@ -6,7 +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 grid2op.Exceptions.Grid2OpException import Grid2OpException +from grid2op.Exceptions.grid2OpException import Grid2OpException class NotEnoughAttentionBudget(Grid2OpException): diff --git a/grid2op/Exceptions/BackendExceptions.py b/grid2op/Exceptions/backendExceptions.py similarity index 63% rename from grid2op/Exceptions/BackendExceptions.py rename to grid2op/Exceptions/backendExceptions.py index d980de4ff..297c63d69 100644 --- a/grid2op/Exceptions/BackendExceptions.py +++ b/grid2op/Exceptions/backendExceptions.py @@ -6,7 +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 grid2op.Exceptions.Grid2OpException import Grid2OpException +from grid2op.Exceptions.grid2OpException import Grid2OpException # Backend @@ -19,7 +19,17 @@ class BackendError(Grid2OpException): class DivergingPowerflow(BackendError): - """Specific error that should be raised when the powerflow diverges + """ + This exception indicate that the :class:`grid2op.Backend.Backend` is not able to find a valid solution to the + physical _grid it represents. + + This divergence can be due to: + + - the system is not feasible: there is no solution to Kirchhoff's law given the state + - the powergrid is not connected and some area of the grid do not have slack buses + - there is a "voltage collapse" : the voltages are ill conditioned making the _grid un realistic. + - the method to solve the powerflow fails to find a valid solution. In this case, adopting a different + :class:`grid2op.Backend.Backend` might solve the problem. """ pass diff --git a/grid2op/Exceptions/ChronicsExceptions.py b/grid2op/Exceptions/chronicsExceptions.py similarity index 94% rename from grid2op/Exceptions/ChronicsExceptions.py rename to grid2op/Exceptions/chronicsExceptions.py index c6a92cdd0..8574c273a 100644 --- a/grid2op/Exceptions/ChronicsExceptions.py +++ b/grid2op/Exceptions/chronicsExceptions.py @@ -6,7 +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 grid2op.Exceptions.Grid2OpException import Grid2OpException +from grid2op.Exceptions.grid2OpException import Grid2OpException # Chronics diff --git a/grid2op/Exceptions/EnvExceptions.py b/grid2op/Exceptions/envExceptions.py similarity index 98% rename from grid2op/Exceptions/EnvExceptions.py rename to grid2op/Exceptions/envExceptions.py index 08ebf0ef3..33d3f9b30 100644 --- a/grid2op/Exceptions/EnvExceptions.py +++ b/grid2op/Exceptions/envExceptions.py @@ -6,7 +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 grid2op.Exceptions.Grid2OpException import Grid2OpException +from grid2op.Exceptions.grid2OpException import Grid2OpException # Exception bad environment configured diff --git a/grid2op/Exceptions/Grid2OpException.py b/grid2op/Exceptions/grid2OpException.py similarity index 100% rename from grid2op/Exceptions/Grid2OpException.py rename to grid2op/Exceptions/grid2OpException.py diff --git a/grid2op/Exceptions/handlers_exceptions.py b/grid2op/Exceptions/handlers_exceptions.py index c4278f647..57f65d3eb 100644 --- a/grid2op/Exceptions/handlers_exceptions.py +++ b/grid2op/Exceptions/handlers_exceptions.py @@ -6,7 +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 grid2op.Exceptions.ChronicsExceptions import ChronicsError +from grid2op.Exceptions.chronicsExceptions import ChronicsError class HandlerError(ChronicsError): diff --git a/grid2op/Exceptions/IllegalActionExceptions.py b/grid2op/Exceptions/illegalActionExceptions.py similarity index 97% rename from grid2op/Exceptions/IllegalActionExceptions.py rename to grid2op/Exceptions/illegalActionExceptions.py index 84331fe27..d303152d7 100644 --- a/grid2op/Exceptions/IllegalActionExceptions.py +++ b/grid2op/Exceptions/illegalActionExceptions.py @@ -6,7 +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 grid2op.Exceptions.Grid2OpException import Grid2OpException +from grid2op.Exceptions.grid2OpException import Grid2OpException # exception bad actions diff --git a/grid2op/Exceptions/ObservationExceptions.py b/grid2op/Exceptions/observationExceptions.py similarity index 97% rename from grid2op/Exceptions/ObservationExceptions.py rename to grid2op/Exceptions/observationExceptions.py index b7ef3817a..c5b954219 100644 --- a/grid2op/Exceptions/ObservationExceptions.py +++ b/grid2op/Exceptions/observationExceptions.py @@ -6,7 +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 grid2op.Exceptions.Grid2OpException import Grid2OpException +from grid2op.Exceptions.grid2OpException import Grid2OpException class BaseObservationError(Grid2OpException): diff --git a/grid2op/Exceptions/OpponentError.py b/grid2op/Exceptions/opponentError.py similarity index 89% rename from grid2op/Exceptions/OpponentError.py rename to grid2op/Exceptions/opponentError.py index c904e76c3..623d66179 100644 --- a/grid2op/Exceptions/OpponentError.py +++ b/grid2op/Exceptions/opponentError.py @@ -6,7 +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 grid2op.Exceptions.Grid2OpException import Grid2OpException +from grid2op.Exceptions.grid2OpException import Grid2OpException class OpponentError(Grid2OpException): diff --git a/grid2op/Exceptions/PlotExceptions.py b/grid2op/Exceptions/plotExceptions.py similarity index 91% rename from grid2op/Exceptions/PlotExceptions.py rename to grid2op/Exceptions/plotExceptions.py index c81380ec6..885f0192b 100644 --- a/grid2op/Exceptions/PlotExceptions.py +++ b/grid2op/Exceptions/plotExceptions.py @@ -6,7 +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 grid2op.Exceptions.Grid2OpException import Grid2OpException +from grid2op.Exceptions.grid2OpException import Grid2OpException # plot error diff --git a/grid2op/Exceptions/RunnerError.py b/grid2op/Exceptions/runnerError.py similarity index 94% rename from grid2op/Exceptions/RunnerError.py rename to grid2op/Exceptions/runnerError.py index 5663a075a..0cfb0df6e 100644 --- a/grid2op/Exceptions/RunnerError.py +++ b/grid2op/Exceptions/runnerError.py @@ -6,7 +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 grid2op.Exceptions.Grid2OpException import Grid2OpException +from grid2op.Exceptions.grid2OpException import Grid2OpException # Exception Runner is used twice, not possible on windows / macos due to the way multiprocessing works diff --git a/grid2op/Exceptions/simulatorExceptions.py b/grid2op/Exceptions/simulatorExceptions.py index 5f88366d8..c750c994d 100644 --- a/grid2op/Exceptions/simulatorExceptions.py +++ b/grid2op/Exceptions/simulatorExceptions.py @@ -6,7 +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 grid2op.Exceptions.Grid2OpException import Grid2OpException +from grid2op.Exceptions.grid2OpException import Grid2OpException class SimulatorError(Grid2OpException): diff --git a/grid2op/Observation/baseObservation.py b/grid2op/Observation/baseObservation.py index ca913485f..1c0a259fa 100644 --- a/grid2op/Observation/baseObservation.py +++ b/grid2op/Observation/baseObservation.py @@ -583,7 +583,7 @@ def __init__(self, self._vectorized = None # for shunt (these are not stored!) - if self.shunts_data_available: + if type(self).shunts_data_available: self._shunt_p = np.empty(shape=self.n_shunt, dtype=dt_float) self._shunt_q = np.empty(shape=self.n_shunt, dtype=dt_float) self._shunt_v = np.empty(shape=self.n_shunt, dtype=dt_float) @@ -680,7 +680,7 @@ def _aux_copy(self, other): "curtailment_limit_effective", ] - if self.shunts_data_available: + if type(self).shunts_data_available: attr_vect += ["_shunt_bus", "_shunt_v", "_shunt_q", "_shunt_p"] for attr_nm in attr_simple: @@ -1144,6 +1144,12 @@ def process_grid2op_compat(cls): pass cls.attr_list_set = set(cls.attr_list_vect) + def shape(self): + return type(self).shapes() + + def dtype(self): + return type(self).dtypes() + def reset(self): """ INTERNAL @@ -1220,7 +1226,7 @@ def reset(self): self._connectivity_matrix_ = None self._bus_connectivity_matrix_ = None - if self.shunts_data_available: + if type(self).shunts_data_available: self._shunt_p[:] = np.NaN self._shunt_q[:] = np.NaN self._shunt_v[:] = np.NaN @@ -1324,7 +1330,7 @@ def set_game_over(self, env=None): # overflow self.timestep_overflow[:] = 0 - if self.shunts_data_available: + if type(self).shunts_data_available: self._shunt_p[:] = 0.0 self._shunt_q[:] = 0.0 self._shunt_v[:] = 0.0 @@ -1989,7 +1995,7 @@ def flow_bus_matrix(self, active_flow=True, as_csr_matrix=False): self.line_ex_pos_topo_vect, self.line_ex_to_subid ) - if self.shunts_data_available: + if type(self).shunts_data_available: sh_bus = 1 * self._shunt_bus sh_bus[sh_bus > 0] = ( self.shunt_to_subid[sh_bus > 0] * (sh_bus[sh_bus > 0] - 1) @@ -2013,7 +2019,7 @@ def flow_bus_matrix(self, active_flow=True, as_csr_matrix=False): or_vect = self.p_or ex_vect = self.p_ex stor_vect = self.storage_power - if self.shunts_data_available: + if type(self).shunts_data_available: sh_vect = self._shunt_p else: prod_vect = self.gen_q @@ -2021,7 +2027,7 @@ def flow_bus_matrix(self, active_flow=True, as_csr_matrix=False): or_vect = self.q_or ex_vect = self.q_ex stor_vect = np.zeros(self.n_storage, dtype=dt_float) - if self.shunts_data_available: + if type(self).shunts_data_available: sh_vect = self._shunt_q nb_lor = lor_conn.sum() @@ -2062,7 +2068,7 @@ def flow_bus_matrix(self, active_flow=True, as_csr_matrix=False): ) data[bus_stor] -= map_mat.dot(stor_vect[stor_conn]) - if self.shunts_data_available: + if type(self).shunts_data_available: # handle shunts nb_shunt = sh_conn.sum() if nb_shunt: @@ -3873,7 +3879,7 @@ def _update_attr_backend(self, backend): self.gen_margin_down[:] = 0.0 # handle shunts (if avaialble) - if self.shunts_data_available: + if type(self).shunts_data_available: sh_p, sh_q, sh_v, sh_bus = backend.shunt_info() self._shunt_p[:] = sh_p self._shunt_q[:] = sh_q diff --git a/grid2op/Observation/observationSpace.py b/grid2op/Observation/observationSpace.py index 9e64ca48b..add75c631 100644 --- a/grid2op/Observation/observationSpace.py +++ b/grid2op/Observation/observationSpace.py @@ -10,7 +10,7 @@ import copy import logging import os -from grid2op.Exceptions.EnvExceptions import EnvError +from grid2op.Exceptions.envExceptions import EnvError from grid2op.Observation.serializableObservationSpace import ( SerializableObservationSpace, diff --git a/grid2op/Plot/EpisodeReplay.py b/grid2op/Plot/EpisodeReplay.py index fca8e5f82..77d20d1bd 100644 --- a/grid2op/Plot/EpisodeReplay.py +++ b/grid2op/Plot/EpisodeReplay.py @@ -14,7 +14,7 @@ from grid2op.Episode import EpisodeData from grid2op.Exceptions import Grid2OpException from grid2op.Plot.PlotPyGame import PlotPyGame -from grid2op.Exceptions.PlotExceptions import PyGameQuit +from grid2op.Exceptions.plotExceptions import PyGameQuit try: os.environ["PYGAME_HIDE_SUPPORT_PROMPT"] = "hide" diff --git a/grid2op/Plot/PlotPyGame.py b/grid2op/Plot/PlotPyGame.py index 2d8fd2788..a58396337 100644 --- a/grid2op/Plot/PlotPyGame.py +++ b/grid2op/Plot/PlotPyGame.py @@ -22,7 +22,7 @@ import time from grid2op.Plot.BasePlot import BasePlot -from grid2op.Exceptions.PlotExceptions import PyGameQuit, PlotError +from grid2op.Exceptions.plotExceptions import PyGameQuit, PlotError try: os.environ["PYGAME_HIDE_SUPPORT_PROMPT"] = "hide" diff --git a/grid2op/Plot/Plotting.py b/grid2op/Plot/Plotting.py index 6b795ac21..0bf05b490 100644 --- a/grid2op/Plot/Plotting.py +++ b/grid2op/Plot/Plotting.py @@ -11,7 +11,7 @@ from grid2op.Plot.PlotMatplotlib import PlotMatplotlib from grid2op.Plot.PlotPyGame import PlotPyGame -from grid2op.Exceptions.PlotExceptions import PyGameQuit +from grid2op.Exceptions.plotExceptions import PyGameQuit class Plotting: diff --git a/grid2op/Plot/__init__.py b/grid2op/Plot/__init__.py index 6471a313e..220bc2883 100644 --- a/grid2op/Plot/__init__.py +++ b/grid2op/Plot/__init__.py @@ -4,7 +4,7 @@ "PlotPlotly", "PlotPyGame", "Plotting", - "EpisodeReplay", + # "EpisodeReplay", ] from grid2op.Plot.BasePlot import BasePlot @@ -12,7 +12,7 @@ from grid2op.Plot.PlotPlotly import PlotPlotly from grid2op.Plot.PlotPyGame import PlotPyGame from grid2op.Plot.Plotting import Plotting -from grid2op.Plot.EpisodeReplay import EpisodeReplay +# from grid2op.Plot.EpisodeReplay import EpisodeReplay import warnings diff --git a/grid2op/Reward/baseReward.py b/grid2op/Reward/baseReward.py index 2f9dec6dd..ab54b56a6 100644 --- a/grid2op/Reward/baseReward.py +++ b/grid2op/Reward/baseReward.py @@ -176,7 +176,7 @@ def __call__(self, action, env, has_error, is_done, is_illegal, is_ambiguous): An environment instance properly initialized. has_error: ``bool`` - Has there been an error, for example a :class:`grid2op.DivergingPowerFlow` be thrown when the action has + Has there been an error, for example a :class:`grid2op.DivergingPowerflow` be thrown when the action has been implemented in the environment. is_done: ``bool`` diff --git a/grid2op/Space/GridObjects.py b/grid2op/Space/GridObjects.py index abf08bddc..16edd30bb 100644 --- a/grid2op/Space/GridObjects.py +++ b/grid2op/Space/GridObjects.py @@ -654,6 +654,43 @@ def tell_dim_alert(cls, dim_alerts): @classmethod def _clear_class_attribute(cls): + cls.shunts_data_available = False + + # for redispatching / unit commitment + cls._li_attr_disp = [ + "gen_type", + "gen_pmin", + "gen_pmax", + "gen_redispatchable", + "gen_max_ramp_up", + "gen_max_ramp_down", + "gen_min_uptime", + "gen_min_downtime", + "gen_cost_per_MW", + "gen_startup_cost", + "gen_shutdown_cost", + "gen_renewable", + ] + + cls._type_attr_disp = [ + str, + float, + float, + bool, + float, + float, + int, + int, + float, + float, + float, + bool, + ] + + cls._clear_grid_dependant_class_attributes() + + @classmethod + def _clear_grid_dependant_class_attributes(cls): cls.glop_version = grid2op.__version__ cls._PATH_ENV = None @@ -718,37 +755,6 @@ def _clear_class_attribute(cls): # list of attribute to convert it from/to a vector cls._vectorized = None - # for redispatching / unit commitment - cls._li_attr_disp = [ - "gen_type", - "gen_pmin", - "gen_pmax", - "gen_redispatchable", - "gen_max_ramp_up", - "gen_max_ramp_down", - "gen_min_uptime", - "gen_min_downtime", - "gen_cost_per_MW", - "gen_startup_cost", - "gen_shutdown_cost", - "gen_renewable", - ] - - cls._type_attr_disp = [ - str, - float, - float, - bool, - float, - float, - int, - int, - float, - float, - float, - bool, - ] - # redispatch data, not available in all environment cls.redispatching_unit_commitment_availble = False cls.gen_type = None @@ -779,7 +785,6 @@ def _clear_class_attribute(cls): cls.grid_layout = None # shunt data, not available in every backend - cls.shunts_data_available = False cls.n_shunt = None cls.name_shunt = None cls.shunt_to_subid = None @@ -825,7 +830,7 @@ def _raise_error_attr_list_none(self): ``NotImplementedError`` """ - if self.attr_list_vect is None: + if type(self).attr_list_vect is None: raise IncorrectNumberOfElements( "attr_list_vect attribute is not defined for class {}. " "It is not possible to convert it from/to a vector, " @@ -894,7 +899,7 @@ def to_vect(self): self._raise_error_attr_list_none() li_vect = [ self._get_array_from_attr_name(el).astype(dt_float) - for el in self.attr_list_vect + for el in type(self).attr_list_vect ] if li_vect: self._vectorized = np.concatenate(li_vect) @@ -952,7 +957,7 @@ def from_json(self, dict_): """ # TODO optimization for action or observation, to reduce json size, for example using the see `to_json` - all_keys = self.attr_list_vect + self.attr_list_json + all_keys = type(self).attr_list_vect + type(self).attr_list_json for key, array_ in dict_.items(): if key not in all_keys: raise AmbiguousAction(f'Impossible to recognize the key "{key}"') @@ -984,7 +989,7 @@ def _convert_to_json(cls, dict_): elif dtype == bool: dict_[attr_nm] = [bool(el) for el in tmp] - def shape(self): + def shapes(self): """ The shapes of all the components of the action, mainly used for gym compatibility is the shape of all part of the action. @@ -1026,11 +1031,11 @@ def shape(self): """ self._raise_error_attr_list_none() res = np.array( - [self._get_array_from_attr_name(el).shape[0] for el in self.attr_list_vect] + [self._get_array_from_attr_name(el).shape[0] for el in type(self).attr_list_vect] ).astype(dt_int) return res - def dtype(self): + def dtypes(self): """ The types of the components of the GridObjects, mainly used for gym compatibility is the shape of all part of the action. @@ -1071,7 +1076,7 @@ def dtype(self): self._raise_error_attr_list_none() res = np.array( - [self._get_array_from_attr_name(el).dtype for el in self.attr_list_vect] + [self._get_array_from_attr_name(el).dtype for el in type(self).attr_list_vect] ) return res @@ -1168,7 +1173,7 @@ def from_vect(self, vect, check_legit=True): self._raise_error_attr_list_none() prev_ = 0 - for attr_nm, sh, dt in zip(self.attr_list_vect, self.shape(), self.dtype()): + for attr_nm, sh, dt in zip(type(self).attr_list_vect, self.shapes(), self.dtypes()): tmp = vect[prev_ : (prev_ + sh)] # TODO a flag that says "default Nan" for example for when attributes are initialized with @@ -1243,7 +1248,7 @@ def size(self): print("The size of the action space is {}".format(env.action_space.size())) """ - res = self.shape().sum(dtype=dt_int) + res = self.shapes().sum(dtype=dt_int) return res @classmethod @@ -1271,7 +1276,7 @@ def _aux_pos_big_topo(cls, vect_to_subid, vect_to_sub_pos): return res def _init_class_attr(self, obj=None): - """init the class attribute from an instance of the class + """Init the class attribute from an instance of the class THIS IS NOT A CLASS ATTR @@ -2721,7 +2726,7 @@ def init_grid(cls, gridobj, force=False, extra_name=None, force_module=None): my_class = GridObjects._build_cls_from_import(name_res, gridobj._PATH_ENV) if my_class is not None: return my_class - + if not gridobj.shunts_data_available: # if you import env for backend # with shunt and without shunt, then @@ -4404,7 +4409,7 @@ class {cls.__name__}({cls._INIT_GRID_CLS.__name__}): grid_layout = {grid_layout_str} # shunt data, not available in every backend - shunts_data_available = {"True" if cls.redispatching_unit_commitment_availble else "False"} + shunts_data_available = {"True" if cls.shunts_data_available else "False"} n_shunt = {cls.n_shunt} name_shunt = np.array([{name_shunt_str}]) shunt_to_subid = {shunt_to_subid_str} diff --git a/grid2op/Space/SerializableSpace.py b/grid2op/Space/SerializableSpace.py index 6beaa5e7f..7aa514a69 100644 --- a/grid2op/Space/SerializableSpace.py +++ b/grid2op/Space/SerializableSpace.py @@ -111,9 +111,9 @@ def __init__(self, gridobj, subtype=object, _init_grid=True): self.global_vars = None - self.shape = self._template_obj.shape() - self.dtype = self._template_obj.dtype() - self.attr_list_vect = copy.deepcopy(self._template_obj.attr_list_vect) + self._shape = self._template_obj.shapes() + self._dtype = self._template_obj.dtypes() + self.attr_list_vect = copy.deepcopy(type(self._template_obj).attr_list_vect) self._to_extract_vect = {} # key: attr name, value: tuple: (beg_, end_, dtype) beg_ = 0 @@ -123,6 +123,14 @@ def __init__(self, gridobj, subtype=object, _init_grid=True): self._to_extract_vect[attr] = (beg_, end_, dtype_) beg_ += size + @property + def shape(self): + return self._shape + + @property + def dtype(self): + return self._dtype + def _custom_deepcopy_for_copy(self, new_obj): RandomObject._custom_deepcopy_for_copy(self, new_obj) @@ -132,10 +140,10 @@ def _custom_deepcopy_for_copy(self, new_obj): new_obj._template_obj = self._template_obj.copy() new_obj.n = self.n new_obj.global_vars = copy.deepcopy(self.global_vars) - new_obj.shape = copy.deepcopy(self.shape) - new_obj.dtype = copy.deepcopy(self.dtype) - new_obj.attr_list_vect = copy.deepcopy(self.attr_list_vect) - new_obj._to_extract_vect = copy.deepcopy(self._to_extract_vect) + new_obj._shape = copy.deepcopy(self._shape) + new_obj._dtype = copy.deepcopy(self._dtype) + new_obj.attr_list_vect = copy.deepcopy(self.attr_list_vect) # TODO is this necessary, that's class attribute I think + new_obj._to_extract_vect = copy.deepcopy(self._to_extract_vect) # TODO is this necessary, that's class attribute I think @staticmethod def from_dict(dict_): diff --git a/grid2op/__init__.py b/grid2op/__init__.py index ac42f79b0..bd891c039 100644 --- a/grid2op/__init__.py +++ b/grid2op/__init__.py @@ -11,7 +11,7 @@ Grid2Op """ -__version__ = '1.9.5' +__version__ = '1.9.8.dev0' __all__ = [ "Action", diff --git a/grid2op/data_test/runner_data/res_agent_1.9.6/00/_parameters.json b/grid2op/data_test/runner_data/res_agent_1.9.6/00/_parameters.json new file mode 100644 index 000000000..ce75edee3 --- /dev/null +++ b/grid2op/data_test/runner_data/res_agent_1.9.6/00/_parameters.json @@ -0,0 +1,23 @@ +{ + "ACTIVATE_STORAGE_LOSS": true, + "ALARM_BEST_TIME": 12, + "ALARM_WINDOW_SIZE": 12, + "ALERT_TIME_WINDOW": 12, + "ALLOW_DISPATCH_GEN_SWITCH_OFF": true, + "ENV_DC": false, + "FORECAST_DC": false, + "HARD_OVERFLOW_THRESHOLD": 2.0, + "IGNORE_MIN_UP_DOWN_TIME": true, + "INIT_STORAGE_CAPACITY": 0.5, + "LIMIT_INFEASIBLE_CURTAILMENT_STORAGE_ACTION": false, + "MAX_LINE_STATUS_CHANGED": 1, + "MAX_SIMULATE_PER_EPISODE": -1, + "MAX_SIMULATE_PER_STEP": -1, + "MAX_SUB_CHANGED": 1, + "NB_TIMESTEP_COOLDOWN_LINE": 0, + "NB_TIMESTEP_COOLDOWN_SUB": 0, + "NB_TIMESTEP_OVERFLOW_ALLOWED": 2, + "NB_TIMESTEP_RECONNECTION": 10, + "NO_OVERFLOW_DISCONNECTION": false, + "SOFT_OVERFLOW_THRESHOLD": 1.0 +} \ No newline at end of file diff --git a/grid2op/data_test/runner_data/res_agent_1.9.6/00/actions.npz b/grid2op/data_test/runner_data/res_agent_1.9.6/00/actions.npz new file mode 100644 index 000000000..767abd9ad Binary files /dev/null and b/grid2op/data_test/runner_data/res_agent_1.9.6/00/actions.npz differ diff --git a/grid2op/data_test/runner_data/res_agent_1.9.6/00/agent_exec_times.npz b/grid2op/data_test/runner_data/res_agent_1.9.6/00/agent_exec_times.npz new file mode 100644 index 000000000..4dab106f0 Binary files /dev/null and b/grid2op/data_test/runner_data/res_agent_1.9.6/00/agent_exec_times.npz differ diff --git a/grid2op/data_test/runner_data/res_agent_1.9.6/00/disc_lines_cascading_failure.npz b/grid2op/data_test/runner_data/res_agent_1.9.6/00/disc_lines_cascading_failure.npz new file mode 100644 index 000000000..298421483 Binary files /dev/null and b/grid2op/data_test/runner_data/res_agent_1.9.6/00/disc_lines_cascading_failure.npz differ diff --git a/grid2op/data_test/runner_data/res_agent_1.9.6/00/env_modifications.npz b/grid2op/data_test/runner_data/res_agent_1.9.6/00/env_modifications.npz new file mode 100644 index 000000000..6e06d3e28 Binary files /dev/null and b/grid2op/data_test/runner_data/res_agent_1.9.6/00/env_modifications.npz differ diff --git a/grid2op/data_test/runner_data/res_agent_1.9.6/00/episode_meta.json b/grid2op/data_test/runner_data/res_agent_1.9.6/00/episode_meta.json new file mode 100644 index 000000000..7223c9436 --- /dev/null +++ b/grid2op/data_test/runner_data/res_agent_1.9.6/00/episode_meta.json @@ -0,0 +1,11 @@ +{ + "agent_seed": null, + "backend_type": "PandaPowerBackend_rte_case5_example", + "chronics_max_timestep": "100", + "chronics_path": "/home/donnotben/Documents/grid2op_dev/grid2op/data/rte_case5_example/chronics/00", + "cumulative_reward": 9.161613464355469, + "env_seed": null, + "env_type": "Environment_rte_case5_example", + "grid_path": "/home/donnotben/Documents/grid2op_dev/grid2op/data/rte_case5_example/grid.json", + "nb_timestep_played": 3 +} \ No newline at end of file diff --git a/grid2op/data_test/runner_data/res_agent_1.9.6/00/episode_times.json b/grid2op/data_test/runner_data/res_agent_1.9.6/00/episode_times.json new file mode 100644 index 000000000..a80346de4 --- /dev/null +++ b/grid2op/data_test/runner_data/res_agent_1.9.6/00/episode_times.json @@ -0,0 +1,12 @@ +{ + "Agent": { + "total": 8.197699935408309e-05 + }, + "Env": { + "apply_act": 0.014833036995696602, + "observation_computation": 0.002485878998413682, + "powerflow_computation": 0.06346367900550831, + "total": 0.0807825949996186 + }, + "total": 0.08239645399953588 +} \ No newline at end of file diff --git a/grid2op/data_test/runner_data/res_agent_1.9.6/00/grid2op.info b/grid2op/data_test/runner_data/res_agent_1.9.6/00/grid2op.info new file mode 100644 index 000000000..4889892d4 --- /dev/null +++ b/grid2op/data_test/runner_data/res_agent_1.9.6/00/grid2op.info @@ -0,0 +1,3 @@ +{ + "version": "1.9.6" +} \ No newline at end of file diff --git a/grid2op/data_test/runner_data/res_agent_1.9.6/00/observations.npz b/grid2op/data_test/runner_data/res_agent_1.9.6/00/observations.npz new file mode 100644 index 000000000..3cb5dd4a1 Binary files /dev/null and b/grid2op/data_test/runner_data/res_agent_1.9.6/00/observations.npz differ diff --git a/grid2op/data_test/runner_data/res_agent_1.9.6/00/opponent_attack.npz b/grid2op/data_test/runner_data/res_agent_1.9.6/00/opponent_attack.npz new file mode 100644 index 000000000..e05f26912 Binary files /dev/null and b/grid2op/data_test/runner_data/res_agent_1.9.6/00/opponent_attack.npz differ diff --git a/grid2op/data_test/runner_data/res_agent_1.9.6/00/other_rewards.json b/grid2op/data_test/runner_data/res_agent_1.9.6/00/other_rewards.json new file mode 100644 index 000000000..ca609c0c6 --- /dev/null +++ b/grid2op/data_test/runner_data/res_agent_1.9.6/00/other_rewards.json @@ -0,0 +1,5 @@ +[ + {}, + {}, + {} +] \ No newline at end of file diff --git a/grid2op/data_test/runner_data/res_agent_1.9.6/00/rewards.npz b/grid2op/data_test/runner_data/res_agent_1.9.6/00/rewards.npz new file mode 100644 index 000000000..9e7ce99c6 Binary files /dev/null and b/grid2op/data_test/runner_data/res_agent_1.9.6/00/rewards.npz differ diff --git a/grid2op/data_test/runner_data/res_agent_1.9.6/01/_parameters.json b/grid2op/data_test/runner_data/res_agent_1.9.6/01/_parameters.json new file mode 100644 index 000000000..ce75edee3 --- /dev/null +++ b/grid2op/data_test/runner_data/res_agent_1.9.6/01/_parameters.json @@ -0,0 +1,23 @@ +{ + "ACTIVATE_STORAGE_LOSS": true, + "ALARM_BEST_TIME": 12, + "ALARM_WINDOW_SIZE": 12, + "ALERT_TIME_WINDOW": 12, + "ALLOW_DISPATCH_GEN_SWITCH_OFF": true, + "ENV_DC": false, + "FORECAST_DC": false, + "HARD_OVERFLOW_THRESHOLD": 2.0, + "IGNORE_MIN_UP_DOWN_TIME": true, + "INIT_STORAGE_CAPACITY": 0.5, + "LIMIT_INFEASIBLE_CURTAILMENT_STORAGE_ACTION": false, + "MAX_LINE_STATUS_CHANGED": 1, + "MAX_SIMULATE_PER_EPISODE": -1, + "MAX_SIMULATE_PER_STEP": -1, + "MAX_SUB_CHANGED": 1, + "NB_TIMESTEP_COOLDOWN_LINE": 0, + "NB_TIMESTEP_COOLDOWN_SUB": 0, + "NB_TIMESTEP_OVERFLOW_ALLOWED": 2, + "NB_TIMESTEP_RECONNECTION": 10, + "NO_OVERFLOW_DISCONNECTION": false, + "SOFT_OVERFLOW_THRESHOLD": 1.0 +} \ No newline at end of file diff --git a/grid2op/data_test/runner_data/res_agent_1.9.6/01/actions.npz b/grid2op/data_test/runner_data/res_agent_1.9.6/01/actions.npz new file mode 100644 index 000000000..aa023834c Binary files /dev/null and b/grid2op/data_test/runner_data/res_agent_1.9.6/01/actions.npz differ diff --git a/grid2op/data_test/runner_data/res_agent_1.9.6/01/agent_exec_times.npz b/grid2op/data_test/runner_data/res_agent_1.9.6/01/agent_exec_times.npz new file mode 100644 index 000000000..b76b3c8a9 Binary files /dev/null and b/grid2op/data_test/runner_data/res_agent_1.9.6/01/agent_exec_times.npz differ diff --git a/grid2op/data_test/runner_data/res_agent_1.9.6/01/disc_lines_cascading_failure.npz b/grid2op/data_test/runner_data/res_agent_1.9.6/01/disc_lines_cascading_failure.npz new file mode 100644 index 000000000..714f93b4d Binary files /dev/null and b/grid2op/data_test/runner_data/res_agent_1.9.6/01/disc_lines_cascading_failure.npz differ diff --git a/grid2op/data_test/runner_data/res_agent_1.9.6/01/env_modifications.npz b/grid2op/data_test/runner_data/res_agent_1.9.6/01/env_modifications.npz new file mode 100644 index 000000000..92e0ead30 Binary files /dev/null and b/grid2op/data_test/runner_data/res_agent_1.9.6/01/env_modifications.npz differ diff --git a/grid2op/data_test/runner_data/res_agent_1.9.6/01/episode_meta.json b/grid2op/data_test/runner_data/res_agent_1.9.6/01/episode_meta.json new file mode 100644 index 000000000..e66c193de --- /dev/null +++ b/grid2op/data_test/runner_data/res_agent_1.9.6/01/episode_meta.json @@ -0,0 +1,11 @@ +{ + "agent_seed": null, + "backend_type": "PandaPowerBackend_rte_case5_example", + "chronics_max_timestep": "100", + "chronics_path": "/home/donnotben/Documents/grid2op_dev/grid2op/data/rte_case5_example/chronics/01", + "cumulative_reward": 20.21123504638672, + "env_seed": null, + "env_type": "Environment_rte_case5_example", + "grid_path": "/home/donnotben/Documents/grid2op_dev/grid2op/data/rte_case5_example/grid.json", + "nb_timestep_played": 5 +} \ No newline at end of file diff --git a/grid2op/data_test/runner_data/res_agent_1.9.6/01/episode_times.json b/grid2op/data_test/runner_data/res_agent_1.9.6/01/episode_times.json new file mode 100644 index 000000000..05f3f91a6 --- /dev/null +++ b/grid2op/data_test/runner_data/res_agent_1.9.6/01/episode_times.json @@ -0,0 +1,12 @@ +{ + "Agent": { + "total": 0.00018192499919678085 + }, + "Env": { + "apply_act": 0.03575586100487271, + "observation_computation": 0.005782992000604281, + "powerflow_computation": 0.15825524700267124, + "total": 0.19979410000814823 + }, + "total": 0.20350440100082778 +} \ No newline at end of file diff --git a/grid2op/data_test/runner_data/res_agent_1.9.6/01/grid2op.info b/grid2op/data_test/runner_data/res_agent_1.9.6/01/grid2op.info new file mode 100644 index 000000000..4889892d4 --- /dev/null +++ b/grid2op/data_test/runner_data/res_agent_1.9.6/01/grid2op.info @@ -0,0 +1,3 @@ +{ + "version": "1.9.6" +} \ No newline at end of file diff --git a/grid2op/data_test/runner_data/res_agent_1.9.6/01/observations.npz b/grid2op/data_test/runner_data/res_agent_1.9.6/01/observations.npz new file mode 100644 index 000000000..ac1626c4f Binary files /dev/null and b/grid2op/data_test/runner_data/res_agent_1.9.6/01/observations.npz differ diff --git a/grid2op/data_test/runner_data/res_agent_1.9.6/01/opponent_attack.npz b/grid2op/data_test/runner_data/res_agent_1.9.6/01/opponent_attack.npz new file mode 100644 index 000000000..e05f26912 Binary files /dev/null and b/grid2op/data_test/runner_data/res_agent_1.9.6/01/opponent_attack.npz differ diff --git a/grid2op/data_test/runner_data/res_agent_1.9.6/01/other_rewards.json b/grid2op/data_test/runner_data/res_agent_1.9.6/01/other_rewards.json new file mode 100644 index 000000000..3f83ec75a --- /dev/null +++ b/grid2op/data_test/runner_data/res_agent_1.9.6/01/other_rewards.json @@ -0,0 +1,7 @@ +[ + {}, + {}, + {}, + {}, + {} +] \ No newline at end of file diff --git a/grid2op/data_test/runner_data/res_agent_1.9.6/01/rewards.npz b/grid2op/data_test/runner_data/res_agent_1.9.6/01/rewards.npz new file mode 100644 index 000000000..0e54c61da Binary files /dev/null and b/grid2op/data_test/runner_data/res_agent_1.9.6/01/rewards.npz differ diff --git a/grid2op/data_test/runner_data/res_agent_1.9.6/dict_action_space.json b/grid2op/data_test/runner_data/res_agent_1.9.6/dict_action_space.json new file mode 100644 index 000000000..ed56e26cb --- /dev/null +++ b/grid2op/data_test/runner_data/res_agent_1.9.6/dict_action_space.json @@ -0,0 +1,219 @@ +{ + "_PATH_ENV": null, + "_init_subtype": "grid2op.Action.topologyAction.TopologyAction", + "alarms_area_lines": [], + "alarms_area_names": [], + "alarms_lines_area": {}, + "alertable_line_ids": [], + "alertable_line_names": [], + "assistant_warning_type": null, + "dim_alarms": 0, + "dim_alerts": 0, + "env_name": "rte_case5_example", + "gen_cost_per_MW": [ + 0.0, + 70.0 + ], + "gen_max_ramp_down": [ + 0.0, + 10.0 + ], + "gen_max_ramp_up": [ + 0.0, + 10.0 + ], + "gen_min_downtime": [ + 0, + 4 + ], + "gen_min_uptime": [ + 0, + 4 + ], + "gen_pmax": [ + 10.0, + 30.0 + ], + "gen_pmin": [ + 0.0, + 0.0 + ], + "gen_pos_topo_vect": [ + 4, + 8 + ], + "gen_redispatchable": [ + false, + true + ], + "gen_renewable": [ + true, + false + ], + "gen_shutdown_cost": [ + 0.0, + 1.0 + ], + "gen_startup_cost": [ + 0.0, + 2.0 + ], + "gen_to_sub_pos": [ + 4, + 2 + ], + "gen_to_subid": [ + 0, + 1 + ], + "gen_type": [ + "wind", + "thermal" + ], + "glop_version": "1.9.6", + "grid_layout": { + "sub_0": [ + 0.0, + 0.0 + ], + "sub_1": [ + 0.0, + 400.0 + ], + "sub_2": [ + 200.0, + 400.0 + ], + "sub_3": [ + 400.0, + 400.0 + ], + "sub_4": [ + 400.0, + 0.0 + ] + }, + "line_ex_pos_topo_vect": [ + 6, + 9, + 13, + 18, + 10, + 14, + 15, + 19 + ], + "line_ex_to_sub_pos": [ + 0, + 0, + 0, + 0, + 1, + 1, + 2, + 1 + ], + "line_ex_to_subid": [ + 1, + 2, + 3, + 4, + 2, + 3, + 3, + 4 + ], + "line_or_pos_topo_vect": [ + 0, + 1, + 2, + 3, + 7, + 11, + 12, + 16 + ], + "line_or_to_sub_pos": [ + 0, + 1, + 2, + 3, + 1, + 2, + 3, + 3 + ], + "line_or_to_subid": [ + 0, + 0, + 0, + 0, + 1, + 2, + 2, + 3 + ], + "load_pos_topo_vect": [ + 5, + 17, + 20 + ], + "load_to_sub_pos": [ + 5, + 4, + 2 + ], + "load_to_subid": [ + 0, + 3, + 4 + ], + "name_gen": [ + "gen_0_0", + "gen_1_1" + ], + "name_line": [ + "0_1_0", + "0_2_1", + "0_3_2", + "0_4_3", + "1_2_4", + "2_3_5", + "2_3_6", + "3_4_7" + ], + "name_load": [ + "load_0_0", + "load_3_1", + "load_4_2" + ], + "name_shunt": [], + "name_storage": [], + "name_sub": [ + "sub_0", + "sub_1", + "sub_2", + "sub_3", + "sub_4" + ], + "shunt_to_subid": [], + "storage_Emax": [], + "storage_Emin": [], + "storage_charging_efficiency": [], + "storage_discharging_efficiency": [], + "storage_loss": [], + "storage_marginal_cost": [], + "storage_max_p_absorb": [], + "storage_max_p_prod": [], + "storage_pos_topo_vect": [], + "storage_to_sub_pos": [], + "storage_to_subid": [], + "storage_type": [], + "sub_info": [ + 6, + 3, + 4, + 5, + 3 + ] +} \ No newline at end of file diff --git a/grid2op/data_test/runner_data/res_agent_1.9.6/dict_attack_space.json b/grid2op/data_test/runner_data/res_agent_1.9.6/dict_attack_space.json new file mode 100644 index 000000000..ee138682b --- /dev/null +++ b/grid2op/data_test/runner_data/res_agent_1.9.6/dict_attack_space.json @@ -0,0 +1,219 @@ +{ + "_PATH_ENV": null, + "_init_subtype": "grid2op.Action.dontAct.DontAct", + "alarms_area_lines": [], + "alarms_area_names": [], + "alarms_lines_area": {}, + "alertable_line_ids": [], + "alertable_line_names": [], + "assistant_warning_type": null, + "dim_alarms": 0, + "dim_alerts": 0, + "env_name": "rte_case5_example", + "gen_cost_per_MW": [ + 0.0, + 70.0 + ], + "gen_max_ramp_down": [ + 0.0, + 10.0 + ], + "gen_max_ramp_up": [ + 0.0, + 10.0 + ], + "gen_min_downtime": [ + 0, + 4 + ], + "gen_min_uptime": [ + 0, + 4 + ], + "gen_pmax": [ + 10.0, + 30.0 + ], + "gen_pmin": [ + 0.0, + 0.0 + ], + "gen_pos_topo_vect": [ + 4, + 8 + ], + "gen_redispatchable": [ + false, + true + ], + "gen_renewable": [ + true, + false + ], + "gen_shutdown_cost": [ + 0.0, + 1.0 + ], + "gen_startup_cost": [ + 0.0, + 2.0 + ], + "gen_to_sub_pos": [ + 4, + 2 + ], + "gen_to_subid": [ + 0, + 1 + ], + "gen_type": [ + "wind", + "thermal" + ], + "glop_version": "1.9.6", + "grid_layout": { + "sub_0": [ + 0.0, + 0.0 + ], + "sub_1": [ + 0.0, + 400.0 + ], + "sub_2": [ + 200.0, + 400.0 + ], + "sub_3": [ + 400.0, + 400.0 + ], + "sub_4": [ + 400.0, + 0.0 + ] + }, + "line_ex_pos_topo_vect": [ + 6, + 9, + 13, + 18, + 10, + 14, + 15, + 19 + ], + "line_ex_to_sub_pos": [ + 0, + 0, + 0, + 0, + 1, + 1, + 2, + 1 + ], + "line_ex_to_subid": [ + 1, + 2, + 3, + 4, + 2, + 3, + 3, + 4 + ], + "line_or_pos_topo_vect": [ + 0, + 1, + 2, + 3, + 7, + 11, + 12, + 16 + ], + "line_or_to_sub_pos": [ + 0, + 1, + 2, + 3, + 1, + 2, + 3, + 3 + ], + "line_or_to_subid": [ + 0, + 0, + 0, + 0, + 1, + 2, + 2, + 3 + ], + "load_pos_topo_vect": [ + 5, + 17, + 20 + ], + "load_to_sub_pos": [ + 5, + 4, + 2 + ], + "load_to_subid": [ + 0, + 3, + 4 + ], + "name_gen": [ + "gen_0_0", + "gen_1_1" + ], + "name_line": [ + "0_1_0", + "0_2_1", + "0_3_2", + "0_4_3", + "1_2_4", + "2_3_5", + "2_3_6", + "3_4_7" + ], + "name_load": [ + "load_0_0", + "load_3_1", + "load_4_2" + ], + "name_shunt": [], + "name_storage": [], + "name_sub": [ + "sub_0", + "sub_1", + "sub_2", + "sub_3", + "sub_4" + ], + "shunt_to_subid": [], + "storage_Emax": [], + "storage_Emin": [], + "storage_charging_efficiency": [], + "storage_discharging_efficiency": [], + "storage_loss": [], + "storage_marginal_cost": [], + "storage_max_p_absorb": [], + "storage_max_p_prod": [], + "storage_pos_topo_vect": [], + "storage_to_sub_pos": [], + "storage_to_subid": [], + "storage_type": [], + "sub_info": [ + 6, + 3, + 4, + 5, + 3 + ] +} \ No newline at end of file diff --git a/grid2op/data_test/runner_data/res_agent_1.9.6/dict_env_modification_space.json b/grid2op/data_test/runner_data/res_agent_1.9.6/dict_env_modification_space.json new file mode 100644 index 000000000..d51d1e6b4 --- /dev/null +++ b/grid2op/data_test/runner_data/res_agent_1.9.6/dict_env_modification_space.json @@ -0,0 +1,219 @@ +{ + "_PATH_ENV": null, + "_init_subtype": "grid2op.Action.completeAction.CompleteAction", + "alarms_area_lines": [], + "alarms_area_names": [], + "alarms_lines_area": {}, + "alertable_line_ids": [], + "alertable_line_names": [], + "assistant_warning_type": null, + "dim_alarms": 0, + "dim_alerts": 0, + "env_name": "rte_case5_example", + "gen_cost_per_MW": [ + 0.0, + 70.0 + ], + "gen_max_ramp_down": [ + 0.0, + 10.0 + ], + "gen_max_ramp_up": [ + 0.0, + 10.0 + ], + "gen_min_downtime": [ + 0, + 4 + ], + "gen_min_uptime": [ + 0, + 4 + ], + "gen_pmax": [ + 10.0, + 30.0 + ], + "gen_pmin": [ + 0.0, + 0.0 + ], + "gen_pos_topo_vect": [ + 4, + 8 + ], + "gen_redispatchable": [ + false, + true + ], + "gen_renewable": [ + true, + false + ], + "gen_shutdown_cost": [ + 0.0, + 1.0 + ], + "gen_startup_cost": [ + 0.0, + 2.0 + ], + "gen_to_sub_pos": [ + 4, + 2 + ], + "gen_to_subid": [ + 0, + 1 + ], + "gen_type": [ + "wind", + "thermal" + ], + "glop_version": "1.9.6", + "grid_layout": { + "sub_0": [ + 0.0, + 0.0 + ], + "sub_1": [ + 0.0, + 400.0 + ], + "sub_2": [ + 200.0, + 400.0 + ], + "sub_3": [ + 400.0, + 400.0 + ], + "sub_4": [ + 400.0, + 0.0 + ] + }, + "line_ex_pos_topo_vect": [ + 6, + 9, + 13, + 18, + 10, + 14, + 15, + 19 + ], + "line_ex_to_sub_pos": [ + 0, + 0, + 0, + 0, + 1, + 1, + 2, + 1 + ], + "line_ex_to_subid": [ + 1, + 2, + 3, + 4, + 2, + 3, + 3, + 4 + ], + "line_or_pos_topo_vect": [ + 0, + 1, + 2, + 3, + 7, + 11, + 12, + 16 + ], + "line_or_to_sub_pos": [ + 0, + 1, + 2, + 3, + 1, + 2, + 3, + 3 + ], + "line_or_to_subid": [ + 0, + 0, + 0, + 0, + 1, + 2, + 2, + 3 + ], + "load_pos_topo_vect": [ + 5, + 17, + 20 + ], + "load_to_sub_pos": [ + 5, + 4, + 2 + ], + "load_to_subid": [ + 0, + 3, + 4 + ], + "name_gen": [ + "gen_0_0", + "gen_1_1" + ], + "name_line": [ + "0_1_0", + "0_2_1", + "0_3_2", + "0_4_3", + "1_2_4", + "2_3_5", + "2_3_6", + "3_4_7" + ], + "name_load": [ + "load_0_0", + "load_3_1", + "load_4_2" + ], + "name_shunt": [], + "name_storage": [], + "name_sub": [ + "sub_0", + "sub_1", + "sub_2", + "sub_3", + "sub_4" + ], + "shunt_to_subid": [], + "storage_Emax": [], + "storage_Emin": [], + "storage_charging_efficiency": [], + "storage_discharging_efficiency": [], + "storage_loss": [], + "storage_marginal_cost": [], + "storage_max_p_absorb": [], + "storage_max_p_prod": [], + "storage_pos_topo_vect": [], + "storage_to_sub_pos": [], + "storage_to_subid": [], + "storage_type": [], + "sub_info": [ + 6, + 3, + 4, + 5, + 3 + ] +} \ No newline at end of file diff --git a/grid2op/data_test/runner_data/res_agent_1.9.6/dict_observation_space.json b/grid2op/data_test/runner_data/res_agent_1.9.6/dict_observation_space.json new file mode 100644 index 000000000..81b7213c9 --- /dev/null +++ b/grid2op/data_test/runner_data/res_agent_1.9.6/dict_observation_space.json @@ -0,0 +1,219 @@ +{ + "_PATH_ENV": null, + "_init_subtype": "grid2op.Observation.completeObservation.CompleteObservation", + "alarms_area_lines": [], + "alarms_area_names": [], + "alarms_lines_area": {}, + "alertable_line_ids": [], + "alertable_line_names": [], + "assistant_warning_type": null, + "dim_alarms": 0, + "dim_alerts": 0, + "env_name": "rte_case5_example", + "gen_cost_per_MW": [ + 0.0, + 70.0 + ], + "gen_max_ramp_down": [ + 0.0, + 10.0 + ], + "gen_max_ramp_up": [ + 0.0, + 10.0 + ], + "gen_min_downtime": [ + 0, + 4 + ], + "gen_min_uptime": [ + 0, + 4 + ], + "gen_pmax": [ + 10.0, + 30.0 + ], + "gen_pmin": [ + 0.0, + 0.0 + ], + "gen_pos_topo_vect": [ + 4, + 8 + ], + "gen_redispatchable": [ + false, + true + ], + "gen_renewable": [ + true, + false + ], + "gen_shutdown_cost": [ + 0.0, + 1.0 + ], + "gen_startup_cost": [ + 0.0, + 2.0 + ], + "gen_to_sub_pos": [ + 4, + 2 + ], + "gen_to_subid": [ + 0, + 1 + ], + "gen_type": [ + "wind", + "thermal" + ], + "glop_version": "1.9.6", + "grid_layout": { + "sub_0": [ + 0.0, + 0.0 + ], + "sub_1": [ + 0.0, + 400.0 + ], + "sub_2": [ + 200.0, + 400.0 + ], + "sub_3": [ + 400.0, + 400.0 + ], + "sub_4": [ + 400.0, + 0.0 + ] + }, + "line_ex_pos_topo_vect": [ + 6, + 9, + 13, + 18, + 10, + 14, + 15, + 19 + ], + "line_ex_to_sub_pos": [ + 0, + 0, + 0, + 0, + 1, + 1, + 2, + 1 + ], + "line_ex_to_subid": [ + 1, + 2, + 3, + 4, + 2, + 3, + 3, + 4 + ], + "line_or_pos_topo_vect": [ + 0, + 1, + 2, + 3, + 7, + 11, + 12, + 16 + ], + "line_or_to_sub_pos": [ + 0, + 1, + 2, + 3, + 1, + 2, + 3, + 3 + ], + "line_or_to_subid": [ + 0, + 0, + 0, + 0, + 1, + 2, + 2, + 3 + ], + "load_pos_topo_vect": [ + 5, + 17, + 20 + ], + "load_to_sub_pos": [ + 5, + 4, + 2 + ], + "load_to_subid": [ + 0, + 3, + 4 + ], + "name_gen": [ + "gen_0_0", + "gen_1_1" + ], + "name_line": [ + "0_1_0", + "0_2_1", + "0_3_2", + "0_4_3", + "1_2_4", + "2_3_5", + "2_3_6", + "3_4_7" + ], + "name_load": [ + "load_0_0", + "load_3_1", + "load_4_2" + ], + "name_shunt": [], + "name_storage": [], + "name_sub": [ + "sub_0", + "sub_1", + "sub_2", + "sub_3", + "sub_4" + ], + "shunt_to_subid": [], + "storage_Emax": [], + "storage_Emin": [], + "storage_charging_efficiency": [], + "storage_discharging_efficiency": [], + "storage_loss": [], + "storage_marginal_cost": [], + "storage_max_p_absorb": [], + "storage_max_p_prod": [], + "storage_pos_topo_vect": [], + "storage_to_sub_pos": [], + "storage_to_subid": [], + "storage_type": [], + "sub_info": [ + 6, + 3, + 4, + 5, + 3 + ] +} \ No newline at end of file diff --git a/grid2op/data_test/runner_data/res_agent_1.9.7/00/_parameters.json b/grid2op/data_test/runner_data/res_agent_1.9.7/00/_parameters.json new file mode 100644 index 000000000..ce75edee3 --- /dev/null +++ b/grid2op/data_test/runner_data/res_agent_1.9.7/00/_parameters.json @@ -0,0 +1,23 @@ +{ + "ACTIVATE_STORAGE_LOSS": true, + "ALARM_BEST_TIME": 12, + "ALARM_WINDOW_SIZE": 12, + "ALERT_TIME_WINDOW": 12, + "ALLOW_DISPATCH_GEN_SWITCH_OFF": true, + "ENV_DC": false, + "FORECAST_DC": false, + "HARD_OVERFLOW_THRESHOLD": 2.0, + "IGNORE_MIN_UP_DOWN_TIME": true, + "INIT_STORAGE_CAPACITY": 0.5, + "LIMIT_INFEASIBLE_CURTAILMENT_STORAGE_ACTION": false, + "MAX_LINE_STATUS_CHANGED": 1, + "MAX_SIMULATE_PER_EPISODE": -1, + "MAX_SIMULATE_PER_STEP": -1, + "MAX_SUB_CHANGED": 1, + "NB_TIMESTEP_COOLDOWN_LINE": 0, + "NB_TIMESTEP_COOLDOWN_SUB": 0, + "NB_TIMESTEP_OVERFLOW_ALLOWED": 2, + "NB_TIMESTEP_RECONNECTION": 10, + "NO_OVERFLOW_DISCONNECTION": false, + "SOFT_OVERFLOW_THRESHOLD": 1.0 +} \ No newline at end of file diff --git a/grid2op/data_test/runner_data/res_agent_1.9.7/00/actions.npz b/grid2op/data_test/runner_data/res_agent_1.9.7/00/actions.npz new file mode 100644 index 000000000..462144466 Binary files /dev/null and b/grid2op/data_test/runner_data/res_agent_1.9.7/00/actions.npz differ diff --git a/grid2op/data_test/runner_data/res_agent_1.9.7/00/agent_exec_times.npz b/grid2op/data_test/runner_data/res_agent_1.9.7/00/agent_exec_times.npz new file mode 100644 index 000000000..db7812c1b Binary files /dev/null and b/grid2op/data_test/runner_data/res_agent_1.9.7/00/agent_exec_times.npz differ diff --git a/grid2op/data_test/runner_data/res_agent_1.9.7/00/disc_lines_cascading_failure.npz b/grid2op/data_test/runner_data/res_agent_1.9.7/00/disc_lines_cascading_failure.npz new file mode 100644 index 000000000..298421483 Binary files /dev/null and b/grid2op/data_test/runner_data/res_agent_1.9.7/00/disc_lines_cascading_failure.npz differ diff --git a/grid2op/data_test/runner_data/res_agent_1.9.7/00/env_modifications.npz b/grid2op/data_test/runner_data/res_agent_1.9.7/00/env_modifications.npz new file mode 100644 index 000000000..e944d2451 Binary files /dev/null and b/grid2op/data_test/runner_data/res_agent_1.9.7/00/env_modifications.npz differ diff --git a/grid2op/data_test/runner_data/res_agent_1.9.7/00/episode_meta.json b/grid2op/data_test/runner_data/res_agent_1.9.7/00/episode_meta.json new file mode 100644 index 000000000..13c2380d7 --- /dev/null +++ b/grid2op/data_test/runner_data/res_agent_1.9.7/00/episode_meta.json @@ -0,0 +1,11 @@ +{ + "agent_seed": null, + "backend_type": "PandaPowerBackend_rte_case5_example", + "chronics_max_timestep": "100", + "chronics_path": "/home/donnotben/Documents/grid2op_dev/grid2op/data/rte_case5_example/chronics/00", + "cumulative_reward": 30.19790267944336, + "env_seed": null, + "env_type": "Environment_rte_case5_example", + "grid_path": "/home/donnotben/Documents/grid2op_dev/grid2op/data/rte_case5_example/grid.json", + "nb_timestep_played": 7 +} \ No newline at end of file diff --git a/grid2op/data_test/runner_data/res_agent_1.9.7/00/episode_times.json b/grid2op/data_test/runner_data/res_agent_1.9.7/00/episode_times.json new file mode 100644 index 000000000..bde90efc0 --- /dev/null +++ b/grid2op/data_test/runner_data/res_agent_1.9.7/00/episode_times.json @@ -0,0 +1,12 @@ +{ + "Agent": { + "total": 0.00018804800129146315 + }, + "Env": { + "apply_act": 0.03656216100080201, + "observation_computation": 0.006631043999732356, + "powerflow_computation": 0.16643031500098004, + "total": 0.2096235200015144 + }, + "total": 0.21395956200012733 +} \ No newline at end of file diff --git a/grid2op/data_test/runner_data/res_agent_1.9.7/00/grid2op.info b/grid2op/data_test/runner_data/res_agent_1.9.7/00/grid2op.info new file mode 100644 index 000000000..a3ad9d7be --- /dev/null +++ b/grid2op/data_test/runner_data/res_agent_1.9.7/00/grid2op.info @@ -0,0 +1,3 @@ +{ + "version": "1.9.7" +} \ No newline at end of file diff --git a/grid2op/data_test/runner_data/res_agent_1.9.7/00/observations.npz b/grid2op/data_test/runner_data/res_agent_1.9.7/00/observations.npz new file mode 100644 index 000000000..4f6b461cb Binary files /dev/null and b/grid2op/data_test/runner_data/res_agent_1.9.7/00/observations.npz differ diff --git a/grid2op/data_test/runner_data/res_agent_1.9.7/00/opponent_attack.npz b/grid2op/data_test/runner_data/res_agent_1.9.7/00/opponent_attack.npz new file mode 100644 index 000000000..e05f26912 Binary files /dev/null and b/grid2op/data_test/runner_data/res_agent_1.9.7/00/opponent_attack.npz differ diff --git a/grid2op/data_test/runner_data/res_agent_1.9.7/00/other_rewards.json b/grid2op/data_test/runner_data/res_agent_1.9.7/00/other_rewards.json new file mode 100644 index 000000000..602358501 --- /dev/null +++ b/grid2op/data_test/runner_data/res_agent_1.9.7/00/other_rewards.json @@ -0,0 +1,9 @@ +[ + {}, + {}, + {}, + {}, + {}, + {}, + {} +] \ No newline at end of file diff --git a/grid2op/data_test/runner_data/res_agent_1.9.7/00/rewards.npz b/grid2op/data_test/runner_data/res_agent_1.9.7/00/rewards.npz new file mode 100644 index 000000000..0750b1606 Binary files /dev/null and b/grid2op/data_test/runner_data/res_agent_1.9.7/00/rewards.npz differ diff --git a/grid2op/data_test/runner_data/res_agent_1.9.7/01/_parameters.json b/grid2op/data_test/runner_data/res_agent_1.9.7/01/_parameters.json new file mode 100644 index 000000000..ce75edee3 --- /dev/null +++ b/grid2op/data_test/runner_data/res_agent_1.9.7/01/_parameters.json @@ -0,0 +1,23 @@ +{ + "ACTIVATE_STORAGE_LOSS": true, + "ALARM_BEST_TIME": 12, + "ALARM_WINDOW_SIZE": 12, + "ALERT_TIME_WINDOW": 12, + "ALLOW_DISPATCH_GEN_SWITCH_OFF": true, + "ENV_DC": false, + "FORECAST_DC": false, + "HARD_OVERFLOW_THRESHOLD": 2.0, + "IGNORE_MIN_UP_DOWN_TIME": true, + "INIT_STORAGE_CAPACITY": 0.5, + "LIMIT_INFEASIBLE_CURTAILMENT_STORAGE_ACTION": false, + "MAX_LINE_STATUS_CHANGED": 1, + "MAX_SIMULATE_PER_EPISODE": -1, + "MAX_SIMULATE_PER_STEP": -1, + "MAX_SUB_CHANGED": 1, + "NB_TIMESTEP_COOLDOWN_LINE": 0, + "NB_TIMESTEP_COOLDOWN_SUB": 0, + "NB_TIMESTEP_OVERFLOW_ALLOWED": 2, + "NB_TIMESTEP_RECONNECTION": 10, + "NO_OVERFLOW_DISCONNECTION": false, + "SOFT_OVERFLOW_THRESHOLD": 1.0 +} \ No newline at end of file diff --git a/grid2op/data_test/runner_data/res_agent_1.9.7/01/actions.npz b/grid2op/data_test/runner_data/res_agent_1.9.7/01/actions.npz new file mode 100644 index 000000000..f2a01fe59 Binary files /dev/null and b/grid2op/data_test/runner_data/res_agent_1.9.7/01/actions.npz differ diff --git a/grid2op/data_test/runner_data/res_agent_1.9.7/01/agent_exec_times.npz b/grid2op/data_test/runner_data/res_agent_1.9.7/01/agent_exec_times.npz new file mode 100644 index 000000000..291b9572e Binary files /dev/null and b/grid2op/data_test/runner_data/res_agent_1.9.7/01/agent_exec_times.npz differ diff --git a/grid2op/data_test/runner_data/res_agent_1.9.7/01/disc_lines_cascading_failure.npz b/grid2op/data_test/runner_data/res_agent_1.9.7/01/disc_lines_cascading_failure.npz new file mode 100644 index 000000000..298421483 Binary files /dev/null and b/grid2op/data_test/runner_data/res_agent_1.9.7/01/disc_lines_cascading_failure.npz differ diff --git a/grid2op/data_test/runner_data/res_agent_1.9.7/01/env_modifications.npz b/grid2op/data_test/runner_data/res_agent_1.9.7/01/env_modifications.npz new file mode 100644 index 000000000..932771c86 Binary files /dev/null and b/grid2op/data_test/runner_data/res_agent_1.9.7/01/env_modifications.npz differ diff --git a/grid2op/data_test/runner_data/res_agent_1.9.7/01/episode_meta.json b/grid2op/data_test/runner_data/res_agent_1.9.7/01/episode_meta.json new file mode 100644 index 000000000..b5de19661 --- /dev/null +++ b/grid2op/data_test/runner_data/res_agent_1.9.7/01/episode_meta.json @@ -0,0 +1,11 @@ +{ + "agent_seed": null, + "backend_type": "PandaPowerBackend_rte_case5_example", + "chronics_max_timestep": "100", + "chronics_path": "/home/donnotben/Documents/grid2op_dev/grid2op/data/rte_case5_example/chronics/01", + "cumulative_reward": 8.710962295532227, + "env_seed": null, + "env_type": "Environment_rte_case5_example", + "grid_path": "/home/donnotben/Documents/grid2op_dev/grid2op/data/rte_case5_example/grid.json", + "nb_timestep_played": 3 +} \ No newline at end of file diff --git a/grid2op/data_test/runner_data/res_agent_1.9.7/01/episode_times.json b/grid2op/data_test/runner_data/res_agent_1.9.7/01/episode_times.json new file mode 100644 index 000000000..4d1cae8e9 --- /dev/null +++ b/grid2op/data_test/runner_data/res_agent_1.9.7/01/episode_times.json @@ -0,0 +1,12 @@ +{ + "Agent": { + "total": 6.966899945837213e-05 + }, + "Env": { + "apply_act": 0.01420826599951397, + "observation_computation": 0.0023521240009358735, + "powerflow_computation": 0.05833839099977922, + "total": 0.07489878100022906 + }, + "total": 0.07635611800014885 +} \ No newline at end of file diff --git a/grid2op/data_test/runner_data/res_agent_1.9.7/01/grid2op.info b/grid2op/data_test/runner_data/res_agent_1.9.7/01/grid2op.info new file mode 100644 index 000000000..a3ad9d7be --- /dev/null +++ b/grid2op/data_test/runner_data/res_agent_1.9.7/01/grid2op.info @@ -0,0 +1,3 @@ +{ + "version": "1.9.7" +} \ No newline at end of file diff --git a/grid2op/data_test/runner_data/res_agent_1.9.7/01/observations.npz b/grid2op/data_test/runner_data/res_agent_1.9.7/01/observations.npz new file mode 100644 index 000000000..823b21e59 Binary files /dev/null and b/grid2op/data_test/runner_data/res_agent_1.9.7/01/observations.npz differ diff --git a/grid2op/data_test/runner_data/res_agent_1.9.7/01/opponent_attack.npz b/grid2op/data_test/runner_data/res_agent_1.9.7/01/opponent_attack.npz new file mode 100644 index 000000000..e05f26912 Binary files /dev/null and b/grid2op/data_test/runner_data/res_agent_1.9.7/01/opponent_attack.npz differ diff --git a/grid2op/data_test/runner_data/res_agent_1.9.7/01/other_rewards.json b/grid2op/data_test/runner_data/res_agent_1.9.7/01/other_rewards.json new file mode 100644 index 000000000..ca609c0c6 --- /dev/null +++ b/grid2op/data_test/runner_data/res_agent_1.9.7/01/other_rewards.json @@ -0,0 +1,5 @@ +[ + {}, + {}, + {} +] \ No newline at end of file diff --git a/grid2op/data_test/runner_data/res_agent_1.9.7/01/rewards.npz b/grid2op/data_test/runner_data/res_agent_1.9.7/01/rewards.npz new file mode 100644 index 000000000..eac7f339b Binary files /dev/null and b/grid2op/data_test/runner_data/res_agent_1.9.7/01/rewards.npz differ diff --git a/grid2op/data_test/runner_data/res_agent_1.9.7/dict_action_space.json b/grid2op/data_test/runner_data/res_agent_1.9.7/dict_action_space.json new file mode 100644 index 000000000..277537f84 --- /dev/null +++ b/grid2op/data_test/runner_data/res_agent_1.9.7/dict_action_space.json @@ -0,0 +1,219 @@ +{ + "_PATH_ENV": null, + "_init_subtype": "grid2op.Action.topologyAction.TopologyAction", + "alarms_area_lines": [], + "alarms_area_names": [], + "alarms_lines_area": {}, + "alertable_line_ids": [], + "alertable_line_names": [], + "assistant_warning_type": null, + "dim_alarms": 0, + "dim_alerts": 0, + "env_name": "rte_case5_example", + "gen_cost_per_MW": [ + 0.0, + 70.0 + ], + "gen_max_ramp_down": [ + 0.0, + 10.0 + ], + "gen_max_ramp_up": [ + 0.0, + 10.0 + ], + "gen_min_downtime": [ + 0, + 4 + ], + "gen_min_uptime": [ + 0, + 4 + ], + "gen_pmax": [ + 10.0, + 30.0 + ], + "gen_pmin": [ + 0.0, + 0.0 + ], + "gen_pos_topo_vect": [ + 4, + 8 + ], + "gen_redispatchable": [ + false, + true + ], + "gen_renewable": [ + true, + false + ], + "gen_shutdown_cost": [ + 0.0, + 1.0 + ], + "gen_startup_cost": [ + 0.0, + 2.0 + ], + "gen_to_sub_pos": [ + 4, + 2 + ], + "gen_to_subid": [ + 0, + 1 + ], + "gen_type": [ + "wind", + "thermal" + ], + "glop_version": "1.9.7", + "grid_layout": { + "sub_0": [ + 0.0, + 0.0 + ], + "sub_1": [ + 0.0, + 400.0 + ], + "sub_2": [ + 200.0, + 400.0 + ], + "sub_3": [ + 400.0, + 400.0 + ], + "sub_4": [ + 400.0, + 0.0 + ] + }, + "line_ex_pos_topo_vect": [ + 6, + 9, + 13, + 18, + 10, + 14, + 15, + 19 + ], + "line_ex_to_sub_pos": [ + 0, + 0, + 0, + 0, + 1, + 1, + 2, + 1 + ], + "line_ex_to_subid": [ + 1, + 2, + 3, + 4, + 2, + 3, + 3, + 4 + ], + "line_or_pos_topo_vect": [ + 0, + 1, + 2, + 3, + 7, + 11, + 12, + 16 + ], + "line_or_to_sub_pos": [ + 0, + 1, + 2, + 3, + 1, + 2, + 3, + 3 + ], + "line_or_to_subid": [ + 0, + 0, + 0, + 0, + 1, + 2, + 2, + 3 + ], + "load_pos_topo_vect": [ + 5, + 17, + 20 + ], + "load_to_sub_pos": [ + 5, + 4, + 2 + ], + "load_to_subid": [ + 0, + 3, + 4 + ], + "name_gen": [ + "gen_0_0", + "gen_1_1" + ], + "name_line": [ + "0_1_0", + "0_2_1", + "0_3_2", + "0_4_3", + "1_2_4", + "2_3_5", + "2_3_6", + "3_4_7" + ], + "name_load": [ + "load_0_0", + "load_3_1", + "load_4_2" + ], + "name_shunt": [], + "name_storage": [], + "name_sub": [ + "sub_0", + "sub_1", + "sub_2", + "sub_3", + "sub_4" + ], + "shunt_to_subid": [], + "storage_Emax": [], + "storage_Emin": [], + "storage_charging_efficiency": [], + "storage_discharging_efficiency": [], + "storage_loss": [], + "storage_marginal_cost": [], + "storage_max_p_absorb": [], + "storage_max_p_prod": [], + "storage_pos_topo_vect": [], + "storage_to_sub_pos": [], + "storage_to_subid": [], + "storage_type": [], + "sub_info": [ + 6, + 3, + 4, + 5, + 3 + ] +} \ No newline at end of file diff --git a/grid2op/data_test/runner_data/res_agent_1.9.7/dict_attack_space.json b/grid2op/data_test/runner_data/res_agent_1.9.7/dict_attack_space.json new file mode 100644 index 000000000..9a8d792cd --- /dev/null +++ b/grid2op/data_test/runner_data/res_agent_1.9.7/dict_attack_space.json @@ -0,0 +1,219 @@ +{ + "_PATH_ENV": null, + "_init_subtype": "grid2op.Action.dontAct.DontAct", + "alarms_area_lines": [], + "alarms_area_names": [], + "alarms_lines_area": {}, + "alertable_line_ids": [], + "alertable_line_names": [], + "assistant_warning_type": null, + "dim_alarms": 0, + "dim_alerts": 0, + "env_name": "rte_case5_example", + "gen_cost_per_MW": [ + 0.0, + 70.0 + ], + "gen_max_ramp_down": [ + 0.0, + 10.0 + ], + "gen_max_ramp_up": [ + 0.0, + 10.0 + ], + "gen_min_downtime": [ + 0, + 4 + ], + "gen_min_uptime": [ + 0, + 4 + ], + "gen_pmax": [ + 10.0, + 30.0 + ], + "gen_pmin": [ + 0.0, + 0.0 + ], + "gen_pos_topo_vect": [ + 4, + 8 + ], + "gen_redispatchable": [ + false, + true + ], + "gen_renewable": [ + true, + false + ], + "gen_shutdown_cost": [ + 0.0, + 1.0 + ], + "gen_startup_cost": [ + 0.0, + 2.0 + ], + "gen_to_sub_pos": [ + 4, + 2 + ], + "gen_to_subid": [ + 0, + 1 + ], + "gen_type": [ + "wind", + "thermal" + ], + "glop_version": "1.9.7", + "grid_layout": { + "sub_0": [ + 0.0, + 0.0 + ], + "sub_1": [ + 0.0, + 400.0 + ], + "sub_2": [ + 200.0, + 400.0 + ], + "sub_3": [ + 400.0, + 400.0 + ], + "sub_4": [ + 400.0, + 0.0 + ] + }, + "line_ex_pos_topo_vect": [ + 6, + 9, + 13, + 18, + 10, + 14, + 15, + 19 + ], + "line_ex_to_sub_pos": [ + 0, + 0, + 0, + 0, + 1, + 1, + 2, + 1 + ], + "line_ex_to_subid": [ + 1, + 2, + 3, + 4, + 2, + 3, + 3, + 4 + ], + "line_or_pos_topo_vect": [ + 0, + 1, + 2, + 3, + 7, + 11, + 12, + 16 + ], + "line_or_to_sub_pos": [ + 0, + 1, + 2, + 3, + 1, + 2, + 3, + 3 + ], + "line_or_to_subid": [ + 0, + 0, + 0, + 0, + 1, + 2, + 2, + 3 + ], + "load_pos_topo_vect": [ + 5, + 17, + 20 + ], + "load_to_sub_pos": [ + 5, + 4, + 2 + ], + "load_to_subid": [ + 0, + 3, + 4 + ], + "name_gen": [ + "gen_0_0", + "gen_1_1" + ], + "name_line": [ + "0_1_0", + "0_2_1", + "0_3_2", + "0_4_3", + "1_2_4", + "2_3_5", + "2_3_6", + "3_4_7" + ], + "name_load": [ + "load_0_0", + "load_3_1", + "load_4_2" + ], + "name_shunt": [], + "name_storage": [], + "name_sub": [ + "sub_0", + "sub_1", + "sub_2", + "sub_3", + "sub_4" + ], + "shunt_to_subid": [], + "storage_Emax": [], + "storage_Emin": [], + "storage_charging_efficiency": [], + "storage_discharging_efficiency": [], + "storage_loss": [], + "storage_marginal_cost": [], + "storage_max_p_absorb": [], + "storage_max_p_prod": [], + "storage_pos_topo_vect": [], + "storage_to_sub_pos": [], + "storage_to_subid": [], + "storage_type": [], + "sub_info": [ + 6, + 3, + 4, + 5, + 3 + ] +} \ No newline at end of file diff --git a/grid2op/data_test/runner_data/res_agent_1.9.7/dict_env_modification_space.json b/grid2op/data_test/runner_data/res_agent_1.9.7/dict_env_modification_space.json new file mode 100644 index 000000000..50858de20 --- /dev/null +++ b/grid2op/data_test/runner_data/res_agent_1.9.7/dict_env_modification_space.json @@ -0,0 +1,219 @@ +{ + "_PATH_ENV": null, + "_init_subtype": "grid2op.Action.completeAction.CompleteAction", + "alarms_area_lines": [], + "alarms_area_names": [], + "alarms_lines_area": {}, + "alertable_line_ids": [], + "alertable_line_names": [], + "assistant_warning_type": null, + "dim_alarms": 0, + "dim_alerts": 0, + "env_name": "rte_case5_example", + "gen_cost_per_MW": [ + 0.0, + 70.0 + ], + "gen_max_ramp_down": [ + 0.0, + 10.0 + ], + "gen_max_ramp_up": [ + 0.0, + 10.0 + ], + "gen_min_downtime": [ + 0, + 4 + ], + "gen_min_uptime": [ + 0, + 4 + ], + "gen_pmax": [ + 10.0, + 30.0 + ], + "gen_pmin": [ + 0.0, + 0.0 + ], + "gen_pos_topo_vect": [ + 4, + 8 + ], + "gen_redispatchable": [ + false, + true + ], + "gen_renewable": [ + true, + false + ], + "gen_shutdown_cost": [ + 0.0, + 1.0 + ], + "gen_startup_cost": [ + 0.0, + 2.0 + ], + "gen_to_sub_pos": [ + 4, + 2 + ], + "gen_to_subid": [ + 0, + 1 + ], + "gen_type": [ + "wind", + "thermal" + ], + "glop_version": "1.9.7", + "grid_layout": { + "sub_0": [ + 0.0, + 0.0 + ], + "sub_1": [ + 0.0, + 400.0 + ], + "sub_2": [ + 200.0, + 400.0 + ], + "sub_3": [ + 400.0, + 400.0 + ], + "sub_4": [ + 400.0, + 0.0 + ] + }, + "line_ex_pos_topo_vect": [ + 6, + 9, + 13, + 18, + 10, + 14, + 15, + 19 + ], + "line_ex_to_sub_pos": [ + 0, + 0, + 0, + 0, + 1, + 1, + 2, + 1 + ], + "line_ex_to_subid": [ + 1, + 2, + 3, + 4, + 2, + 3, + 3, + 4 + ], + "line_or_pos_topo_vect": [ + 0, + 1, + 2, + 3, + 7, + 11, + 12, + 16 + ], + "line_or_to_sub_pos": [ + 0, + 1, + 2, + 3, + 1, + 2, + 3, + 3 + ], + "line_or_to_subid": [ + 0, + 0, + 0, + 0, + 1, + 2, + 2, + 3 + ], + "load_pos_topo_vect": [ + 5, + 17, + 20 + ], + "load_to_sub_pos": [ + 5, + 4, + 2 + ], + "load_to_subid": [ + 0, + 3, + 4 + ], + "name_gen": [ + "gen_0_0", + "gen_1_1" + ], + "name_line": [ + "0_1_0", + "0_2_1", + "0_3_2", + "0_4_3", + "1_2_4", + "2_3_5", + "2_3_6", + "3_4_7" + ], + "name_load": [ + "load_0_0", + "load_3_1", + "load_4_2" + ], + "name_shunt": [], + "name_storage": [], + "name_sub": [ + "sub_0", + "sub_1", + "sub_2", + "sub_3", + "sub_4" + ], + "shunt_to_subid": [], + "storage_Emax": [], + "storage_Emin": [], + "storage_charging_efficiency": [], + "storage_discharging_efficiency": [], + "storage_loss": [], + "storage_marginal_cost": [], + "storage_max_p_absorb": [], + "storage_max_p_prod": [], + "storage_pos_topo_vect": [], + "storage_to_sub_pos": [], + "storage_to_subid": [], + "storage_type": [], + "sub_info": [ + 6, + 3, + 4, + 5, + 3 + ] +} \ No newline at end of file diff --git a/grid2op/data_test/runner_data/res_agent_1.9.7/dict_observation_space.json b/grid2op/data_test/runner_data/res_agent_1.9.7/dict_observation_space.json new file mode 100644 index 000000000..81ca6e332 --- /dev/null +++ b/grid2op/data_test/runner_data/res_agent_1.9.7/dict_observation_space.json @@ -0,0 +1,219 @@ +{ + "_PATH_ENV": null, + "_init_subtype": "grid2op.Observation.completeObservation.CompleteObservation", + "alarms_area_lines": [], + "alarms_area_names": [], + "alarms_lines_area": {}, + "alertable_line_ids": [], + "alertable_line_names": [], + "assistant_warning_type": null, + "dim_alarms": 0, + "dim_alerts": 0, + "env_name": "rte_case5_example", + "gen_cost_per_MW": [ + 0.0, + 70.0 + ], + "gen_max_ramp_down": [ + 0.0, + 10.0 + ], + "gen_max_ramp_up": [ + 0.0, + 10.0 + ], + "gen_min_downtime": [ + 0, + 4 + ], + "gen_min_uptime": [ + 0, + 4 + ], + "gen_pmax": [ + 10.0, + 30.0 + ], + "gen_pmin": [ + 0.0, + 0.0 + ], + "gen_pos_topo_vect": [ + 4, + 8 + ], + "gen_redispatchable": [ + false, + true + ], + "gen_renewable": [ + true, + false + ], + "gen_shutdown_cost": [ + 0.0, + 1.0 + ], + "gen_startup_cost": [ + 0.0, + 2.0 + ], + "gen_to_sub_pos": [ + 4, + 2 + ], + "gen_to_subid": [ + 0, + 1 + ], + "gen_type": [ + "wind", + "thermal" + ], + "glop_version": "1.9.7", + "grid_layout": { + "sub_0": [ + 0.0, + 0.0 + ], + "sub_1": [ + 0.0, + 400.0 + ], + "sub_2": [ + 200.0, + 400.0 + ], + "sub_3": [ + 400.0, + 400.0 + ], + "sub_4": [ + 400.0, + 0.0 + ] + }, + "line_ex_pos_topo_vect": [ + 6, + 9, + 13, + 18, + 10, + 14, + 15, + 19 + ], + "line_ex_to_sub_pos": [ + 0, + 0, + 0, + 0, + 1, + 1, + 2, + 1 + ], + "line_ex_to_subid": [ + 1, + 2, + 3, + 4, + 2, + 3, + 3, + 4 + ], + "line_or_pos_topo_vect": [ + 0, + 1, + 2, + 3, + 7, + 11, + 12, + 16 + ], + "line_or_to_sub_pos": [ + 0, + 1, + 2, + 3, + 1, + 2, + 3, + 3 + ], + "line_or_to_subid": [ + 0, + 0, + 0, + 0, + 1, + 2, + 2, + 3 + ], + "load_pos_topo_vect": [ + 5, + 17, + 20 + ], + "load_to_sub_pos": [ + 5, + 4, + 2 + ], + "load_to_subid": [ + 0, + 3, + 4 + ], + "name_gen": [ + "gen_0_0", + "gen_1_1" + ], + "name_line": [ + "0_1_0", + "0_2_1", + "0_3_2", + "0_4_3", + "1_2_4", + "2_3_5", + "2_3_6", + "3_4_7" + ], + "name_load": [ + "load_0_0", + "load_3_1", + "load_4_2" + ], + "name_shunt": [], + "name_storage": [], + "name_sub": [ + "sub_0", + "sub_1", + "sub_2", + "sub_3", + "sub_4" + ], + "shunt_to_subid": [], + "storage_Emax": [], + "storage_Emin": [], + "storage_charging_efficiency": [], + "storage_discharging_efficiency": [], + "storage_loss": [], + "storage_marginal_cost": [], + "storage_max_p_absorb": [], + "storage_max_p_prod": [], + "storage_pos_topo_vect": [], + "storage_to_sub_pos": [], + "storage_to_subid": [], + "storage_type": [], + "sub_info": [ + 6, + 3, + 4, + 5, + 3 + ] +} \ No newline at end of file diff --git a/grid2op/gym_compat/gym_act_space.py b/grid2op/gym_compat/gym_act_space.py index 57dc8cfc1..8bc428e2e 100644 --- a/grid2op/gym_compat/gym_act_space.py +++ b/grid2op/gym_compat/gym_act_space.py @@ -137,7 +137,7 @@ def __init__(self, env, converter=None, dict_variables=None): self._init_env = None else: raise RuntimeError( - "GymActionSpace must be created with an Environment of an ActionSpace (or a Converter)" + "GymActionSpace must be created with an Environment or an ActionSpace (or a Converter)" ) dict_ = {} # TODO Make sure it works well ! diff --git a/grid2op/multi_agent/my_test.py b/grid2op/multi_agent/my_test.py deleted file mode 100644 index 3c48e88ec..000000000 --- a/grid2op/multi_agent/my_test.py +++ /dev/null @@ -1,16 +0,0 @@ -import grid2op -from grid2op.multi_agent.multiAgentEnv import MultiAgentEnv - -env = grid2op.make("l2rpn_case14_sandbox", test = True) -action_domains = { - 'agent_0' : [0,1,2,3, 4], - 'agent_1' : [5,6,7,8,9,10,11,12,13] - } -observation_domains = { - 'agent_0' : action_domains['agent_1'], - 'agent_1' : action_domains['agent_0'] - } - -# run redispatch agent on one scenario for 100 timesteps -ma_env = MultiAgentEnv(env, observation_domains, action_domains) - diff --git a/grid2op/tests/BaseBackendTest.py b/grid2op/tests/BaseBackendTest.py index c0cd9ba19..ad24c2ca6 100644 --- a/grid2op/tests/BaseBackendTest.py +++ b/grid2op/tests/BaseBackendTest.py @@ -74,7 +74,7 @@ def get_path(self): def test_properNames(self): self.skip_if_needed() - backend = self.make_backend() + backend = self.make_backend_with_glue_code() path = self.get_path() with warnings.catch_warnings(): @@ -97,7 +97,7 @@ def get_casefile(self): return "test_case14.json" def test_load_file(self): - backend = self.make_backend() + backend = self.make_backend_with_glue_code() path_matpower = self.get_path() case_file = self.get_casefile() with warnings.catch_warnings(): @@ -191,7 +191,7 @@ def test_load_file(self): assert np.max(np.abs(q_bus.flatten())) <= self.tolvect def test_assert_grid_correct(self): - backend = self.make_backend() + backend = self.make_backend_with_glue_code() path_matpower = self.get_path() case_file = self.get_casefile() with warnings.catch_warnings(): @@ -212,7 +212,7 @@ def get_casefile(self): return "test_case14.json" def setUp(self): - self.backend = self.make_backend() + self.backend = self.make_backend_with_glue_code() self.path_matpower = self.get_path() self.case_file = self.get_casefile() with warnings.catch_warnings(): @@ -813,7 +813,7 @@ def get_casefile(self): return "test_case14.json" def setUp(self): - self.backend = self.make_backend() + self.backend = self.make_backend_with_glue_code() self.path_matpower = self.get_path() self.case_file = self.get_casefile() with warnings.catch_warnings(): @@ -1422,13 +1422,13 @@ def test_get_action_to_set_storage(self): env = grid2op.make( "educ_case14_storage", test=True, - backend=self.make_backend(), + backend=self.make_backend_with_glue_code(), _add_to_name=type(self).__name__ ) env2 = grid2op.make( "educ_case14_storage", test=True, - backend=self.make_backend(), + backend=self.make_backend_with_glue_code(), _add_to_name=type(self).__name__ ) obs, *_ = env.step(env.action_space({"set_storage": [-1.0, 1.0]})) @@ -1453,7 +1453,7 @@ def test_update_from_obs(self): env = grid2op.make( "rte_case14_realistic", test=True, - backend=self.make_backend(), + backend=self.make_backend_with_glue_code(), _add_to_name=type(self).__name__ ) @@ -1559,8 +1559,7 @@ def get_path(self): return PATH_DATA_TEST def setUp(self): - self.backend = self.make_backend(detailed_infos_for_cascading_failures=True) - type(self.backend)._clear_class_attribute() + self.backend = self.make_backend_with_glue_code(detailed_infos_for_cascading_failures=True) self.path_matpower = self.get_path() self.case_file = self.get_casefile() with warnings.catch_warnings(): @@ -1885,12 +1884,11 @@ class BaseTestChangeBusAffectRightBus(MakeBackend): def test_set_bus(self): self.skip_if_needed() # print("test_set_bus") - backend = self.make_backend() - type(backend)._clear_class_attribute() + backend = self.make_backend_with_glue_code() with warnings.catch_warnings(): warnings.filterwarnings("ignore") env = grid2op.make("rte_case14_realistic", test=True, backend=backend, - _add_to_name=type(self).__name__) + _add_to_name=type(self).__name__) env.reset() action = env.action_space({"set_bus": {"lines_or_id": [(17, 2)]}}) obs, reward, done, info = env.step(action) @@ -1901,8 +1899,7 @@ def test_set_bus(self): def test_change_bus(self): self.skip_if_needed() # print("test_change_bus") - backend = self.make_backend() - type(backend)._clear_class_attribute() + backend = self.make_backend_with_glue_code() with warnings.catch_warnings(): warnings.filterwarnings("ignore") env = grid2op.make("rte_case14_realistic", test=True, backend=backend, @@ -1916,8 +1913,7 @@ def test_change_bus(self): def test_change_bustwice(self): self.skip_if_needed() # print("test_change_bustwice") - backend = self.make_backend() - type(backend)._clear_class_attribute() + backend = self.make_backend_with_glue_code() with warnings.catch_warnings(): warnings.filterwarnings("ignore") env = grid2op.make("rte_case14_realistic", test=True, backend=backend, @@ -1938,8 +1934,7 @@ def test_change_bustwice(self): def test_isolate_load(self): self.skip_if_needed() # print("test_isolate_load") - backend = self.make_backend() - type(backend)._clear_class_attribute() + backend = self.make_backend_with_glue_code() with warnings.catch_warnings(): warnings.filterwarnings("ignore") env = grid2op.make("rte_case14_realistic", test=True, backend=backend, @@ -1951,8 +1946,7 @@ def test_isolate_load(self): def test_reco_disco_bus(self): self.skip_if_needed() # print("test_reco_disco_bus") - backend = self.make_backend() - type(backend)._clear_class_attribute() + backend = self.make_backend_with_glue_code() with warnings.catch_warnings(): warnings.filterwarnings("ignore") env_case1 = grid2op.make( @@ -1978,8 +1972,7 @@ def test_reco_disco_bus(self): def test_reco_disco_bus2(self): self.skip_if_needed() # print("test_reco_disco_bus2") - backend = self.make_backend() - type(backend)._clear_class_attribute() + backend = self.make_backend_with_glue_code() with warnings.catch_warnings(): warnings.filterwarnings("ignore") env_case2 = grid2op.make( @@ -2005,8 +1998,7 @@ def test_reco_disco_bus2(self): def test_reco_disco_bus3(self): self.skip_if_needed() # print("test_reco_disco_bus3") - backend = self.make_backend() - type(backend)._clear_class_attribute() + backend = self.make_backend_with_glue_code() with warnings.catch_warnings(): warnings.filterwarnings("ignore") env_case2 = grid2op.make( @@ -2030,8 +2022,7 @@ def test_reco_disco_bus3(self): def test_reco_disco_bus4(self): self.skip_if_needed() # print("test_reco_disco_bus4") - backend = self.make_backend() - type(backend)._clear_class_attribute() + backend = self.make_backend_with_glue_code() with warnings.catch_warnings(): warnings.filterwarnings("ignore") env_case2 = grid2op.make( @@ -2055,8 +2046,7 @@ def test_reco_disco_bus4(self): def test_reco_disco_bus5(self): self.skip_if_needed() # print("test_reco_disco_bus5") - backend = self.make_backend() - type(backend)._clear_class_attribute() + backend = self.make_backend_with_glue_code() with warnings.catch_warnings(): warnings.filterwarnings("ignore") env_case2 = grid2op.make( @@ -2078,8 +2068,7 @@ def test_reco_disco_bus5(self): class BaseTestShuntAction(MakeBackend): def test_shunt_ambiguous_id_incorrect(self): self.skip_if_needed() - backend = self.make_backend() - type(backend)._clear_class_attribute() + backend = self.make_backend_with_glue_code() with warnings.catch_warnings(): warnings.filterwarnings("ignore") with grid2op.make( @@ -2088,16 +2077,15 @@ def test_shunt_ambiguous_id_incorrect(self): gamerules_class=AlwaysLegal, action_class=CompleteAction, backend=backend, - _add_to_name=type(self).__name__ + _add_to_name=type(self).__name__ + "_1" ) as env_case2: with self.assertRaises(AmbiguousAction): act = env_case2.action_space({"shunt": {"set_bus": [(0, 2)]}}) def test_shunt_effect(self): self.skip_if_needed() - backend1 = self.make_backend() - backend2 = self.make_backend() - type(backend1)._clear_class_attribute() + backend1 = self.make_backend_with_glue_code() + backend2 = self.make_backend_with_glue_code() with warnings.catch_warnings(): warnings.filterwarnings("ignore") env_ref = grid2op.make( @@ -2106,7 +2094,7 @@ def test_shunt_effect(self): gamerules_class=AlwaysLegal, action_class=CompleteAction, backend=backend1, - _add_to_name=type(self).__name__ + _add_to_name=type(self).__name__ + "_2" ) env_change_q = grid2op.make( "rte_case14_realistic", @@ -2114,7 +2102,7 @@ def test_shunt_effect(self): gamerules_class=AlwaysLegal, action_class=CompleteAction, backend=backend2, - _add_to_name=type(self).__name__ + _add_to_name=type(self).__name__ + "_3" ) param = env_ref.parameters param.NO_OVERFLOW_DISCONNECTION = True @@ -2172,9 +2160,8 @@ def test_shunt_effect(self): class BaseTestResetEqualsLoadGrid(MakeBackend): def setUp(self): - backend1 = self.make_backend() - backend2 = self.make_backend() - type(backend1)._clear_class_attribute() + backend1 = self.make_backend_with_glue_code() + backend2 = self.make_backend_with_glue_code() with warnings.catch_warnings(): warnings.filterwarnings("ignore") self.env1 = grid2op.make("rte_case5_example", test=True, backend=backend1, _add_to_name=type(self).__name__) @@ -2306,8 +2293,7 @@ def test_obs_from_same_chronic(self): def test_combined_changes(self): # Unlimited sub changes - backend = self.make_backend() - type(backend)._clear_class_attribute() + backend = self.make_backend_with_glue_code() params = grid2op.Parameters.Parameters() params.MAX_SUB_CHANGED = 999 @@ -2378,8 +2364,7 @@ def aux_random_topos_act(self, env, n=128, r=2): class BaseTestVoltageOWhenDisco(MakeBackend): def test_this(self): self.skip_if_needed() - backend = self.make_backend() - type(backend)._clear_class_attribute() + backend = self.make_backend_with_glue_code() with warnings.catch_warnings(): warnings.filterwarnings("ignore") with grid2op.make("rte_case14_realistic", test=True, backend=backend, _add_to_name=type(self).__name__) as env: @@ -2394,8 +2379,7 @@ def test_this(self): class BaseTestChangeBusSlack(MakeBackend): def test_change_slack_case14(self): self.skip_if_needed() - backend = self.make_backend() - type(backend)._clear_class_attribute() + backend = self.make_backend_with_glue_code() with warnings.catch_warnings(): warnings.filterwarnings("ignore") env = grid2op.make("rte_case14_realistic", test=True, backend=backend, _add_to_name=type(self).__name__) @@ -2441,8 +2425,7 @@ def _aux_test_kirchoff(self): def test_there_are_storage(self): """test the backend properly loaded the storage units""" self.skip_if_needed() - backend = self.make_backend() - type(backend)._clear_class_attribute() + backend = self.make_backend_with_glue_code() with warnings.catch_warnings(): warnings.filterwarnings("ignore") self.env = grid2op.make("educ_case14_storage", test=True, backend=backend, _add_to_name=type(self).__name__) @@ -2451,8 +2434,7 @@ def test_there_are_storage(self): def test_storage_action_mw(self): """test the actions are properly implemented in the backend""" self.skip_if_needed() - backend = self.make_backend() - type(backend)._clear_class_attribute() + backend = self.make_backend_with_glue_code() with warnings.catch_warnings(): warnings.filterwarnings("ignore") self.env = grid2op.make("educ_case14_storage", test=True, backend=backend, _add_to_name=type(self).__name__) @@ -2522,8 +2504,7 @@ def test_storage_action_topo(self): param = Parameters() param.NB_TIMESTEP_COOLDOWN_SUB = 0 param.NB_TIMESTEP_COOLDOWN_LINE = 0 - backend = self.make_backend() - type(backend)._clear_class_attribute() + backend = self.make_backend_with_glue_code() with warnings.catch_warnings(): warnings.filterwarnings("ignore") self.env = grid2op.make( @@ -2671,8 +2652,7 @@ class BaseIssuesTest(MakeBackend): def test_issue_125(self): # https://github.com/rte-france/Grid2Op/issues/125 self.skip_if_needed() - backend = self.make_backend() - type(backend)._clear_class_attribute() + backend = self.make_backend_with_glue_code() with warnings.catch_warnings(): warnings.filterwarnings("ignore") env = grid2op.make("rte_case14_realistic", test=True, backend=backend, _add_to_name=type(self).__name__) @@ -2693,8 +2673,7 @@ def test_issue_125(self): def test_issue_134(self): self.skip_if_needed() - backend = self.make_backend() - type(backend)._clear_class_attribute() + backend = self.make_backend_with_glue_code() param = Parameters() param.NB_TIMESTEP_COOLDOWN_LINE = 0 @@ -2771,8 +2750,7 @@ def test_issue_134(self): def test_issue_134_check_ambiguity(self): self.skip_if_needed() - backend = self.make_backend() - type(backend)._clear_class_attribute() + backend = self.make_backend_with_glue_code() param = Parameters() param.MAX_LINE_STATUS_CHANGED = 9999 @@ -2801,8 +2779,7 @@ def test_issue_134_check_ambiguity(self): def test_issue_134_withcooldown_forrules(self): self.skip_if_needed() - backend = self.make_backend() - type(backend)._clear_class_attribute() + backend = self.make_backend_with_glue_code() param = Parameters() param.NB_TIMESTEP_COOLDOWN_LINE = 20 @@ -2943,8 +2920,7 @@ def test_issue_134_withcooldown_forrules(self): def test_issue_copyenv(self): # https://github.com/BDonnot/lightsim2grid/issues/10 - backend = self.make_backend() - type(backend)._clear_class_attribute() + backend = self.make_backend_with_glue_code() with warnings.catch_warnings(): warnings.filterwarnings("ignore") env1 = grid2op.make("rte_case14_realistic", test=True, backend=backend, _add_to_name=type(self).__name__) @@ -2956,8 +2932,7 @@ def test_issue_copyenv(self): class BaseStatusActions(MakeBackend): def _make_my_env(self): - backend = self.make_backend() - type(backend)._clear_class_attribute() + backend = self.make_backend_with_glue_code() param = Parameters() param.NB_TIMESTEP_COOLDOWN_LINE = 0 param.NB_TIMESTEP_COOLDOWN_SUB = 0 diff --git a/grid2op/tests/BaseRedispTest.py b/grid2op/tests/BaseRedispTest.py index f12087dd4..b6a4b6567 100644 --- a/grid2op/tests/BaseRedispTest.py +++ b/grid2op/tests/BaseRedispTest.py @@ -33,7 +33,7 @@ def get_casefile(self): def setUp(self): super().setUp() # powergrid - self.backend = self.make_backend() + self.backend = self.make_backend_with_glue_code() self.path_matpower = self.get_path() self.case_file = self.get_casefile() @@ -374,7 +374,7 @@ def get_casefile(self): def setUp(self): super().setUp() # powergrid - self.backend = self.make_backend() + self.backend = self.make_backend_with_glue_code() self.path_matpower = self.get_path() self.case_file = self.get_casefile() @@ -476,7 +476,7 @@ class BaseTestRedispTooLowHigh(MakeBackend): # test bug reported in issues https://github.com/rte-france/Grid2Op/issues/44 def setUp(self) -> None: super().setUp() - backend = self.make_backend() + backend = self.make_backend_with_glue_code() with warnings.catch_warnings(): warnings.filterwarnings("ignore") self.env = grid2op.make("rte_case14_redisp", @@ -574,7 +574,7 @@ class BaseTestDispatchRampingIllegalETC(MakeBackend): def setUp(self): super().setUp() # powergrid - backend = self.make_backend() + backend = self.make_backend_with_glue_code() with warnings.catch_warnings(): warnings.filterwarnings("ignore") self.env = grid2op.make("rte_case14_test", test=True, backend=backend, @@ -842,7 +842,7 @@ class BaseTestLoadingAcceptAlmostZeroSumRedisp(MakeBackend): def setUp(self): super().setUp() # powergrid - backend = self.make_backend() + backend = self.make_backend_with_glue_code() with warnings.catch_warnings(): warnings.filterwarnings("ignore") self.env = grid2op.make("rte_case14_test", test=True, backend=backend, diff --git a/grid2op/tests/aaa_test_backend_interface.py b/grid2op/tests/aaa_test_backend_interface.py index b320b0d44..e45361b04 100644 --- a/grid2op/tests/aaa_test_backend_interface.py +++ b/grid2op/tests/aaa_test_backend_interface.py @@ -9,6 +9,8 @@ import os import numpy as np import warnings +import grid2op +from grid2op.Backend import Backend from grid2op.tests.helper_path_test import HelperTests, MakeBackend, PATH_DATA from grid2op.Exceptions import BackendError, Grid2OpException @@ -36,9 +38,9 @@ def aux_get_env_name(self): """do not run nor modify ! (used for this test class only)""" return "BasicTest_load_grid_" + type(self).__name__ - def aux_make_backend(self): + def aux_make_backend(self) -> Backend: """do not run nor modify ! (used for this test class only)""" - backend = self.make_backend() + backend = self.make_backend_with_glue_code() backend.load_grid(self.get_path(), self.get_casefile()) backend.load_redispacthing_data("tmp") # pretend there is no generator backend.load_storage_data(self.get_path()) @@ -50,7 +52,7 @@ def aux_make_backend(self): def test_00create_backend(self): """Tests the backend can be created (not integrated in a grid2op environment yet)""" self.skip_if_needed() - backend = self.make_backend() + backend = self.make_backend_with_glue_code() def test_01load_grid(self): """Tests the grid can be loaded (supposes that your backend can read the grid.json in educ_case14_storage)* @@ -230,6 +232,8 @@ def test_06modify_shunt(self): cls = type(backend) if not cls.shunts_data_available: self.skipTest("Your backend does not support shunts") + if cls.n_shunt == 0: + self.skipTest("The grid you used for testing does not contain any shunts") init_shunt_p = np.array([0.0]) init_shunt_q = np.array([-19.]) @@ -577,6 +581,28 @@ def test_13_disco_reco_lines_pf_getter(self): assert not np.allclose(tmp_ex_reco[2][line_id], 0.), f"extremity voltage on connected line {line_id} is > 0." assert not np.allclose(tmp_ex_reco[3][line_id], 0.), f"extremity flow (amps) on connected line {line_id} is > 0." + def _aux_check_topo_vect(self, backend : Backend): + topo_vect = backend.get_topo_vect() + dim_topo = type(backend).dim_topo + assert len(topo_vect) == dim_topo, (f"backend.get_topo_vect() should return a vector of size 'dim_topo' " + f"({dim_topo}) but found size is {len(topo_vect)}. " + f"Remember: shunt are not part of the topo_vect") + assert np.all(topo_vect <= 2), (f"For simple environment, we suppose there are 2 buses per substation / voltage levels. " + f"topo_vect is supposed to give the id of the busbar (in the substation) to " + f"which the element is connected. This cannot be {np.max(topo_vect)}." + f"NB: this test is expected to fail if you test on a grid where more " + f"at least a substation can be split into (strictly) " + f"more than 2 independant buses.") + + assert np.all(topo_vect >= -1), (f"All element of topo_vect should be >= -1 (-1 meaning disconnected), " + f" or if it's a number >= 1 it's the id of the busbar") + + assert np.all(topo_vect != 0), (f"To avoid mixing the 'do not move an element' action and the " + f"id of a busbar, we decided that busbars labelling should start at 1 " + f"and not at 0. So there should not be any component of topo_vect that " + f"equals to 0.") + return topo_vect + def test_14change_topology(self): """try to change the topology of 2 different substations : connect their elements to different busbars and check consistency @@ -599,8 +625,11 @@ def test_14change_topology(self): cls = type(backend) res = backend.runpf(is_dc=False) + + _ = self._aux_check_topo_vect(backend) + if not cls.shunts_data_available: - warnings.warn(f"{type(self.__name__)} test_14change_topology: This test is not performed in depth as your backend does not support shunts") + warnings.warn(f"{type(self).__name__} test_14change_topology: This test is not performed in depth as your backend does not support shunts") else: p_subs, q_subs, p_bus, q_bus, diff_v_bus = backend.check_kirchoff() assert np.allclose(p_subs, 0., atol=3 * self.tol_one), "there are some discrepency in the backend after a powerflow (no modif): kirchoff laws are not met for p (creation or suppression of active). Check the handling of the slack bus(se) maybe ?" @@ -622,7 +651,7 @@ def test_14change_topology(self): assert res[0], "Your powerflow has diverged after the loading of the file, which should not happen" if not cls.shunts_data_available: - warnings.warn(f"{type(self.__name__)} test_14change_topology: This test is not performed in depth as your backend does not support shunts") + warnings.warn(f"{type(self).__name__} test_14change_topology: This test is not performed in depth as your backend does not support shunts") else: p_subs, q_subs, p_bus, q_bus, diff_v_bus = backend.check_kirchoff() assert np.allclose(p_subs, 0., atol=3 * self.tol_one), "there are some discrepency in the backend after a powerflow (modif with no impact): kirchoff laws are not met for p (creation or suppression of active)." @@ -648,7 +677,7 @@ def test_14change_topology(self): res = backend.runpf(is_dc=False) assert res[0], "Your powerflow has diverged after a topology action (but should not). Check `apply_action` for topology" if not cls.shunts_data_available: - warnings.warn(f"{type(self.__name__)} test_14change_topology: This test is not performed in depth as your backend does not support shunts") + warnings.warn(f"{type(self).__name__} test_14change_topology: This test is not performed in depth as your backend does not support shunts") else: p_subs, q_subs, p_bus, q_bus, diff_v_bus = backend.check_kirchoff() assert np.allclose(p_subs, 0., atol=3 * self.tol_one), "there are some discrepency in the backend after a powerflow (modif with a real impact): kirchoff laws are not met for p (creation or suppression of active)." @@ -722,8 +751,8 @@ def test_15_reset(self): assert np.allclose(v2_or, v_or), f"The v_or differ between its original value and after a reset. Check backend.reset()" assert np.allclose(a2_or, a_or), f"The a_or flow differ between its original value and after a reset. Check backend.reset()" - def test_16_isolated_load_make_divergence(self): - """Tests that an isolated load will make the method `run_pf` "diverge" (in AC and DC) [behaviour might change in the future] + def test_16_isolated_load_stops_computation(self): + """Tests that an isolated load will be spotted by the `run_pf` method and forwarded to grid2op by returining `False, an_exception` (in AC and DC) This test supposes that : @@ -731,6 +760,11 @@ def test_16_isolated_load_make_divergence(self): - backend.runpf() (AC and DC mode) is implemented - backend.apply_action() for topology modification - backend.reset() is implemented + + .. note:: + Currently this stops the computation of the environment and lead to a game over. + + This behaviour might change in the future. """ self.skip_if_needed() backend = self.aux_make_backend() @@ -746,7 +780,7 @@ def test_16_isolated_load_make_divergence(self): assert not res[0], "It is expected (at time of writing) that your backend returns `False` in case of isolated loads in AC." assert res[1] is not None, "When your backend diverges, we expect it throws an exception (second return value)" error = res[1] - assert isinstance(error, Grid2OpException), "When your backend return `False`, we expect it throws an exception inheriting from Grid2OpException (second return value)" + assert isinstance(error, Grid2OpException), f"When your backend return `False`, we expect it throws an exception inheriting from Grid2OpException (second return value), backend returned {type(error)}" if not isinstance(error, BackendError): warnings.warn("The error returned by your backend when it stopped (due to isolated shunt) should preferably inherit from BackendError") @@ -761,12 +795,12 @@ def test_16_isolated_load_make_divergence(self): assert not res[0], "It is expected (at time of writing) that your backend returns `False` in case of isolated loads in DC." assert res[1] is not None, "When your backend diverges, we expect it throws an exception (second return value)" error = res[1] - assert isinstance(error, Grid2OpException), "When your backend return `False`, we expect it throws an exception inheriting from Grid2OpException (second return value)" + assert isinstance(error, Grid2OpException), f"When your backend return `False`, we expect it throws an exception inheriting from Grid2OpException (second return value), backend returned {type(error)}" if not isinstance(error, BackendError): warnings.warn("The error returned by your backend when it stopped (due to isolated shunt) should preferably inherit from BackendError") - def test_17_isolated_gen_make_divergence(self): - """Tests that an isolated generator will make the method `run_pf` "diverge" (in AC and DC) [behaviour might change in the future] + def test_17_isolated_gen_stops_computation(self): + """Tests that an isolated generator will be spotted by the `run_pf` method and forwarded to grid2op by returining `False, an_exception` (in AC and DC) This test supposes that : @@ -774,6 +808,11 @@ def test_17_isolated_gen_make_divergence(self): - backend.runpf() (AC and DC mode) is implemented - backend.apply_action() for topology modification - backend.reset() is implemented + + .. note:: + Currently this stops the computation of the environment and lead to a game over. + + This behaviour might change in the future. """ self.skip_if_needed() backend = self.aux_make_backend() @@ -789,7 +828,7 @@ def test_17_isolated_gen_make_divergence(self): assert not res[0], "It is expected (at time of writing) that your backend returns `False` in case of isolated gen." assert res[1] is not None, "When your backend diverges, we expect it throws an exception (second return value)" error = res[1] - assert isinstance(error, Grid2OpException), "When your backend return `False`, we expect it throws an exception inheriting from Grid2OpException (second return value)" + assert isinstance(error, Grid2OpException), f"When your backend return `False`, we expect it throws an exception inheriting from Grid2OpException (second return value), backend returned {type(error)}" if not isinstance(error, BackendError): warnings.warn("The error returned by your backend when it stopped (due to isolated shunt) should preferably inherit from BackendError") @@ -804,12 +843,12 @@ def test_17_isolated_gen_make_divergence(self): assert not res[0], "It is expected (at time of writing) that your backend returns `False` in case of isolated gen." assert res[1] is not None, "When your backend diverges, we expect it throws an exception (second return value)" error = res[1] - assert isinstance(error, Grid2OpException), "When your backend return `False`, we expect it throws an exception inheriting from Grid2OpException (second return value)" + assert isinstance(error, Grid2OpException), f"When your backend return `False`, we expect it throws an exception inheriting from Grid2OpException (second return value), backend returned {type(error)}" if not isinstance(error, BackendError): warnings.warn("The error returned by your backend when it stopped (due to isolated shunt) should preferably inherit from BackendError") - def test_18_isolated_shunt_make_divergence(self): - """Tests test that an isolated shunt will make the method `run_pf` "diverge" (in AC and DC) [behaviour might change in the future] + def test_18_isolated_shunt_stops_computation(self): + """Tests test that an isolated shunt will be spotted by the `run_pf` method and forwarded to grid2op by returining `False, an_exception` (in AC and DC) This test supposes that : @@ -819,6 +858,11 @@ def test_18_isolated_shunt_make_divergence(self): - backend.reset() is implemented NB: this test is skipped if your backend does not (yet :-) ) supports shunt + + .. note:: + Currently this stops the computation of the environment and lead to a game over. + + This behaviour might change in the future. """ self.skip_if_needed() backend = self.aux_make_backend() @@ -838,7 +882,7 @@ def test_18_isolated_shunt_make_divergence(self): assert not res[0], "It is expected (at time of writing) that your backend returns `False` in case of isolated shunt." assert res[1] is not None, "When your backend diverges, we expect it throws an exception (second return value)" error = res[1] - assert isinstance(error, Grid2OpException), "When your backend return `False`, we expect it throws an exception inheriting from Grid2OpException (second return value)" + assert isinstance(error, Grid2OpException), f"When your backend return `False`, we expect it throws an exception inheriting from Grid2OpException (second return value), backend returned {type(error)}" if not isinstance(error, BackendError): warnings.warn("The error returned by your backend when it stopped (due to isolated shunt) should preferably inherit from BackendError") @@ -853,12 +897,12 @@ def test_18_isolated_shunt_make_divergence(self): assert not res[0], "It is expected (at time of writing) that your backend returns `False` in case of isolated shunt in DC." assert res[1] is not None, "When your backend stops, we expect it throws an exception (second return value)" error = res[1] - assert isinstance(error, Grid2OpException), "When your backend returns `False`, we expect it throws an exception inheriting from Grid2OpException (second return value)" + assert isinstance(error, Grid2OpException), f"When your backend returns `False`, we expect it throws an exception inheriting from Grid2OpException (second return value), backend returned {type(error)}" if not isinstance(error, BackendError): warnings.warn("The error returned by your backend when it stopped (due to isolated shunt) should preferably inherit from BackendError") - def test_19_isolated_storage_make_divergence(self): - """Teststest that an isolated storage unit will make the method `run_pf` "diverge" (in AC and DC) [behaviour might change in the future] + def test_19_isolated_storage_stops_computation(self): + """Teststest that an isolated storage unit will be spotted by the `run_pf` method and forwarded to grid2op by returining `False, an_exception` (in AC and DC) This test supposes that : @@ -868,6 +912,11 @@ def test_19_isolated_storage_make_divergence(self): - backend.reset() is implemented NB: this test is skipped if your backend does not (yet :-) ) supports storage units + + .. note:: + Currently this stops the computation of the environment and lead to a game over. + + This behaviour might change in the future. """ self.skip_if_needed() backend = self.aux_make_backend() @@ -884,7 +933,7 @@ def test_19_isolated_storage_make_divergence(self): assert not res[0], "It is expected (at time of writing) that your backend returns `False` in case of isolated storage units in AC." assert res[1] is not None, "When your backend stops, we expect it throws an exception (second return value)" error = res[1] - assert isinstance(error, Grid2OpException), "When your backend return `False`, we expect it throws an exception inheriting from Grid2OpException (second return value)" + assert isinstance(error, Grid2OpException), f"When your backend return `False`, we expect it throws an exception inheriting from Grid2OpException (second return value), backend returned {type(error)}" if not isinstance(error, BackendError): warnings.warn("The error returned by your backend when it stopped (due to isolated storage units) should preferably inherit from BackendError") @@ -898,12 +947,12 @@ def test_19_isolated_storage_make_divergence(self): assert not res[0], "It is expected (at time of writing) that your backend returns `False` in case of isolated storage unit." assert res[1] is not None, "When your backend stops, we expect it throws an exception (second return value)" error = res[1] - assert isinstance(error, Grid2OpException), "When your backend return `False`, we expect it throws an exception inheriting from Grid2OpException (second return value)" + assert isinstance(error, Grid2OpException), f"When your backend return `False`, we expect it throws an exception inheriting from Grid2OpException (second return value), backend returned {type(error)}" if not isinstance(error, BackendError): warnings.warn("The error returned by your backend when it stopped (due to isolated storage units) should preferably inherit from BackendError") - def test_20_disconnected_load_make_divergence(self): - """Tests that a disconnected load unit will make the method `run_pf` "diverge" (in AC and DC) [behaviour might change in the future] + def test_20_disconnected_load_stops_computation(self): + """Tests that a disconnected load unit will be spotted by the `run_pf` method and forwarded to grid2op by returining `False, an_exception` (in AC and DC) This test supposes that : @@ -913,6 +962,11 @@ def test_20_disconnected_load_make_divergence(self): - backend.reset() is implemented NB: this test is skipped if your backend does not (yet :-) ) supports storage units + + .. note:: + Currently this stops the computation of the environment and lead to a game over. + + This behaviour might change in the future. """ self.skip_if_needed() backend = self.aux_make_backend() @@ -927,7 +981,7 @@ def test_20_disconnected_load_make_divergence(self): assert not res[0], "It is expected (at time of writing) that your backend returns `False` in case of disconnected load in AC." assert res[1] is not None, "When your backend stops, we expect it throws an exception (second return value)" error = res[1] - assert isinstance(error, Grid2OpException), "When your backend return `False`, we expect it throws an exception inheriting from Grid2OpException (second return value)" + assert isinstance(error, Grid2OpException), f"When your backend return `False`, we expect it throws an exception inheriting from Grid2OpException (second return value), backend returned {type(error)}" if not isinstance(error, BackendError): warnings.warn("The error returned by your backend when it stopped (due to disconnected load) should preferably inherit from BackendError") @@ -942,12 +996,12 @@ def test_20_disconnected_load_make_divergence(self): assert not res[0], "It is expected (at time of writing) that your backend returns `False` in case of disconnected load in DC." assert res[1] is not None, "When your backend stops, we expect it throws an exception (second return value)" error = res[1] - assert isinstance(error, Grid2OpException), "When your backend return `False`, we expect it throws an exception inheriting from Grid2OpException (second return value)" + assert isinstance(error, Grid2OpException), f"When your backend return `False`, we expect it throws an exception inheriting from Grid2OpException (second return value), backend returned {type(error)}" if not isinstance(error, BackendError): warnings.warn("The error returned by your backend when it stopped (due to disconnected load) should preferably inherit from BackendError") - def test_21_disconnected_gen_make_divergence(self): - """Tests that a disconnected generator will make the method `run_pf` "diverge" (in AC and DC) [behaviour might change in the future] + def test_21_disconnected_gen_stops_computation(self): + """Tests that a disconnected generator will be spotted by the `run_pf` method and forwarded to grid2op by returining `False, an_exception` (in AC and DC) This test supposes that : @@ -957,6 +1011,11 @@ def test_21_disconnected_gen_make_divergence(self): - backend.reset() is implemented NB: this test is skipped if your backend does not (yet :-) ) supports storage units + + .. note:: + Currently this stops the computation of the environment and lead to a game over. + + This behaviour might change in the future. """ self.skip_if_needed() backend = self.aux_make_backend() @@ -971,7 +1030,7 @@ def test_21_disconnected_gen_make_divergence(self): assert not res[0], "It is expected (at time of writing) that your backend returns `False` in case of disconnected gen in AC." assert res[1] is not None, "When your backend stops, we expect it throws an exception (second return value)" error = res[1] - assert isinstance(error, Grid2OpException), "When your backend return `False`, we expect it throws an exception inheriting from Grid2OpException (second return value)" + assert isinstance(error, Grid2OpException), f"When your backend return `False`, we expect it throws an exception inheriting from Grid2OpException (second return value), backend returned {type(error)}" if not isinstance(error, BackendError): warnings.warn("The error returned by your backend when it stopped (due to disconnected gen) should preferably inherit from BackendError") @@ -986,15 +1045,15 @@ def test_21_disconnected_gen_make_divergence(self): assert not res[0], "It is expected (at time of writing) that your backend returns `False` in case of disconnected gen in DC." assert res[1] is not None, "When your backend stops, we expect it throws an exception (second return value)" error = res[1] - assert isinstance(error, Grid2OpException), "When your backend return `False`, we expect it throws an exception inheriting from Grid2OpException (second return value)" + assert isinstance(error, Grid2OpException), f"When your backend return `False`, we expect it throws an exception inheriting from Grid2OpException (second return value), backend returned {type(error)}" if not isinstance(error, BackendError): warnings.warn("The error returned by your backend when it stopped (due to disconnected gen) should preferably inherit from BackendError") - def test_22_islanded_grid_make_divergence(self): - """Tests that when the grid is split in two different "sub_grid" it makes the runpf diverge both in AC and DC + def test_22_islanded_grid_stops_computation(self): + """Tests that when the grid is split in two different "sub_grid" is spotted by the `run_pf` method and forwarded to grid2op by returining `False, an_exception` (in AC and DC) For information, this is suppose to make a subgrid with substation 5, 11 and 12 on one side - and all the rest on the other. + and all the rest on the other (and works only for educ_case14_storage grid or equivalent). This test supposes that : @@ -1005,6 +1064,11 @@ def test_22_islanded_grid_make_divergence(self): - backend.reset() is implemented NB: this test is skipped if your backend does not (yet :-) ) supports storage units + + .. note:: + Currently this stops the computation of the environment and lead to a game over. + + This behaviour might change in the future. """ self.skip_if_needed() backend = self.aux_make_backend() @@ -1018,7 +1082,7 @@ def test_22_islanded_grid_make_divergence(self): res = backend.runpf(is_dc=False) assert not res[0], "It is expected that your backend return `False` in case of non connected grid in AC." error = res[1] - assert isinstance(error, Grid2OpException), "When your backend return `False`, we expect it throws an exception inheriting from Grid2OpException (second return value)" + assert isinstance(error, Grid2OpException), f"When your backend return `False`, we expect it throws an exception inheriting from Grid2OpException (second return value), backend returned {type(error)}" if not isinstance(error, BackendError): warnings.warn("The error returned by your backend when it stopped (due to non connected grid) should preferably inherit from BackendError") backend.reset(self.get_path(), self.get_casefile()) @@ -1034,7 +1098,7 @@ def test_22_islanded_grid_make_divergence(self): res = backend.runpf(is_dc=True) assert not res[0], "It is expected that your backend throws an exception inheriting from BackendError in case of non connected grid in DC." error = res[1] - assert isinstance(error, Grid2OpException), "When your backend return `False`, we expect it throws an exception inheriting from Grid2OpException (second return value)" + assert isinstance(error, Grid2OpException), f"When your backend return `False`, we expect it throws an exception inheriting from Grid2OpException (second return value), backend returned {type(error)}" if not isinstance(error, BackendError): warnings.warn("The error returned by your backend when it stopped (due to non connected grid) should preferably inherit from BackendError") @@ -1215,4 +1279,256 @@ def test_26_copy(self): p_or_cpy, *_ = backend_cpy.lines_or_info() assert not np.allclose(p_or, p_or_cpy), (f"The p_or for your backend and its copy are identical though one has been modify and not the other. " "It is likely that backend.copy implementation does not perform a deep copy") - \ No newline at end of file + + def test_27_topo_vect_disconnect(self): + """Tests that the topo_vect vector is properly computed in some + atomic cases (disconnection of elements that can be disconnected) + + This test supposes that : + + - backend.load_grid(...) is implemented + - backend.runpf() (AC mode) is implemented + - backend.apply_action() for all types of action + - backend.reset() is implemented + - backend.get_topo_vect() is implemented + + NB: part of this test is skipped if your backend does not support shunts + NB: part of this test is skipped if your backend does not support storage units + or if there are no storage units on the grid you test it on. + + """ + self.skip_if_needed() + backend = self.aux_make_backend() + cls = type(backend) + + res = backend.runpf(is_dc=False) + topo_vect_orig = self._aux_check_topo_vect(backend) + + # disconnect line + line_id = 0 + backend.reset(self.get_path(), self.get_casefile()) + action = type(backend)._complete_action_class() + action.update({"set_line_status": [(line_id, -1)]}) + bk_act = type(backend).my_bk_act_class() + bk_act += action + backend.apply_action(bk_act) + res = backend.runpf(is_dc=False) + topo_vect = self._aux_check_topo_vect(backend) + error_msg = (f"Line {line_id} has been disconnected, yet according to 'topo_vect' " + f"is still connected (origin side) to busbar {topo_vect[cls.line_or_pos_topo_vect[line_id]]}") + assert topo_vect[cls.line_or_pos_topo_vect[line_id]] == -1, error_msg + error_msg = (f"Line {line_id} has been disconnected, yet according to 'topo_vect' " + f"is still connected (ext side) to busbar {topo_vect[cls.line_ex_pos_topo_vect[line_id]]}") + assert topo_vect[cls.line_ex_pos_topo_vect[line_id]] == -1, error_msg + + # disconnect storage + if cls.n_storage > 0: + sto_id = 0 + backend.reset(self.get_path(), self.get_casefile()) + action = type(backend)._complete_action_class() + action.update({"set_bus": {"storages_id": [(sto_id, -1)]}}) + bk_act = type(backend).my_bk_act_class() + bk_act += action + backend.apply_action(bk_act) + res = backend.runpf(is_dc=False) + topo_vect = self._aux_check_topo_vect(backend) + error_msg = (f"Storage {sto_id} has been disconnected, yet according to 'topo_vect' " + f"is still connected (origin side) to busbar {topo_vect[cls.storage_pos_topo_vect[line_id]]}") + assert topo_vect[cls.storage_pos_topo_vect[sto_id]] == -1, error_msg + else: + warnings.warn(f"{type(self).__name__} test_27_topo_vect_disconnect: This test is not performed in depth as your backend does not support storage units (or there are none on the grid)") + + # disconnect shunt + if not cls.shunts_data_available: + warnings.warn(f"{type(self).__name__} test_27_topo_vect_disconnect: This test is not performed in depth as your backend does not support shunts data") + elif cls.n_shunt == 0: + warnings.warn(f"{type(self).__name__} test_27_topo_vect_disconnect The grid you used for testing does not contain any shunt, this test is not performed in depth") + else: + # so cls.shunts_data_available and cls.n_shunt >= 1 + shunt_id = 0 + backend.reset(self.get_path(), self.get_casefile()) + action = type(backend)._complete_action_class() + action.update({"shunt": {"shunt_bus": [(shunt_id, -1)]}}) + bk_act = type(backend).my_bk_act_class() + bk_act += action + backend.apply_action(bk_act) + res = backend.runpf(is_dc=False) + topo_vect = self._aux_check_topo_vect(backend) + error_msg = (f"Disconnecting a shunt should have no impact on the topo_vect vector " + f"as shunt are not taken into account in this") + assert (topo_vect == topo_vect_orig).all(), error_msg + + def _aux_aux_get_line(self, el_id, el_to_subid, line_xx_to_subid): + sub_id = el_to_subid[el_id] + if (line_xx_to_subid == sub_id).sum() >= 2: + return True, np.where(line_xx_to_subid == sub_id)[0][0] + elif (line_xx_to_subid == sub_id).sum() == 1: + return False, np.where(line_xx_to_subid == sub_id)[0][0] + else: + return None + + def _aux_get_lines(self, cls, el_id, el_to_subid): + or_id = None + ex_id = None + + line_or_maybe = self._aux_aux_get_line(el_id, el_to_subid, cls.line_or_to_subid) + if line_or_maybe is not None: + can_do_or, or_id = line_or_maybe + if can_do_or: + return or_id, ex_id + line_ex_maybe = self._aux_aux_get_line(el_id, el_to_subid, cls.line_ex_to_subid) + + if line_ex_maybe is None: + if line_or_maybe is None: + # not possible for this el_id + return None + if not can_do_or: + # only one line to this substation (or side) + return None + else: + # line_ex_maybe is not None + if line_or_maybe is None: + # only one line to this substation (ex side) + return None + can_do_ex, ex_id = line_ex_maybe + if can_do_ex: + # 2 ext lines are connected I return 1 + return None, ex_id + else: + # one "or" and one "ex" I return the or + return or_id, None + + def _aux_check_el_generic(self, backend, busbar_id, + nb_el, el_to_subid, + el_nm, el_key, el_pos_topo_vect): + cls = type(backend) + # try to find a line with which an element of this type can be moved + # we do that to avoid avoid isolated element on the grid + res = None + el_id = -1 + while res is None: + el_id += 1 + if el_id >= nb_el: + break + res = self._aux_get_lines(cls, el_id, el_to_subid) + if res is None: + # there would be an isolated element if I move all element of this type, + # I cannot perform the test, probably a more suitable grid could be used. + warnings.warn(f"{type(self).__name__} test_28_topo_vect_set: The grid you provide does not " + f"allow to set_bus with {el_nm}, because no {el_nm} is " + f"connected to a substation with at least 2 powerlines. " + f"You need to change the powergrid used for this test if you " + f"want to perform it in depth.") + return + + # prepare the action to move the element and the line + or_id, ex_id = res + if or_id is not None: + key_ = "lines_or_id" + val = [(or_id, busbar_id)] + else: + key_ = "lines_ex_id" + val = [(ex_id, busbar_id)] + + action = type(backend)._complete_action_class() + action.update({"set_bus": { + el_key: [(el_id, busbar_id)], # move the element + key_: val # move the line + }}) + bk_act = type(backend).my_bk_act_class() + bk_act += action + backend.apply_action(bk_act) # apply the action + res = backend.runpf(is_dc=False) + # now check the topology vector + topo_vect = self._aux_check_topo_vect(backend) + error_msg = (f"{el_nm} {el_id} has been moved to busbar {busbar_id}, yet according to 'topo_vect' " + f"it is connected to busbar {topo_vect[el_pos_topo_vect[el_id]]}") + + assert topo_vect[el_pos_topo_vect[el_id]] == busbar_id, error_msg + + def test_28_topo_vect_set(self): + """Tests that the topo_vect vector is properly computed in some + atomic cases (moved elements) + + This test supposes that : + + - backend.load_grid(...) is implemented + - backend.runpf() (AC mode) is implemented + - backend.apply_action() for all types of action + - backend.reset() is implemented + - backend.get_topo_vect() is implemented + + """ + self.skip_if_needed() + backend = self.aux_make_backend() + cls = type(backend) + + res = backend.runpf(is_dc=False) + topo_vect_orig = self._aux_check_topo_vect(backend) + + # line or + line_id = 0 + busbar_id = 2 + backend.reset(self.get_path(), self.get_casefile()) + action = type(backend)._complete_action_class() + action.update({"set_bus": {"lines_or_id": [(line_id, busbar_id)]}}) + bk_act = type(backend).my_bk_act_class() + bk_act += action + backend.apply_action(bk_act) + res = backend.runpf(is_dc=False) + topo_vect = self._aux_check_topo_vect(backend) + error_msg = (f"Line {line_id} (or. side) has been moved to busbar {busbar_id}, yet according to 'topo_vect' " + f"is still connected (origin side) to busbar {topo_vect[cls.line_or_pos_topo_vect[line_id]]}") + assert topo_vect[cls.line_or_pos_topo_vect[line_id]] == busbar_id, error_msg + + # line ex + line_id = 0 + busbar_id = 2 + backend.reset(self.get_path(), self.get_casefile()) + action = type(backend)._complete_action_class() + action.update({"set_bus": {"lines_ex_id": [(line_id, busbar_id)]}}) + bk_act = type(backend).my_bk_act_class() + bk_act += action + backend.apply_action(bk_act) + res = backend.runpf(is_dc=False) + topo_vect = self._aux_check_topo_vect(backend) + error_msg = (f"Line {line_id} (ex. side) has been moved to busbar {busbar_id}, yet according to 'topo_vect' " + f"is still connected (ext side) to busbar {topo_vect[cls.line_ex_pos_topo_vect[line_id]]}") + assert topo_vect[cls.line_ex_pos_topo_vect[line_id]] == busbar_id, error_msg + + # load + backend.reset(self.get_path(), self.get_casefile()) + busbar_id = 2 + nb_el = cls.n_load + el_to_subid = cls.load_to_subid + el_nm = "load" + el_key = "loads_id" + el_pos_topo_vect = cls.load_pos_topo_vect + self._aux_check_el_generic(backend, busbar_id, nb_el, el_to_subid, + el_nm, el_key, el_pos_topo_vect) + + # generator + backend.reset(self.get_path(), self.get_casefile()) + busbar_id = 2 + nb_el = cls.n_gen + el_to_subid = cls.gen_to_subid + el_nm = "generator" + el_key = "generators_id" + el_pos_topo_vect = cls.gen_pos_topo_vect + self._aux_check_el_generic(backend, busbar_id, nb_el, el_to_subid, + el_nm, el_key, el_pos_topo_vect) + + # storage + if cls.n_storage > 0: + backend.reset(self.get_path(), self.get_casefile()) + busbar_id = 2 + nb_el = cls.n_storage + el_to_subid = cls.storage_to_subid + el_nm = "storage" + el_key = "storages_id" + el_pos_topo_vect = cls.storage_pos_topo_vect + self._aux_check_el_generic(backend, busbar_id, nb_el, el_to_subid, + el_nm, el_key, el_pos_topo_vect) + else: + warnings.warn(f"{type(self).__name__} test_28_topo_vect_set: This test is not performed in depth as your backend does not support storage units (or there are none on the grid)") + \ No newline at end of file diff --git a/grid2op/tests/helper_path_test.py b/grid2op/tests/helper_path_test.py index f1ad50281..683b65bd8 100644 --- a/grid2op/tests/helper_path_test.py +++ b/grid2op/tests/helper_path_test.py @@ -63,6 +63,13 @@ class MakeBackend(ABC, HelperTests): def make_backend(self, detailed_infos_for_cascading_failures=False) -> Backend: pass + def make_backend_with_glue_code(self, detailed_infos_for_cascading_failures=False, extra_name="") -> Backend: + Backend._clear_class_attribute() + bk = self.make_backend(detailed_infos_for_cascading_failures=detailed_infos_for_cascading_failures) + type(bk)._clear_grid_dependant_class_attributes() + type(bk).set_env_name(type(self).__name__ + extra_name) + return bk + def get_path(self) -> str: raise NotImplementedError( "This function should be implemented for the test suit you are developping" diff --git a/grid2op/tests/test_Action.py b/grid2op/tests/test_Action.py index e9f8bf5b1..5de72f7b9 100644 --- a/grid2op/tests/test_Action.py +++ b/grid2op/tests/test_Action.py @@ -27,9 +27,6 @@ # TODO check that if i set the element of a powerline to -1, then it's working as intended (disconnect both ends) -import pdb - - def _get_action_grid_class(): GridObjects.env_name = "test_action_env" GridObjects.n_gen = 5 @@ -387,7 +384,8 @@ def setUp(self): def tearDown(self): self.authorized_keys = {} - self.gridobj._clear_class_attribute() + type(self.gridobj)._clear_class_attribute() + GridObjects._clear_class_attribute() def test_reset_modified_flags(self): act = self.helper_action.sample() @@ -874,9 +872,9 @@ def test_to_vect(self): tmp[-action.n_gen :] = -1 # compute the "set_bus" vect - id_set = np.where(np.array(action.attr_list_vect) == "_set_topo_vect")[0][0] + id_set = np.where(np.array(type(action).attr_list_vect) == "_set_topo_vect")[0][0] size_before = 0 - for el in action.attr_list_vect[:id_set]: + for el in type(action).attr_list_vect[:id_set]: arr_ = action._get_array_from_attr_name(el) size_before += arr_.shape[0] tmp[size_before : (size_before + action.dim_topo)] = np.array( @@ -941,11 +939,11 @@ def test_to_vect(self): 0, ] ) - id_change = np.where(np.array(action.attr_list_vect) == "_change_bus_vect")[0][ + id_change = np.where(np.array(type(action).attr_list_vect) == "_change_bus_vect")[0][ 0 ] size_before = 0 - for el in action.attr_list_vect[:id_change]: + for el in type(action).attr_list_vect[:id_change]: arr_ = action._get_array_from_attr_name(el) size_before += arr_.shape[0] tmp[size_before : (size_before + action.dim_topo)] = 1.0 * np.array( @@ -1448,11 +1446,11 @@ def test_to_from_vect_action(self): def test_sum_shape_equal_size(self): act = self.helper_action({}) - assert act.size() == np.sum(act.shape()) + assert act.size() == np.sum(act.shapes()) def test_shape_correct(self): act = self.helper_action({}) - assert act.shape().shape == act.dtype().shape + assert act.shapes().shape == act.dtypes().shape def test_redispatching(self): self._skipMissingKey("redispatch") diff --git a/grid2op/tests/test_BackendAction.py b/grid2op/tests/test_BackendAction.py index b773404cd..84486f512 100644 --- a/grid2op/tests/test_BackendAction.py +++ b/grid2op/tests/test_BackendAction.py @@ -72,7 +72,7 @@ def apply_action(self, backendAction=None): if np.any(load_q.changed): tmp_load_q.iloc[load_q.changed] = load_q.values[load_q.changed] - if self.shunts_data_available: + if type(self).shunts_data_available: shunt_p, shunt_q, shunt_bus = shunts__ if np.any(shunt_p.changed): diff --git a/grid2op/tests/test_Environment.py b/grid2op/tests/test_Environment.py index 1cd2eee78..ac1e96df5 100644 --- a/grid2op/tests/test_Environment.py +++ b/grid2op/tests/test_Environment.py @@ -530,7 +530,7 @@ def test_reset_after_blackout_withdetailed_info(self, env=None): obs, reward, done, info = env.step(env.action_space()) # at this stage there is a cascading failure assert len(info["exception"]) - assert isinstance(info["exception"][0], DivergingPowerFlow) + assert isinstance(info["exception"][0], BackendError) assert "detailed_infos_for_cascading_failures" in info assert len(info["detailed_infos_for_cascading_failures"]) # reset the grid diff --git a/grid2op/tests/test_Observation.py b/grid2op/tests/test_Observation.py index 944653f1b..7019c87fc 100644 --- a/grid2op/tests/test_Observation.py +++ b/grid2op/tests/test_Observation.py @@ -34,10 +34,6 @@ # temporary deactivation of all the failing test until simulate is fixed DEACTIVATE_FAILING_TEST = False -import warnings - -warnings.simplefilter("error") - class TestBasisObsBehaviour(unittest.TestCase): def setUp(self): @@ -50,7 +46,10 @@ def setUp(self): with warnings.catch_warnings(): warnings.filterwarnings("ignore") - self.env = grid2op.make("rte_case14_test", test=True, _add_to_name=type(self).__name__) + self.env = grid2op.make("rte_case14_test", + test=True, + _add_to_name=type(self).__name__) + self.dict_ = { "name_gen": ["gen_1_0", "gen_2_1", "gen_5_2", "gen_7_3", "gen_0_4"], "name_load": [ @@ -992,7 +991,7 @@ def tearDown(self): def test_sum_shape_equal_size(self): obs = self.env.observation_space(self.env) - assert obs.size() == np.sum(obs.shape()) + assert obs.size() == np.sum(obs.shapes()) def test_sub_topology(self): """test the sub_topology function""" @@ -2013,19 +2012,21 @@ def test_observation_space(self): def test_shape_correct(self): obs = self.env.observation_space(self.env) - assert obs.shape().shape == obs.dtype().shape - assert np.all(obs.dtype() == self.dtypes) - assert np.all(obs.shape() == self.shapes) + assert obs.shapes().shape == obs.dtypes().shape + assert np.all(obs.dtypes() == self.dtypes) + assert np.all(obs.shapes() == self.shapes) def test_0_load_properly(self): # this test aims at checking that everything in setUp is working properly, eg that "ObsEnv" class has enough # information for example - pass + assert type(self.env).shunts_data_available def test_1_generating_obs(self): # test that helper_obs is abl to generate a valid observation + assert type(self.env).shunts_data_available obs = self.env.observation_space(self.env) - pass + assert type(self.env).shunts_data_available + assert type(obs).shunts_data_available def test_2_reset(self): # test that helper_obs is abl to generate a valid observation @@ -2033,8 +2034,8 @@ def test_2_reset(self): assert obs.prod_p[0] is not None obs.reset() assert np.all(np.isnan(obs.prod_p)) - assert np.all(obs.dtype() == self.dtypes) - assert np.all(obs.shape() == self.shapes) + assert np.all(obs.dtypes() == self.dtypes) + assert np.all(obs.shapes() == self.shapes) def test_3_reset(self): # test that helper_obs is able to generate a valid observation @@ -2043,15 +2044,15 @@ def test_3_reset(self): assert obs == obs2 obs2.reset() assert np.all(np.isnan(obs2.prod_p)) - assert np.all(obs2.dtype() == self.dtypes) - assert np.all(obs2.shape() == self.shapes) + assert np.all(obs2.dtypes() == self.dtypes) + assert np.all(obs2.shapes() == self.shapes) # assert obs.prod_p is not None def test_shapes_types(self): obs = self.env.observation_space(self.env) - dtypes = obs.dtype() + dtypes = obs.dtypes() assert np.all(dtypes == self.dtypes) - shapes = obs.shape() + shapes = obs.shapes() assert np.all(shapes == self.shapes) def test_4_to_from_vect(self): @@ -2062,8 +2063,8 @@ def test_4_to_from_vect(self): assert vect.shape[0] == obs.size() obs2.reset() obs2.from_vect(vect) - assert np.all(obs.dtype() == self.dtypes) - assert np.all(obs.shape() == self.shapes) + assert np.all(obs.dtypes() == self.dtypes) + assert np.all(obs.shapes() == self.shapes) # TODO there is not reason that these 2 are equal: reset, will erase everything # TODO whereas creating the observation diff --git a/grid2op/tests/test_Runner.py b/grid2op/tests/test_Runner.py index 3f07aa996..1d8dcd233 100644 --- a/grid2op/tests/test_Runner.py +++ b/grid2op/tests/test_Runner.py @@ -501,6 +501,12 @@ def test_backward_compatibility(self): "1.8.1", # "1.9.0", # this one is bugy I don"t know why "1.9.1", + "1.9.2", + "1.9.3", + "1.9.4", + "1.9.5", + "1.9.6", + "1.9.7", ] curr_version = "test_version" assert ( diff --git a/grid2op/tests/test_act_as_serializable_dict.py b/grid2op/tests/test_act_as_serializable_dict.py index e9590714f..f15f6fae1 100644 --- a/grid2op/tests/test_act_as_serializable_dict.py +++ b/grid2op/tests/test_act_as_serializable_dict.py @@ -118,7 +118,7 @@ def _action_setup(self): def tearDown(self): self.authorized_keys = {} - self.gridobj._clear_class_attribute() + type(self.gridobj)._clear_class_attribute() ActionSpace._clear_class_attribute() def setUp(self): diff --git a/grid2op/tests/test_env_diff_format.py b/grid2op/tests/test_env_diff_format.py index ea1f7e3f3..d8cd88456 100644 --- a/grid2op/tests/test_env_diff_format.py +++ b/grid2op/tests/test_env_diff_format.py @@ -46,7 +46,7 @@ def make_backend(self, detailed_infos_for_cascading_failures=False): return backend def setUp(self): - self.tests_skipped = ("test_01load_grid", "test_22_islanded_grid_make_divergence") + self.tests_skipped = ("test_01load_grid", "test_22_islanded_grid_stops_computation") return super().setUp() diff --git a/grid2op/tests/test_issue_164.py b/grid2op/tests/test_issue_164.py index 6af4c210b..c9817affc 100644 --- a/grid2op/tests/test_issue_164.py +++ b/grid2op/tests/test_issue_164.py @@ -12,7 +12,6 @@ import grid2op from grid2op.Reward import BaseReward from grid2op.dtypes import dt_float -from grid2op.Exceptions import DivergingPowerFlow class Test164_Reward(BaseReward): diff --git a/grid2op/tests/test_issue_550.py b/grid2op/tests/test_issue_550.py new file mode 100644 index 000000000..7b5f3c553 --- /dev/null +++ b/grid2op/tests/test_issue_550.py @@ -0,0 +1,46 @@ +# Copyright (c) 2023, 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 grid2op +from grid2op.Backend import PandaPowerBackend +import warnings +import unittest + + +class PandaPowerNoShunt_Test550(PandaPowerBackend): + shunts_data_available = False # class attribute (only one used) + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + +class Issue550Tester(unittest.TestCase): + def test_no_shunt(self): + with warnings.catch_warnings(): + warnings.filterwarnings("ignore") + env = grid2op.make("l2rpn_case14_sandbox", + test=True, + backend=PandaPowerNoShunt_Test550(), + _add_to_name=type(self).__name__) + obs_init = env.reset() + assert not type(obs_init).shunts_data_available + assert not type(env.backend).shunts_data_available + + def test_with_shunt(self): + with warnings.catch_warnings(): + warnings.filterwarnings("ignore") + env = grid2op.make("l2rpn_case14_sandbox", + test=True, + backend=PandaPowerBackend(), + _add_to_name=type(self).__name__) + obs_init = env.reset() + assert type(obs_init).shunts_data_available + assert type(env.backend).shunts_data_available + + +if __name__ == "__main__": + unittest.main() diff --git a/grid2op/tests/test_issue_561.py b/grid2op/tests/test_issue_561.py new file mode 100644 index 000000000..f598bb47e --- /dev/null +++ b/grid2op/tests/test_issue_561.py @@ -0,0 +1,45 @@ +# Copyright (c) 2023, 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 numpy as np +import grid2op +from grid2op.Backend import PandaPowerBackend +import warnings +import unittest + + +class PandaPowerNoShunt_Test(PandaPowerBackend): + shunts_data_available = False # class attribute (only one used) + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + def _init_private_attrs(self) -> None: + super()._init_private_attrs() + + +class Issue561Tester(unittest.TestCase): + def test_update_from_obs(self): + with warnings.catch_warnings(): + warnings.filterwarnings("ignore") + env = grid2op.make("l2rpn_case14_sandbox", + test=True, + backend=PandaPowerNoShunt_Test(), + _add_to_name=type(self).__name__) + obs_init = env.reset() + assert not type(obs_init).shunts_data_available + assert not type(env.backend).shunts_data_available + backend = env.backend.copy() + backend1 = env.backend.copy() + obs, *_ = env.step(env.action_space()) + obs.load_p[:] += 1. # to make sure everything changes + backend.update_from_obs(obs) + assert np.all(backend._grid.load["p_mw"] != backend1._grid.load["p_mw"]) + + +if __name__ == "__main__": + unittest.main() diff --git a/grid2op/tests/test_no_backend_copy.py b/grid2op/tests/test_no_backend_copy.py index ada1e7336..6a48d8676 100644 --- a/grid2op/tests/test_no_backend_copy.py +++ b/grid2op/tests/test_no_backend_copy.py @@ -12,10 +12,10 @@ import copy from grid2op.Backend import PandaPowerBackend -from grid2op.Exceptions import NoForecastAvailable -from grid2op.Exceptions.EnvExceptions import EnvError -from grid2op.Exceptions.ObservationExceptions import BaseObservationError -from grid2op.Exceptions.simulatorExceptions import SimulatorError +from grid2op.Exceptions import (NoForecastAvailable, + EnvError, + BaseObservationError, + SimulatorError) from grid2op.simulator import Simulator diff --git a/setup.py b/setup.py index 5e4a176d0..68b3586f9 100644 --- a/setup.py +++ b/setup.py @@ -96,7 +96,11 @@ def my_test_suite(): if sys.version_info.minor == 12: # numba is not available for python 3.12 at the moment - pkgs["extras"]["test"] = [el for el in pkgs["extras"]["test"] if not ("numba" in el)] + pkgs["extras"]["test"] = [el for el in pkgs["extras"]["test"] if (not ("numba" in el) and + not ("gym" in el) and + not ('stable-baselines3' in el) + ) + ] setup(description='An gymnasium compatible environment to model sequential decision making for powersystems', long_description=long_description,