Source code for pyEpiabm.sweep.initial_infected_sweep
#
# Seed infected individuals in population
#
import random
import math
import logging
from pyEpiabm.property import InfectionStatus
from pyEpiabm.sweep.host_progression_sweep import HostProgressionSweep
from pyEpiabm.core import Parameters
from .abstract_sweep import AbstractSweep
[docs]
class InitialInfectedSweep(AbstractSweep):
"""Class for sweeping through population at start
of simulation and setting an initial number of infected people,
with status InfectMild.
"""
[docs]
def __call__(self, sim_params: dict):
"""Method that randomly chooses a user-supplied number of people
in the population, changes their infection status to InfectMild
and sets their time of next status change.
Parameters
----------
sim_params : dict
Dictionary of simulation parameters
"""
pop_size = self._population.total_people()
if pop_size < \
sim_params["initial_infected_number"]:
raise ValueError('Initial number of infected people needs to be'
+ ' less than the total population')
if math.floor(sim_params["initial_infected_number"]) < \
sim_params["initial_infected_number"]:
logging.warning("Initial number of infected people needs to be an"
+ " integer so we use floor function to round"
+ " down. Inputed value was"
+ f" {sim_params['initial_infected_number']}")
sim_params["initial_infected_number"] = \
math.floor(sim_params["initial_infected_number"])
start_time = sim_params["simulation_start_time"]
if start_time < 0:
raise ValueError('Simulation start time needs to be greater or'
+ ' equal to 0')
# Checks whether there are enough susceptible people to infect.
status = InfectionStatus.Susceptible
num_susceptible = 0
for cell in self._population.cells:
num_susceptible = num_susceptible + \
sum(cell.compartment_counter.retrieve()[status])
if num_susceptible < sim_params["initial_infected_number"]:
raise ValueError('There are not enough susceptible people in the \
population to infect')
# set default to not treat carehome residents differently
carehome_inf = 1
if hasattr(Parameters.instance(), 'carehome_params'):
care_param = Parameters.instance().carehome_params
carehome_inf = care_param["carehome_allow_initial_infections"]
if ("initial_infect_cell" not in sim_params
or not sim_params["initial_infect_cell"]):
all_persons = [pers for cell in self._population.cells for pers
in cell.persons if
(pers.infection_status ==
InfectionStatus.Susceptible)]
else:
cells_list = []
for cell in self._population.cells:
if len(cell.persons) >= sim_params["initial_infected_number"]:
cells_list.append(cell)
if len(cells_list) == 0:
raise ValueError('There are no cells with enough people\
to seed initial infections')
else:
cell = random.choice(cells_list)
all_persons = [pers for pers in cell.persons if
(pers.infection_status ==
InfectionStatus.Susceptible)]
if carehome_inf == 0:
for person in all_persons:
if person.care_home_resident:
all_persons.remove(person)
if len(all_persons) < sim_params["initial_infected_number"]:
raise ValueError('There are not enough susceptible people in the \
population to infect due to excluding \
care home residents')
pers_to_infect = random.sample(all_persons,
int(sim_params
["initial_infected_number"]))
for person in pers_to_infect:
person.update_status(InfectionStatus.InfectMild)
person.household.remove_susceptible_person(person)
person.next_infection_status = InfectionStatus.Recovered
HostProgressionSweep.set_infectiousness(person, start_time)
HostProgressionSweep().update_time_status_change(person,
start_time)