def _aux_backward(self, base_path, g2op_version_txt, g2op_version): episode_studied = EpisodeData.list_episode(os.path.join(base_path, g2op_version_txt)) for base_path, episode_path in episode_studied: assert 'curtailment' in CompleteObservation.attr_list_vect, f"error after the legacy version " \ f"{g2op_version}" this_episode = EpisodeData.from_disk(base_path, episode_path) assert 'curtailment' in CompleteObservation.attr_list_vect, f"error after the legacy version " \ f"{g2op_version}" full_episode_path = os.path.join(base_path, episode_path) with open(os.path.join(full_episode_path, "episode_meta.json"), "r", encoding="utf-8") as f: meta_data = json.load(f) nb_ts = int(meta_data["nb_timestep_played"]) try: assert len(this_episode.actions) == nb_ts, f"wrong number of elements for actions for version " \ f"{g2op_version_txt}: {len(this_episode.actions)} vs {nb_ts}" assert len(this_episode.observations) == nb_ts + 1, f"wrong number of elements for observations " \ f"for version {g2op_version_txt}: " \ f"{len(this_episode.observations)} vs {nb_ts}" assert len(this_episode.env_actions) == nb_ts, f"wrong number of elements for env_actions for " \ f"version {g2op_version_txt}: " \ f"{len(this_episode.env_actions)} vs {nb_ts}" except Exception as exc_: raise exc_ if g2op_version <= "1.4.0": assert EpisodeData.get_grid2op_version(full_episode_path) == "<=1.4.0", \ "wrong grid2op version stored (grid2op version <= 1.4.0)" elif g2op_version == "test_version": assert EpisodeData.get_grid2op_version(full_episode_path) == grid2op.__version__, \ "wrong grid2op version stored (test_version)" else: assert EpisodeData.get_grid2op_version(full_episode_path) == g2op_version, \ "wrong grid2op version stored (>=1.5.0)"
def _aux_backward(self, base_path, g2op_version): episode_studied = EpisodeData.list_episode(os.path.join(base_path, g2op_version)) for base_path, episode_path in episode_studied: this_episode = EpisodeData.from_disk(base_path, episode_path) with open(os.path.join(os.path.join(base_path, episode_path), "episode_meta.json"), "r", encoding="utf-8") as f: meta_data = json.load(f) nb_ts = int(meta_data["nb_timestep_played"]) try: assert len(this_episode.actions) == nb_ts, f"wrong number of elements for actions for version " \ f"{g2op_version}: {len(this_episode.actions)} vs {nb_ts}" assert len(this_episode.observations) == nb_ts + 1, f"wrong number of elements for observations " \ f"for version {g2op_version}: " \ f"{len(this_episode.observations)} vs {nb_ts}" assert len(this_episode.env_actions) == nb_ts, f"wrong number of elements for env_actions for " \ f"version {g2op_version}: " \ f"{len(this_episode.env_actions)} vs {nb_ts}" except: import pdb pdb.set_trace()
def compute(self, agent=None, parameters=None, nb_scenario=1, scores_func=None, max_step=-1, env_seeds=None, agent_seeds=None, nb_process=1, pbar=False): """ This function will save (to be later used with :func:`EpisodeStatistics.get_statistics`) all the observation at all time steps, for a given number of scenario (see attributes nb_scenario). This is useful when you want to store at a given place some information to use later on on your agent. Notes ----- Depending on its parameters (mainly the environment, the agent and the number of scenarios computed) this function might take a really long time to compute. However you only need to compute it once (unless you delete its results with :func:`EpisodeStatistics.clear_all` or :func:`EpisodeStatistics.clear_episode_data` Results might also take a lot of space on the hard drive (possibly few GB as all information of all observations encountered are stored) Parameters ---------- agent: :class:`grid2op.Agent.BaseAgent` The agent you want to use to generate the statistics. Note that the statistics are highly dependant on the agent. For now only one set of statistics are computed. If you want to run a different agent previous results will be erased. parameters: :class:`grid2op.Parameters.Parameters` The parameters you want to use when computing this statistics nb_scenario: ``int`` Number of scenarios that will be evaluated scores_func: :class:`grid2op.Reward.BaseReward` A reward used to compute the score of an Agent (it can now be a dictionary of BaseReward) nb_scenario: ``int`` On how many scenarios you want the statistics to be computed max_step: ``int`` Maximum number of steps you want to compute (see :func:`grid2op.Runner.Runner.run`) env_seeds: ``list`` List of seeds used for the environment (for reproducible results) (see :func:`grid2op.Runner.Runner.run`) agent_seeds: ``list`` List of seeds used for the agent (for reproducible results) (see :func:`grid2op.Runner.Runner.run`). nb_process: ``int`` Number of process to use (see :func:`grid2op.Runner.Runner.run`) pbar: ``bool`` Whether a progress bar is displayed (see :func:`grid2op.Runner.Runner.run`) """ if agent is None: agent = DoNothingAgent(self.env.action_space) if parameters is None: parameters = copy.deepcopy(self.env.parameters) if not isinstance(agent, BaseAgent): raise RuntimeError( "\"agent\" should be either \"None\" to use DoNothingAgent or an agent that inherits " "grid2op.Agent.BaseAgent") if not isinstance(parameters, Parameters): raise RuntimeError( "\"parameters\" should be either \"None\" to use the default parameters passed in the " "environment or inherits grid2op.Parameters.Parameters") score_names = None dict_metadata = self._fill_metadata(agent, parameters, max_step, agent_seeds, env_seeds) if scores_func is not None: if EpisodeStatistics._check_if_base_reward(scores_func): dict_metadata["score_class"] = f"{scores_func}" score_names = [self.SCORES] elif isinstance(scores_func, dict): score_names = [] for nm, score_fun in scores_func.items(): if not EpisodeStatistics._check_if_base_reward(score_fun): raise Grid2OpException( "if using \"score_fun\" as a dictionary, each value need to be a " "BaseReward") dict_metadata[f"score_class_{nm}"] = f"{score_fun}" score_names.append(f"{nm}_{self.SCORES}") else: raise Grid2OpException( "score_func should be either a dictionary or an instance of BaseReward" ) self.run_env(env=self.env, path_save=self.path_save_stats, parameters=parameters, scores_func=scores_func, agent=agent, max_step=max_step, env_seeds=env_seeds, agent_seeds=agent_seeds, pbar=pbar, nb_process=nb_process, nb_scenario=nb_scenario) # inform grid2op this is a statistics directory self._tell_is_stats() if scores_func is not None: self._tell_has_score() # now clean a bit the output directory os.remove(os.path.join(self.path_save_stats, EpisodeData.ACTION_SPACE)) os.remove(os.path.join(self.path_save_stats, EpisodeData.ATTACK_SPACE)) os.remove( os.path.join(self.path_save_stats, EpisodeData.ENV_MODIF_SPACE)) os.remove(os.path.join(self.path_save_stats, EpisodeData.OBS_SPACE)) li_episodes = EpisodeData.list_episode(self.path_save_stats) for path_tmp, episode_name in li_episodes: # remove the useless information (saved but not used) self._delete_if_exists(path_tmp, episode_name, EpisodeData.ACTIONS) self._delete_if_exists(path_tmp, episode_name, EpisodeData.AG_EXEC_TIMES) self._delete_if_exists(path_tmp, episode_name, EpisodeData.LINES_FAILURES) self._delete_if_exists(path_tmp, episode_name, EpisodeData.ENV_ACTIONS) self._delete_if_exists(path_tmp, episode_name, EpisodeData.ATTACK) if scores_func is not None: self._retrieve_scores(path_tmp, episode_name) else: self._delete_if_exists(path_tmp, episode_name, EpisodeData.OTHER_REWARDS) self._delete_if_exists(path_tmp, episode_name, EpisodeData.REWARDS) # reformat the observation into a proper "human readable" format self._clean_observations(path_tmp, episode_name) # and now gather the information for at the top level self._gather_all(li_episodes, dict_metadata, score_names=score_names)