def check_validity(self, backend): super(GridStateFromFileWithForecasts, self).check_validity(backend) at_least_one = False if self.load_p_forecast is not None: if self.load_p_forecast.shape[1] != backend.n_load: raise IncorrectNumberOfLoads( "for the active part. It should be {} but is in fact {}" "".format(backend.n_load, len(self.load_p))) at_least_one = True if self.load_q_forecast is not None: if self.load_q_forecast.shape[1] != backend.n_load: raise IncorrectNumberOfLoads( "for the reactive part. It should be {} but is in fact {}" "".format(backend.n_load, len(self.load_q))) at_least_one = True if self.prod_p_forecast is not None: if self.prod_p_forecast.shape[1] != backend.n_gen: raise IncorrectNumberOfGenerators( "for the active part. It should be {} but is in fact {}" "".format(backend.n_gen, len(self.prod_p))) at_least_one = True if self.prod_v_forecast is not None: if self.prod_v_forecast.shape[1] != backend.n_gen: raise IncorrectNumberOfGenerators( "for the voltage part. It should be {} but is in fact {}" "".format(backend.n_gen, len(self.prod_v))) at_least_one = True if self.maintenance_forecast is not None: if self.maintenance_forecast.shape[1] != backend.n_line: raise IncorrectNumberOfLines( "for the _maintenance. It should be {} but is in fact {}" "".format(backend.n_line, len(self.maintenance))) at_least_one = True if not at_least_one: raise ChronicsError( "You used a class that read forecasted data, yet there is no forecasted data in" "\"{}\". Please fall back to using class \"GridStateFromFile\" instead of " "\"{}\"".format(self.path, type(self))) for name_arr, arr in zip( ["load_q", "load_p", "prod_v", "prod_p", "maintenance"], [ self.load_q_forecast, self.load_p_forecast, self.prod_v_forecast, self.prod_p_forecast, self.maintenance_forecast ]): if arr is not None: if self.chunk_size is None: if arr.shape[0] < self.n_: raise EnvError( "Array for forecast {}_forecasted as not the same number of rows of load_p. " "The chronics cannot be loaded properly.".format( name_arr))
def assert_grid_correct_after_powerflow(self): """ .. warning:: /!\\\\ Internal, do not use unless you know what you are doing /!\\\\ This is done as it should be by the Environment This method is called by the environment. It ensure that the backend remains consistent even after a powerflow has be run with :func:`Backend.runpf` method. :return: ``None`` :raise: :class:`grid2op.Exceptions.EnvError` and possibly all of its derived class. """ # test the results gives the proper size self.__class__ = self.init_grid(self) self.my_bk_act_class = self.my_bk_act_class.init_grid(self) self._complete_action_class = self._complete_action_class.init_grid( self) tmp = self.get_line_status() if tmp.shape[0] != self.n_line: raise IncorrectNumberOfLines( "returned by \"backend.get_line_status()\"") if np.any(~np.isfinite(tmp)): raise EnvironmentError( "Power cannot be computed on the first time step, please check your data." ) tmp = self.get_line_flow() if tmp.shape[0] != self.n_line: raise IncorrectNumberOfLines( "returned by \"backend.get_line_flow()\"") if np.any(~np.isfinite(tmp)): raise EnvironmentError( "Power cannot be computed on the first time step, please check your data." ) tmp = self.get_thermal_limit() if tmp.shape[0] != self.n_line: raise IncorrectNumberOfLines( "returned by \"backend.get_thermal_limit()\"") if np.any(~np.isfinite(tmp)): raise EnvironmentError( "Power cannot be computed on the first time step, please check your data." ) tmp = self.get_line_overflow() if tmp.shape[0] != self.n_line: raise IncorrectNumberOfLines( "returned by \"backend.get_line_overflow()\"") if np.any(~np.isfinite(tmp)): raise EnvironmentError( "Power cannot be computed on the first time step, please check your data." ) tmp = self.generators_info() if len(tmp) != 3: raise EnvError( "\"generators_info()\" should return a tuple with 3 elements: p, q and v" ) for el in tmp: if el.shape[0] != self.n_gen: raise IncorrectNumberOfGenerators( "returned by \"backend.generators_info()\"") tmp = self.loads_info() if len(tmp) != 3: raise EnvError( "\"loads_info()\" should return a tuple with 3 elements: p, q and v" ) for el in tmp: if el.shape[0] != self.n_load: raise IncorrectNumberOfLoads( "returned by \"backend.loads_info()\"") tmp = self.lines_or_info() if len(tmp) != 4: raise EnvError( "\"lines_or_info()\" should return a tuple with 4 elements: p, q, v and a" ) for el in tmp: if el.shape[0] != self.n_line: raise IncorrectNumberOfLines( "returned by \"backend.lines_or_info()\"") tmp = self.lines_ex_info() if len(tmp) != 4: raise EnvError( "\"lines_ex_info()\" should return a tuple with 4 elements: p, q, v and a" ) for el in tmp: if el.shape[0] != self.n_line: raise IncorrectNumberOfLines( "returned by \"backend.lines_ex_info()\"") tmp = self.get_topo_vect() if tmp.shape[0] != np.sum(self.sub_info): raise IncorrectNumberOfElements( "returned by \"backend.get_topo_vect()\"") if np.any(~np.isfinite(tmp)): raise EnvError( "Some components of \"backend.get_topo_vect()\" are not finite. This should be integer." )
def check_validity(self, backend): at_least_one = False if self.load_p is not None: if self.load_p.shape[1] != backend.n_load: msg_err = "for the active part. It should be {} but is in fact {}" raise IncorrectNumberOfLoads( msg_err.format(backend.n_load, self.load_p.shape[1])) at_least_one = True if self.load_q is not None: if self.load_q.shape[1] != backend.n_load: msg_err = "for the reactive part. It should be {} but is in fact {}" raise IncorrectNumberOfLoads( msg_err.format(backend.n_load, self.load_q.shape[1])) at_least_one = True if self.prod_p is not None: if self.prod_p.shape[1] != backend.n_gen: msg_err = "for the active part. It should be {} but is in fact {}" raise IncorrectNumberOfGenerators( msg_err.format(backend.n_gen, self.prod_p.shape[1])) at_least_one = True if self.prod_v is not None: if self.prod_v.shape[1] != backend.n_gen: msg_err = "for the voltage part. It should be {} but is in fact {}" raise IncorrectNumberOfGenerators( msg_err.format(backend.n_gen, self.prod_v.shape[1])) at_least_one = True if self.hazards is not None: if self.hazards.shape[1] != backend.n_line: msg_err = "for the outage. It should be {} but is in fact {}" raise IncorrectNumberOfLines( msg_err.format(backend.n_line, self.hazards.shape[1])) at_least_one = True if self.maintenance is not None: if self.maintenance.shape[1] != backend.n_line: msg_err = "for the maintenance. It should be {} but is in fact {}" raise IncorrectNumberOfLines( msg_err.format(backend.n_line, self.maintenance.shape[1])) at_least_one = True if self.maintenance_time is not None: if self.maintenance_time.shape[1] != backend.n_line: msg_err = "for the maintenance times. It should be {} but is in fact {}" raise IncorrectNumberOfLines( msg_err.format(backend.n_line, self.maintenance_time.shape[1])) at_least_one = True if self.maintenance_duration is not None: if self.maintenance_duration.shape[1] != backend.n_line: msg_err = "for the maintenance durations. It should be {} but is in fact {}" raise IncorrectNumberOfLines( msg_err.format(backend.n_line, self.maintenance_duration.shape[1])) at_least_one = True if self.hazard_duration is not None: if self.hazard_duration.shape[1] != backend.n_line: msg_err = "for the hazard durations. It should be {} but is in fact {}" raise IncorrectNumberOfLines( msg_err.format(backend.n_line, self.hazard_duration.shape[1])) at_least_one = True if not at_least_one: raise ChronicsError( "No files are found in directory \"{}\". If you don't want to load any chronics, use " "\"ChangeNothing\" and not \"{}\" to load chronics." "".format(self.path, type(self))) for name_arr, arr in zip([ "load_q", "load_p", "prod_v", "prod_p", "maintenance", "hazards", "maintenance time", "maintenance duration", "hazard duration" ], [ self.load_q, self.load_p, self.prod_v, self.prod_p, self.maintenance, self.hazards, self.maintenance_time, self.maintenance_duration, self.hazard_duration ]): if arr is not None: if self.chunk_size is None: if arr.shape[0] != self.n_: msg_err = "Array {} has not the same number of rows than the maintenance. " \ "The chronics cannot be loaded properly." raise EnvError(msg_err.format(name_arr)) if self.max_iter > 0: if self.max_iter > self.n_: msg_err = "Files count {} rows and you ask this episode to last at {} timestep." raise InsufficientData(msg_err.format(self.n_, self.max_iter))
def check_validity(self, backend): """ A call to this method ensure that the action that will be sent to the current :class:`grid2op.Environment` can be properly implemented by its :class:`grid2op.Backend`. This specific method check that the dimension of all vectors are consistent Parameters ---------- backend: :class:`grid2op.Backend.Backend` The backend used by the :class:`grid2op.Environment.Environment` Returns ------- ``None`` """ at_least_one = False if self.load_p is not None: if self.load_p.shape[1] != backend.n_load: msg_err = "for the active part. It should be {} but is in fact {}" raise IncorrectNumberOfLoads( msg_err.format(backend.n_load, self.load_p.shape[1])) at_least_one = True if self.load_q is not None: if self.load_q.shape[1] != backend.n_load: msg_err = "for the reactive part. It should be {} but is in fact {}" raise IncorrectNumberOfLoads( msg_err.format(backend.n_load, self.load_q.shape[1])) at_least_one = True if self.prod_p is not None: if self.prod_p.shape[1] != backend.n_gen: msg_err = "for the active part. It should be {} but is in fact {}" raise IncorrectNumberOfGenerators( msg_err.format(backend.n_gen, self.prod_p.shape[1])) at_least_one = True if self.prod_v is not None: if self.prod_v.shape[1] != backend.n_gen: msg_err = "for the voltage part. It should be {} but is in fact {}" raise IncorrectNumberOfGenerators( msg_err.format(backend.n_gen, self.prod_v.shape[1])) at_least_one = True if self.hazards is not None: if self.hazards.shape[1] != backend.n_line: msg_err = "for the outage. It should be {} but is in fact {}" raise IncorrectNumberOfLines( msg_err.format(backend.n_line, self.hazards.shape[1])) at_least_one = True if self.maintenance is not None: if self.maintenance.shape[1] != backend.n_line: msg_err = "for the maintenance. It should be {} but is in fact {}" raise IncorrectNumberOfLines( msg_err.format(backend.n_line, self.maintenance.shape[1])) at_least_one = True if self.maintenance_time is not None: if self.maintenance_time.shape[1] != backend.n_line: msg_err = "for the maintenance times. It should be {} but is in fact {}" raise IncorrectNumberOfLines( msg_err.format(backend.n_line, self.maintenance_time.shape[1])) at_least_one = True if self.maintenance_duration is not None: if self.maintenance_duration.shape[1] != backend.n_line: msg_err = "for the maintenance durations. It should be {} but is in fact {}" raise IncorrectNumberOfLines( msg_err.format(backend.n_line, self.maintenance_duration.shape[1])) at_least_one = True if self.hazard_duration is not None: if self.hazard_duration.shape[1] != backend.n_line: msg_err = "for the hazard durations. It should be {} but is in fact {}" raise IncorrectNumberOfLines( msg_err.format(backend.n_line, self.hazard_duration.shape[1])) at_least_one = True if not at_least_one: raise ChronicsError( "No files are found in directory \"{}\". If you don't want to load any chronics, use " "\"ChangeNothing\" and not \"{}\" to load chronics." "".format(self.path, type(self))) for name_arr, arr in zip([ "load_q", "load_p", "prod_v", "prod_p", "maintenance", "hazards", "maintenance time", "maintenance duration", "hazard duration" ], [ self.load_q, self.load_p, self.prod_v, self.prod_p, self.maintenance, self.hazards, self.maintenance_time, self.maintenance_duration, self.hazard_duration ]): if arr is not None: if self.chunk_size is None: if arr.shape[0] != self.n_: msg_err = "Array {} has not the same number of rows of load_p. The chronics cannot be loaded properly." raise EnvError(msg_err.format(name_arr)) if self.max_iter > 0: if self.max_iter > self.n_: msg_err = "Files count {} rows and you ask this episode to last at {} timestep." raise InsufficientData(msg_err.format(self.n_, self.max_iter))