def run_model(param_updates, n_steps=200, lockdown_at=None):
    params = setup_params(param_updates)
    # Create an instance of the Model
    model = Model(params)
    m_out = []
    for step in trange(n_steps):
        # Evaluate each step and save the results
        model.one_time_step()
        # LOGGER.info(
        #     model.one_time_step_results()
        # )  # If we want to see the results as we go uncomment this block
        m_out.append(model.one_time_step_results())
        if lockdown_at:
            if step == lockdown_at:
                model.update_running_params("lockdown_on", 1)
                LOGGER.info(f"turning on lock down at step {step}")
                LOGGER.info(
                    f'lockdown_house_interaction_multiplier = {params.get_param("lockdown_house_interaction_multiplier")}'
                )
                LOGGER.info(
                    f'lockdown_random_network_multiplier = {params.get_param("lockdown_random_network_multiplier")}'
                )
                for oc_net in OccupationNetworkEnum:
                    LOGGER.info(
                        f'lockdown_occupation_multiplier{oc_net.name} = {params.get_param(f"lockdown_occupation_multiplier{oc_net.name}")}'
                    )
    df = pd.DataFrame(m_out)
    model.write_output_files()
    return df
Ejemplo n.º 2
0
 def test_set_params_occupation_network_by_age_check_used(self):
     p = Parameters(
         read_param_file=True,
         input_households="tests/data/baseline_household_demographics.csv",
         input_param_file="tests/data/baseline_parameters.csv",
         param_line_number=1,
     )
     model = Model(p)
     non_scaled = [
         model.get_param(f"daily_fraction_work_used{age.name}")
         for age in OccupationNetworkEnum
     ]
     model.update_running_params("lockdown_on", 1)
     scaled = [
         model.get_param(f"daily_fraction_work_used{age.name}")
         for age in OccupationNetworkEnum
     ]
     for non_scaled_i, scaled_i in zip(non_scaled, scaled):
         assert non_scaled_i * 0.2 == scaled_i
     model.update_running_params(
         "lockdown_occupation_multiplier_primary_network", 10.0)
     scaled = [
         model.get_param(f"daily_fraction_work_used{age.name}")
         for age in OccupationNetworkEnum
     ]
     for non_scaled_i, scaled_i, factor in zip(non_scaled, scaled, [
             10.0,
             0.2,
             0.2,
             0.2,
             0.2,
     ]):
         assert non_scaled_i * factor == scaled_i
Ejemplo n.º 3
0
 def test_run_model_read_prama_file_false(self):
     all_params = pd.read_csv("tests/data/baseline_parameters.csv")
     p = Parameters(
         read_param_file=False,
         input_households="tests/data/baseline_household_demographics.csv",
     )
     for key in all_params:
         value = all_params[key][0]
         try:
             p.set_param(key, float(value))
         except TypeError:
             p.set_param(key, int(value))
     m = Model(p)
     m.one_time_step()
     assert m.one_time_step_results()["time"] == 1
Ejemplo n.º 4
0
def _worker(
    args: Tuple[Region, Mapping[Age10Y, float], multiprocessing.Queue],
    output_dir: str,
    parameters_path: str,
    household_demographics_path: str,
    total_individuals: int,
    lockdown_start: Optional[int],
    lockdown_end: int,
    end_time: int,
) -> None:
    region, populations, queue = args
    # Prepare output paths for each region
    output_file_name = pathlib.Path(output_dir).joinpath(f"{region.name}_ts.csv")
    detailed_output_dir = pathlib.Path(output_dir).joinpath(f"{region.name}_detailed")
    os.makedirs(detailed_output_dir, exist_ok=True)

    # Init parameters from repo baseline
    params = Parameters(
        parameters_path, 1, str(detailed_output_dir), household_demographics_path,
    )
    # Set more simulation params
    params.set_param("n_total", total_individuals)
    params.set_param("end_time", end_time)
    # FIXME: not writing detailed output
    params.set_param("sys_write_individual", 1)

    # Set populations
    for k, v in populations.items():
        params.set_param(k.value, v)

    # Activate lockdown if specified
    if lockdown_start is not None:
        for k, v in LOCKDOWN_PARMAETERS.items():
            params.set_param(k, v)
        params.set_param("lockdown_time_on", lockdown_start)
        params.set_param("lockdown_time_off", lockdown_end)

    # Set up model
    model = simulation.COVID19IBM(model=Model(params))
    agent = simulation.Agent()
    results = collections.defaultdict(list)

    # Set up simulation
    current_state = model.start_simulation()
    current_action = agent.start_simulation(current_state)

    # Run simulation
    for step in range(end_time):
        current_state = model.step(current_action)
        current_action = agent.step(current_state)
        for key, value in current_state.items():
            results[key].append(value)
        queue.put((step, current_state))

    # Extract and write outputs
    outputs = pd.DataFrame(results)
    outputs.drop(columns=["test_on_symptoms", "app_turned_on"])
    outputs.to_csv(output_file_name, index=False)
Ejemplo n.º 5
0
    def test_set_params_manual_traceable_fraction(self):
        p = Parameters(
            read_param_file=True,
            input_households="tests/data/baseline_household_demographics.csv",
            input_param_file="tests/data/baseline_parameters.csv",
            param_line_number=1,
        )

        p.set_param("manual_traceable_fraction_occupation", 0.8)
        assert p.get_param("manual_traceable_fraction_occupation") == 0.8

        p.set_param("manual_traceable_fraction_household", 0.6)
        assert p.get_param("manual_traceable_fraction_household") == 0.6
        assert p.get_param("manual_traceable_fraction_occupation") == 0.8

        model = Model(p)
        model.update_running_params("manual_traceable_fraction_household", 0.4)
        assert model.get_param("manual_traceable_fraction_household") == 0.4
Ejemplo n.º 6
0
def get_simulation( params ):
    params.set_param( "end_time", 500 )
    model = simulation.COVID19IBM(model = Model(params))
    sim = simulation.Simulation(env = model, end_time = params.get_param( "end_time" ) )
    return sim
Ejemplo n.º 7
0
from COVID19.model import Model, Parameters
import COVID19.simulation as simulation
import pandas as pd

input_params = pd.read_csv('./tests/data/baseline_parameters.csv')
input_households = pd.read_csv('./tests/data/baseline_household_demographics.csv')

print(input_params)
print(input_households)

params = Parameters(
    input_param_file="./tests/data/baseline_parameters.csv",
    param_line_number=1,
    output_file_dir="./data_test",
    input_households="./tests/data/baseline_household_demographics.csv"
)
params.set_param( "n_total", 10000)
params.set_param( "app_turn_on_time", 10)

model = simulation.COVID19IBM(model = Model(params))
sim   = simulation.Simulation(env = model, end_time = 100 )
sim.steps( 1000 )
print( pd.DataFrame.from_dict(sim.results) )     
Ejemplo n.º 8
0
def get_model_swig(params):
    """
    Gets the Swig model object
    """
    return Model(params)
Ejemplo n.º 9
0
def setup_model(d: dict = None):
    params = setup_parameters(d)
    params.set_param("sys_write_individual", 0)
    model = Model(params)
    return model
Ejemplo n.º 10
0
def free_abm(
        params,
        logger=dummy_logger(),
        input_parameter_file="./abm_params/baseline_parameters.csv",
        household_demographics_file="./abm_params/baseline_household_demographics.csv",
        parameter_line_number=1,
        name_file_res="res",
        output_dir="./output/",
        save_every_iter=5,
        stop_zero_I=True,
        data={},
        callback=lambda data: None):
    '''
    Simulate the openABM epidemic simulation with no intervention strategy

    input
    -----
    params: Dict
            Dictonary with openABM to set
    results:
        print on file true configurations and transmission
    '''

    params_model = Parameters(input_parameter_file, parameter_line_number,
                              output_dir, household_demographics_file)

    fold_out = Path(output_dir)
    if not fold_out.exists():
        fold_out.mkdir(parents=True)

    params_model = Parameters()
    for k, val in params.items():
        params_model.set_param(k, val)
    model = simulation.COVID19IBM(model=Model(params_model))

    T = params_model.get_param("end_time")
    N = params_model.get_param("n_total")
    sim = simulation.Simulation(env=model, end_time=T, verbose=False)
    for col_name in ["I", "IR"]:
        data[col_name] = np.full(T, np.nan)
    for t in range(T):
        sim.steps(1)
        status = np.array(covid19.get_state(model.model.c_model))
        state = status_to_state(status)
        nS, nI, nR = (state == 0).sum(), (state == 1).sum(), (state == 2).sum()
        if nI == 0 and stop_zero_I:
            logger.info(
                "stopping simulation as there are no more infected individuals"
            )
            break
        logger.info(f'time:{t}')

        data["I"][t] = nI
        data["IR"][t] = nI + nR

        callback(data)

    # print and import files
    sim.env.model.write_individual_file()
    df_indiv = pd.read_csv(output_dir + "individual_file_Run1.csv",
                           skipinitialspace=True)
    df_indiv.to_csv(output_dir + name_file_res + "_individuals.gz")
    sim.env.model.write_transmissions()
    df_trans = pd.read_csv(output_dir + "transmission_Run1.csv")
    df_trans.to_csv(output_dir + name_file_res + "_transmissions.gz")
    print("End of Simulation")
    return
Ejemplo n.º 11
0
def loop_abm(
        params,
        inference_algo,
        logger=dummy_logger(),
        input_parameter_file="./abm_params/baseline_parameters.csv",
        household_demographics_file="./abm_params/baseline_household_demographics.csv",
        parameter_line_number=1,
        seed=1,
        initial_steps=0,
        num_test_random=50,
        num_test_algo=50,
        fraction_SM_obs=0.2,
        fraction_SS_obs=1,
        quarantine_HH=False,
        test_HH=False,
        name_file_res="res",
        output_dir="./output/",
        save_every_iter=5,
        stop_zero_I=True,
        adoption_fraction=1.0,
        fp_rate=0.0,
        fn_rate=0.0,
        smartphone_users_abm=False,  # if True use app users fraction from OpenABM model
        callback=lambda x: None,
        data={}):
    '''
    Simulate interventions strategy on the openABM epidemic simulation.

    input
    -----
    params: Dict
            Dictonary with openABM to set
    inference_algo: Class (rank_template)
            Class for order the nodes according to the prob to be infected
            logger = logger for printing intermediate steps
    results:
        print on file true configurations and transmission
    '''

    params_model = Parameters(input_parameter_file, parameter_line_number,
                              output_dir, household_demographics_file)

    ### create output_dir if missing
    fold_out = Path(output_dir)
    if not fold_out.exists():
        fold_out.mkdir(parents=True)

    ### initialize a separate random stream
    rng = np.random.RandomState()
    rng.seed(seed)

    ### initialize ABM model
    for k, val in params.items():
        params_model.set_param(k, val)
    model = Model(params_model)
    model = simulation.COVID19IBM(model=model)

    T = params_model.get_param("end_time")
    N = params_model.get_param("n_total")
    sim = simulation.Simulation(env=model, end_time=T, verbose=False)
    house = covid19.get_house(model.model.c_model)
    housedict = listofhouses(house)
    has_app = covid19.get_app_users(
        model.model.c_model) if smartphone_users_abm else np.ones(N, dtype=int)
    has_app &= (rng.random(N) <= adoption_fraction)

    ### init data and data_states
    data_states = {}
    data_states["true_conf"] = np.zeros((T, N))
    data_states["statuses"] = np.zeros((T, N))
    data_states["tested_algo"] = []
    data_states["tested_random"] = []
    data_states["tested_SS"] = []
    data_states["tested_SM"] = []
    for name in [
            "num_quarantined", "q_SS", "q_SM", "q_algo", "q_random", "q_all",
            "infected_free", "S", "I", "R", "IR", "aurI", "prec1%", "prec5%",
            "test_+", "test_-", "test_f+", "test_f-"
    ]:
        data[name] = np.full(T, np.nan)
    data["logger"] = logger

    ### init inference algo
    inference_algo.init(N, T)

    ### running variables
    indices = np.arange(N, dtype=int)
    excluded = np.zeros(N, dtype=bool)
    daily_obs = []
    all_obs = []
    all_quarantined = []
    freebirds = 0
    num_quarantined = 0
    fp_num = 0
    fn_num = 0
    p_num = 0
    n_num = 0

    noise_SM = rng.random(N)
    noise_SS = rng.random(N) if fraction_SS_obs < 1 else None
    nfree = params_model.get_param("n_seed_infection")
    for t in range(T):
        ### advance one time step
        sim.steps(1)
        status = np.array(covid19.get_state(model.model.c_model))
        state = status_to_state(status)
        data_states["true_conf"][t] = state
        nS, nI, nR = (state == 0).sum(), (state == 1).sum(), (state == 2).sum()
        if nI == 0 and stop_zero_I:
            logger.info(
                "stopping simulation as there are no more infected individuals"
            )
            break
        if t == initial_steps:
            logger.info("\nobservation-based inference algorithm starts now\n")
        logger.info(f'time:{t}')

        ### extract contacts
        daily_contacts = covid19.get_contacts_daily(model.model.c_model, t)
        logger.info(f"number of unique contacts: {len(daily_contacts)}")

        ### compute potential test results for all
        if fp_rate or fn_rate:
            noise = rng.random(N)
            f_state = (state == 1) * (noise > fn_rate) + (state == 0) * (
                noise < fp_rate) + 2 * (state == 2)
        else:
            f_state = state

        to_quarantine = []
        all_test = []
        excluded_now = excluded.copy()
        fp_num_today = 0
        fn_num_today = 0
        p_num_today = 0
        n_num_today = 0

        def test_and_quarantine(rank, num):
            nonlocal to_quarantine, excluded_now, all_test, fp_num_today, fn_num_today, p_num_today, n_num_today
            test_rank = []
            for i in rank:
                if len(test_rank) == num:
                    break
                if excluded_now[i]:
                    continue
                test_rank += [i]
                if f_state[i] == 1:
                    p_num_today += 1
                    if state[i] != 1:
                        fp_num_today += 1
                    q = housedict[house[i]] if quarantine_HH else [i]
                    excluded_now[q] = True
                    to_quarantine += q
                    excluded[q] = True
                    if test_HH:
                        all_test += q
                    else:
                        all_test += [i]
                else:
                    n_num_today += 1
                    if state[i] == 1:
                        fn_num_today += 1
                    excluded_now[i] = True
                    all_test += [i]
            return test_rank

        ### compute rank from algorithm
        num_test_algo_today = num_test_algo
        if t < initial_steps:
            daily_obs = []
            num_test_algo_today = 0

        weighted_contacts = [(c[0], c[1], c[2], 2.0 if c[3] == 0 else 1.0)
                             for c in daily_contacts
                             if (has_app[c[0]] and has_app[c[1]])]
        if nfree == 0 and quarantine_HH:
            print("faster end")
            rank_algo = np.zeros((N, 2))
            rank_algo[:, 0] = np.arange(N)
            rank_algo[:, 1] = np.random.rand(N)
        else:
            rank_algo = inference_algo.rank(t, weighted_contacts, daily_obs,
                                            data)
        rank = np.array(sorted(rank_algo, key=lambda tup: tup[1],
                               reverse=True))
        rank = [int(tup[0]) for tup in rank]

        ### test num_test_algo_today individuals
        test_algo = test_and_quarantine(rank, num_test_algo_today)

        ### compute roc now, only excluding past tests
        eventsI = events_list(t, [(i, 1, t)
                                  for (i, tf) in enumerate(excluded) if tf],
                              data_states["true_conf"],
                              check_fn=check_fn_I)
        xI, yI, aurI, sortlI = roc_curve(dict(rank_algo), eventsI, lambda x: x)

        ### test all SS
        if fraction_SS_obs < 1:
            SS = indices[(status == 4) & (noise_SS < fraction_SS_obs)]
        else:
            SS = indices[status == 4]
        SS = test_and_quarantine(SS, len(SS))

        ### test a fraction of SM
        SM = indices[(status == 5) & (noise_SM < fraction_SM_obs)]
        SM = test_and_quarantine(SM, len(SM))

        ### do num_test_random extra random tests
        test_random = test_and_quarantine(rng.permutation(N), num_test_random)

        ### quarantine infected individuals
        num_quarantined += len(to_quarantine)
        covid19.intervention_quarantine_list(model.model.c_model,
                                             to_quarantine, T + 1)

        ### update observations
        daily_obs = [(int(i), int(f_state[i]), int(t)) for i in all_test]
        all_obs += daily_obs

        ### exclude forever nodes that are observed recovered
        rec = [i[0] for i in daily_obs if f_state[i[0]] == 2]
        excluded[rec] = True

        ### update data
        data_states["tested_algo"].append(test_algo)
        data_states["tested_random"].append(test_random)
        data_states["tested_SS"].append(SS)
        data_states["tested_SM"].append(SM)
        data_states["statuses"][t] = status
        data["S"][t] = nS
        data["I"][t] = nI
        data["R"][t] = nR
        data["IR"][t] = nR + nI
        data["aurI"][t] = aurI
        prec = lambda f: yI[int(f / 100 * len(yI))] / int(f / 100 * len(
            yI)) if len(yI) else np.nan
        ninfq = sum(state[to_quarantine] > 0)
        nfree = int(nI - sum(excluded[state == 1]))
        data["aurI"][t] = aurI
        data["prec1%"][t] = prec(1)
        data["prec5%"][t] = prec(5)
        data["num_quarantined"][t] = num_quarantined
        data["test_+"][t] = p_num
        data["test_-"][t] = n_num
        data["test_f+"][t] = fp_num
        data["test_f-"][t] = fn_num
        data["q_SS"][t] = len(SS)
        data["q_SM"][t] = len(SM)
        sus_test_algo = sum(state[test_algo] == 0)
        inf_test_algo = sum(state[test_algo] == 1)
        rec_test_algo = sum(state[test_algo] == 2)
        inf_test_random = sum(state[test_random] == 1)
        data["q_algo"][t] = inf_test_algo
        data["q_random"][t] = sum(state[test_random] == 1)
        data["infected_free"][t] = nfree
        asbirds = 'a bird' if nfree == 1 else 'birds'

        fp_num += fp_num_today
        fn_num += fn_num_today
        n_num += n_num_today
        p_num += p_num_today

        ### show output
        logger.info(f"True  : (S,I,R): ({nS:.1f}, {nI:.1f}, {nR:.1f})")
        logger.info(
            f"AUR_I : {aurI:.3f}, prec(1% of {len(yI)}): {prec(1):.2f}, prec5%: {prec(5):.2f}"
        )
        logger.info(
            f"SS: {len(SS)}, SM: {len(SM)}, results test algo (S,I,R): ({sus_test_algo},{inf_test_algo},{rec_test_algo}), infected test random: {inf_test_random}/{num_test_random}"
        )
        logger.info(
            f"false+: {fp_num} (+{fp_num_today}), false-: {fn_num} (+{fn_num_today})"
        )
        logger.info(
            f"...quarantining {len(to_quarantine)} guys -> got {ninfq} infected, {nfree} free as {asbirds} ({nfree-freebirds:+d})"
        )
        freebirds = nfree

        ### callback
        callback(data)

        if t % save_every_iter == 0:
            df_save = pd.DataFrame.from_records(data, exclude=["logger"])
            df_save.to_csv(output_dir + name_file_res + "_res.gz")

    # save files
    df_save = pd.DataFrame.from_records(data, exclude=["logger"])
    df_save.to_csv(output_dir + name_file_res + "_res.gz")
    with open(output_dir + name_file_res + "_states.pkl",
              mode="wb") as f_states:
        pickle.dump(data_states, f_states)
    sim.env.model.write_individual_file()
    df_indiv = pd.read_csv(output_dir + "individual_file_Run1.csv",
                           skipinitialspace=True)
    df_indiv.to_csv(output_dir + name_file_res + "_individuals.gz")
    sim.env.model.write_transmissions()
    df_trans = pd.read_csv(output_dir + "transmission_Run1.csv")
    df_trans.to_csv(output_dir + name_file_res + "_transmissions.gz")
    return df_save
Ejemplo n.º 12
0
def get_model_swig(params):
    return Model(params)