diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 3b1666b16..0f5b13447 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -42,6 +42,8 @@ Change Log - [ADDED] possibility to change the "soft_overflow_threshold" in the parameters (like the "hard_overflow_threshold" but for delayed protections). See `param.SOFT_OVERFLOW_THRESHOLD` +- [ADDED] the `gym_env.observation_space.get_index(attr_nm)` for `BoxGymObsSpace` that allows to retrieve which index + of the observation represents which attribute. [1.9.2] - 2023-07-26 --------------------- diff --git a/grid2op/gym_compat/box_gym_obsspace.py b/grid2op/gym_compat/box_gym_obsspace.py index 5a5a778a7..edb979383 100644 --- a/grid2op/gym_compat/box_gym_obsspace.py +++ b/grid2op/gym_compat/box_gym_obsspace.py @@ -6,6 +6,7 @@ # SPDX-License-Identifier: MPL-2.0 # This file is part of Grid2Op, Grid2Op a testbed platform to model sequential decision making in power systems. +from typing import Tuple import copy import warnings import numpy as np @@ -813,6 +814,54 @@ def to_gym(self, grid2op_observation): def close(self): pass + def get_indexes(self, key: str) -> Tuple[int, int]: + """Allows to retrieve the indexes of the gym action that + are concerned by the attribute name `key` given in input. + + .. versionadded:: 1.9.3 + + .. warning:: + Copy paste from box_gym_act_space, need refacto ! + + Parameters + ---------- + key : str + the attribute name (*eg* "set_storage" or "redispatch") + + Returns + ------- + Tuple[int, int] + _description_ + + Examples + -------- + + You can use it like: + + .. code-block:: python + + gym_env = ... # an environment with a BoxActSpace + + act = np.zeros(gym_env.action_space.shape) + key = "redispatch" # "redispatch", "curtail", "set_storage" + start_, end_ = gym_env.action_space.get_indexes(key) + act[start_:end_] = np.random.uniform(high=1, low=-1, size=env.gen_redispatchable.sum()) + # act only modifies the redispatch with the input given (here a uniform redispatching between -1 and 1) + + """ + error_msg =(f"Impossible to use the grid2op action property \"{key}\"" + f"with this action space.") + if key not in self._attr_to_keep: + raise Grid2OpException(error_msg) + prev = 0 + for attr_nm, where_to_put in zip( + self._attr_to_keep, self._dims + ): + if attr_nm == key: + return prev, where_to_put + prev = where_to_put + raise Grid2OpException(error_msg) + def normalize_attr(self, attr_nm: str): """ This function normalizes the part of the space diff --git a/grid2op/tests/test_Parameters.py b/grid2op/tests/test_Parameters.py index 7c609eb38..3be4a4892 100644 --- a/grid2op/tests/test_Parameters.py +++ b/grid2op/tests/test_Parameters.py @@ -87,7 +87,7 @@ def _aux_check_attr_int(self, param, attr_name): setattr(param, attr_name, 1) param.check_valid() - def _aux_check_attr_float(self, param, attr_name): + def _aux_check_attr_float(self, param, attr_name, test_bool=True): tmp = getattr(param, attr_name) # don't work with string setattr(param, attr_name, "toto") @@ -102,8 +102,9 @@ def _aux_check_attr_float(self, param, attr_name): with self.assertRaises(RuntimeError): param.check_valid() # work with bool - setattr(param, attr_name, True) - param.check_valid() + if test_bool: + setattr(param, attr_name, True) + param.check_valid() # work with int value setattr(param, attr_name, int(tmp)) param.check_valid() @@ -153,9 +154,11 @@ def test_check_valid(self): except Exception as exc_: raise RuntimeError(f'Exception "{exc_}" for attribute "{attr_nm}"') # float types - for attr_nm in ["HARD_OVERFLOW_THRESHOLD", "INIT_STORAGE_CAPACITY"]: + for attr_nm in ["HARD_OVERFLOW_THRESHOLD", + "SOFT_OVERFLOW_THRESHOLD", + "INIT_STORAGE_CAPACITY"]: try: - self._aux_check_attr_float(p, attr_nm) + self._aux_check_attr_float(p, attr_nm, test_bool=(attr_nm!="HARD_OVERFLOW_THRESHOLD")) except Exception as exc_: raise RuntimeError(f'Exception "{exc_}" for attribute "{attr_nm}"') diff --git a/grid2op/tests/test_change_param_from_obs.py b/grid2op/tests/test_change_param_from_obs.py index e13a0537e..8a0b124f6 100644 --- a/grid2op/tests/test_change_param_from_obs.py +++ b/grid2op/tests/test_change_param_from_obs.py @@ -26,7 +26,7 @@ def tearDown(self) -> None: def test_change_param_simulate(self): l_id = 3 params = self.env.parameters - params.HARD_OVERFLOW_THRESHOLD = 1. + params.HARD_OVERFLOW_THRESHOLD = 1.001 th_lim = self.env.get_thermal_limit() th_lim[l_id] = 170 self.env.set_thermal_limit(th_lim)