From f0bdda7c7d991e35ad705c424b1ae68cca7728c1 Mon Sep 17 00:00:00 2001 From: Nicolas Mounet Date: Tue, 26 Apr 2022 11:19:33 +0200 Subject: [PATCH] Adding mask inhale efficiency factor to short-range exposure; adding corresponding test; some cosmetics in test_short_range_model.py --- cara/models.py | 2 +- cara/tests/models/test_short_range_model.py | 58 ++++++++++++++++++--- 2 files changed, 51 insertions(+), 9 deletions(-) diff --git a/cara/models.py b/cara/models.py index 9d7898fd..c6df3464 100644 --- a/cara/models.py +++ b/cara/models.py @@ -1377,7 +1377,7 @@ class ExposureModel: f_inf = self.concentration_model.infected.fraction_of_infectious_virus() deposited_exposure *= (f_inf * self.concentration_model.virus.viral_load_in_sputum - ) + * (1 - self.exposed.mask.inhale_efficiency())) # long-range concentration deposited_exposure += self.long_range_deposited_exposure_between_bounds(time1, time2) diff --git a/cara/tests/models/test_short_range_model.py b/cara/tests/models/test_short_range_model.py index b1dee050..ceef0bb2 100644 --- a/cara/tests/models/test_short_range_model.py +++ b/cara/tests/models/test_short_range_model.py @@ -6,10 +6,13 @@ import pytest from cara import models import cara.monte_carlo as mc_models from cara.apps.calculator.model_generator import build_expiration -from cara.monte_carlo.data import short_range_expiration_distributions, short_range_distances, activity_distributions +from cara.monte_carlo.data import short_range_expiration_distributions,\ + expiration_distributions, short_range_distances, activity_distributions # TODO: seed better the random number generators np.random.seed(2000) +SAMPLE_SIZE = 250_000 + @pytest.fixture def concentration_model() -> mc_models.ConcentrationModel: @@ -41,8 +44,8 @@ def short_range_model(): def test_short_range_model_ndarray(concentration_model, short_range_model): - concentration_model = concentration_model.build_model(250_000) - model = short_range_model.build_model(250_000) + concentration_model = concentration_model.build_model(SAMPLE_SIZE) + model = short_range_model.build_model(SAMPLE_SIZE) assert isinstance(model._normed_concentration(concentration_model, 10.75), np.ndarray) assert isinstance(model.short_range_concentration(concentration_model, 10.75), np.ndarray) assert isinstance(model._normed_jet_exposure_between_bounds(concentration_model, 10.75, 10.85), np.ndarray) @@ -60,10 +63,10 @@ def test_short_range_model_ndarray(concentration_model, short_range_model): ] ) def test_dilution_factor(activity, expected_dilution): - model = models.ShortRangeModel(expiration="Breathing", + model = mc_models.ShortRangeModel(expiration=short_range_expiration_distributions['Breathing'], activity=models.Activity.types[activity], presence=models.SpecificInterval(present_times=((10.5, 11.0),)), - distance=0.854) + distance=0.854).build_model(SAMPLE_SIZE) assert isinstance(model.dilution_factor(), np.ndarray) np.testing.assert_almost_equal( model.dilution_factor(), expected_dilution, decimal=10 @@ -105,11 +108,50 @@ def test_extract_between_bounds(short_range_model, time1, time2, [12.0, 0.], ] ) -def test_short_range_concentration(time, expected_short_range_concentration, concentration_model, short_range_model): - concentration_model = concentration_model.build_model(250_000) - model = short_range_model.build_model(250_000) +def test_short_range_concentration(time, expected_short_range_concentration, + concentration_model, short_range_model): + concentration_model = concentration_model.build_model(SAMPLE_SIZE) + model = short_range_model.build_model(SAMPLE_SIZE) np.testing.assert_allclose( np.array(model.short_range_concentration(concentration_model, time)).mean(), expected_short_range_concentration, rtol=0.02 ) + +def test_short_range_exposure_with_ndarray_mask(): + c_model = mc_models.ConcentrationModel( + room=models.Room(volume=50, humidity=0.3), + ventilation=models.AirChange(active=models.PeriodicInterval(period=120, duration=120), + air_exch=10_000_000,), + infected=mc_models.InfectedPopulation( + number=1, + presence=models.SpecificInterval(present_times=((8.5, 12.5), (13.5, 17.5))), + virus=models.Virus.types['SARS_CoV_2_DELTA'], + mask=models.Mask.types['No mask'], + activity=models.Activity.types['Seated'], + expiration=expiration_distributions['Breathing'], + host_immunity=0., + ), + evaporation_factor=0.3, + ) + sr_model = mc_models.ShortRangeModel(expiration=short_range_expiration_distributions['Shouting'], + activity=models.Activity.types['Heavy exercise'], + presence=models.SpecificInterval(present_times=((10.5, 11.0),)), + distance=0.854) + e_model = mc_models.ExposureModel( + concentration_model = c_model, + short_range = (sr_model,), + exposed = mc_models.Population( + number=1, + presence=models.SpecificInterval(present_times=((8.5, 12.5), (13.5, 17.5))), + mask=models.Mask(η_inhale=np.array([0., 0.3, 0.5])), + activity=models.Activity.types['Light activity'], + host_immunity=0., + ), + ).build_model(SAMPLE_SIZE) + assert isinstance(e_model.deposited_exposure(), np.ndarray) + assert len(e_model.deposited_exposure()) == 3 + np.testing.assert_allclose(e_model.deposited_exposure(), + e_model.deposited_exposure()[0]*np.array([1., 0.7, 0.5]), + rtol=1e-8) +