Source code for pyEpiabm.utility.antibody_multiplier

#
# Class to produce a multiplier for the force of infection depending on an
# individual's IgG antibody count
#

import pyEpiabm as pe


[docs] class AntibodyMultiplier: """Class which calculates a multiplier for the susceptibility in the force of infection (to be used in personal_foi.py) based on the current IgG antibody count. """ def __init__(self, max_41: float, half_life_41: float, change_in_max_10: float, change_in_half_life_10: float, days_positive_pcr_to_max_igg: int): """Constructor Method Parameters ---------- max_41 : float Maximum IgG titre (at the age of 41) half_life_41 : float Half-life in IgG titre (at the age of 41) change_in_max_10 : float Amount by which the maximum IgG increases for every extra 10 years of age a person has change_in_half_life_10 : float Amount by which the half-life in IgG increases for every extra 10 years of age a person has days_positive_pcr_to_max_igg : int Mean number of days from the first positive PCR test to the day of maximum IgG titre """ self.max_41 = max_41 self.half_life_41 = half_life_41 self.change_in_max_10 = change_in_max_10 self.change_in_half_life_10 = change_in_half_life_10 self.days_positive_pcr_to_max_igg = days_positive_pcr_to_max_igg # Parameter checks if max_41 <= 0: raise ValueError("max_41 must be positive") if half_life_41 <= 0: raise ValueError("half_life_41 must be positive") if days_positive_pcr_to_max_igg <= 0: raise ValueError("days_positive_pcr_to_max_igg must be positive") # We also need to ensure that the maximal IgG and half life will never # go negative when taking the changes into account. Multiplying by 4 # corresponds to a change in 40 years of age from 41. maximal_change_in_max_igg = change_in_max_10 * 4 maximal_change_in_half_life = change_in_half_life_10 * 4 if abs(maximal_change_in_max_igg) > max_41: raise ValueError(f"change_in_max_10 is too large in magnitude " f"(supplied: |{change_in_max_10}|, " f"maximal: {max_41 / 4})") if abs(maximal_change_in_half_life) > half_life_41: raise ValueError(f"change_in_half_life_10 is too large is too " f"large in magnitude (supplied: " f"|{change_in_half_life_10}|, maximal: " f"{half_life_41 / 4})") # This is the normalisation constant used later, defined as the maximal # IgG value (at time_since_max = 0) for the maximal age_group self.normalisation = self._calculate_igg_titre(0, 16)
[docs] def __call__(self, time_since_infection: float, age_group: int) -> float: """Calculates the multiplier to be used in the force of infection. Takes the form 1 - A * 2^(-bt) where A and b are factors dependent on `age_group`. If we are not using ages, then we use values for age = 41. This will be a decaying exponential from the time of peak IgG titre, which occurs a fixed period of time after first being infected. Before the peak a person cannot be re-infected, so their force of infection will be zero. Parameters ---------- time_since_infection : float Time (in days) since the `Person` first became infected age_group : int Age group of the `Person` Returns ------- float An IgG multiplier for the force of infection """ # If time_since_infection < days_positive_pcr_to_max_igg, then the # person cannot be reinfected yet, so set their multiplier to 0. if time_since_infection < self.days_positive_pcr_to_max_igg: return 0 # time_since_max represents the days since maximal IgG titre time_since_max = (time_since_infection - self.days_positive_pcr_to_max_igg) # If we are not using ages, then we take the normalised titre to just # be dependent on the half_life_41 value (as we want igg_titre = 1 # when time_since_max = 0) if not pe.Parameters.instance().use_ages: igg_titre = 2 ** (- time_since_max / self.half_life_41) else: igg_titre = self._calculate_igg_titre(time_since_max, age_group) igg_titre /= self.normalisation return 1 - igg_titre
def _calculate_igg_titre(self, time_since_max: float, age_group: int) -> float: """The general expression for the titre is A * 2^(-t/c) where A is the max titre and c is the half-life. Both these values vary with age, and so given the values at age = 41 and the changes per 10 years of age, we calculate A and c for any given age_group. Parameters ---------- time_since_max : float Time (in days) since a `Person`'s maximal IgG titre age_group : int Age group of the `Person` Returns ------- float A value representing the IgG titre at a certain time """ # Calculate parameters based on the person's age group # Note that 41 corresponds to an age_group of 8, and as the change # is over 10 years, we need to divide by 2 to get the change for # 5 years change_in_max = (age_group - 8) * self.change_in_max_10 / 2 change_in_half_life = ((age_group - 8) * self.change_in_half_life_10 / 2) # Find IgG titre igg_titre = ((self.max_41 + change_in_max) * (2 ** (- time_since_max / (self.half_life_41 + change_in_half_life)))) return igg_titre