def draw_animation(self) -> None: # colors self.norm = matplotlib.colors.Normalize(vmin=0, vmax=2 * np.pi) self.cm = cmocean.cm.phase # time total_frames = len(self.timestamps) start_t = time.time() log.info("Drawing start at t=%s" % datetime.datetime.fromtimestamp( start_t).strftime('%Y-%m-%d %H:%M:%S')) anim = animation.FuncAnimation(self.fig, self.update_animation, init_func=lambda: (), frames=total_frames, interval=200, blit=True, repeat=True, fargs=(start_t, )) SaveAndLoad.make_path_available(self.output_file) anim.save(self.output_file, writer=self.writer) elapsed = time.time() - start_t log.info("Drawing ended at t=%s, elapsed: %dh %dm %ds" % (datetime.datetime.fromtimestamp( time.time()).strftime('%Y-%m-%d %H:%M:%S'), elapsed // 3600 % 24, elapsed // 60 % 60, elapsed % 60)) log.info("Visualisation results saved")
def save_results(self, output_file: str): def save_prop_name(prop_name: str): SaveAndLoad.save_data_dirname(self.data_holders[prop_name], output_file, "%s.json" % prop_name) # save the actual data simple_propreties = ["avg_speed", "avg_angle", "groups", "group_size", "group_to_size", "group_size_avg", "group_size_avg_fit", "correlations", "correlations_fit"] for property_name in simple_propreties: if self.to_process[property_name]: save_prop_name(property_name) # save the simulation's parameters self.simulation_params["processing_options"] = self.options SaveAndLoad.save_data_dirname(self.simulation_params, output_file, "processing_parameters.json")
def load_data(self, input_file: str) -> None: # load data data = SaveAndLoad.load_data(input_file) self.frames = data["frames"] self.simulation_params = data["parameters"] log.info("Processor: Got %d frames" % len(self.frames))
def load_data(self, simulation_data_file: str, processing_dir: str) -> None: # decide which data is necessary data_to_fetch = set() for drawable in self.to_draw: required_data = drawable_to_data[drawable] for data in required_data: data_to_fetch.add(data) if self.options["quiver_color_by_group"] or self.options[ "quiver_draw_by_group"]: data_to_fetch.add("groups") # load data self.processed_data = {} if "_simulation" in data_to_fetch: self.processed_data["_simulation"] = SaveAndLoad.load_data( simulation_data_file) data_to_fetch.remove("_simulation") for property_name in data_to_fetch: self.processed_data[property_name] = SaveAndLoad.load_data_dirname( processing_dir, "%s.json" % property_name) self.simulation_parameters = SaveAndLoad.load_data_dirname( processing_dir, "processing_parameters.json")
def process_frame(self, frame: list, frame_number: int): # get simulation parameters L = self.simulation_params["L"] eta = self.simulation_params["eta"] interaction_radius = self.simulation_params["interaction_radius"] # recreate environment if self.to_process["groups"] or self.to_process["group_size"] or self.to_process["group_size_avg"]: sky = SaveAndLoad.recreate_frame(frame, L, interaction_radius) physics = Physics(sky, interaction_radius, eta) else: sky = SaveAndLoad.recreate_frame(frame, L, L) if self.to_process["avg_speed"]: self.process_avg_speed(sky) if self.to_process["avg_angle"]: self.process_avg_angle(sky) if self.to_process["groups"] or self.to_process["group_size"] or self.to_process["group_size_avg"]: groups, bird_to_group = physics.get_groups() group_to_size, size_occurences = get_group_size_occurences(groups) if self.to_process["group_to_size"]: self.process_group_to_size(group_to_size) if self.to_process["groups"]: self.process_groups(sky, bird_to_group) if self.to_process["group_size"]: self.process_group_size(size_occurences) if self.to_process["group_size_avg"]: self.process_group_size_avg(size_occurences, frame_number) if self.to_process["group_size_avg_fit"]: self.process_group_size_avg_fit() if self.to_process["correlations"]: self.process_correlations(sky, L) if self.to_process["correlations_fit"]: self.process_correlations_fit(L)
def save_prop_name(prop_name: str): SaveAndLoad.save_data_dirname(self.data_holders[prop_name], output_file, "%s.json" % prop_name)
def simulate(physics: Physics, dt: float, total_time: float, verbose_prop: float = .01, output_file: str = "simulation_data/data.json", evolve=lambda sky: None): timestamps = np.arange(0, total_time, dt) total_frames = len(timestamps) frames = [] start_t = time.time() log.info( "Simulation start at t=%s. Parameters: total_time=%.1f, dt=%.2f, L=%.1f, N=%d, vel=%.1f, omega=%.1f, r=%.1f, eta=%.2f" % (datetime.datetime.fromtimestamp(start_t).strftime( '%Y-%m-%d %H:%M:%S'), total_time, dt, physics.sky.L, len(physics.sky.birds), physics.sky.birds[0].vel, physics.sky.birds[0].ang_vel, physics.interaction_radius, physics.eta)) frame_number = 0 for _ in timestamps: frame_number += 1 if frame_number % (1 + int(total_frames * verbose_prop)) == 0: time_per_frame = (time.time() - start_t) / frame_number remaining_time = time_per_frame * (total_frames - frame_number) log.info("Simulating frame %d/%d - remaining est. %dh %dm %ds" % ( frame_number, total_frames, remaining_time // 3600 % 24, remaining_time // 60 % 60, remaining_time % 60, )) if evolve is not None: evolve(physics.sky) physics.advance(dt) frames.append([[bird.pos, bird.angle, bird.vel, bird.ang_vel] for bird in physics.sky.birds]) elapsed = time.time() - start_t log.info( "Simulation ended at t=%s, elapsed: %dh %dm %ds. N=%d, L=%d, eta=%.2f, v=%.1f, omega=%.1f, T=%d, dt=%.1f" % (datetime.datetime.fromtimestamp( time.time()).strftime('%Y-%m-%d %H:%M:%S'), elapsed // 3600 % 24, elapsed // 60 % 60, elapsed % 60, len(physics.sky.birds), physics.sky.L, physics.eta, physics.sky.birds[0].vel, physics.sky.birds[0].ang_vel, total_time, dt)) data_to_save = { "frames": frames, "parameters": { "dt": dt, "total_time": total_time, "L": physics.sky.L, "eta": physics.eta, "interaction_radius": physics.interaction_radius } } SaveAndLoad.save_data(data_to_save, output_file) log.info("Simulation results saved")