Ejemplo n.º 1
0
class MiscellaneousFeatureTests(CovaTest):
    def setUp(self):
        super().setUp()
        self.sim = Sim(pop_size=500)
        self.pars = parameters.make_pars()
        self.is_debugging = False

    def test_xslx_generation(self):
        super().tearDown()
        self.is_debugging = False
        root_filename = "DEBUG_test_xlsx_generation"
        excel_filename = f"{root_filename}.xlsx"
        if os.path.isfile(excel_filename):
            os.unlink(excel_filename)
        test_infected_value = 31
        params_dict = {'pop_size': 500, 'pop_infected': test_infected_value}
        self.run_sim(params_dict)
        self.sim.to_excel(filename=root_filename)
        simulation_df = pd.ExcelFile(excel_filename)
        expected_sheets = ['Results', 'Parameters']
        for sheet in expected_sheets:
            self.assertIn(sheet, simulation_df.sheet_names)
        params_df = simulation_df.parse('Parameters')
        observed_infected_param = params_df.loc[
            params_df['Parameter'] == 'pop_infected', 'Value'].values[0]
        self.assertEqual(
            observed_infected_param,
            test_infected_value,
            msg=
            "Should be able to parse the pop_infected parameter from the results sheet"
        )
        results_df = simulation_df.parse('Results')
        observed_day_0_exposed = results_df.loc[results_df['t'] == 0,
                                                'n_exposed'].values[0]
        self.assertGreaterEqual(
            observed_day_0_exposed,
            test_infected_value,
            msg=
            "Should be able to parse the day 0 n_exposed value from the results sheet."
        )
        if not self.is_debugging:
            os.unlink(excel_filename)

    def test_set_pars_invalid_key(self):
        with self.assertRaises(KeyError) as context:
            self.sim['n_infectey'] = 10
        error_message = str(context.exception)
        self.assertIn('n_infectey', error_message)
        self.assertIn('pop_infected', error_message)

    def test_update_pars_invalid_key(self):
        invalid_key = {'dooty_doo': 5}
        with self.assertRaises(KeyError) as context:
            self.sim.update_pars(invalid_key)
        error_message = str(context.exception)
        self.assertIn('dooty_doo', error_message)
class MiscellaneousFeatureTests(CovaSimTest):
    def setUp(self):
        super().setUp()
        self.sim = Sim()
        self.pars = parameters.make_pars()
        self.is_debugging = False

    def test_xslx_generation(self):
        super().tearDown()
        self.sim.run()
        self.sim.to_xlsx()
        pass

    def test_set_pars_invalid_key(self):
        with self.assertRaises(KeyError) as context:
            self.sim['n_infectey'] = 10
            pass
        error_message = str(context.exception)
        self.assertIn('n_infectey', error_message)
        self.assertIn('n_infected', error_message)
        print("OH YEAH")
        pass

    def test_update_pars_invalid_key(self):
        invalid_key = {'dooty_doo': 5}
        with self.assertRaises(KeyError) as context:
            self.sim.update_pars(invalid_key)
            pass
        error_message = str(context.exception)
        self.assertIn('dooty_doo', error_message)
        pass

    def test_update_pars_invalid_type(self):
        invalid_key = ('dooty_doo', 5)
        with self.assertRaises(TypeError) as context:
            self.sim.update_pars(invalid_key)
            pass
        error_message = str(context.exception)
        self.assertIn('dict', error_message)
        pass
Ejemplo n.º 3
0
class CovaSimTest(unittest.TestCase):
    def setUp(self):
        self.is_debugging = False

        self.simulation_parameters = None
        self.simulation_prognoses = None
        self.sim = None
        self.simulation_result = None
        self.interventions = None
        self.expected_result_filename = f"DEBUG_{self.id()}.json"
        if os.path.isfile(self.expected_result_filename):
            os.unlink(self.expected_result_filename)
        pass

    def tearDown(self):
        if not self.is_debugging:
            if os.path.isfile(self.expected_result_filename):
                os.unlink(self.expected_result_filename)
        pass

    # region configuration methods
    def set_simulation_parameters(self, params_dict=None):
        """
        Overrides all of the default sim parameters
        with the ones in the dictionary
        Args:
            params_dict: keys are param names, values are expected values to use

        Returns:
            None, sets self.simulation_params

        """
        if not self.simulation_parameters:
            self.simulation_parameters = parameters.make_pars(
                set_prognoses=True, prog_by_age=True)
        if params_dict:
            self.simulation_parameters.update(params_dict)
        pass

    def set_simulation_prognosis_probability(self, params_dict):
        """
        Allows for testing prognoses probability as absolute rather than relative.
        NOTE: You can only call this once per test or you will overwrite your stuff.
        """
        ProbKeys = TestProperties.ParameterKeys.ProgressionKeys.ProbabilityKeys
        RelativeProbabilityKeys = ProbKeys.RelativeProbKeys
        supported_probabilities = [
            RelativeProbabilityKeys.inf_to_symptomatic_probability,
            RelativeProbabilityKeys.sym_to_severe_probability,
            RelativeProbabilityKeys.sev_to_critical_probability,
            RelativeProbabilityKeys.crt_to_death_probability
        ]
        if not self.simulation_parameters:
            self.set_simulation_parameters()
            pass

        if not self.simulation_prognoses:
            self.simulation_prognoses = parameters.get_prognoses(
                self.simulation_parameters[ProbKeys.progression_by_age])

        PrognosisKeys = ProbKeys.PrognosesListKeys
        for k in params_dict:
            prognosis_in_question = None
            expected_prob = params_dict[k]
            if k == RelativeProbabilityKeys.inf_to_symptomatic_probability:
                prognosis_in_question = PrognosisKeys.symptomatic_probabilities
            elif k == RelativeProbabilityKeys.sym_to_severe_probability:
                prognosis_in_question = PrognosisKeys.severe_probabilities
            elif k == RelativeProbabilityKeys.sev_to_critical_probability:
                prognosis_in_question = PrognosisKeys.critical_probabilities
            elif k == RelativeProbabilityKeys.crt_to_death_probability:
                prognosis_in_question = PrognosisKeys.death_probs
            else:
                raise KeyError(
                    f"Key {k} not found in {supported_probabilities}.")
            old_probs = self.simulation_prognoses[prognosis_in_question]
            self.simulation_prognoses[prognosis_in_question] = np.array(
                [expected_prob] * len(old_probs))
            pass
        pass

    def set_duration_distribution_parameters(self, duration_in_question, par1,
                                             par2):
        if not self.simulation_parameters:
            self.set_simulation_parameters()
            pass
        duration_node = self.simulation_parameters["dur"]
        duration_node[duration_in_question] = {
            "dist": "normal",
            "par1": par1,
            "par2": par2
        }
        params_dict = {"dur": duration_node}
        self.set_simulation_parameters(params_dict=params_dict)

    def run_sim(self,
                params_dict=None,
                write_results_json=False,
                population_type=None):
        if not self.simulation_parameters or params_dict:  # If we need one, or have one here
            self.set_simulation_parameters(params_dict=params_dict)
            pass

        self.simulation_parameters['interventions'] = self.interventions

        self.sim = Sim(pars=self.simulation_parameters, datafile=None)
        if not self.simulation_prognoses:
            self.simulation_prognoses = parameters.get_prognoses(
                self.simulation_parameters[
                    TestProperties.ParameterKeys.ProgressionKeys.
                    ProbabilityKeys.progression_by_age])
            pass

        self.sim['prognoses'] = self.simulation_prognoses
        if population_type:
            self.sim.update_pars(pop_type=population_type)
        self.sim.run(verbose=0)
        self.simulation_result = self.sim.to_json(tostring=False)
        if write_results_json or self.is_debugging:
            with open(self.expected_result_filename, 'w') as outfile:
                json.dump(self.simulation_result,
                          outfile,
                          indent=4,
                          sort_keys=True)
        pass

    # endregion

    # region simulation results support
    def get_full_result_channel(self, channel):
        result_data = self.simulation_result["results"][channel]
        return result_data

    def get_day_zero_channel_value(
            self,
            channel=TestProperties.ResultsDataKeys.susceptible_at_timestep):
        """

        Args:
            channel: timeseries channel to report ('n_susceptible')

        Returns: day zero value for channel

        """
        result_data = self.get_full_result_channel(channel=channel)
        return result_data[0]

    def get_day_final_channel_value(self, channel):
        channel = self.get_full_result_channel(channel=channel)
        return channel[-1]

    # endregion

    # region interventions support
    def intervention_set_changebeta(self,
                                    days_array,
                                    multiplier_array,
                                    layers=None):
        self.interventions = change_beta(days=days_array,
                                         changes=multiplier_array,
                                         layers=layers)
        pass

    def intervention_set_test_prob(self,
                                   symptomatic_prob=0,
                                   asymptomatic_prob=0,
                                   asymptomatic_quarantine_prob=0,
                                   symp_quar_prob=0,
                                   test_sensitivity=1.0,
                                   loss_prob=0.0,
                                   test_delay=1,
                                   start_day=0):
        self.interventions = test_prob(
            symp_prob=symptomatic_prob,
            asymp_prob=asymptomatic_prob,
            asymp_quar_prob=asymptomatic_quarantine_prob,
            symp_quar_prob=symp_quar_prob,
            test_sensitivity=test_sensitivity,
            loss_prob=loss_prob,
            test_delay=test_delay,
            start_day=start_day)
        pass

    def intervention_set_contact_tracing(self,
                                         start_day,
                                         trace_probabilities=None,
                                         trace_times=None):
        #  see ../tests/test_interventions_testing.test_tracedelay
        #  trace_probs = {'h': 1, 's': 1, 'w': 1, 'c': 1}
        #  trace_time = {'h': 0, 's': 1, 'w': 1, 'c': 2}
        #  pars.quar_period = 60 # 60 days
        if not trace_probabilities:
            trace_probabilities = {'h': 1, 's': 1, 'w': 1, 'c': 1}
            pass
        if not trace_times:
            trace_times = {'h': 1, 's': 1, 'w': 1, 'c': 1}
        self.interventions = contact_tracing(trace_probs=trace_probabilities,
                                             trace_time=trace_times,
                                             start_day=start_day)
        pass

    def intervention_build_sequence(self, day_list, intervention_list):
        my_sequence = sequence(days=day_list, interventions=intervention_list)
        self.interventions = my_sequence

    # endregion

    # region specialized simulation methods
    def set_microsim(self):
        Simkeys = TestProperties.ParameterKeys.SimulationKeys
        Micro = TestProperties.SpecializedSimulations.Microsim
        microsim_parameters = {
            Simkeys.number_agents: Micro.n,
            Simkeys.initial_infected_count: Micro.pop_infected,
            Simkeys.number_simulated_days: Micro.n_days
        }
        self.set_simulation_parameters(microsim_parameters)
        pass

    def set_everyone_infected(self, agent_count=1000):
        Simkeys = TestProperties.ParameterKeys.SimulationKeys
        everyone_infected = {
            Simkeys.number_agents: agent_count,
            Simkeys.initial_infected_count: agent_count
        }
        self.set_simulation_parameters(params_dict=everyone_infected)
        pass

    DurationKeys = TestProperties.ParameterKeys.ProgressionKeys.DurationKeys

    def set_everyone_infectious_same_day(self,
                                         num_agents,
                                         days_to_infectious=1,
                                         num_days=60):
        """
        Args:
            num_agents: number of agents to create and infect
            days_to_infectious: days until all agents are infectious (1)
            num_days: days to simulate (60)
        """
        self.set_everyone_infected(agent_count=num_agents)
        prob_dict = {
            TestProperties.ParameterKeys.ProgressionKeys.ProbabilityKeys.RelativeProbKeys.inf_to_symptomatic_probability:
            0
        }
        self.set_simulation_prognosis_probability(prob_dict)
        test_config = {
            TestProperties.ParameterKeys.SimulationKeys.number_simulated_days:
            num_days
        }
        self.set_duration_distribution_parameters(
            duration_in_question=DurationKeys.exposed_to_infectious,
            par1=days_to_infectious,
            par2=0)
        self.set_simulation_parameters(params_dict=test_config)
        pass

    def set_everyone_symptomatic(self, num_agents, constant_delay: int = None):
        """
        Cause all agents in the simulation to begin infected
        And proceed to symptomatic (but not severe or death)
        Args:
            num_agents: Number of agents to begin with
        """
        self.set_everyone_infectious_same_day(num_agents=num_agents,
                                              days_to_infectious=0)
        prob_dict = {
            TestProperties.ParameterKeys.ProgressionKeys.ProbabilityKeys.RelativeProbKeys.inf_to_symptomatic_probability:
            1.0,
            TestProperties.ParameterKeys.ProgressionKeys.ProbabilityKeys.RelativeProbKeys.sym_to_severe_probability:
            0
        }
        self.set_simulation_prognosis_probability(prob_dict)
        if constant_delay is not None:
            self.set_duration_distribution_parameters(
                duration_in_question=DurationKeys.infectious_to_symptomatic,
                par1=constant_delay,
                par2=0)
        pass

    def set_everyone_is_going_to_die(self, num_agents):
        """
        Cause all agents in the simulation to begin infected and die.
        Args:
            num_agents: Number of agents to simulate
        """
        ProbKeys = TestProperties.ParameterKeys.ProgressionKeys.ProbabilityKeys.RelativeProbKeys
        self.set_everyone_infectious_same_day(num_agents=num_agents)
        prob_dict = {
            ProbKeys.inf_to_symptomatic_probability: 1,
            ProbKeys.sym_to_severe_probability: 1,
            ProbKeys.sev_to_critical_probability: 1,
            ProbKeys.crt_to_death_probability: 1
        }
        self.set_simulation_prognosis_probability(prob_dict)
        pass

    def set_everyone_severe(self, num_agents, constant_delay: int = None):
        self.set_everyone_symptomatic(num_agents=num_agents,
                                      constant_delay=constant_delay)
        prob_dict = {
            TestProperties.ParameterKeys.ProgressionKeys.ProbabilityKeys.RelativeProbKeys.sym_to_severe_probability:
            1.0,
            TestProperties.ParameterKeys.ProgressionKeys.ProbabilityKeys.RelativeProbKeys.sev_to_critical_probability:
            0.0
        }
        self.set_simulation_prognosis_probability(prob_dict)
        if constant_delay is not None:
            self.set_duration_distribution_parameters(
                duration_in_question=DurationKeys.symptomatic_to_severe,
                par1=constant_delay,
                par2=0)
        pass

    def set_everyone_critical(self, num_agents, constant_delay: int = None):
        """
        Causes all agents to become critically ill day 1
        """
        self.set_everyone_severe(num_agents=num_agents,
                                 constant_delay=constant_delay)
        prob_dict = {
            TestProperties.ParameterKeys.ProgressionKeys.ProbabilityKeys.RelativeProbKeys.sev_to_critical_probability:
            1.0,
            TestProperties.ParameterKeys.ProgressionKeys.ProbabilityKeys.RelativeProbKeys.crt_to_death_probability:
            0.0
        }
        self.set_simulation_prognosis_probability(prob_dict)
        if constant_delay is not None:
            self.set_duration_distribution_parameters(
                duration_in_question=DurationKeys.severe_to_critical,
                par1=constant_delay,
                par2=0)
        pass

    def set_smallpop_hightransmission(self):
        """
        Creates a small population with lots of transmission
        """
        Simkeys = TestProperties.ParameterKeys.SimulationKeys
        Transkeys = TestProperties.ParameterKeys.TransmissionKeys
        Hightrans = TestProperties.SpecializedSimulations.Hightransmission
        hightrans_parameters = {
            Simkeys.number_agents: Hightrans.n,
            Simkeys.initial_infected_count: Hightrans.pop_infected,
            Simkeys.number_simulated_days: Hightrans.n_days,
            Transkeys.beta: Hightrans.beta
        }
        self.set_simulation_parameters(hightrans_parameters)
        pass

    # endregion
    pass