Skip to content

Transmission

Transmission

Source code in june/epidemiology/infection/transmission.py
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class Transmission:
    """ """
    __slots__ = "probability"

    def __init__(self):
        self.probability = 0.0

    def update_infection_probability(self, time_from_infection):
        """

        Args:
            time_from_infection: 

        """
        raise NotImplementedError()

update_infection_probability(time_from_infection)

Parameters:

Name Type Description Default
time_from_infection
required
Source code in june/epidemiology/infection/transmission.py
26
27
28
29
30
31
32
33
def update_infection_probability(self, time_from_infection):
    """

    Args:
        time_from_infection: 

    """
    raise NotImplementedError()

TransmissionConstant

Bases: Transmission

Source code in june/epidemiology/infection/transmission.py
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
class TransmissionConstant(Transmission):
    """ """
    def __init__(self, probability=0.3):
        super().__init__()
        self.probability = probability

    @classmethod
    def from_file(
        cls, config_path: str = default_config_path
    ) -> "TransmissionConstant":
        """

        Args:
            config_path (str, optional): (Default value = default_config_path)

        """
        with open(config_path) as f:
            config = yaml.safe_load(f)
        probability = CompletionTime.from_dict(config["probability"])()
        return TransmissionConstant(probability=probability)

    def update_infection_probability(self, time_from_infection):
        """

        Args:
            time_from_infection: 

        """
        pass

from_file(config_path=default_config_path) classmethod

Parameters:

Name Type Description Default
config_path str

(Default value = default_config_path)

default_config_path
Source code in june/epidemiology/infection/transmission.py
42
43
44
45
46
47
48
49
50
51
52
53
54
55
@classmethod
def from_file(
    cls, config_path: str = default_config_path
) -> "TransmissionConstant":
    """

    Args:
        config_path (str, optional): (Default value = default_config_path)

    """
    with open(config_path) as f:
        config = yaml.safe_load(f)
    probability = CompletionTime.from_dict(config["probability"])()
    return TransmissionConstant(probability=probability)

update_infection_probability(time_from_infection)

Parameters:

Name Type Description Default
time_from_infection
required
Source code in june/epidemiology/infection/transmission.py
57
58
59
60
61
62
63
64
def update_infection_probability(self, time_from_infection):
    """

    Args:
        time_from_infection: 

    """
    pass

TransmissionGamma

Bases: Transmission

Module to simulate the infectiousness profiles found in : - https://www.nature.com/articles/s41591-020-0869-5 - https://arxiv.org/pdf/2007.06602.pdf

Source code in june/epidemiology/infection/transmission.py
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
class TransmissionGamma(Transmission):
    """Module to simulate the infectiousness profiles found in :
        - https://www.nature.com/articles/s41591-020-0869-5
        - https://arxiv.org/pdf/2007.06602.pdf

    """

    __slots__ = ("shape", "shift", "scale", "norm", "probability")

    def __init__(
        self,
        max_infectiousness: float = 1.0,
        shape: float = 2.0,
        rate: float = 3.0,
        shift: float = -2.0,
        max_symptoms: Optional[str] = None,
        asymptomatic_infectious_factor: Optional[float] = None,
        mild_infectious_factor: Optional[float] = None,
    ):
        """
        Parameters
        ----------
        max_infectiousness:
            value of the infectiousness at its peak
        shape:
            shape parameter of the gamma distribution (a for scipy stats)
        rate:
            rate parameter of the gamma distribution (1/rate = scale for scipy stats)
        shift:
            location parameter of the gamma distribution
        max_symptoms:
            maximum symptoms the individual will develop, used to reduce the infectiousness
            of asymptomatic and mild individuals if wanted
        asymptomatic_infectious_factor:
            factor to reduce the infectiousness of asymptomatic individuals
        mild_infectious_factor:
            factor to reduce the infectiousness of mild individuals
        """
        self.shape = shape
        self.shift = shift
        self.scale = 1.0 / rate
        self.norm = max_infectiousness
        if (
            asymptomatic_infectious_factor is not None
            and mild_infectious_factor is not None
        ):
            self.norm *= self._modify_infectiousness_for_symptoms(
                max_symptoms=max_symptoms,
                asymptomatic_infectious_factor=asymptomatic_infectious_factor,
                mild_infectious_factor=mild_infectious_factor,
            )
        self.probability = 0.0

    @classmethod
    def from_file(
        cls, max_symptoms: str = None, config_path: str = default_gamma_config_path
    ) -> "TransmissionGamma":
        """Generate transmission class reading parameters from config file

        Args:
            max_symptoms (str, optional): maximum symptoms the individual will develop, used to reduce the infectiousness
        of asymptomatic and mild individuals if wanted (Default value = None)
            config_path (str, optional): path to config parameters (Default value = default_gamma_config_path)

        """
        with open(config_path) as f:
            config = yaml.safe_load(f)
        max_infectiousness = CompletionTime.from_dict(config["max_infectiousness"])()
        shape = CompletionTime.from_dict(config["shape"])()
        rate = CompletionTime.from_dict(config["rate"])()
        shift = CompletionTime.from_dict(config["shift"])()
        asymptomatic_infectious_factor = CompletionTime.from_dict(
            config["asymptomatic_infectious_factor"]
        )()
        mild_infectious_factor = CompletionTime.from_dict(
            config["mild_infectious_factor"]
        )()

        return cls(
            max_infectiousness=max_infectiousness,
            shape=shape,
            rate=rate,
            shift=shift,
            max_symptoms=max_symptoms,
            asymptomatic_infectious_factor=asymptomatic_infectious_factor,
            mild_infectious_factor=mild_infectious_factor,
        )

    @classmethod
    def from_file_linked_symptoms(
        cls,
        time_to_symptoms_onset: float,
        max_symptoms: str = None,
        config_path: str = default_gamma_config_path,
    ) -> "TransmissionGamma":
        """Generate transmission class reading parameters from config file, linked to
        the time of symptoms onset

        Args:
            time_to_symptoms_onset (float): time (from infection) at which the person becomes symptomatic
            max_symptoms (str, optional): maximum symptoms the individual will develop, used to reduce the infectiousness
        of asymptomatic and mild individuals if wanted (Default value = None)
            config_path (str, optional): path to config parameters (Default value = default_gamma_config_path)

        """

        with open(config_path) as f:
            config = yaml.safe_load(f)
        max_infectiousness = CompletionTime.from_dict(config["max_infectiousness"])()
        shape = CompletionTime.from_dict(config["shape"])()
        rate = CompletionTime.from_dict(config["rate"])()
        shift = CompletionTime.from_dict(config["shift"])() + time_to_symptoms_onset
        asymptomatic_infectious_factor = CompletionTime.from_dict(
            config["asymptomatic_infectious_factor"]
        )()
        mild_infectious_factor = CompletionTime.from_dict(
            config["mild_infectious_factor"]
        )()

        return cls(
            max_infectiousness=max_infectiousness,
            shape=shape,
            rate=rate,
            shift=shift,
            max_symptoms=max_symptoms,
            asymptomatic_infectious_factor=asymptomatic_infectious_factor,
            mild_infectious_factor=mild_infectious_factor,
        )

    def update_infection_probability(self, time_from_infection: float):
        """Performs a probability update given time from infection

        Args:
            time_from_infection (float): time elapsed since person became infected

        """
        self.probability = self.norm * gamma_pdf(
            x=time_from_infection, a=self.shape, loc=self.shift, scale=self.scale
        )

    @property
    def time_at_maximum_infectivity(self) -> float:
        """Computes the time at which the individual is maximally infectious (in this case for
        a gamma distribution


        Returns:
            : time at maximal infectiousness

        """
        return (self.shape - 1) * self.scale + self.shift

    def _modify_infectiousness_for_symptoms(
        self,
        max_symptoms: str,
        asymptomatic_infectious_factor=None,
        mild_infectious_factor=None,
    ):
        """Lowers the infectiousness of asymptomatic and mild cases, by modifying
        the norm of the distribution

        Args:
            max_symptoms (str): maximum symptom severity the person will ever have
            asymptomatic_infectious_factor: factor to reduce the infectiousness of asymptomatic individuals (Default value = None)
            mild_infectious_factor: factor to reduce the infectiousness of mild individuals (Default value = None)

        """
        if (
            asymptomatic_infectious_factor is not None
            and max_symptoms == "asymptomatic"
        ):
            return asymptomatic_infectious_factor
        elif mild_infectious_factor is not None and max_symptoms == "mild":
            return mild_infectious_factor
        return 1.0

time_at_maximum_infectivity property

Computes the time at which the individual is maximally infectious (in this case for a gamma distribution

Returns:

Type Description
float

time at maximal infectiousness

__init__(max_infectiousness=1.0, shape=2.0, rate=3.0, shift=-2.0, max_symptoms=None, asymptomatic_infectious_factor=None, mild_infectious_factor=None)

Parameters

max_infectiousness: value of the infectiousness at its peak shape: shape parameter of the gamma distribution (a for scipy stats) rate: rate parameter of the gamma distribution (1/rate = scale for scipy stats) shift: location parameter of the gamma distribution max_symptoms: maximum symptoms the individual will develop, used to reduce the infectiousness of asymptomatic and mild individuals if wanted asymptomatic_infectious_factor: factor to reduce the infectiousness of asymptomatic individuals mild_infectious_factor: factor to reduce the infectiousness of mild individuals

Source code in june/epidemiology/infection/transmission.py
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
def __init__(
    self,
    max_infectiousness: float = 1.0,
    shape: float = 2.0,
    rate: float = 3.0,
    shift: float = -2.0,
    max_symptoms: Optional[str] = None,
    asymptomatic_infectious_factor: Optional[float] = None,
    mild_infectious_factor: Optional[float] = None,
):
    """
    Parameters
    ----------
    max_infectiousness:
        value of the infectiousness at its peak
    shape:
        shape parameter of the gamma distribution (a for scipy stats)
    rate:
        rate parameter of the gamma distribution (1/rate = scale for scipy stats)
    shift:
        location parameter of the gamma distribution
    max_symptoms:
        maximum symptoms the individual will develop, used to reduce the infectiousness
        of asymptomatic and mild individuals if wanted
    asymptomatic_infectious_factor:
        factor to reduce the infectiousness of asymptomatic individuals
    mild_infectious_factor:
        factor to reduce the infectiousness of mild individuals
    """
    self.shape = shape
    self.shift = shift
    self.scale = 1.0 / rate
    self.norm = max_infectiousness
    if (
        asymptomatic_infectious_factor is not None
        and mild_infectious_factor is not None
    ):
        self.norm *= self._modify_infectiousness_for_symptoms(
            max_symptoms=max_symptoms,
            asymptomatic_infectious_factor=asymptomatic_infectious_factor,
            mild_infectious_factor=mild_infectious_factor,
        )
    self.probability = 0.0

from_file(max_symptoms=None, config_path=default_gamma_config_path) classmethod

Generate transmission class reading parameters from config file

Parameters:

Name Type Description Default
max_symptoms str

maximum symptoms the individual will develop, used to reduce the infectiousness

None

of asymptomatic and mild individuals if wanted (Default value = None) config_path (str, optional): path to config parameters (Default value = default_gamma_config_path)

Source code in june/epidemiology/infection/transmission.py
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
@classmethod
def from_file(
    cls, max_symptoms: str = None, config_path: str = default_gamma_config_path
) -> "TransmissionGamma":
    """Generate transmission class reading parameters from config file

    Args:
        max_symptoms (str, optional): maximum symptoms the individual will develop, used to reduce the infectiousness
    of asymptomatic and mild individuals if wanted (Default value = None)
        config_path (str, optional): path to config parameters (Default value = default_gamma_config_path)

    """
    with open(config_path) as f:
        config = yaml.safe_load(f)
    max_infectiousness = CompletionTime.from_dict(config["max_infectiousness"])()
    shape = CompletionTime.from_dict(config["shape"])()
    rate = CompletionTime.from_dict(config["rate"])()
    shift = CompletionTime.from_dict(config["shift"])()
    asymptomatic_infectious_factor = CompletionTime.from_dict(
        config["asymptomatic_infectious_factor"]
    )()
    mild_infectious_factor = CompletionTime.from_dict(
        config["mild_infectious_factor"]
    )()

    return cls(
        max_infectiousness=max_infectiousness,
        shape=shape,
        rate=rate,
        shift=shift,
        max_symptoms=max_symptoms,
        asymptomatic_infectious_factor=asymptomatic_infectious_factor,
        mild_infectious_factor=mild_infectious_factor,
    )

from_file_linked_symptoms(time_to_symptoms_onset, max_symptoms=None, config_path=default_gamma_config_path) classmethod

Generate transmission class reading parameters from config file, linked to the time of symptoms onset

Parameters:

Name Type Description Default
time_to_symptoms_onset float

time (from infection) at which the person becomes symptomatic

required
max_symptoms str

maximum symptoms the individual will develop, used to reduce the infectiousness

None

of asymptomatic and mild individuals if wanted (Default value = None) config_path (str, optional): path to config parameters (Default value = default_gamma_config_path)

Source code in june/epidemiology/infection/transmission.py
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
@classmethod
def from_file_linked_symptoms(
    cls,
    time_to_symptoms_onset: float,
    max_symptoms: str = None,
    config_path: str = default_gamma_config_path,
) -> "TransmissionGamma":
    """Generate transmission class reading parameters from config file, linked to
    the time of symptoms onset

    Args:
        time_to_symptoms_onset (float): time (from infection) at which the person becomes symptomatic
        max_symptoms (str, optional): maximum symptoms the individual will develop, used to reduce the infectiousness
    of asymptomatic and mild individuals if wanted (Default value = None)
        config_path (str, optional): path to config parameters (Default value = default_gamma_config_path)

    """

    with open(config_path) as f:
        config = yaml.safe_load(f)
    max_infectiousness = CompletionTime.from_dict(config["max_infectiousness"])()
    shape = CompletionTime.from_dict(config["shape"])()
    rate = CompletionTime.from_dict(config["rate"])()
    shift = CompletionTime.from_dict(config["shift"])() + time_to_symptoms_onset
    asymptomatic_infectious_factor = CompletionTime.from_dict(
        config["asymptomatic_infectious_factor"]
    )()
    mild_infectious_factor = CompletionTime.from_dict(
        config["mild_infectious_factor"]
    )()

    return cls(
        max_infectiousness=max_infectiousness,
        shape=shape,
        rate=rate,
        shift=shift,
        max_symptoms=max_symptoms,
        asymptomatic_infectious_factor=asymptomatic_infectious_factor,
        mild_infectious_factor=mild_infectious_factor,
    )

update_infection_probability(time_from_infection)

Performs a probability update given time from infection

Parameters:

Name Type Description Default
time_from_infection float

time elapsed since person became infected

required
Source code in june/epidemiology/infection/transmission.py
240
241
242
243
244
245
246
247
248
249
def update_infection_probability(self, time_from_infection: float):
    """Performs a probability update given time from infection

    Args:
        time_from_infection (float): time elapsed since person became infected

    """
    self.probability = self.norm * gamma_pdf(
        x=time_from_infection, a=self.shape, loc=self.shift, scale=self.scale
    )

gamma_pdf(x, a, loc, scale)

Implementation of gamma PDF in numba

Parameters:

Name Type Description Default
x float

x variable

required
a float

shape factor

required
loc float

denominator in exponential

required
scale float
required
Source code in june/epidemiology/infection/transmission.py
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
@nb.jit(nopython=True)
def gamma_pdf(x: float, a: float, loc: float, scale: float) -> float:
    """Implementation of gamma PDF in numba

    Args:
        x (float): x variable
        a (float): shape factor
        loc (float): denominator in exponential
        scale (float): 

    """
    if x < loc:
        return 0.0
    return (
        1.0
        / gamma(a)
        * ((x - loc) / scale) ** (a - 1)
        * np.exp(-(x - loc) / scale)
        / scale
    )

gamma_pdf_vectorised(x, a, loc, scale)

Implementation of gamma PDF in numba

Parameters:

Name Type Description Default
x float

x variable

required
a float

shape factor

required
loc float

denominator in exponential

required
scale float
required
Source code in june/epidemiology/infection/transmission.py
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
@nb.jit(nopython=True)
def gamma_pdf_vectorised(x: float, a: float, loc: float, scale: float) -> float:
    """Implementation of gamma PDF in numba

    Args:
        x (float): x variable
        a (float): shape factor
        loc (float): denominator in exponential
        scale (float): 

    """
    return np.where(
        x < loc,
        0.0,
        1.0
        / gamma(a)
        * ((x - loc) / scale) ** (a - 1)
        * np.exp(-(x - loc) / scale)
        / scale,
    )