added logic behing ER and concentration (model)

This commit is contained in:
Luis Aleixo 2021-08-03 13:45:14 +02:00
parent 0935056df2
commit f6340d7986
6 changed files with 38 additions and 39 deletions

View file

@ -685,15 +685,14 @@ class InfectedPopulation(Population):
ER = (self.virus.viral_load_in_sputum *
self.activity.exhalation_rate *
10 ** 6 *
aerosols /
self.virus.infectious_dose)
aerosols)
# For superspreading event, where ejection_factor is infinite we fix the ER
# based on Miller et al. (2020).
if isinstance(aerosols, np.ndarray):
ER[np.isinf(aerosols)] = 970
ER[np.isinf(aerosols)] = 970 * self.virus.infectious_dose
elif np.isinf(aerosols):
ER = 970
ER = 970 * self.virus.infectious_dose
return ER
@ -867,7 +866,7 @@ class ExposureModel:
#: The fraction of viruses actually deposited in the respiratory tract
fraction_deposited: _VectorisedFloat = 0.6
def quanta_exposure(self) -> _VectorisedFloat:
def exposure(self) -> _VectorisedFloat:
"""The number of virus quanta per meter^3."""
exposure = 0.0
@ -877,7 +876,7 @@ class ExposureModel:
return exposure * self.repeats
def infection_probability(self) -> _VectorisedFloat:
exposure = self.quanta_exposure()
exposure = self.exposure()
inf_aero = (
self.exposed.activity.inhalation_rate *
@ -886,7 +885,7 @@ class ExposureModel:
)
# Probability of infection.
return (1 - np.exp(-inf_aero)) * 100
return (1 - np.exp(-(inf_aero/self.concentration_model.virus.infectious_dose))) * 100
def expected_new_cases(self) -> _VectorisedFloat:
prob = self.infection_probability()

View file

@ -75,7 +75,7 @@ def test_exposure_model_ndarray(population, cm, f_dep,
expected_exposure, expected_probability):
model = ExposureModel(cm, population, fraction_deposited = f_dep)
np.testing.assert_almost_equal(
model.quanta_exposure(), expected_exposure
model.exposure(), expected_exposure
)
np.testing.assert_almost_equal(
model.infection_probability(), expected_probability, decimal=10
@ -94,7 +94,7 @@ def test_exposure_model_ndarray_and_float_mix(population):
expected_exposure = np.array([14.4, 14.4])
np.testing.assert_almost_equal(
model.quanta_exposure(), expected_exposure
model.exposure(), expected_exposure
)
assert isinstance(model.infection_probability(), np.ndarray)
@ -109,10 +109,10 @@ def test_exposure_model_compare_scalar_vector(population):
model_array = ExposureModel(cm_array, population)
expected_exposure = 14.4
np.testing.assert_almost_equal(
model_scalar.quanta_exposure(), expected_exposure
model_scalar.exposure(), expected_exposure
)
np.testing.assert_almost_equal(
model_array.quanta_exposure(), np.array([expected_exposure]*2)
model_array.exposure(), np.array([expected_exposure]*2)
)
@ -152,4 +152,4 @@ def test_exposure_model_integral_accuracy(exposed_time_interval,
models.Activity.types['Standing'],
)
model = ExposureModel(conc_model, population, fraction_deposited=1.)
np.testing.assert_allclose(model.quanta_exposure(), expected_quanta)
np.testing.assert_allclose(model.exposure(), expected_quanta)

View file

@ -14,7 +14,7 @@ import cara.models
def test_infected_population_vectorisation(override_params):
defaults = {
'viral_load_in_sputum': 1e9,
'infectious_dose': 50,
'quantum_infectious_dose': 50,
'exhalation_rate': 0.75,
}
defaults.update(override_params)
@ -33,7 +33,7 @@ def test_infected_population_vectorisation(override_params):
),
virus=cara.models.Virus(
viral_load_in_sputum=defaults['viral_load_in_sputum'],
infectious_dose=defaults['infectious_dose'],
infectious_dose=defaults['quantum_infectious_dose'],
),
expiration=cara.models.Expiration((1., 0., 0.)),
)

View file

@ -7,7 +7,7 @@ import cara.data as data
def test_no_mask_superspeading_emission_rate(baseline_model):
expected_rate = 970.
expected_rate = 48500.
npt.assert_allclose(
[baseline_model.infected.emission_rate(t) for t in [0, 1, 4, 4.5, 5, 8, 9]],
[0, expected_rate, expected_rate, 0, 0, expected_rate, 0],
@ -44,7 +44,7 @@ def test_concentrations(baseline_model):
concentrations = [baseline_model.concentration(t) for t in ts]
npt.assert_allclose(
concentrations,
[0.000000e+00, 0.41611256, 1.3205628e-14, 0.41611256, 4.1909001e-28],
[0.000000e+00, 20.805628, 6.602814e-13, 20.805628, 2.09545e-26],
rtol=1e-6
)
@ -354,16 +354,16 @@ def build_exposure_model(concentration_model):
)
# expected quanta were computed with a trapezoidal integration, using
# expected exposure were computed with a trapezoidal integration, using
# a mesh of 100'000 pts per exposed presence interval.
@pytest.mark.parametrize(
"month, expected_quanta",
"month, expected_exposure",
[
['Jan', 9.930854],
['Jun', 37.962708],
['Jan', 496.5427],
['Jun', 1898.1354],
],
)
def test_quanta_hourly_dep(month,expected_quanta):
def test_exposure_hourly_dep(month,expected_exposure):
m = build_exposure_model(
build_hourly_dependent_model(
month,
@ -371,20 +371,20 @@ def test_quanta_hourly_dep(month,expected_quanta):
intervals_presence_infected=((8, 12), (13, 17))
)
)
quanta = m.quanta_exposure()
npt.assert_allclose(quanta, expected_quanta)
exposure = m.exposure()
npt.assert_allclose(exposure, expected_exposure)
# expected quanta were computed with a trapezoidal integration, using
# expected exposure were computed with a trapezoidal integration, using
# a mesh of 100'000 pts per exposed presence interval and 25 pts per hour
# for the temperature discretization.
@pytest.mark.parametrize(
"month, expected_quanta",
"month, expected_exposure",
[
['Jan', 9.993842],
['Jun', 40.151985],
['Jan', 499.6921],
['Jun', 2007.59925],
],
)
def test_quanta_hourly_dep_refined(month,expected_quanta):
def test_exposure_hourly_dep_refined(month,expected_exposure):
m = build_exposure_model(
build_hourly_dependent_model(
month,
@ -393,5 +393,5 @@ def test_quanta_hourly_dep_refined(month,expected_quanta):
temperatures=data.GenevaTemperatures,
)
)
quanta = m.quanta_exposure()
npt.assert_allclose(quanta, expected_quanta, rtol=0.02)
exposure = m.exposure()
npt.assert_allclose(exposure, expected_exposure, rtol=0.02)

View file

@ -84,6 +84,6 @@ def test_build_concentration_model(baseline_mc_model: cara.monte_carlo.Concentra
def test_build_exposure_model(baseline_mc_exposure_model: cara.monte_carlo.ExposureModel):
model = baseline_mc_exposure_model.build_model(7)
assert isinstance(model, cara.models.ExposureModel)
prob = model.quanta_exposure()
prob = model.exposure()
assert isinstance(prob, np.ndarray)
assert prob.shape == (7, )

View file

@ -233,7 +233,7 @@ def skagit_chorale_mc():
@pytest.mark.parametrize(
"mc_model, expected_pi, expected_new_cases, expected_dose, expected_qR",
"mc_model, expected_pi, expected_new_cases, expected_dose, expected_ER",
[
["shared_office_mc", 10.7, 0.32, 0.954, 10.9],
["classroom_mc", 36.1, 6.85, 13.0, 474.4],
@ -244,22 +244,22 @@ def skagit_chorale_mc():
]
)
def test_report_models(mc_model, expected_pi, expected_new_cases,
expected_dose, expected_qR, request):
expected_dose, expected_ER, request):
mc_model = request.getfixturevalue(mc_model)
exposure_model = mc_model.build_model(size=SAMPLE_SIZE)
npt.assert_allclose(exposure_model.infection_probability().mean(),
expected_pi, rtol=TOLERANCE)
npt.assert_allclose(exposure_model.expected_new_cases().mean(),
expected_new_cases, rtol=TOLERANCE)
npt.assert_allclose(exposure_model.quanta_exposure().mean(),
npt.assert_allclose(exposure_model.exposure().mean(),
expected_dose, rtol=TOLERANCE)
npt.assert_allclose(
exposure_model.concentration_model.infected.emission_rate_when_present().mean(),
expected_qR, rtol=TOLERANCE)
expected_ER, rtol=TOLERANCE)
@pytest.mark.parametrize(
"mask_type, month, expected_pi, expected_dose, expected_qR",
"mask_type, month, expected_pi, expected_dose, expected_ER",
[
["No mask", "Jul", 30.0, 6.764, 64.9],
["Type I", "Jul", 10.2, 1.223, 11.7],
@ -268,7 +268,7 @@ def test_report_models(mc_model, expected_pi, expected_new_cases,
],
)
def test_small_shared_office_Geneva(mask_type, month, expected_pi,
expected_dose, expected_qR):
expected_dose, expected_ER):
concentration_mc = mc.ConcentrationModel(
room=models.Room(volume=33, humidity=0.5),
ventilation=models.MultipleVentilation(
@ -309,8 +309,8 @@ def test_small_shared_office_Geneva(mask_type, month, expected_pi,
exposure_model = exposure_mc.build_model(size=SAMPLE_SIZE)
npt.assert_allclose(exposure_model.infection_probability().mean(),
expected_pi, rtol=TOLERANCE)
npt.assert_allclose(exposure_model.quanta_exposure().mean(),
npt.assert_allclose(exposure_model.exposure().mean(),
expected_dose, rtol=TOLERANCE)
npt.assert_allclose(
exposure_model.concentration_model.infected.emission_rate_when_present().mean(),
expected_qR, rtol=TOLERANCE)
expected_ER, rtol=TOLERANCE)