def model(districts, populations, cases, seed) -> NetworkedSIR:
    max_ts = cases["date_reported"].max()
    units = [
        SIR(district, populations[i], 
        dT0 = len(cases[(cases.geo_reported == district) & (cases.date_reported == max_ts)]), 
        mobility = 0.000001)
        for (i, district) in enumerate(districts)
    ]
    return NetworkedSIR(units, random_seed=seed)
def model(districts, populations, cases, seed) -> NetworkedSIR:
    units = [
        SIR(district, populations[i], 
        dT0 = cases[i], 
        R0 = 0, 
        D0 = 0, 
        mobility = 0.000001)
        for (i, district) in enumerate(districts)
    ]
    return NetworkedSIR(units, random_seed=seed)
Exemple #3
0
def run_simulation(school: SIR, nonschool: SIR):
    for _ in range(30):
        school.run(1)
        nonschool.forward_epi_step(dB = 2*school.dT[-1]//3) # doesn't preserve population

    dT_school    = np.array(school.dT)
    dT_nonschool = np.array(nonschool.dT)

    dT = dT_school + dT_nonschool

    var_up_school = np.array(school.upper_CI) - dT_school
    var_dn_school = np.array(school.lower_CI) - dT_school

    var_up_nonschool = np.array(nonschool.upper_CI) - dT_nonschool
    var_dn_nonschool = np.array(nonschool.lower_CI) - dT_nonschool

    dT_CI_l = dT - np.sqrt(var_dn_school**2 + var_dn_nonschool**2)
    dT_CI_u = dT + np.sqrt(var_up_school**2 + var_up_nonschool**2)

    return (dT[1:], dT_CI_l[1:], dT_CI_u[1:])
Exemple #4
0
def models(seed, simulated_school_Rt = school_Rt):
    school    = SIR("school",
        population = school_proportion * total_pop, 
        infectious_period = 6.25, 
        I0 = age_ts.sum(level = 0)["school"], 
        dT0 = age_ts.loc["school"][-1], 
        lower_CI = school_T_lb, 
        upper_CI = school_T_ub,
        Rt0 = simulated_school_Rt,
        random_seed = seed)
    nonschool = SIR("nonschool", 
        population = (1 - school_proportion) * total_pop, 
        infectious_period = 5.0, 
        I0 = age_ts.sum(level = 0)["nonschool"], 
        dT0 = age_ts.loc["nonschool"][-1], 
        lower_CI = school_T_lb, 
        upper_CI = school_T_ub,
        Rt0 = nonschool_Rt,
        random_seed = seed)
    return (school, nonschool)
Exemple #5
0
    geo_tag = f"{state}_{district}_"

    dD0 = ts.loc[district].dD.loc[simulation_start]
    I0 = max(0, (T_scaled - R - D))

    print(district, I0, "extended IFR",
          ts.loc[district].dD.cumsum()[simulation_start] / T_scaled,
          "instantaneous IFR", dD0 / (gamma * I0))

    # # run model forward with no vaccination
    model = SIR(
        name=district,
        population=N_district,
        dT0=np.ones(num_sims) *
        (dT_conf_district_smooth[simulation_start] * T_ratio).astype(int),
        Rt0=Rt[simulation_start],
        I0=np.ones(num_sims) * I0,
        R0=np.ones(num_sims) * R,
        D0=np.ones(num_sims) * D,
        mortality=ts.loc[district].dD.cumsum()[simulation_start] /
        T_scaled if I0 == 0 else dD0 / (gamma * I0),
        random_seed=0)
    model.dD[0] = np.ones(num_sims)
    param_tag = "novaccination"
    ran_models[geo_tag + param_tag] = model

    t = 0
    while (model.Rt[-1].mean() > Rt_threshold) and (model.dT[-1].mean() > 0):
        model.parallel_forward_epi_step()
        print("::::", district, "no vax", t, np.mean(model.dT[-1]),
              np.std(model.dT[-1]), model.Rt[-1].mean())
        t += 1
Exemple #6
0
    var_dn_nonschool = np.array(nonschool.lower_CI) - dT_nonschool

    dT_CI_l = dT - np.sqrt(var_dn_school**2 + var_dn_nonschool**2)
    dT_CI_u = dT + np.sqrt(var_up_school**2 + var_up_nonschool**2)

    return (dT[1:], dT_CI_l[1:], dT_CI_u[1:])


rt1_10x = run_simulation(*models(0, 1.10*school_Rt))
rt1_25x = run_simulation(*models(0, 1.25*school_Rt))
rt1_50x = run_simulation(*models(0, 1.50*school_Rt))

(dates, Rt_pred, Rt_CI_upper, Rt_CI_lower, T_pred, T_CI_upper, T_CI_lower, total_cases, new_cases_ts, anomalies, anomaly_dates)\
    = analytical_MPVS(age_ts.sum(level = 1), CI = CI, smoothing = smoothing, totals = False)

MAK = SIR(name = "MAK", population = 1.339e6, dT0 = T_pred[-1], Rt0 = Rt_pred[-1], upper_CI = T_CI_upper[-1], lower_CI = T_CI_lower[-1], mobility = 0, random_seed = 0, I0 = age_ts.sum(level = 1).sum()).run(30)

plt.daily_cases(dates, T_pred, T_CI_upper, T_CI_lower, new_cases_ts, anomaly_dates, anomalies, CI, 
    prediction_ts = [
        (MAK.dT[:-1], MAK.lower_CI[1:], MAK.upper_CI[1:], plt.PRED_PURPLE, "current social distancing"),
        (*rt1_10x, "orange",         "10% increase in school-age $R_t$"),
        (*rt1_25x, "mediumseagreen", "25% increase in school-age $R_t$"),
        (*rt1_50x, "hotpink",        "50% increase in school-age $R_t$"),
    ])\
    .xlabel("\ndate")\
    .ylabel("cases\n")
    # .title("\nMakassar Daily Cases - school reopening scenarios")\
    # .annotate("\nBayesian training process on empirical data, with anomalies identified")
(_, r) = plt.xlim()
plt.xlim(left = pd.Timestamp("Sep 1, 2020"), right = r)
plt.ylim(bottom = 10, top = 1000)
def model(seed = 0):
    return NetworkedSIR([SIR(
        name = "SULSEL", population = 8_819_500, 
        dT0 = historical.iloc[-1][0], Rt0 = Rt_pred[-1], upper_CI = T_CI_upper[-1], lower_CI = T_CI_lower[-1], 
        mobility = 0, I0 = historical.sum()[0]
    )], random_seed = seed)
logger.info("running province-level Rt estimate")
(dates, Rt_pred, Rt_CI_upper, Rt_CI_lower, T_pred, T_CI_upper, T_CI_lower, total_cases, new_cases_ts, anomalies, anomaly_dates)\
    = analytical_MPVS(new_cases, CI = CI, smoothing = smoothing, totals = False)

plt.Rt(dates, Rt_pred, Rt_CI_upper, Rt_CI_lower, CI)\
    .title("\nSouth Sulawesi: Reproductive Number Estimate")\
    .xlabel("\ndate")\
    .ylabel("$R_t$\n", rotation=0, labelpad=30)\
    .annotate(f"\n{window}-day smoothing window, gamma-prior Bayesian estimation method")\
    .show()

logger.info("running case-forward prediction")
prediction_period = 14*days
I0 = (~cases.confirmed.isna()).sum() - (~cases.recovered.isna()).sum() - (~cases.died.isna()).sum()
IDN = SIR(name = "IDN", population = 8_819_500, dT0 = T_pred[-1], Rt0 = Rt_pred[-1], upper_CI = T_CI_upper[-1], lower_CI = T_CI_lower[-1], mobility = 0, random_seed = 0, I0 = I0)\
           .run(prediction_period)

plt.daily_cases(dates, T_pred, T_CI_upper, T_CI_lower, new_cases_ts, anomaly_dates, anomalies, CI, 
    prediction_ts = [
        (IDN.dT[:-1], IDN.lower_CI[1:], IDN.upper_CI[1:], plt.PRED_PURPLE, "predicted cases")
    ])\
    .title("\nSouth Sulawesi: Daily Cases")\
    .xlabel("\ndate")\
    .ylabel("cases\n")\
    .annotate("\nBayesian training process on empirical data, with anomalies identified")\
    .show()

# makassar estimates 
mak_cases     = cases[cases.regency == "Makassar"]
mak_new_cases = mak_cases.confirmed.value_counts().sort_index()
 def model(seed):
     return NetworkedSIR([SIR(name = state, population = pop, dT0 = T_pred[-1], Rt0 = Rt_pred[-1], mobility = 0, I0 = I0)], random_seed = seed) 
import adaptive.plots as plt
from adaptive.models import SIR
from adaptive.estimators import analytical_MPVS, parametric_scheme_mcmc, branching_random_walk
from adaptive.smoothing import convolution
import numpy as np
import pandas as pd
import pymc3 as pm

sir_model = SIR("test",
                population=500000,
                I0=100,
                dT0=20,
                Rt0=1.01,
                random_seed=0)

total_t = 0
schedule = [(1.01, 75), (1.4, 75), (0.9, 75)]
R0_timeseries = []
for (R0, t) in schedule:
    R0_timeseries += [R0] * t
    sir_model.Rt0 = R0
    sir_model.run(t)
    total_t += t

plt.plot(sir_model.dT)
plt.show()
plt.plot(R0_timeseries, "-", color="black", label="$R_0$")
plt.plot(sir_model.Rt, "-", color="dodgerblue", label="$R_t$")
plt.legend(framealpha=1, handlelength=1, loc="best")
plt.PlotDevice().xlabel("time").ylabel("reproductive rate").adjust(left=0.10,
                                                                   bottom=0.15,
Exemple #11
0
natl_cases = sum(province_cases.values())


logger.info("running national-level Rt estimate")
(dates, Rt_pred, Rt_CI_upper, Rt_CI_lower, T_pred, T_CI_upper, T_CI_lower, total_cases, new_cases_ts, anomalies, anomaly_dates)\
     = analytical_MPVS(natl_cases, CI = CI, smoothing = smoothing) 

plt.Rt(dates, Rt_pred, Rt_CI_upper, Rt_CI_lower, CI, ymin=0, ymax=4)\
    .title("\nIndonesia: Reproductive Number Estimate")\
    .xlabel("\ndate")\
    .ylabel("$R_t$", rotation=0, labelpad=30)\
    .annotate(f"\n{window}-day smoothing window, gamma-prior Bayesian estimation method")\
    .show()

logger.info("running case-forward prediction")
IDN = SIR("IDN", 267.7e6, dT0 = T_pred[-1], Rt0 = Rt_pred[-1], mobility = 0, random_seed = 0).run(14)


logger.info("province-level projections")
migration = np.zeros((len(provinces), len(provinces)))
estimates = []
max_len = 1 + max(map(len, provinces))
with tqdm(provinces) as progress:
    for (province, cases) in province_cases.items():
        progress.set_description(f"{province :<{max_len}}")
        (dates, Rt_pred, Rt_CI_upper, Rt_CI_lower, *_) = analytical_MPVS(cases, CI = CI, smoothing = smoothing)
        apr_idx = np.argmax(dates >  "31 Mar, 2020")
        may_idx = np.argmax(dates >= "01 May, 2020")
        max_idx = np.argmax(Rt_pred[apr_idx:may_idx])
        apr_max_idx = apr_idx + max_idx
        estimates.append((province, Rt_pred[-1], Rt_CI_lower[-1], Rt_CI_upper[-1], max(0, linear_projection(dates, Rt_pred, window, period = 2*weeks)), Rt_pred[apr_max_idx], Rt_CI_lower[apr_max_idx], Rt_CI_upper[apr_max_idx], dates[apr_max_idx], cases.iloc[-1][0]))
Exemple #12
0
logger.info("running province-level Rt estimate")
(dates, RR_pred, RR_CI_upper, RR_CI_lower, T_pred, T_CI_upper, T_CI_lower, total_cases, new_cases_ts, anomalies, anomaly_dates)\
    = analytical_MPVS(jakarta_cases, CI = CI, smoothing = smoothing, totals=False) 

plt.Rt(dates, RR_pred[1:], RR_CI_upper[1:], RR_CI_lower[1:], CI)\
    .title("\nDKI Jakarta: Reproductive Number Estimate")\
    .xlabel("\ndate")\
    .ylabel("$R_t$\n", rotation=0, labelpad=30)\
    .annotate(f"\n{window}-day smoothing window, gamma-prior Bayesian estimation method")\
    .show()


logger.info("running case-forward prediction")
prediction_period = 14*days
IDN = SIR(name = "IDN", population = 267.7e6, dT0 = T_pred[-1], Rt0 = RR_pred[-1], upper_CI = T_CI_upper[-1], lower_CI = T_CI_lower[-1], mobility = 0, random_seed = 0)\
           .run(prediction_period)
 
plt.daily_cases(dates, T_pred[1:], T_CI_upper[1:], T_CI_lower[1:], new_cases_ts[1:], anomaly_dates, anomalies, CI, 
    prediction_ts = [
        (IDN.dT[:-1], IDN.lower_CI[1:], IDN.upper_CI[1:], None, "predicted cases")
    ])\
    .title("\nDKI Jakarta: Daily Cases")\
    .xlabel("\ndate")\
    .ylabel("cases\n")\
    .annotate("\nBayesian training process on empirical data, with anomalies identified")\
    .show()

logger.info("district-level projections")
district_cases = dkij.groupby(["district", "date_positiveresult"])["id"].count().sort_index()
districts = dkij.district.unique()
migration = np.zeros((len(districts), len(districts)))
Exemple #13
0
# first, look at state level predictions
(dates, Rt_pred, Rt_CI_upper, Rt_CI_lower, T_pred, T_CI_upper, T_CI_lower,
 total_cases, new_cases_ts, anomalies, anomaly_dates) = analytical_MPVS(
     state_ts,
     CI=CI,
     smoothing=notched_smoothing(window=smoothing),
     totals=False)

plt.Rt(dates, Rt_pred[1:], Rt_CI_upper[1:], Rt_CI_lower[1:], CI, ymin=0, ymax=3)\
    .title("\nBihar: Reproductive Number Estimate (Covid19India Data)")\
    .annotate(f"public data from {str(dates[0]).split()[0]} to {str(dates[-1]).split()[0]}")\
    .xlabel("\ndate")\
    .ylabel("$R_t$", rotation=0, labelpad=20)\
    .show()

Bihar = SIR(name="Bihar",
            population=99_000_000,
            dT0=T_pred[-1],
            Rt0=Rt_pred[-1],
            mobility=0,
            random_seed=0)
Bihar.run(14)

plt.daily_cases(dates, T_pred[1:], T_CI_upper[1:], T_CI_lower[1:], new_cases_ts[1:], anomaly_dates, anomalies, CI,
    prediction_ts = [(Bihar.dT[:-1], Bihar.lower_CI[1:], Bihar.upper_CI[1:], None, "predicted cases")])\
    .title("\nBihar: Daily Cases")\
    .xlabel("\ndate")\
    .ylabel("cases\n")\
    .annotate("\nBayesian training process on empirical data, with anomalies identified")\
    .show()

# now, do district-level estimation
        policies = [RandomVaccineAssignment(daily_vax_doses, IN_age_ratios)]
    else:
        policies = [
            RandomVaccineAssignment(daily_vax_doses, IN_age_ratios),
            PrioritizedAssignment(daily_vax_doses, split_by_age(S),
                                  [6, 5, 4, 3, 2, 1, 0], "mortality"),
            PrioritizedAssignment(daily_vax_doses, split_by_age(S),
                                  [1, 2, 3, 4, 0, 5, 6], "contactrate")
        ]

    for vaccination_policy in policies:
        model = SIR(name=state,
                    population=N,
                    dT0=np.ones(num_sims) *
                    (dT_conf_smooth[simulation_start] * T_ratio).astype(int),
                    Rt0=Rt[simulation_start] * N / (N - T_sero),
                    I0=np.ones(num_sims) * S,
                    R0=np.ones(num_sims) * R,
                    D0=np.ones(num_sims) * D,
                    random_seed=0)

        t = 0
        dVx = [np.zeros(len(IN_age_structure))]

        # run vax rate forward 1 year, then until 75% of pop is recovered or vax
        while (t <= 365) or ((t > 365) and
                             (model.R[-1].mean() +
                              (daily_vax_doses * t)) / N < immunity_threshold):
            dVx.append(vaccination_policy.distribute_doses(model))
            print("::::", state, vax_pct_annual_goal, vax_effectiveness,
                  vaccination_policy.name(), t, np.mean(model.dT[-1]),
T_scaled = dT_conf_smooth.cumsum()[simulation_start] * T_ratio

D, R = df.loc[simulation_start, "TT"]["total"][["deceased", "recovered"]]
S = N_natl - T_scaled - D - R

(Rt_dates, Rt_est, *_) = analytical_MPVS(T_ratio * dT_conf_smooth,
                                         CI=CI,
                                         smoothing=lambda _: _,
                                         totals=False)
Rt = dict(zip(Rt_dates, Rt_est))

model = SIR(name=state,
            population=N_natl,
            dT0=np.ones(num_sims) *
            (dT_conf_smooth[simulation_start] * T_ratio).astype(int),
            Rt0=Rt[simulation_start],
            I0=np.ones(num_sims) * (T_scaled - R - D),
            R0=np.ones(num_sims) * R,
            D0=np.ones(num_sims) * D,
            mortality=mu_TN,
            random_seed=0)

while np.mean(model.dT[-1]) > 0:
    model.parallel_forward_epi_step()

pd.DataFrame(data = {
        "date": [simulation_start + pd.Timedelta(n, "days") for n in range(len(model.dT))],
        "dT"  : [np.mean(_)/N_natl for _ in model.dT],
        "dD"  : [np.mean(_)/N_natl for _ in model.dD],
    })\
    .assign(month = lambda _: _.date.dt.month.astype(str) + "_" + _.date.dt.year.astype(str))\
    .groupby("month")\
    (Rt_dates, Rt_est, *_) = analytical_MPVS(T_ratio * dT_conf_district_smooth,
                                             CI=CI,
                                             smoothing=lambda _: _,
                                             totals=False)
    Rt = dict(zip(Rt_dates, Rt_est))

    daily_rate = vax_pct_annual_goal / 365
    daily_vax_doses = int(vax_effectiveness * daily_rate * N_district)

    T_scaled = dT_conf_district_smooth.cumsum()[simulation_start] * T_ratio

    model = SIR(
        name=state,
        population=N_district,
        dT0=np.ones(num_sims) *
        (dT_conf_district_smooth[simulation_start] * T_ratio).astype(int),
        Rt0=Rt[simulation_start] * N_district / (N_district - T_scaled),
        I0=np.ones(num_sims) * (T_scaled - R - D),
        R0=np.ones(num_sims) * R,
        D0=np.ones(num_sims) * D,
        random_seed=0)

    t = 0
    dVx = [np.zeros(len(IN_age_structure))]

    # run vax rate forward 1 year, then until 75% of pop is recovered or vax
    while (t <= 365) or (
        (t > 365) and
        (model.R[-1].mean() +
         (daily_vax_doses * t)) / N_district < immunity_threshold):
        dVx.append(Multinomial.rvs(daily_vax_doses, IN_age_ratios))
        model.S[-1] -= daily_vax_doses
    # grab time series
    R = df[state].loc[simulation_start, "total", "recovered"]
    D = df[state].loc[simulation_start, "total", "deceased"]

    # run Rt estimation on scaled timeseries
    (Rt_dates, Rt_est, *_) = analytical_MPVS(T_ratio * dT_conf_smooth,
                                             CI=CI,
                                             smoothing=lambda _: _,
                                             totals=False)
    Rt = dict(zip(Rt_dates, Rt_est))

    model = SIR(name=state,
                population=N,
                dT0=np.ones(num_sims) *
                (dT_conf_smooth[simulation_start] * T_ratio).astype(int),
                Rt0=Rt[simulation_start] * N / (N - T_sero),
                I0=np.ones(num_sims) * (T_sero - R - D),
                R0=np.ones(num_sims) * R,
                D0=np.ones(num_sims) * D,
                random_seed=0)
    i = 0

    print(
        Rt[simulation_start], Rt[simulation_start] * N /
        (N - T_ratio * T_conf_smooth[simulation_start]))

    while np.mean(model.dT[-1]) > 0:
        model.parallel_forward_epi_step(num_sims=num_sims)
        i += 1
        print(state, i, np.mean(model.dT[-1]), np.std(model.dT[-1]))
    Rt_m = np.mean(Rt[(Rt.index >= "31 March, 2020") & (Rt.index <= "17 May, 2020")])[0]
    Rt_v = np.mean(Rt[(Rt.index <  "31 March, 2020")])[0]
    print("  + Rt today:", Rt_pred[-1])
    print("  + Rt_m    :", Rt_m)
    print("  + Rt_v    :", Rt_v)
    historical = pd.DataFrame({"smoothed": new_cases_ts}, index = dates)

    plt.Rt(dates, Rt_pred, RR_CI_lower, RR_CI_upper, CI)\
        .ylabel("$R_t$")\
        .xlabel("date")\
        .title(f"\n{state}: Reproductive Number Estimate")\
        .annotate(f"public data from {str(dates[0]).split()[0]} to {str(dates[-1]).split()[0]}")\
        .show()
    
    I0 = (ts.loc[state].Hospitalized - ts.loc[state].Recovered - ts.loc[state].Deceased).sum()
    state_model = SIR(name = state, population = pop, dT0 = T_pred[-1], Rt0 = Rt_pred[-1], mobility = 0, I0 = I0, upper_CI = T_CI_upper[-1], lower_CI = T_CI_lower[-1], random_seed = 0).run(10)

    empirical = state_ts_full[(state_ts_full.index >= "Oct 14, 2020") & (state_ts_full.index < "Oct 25, 2020")]

    plt.daily_cases(dates, T_pred, T_CI_upper, T_CI_lower, new_cases_ts, anomaly_dates, anomalies, CI, 
        prediction_ts=[
            (state_model.dT, state_model.lower_CI, state_model.upper_CI, plt.PRED_PURPLE, "predicted cases"),
        ] + [(empirical, empirical, empirical, "black", "empirical post-prediction cases")] if state != "Maharashtra" else [])\
        .ylabel("cases")\
        .xlabel("date")\
        .title(f"\n{state}: Daily Cases")\
        .annotate("\nBayesian training process on empirical data, with anomalies identified")
    _, r = plt.xlim()
    plt.xlim(left = pd.Timestamp("August 01, 2020"), right = r)
    plt.show()