def test_plot(self): self.episode_data = EpisodeData.from_disk( os.path.join(self.agents_path, self.agent_name), self.scenario_name ) self.episode_analytics = EpisodeAnalytics( self.episode_data, self.scenario_name, self.agent_name ) self.episode_analytics.decorate(self.episode_data) make_network(self.episode_analytics).plot_obs(self.episode_analytics.observations[0])
def setUp(self): self.agents_path = agents_path self.agent_name = 'greedy-baseline' self.scenario_name = '000' self.episode_data = EpisodeData.from_disk( os.path.join(self.agents_path, self.agent_name), self.scenario_name ) self.episode_analytics = EpisodeAnalytics( self.episode_data, self.scenario_name, self.agent_name )
def load(self, backend, agent_path=None, name=None, data=None, env_kwargs={}): if data is None: if agent_path is not None and name is not None: self.episode_data = EpisodeData.from_disk(agent_path, name) else: raise Grid2OpException("To replay an episode you need at least to provide an EpisodeData " "(using the keyword argument \"data=...\") or provide the path and name where " "the " "episode is stored (keyword arguments \"agent_path\" and \"name\").") else: self.episode_data = copy.deepcopy(data) self.episode_data.reboot() if self.env is not None: self.env.close() self.env = None self.chronics_handler = ChronicsHandler(chronicsClass=_GridFromLog, episode_data=self.episode_data) if "chronics_handler" in env_kwargs: del env_kwargs["chronics_handler"] if "backend" in env_kwargs: del env_kwargs["backend"] if "opponent_class" in env_kwargs: del env_kwargs["opponent_class"] if "name" in env_kwargs: del env_kwargs["name"] seed = None with open(os.path.join(agent_path, name, "episode_meta.json")) as f: dict_ = json.load(f) nm = re.sub("Environment_", "", dict_["env_type"]) if dict_["env_seed"] is not None: seed = int(dict_["env_seed"]) self.env = Environment(**env_kwargs, backend=backend, chronics_handler=self.chronics_handler, opponent_class=OpponentFromLog, name=nm) if seed is not None: self.env.seed(seed) tmp = self.env.reset() # always have the two bellow synch ! otherwise it messes up the "chronics" # in the env, when calling "env.step" self.current_time_step = 0 self.env.chronics_handler.real_data.curr_iter = 0 # first observation of the scenario current_obs = self.episode_data.observations[self.current_time_step] self._assign_state(current_obs) return self.env.get_obs()
def test_multi_topo(self): self.agent_name = 'multiTopology-baseline' self.scenario_name = '000' self.episode_data = EpisodeData.from_disk( os.path.join(self.agents_path, self.agent_name), self.scenario_name ) self.episode_analytics = EpisodeAnalytics( self.episode_data, self.scenario_name, self.agent_name ) nb_actions = self.episode_analytics.action_data_table[ ['action_line', 'action_subs']].sum() self.assertEqual(nb_actions.action_line, 25.0) self.assertEqual(nb_actions.action_subs, 38.0) action_per_line = get_action_per_line(self.episode_analytics) action_per_sub = get_action_per_sub(self.episode_analytics) # We need to sort the labels for which values are equal. # Otherwise, the output is random. self.assertListEqual( sorted(action_per_sub[0].x.tolist()), ['sub_3', 'sub_5'] ) self.assertListEqual( action_per_sub[0].y.tolist(), [19, 19] ) self.assertListEqual( action_per_line[0].x.tolist(), ['3_6_15', '9_10_12'] ) self.assertListEqual( action_per_line[0].y.tolist(), [13, 12] ) self.assertListEqual( self.episode_analytics.action_data_table.action_id[:5].tolist(), [0, 1, 1, 2, 3] ) self.assertListEqual( self.episode_analytics.action_data_table.distance[:5].tolist(), [1, 2, 2, 0, 3] )
def replay_episode(self, episode_id, fps=2.0, gif_name=None, display=True, start_step=0, end_step=-1, line_info="rho", load_info="p", gen_info="p", resolution=(1280, 720)): """ When called, this function will start the display of the episode in a "mini movie" format. Parameters ---------- episode_id: ``str`` ID of the episode to replay fps: ``float`` Frames per second. When it's low, you will have more time to look at each frame, but the episode will last longer. When it's high, episode will be faster, but frames will stay less time on the screen. gif_name: ``str`` If provided, a .gif file is saved in the episode folder with the name :gif_name:. The .gif extension is appened by this function start_step: ``int`` Default to 0. The step at which to start generating the gif end_step: ``int`` Default to -1. The step at which to stop generating the gif. Set to -1 to specify no limit load_info: ``str`` Defaults to "p". What kind of values to show on loads. Can be oneof `["p", "v", None]` gen_info: ``str`` Defaults to "p". What kind of values to show on generators. Can be oneof `["p", "v", None]` line_info: ``str`` Defaults to "rho". What kind of values to show on lines. Can be oneof `["rho", "a", "p", "v", None]` resolution: ``tuple`` Defaults to (1280, 720). The resolution to use for the gif. """ # Check args path_ep = os.path.join(self.agent_path, episode_id) if not os.path.exists(path_ep): raise Grid2OpException( "No episode is found at \"{}\".".format(path_ep)) # Load episode observations self.episode_data = EpisodeData.from_disk(agent_path=self.agent_path, name=episode_id) all_obs = [el for el in self.episode_data.observations] # Create a plotter width, height = resolution plot_runner = PlotMatplot(self.episode_data.observation_space, width=width, height=height, load_name=False, gen_name=False) # Some vars for gif export if enabled frames = [] gif_path = None if gif_name is not None: gif_path = os.path.join(path_ep, gif_name + ".gif") # Render loop figure = None time_per_frame = 1.0 / fps for step, obs in enumerate(all_obs): # Skip up to start_step if step < start_step: continue # Terminate if reached end_step if end_step > 0 and step >= end_step: break # Get a timestamp for current frame start_time = time.time() # Render the observation fig = plot_runner.plot_obs(observation=obs, line_info=line_info, gen_info=gen_info, load_info=load_info, figure=figure, redraw=True) if figure is None and display: fig.show() elif display: fig.canvas.draw() # Store figure for re-use figure = fig # Save pixel array if needed if gif_name is not None: frames.append(plot_runner.convert_figure_to_numpy_HWC(figure)) # Get the timestamp after frame is rendered end_time = time.time() delta_time = end_time - start_time # Cap fps for display mode if display: wait_time = time_per_frame - delta_time if wait_time > 0.0: time.sleep(wait_time) # Export all frames as gif if enabled if gif_name is not None and len(frames) > 0: try: imageio.mimwrite(gif_path, frames, fps=fps) # Try to compress try: from pygifsicle import optimize optimize(gif_path, options=["-w", "--no-conserve-memory"]) except: warn_msg = "Failed to optimize .GIF size, but gif is still saved:\n" \ "Install dependencies to reduce size by ~3 folds\n" \ "apt-get install gifsicle && pip3 install pygifsicle" warnings.warn(warn_msg) except Exception as e: warnings.warn( "Impossible to save gif with error :\n{}".format(e))
def replay_episode(self, episode_id, fps=2.0, gif_name=None, display=True): """ When called, this function will start the display of the episode in a "mini movie" format. Parameters ---------- episode_id: ``str`` ID of the episode to replay fps: ``float`` Frames per second. When it's low, you will have more time to look at each frame, but the episode will last longer. When it's high, episode will be faster, but frames will stay less time on the screen. gif_name: ``str`` If provided, a .gif file is saved in the episode folder with the name :gif_name:. The .gif extension is appened by this function """ # Check args path_ep = os.path.join(self.agent_path, episode_id) if not os.path.exists(path_ep): raise Grid2OpException( "No episode is found at \"{}\".".format(path_ep)) # Load episode observations self.episode_data = EpisodeData.from_disk(agent_path=self.agent_path, name=episode_id) all_obs = [el for el in self.episode_data.observations] # Create a plotter plot_runner = PlotMatplot(self.episode_data.observation_space) # Some vars for gif export if enabled frames = [] gif_path = None if gif_name is not None: gif_path = os.path.join(path_ep, gif_name + ".gif") # Render loop figure = None time_per_frame = 1.0 / fps for obs in all_obs: # Get a timestamp for current frame start_time = time.time() # Render the observation fig = plot_runner.plot_obs(observation=obs, figure=figure, redraw=True) if figure is None and display: fig.show() elif display: fig.canvas.draw() # Store figure for re-use figure = fig # Save pixel array if needed if gif_name is not None: frames.append(plot_runner.convert_figure_to_numpy_HWC(figure)) # Get the timestamp after frame is rendered end_time = time.time() delta_time = end_time - start_time # Cap fps for display mode if display: wait_time = time_per_frame - delta_time if wait_time > 0.0: time.sleep(wait_time) # Export all frames as gif if enabled if gif_name is not None: imageio.mimwrite(gif_path, frames, fps=fps) # Try to compress try: from pygifsicle import optimize optimize(gif_path, options=["-w", "--no-conserve-memory"]) except: warn_msg = "Failed to optimize .GIF size, but gif is still saved:\n" \ "Install dependencies to reduce size by ~3 folds\n" \ "apt-get install gifsicle && pip3 install pygifsicle" warnings.warn(warn_msg)