Skip to content

Commit

Permalink
fixing broken tests (hopefully) and improve AAA backend test suite fo…
Browse files Browse the repository at this point in the history
…r new feature

Signed-off-by: DONNOT Benjamin <[email protected]>
  • Loading branch information
BDonnot committed Nov 26, 2024
1 parent d6bf9a8 commit 8b70407
Show file tree
Hide file tree
Showing 6 changed files with 252 additions and 138 deletions.
46 changes: 28 additions & 18 deletions grid2op/Backend/backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,9 @@ class Backend(GridObjects, ABC):
_complete_action_class : "Optional[grid2op.Action.CompleteAction]"= None

ERR_INIT_POWERFLOW : str = "Power cannot be computed on the first time step, please check your data."
ERR_DETACHMENT : str = ("One or more {} were isolated from the grid "
"but this is not allowed or not supported (Game Over) (detachment_is_allowed is False), "
"check {} {}")
def __init__(self,
detailed_infos_for_cascading_failures:bool=False,
can_be_copied:bool=True,
Expand Down Expand Up @@ -181,7 +184,7 @@ def __init__(self,
self.n_busbar_per_sub: int = DEFAULT_N_BUSBAR_PER_SUB

#: .. versionadded: 1.11.0
self._missing_detachment_support : bool = True
self._missing_detachment_support_info : bool = True
self.detachment_is_allowed : bool = DEFAULT_ALLOW_DETACHMENT

def can_handle_more_than_2_busbar(self):
Expand Down Expand Up @@ -270,7 +273,7 @@ def can_handle_detachment(self):
We highly recommend you do not try to override this function.
At least, at time of writing there is no good reason to do so.
"""
self._missing_detachment_support = False
self._missing_detachment_support_info = False
self.detachment_is_allowed = type(self).detachment_is_allowed

def cannot_handle_detachment(self):
Expand All @@ -297,7 +300,7 @@ def cannot_handle_detachment(self):
We highly recommend you do not try to override this function.
At least, at time of writing there is no good reason to do so.
"""
self._missing_detachment_support = False
self._missing_detachment_support_info = False
if type(self).detachment_is_allowed != DEFAULT_ALLOW_DETACHMENT:
warnings.warn("You asked in 'make' function to allow shedding. This is"
f"not possible with a backend of type {type(self)}.")
Expand Down Expand Up @@ -1079,7 +1082,7 @@ def _runpf_with_diverging_exception(self, is_dc : bool) -> Optional[Exception]:
"""
conv = False
exc_me = None

cls = type(self)
try:
conv, exc_me = self.runpf(is_dc=is_dc) # run powerflow

Expand All @@ -1091,21 +1094,28 @@ def _runpf_with_diverging_exception(self, is_dc : bool) -> Optional[Exception]:
# Check if loads/gens have been detached and if this is allowed, otherwise raise an error
# .. versionadded:: 1.11.0
topo_vect = self.get_topo_vect()
load_buses = topo_vect[self.load_pos_topo_vect]
if not self.detachment_is_allowed and (load_buses == -1).any():
raise Grid2OpException(f"One or more loads were detached before powerflow in Backend {type(self).__name__}"
"but this is not allowed or not supported (Game Over)")
load_buses = topo_vect[cls.load_pos_topo_vect]
if not cls.detachment_is_allowed and (load_buses == -1).any():
raise BackendError(cls.ERR_DETACHMENT.format("loads", "loads", (load_buses == -1).nonzero()[0]))

gen_buses = topo_vect[self.gen_pos_topo_vect]
gen_buses = topo_vect[cls.gen_pos_topo_vect]
if not cls.detachment_is_allowed and (gen_buses == -1).any():
raise BackendError(cls.ERR_DETACHMENT.format("gens", "gens", (gen_buses == -1).nonzero()[0]))

if not self.detachment_is_allowed and (gen_buses == -1).any():
raise Grid2OpException(f"One or more generators were detached before powerflow in Backend {type(self).__name__}"
"but this is not allowed or not supported (Game Over)")
if cls.n_storage > 0:
storage_buses = topo_vect[cls.storage_pos_topo_vect]
storage_p, *_ = self.storages_info()
sto_maybe_error = (storage_buses == -1) & (np.abs(storage_p) >= 1e-6)
if not cls.detachment_is_allowed and sto_maybe_error.any():
raise BackendError((cls.ERR_DETACHMENT.format("storages", "storages", sto_maybe_error.nonzero()[0]) +
" NB storage units are allowed to be disconnected even if "
"`detachment_is_allowed` is False but only if the don't produce active power."))

except Grid2OpException as exc_:
exc_me = exc_

if not conv and exc_me is None:
exc_me = DivergingPowerflow(
exc_me = BackendError(
"GAME OVER: Powerflow has diverged during computation "
"or a load has been disconnected or a generator has been disconnected."
)
Expand Down Expand Up @@ -2181,8 +2191,8 @@ def assert_grid_correct(self, _local_dir_cls=None) -> None:
"attribute. This is known issue in lightims2grid <= 0.7.5. Please "
"upgrade your backend. This will raise an error in the future.")

if hasattr(self, "_missing_detachment_support"):
if self._missing_detachment_support:
if hasattr(self, "_missing_detachment_support_info"):
if self._missing_detachment_support_info:
warnings.warn("The backend implementation you are using is probably too old to take advantage of the "
"new feature added in grid2op 1.11.0: the possibility "
"to detach loads or generators without leading to an immediate game over. "
Expand All @@ -2194,12 +2204,12 @@ def assert_grid_correct(self, _local_dir_cls=None) -> None:
"\nAnd of course, ideally, if the current implementation "
"of your backend cannot handle detachment then change it :-)\n"
"Your backend will behave as if it did not support it.")
self._missing_detachment_support = False
self._missing_detachment_support_info = False
self.detachment_is_allowed = DEFAULT_ALLOW_DETACHMENT
else:
self._missing_detachment_support = False
self._missing_detachment_support_info = False
self.detachment_is_allowed = DEFAULT_ALLOW_DETACHMENT
warnings.warn("Your backend is missing the `_missing_detachment_support` "
warnings.warn("Your backend is missing the `_missing_detachment_support_info` "
"attribute.")

orig_type = type(self)
Expand Down
17 changes: 9 additions & 8 deletions grid2op/Backend/pandaPowerBackend.py
Original file line number Diff line number Diff line change
Expand Up @@ -829,6 +829,9 @@ def storage_deact_for_backward_comaptibility(self) -> None:
self.storage_p = np.full(cls.n_storage, dtype=dt_float, fill_value=np.NaN)
self.storage_q = np.full(cls.n_storage, dtype=dt_float, fill_value=np.NaN)
self.storage_v = np.full(cls.n_storage, dtype=dt_float, fill_value=np.NaN)
self._topo_vect.flags.writeable = True
self._topo_vect.resize(cls.dim_topo)
self._topo_vect.flags.writeable = False
self._get_topo_vect()

def _convert_id_topo(self, id_big_topo):
Expand Down Expand Up @@ -899,7 +902,6 @@ def apply_action(self, backendAction: Union["grid2op.Action._backendAction._Back
tmp_stor_p = self._grid.storage["p_mw"]
if (storage.changed).any():
tmp_stor_p.iloc[storage.changed] = storage.values[storage.changed]

# topology of the storage
stor_bus = backendAction.get_storages_bus()
new_bus_num = dt_int(1) * self._grid.storage["bus"].values
Expand Down Expand Up @@ -1183,11 +1185,8 @@ def runpf(self, is_dc : bool=False) -> Tuple[bool, Union[Exception, None]]:
self.storage_v[:],
self.storage_theta[:],
) = self._storages_info()

deact_storage = ~np.isfinite(self.storage_v)
if (np.abs(self.storage_p[deact_storage]) > self.tol).any():
raise pp.powerflow.LoadflowNotConverged(
"Isolated storage set to absorb / produce something"
)
self.storage_p[deact_storage] = 0.0
self.storage_q[deact_storage] = 0.0
self.storage_v[deact_storage] = 0.0
Expand Down Expand Up @@ -1336,7 +1335,7 @@ def copy(self) -> "PandaPowerBackend":
res._in_service_trafo_col_id = self._in_service_trafo_col_id

res._missing_two_busbars_support_info = self._missing_two_busbars_support_info
res._missing_detachment_support = self._missing_detachment_support
res._missing_detachment_support_info = self._missing_detachment_support_info
res.div_exception = self.div_exception
return res

Expand Down Expand Up @@ -1552,8 +1551,10 @@ def _storages_info(self):
if self.n_storage:
# this is because we support "backward comaptibility" feature. So the storage can be
# deactivated from the Environment...
p_storage = self._grid.res_storage["p_mw"].values.astype(dt_float)
q_storage = self._grid.res_storage["q_mvar"].values.astype(dt_float)
# p_storage = self._grid.res_storage["p_mw"].values.astype(dt_float)
# q_storage = self._grid.res_storage["q_mvar"].values.astype(dt_float)
p_storage = self._grid.storage["p_mw"].values.astype(dt_float)
q_storage = self._grid.storage["q_mvar"].values.astype(dt_float)
v_storage = (
self._grid.res_bus.loc[self._grid.storage["bus"].values][
"vm_pu"
Expand Down
7 changes: 3 additions & 4 deletions grid2op/Environment/environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ def _init_backend(
need_process_backend = False
if not self.backend.is_loaded:
if hasattr(self.backend, "init_pp_backend") and self.backend.init_pp_backend is not None:
# hack for lightsim2grid ...
# hack for legacy lightsim2grid ...
if type(self.backend.init_pp_backend)._INIT_GRID_CLS is not None:
type(self.backend.init_pp_backend)._INIT_GRID_CLS._clear_grid_dependant_class_attributes()
type(self.backend.init_pp_backend)._clear_grid_dependant_class_attributes()
Expand All @@ -282,7 +282,6 @@ def _init_backend(
type(self.backend).set_env_name(self.name)
type(self.backend).set_n_busbar_per_sub(self._n_busbar)
type(self.backend).set_detachment_is_allowed(self._allow_detachment)

if self._compat_glop_version is not None:
type(self.backend).glop_version = self._compat_glop_version

Expand All @@ -296,8 +295,8 @@ def _init_backend(
except BackendError as exc_:
self.backend.redispatching_unit_commitment_availble = False
warnings.warn(f"Impossible to load redispatching data. This is not an error but you will not be able "
f"to use all grid2op functionalities. "
f"The error was: \"{exc_}\"")
f"to use all grid2op functionalities. "
f"The error was: \"{exc_}\"")
exc_ = self.backend.load_grid_layout(self.get_path_env())
if exc_ is not None:
warnings.warn(
Expand Down
Loading

0 comments on commit 8b70407

Please sign in to comment.