tlo.methods.healthsystem module

class HSI_Event(module, *args, **kwargs)[source]

Base HSI event class, from which all others inherit.

Concrete subclasses should also inherit from one of the EventMixin classes defined below, and implement at least an apply and did_not_run method.

Class attributes:

bed_days_allocated_to_this_event : <property object at 0x7feb9078a270>

Functions (defined or overridden in class HSI_Event):

__init__(module, *args, **kwargs)[source]

Create a new event.

Note that just creating an event does not schedule it to happen; that must be done by calling Simulation.schedule_event.

Parameters

module – the module that created this event. All subclasses of Event take this as the first argument in their constructor, but may also take further keyword arguments.

apply(squeeze_factor=0.0, *args, **kwargs)[source]

Apply this event to the population.

Must be implemented by subclasses.

did_not_run(*args, **kwargs)[source]

Called when this event is due but it is not run. Return False to prevent the event being rescheduled, or True to allow the rescheduling. This is called each time that the event is tried to be run but it cannot be.

never_ran()[source]

Called when this event is was entered to the HSI Event Queue, but was never run.

post_apply_hook()[source]

Impose the bed-days footprint (if target of the HSI is a person_id)

run(squeeze_factor)[source]

Make the event happen.

get_consumables(item_codes: Union[None, integer, int, list, set, dict] = None, optional_item_codes: Union[None, integer, int, list, set, dict] = None, to_log: Optional[bool] = True, return_individual_results: Optional[bool] = False) Union[bool, dict][source]

Function to allow for getting and checking of entire set of consumables. All requests for consumables should use this function. :param item_codes: The item code(s) (and quantities) of the consumables that are requested and which determine the summary result for availability/non-availability. This can be an int (the item_code needed [assume quantity=1]), a list or set (the collection of item_codes [for each assuming quantity=1]), or a dict (with key:value pairs <item_code>:<quantity>). :param optional_item_codes: The item code(s) (and quantities) of the consumables that are requested and which do

not determine the summary result for availability/non-availability. (Same format as item_codes). This is useful when a large set of items may be used, but the viability of a subsequent operation depends only on a subset.

Parameters

return_individual_results – If True returns a dict giving the availability of each item_code requested

(otherwise gives a bool indicating if all the item_codes requested are available). :param to_log: If True, logs the request. :returns A bool indicating whether every item is available, or a dict indicating the availability of each

item.

Note that disease module can use the get_item_codes_from_package_name and get_item_code_from_item_name

methods in the HealthSystem module to find item_codes.

make_beddays_footprint(dict_of_beddays)[source]

Helper function to make a correctly-formed ‘bed-days footprint’

is_all_beddays_allocated()[source]

Check if the entire footprint requested is allocated

make_appt_footprint(dict_of_appts)[source]

Helper function to make appointment footprint in format expected downstream.

Should be passed a dictionary keyed by appointment type codes with non-negative values.

initialise()[source]

Initialise the HSI: * Set the facility_info * Compute appt-footprint time requirements

_check_if_appt_footprint_can_run()[source]

Check that event (if individual level) is able to run with this configuration of officers (i.e. check that this does not demand officers that are _never_ available), and issue warning if not.

class HSIEventWrapper(hsi_event, run_hsi=True, *args, **kwargs)[source]

This is wrapper that contains an HSI event.

It is used:

1) When the healthsystem is in mode ‘disabled=True’ such that HSI events sent to the health system scheduler are passed to the main simulation scheduler for running on the date of topen. (Note, it is run with squeeze_factor=0.0.) 2) When the healthsytsem is in mode diable_and_reject_all=True such that HSI are not run but the never_ran method is run on the date of tclose. 3) When an HSI has been submitted to schedule_hsi_event but the service is not available.

Bases: tlo.events.Event

Functions (defined or overridden in class HSIEventWrapper):

__init__(hsi_event, run_hsi=True, *args, **kwargs)[source]

Create a new event.

Note that just creating an event does not schedule it to happen; that must be done by calling Simulation.schedule_event.

Parameters
  • module – the module that created this event. All subclasses of Event take this as the first argument in their constructor, but may also take further keyword arguments.

  • priority – a keyword-argument to set the priority (see Priority enum)

run()[source]

Do the appropriate action on the HSI event

class HealthSystem(name: Optional[str] = None, resourcefilepath: Optional[Path] = None, service_availability: Optional[List[str]] = None, mode_appt_constraints: int = 0, cons_availability: Optional[str] = None, beds_availability: Optional[str] = None, ignore_priority: bool = False, capabilities_coefficient: Optional[float] = None, use_funded_or_actual_staffing: Optional[str] = 'funded_plus', disable: bool = False, disable_and_reject_all: bool = False, store_hsi_events_that_have_run: bool = False, record_hsi_event_details: bool = False)[source]

This is the Health System Module. The execution of all health systems interactions are controlled through this module.

Bases: tlo.core.Module

PARAMETERS:

Item

Type

Description

Master_Facilities_List

DATA_FRAME

Listing of all health facilities.

Officer_Types_Table

DATA_FRAME

The names of the types of health workers (“officers”)

Appt_Types_Table

DATA_FRAME

The names of the type of appointments with the health system

Appt_Offered_By_Facility_Level

DATA_FRAME

Table indicating whether or not each appointment is offered at each facility level.

Appt_Time_Table

DATA_FRAME

The time taken for each appointment, according to officer and facility type.

Daily_Capabilities_actual

DATA_FRAME

The capabilities (minutes of time available of each type of officer in each facility) based on the _estimated current_ number and distribution of staff estimated.

Daily_Capabilities_funded

DATA_FRAME

The capabilities (minutes of time available of each type of officer in each facility) based on the _potential_ number and distribution of staff estimated (i.e. those positions that can be funded).

Daily_Capabilities_funded_plus

DATA_FRAME

The capabilities (minutes of time available of each type of officer in each facility) based on the _potential_ number and distribution of staff estimated, with adjustments to permit each appointment type that should be run at facility level to do so in every district.

item_and_package_code_lookups

DATA_FRAME

Data imported from the OneHealth Tool on consumable items, packages and costs.

availability_estimates

DATA_FRAME

Estimated availability of consumables in the LMIS dataset.

cons_availability

STRING

Availability of consumables. If ‘default’ then use the availability specified in the ResourceFile; if ‘none’, then let no consumable be ever be available; if ‘all’, then all consumables are always available. When using ‘all’ or ‘none’, requests for consumables are not logged. NB. This parameter is over-riddenif an argument is provided to the module initialiser.

BedCapacity

DATA_FRAME

Data on the number of beds available of each type by facility_id

beds_availability

STRING

Availability of beds. If ‘default’ then use the availability specified in the ResourceFile; if ‘none’, then let no beds be ever be available; if ‘all’, then all beds are always available. NB. This parameter is over-ridden if an argument is provided to the module initialiser.

Service_Availability

LIST

List of services to be available. NB. This parameter is over-ridden if an argument is provided to the module initialiser.

PROPERTIES:

Item

Type

Description

hs_is_inpatient

BOOL

Whether or not the person is currently an in-patient at any medical facility

Class attributes:

INIT_DEPENDENCIES : {‘Demography’}

capabilities_today : <property object at 0x7feb9078a360>

Functions (defined or overridden in class HealthSystem):

__init__(name: Optional[str] = None, resourcefilepath: Optional[Path] = None, service_availability: Optional[List[str]] = None, mode_appt_constraints: int = 0, cons_availability: Optional[str] = None, beds_availability: Optional[str] = None, ignore_priority: bool = False, capabilities_coefficient: Optional[float] = None, use_funded_or_actual_staffing: Optional[str] = 'funded_plus', disable: bool = False, disable_and_reject_all: bool = False, store_hsi_events_that_have_run: bool = False, record_hsi_event_details: bool = False)[source]
Parameters
  • name – Name to use for module, defaults to module class name if None.

  • resourcefilepath – Path to directory containing resource files.

  • service_availability – A list of treatment IDs to allow.

  • mode_appt_constraints – Integer code in {0, 1, 2} determining mode of constraints with regards to officer numbers and time - 0: no constraints, all HSI events run with no squeeze factor, 1: elastic constraints, all HSI events run with squeeze factor, 2: hard constraints, only HSI events with no squeeze factor run.

  • cons_availability – If ‘default’ then use the availability specified in the ResourceFile; if ‘none’, then

let no consumable be ever be available; if ‘all’, then all consumables are always available. When using ‘all’ or ‘none’, requests for consumables are not logged. :param beds_availability: If ‘default’ then use the availability specified in the ResourceFile; if ‘none’, then let no beds be ever be available; if ‘all’, then all beds are always available. :param ignore_priority: If True do not use the priority information in HSI

event to schedule

Parameters
  • capabilities_coefficient – Multiplier for the capabilities of health officers, if None set to ratio of initial population to estimated 2010 population.

  • use_funded_or_actual_staffing – If actual, then use the numbers and distribution of staff estimated to

be available currently; If funded, then use the numbers and distribution of staff that are potentially available. :param disable: If True, disables the health system (no constraints and no

logging) and every HSI event runs.

Parameters
  • disable_and_reject_all – If True, disable health system and no HSI events run

  • store_hsi_events_that_have_run – Convenience flag for debugging.

  • record_hsi_event_details – Whether to record details of HSI events used.

read_parameters(data_folder)[source]

Read parameter values from file, if required.

Must be implemented by subclasses.

Parameters

data_folder – path of a folder supplied to the Simulation containing data files. Typically modules would read a particular file within here.

pre_initialise_population()[source]

Generate the accessory classes used by the HealthSystem and pass to them the data that has been read.

initialise_population(population)[source]

Set our property values for the initial population.

Must be implemented by subclasses.

This method is called by the simulation when creating the initial population, and is responsible for assigning initial values, for every individual, of those properties ‘owned’ by this module, i.e. those declared in its PROPERTIES dictionary.

TODO: We probably need to declare somehow which properties we ‘read’ here, so the simulation knows what order to initialise modules in!

Parameters

population – the population of individuals

initialise_simulation(sim)[source]

Get ready for simulation start.

Must be implemented by subclasses.

This method is called just before the main simulation loop begins, and after all modules have read their parameters and the initial population has been created. It is a good place to add initial events to the event queue.

on_birth(mother_id, child_id)[source]

Initialise our properties for a newborn individual.

Must be implemented by subclasses.

This is called by the simulation whenever a new person is born.

Parameters
  • mother – the mother for this child (can be -1 if the mother is not identified).

  • child – the new child

on_simulation_end()[source]

Put out to the log the information from the tracker of the last day of the simulation

process_human_resources_files()[source]

Create the data-structures needed from the information read into the parameters.

format_daily_capabilities() Series[source]

This will updates the dataframe for the self.parameters[‘Daily_Capabilities’] so as to include every permutation of officer_type_code and facility_id, with zeros against permutations where no capacity is available.

It also give the dataframe an index that is useful for merging on (based on Facility_ID and Officer Type)

(This is so that its easier to track where demands are being placed where there is no capacity)

get_service_availability() List[str][source]

Returns service availability. (Should be equal to what is specified by the parameter, but overwrite with what was provided in argument if an argument was specified – provided for backward compatibility/debugging.)

get_cons_availability() str[source]

Set consumables availability. (Should be equal to what is specified by the parameter, but overwrite with what was provided in argument if an argument was specified – provided for backward compatibility/debugging.)

get_beds_availability() str[source]

Set beds availability. (Should be equal to what is specified by the parameter, but overwrite with what was provided in argument if an argument was specified – provided for backward compatibility/debugging.)

schedule_hsi_event(hsi_event: HSI_Event, priority: int, topen: datetime, tclose: Optional[datetime] = None, do_hsi_event_checks: bool = True)[source]

Schedule a health system interaction (HSI) event.

Parameters
  • hsi_event – The HSI event to be scheduled.

  • priority – The priority for the HSI event: 0 (highest), 1 or 2 (lowest)

  • topen – The earliest date at which the HSI event should run.

  • tclose – The latest date at which the HSI event should run. Set to one week after topen if None.

  • do_hsi_event_checks – Whether to perform sanity checks on the passed hsi_event argument to check that it constitutes a valid HSI event. This is intended for allowing disabling of these checks when scheduling multiple HSI events of the same HSI_Event subclass together, in which case typically performing these checks for each individual HSI event of the shared type will be redundant.

_add_hsi_event_queue_item_to_hsi_event_queue(priority, topen, tclose, hsi_event) None[source]

Add an event to the HSI_EVENT_QUEUE.

check_hsi_event_is_valid(hsi_event)[source]

Check the integrity of an HSI_Event.

static is_treatment_id_allowed(treatment_id: str, service_availability: list) bool[source]

Determine if a treatment_id (specified as a string) can be run (i.e., is within the allowable set of treatments, given by self.service_availability.

schedule_batch_of_individual_hsi_events(hsi_event_class, person_ids, priority, topen, tclose=None, **event_kwargs)[source]

Schedule a batch of individual-scoped HSI events of the same type.

Only performs sanity checks on the HSI event for the first scheduled event thus removing the overhead of multiple redundant checks.

Parameters
  • hsi_event_class – The HSI_Event subclass of the events to schedule.

  • person_ids – A sequence of person ID index values to use as the targets of the HSI events being scheduled.

  • priority – The priority for the HSI events: 0 (highest), 1 or 2 (lowest). Either a single value for all events or an iterable of per-target values.

  • topen – The earliest date at which the HSI events should run. Either a single value for all events or an iterable of per-target values.

  • tclose – The latest date at which the HSI events should run. Set to one week after topen if None. Either a single value for all events or an iterable of per-target values.

  • event_kwargs – Any additional keyword arguments to pass to the hsi_event_class initialiser in addition to person_id.

appt_footprint_is_valid(appt_footprint)[source]

Checks an appointment footprint to ensure it is in the correct format. :param appt_footprint: Appointment footprint to check. :return: True if valid and False otherwise.

get_blank_appt_footprint()[source]

This is a helper function so that disease modules can easily create their appt_footprints. It returns an empty Counter instance.

get_facility_info(hsi_event) FacilityInfo[source]

Helper function to find the facility at which an HSI event will take place based on their district of residence and the level of the facility of the HSI.

get_appt_footprint_as_time_request(facility_info: FacilityInfo, appt_footprint: dict)[source]

This will take an APPT_FOOTPRINT and return the required appointments in terms of the time required of each Officer Type in each Facility ID. The index will identify the Facility ID and the Officer Type in the same format as is used in Daily_Capabilities. :params facility_info: The FacilityInfo describing the facility at which the appointment occurs :param appt_footprint: The actual appt footprint (optional) if different to that in the HSI event. :return: A Counter that gives the times required for each officer-type in each facility_ID, where this time

is non-zero.

get_squeeze_factors(footprints_per_event, total_footprint, current_capabilities)[source]

This will compute the squeeze factors for each HSI event from the list of all the calls on health system resources for the day. The squeeze factor is defined as (call/available - 1). ie. the highest fractional over-demand among any type of officer that is called-for in the appt_footprint of an HSI event. A value of 0.0 signifies that there is no squeezing (sufficient resources for the EXPECTED_APPT_FOOTPRINT). A value of 99.99 signifies that the call is for an officer_type in a health-facility that is not available.

Parameters
  • footprints_per_event – List, one entry per HSI event, containing the minutes required from each health officer in each health facility as a Counter (using the standard index)

  • total_footprint – Counter, containing the total minutes required from each health officer in each health facility when non-zero, (using the standard index)

  • current_capabilities – Series giving the amount of time available for each health officer in each health facility (using the standard index)

Returns

squeeze_factors: an array of the squeeze factors for each HSI event (position in array matches that in the all_call_today list).

record_hsi_event(hsi_event, actual_appt_footprint=None, squeeze_factor=None, did_run=True)[source]

Record the processing of an HSI event. If this is an individual-level HSI_Event, it will also record the actual appointment footprint :param hsi_event: The HSI_Event (containing the initial expectations of footprints) :param actual_appt_footprint: The actual Appointment Footprint (if individual event) :param squeeze_factor: The squeeze factor (if individual event)

write_to_hsi_log(treatment_id, number_by_appt_type_code, person_id, squeeze_factor, did_run, facility_level, facility_id)[source]

Write the log HSI_Event and add to the summary counter.

log_current_capabilities_and_usage()[source]

This will log the percentage of the current capabilities that is used at each Facility Type, according the runnning_total_footprint.

remove_beddays_footprint(person_id)[source]
find_events_for_person(person_id: int)[source]

Find the events in the HSI_EVENT_QUEUE for a particular person. :param person_id: the person_id of interest :returns list of tuples (date_of_event, event) for that person_id in the HSI_EVENT_QUEUE.

NB. This is for debugging and testing only - not for use in real simulations as it is slow

reset_queue()[source]

Set the HSI event queue to be empty

get_item_codes_from_package_name(package: str) dict[source]

Helper function to provide the item codes and quantities in a dict of the form {<item_code>:<quantity>} for a given package name.

get_item_code_from_item_name(item: str) int[source]

Helper function to provide the item_code (an int) when provided with the name of the item

override_availability_of_consumables(item_codes) None[source]

Over-ride the availability (for all months and all facilities) of certain consumables item_codes. :param item_codes: Dictionary of the form {<item_code>: probability_that_item_is_available} :return: None

on_end_of_day() None[source]

Do jobs to be done at the end of the day (after all HSI run)

on_end_of_year() None[source]

Write to log the current states of the summary counters and reset them.

run_population_level_events(_list_of_population_hsi_event_tuples: List[HSIEventQueueItem]) None[source]

Run a list of population level events.

run_individual_level_events(_list_of_individual_hsi_event_tuples: List[HSIEventQueueItem]) List[source]

Run a list of individual level events. Returns: list of events that did not run (maybe an empty a list).

class HealthSystemScheduler(module: HealthSystem)[source]

This is the HealthSystemScheduler. It is an event that occurs every day and must be the LAST event of the day. It inspects the calls on the healthsystem and commissions event to occur that are consistent with the healthsystem’s capabilities for the following day, given assumptions about how this decision is made.

N.B. Events scheduled for the same day will occur that day, but after those which were scheduled on an earlier date.

The overall Prioritization algorithm is: * Look at events in order (the order is set by the heapq: see schedule_hsi_event) * Ignore if the current data is before topen * Remove and do nothing if tclose has expired * Run any population-level HSI events * For an individual-level HSI event, check if there are sufficient health system capabilities to run the event

If the event is to be run, then the following events occur:
  • The HSI event itself is run.

  • The occurence of the event is logged

  • The resources used are ‘occupied’ (if individual level HSI event)

  • Other disease modules are alerted of the occurence of the HSI event (if individual level HSI event)

Here is where we can have multiple types of assumption regarding how these capabilities are modelled.

Bases: tlo.events.RegularEvent, tlo.events.Event, tlo.events.PopulationScopeEventMixin

Functions (defined or overridden in class HealthSystemScheduler):

__init__(module: HealthSystem)[source]

Create a new regular event.

Parameters
  • module – the module that created this event

  • frequency (pandas.tseries.offsets.DateOffset) – the interval from one occurrence to the next (must be supplied as a keyword argument)

static _is_today_last_day_of_the_year(date)[source]
_get_events_due_today() Tuple[List, List][source]

Interrogate the HSI_EVENT queue object to remove from it the events due today, and to return these in two lists:

  • list_of_individual_hsi_event_tuples_due_today

  • list_of_population_hsi_event_tuples_due_today

apply(population)[source]

Apply this event to the population.

Must be implemented by subclasses.

Parameters

population – the current population

class HealthSystemChangeParameters(module: HealthSystem, parameters: Dict)[source]
Event that causes certain internal parameters of the HealthSystem to be changed; specifically:
  • mode_appt_constraints

  • ignore_priority

  • capabilities_coefficient

  • cons_availability

  • beds_availability

Note that no checking is done here on the suitability of values of each parameter.

Bases: tlo.events.Event, tlo.events.PopulationScopeEventMixin

Functions (defined or overridden in class HealthSystemChangeParameters):

__init__(module: HealthSystem, parameters: Dict)[source]

Create a new event.

Note that just creating an event does not schedule it to happen; that must be done by calling Simulation.schedule_event.

Parameters
  • module – the module that created this event. All subclasses of Event take this as the first argument in their constructor, but may also take further keyword arguments.

  • priority – a keyword-argument to set the priority (see Priority enum)

apply(population)[source]

Apply this event to the population.

Must be implemented by subclasses.

Parameters

population – the current population