77 lines
2.9 KiB
Python
77 lines
2.9 KiB
Python
import numpy as np
|
|
import pytest
|
|
from retry import retry
|
|
|
|
import caimira.monte_carlo as mc
|
|
from caimira import models
|
|
from caimira.dataclass_utils import nested_replace
|
|
from caimira.apps.calculator import report_generator
|
|
from caimira.monte_carlo.data import activity_distributions, virus_distributions, expiration_distributions
|
|
|
|
|
|
@pytest.fixture
|
|
def baseline_exposure_model():
|
|
concentration_mc = mc.ConcentrationModel(
|
|
room=models.Room(volume=50, inside_temp=models.PiecewiseConstant((0., 24.), (298,)), humidity=0.5),
|
|
ventilation=models.MultipleVentilation(
|
|
ventilations=(
|
|
models.AirChange(active=models.PeriodicInterval(period=120, duration=120), air_exch=0.25),
|
|
)
|
|
),
|
|
infected=mc.InfectedPopulation(
|
|
number=1,
|
|
presence=mc.SpecificInterval(present_times=((0, 3.5), (4.5, 9))),
|
|
virus=virus_distributions['SARS_CoV_2_DELTA'],
|
|
mask=models.Mask.types['No mask'],
|
|
activity=activity_distributions['Seated'],
|
|
expiration=expiration_distributions['Breathing'],
|
|
host_immunity=0.,
|
|
),
|
|
evaporation_factor=0.3,
|
|
)
|
|
return mc.ExposureModel(
|
|
concentration_model=concentration_mc,
|
|
short_range=(),
|
|
exposed=mc.Population(
|
|
number=3,
|
|
presence=mc.SpecificInterval(present_times=((0, 3.5), (4.5, 9))),
|
|
activity=activity_distributions['Seated'],
|
|
mask=models.Mask.types['No mask'],
|
|
host_immunity=0.,
|
|
),
|
|
geographical_data=models.Cases(),
|
|
)
|
|
|
|
|
|
@retry(tries=2)
|
|
def test_conditional_prob_inf_given_vl_dist(baseline_exposure_model):
|
|
|
|
viral_loads = np.array([3., 5., 7., 9.,])
|
|
mc_model: models.ExposureModel = baseline_exposure_model.build_model(1_000_000)
|
|
|
|
expected_pi_means = []
|
|
expected_lower_percentiles = []
|
|
expected_upper_percentiles = []
|
|
|
|
for vl in viral_loads:
|
|
model_vl: models.ExposureModel = nested_replace(
|
|
mc_model, {
|
|
'concentration_model.infected.virus.viral_load_in_sputum' : 10**vl,
|
|
}
|
|
)
|
|
pi = model_vl.infection_probability()/100
|
|
|
|
expected_pi_means.append(np.mean(pi))
|
|
expected_lower_percentiles.append(np.quantile(pi, 0.05))
|
|
expected_upper_percentiles.append(np.quantile(pi, 0.95))
|
|
|
|
infection_probability = mc_model.infection_probability() / 100
|
|
specific_vl = np.log10(mc_model.concentration_model.infected.virus.viral_load_in_sputum)
|
|
step = 8/100
|
|
actual_pi_means, actual_lower_percentiles, actual_upper_percentiles = (
|
|
report_generator.conditional_prob_inf_given_vl_dist(infection_probability, viral_loads, specific_vl, step)
|
|
)
|
|
|
|
assert np.allclose(actual_pi_means, expected_pi_means, atol=0.001)
|
|
assert np.allclose(actual_lower_percentiles, expected_lower_percentiles, atol=0.001)
|
|
assert np.allclose(actual_upper_percentiles, expected_upper_percentiles, atol=0.001)
|