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")
예제 #2
0
    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")
예제 #3
0
    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")
예제 #5
0
    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)
예제 #6
0
 def save_prop_name(prop_name: str):
     SaveAndLoad.save_data_dirname(self.data_holders[prop_name], output_file, "%s.json" % prop_name)
예제 #7
0
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")