Skip to content

Symptoms and the SymptomManager

Tim Hallett edited this page Jan 11, 2023 · 5 revisions

Symptoms and the SymptomManager

Symptoms

We define a symptom as an instance of a class called Symptom. The class holds information about how that symptom affects healthcare-seeking behaviour. Symptoms must be registered with the SymptomManager in the read_parameters method of a Module subclass.

Spurious symptoms

The SymptomManager generates "spurious" occurrences of generic symptoms. These are notionally being caused by diseases that are not included in the TLO model. They have no effect other than to perhaps cause someone to seek care and may contribute to a condition being misdiagnosed. This can be turned on/off when you instantiate the SymptomManager, for example

symptommanager.SymptomManager(resourcefilepath=resourcefilepath, spurious_symptoms=True)

Registering symptoms in a disease module

  1. To use symptoms, a disease module must declare itself to be a disease module. To do this, in the class definition (near to where the PARAMETERS and PROPERTIES class attributes are defined) include this line:
METADATA = {Metadata.DISEASE_MODULE}
  1. Then the symptoms must be created and registered. In the read_parameters method of the module, add (an adaptation of) the following:
        # Create and register symptoms that this module will use:
        self.sim.modules['SymptomManager'].register_symptom(
                Symptom(
                    name='inappropriate_jokes',           # <-- the name of the symptom
                ),
                Symptom(                   # <-- multiple symptoms can be declared in one call
                    name='craving_sandwiches',
                    odds_ratio_health_seeking_in_children=1.5, # <-- specify if this symptom increases the likelihood of seeking care (in comparison to that of the 'average' symptom)
                    odds_ratio_health_seeking_in_adults=3.0
                ),
                Symptom(
                    name='leg_has_not_quite_yet_fallen_off',           
                    odds_ratio_health_seeking_in_adults=2.0,
                    odds_ratio_health_seeking_in_children=2.0,
                    prob_seeks_emergency_appt_in_adults=0.25,   # <--- includes these parameters to allow for some chance of emergency healthcare seeking.
                    prob_seeks_emergency_appt_in_children=0.75,
                )
        )

When defining a Symptom remember:

  • The "odds_ratio" parameter is giving information about the tendency of a person with this symptom onset to seek care in comparison to the 'average symptom'. (Other characteristics of the person also influence this: see the HealthSeekingBehaviour module.)
  • The "prob_seeks_emergency_appt" parameter is giving information about the probability that the care that is sought (if care is sought) is emergency care [care is sought immediately and at a level '1b' facility (HSI_GenericEmergencyFirstApptAtFacilityLevel1)] rather than [care is sought after a short delay at a level '0' facility (HSI_GenericFirstApptAtFacilityLevel0)]
  • The "classical" emergency symptom (which certainly causes emergency care seeking upon onset) can be created even more simply using:
Symptom.emergency('leg_has_completely_fallen_off'),  # <-- emergency care seeking for all, or ....
Symptom.emergency('leg_has_completely_fallen_off', which='adults'),   # <--- ... just among those aged 15+ years
Symptom.emergency('leg_has_completely_fallen_off', which='children'),  # <--- ... just among those aged <15 years.

N.B. There should be no need to edit healthseekingbehaviour.py: the influence of a symptom registered in this way on healthcare seeking behaviour is handled automatically.

Using SymptomManager in a disease module

The SymptomManager class provides two main methods for changing the symptoms associated with one or more persons

SymptomManager.change_symptom

Used to add or remove a disease module as the cause for one or more symptoms from one or more persons.

Arguments

  • person_id: Integer index or sequence of integer indices, for person or persons to change symptom state for.
  • symptom_string: String containing name for symptom (as registered with SymptomManager) to change, or if multiple symptoms are to be changed, a sequence of strings corresponding to the names of all symptoms to change.
  • add_or_remove: Either "+" to add the symptom(s) for the specified person(s) or "-" to remove.
  • disease_module: The disease module (Module subclass) responsible for the symptom change.
  • duration_in_days: Integer defining number of days after which symptom should be removed if self-resolving. If set to None (the default), the symptom will not self-resolve.
  • date_of_onset: The simulation date for symptoms to start. If set to None (the default) the symptom change occurs immediately. This should only be set to a non-None value if add_or_remove is set to "+".

Examples

In the below we assume symptom_manager corresponds to an initialised instance of SymptomManager, disease_module to the disease module responsible for the symptom changes, person_ids to a list of integer indices for persons in the population dataframe and symptom_strings to a list of symptom names associated with the disease module.

Adding then removing a single symptom for an individual

symptom_manager.change_symptom(person_ids[0], symptom_strings[0], '+', disease_module)
symptom_manager.change_symptom(person_ids[0], symptom_strings[0], '-', disease_module)

Adding then removing a single symptom for multiple persons

symptom_manager.change_symptom(person_ids, symptom_strings[0], '+', disease_module)
symptom_manager.change_symptom(person_ids, symptom_strings[0], '-', disease_module)

Adding then removing multiple symptoms for a single person

symptom_manager.change_symptom(person_ids[0], symptom_strings, '+', disease_module)
symptom_manager.change_symptom(person_ids[0], symptom_strings, '-', disease_module)

Adding then removing multiple symptoms for multiple persons

symptom_manager.change_symptom(person_ids, symptom_strings, '+', disease_module)
symptom_manager.change_symptom(person_ids, symptom_strings, '-', disease_module)

SymptomManager.clear_symptoms

Used to remove a disease module as the cause for any symptoms currently set.

Arguments

  • person_id: Integer index or sequence of integer indices, for person or persons to clear symptoms for.
  • disease_module: The disease module (Module subclass) responsible for the symptom change.

Examples

In the below we assume symptom_manager corresponds to an initialised instance of SymptomManager, disease_module to the disease module responsible for the symptom changes and person_ids to a list of integer indices for persons in the population dataframe.

Removing all symptoms for a single person

symptom_manager.clear_symptoms(person_ids[0], disease_module)

Removing all symptoms for multiple persons

symptom_manager.clear_symptoms(person_ids, disease_module)
Clone this wiki locally