tlo.scenario module¶
Creating and running simulation scenarios for TLOmodel
Scenarios are used to specify, configure and run a single or set of TLOmodel simulations. A scenario is created by by subclassing BaseScenario and specifying the scenario options therein. You can override parameters of the module in various ways in the scenario. See the BaseScenario class for more information.
The subclass of BaseScenario is then used to create draws, which can be considered a fully-specified configuration of the scenario, or a parameter draw.
Each draw is run one or more times - run is a single execution of the simulation. Each run of a draw has a different seed but is otherwise identical. Each run has its own simulation seed, introducing randomness into each simulation. A collection of runs for a given draw describes the random variation in the simulation.
A simple example of a subclass of BaseScenario:
class MyTestScenario(BaseScenario):
def __init__(self):
super().__init__()
self.seed = 12
self.start_date = Date(2010, 1, 1)
self.end_date = Date(2011, 1, 1)
self.pop_size = 200
self.number_of_draws = 2
self.runs_per_draw = 2
def log_configuration(self):
return {
'filename': 'my_test_scenario',
'directory': './outputs',
'custom_levels': {'*': logging.INFO}
}
def modules(self):
return [
demography.Demography(resourcefilepath=self.resources),
enhanced_lifestyle.Lifestyle(resourcefilepath=self.resources),
]
def draw_parameters(self, draw_number, rng):
return {
'Lifestyle': {
'init_p_urban': rng.randint(10, 20) / 100.0,
}
}
In summary:
A scenario specifies the configuration of the simulation. The simulation start and end dates, initial population size, logging setup and registered modules. Optionally, you can also override parameters of modules.
A draw is a realisation of a scenario configuration. A scenario can have one or more draws. Draws are uninteresting unless you are overriding parameters. If you do not override any model parameters, you would only have one draw.
A run is the result of running the simulation using a specific configuration. Each draw would run one or more times. Each run for the same draw would have identical configuration except the simulation seed.
- class BaseScenario[source]¶
Bases:
object
An abstract base class for creating Scenarios
A scenario is a configuration of a simulation. Users should subclass this class and implement the following methods:
__init__
- to set scenario attributeslog_configuration
- to configure filename, directory and logging levels for simulation outputmodules
- to list disease, intervention and health system modules for the simulationdraw_parameters
- override parameters for draws from the scenario
- log_configuration(**kwargs)[source]¶
Implementation must return a dictionary configuring logging.
Example:
return { 'filename': 'test_scenario', 'directory': './outputs', 'custom_levels': { '*': logging.WARNING, 'tlo.methods.demography': logging.INFO } }
- modules()[source]¶
Implementation must return a list of instances of TLOmodel modules to register in the simulation.
Example:
return [ demography.Demography(resourcefilepath=self.resources), enhanced_lifestyle.Lifestyle(resourcefilepath=self.resources), healthsystem.HealthSystem(resourcefilepath=self.resources, disable=True, service_availability=['*']), ... ]
- draw_parameters(draw_number, rng)[source]¶
Implementation must return a dictionary of parameters to override for each draw.
The overridden parameters must be scalar (i.e. float, integer or string) as the following examples demonstrate. The argument
draw_number
and a random number generator are available, if required.Change a parameter to a fixed value:
{'Labour': {'average_age_at_pregnancy': 25}}
Sample a value from a distribution:
{'Lifestyle': {'init_p_urban': rng.randint(10, 20) / 100.0}}
Set a value based on the draw number:
{'Labour': {'average_age_at_pregnancy': [25, 30, 35][draw_number]}}
Implementation of this method in a subclass is optional. If no parameters are to be overridden, returns
None
. If no parameters are overridden, only one draw of the scenario is required.A full example for a scenario with 10 draws:
return { 'Lifestyle': { 'init_p_urban': rng.randint(10, 20) / 100.0, }, 'Labour': { 'average_age_at_pregnancy': -10 * rng.exponential(0.1), 'some_other_parameter': np.arange(0.1, 1.1, 0.1)[draw_number] }, }
- Parameters
draw_number (int) – the specific draw number currently being executed by the simulation engine
rng (numpy.random.RandomState) – the scenario’s random number generator for sampling from distributions
- make_grid(ranges: dict) DataFrame [source]¶
Utility method to flatten an n-dimension grid of parameters for use in scenarios
Typically used in draw_parameters determining a set of parameters for a draw. This function will check that the number of draws of the scenario is equal to the number of coordinates in the grid.
Parameter
ranges
is a dictionary of { string key: iterable }, where iterable can be, for example, an np.array or list. The function will return a DataFrame where each key is a column and each row represents a single coordinate in the grid.Usage (in
draw_parameters
):grid = self.make_grid({'p_one': np.linspace(0, 1.0, 5), 'p_two': np.linspace(3.0, 4.0, 2)}) return { 'Mockitis': { grid['p_one'][draw_number], grid['p_two'][draw_number] } }
- Parameters
ranges (dict) – each item of dict represents points across a single dimension
- class ScenarioLoader(scenario_path)[source]¶
Bases:
object
A utility class to load a scenario class from a file path
- class DrawGenerator(scenario_class, number_of_draws, runs_per_draw)[source]¶
Bases:
object
Creates and saves a JSON representation of draws from a scenario.
- class SampleRunner(run_configuration_path)[source]¶
Bases:
object
Reads scenario draws from a JSON configuration and handles running of samples
- property number_of_draws¶
- property runs_per_draw¶
- static low_bias_32(x)[source]¶
A simple integer hash function with uniform distribution. Following description taken from https://github.com/skeeto/hash-prospector
The integer hash function transforms an integer hash key into an integer hash result. For a hash function, the distribution should be uniform. This implies when the hash result is used to calculate hash bucket address, all buckets are equally likely to be picked. In addition, similar hash keys should be hashed to very different hash results. Ideally, a single bit change in the hash key should influence all bits of the hash result.
- Param
x an integer
- Returns
an integer