diff --git a/cara/models.py b/cara/models.py index cf2ffb8f..794ed21b 100644 --- a/cara/models.py +++ b/cara/models.py @@ -616,7 +616,10 @@ _ExpirationBase.types = { @dataclass(frozen=True) class Activity: + #: Inhalation rate in m^3/h inhalation_rate: _VectorisedFloat + + #: Exhalation rate in m^3/h exhalation_rate: _VectorisedFloat #: Pre-populated examples of activities. @@ -671,6 +674,8 @@ class InfectedPopulation(Population): """ # Emission Rate (infectious quantum / h) + # Note on units: exhalation rate is in m^3/h, aerosols in mL/cm^3 + # and viral load in virus/mL -> 1e6 conversion factor aerosols = self.expiration.aerosols(self.mask) ER = (self.virus.viral_load_in_sputum * @@ -855,6 +860,9 @@ class ExposureModel: #: The number of times the exposure event is repeated (default 1). repeats: int = 1 + #: The fraction of viruses actually deposited in the respiratory tract + fraction_deposited: _VectorisedFloat = 0.6 + def quanta_exposure(self) -> _VectorisedFloat: """The number of virus quanta per meter^3.""" exposure = 0.0 @@ -870,7 +878,7 @@ class ExposureModel: inf_aero = ( self.exposed.activity.inhalation_rate * (1 - self.exposed.mask.inhale_efficiency()) * - exposure + exposure * self.fraction_deposited ) # Probability of infection. diff --git a/cara/tests/conftest.py b/cara/tests/conftest.py index 44b25423..023e4e5a 100644 --- a/cara/tests/conftest.py +++ b/cara/tests/conftest.py @@ -32,5 +32,6 @@ def baseline_exposure_model(baseline_model): presence=baseline_model.infected.presence, activity=baseline_model.infected.activity, mask=baseline_model.infected.mask, - ) + ), + fraction_deposited = 1., ) diff --git a/cara/tests/models/test_exposure_model.py b/cara/tests/models/test_exposure_model.py index 009cf092..35c5ac0c 100644 --- a/cara/tests/models/test_exposure_model.py +++ b/cara/tests/models/test_exposure_model.py @@ -55,22 +55,25 @@ populations = [ @pytest.mark.parametrize( - "population, cm, expected_exposure, expected_probability",[ - [populations[1], KnownConcentrations(lambda t: 1.2), + "population, cm, f_dep, expected_exposure, expected_probability",[ + [populations[1], KnownConcentrations(lambda t: 1.2), 1., np.array([14.4, 14.4]), np.array([99.6803184113, 99.5181053773])], - [populations[2], KnownConcentrations(lambda t: 1.2), + [populations[2], KnownConcentrations(lambda t: 1.2), 1., np.array([14.4, 14.4]), np.array([97.4574432074, 98.3493482895])], - [populations[0], KnownConcentrations(lambda t: np.array([1.2, 2.4])), + [populations[0], KnownConcentrations(lambda t: np.array([1.2, 2.4])), 1., np.array([14.4, 28.8]), np.array([98.3493482895, 99.9727534893])], - [populations[1], KnownConcentrations(lambda t: np.array([1.2, 2.4])), + [populations[1], KnownConcentrations(lambda t: np.array([1.2, 2.4])), 1., np.array([14.4, 28.8]), np.array([99.6803184113, 99.9976777757])], + + [populations[0], KnownConcentrations(lambda t: 2.4), np.array([0.5, 1.]), + 28.8, np.array([98.3493482895, 99.9727534893])], ]) -def test_exposure_model_ndarray(population, cm, +def test_exposure_model_ndarray(population, cm, f_dep, expected_exposure, expected_probability): - model = ExposureModel(cm, population) + model = ExposureModel(cm, population, fraction_deposited = f_dep) np.testing.assert_almost_equal( model.quanta_exposure(), expected_exposure ) @@ -148,5 +151,5 @@ def test_exposure_model_integral_accuracy(exposed_time_interval, 10, presence_interval, models.Mask.types['Type I'], models.Activity.types['Standing'], ) - model = ExposureModel(conc_model, population) + model = ExposureModel(conc_model, population, fraction_deposited=1.) np.testing.assert_allclose(model.quanta_exposure(), expected_quanta) diff --git a/cara/tests/test_known_quantities.py b/cara/tests/test_known_quantities.py index a3b1e5db..4af1c06f 100644 --- a/cara/tests/test_known_quantities.py +++ b/cara/tests/test_known_quantities.py @@ -349,7 +349,8 @@ def build_exposure_model(concentration_model): presence=infected.presence, activity=infected.activity, mask=infected.mask, - ) + ), + fraction_deposited = 1., )