示例#1
0
def plot_points(plt, positions, status, title=None):
    x = [p[0] for p in positions]
    y = [p[1] for p in positions]
    if status is not None:
        c = [STATE_COLORS[s] for s in status]
        sizes = [1, 16, 9, 9, 4, 16]
        scatter = plt.scatter(x=x,
                              y=y,
                              c=status,
                              alpha=0.9,
                              s=[sizes[s] + 4 for s in status])
        running = Counter(status)
        descriptions = list(STATE_DESCRIPTIONS.values())
        running_totals = [(descriptions[k] + " (" + str(v) + ")", k)
                          for k, v in running.items()]
        running_totals.sort(key=lambda rt: rt[1])
        labels = [desc for desc, _ in running_totals]
        plt.legend(handles=scatter.legend_elements()[0],
                   labels=labels,
                   loc='upper left')
        if title:
            plt.title(title)
    else:
        scatter = plt.scatter(x=x, y=y)
    return scatter
示例#2
0
def simulate(params, plt=None, plot_hourly=None, xlabel=None):

    if plot_hourly is None:
        plot_hourly = params['geometry']['n'] < 50000  # Hack, remove

    # Initialize a city's geography and its denizens
    num, num_initially_infected = int(params['geometry']['n']), int(
        params['geometry']['i'])
    num_times_of_day = int(params['motion']['t'])
    precision = int(params['geometry']['p'])
    home, work = home_and_work_locations(geometry_params=params['geometry'],
                                         num=num)
    positions = nudge(home, w=0.05 * params['motion']['w'])
    status = np.random.permutation([INFECTED] * num_initially_infected +
                                   [VULNERABLE] *
                                   (num - num_initially_infected))
    day_fraction = 1.0 / num_times_of_day

    # Population drifts to work and back, incurring viral load based on proximity to others who are infected
    day = 0
    while any(s in [INFECTED, POSITIVE, SYMPTOMATIC] for s in status):
        day = day + 1
        for step_no, time_of_day in enumerate(times_of_day(num_times_of_day)):
            stationary = [s in [DECEASED, POSITIVE] for s in status]
            attractors = destinations(status, time_of_day, home, work)
            positions = evolve_positions(positions=positions,
                                         motion_params=params['motion'],
                                         attractors=attractors,
                                         day_fraction=day_fraction,
                                         stationary=stationary)
            exposed = newly_exposed(positions=positions,
                                    status=status,
                                    precision=precision)
            status = contact_progression(status=status,
                                         health_params=params['health'],
                                         exposed=exposed)
            status = individual_progression(status,
                                            health_params=params['health'],
                                            day_fraction=day_fraction)

            if plt and (plot_hourly or step_no % 12 == 0):
                plt.clf()
                plot_points(plt=plt,
                            positions=positions,
                            status=status,
                            title="Day " + str(day) + ':' +
                            str(time_of_day * num_times_of_day))
                b = params['geometry']['b']
                plt.axis([-b, b, -b, b])
                if xlabel:
                    plt.xlabel(xlabel)
                plt.show(block=False)
                plt.pause(0.01)
            pprint(
                Counter([list(STATE_DESCRIPTIONS.values())[s]
                         for s in status]))
示例#3
0
def simulate(params, plt=None, hourly=None, xlabel=None, callback=plot_callback, home=None, work=None, positions=None, stopping_i=None, stopping_t=None):
    """ OU Pandemic simulation
    :param params:       dict of dict as per pandemic.conventions
    :param plt:          Handle to matplotlib plot
    :param hourly:  Bool        Set False to speed up, True to see commuting
    :param xlabel:       str         Label for plot
    :param callback:     Any function taking home, work, day, params, positions, status (e.g. for plotting, saving etc)
    :return: None        Use the callback
    """
    if stopping_i is None:
        import math
        stopping_i = int(math.ceil(0.7 * params['geometry']['i']))
    if hourly is None:
        hourly = params['geometry']['n'] < 50000  # Hack, remove
    if stopping_t is None:
        stopping_t = 150

    # Initialize a city's geography and its denizens
    num, num_initially_infected = int(params['geometry']['n']),int(params['geometry']['i'])
    num_times_of_day = int(params['motion']['t'])
    precision  = int(params['geometry']['p'])
    if home is None or work is None:
        home, work = home_and_work_locations(geometry_params=params['geometry'],num=num)
    if positions is None:
        positions  = nudge(home,w=0.05*params['motion']['w'])
    status     = np.random.permutation([INFECTED]*num_initially_infected +[VULNERABLE]*(num-num_initially_infected))
    time_step  = 1.0/num_times_of_day

    day = 0
    killed = False
    while sum( s in [ INFECTED ] for s in status )>=stopping_i and day<stopping_t and not killed:
        day = day+1
        for step_no, day_fraction in enumerate(times_of_day(num_times_of_day)):
            stationary = [ s in [DECEASED, POSITIVE] for s in status ]
            attractors = destinations(status, day_fraction, home, work)
            positions  = evolve_positions(positions=positions, motion_params=params['motion'], attractors=attractors,
                                          time_step=time_step , stationary=stationary )
            exposed = newly_exposed(positions=positions, status=status, precision=precision)
            status = contact_progression(status=status, health_params=params['health'], exposed=exposed)
            status = individual_progression(status, health_params=params['health'], day_fraction=time_step )

            if callback:
                signal = callback(day=day, day_fraction=day_fraction, home=home, work=work, positions=positions, status=status, params=params, step_no=step_no, hourly=hourly, plt=plt, xlabel=xlabel)
                if signal is not None:
                    if 'kill' in signal:
                        killed = True
                    if 'lockdown' in signal:
                        work = [ h for h in home ]
                    if 'params' in signal:
                        params.update(signal['params'])
    pprint(Counter([list(STATE_DESCRIPTIONS.values())[s] for s in status]))
示例#4
0
 def plot_metrics(self, plt, logarithmic, differences=False):
     metrics = list(zip(*self.metric_history))[1:]
     if len(metrics[0]) > 3:
         for m in metrics[1:-2]:
             if differences:
                 plt.plot(self.time_history[1:], list(np.diff(m)))
                 plt.set_ylabel('Daily change')
             else:
                 plt.plot(self.time_history, m)
                 plt.set_ylabel('Cumulative')
         if logarithmic:
             plt.set_yscale('log')
         labels = list(STATE_DESCRIPTIONS.values())[1:-2]
         if differences:
             labels = ['net newly ' + lb for lb in labels]
         plt.legend(labels)
         plt.set_xlabel('Days since first ' + str(self.params['geometry']['i']) + ' infections.')
示例#5
0
def simulate(params,
             plt=None,
             plot_hourly=None,
             xlabel=None,
             callback=plot_callback):
    """ OU Pandemic simulation
    :param params:       dict of dict as per pandemic.conventions
    :param plt:          Handle to matplotlib plot
    :param plot_hourly:  Bool        Set False to speed up, True to see commuting
    :param xlabel:       str         Label for plot
    :param callback:     Any function taking home, work, day, params, positions, status (e.g. for plotting, saving etc)
    :return: None        Use the callback
    """

    if plot_hourly is None:
        plot_hourly = params['geometry']['n'] < 50000  # Hack, remove

    # Initialize a city's geography and its denizens
    num, num_initially_infected = int(params['geometry']['n']), int(
        params['geometry']['i'])
    num_times_of_day = int(params['motion']['t'])
    precision = int(params['geometry']['p'])
    home, work = home_and_work_locations(geometry_params=params['geometry'],
                                         num=num)
    positions = nudge(home, w=0.05 * params['motion']['w'])
    status = np.random.permutation([INFECTED] * num_initially_infected +
                                   [VULNERABLE] *
                                   (num - num_initially_infected))
    time_step = 1.0 / num_times_of_day

    # Population drifts to work and back, incurring viral load based on proximity to others who are infected
    day = 0
    while any(s in [INFECTED] for s in status):
        day = day + 1
        for step_no, day_fraction in enumerate(times_of_day(num_times_of_day)):
            stationary = [s in [DECEASED, POSITIVE] for s in status]
            attractors = destinations(status, day_fraction, home, work)
            positions = evolve_positions(positions=positions,
                                         motion_params=params['motion'],
                                         attractors=attractors,
                                         time_step=time_step,
                                         stationary=stationary)
            exposed = newly_exposed(positions=positions,
                                    status=status,
                                    precision=precision)
            status = contact_progression(status=status,
                                         health_params=params['health'],
                                         exposed=exposed)
            status = individual_progression(status,
                                            health_params=params['health'],
                                            day_fraction=time_step)

            if callback:
                callback(day=day,
                         day_fraction=day_fraction,
                         home=home,
                         work=work,
                         positions=positions,
                         status=status,
                         params=params,
                         step_no=step_no,
                         plot_hourly=plot_hourly,
                         plt=plt)
    pprint(Counter([list(STATE_DESCRIPTIONS.values())[s] for s in status]))
    # Get all valid parameter keys that have at least 150 days
    all_params = set()
    all_keys = set()
    ddata = list()
    for s, v in data.items():
        i = int(s)
        vdata = [v_ / 800000 for v_ in json.loads(v)]
        all_keys.add(i)
        params_as_int = i % PARAMS_SCALE
        elapsed = float(s[:8]) / 10000
        record = {
            'key': i,
            'params': params_as_int,
            'elapsed': elapsed,
            'reverse_key': params_as_int * 1000 + elapsed
        }
        for name, val in zip(STATE_DESCRIPTIONS.values(), vdata):
            record.update({name: val})
        ddata.append(record)

    sdata = sorted(ddata, key=lambda x: x['reverse_key'])
    df = pd.DataFrame.from_records(sdata)
    g = df.groupby(by='params').count().sort_values(by='key')
    valid = list(g[g['key'] > 150].index.values)
    print(len(valid))
    valid_row = [k in valid for k in df['params'].values]
    df1 = df.loc[valid_row, :]
    df1.sort_values(by=['params', 'elapsed'], inplace=True)
    df1.drop(columns=['key', 'params', 'elapsed', 'reverse_key'], inplace=True)
    df1.to_csv('dump.csv')