Ejemplo n.º 1
0
 def __init__(self, *args, **kwargs):
     #default data
     self.Config = Configuration()
     self.frame = 0
     # default pop init
     self.population_init()
     self.pop_tracker = Population_trackers()
     #destinations vector init
     self.destinations = initialize_destination_matrix(
         self.Config.size_pop, 1)
     self.figure, self.spec, self.ax1, self.ax2 = build_fig(self.Config)
Ejemplo n.º 2
0
    def run(self):
        '''run simulation'''

        if self.Config.visualise:
            self.fig, self.spec, self.ax1, self.ax2, self.tight_bbox = build_fig(
                self.Config)

        i = 0

        while i < self.Config.simulation_steps:
            try:
                self.tstep()
            except KeyboardInterrupt:
                print('\nCTRL-C caught, exiting')
                sys.exit(1)

            #check whether to end if no infectious persons remain.
            #check if self.frame is above some threshold to prevent early breaking when simulation
            #starts initially with no infections.
            if self.Config.endif_no_infections and self.frame >= 300:
                if len(self.population[(self.population[:, 6] == 1) |
                                       (self.population[:, 6] == 4)]) == 0:
                    i = self.Config.simulation_steps
            else:
                i += 1

        if self.Config.plot_last_tstep:
            self.fig_sir, self.spec_sir, self.ax1_sir = build_fig_SIRonly(
                self.Config)
            draw_SIRonly(self.Config, self.population, self.pop_tracker,
                         self.frame, self.fig_sir, self.spec_sir, self.ax1_sir)

        if self.Config.save_data:
            save_data(self.population, self.pop_tracker)

        #report outcomes
        if self.Config.verbose:
            print('\n-----stopping-----\n')
            print('total timesteps taken: %i' % self.frame)
            print('total dead: %i' %
                  len(self.population[self.population[:, 6] == 3]))
            print('total recovered: %i' %
                  len(self.population[self.population[:, 6] == 2]))
            print('total infected: %i' %
                  len(self.population[self.population[:, 6] == 1]))
            print('total infectious: %i' %
                  len(self.population[(self.population[:, 6] == 1) |
                                      (self.population[:, 6] == 4)]))
            print('total unaffected: %i' %
                  len(self.population[self.population[:, 6] == 0]))
            print('mean distance travelled: %f' %
                  np.mean(self.pop_tracker.distance_travelled))
Ejemplo n.º 3
0
    def __init__(self, *args, **kwargs):
        # load default config data
        self.Config = Configuration()
        self.frame = 0

        # initialize default population
        self.population_init()

        self.pop_tracker = Population_trackers()

        # initalise destinations vector
        self.destinations = initialize_destination_matrix(self.Config.pop_size, 1)

        self.fig, self.spec, self.ax1, self.ax2 = build_fig(self.Config)
Ejemplo n.º 4
0
    def tstep(self):
        '''
        takes a time step in the simulation
        '''
        
        if self.frame == 0 and self.Config.visualise:
            #initialize figure
            self.fig, self.spec, self.ax1, self.ax2 , self.ax3 = build_fig(self.Config)

        #check destinations if active
        #define motion vectors if destinations active and not everybody is at destination
        active_dests = len(self.population[self.population[:,11] != 0]) # look op this only once

        if active_dests > 0 and len(self.population[self.population[:,12] == 0]) > 0:
            self.population = set_destination(self.population, self.destinations)
            self.population = check_at_destination(self.population, self.destinations, 
                                                   wander_factor = self.Config.wander_factor_dest,
                                                   speed = self.Config.speed)

        if active_dests > 0 and len(self.population[self.population[:,12] == 1]) > 0:
            #keep them at destination 到达dest 以一定范围wander
            self.population = keep_at_destination(self.population, self.destinations,
                                                  self.Config.wander_factor)

        #out of bounds 要把wander的方向朝向修改 防止wander超出边界
        #define bounds arrays, excluding those who are marked as having a custom destination
        if len(self.population[:,11] == 0) > 0:
            _xbounds = np.array([[self.Config.xbounds[0] + 0.02, self.Config.xbounds[1] - 0.02]] * len(self.population[self.population[:,11] == 0]))
            _ybounds = np.array([[self.Config.ybounds[0] + 0.02, self.Config.ybounds[1] - 0.02]] * len(self.population[self.population[:,11] == 0]))
            self.population[self.population[:,11] == 0] = out_of_bounds(self.population[self.population[:,11] == 0], 
                                                                        _xbounds, _ybounds)
        
        #set randoms 最大感染数 只要到达过最大感染数就持续lockdown
        if self.Config.lockdown:
            if len(self.pop_tracker.infectious) == 0:
                mx = 0
            else:
                mx = np.max(self.pop_tracker.infectious)

            if len(self.population[self.population[:,6] == 1]) >= len(self.population) * self.Config.lockdown_percentage or\
               mx >= (len(self.population) * self.Config.lockdown_percentage):
                #reduce speed of all members of society 使最大速度为0.001
                self.population[:,5] = np.clip(self.population[:,5], a_min = None, a_max = 0.001)
                #set speeds of complying people to 0 遵循lockdown的速度 为0
                self.population[:,5][self.Config.lockdown_vector == 0] = 0
            else:
                #update randoms
                self.population = update_randoms(self.population, self.Config.pop_size, self.Config.speed)
        else:
            #update randoms
            self.population = update_randoms(self.population, self.Config.pop_size, self.Config.speed)

        #for dead ones: set speed and heading to 0
        self.population[:,3:5][self.population[:,6] == 3] = 0
        
        #update positions
        self.population = update_positions(self.population)

        #find new infections
        self.population, self.destinations = infect(self.population, self.Config, self.frame, 
                                                    send_to_location = self.Config.self_isolate, 
                                                    location_bounds = self.Config.isolation_bounds,  
                                                    destinations = self.destinations, 
                                                    location_no = 1, 
                                                    location_odds = self.Config.self_isolate_proportion)

        #recover and die
        self.population = recover_or_die(self.population, self.frame, self.Config)

        #send cured back to population if self isolation active
        #perhaps put in recover or die class
        #send cured back to population
        self.population[:,11][self.population[:,6] == 2] = 0
        #compute gdp
        peoplegdp, businessgdp, governgdp, totalgdp = economical_change(self.population, self.Config)
        #update population statistics
        self.pop_tracker.update_counts(self.population, peoplegdp, businessgdp, governgdp, totalgdp)


        #visualise
        if self.Config.visualise:
            draw_tstep(self.Config, self.population, self.pop_tracker, self.frame, 
                       self.fig, self.spec, self.ax1, self.ax2,self.ax3)

        #report stuff to console
        sys.stdout.write('\r')
        sys.stdout.write('%i: healthy: %i, infected: %i, immune: %i, in treatment: %i, \
dead: %i, of total: %i' %(self.frame, self.pop_tracker.susceptible[-1], self.pop_tracker.infectious[-1],
                        self.pop_tracker.recovered[-1], len(self.population[self.population[:,10] == 1]),
                        self.pop_tracker.fatalities[-1], self.Config.pop_size))

        #save popdata if required
        if self.Config.save_pop and (self.frame % self.Config.save_pop_freq) == 0:
            save_population(self.population, self.frame, self.Config.save_pop_folder)
        #run callback
        self.callback()

        #update frame
        self.frame += 1
Ejemplo n.º 5
0
    def tstep(self):

        if self.frame == 0:
            self.fig, self.spec, self.ax1, self.ax2 = build_fig(self.Config)

        xbounds = np.array(
            [[self.Config.xbounds[0] + 0.02, self.Config.xbounds[1] - 0.02]] *
            self.Config.pop_size)
        ybounds = np.array(
            [[self.Config.ybounds[0] + 0.02, self.Config.ybounds[1] - 0.02]] *
            self.Config.pop_size)
        self.population = out_of_bounds(self.population, xbounds, ybounds)

        if self.Config.is_lockdown and self.Config.lockdown == False:
            if len(self.population[(self.population[:, 6] == 1)]
                   ) >= self.Config.lockdown_percentage * self.Config.pop_size:
                self.Config.lockdown = True
                print("\nLockdown Started")

        left_range = [
            self.Config.xbounds[0] + 0.02, self.Config.xbounds[1] / 3 - 0.02
        ]
        mid_range = [
            self.Config.xbounds[1] / 3 + 0.02,
            2 * self.Config.xbounds[1] / 3 - 0.02
        ]
        right_range = [
            2 * self.Config.xbounds[1] / 3 + 0.02,
            self.Config.xbounds[1] - 0.02
        ]

        bottom_range = [
            self.Config.ybounds[0] + 0.02, self.Config.ybounds[1] / 2 - 0.02
        ]
        top_range = [
            self.Config.ybounds[1] / 2 + 0.02, self.Config.ybounds[1] - 0.02
        ]

        left_condition = (self.population[:, 1] <= self.Config.xbounds[1] / 3)
        mid_condition = (
            self.population[:, 1] > self.Config.xbounds[1] / 3) & (
                self.population[:, 1] <= 2 * self.Config.xbounds[1] / 3)
        right_condition = (self.population[:, 1] >
                           2 * self.Config.xbounds[1] / 3)

        bottom_condition = (self.population[:, 2] <=
                            self.Config.ybounds[1] / 2)
        top_condition = (self.population[:, 2] > self.Config.ybounds[1] / 2)

        if self.Config.lockdown:

            x_left_bottom = np.array(
                [left_range] *
                len(self.population[left_condition & bottom_condition]))
            y_left_bottom = np.array(
                [bottom_range] *
                len(self.population[left_condition & bottom_condition]))
            self.population[left_condition & bottom_condition] = out_of_bounds(
                self.population[left_condition & bottom_condition],
                x_left_bottom, y_left_bottom)

            x_left_top = np.array(
                [left_range] *
                len(self.population[left_condition & top_condition]))
            y_left_top = np.array(
                [top_range] *
                len(self.population[left_condition & top_condition]))
            self.population[left_condition & top_condition] = out_of_bounds(
                self.population[left_condition & top_condition], x_left_top,
                y_left_top)

            x_mid_bottom = np.array(
                [mid_range] *
                len(self.population[mid_condition & bottom_condition]))
            y_mid_bottom = np.array(
                [bottom_range] *
                len(self.population[mid_condition & bottom_condition]))
            self.population[mid_condition & bottom_condition] = out_of_bounds(
                self.population[mid_condition & bottom_condition],
                x_mid_bottom, y_mid_bottom)

            x_mid_top = np.array(
                [mid_range] *
                len(self.population[mid_condition & top_condition]))
            y_mid_top = np.array(
                [top_range] *
                len(self.population[mid_condition & top_condition]))
            self.population[mid_condition & top_condition] = out_of_bounds(
                self.population[mid_condition & top_condition], x_mid_top,
                y_mid_top)

            x_right_bottom = np.array(
                [right_range] *
                len(self.population[right_condition & bottom_condition]))
            y_right_bottom = np.array(
                [bottom_range] *
                len(self.population[right_condition & bottom_condition]))
            self.population[right_condition
                            & bottom_condition] = out_of_bounds(
                                self.population[right_condition
                                                & bottom_condition],
                                x_right_bottom, y_right_bottom)

            x_right_top = np.array(
                [right_range] *
                len(self.population[right_condition & top_condition]))
            y_right_top = np.array(
                [top_range] *
                len(self.population[right_condition & top_condition]))
            self.population[right_condition & top_condition] = out_of_bounds(
                self.population[right_condition & top_condition], x_right_top,
                y_right_top)

        self.population = update_randoms(self.population, self.Config.pop_size,
                                         self.Config.speed)

        self.population[:, 5][self.population[:, 6] == 3] = 0

        self.population = update_positions(self.population)

        self.population = infect(self.population, self.Config, self.frame)

        self.population = recover_or_die(self.population, self.frame,
                                         self.Config)

        self.pop_tracker.update_counts(self.population)

        draw_tstep(self.Config, self.population, self.pop_tracker, self.frame,
                   self.fig, self.spec, self.ax1, self.ax2)

        self.peak_infections = max(
            self.peak_infections,
            len(self.population[self.population[:, 6] == 1]))

        if self.frame == 50:
            print('\ninfecting patient zero')
            self.population[0][6] = 1

        self.frame += 1