Esempio n. 1
0
def task_plot_combined_rapid_test_demand_params(depends_on, func, produces):
    params = pd.read_pickle(depends_on["params"])
    params = func(params)

    with warnings.catch_warnings():
        warnings.filterwarnings(
            "ignore",
            message="indexing past lexsort depth may impact performance.")
        educ_workers_params = params.loc[("rapid_test_demand",
                                          "educ_worker_shares")]
        students_params = params.loc[("rapid_test_demand", "student_shares")]
        work_offer_params = params.loc[("rapid_test_demand",
                                        "share_workers_receiving_offer")]
        private_demand_params = params.loc[("rapid_test_demand",
                                            "private_demand")]
        work_accept_params = params.loc[("rapid_test_demand",
                                         "share_accepting_work_offer")]

    # educ demand
    share_educ_workers = get_piecewise_linear_interpolation(
        educ_workers_params)
    share_educ_workers = share_educ_workers.loc[PLOT_START_DATE:PLOT_END_DATE]
    share_students = get_piecewise_linear_interpolation(students_params)
    share_students = share_students.loc[PLOT_START_DATE:PLOT_END_DATE]

    # worker demand
    share_workers_receiving_offer = get_piecewise_linear_interpolation(
        work_offer_params)
    share_workers_receiving_offer = share_workers_receiving_offer.loc[
        PLOT_START_DATE:PLOT_END_DATE]
    share_workers_accepting_offer = get_piecewise_linear_interpolation(
        work_accept_params)
    share_workers = share_workers_receiving_offer * share_workers_accepting_offer

    # private demand
    private_demand_shares = get_piecewise_linear_interpolation(
        private_demand_params)
    private_demand_shares = private_demand_shares.loc[
        PLOT_START_DATE:PLOT_END_DATE]

    fig = _plot_rapid_test_demand_shares(
        share_educ_workers=share_educ_workers,
        share_students=share_students,
        share_workers=share_workers,
        private_demand_shares=private_demand_shares,
    )
    fig.savefig(produces["figure"])
    plt.close()

    if "data" in produces.keys():
        df = pd.DataFrame({
            "share_educ_workers": share_educ_workers,
            "share_students": share_students,
            "share_workers": share_workers,
            "private_demand_shares": private_demand_shares,
        })
        df.round(3).to_csv(produces["data"])
def _check_no_work_rapid_tests(new_params):
    accept_params = new_params.loc[
        ("rapid_test_demand", "share_accepting_work_offer"), "value"
    ]
    accept_time_series = get_piecewise_linear_interpolation(params_slice=accept_params)
    assert (accept_time_series == 0).all()

    offer_params = new_params.loc[
        ("rapid_test_demand", "share_workers_receiving_offer"), "value"
    ]
    offer_time_series = get_piecewise_linear_interpolation(params_slice=offer_params)
    assert (offer_time_series == 0).all()
def _check_school_demand_is_zero(new_params):
    teacher_params = new_params.loc[
        ("rapid_test_demand", "educ_worker_shares"), "value"
    ]
    teacher_time_series = get_piecewise_linear_interpolation(
        params_slice=teacher_params
    )
    assert (teacher_time_series == 0).all()

    student_params = new_params.loc[("rapid_test_demand", "student_shares"), "value"]
    student_time_series = get_piecewise_linear_interpolation(
        params_slice=student_params
    )
    assert (student_time_series == 0).all()
def test_mandatory_work_rapid_tests_after_easter(params):
    new_params = params_scenarios.mandatory_work_rapid_tests_after_easter(params)
    accept_params = new_params.loc[
        ("rapid_test_demand", "share_accepting_work_offer"), "value"
    ]
    accept_time_series = get_piecewise_linear_interpolation(params_slice=accept_params)
    assert (accept_time_series[:"2021-04-05"] < 0.95).all()
    assert (accept_time_series["2021-04-06":] == 0.95).all()

    offer_params = new_params.loc[
        ("rapid_test_demand", "share_workers_receiving_offer"), "value"
    ]
    offer_time_series = get_piecewise_linear_interpolation(params_slice=offer_params)
    assert (offer_time_series[:"2021-04-05"] < 0.95).all()
    assert (offer_time_series["2021-04-06":] == 0.95).all()
def task_plot_share_of_workers_receiving_test_offer(depends_on, produces):
    params = pd.read_pickle(depends_on["params"])
    with warnings.catch_warnings():
        warnings.filterwarnings(
            "ignore", message="indexing past lexsort depth may impact performance."
        )
        params_slice = params.loc[
            ("rapid_test_demand", "share_workers_receiving_offer")
        ]
    share_workers_receiving_offer = get_piecewise_linear_interpolation(params_slice)
    share_workers_receiving_offer = share_workers_receiving_offer.loc[
        PLOT_START_DATE:PLOT_END_DATE
    ]

    fig, ax = plt.subplots(figsize=PLOT_SIZE)
    sns.lineplot(
        x=share_workers_receiving_offer.index,
        y=share_workers_receiving_offer,
        ax=ax,
    )
    ax.set_title("Share Workers With Work Contacts With Rapid Test Offer At Work")
    fig, ax = style_plot(fig, ax)
    fig.tight_layout()

    fig.savefig(produces)
    plt.close()
Esempio n. 6
0
def task_plot_private_test_demand_shares(depends_on, produces):
    params = pd.read_pickle(depends_on["params"])
    with warnings.catch_warnings():
        warnings.filterwarnings(
            "ignore",
            message="indexing past lexsort depth may impact performance.")
        params_slice = params.loc[("rapid_test_demand", "private_demand")]

    private_demand_shares = get_piecewise_linear_interpolation(params_slice)
    private_demand_shares = private_demand_shares.loc[
        PLOT_START_DATE:PLOT_END_DATE]

    fig, ax = plt.subplots(figsize=PLOT_SIZE)
    sns.lineplot(
        x=private_demand_shares.index,
        y=private_demand_shares,
        ax=ax,
    )
    ax.set_title(
        "Private Rapid Test Demand\n"
        "(Share of Individuals who Do a Rapid Test \n"
        "When a Household Member Tests Positive Or Becomes Symptomatic Or \n"
        "When Developing Symptoms but not Receiving a Rapid Test Or \n"
        "When Participating in Some Private Events)")
    fig, ax = style_plot(fig, ax)
    fig.tight_layout()

    fig.savefig(produces)
    plt.close()
def test_no_rapid_tests_at_schools_and_private(params):
    new_params = params_scenarios.no_rapid_tests_at_schools_and_private(params)
    _check_school_demand_is_zero(new_params)

    private_slice = new_params.loc[("rapid_test_demand", "private_demand"), "value"]
    private_series = get_piecewise_linear_interpolation(params_slice=private_slice)
    assert (private_series == 0).all()
def test_keep_work_offer_share_at_23_pct_after_easter(params):
    new_params = params_scenarios.keep_work_offer_share_at_23_pct_after_easter(params)
    offer_params = new_params.loc[
        ("rapid_test_demand", "share_workers_receiving_offer"), "value"
    ]
    time_series = get_piecewise_linear_interpolation(params_slice=offer_params)

    assert time_series["2021-04-06"] == 0.23
    assert (time_series["2021-04-06":] == 0.23).all()
def task_plot_overall_share_known_cases(depends_on, produces):
    df_old = pd.read_csv(depends_on["old"])
    old_share_known = _calculate_share_known_cases(
        df_old)[PLOT_START_DATE:"2020-12-24"]

    df_new = pd.read_csv(depends_on["new"])
    new_share_known = _calculate_share_known_cases(df_new)["2020-12-25":]
    share_known = pd.concat([old_share_known, new_share_known])
    share_known.index = share_known.index.normalize()
    assert not share_known.index.duplicated().any()
    dates = share_known.index
    expected_dates = pd.date_range(dates.min(), dates.max())
    missing_dates = [str(x.date()) for x in expected_dates if x not in dates]
    assert (len(missing_dates) == 0
            ), f"There are missing dates in the share_known: {missing_dates}"

    share_known = share_known.loc[PLOT_START_DATE:"2020-12-28"]

    params = pd.read_pickle(depends_on["params"])
    with warnings.catch_warnings():
        warnings.filterwarnings(
            "ignore",
            message="indexing past lexsort depth may impact performance.")
        params_slice = params.loc[("share_known_cases", "share_known_cases")]
    share_known_from_params = get_piecewise_linear_interpolation(params_slice)
    share_known_from_params = share_known_from_params.loc[
        PLOT_START_DATE:PLOT_END_DATE]

    fig, ax = plt.subplots(figsize=PLOT_SIZE)
    sns.lineplot(
        x=share_known.index,
        y=share_known,
        ax=ax,
        label="Dunkelzifferradar",
        alpha=0.6,
        linewidth=3.0,
        color=BLUE,
    )
    sns.lineplot(
        x=share_known_from_params.index,
        y=share_known_from_params,
        ax=ax,
        label="Interpolated and Extrapolated",
        alpha=0.6,
        linewidth=3.0,
        color=RED,
    )
    fig, ax = style_plot(fig, ax)
    ax.set_ylabel("share of cases that are detected")
    fig.tight_layout()

    ax.axvline(pd.Timestamp("2020-12-24"), alpha=0.6, color="k")
    fig.savefig(produces["share_known_cases_fig"])
    plt.close()
def task_plot_share_of_educ_participants_with_rapid_test(depends_on, produces):
    params = pd.read_pickle(depends_on["params"])
    with warnings.catch_warnings():
        warnings.filterwarnings(
            "ignore",
            message="indexing past lexsort depth may impact performance.")
        educ_workers_params = params.loc[("rapid_test_demand",
                                          "educ_worker_shares")]
        students_params = params.loc[("rapid_test_demand", "student_shares")]

    share_educ_workers = get_piecewise_linear_interpolation(
        educ_workers_params)
    share_educ_workers = share_educ_workers.loc[PLOT_START_DATE:PLOT_END_DATE]

    share_students = get_piecewise_linear_interpolation(students_params)
    share_students = share_students.loc[PLOT_START_DATE:PLOT_END_DATE]

    fig, ax = plt.subplots(figsize=PLOT_SIZE)
    sns.lineplot(
        x=share_educ_workers.index,
        y=share_educ_workers,
        ax=ax,
        label="Teachers (School, Preschool, Nursery)",
    )
    sns.lineplot(
        x=share_students.index,
        y=share_students,
        ax=ax,
        label="School Students",
    )
    ax.set_title("Share of Students and Teachers Receiving Rapid Tests")
    fig, ax = style_plot(fig, ax)
    fig.tight_layout()

    fig.savefig(produces)
    plt.close()
def test_start_all_rapid_tests_after_easter(params):
    new_params = params_scenarios.start_all_rapid_tests_after_easter(params)
    slice_tuples = [
        ("rapid_test_demand", "private_demand"),
        ("rapid_test_demand", "educ_worker_shares"),
        ("rapid_test_demand", "student_shares"),
        ("rapid_test_demand", "share_accepting_work_offer"),
        ("rapid_test_demand", "share_workers_receiving_offer"),
    ]

    for loc in slice_tuples:
        params_slice = new_params.loc[loc, "value"]
        time_series = get_piecewise_linear_interpolation(params_slice=params_slice)
        assert (time_series[:"2021-04-05"] == 0).all()
        assert (time_series["2021-04-06":] > 0).all()
Esempio n. 12
0
def _build_new_date_params(before_params_slice, change_date, new_val):
    before = get_piecewise_linear_interpolation(before_params_slice)
    day_before = change_date - pd.Timedelta(days=1)
    if day_before in before:
        val_before_change = before.loc[day_before]
    else:
        val_before_change = before.iloc[-1]

    new_params_slice = before_params_slice.copy(deep=True)
    new_params_slice.index = pd.DatetimeIndex(new_params_slice.index)

    # remove old change points after change date
    new_params_slice = new_params_slice[:day_before]
    # implement the switch on the change date
    new_params_slice.loc[day_before] = val_before_change
    new_params_slice.loc[change_date] = new_val
    # maintain the new value over time
    new_params_slice.loc[pd.Timestamp("2025-12-31")] = new_val
    new_params_slice = new_params_slice.sort_index()
    return new_params_slice
def test_no_private_test_demand(params):
    new_params = params_scenarios.no_private_rapid_test_demand(params)
    comparison = create_comparison_df(new_params=new_params, old_params=params)
    loc = ("rapid_test_demand", "private_demand")
    private_demand_params = params.loc[loc, "value"]
    should_have_changed = private_demand_params[private_demand_params != 0]

    expected = pd.DataFrame()
    expected["before"] = should_have_changed
    expected["name"] = should_have_changed.index
    expected["after"] = 0.0
    expected["category"] = "rapid_test_demand"
    expected["subcategory"] = "private_demand"
    expected = expected.set_index(["category", "subcategory", "name"])
    assert comparison.equals(expected)

    private_series = get_piecewise_linear_interpolation(
        params_slice=new_params.loc[loc, "value"]
    )
    assert (private_series == 0).all()
Esempio n. 14
0
def load_simulation_inputs(
    scenario,
    start_date,
    end_date,
    debug,
    group_share_known_case_path=None,
    period_outputs=False,
    return_last_states=False,
    initial_states_path=None,
    is_resumed=False,
    rapid_test_statistics_path=None,
):
    """Load the simulation inputs.

    Does **not** include: params, path, seed.

    Args:
        scenario (str): string specifying the scenario. A function with the
            same name must exist in src.simulation.scenario_simulation_inputs.
        start_date (str): date on which the simulation starts. Data must be available
            for at least a month before the start date for the burn in period.
        end_date (str): date on which the simulation ends.
        debug (bool): Whether to use the debug or the full initial states.
        group_share_known_case_path (pathlib.Path, str or None): if not None, the group
            share known cases are loaded from this path and used for the creation of the
            initial conditions.
        period_outputs (bool, optional): whether to use period_outputs instead of saving
            the time series. Default is False.
        return_last_states (bool, optional): if True, the last states are returned as
            part of the simulation result.
        initial_states_path (pathlib.Path, optional): Path to the initial states.
            If not given the standard initial states are used.
        is_resumed (bool, optional): if True, the initial_states_path must be given. In
            that case no initial conditions are created
        rapid_test_statistics_path (Path, optional): where to save rapid test
            statistics.


    Returns:
        dict: Dictionary with most arguments of get_simulate_func. Keys are:
            - initial_states
            - contact_models
            - duration
            - events
            - saved_columns
            - virus_strains
            - derived_state_variables
            - seasonality_factor_model
            - initial_conditions
            - susceptibility_factor_model
            - testing_demand_models
            - testing_allocation_models
            - testing_processing_models
            - period_outputs
            - return_last_states
            - return_time_series

            - contact_policies
            - vaccination_models
            - rapid_test_models
            - rapid_test_reaction_models

    """
    if is_resumed:
        assert (
            initial_states_path is not None
        ), "You must specify the path to the initial states if you resume a simulation."

    start_date = pd.Timestamp(start_date)
    end_date = pd.Timestamp(end_date)

    paths = get_simulation_dependencies(
        debug=debug,
        is_resumed=is_resumed,
    )
    if rapid_test_statistics_path is not None:
        paths["rapid_test_statistics_path"] = rapid_test_statistics_path

    if initial_states_path is None:
        initial_states_path = paths["initial_states"]

    if initial_states_path.suffix == ".pkl":
        initial_states = pd.read_pickle(initial_states_path)
    elif initial_states_path.suffix == ".parquet":
        initial_states = pd.read_parquet(paths["initial_states"])

    contact_models = get_all_contact_models()

    # process dates
    one_day = pd.Timedelta(1, unit="D")
    init_start = start_date - pd.Timedelta(31, unit="D")
    init_end = start_date - one_day
    duration = {"start": start_date, "end": end_date}

    # testing models
    share_of_tests_for_symptomatics_series = pd.read_pickle(
        paths["share_of_tests_for_symptomatics_series"]
    )
    test_start = init_start - one_day
    test_end = end_date + one_day
    test_demand_func = partial(
        demand_test,
        share_of_tests_for_symptomatics_series=share_of_tests_for_symptomatics_series,
    )
    testing_demand_models = {
        "symptoms": {
            "model": test_demand_func,
            "start": test_start,
            "end": test_end,
        }
    }
    testing_allocation_models = {
        "direct_allocation": {
            "model": allocate_tests,
            "start": test_start,
            "end": test_end,
        }
    }
    testing_processing_models = {
        "direct_processing": {
            "model": process_tests,
            "start": test_start,
            "end": test_end,
        }
    }

    saved_columns = {
        "initial_states": ["age_group_rki"],
        "disease_states": ["newly_infected", "newly_deceased", "ever_infected"],
        "time": ["date"],
        "other": [
            "new_known_case",
            "virus_strain",
            "n_has_infected",
            "channel_infected_by_contact",
            "state",
            "knows_currently_infected",
            "currently_infected",
        ],
    }

    if not is_resumed:
        virus_shares = pd.read_pickle(paths["virus_shares"])
        rki_infections = pd.read_pickle(paths["rki"])

        group_weights = pd.read_pickle(paths["rki_age_groups"])["weight"]
        if group_share_known_case_path is not None:
            group_share_known_cases = pd.read_pickle(group_share_known_case_path)
        else:
            group_share_known_cases = None

        params = pd.read_pickle(paths["params"])
        with warnings.catch_warnings():
            warnings.filterwarnings(
                "ignore", message="indexing past lexsort depth may impact performance."
            )
            params_slice = params.loc[("share_known_cases", "share_known_cases")]
        overall_share_known_cases = get_piecewise_linear_interpolation(params_slice)

        initial_conditions = create_initial_conditions(
            start=init_start,
            end=init_end,
            seed=3930,
            reporting_delay=5,
            synthetic_data=initial_states[["county", "age_group_rki"]],
            empirical_infections=rki_infections,
            virus_shares=virus_shares,
            overall_share_known_cases=overall_share_known_cases,
            group_share_known_cases=group_share_known_cases,
            group_weights=group_weights,
        )
    else:
        initial_conditions = None

    seasonality_factor_model = partial(seasonality_model, contact_models=contact_models)

    def _currently_infected(df):
        return df["infectious"] | df["symptomatic"] | (df["cd_infectious_true"] >= 0)

    def _knows_currently_infected(df):
        return df["knows_immune"] & df["currently_infected"]

    derived_state_variables = {
        "currently_infected": _currently_infected,
        "knows_currently_infected": _knows_currently_infected,
    }

    events = {
        "introduce_b117": {"model": introduce_b117},
        "introduce_delta": {"model": introduce_delta},
    }
    fixed_inputs = {
        "initial_states": initial_states,
        "contact_models": contact_models,
        "duration": duration,
        "events": events,
        "testing_demand_models": testing_demand_models,
        "testing_allocation_models": testing_allocation_models,
        "testing_processing_models": testing_processing_models,
        "saved_columns": saved_columns,
        "initial_conditions": initial_conditions,
        "susceptibility_factor_model": calculate_susceptibility,
        "virus_strains": ["base_strain", "b117", "delta"],
        "seasonality_factor_model": seasonality_factor_model,
        "derived_state_variables": derived_state_variables,
        "return_last_states": return_last_states,
    }

    if period_outputs:
        fixed_inputs["period_outputs"] = create_period_outputs()
        fixed_inputs["return_time_series"] = False

    scenario_func = getattr(scenario_simulation_inputs, scenario)
    scenario_inputs = scenario_func(paths, fixed_inputs)
    simulation_inputs = combine_dictionaries([fixed_inputs, scenario_inputs])
    return simulation_inputs
Esempio n. 15
0
def _get_school_multipliers(start_date):
    share_age_for_emergency_care = 0.5
    share_in_graduating_classes = 0.25  # 16, 17 and 18 year olds
    share_in_primary = 0.3
    a_b_multiplier = 0.5

    share_getting_strict_emergency_care = 0.2
    share_getting_generous_emergency_care = 0.3

    strict_emergency_care_multiplier = (
        share_age_for_emergency_care
        * share_getting_strict_emergency_care
        * HYGIENE_MULTIPLIER
    )

    generous_emergency_care_multiplier = (
        share_in_graduating_classes * a_b_multiplier
        + share_age_for_emergency_care * share_getting_generous_emergency_care
    ) * HYGIENE_MULTIPLIER

    feb_to_march_a_b_share = (
        share_in_primary + share_in_graduating_classes
    ) * a_b_multiplier
    feb_to_march_emergency_share = (
        share_age_for_emergency_care
        * share_getting_generous_emergency_care
        * a_b_multiplier
    )
    feb_to_march_multiplier = (
        feb_to_march_a_b_share + feb_to_march_emergency_share
    ) * HYGIENE_MULTIPLIER

    a_b_for_most_multiplier = (
        a_b_multiplier + feb_to_march_emergency_share * a_b_multiplier
    )

    school_multiplier_without_vacations = pd.Series(
        {
            start_date: 1.0,
            "2020-11-01": 1.0,
            "2020-11-02": HYGIENE_MULTIPLIER,
            "2020-12-15": HYGIENE_MULTIPLIER,
            # strict emergency care
            "2020-12-16": strict_emergency_care_multiplier,
            "2021-01-10": strict_emergency_care_multiplier,
            # generous emergency care
            "2021-01-11": generous_emergency_care_multiplier,
            "2021-02-21": generous_emergency_care_multiplier,
            # primary and graduating in A / B
            "2021-02-22": feb_to_march_multiplier,
            "2021-03-14": feb_to_march_multiplier,
            # mid March until Easter: A / B for most
            "2021-03-15": a_b_for_most_multiplier,
            "2021-04-05": a_b_for_most_multiplier,
            # easter until may:
            "2021-04-06": generous_emergency_care_multiplier,
            "2021-04-30": generous_emergency_care_multiplier,
            # may
            "2021-05-01": a_b_for_most_multiplier,
            "2021-05-31": a_b_for_most_multiplier,
        }
    )

    school_multiplier_without_vacations = get_piecewise_linear_interpolation(
        school_multiplier_without_vacations
    )

    school_multiplier_with_vacations = pd.Series(
        {
            start_date: 1.0,
            # fall vacation:
            # first start on 2020-10-05. last end 2020-11-06
            # on average from 2020-10-13 to 2020-10-23
            # there was no overlap in the fall vacation dates between states.
            "2020-10-05": 1.0,
            "2020-10-13": 0.3,  # number to cover that many states had fall vacation
            "2020-10-23": 0.3,
            "2020-11-06": HYGIENE_MULTIPLIER,
            # strict emergency care started in the week before Christmas
            "2020-12-15": HYGIENE_MULTIPLIER,
            "2020-12-16": strict_emergency_care_multiplier,
            # Christmas vacations started on 2002-12-21 in most states.
            # Christmas vacations ended between 2021-01-02 and 2021-01-10.
            "2020-12-20": strict_emergency_care_multiplier,
            "2020-12-21": 0.0,
            "2021-01-02": 0.0,
            "2021-01-10": strict_emergency_care_multiplier,
            # generous emergency care
            # winter vacations were from 2021-01-25 until 2021-03-12 depending on the
            # state and only short so we ignore them here.
            "2021-01-11": generous_emergency_care_multiplier,
            "2021-02-21": generous_emergency_care_multiplier,
            # primary and graduating in A / B
            "2021-02-22": feb_to_march_multiplier,
            "2021-03-14": feb_to_march_multiplier,
            # mid March until Easter: A / B for most
            "2021-03-15": a_b_for_most_multiplier,
            "2021-03-26": a_b_for_most_multiplier,
            # Easter vacations started on 2021-03-29 in most states
            # and ended between 2021-04-05 and 2021-04-16, for most on 2021-04-10
            "2021-03-29": 0.0,
            "2021-04-06": 0.0,
            "2021-04-10": 0.1,  # some states started school before 2021-04-10
            # easter until may:
            "2021-04-11": generous_emergency_care_multiplier,
            "2021-04-30": generous_emergency_care_multiplier,
            # may
            # we ignore Pentecoast vacation because it was <4 days on average
            "2021-05-01": a_b_for_most_multiplier,
            "2021-05-31": a_b_for_most_multiplier,
        }
    )
    school_multiplier_with_vacations = get_piecewise_linear_interpolation(
        school_multiplier_with_vacations
    )

    return school_multiplier_without_vacations, school_multiplier_with_vacations