adapted post_init method for diameter-independent elements of the IVRR

This commit is contained in:
Luis Aleixo 2022-10-19 17:55:18 +02:00
parent 5a6f4d54a1
commit 24ef358571
2 changed files with 22 additions and 45 deletions

View file

@ -1331,38 +1331,16 @@ class ExposureModel:
The infection probability formula assumes that if the diameter The infection probability formula assumes that if the diameter
is an array, then none of the ventilation parameters, room volume or virus is an array, then none of the ventilation parameters, room volume or virus
decay constant, are arrays as well. decay constant, are arrays as well.
The IVRR is the unique term in the exponential of the concentration formula, therefore
there is a check for the diameter-independent elements of the infectious_virus_removal_rate method.
""" """
def verify_ventilation(vent: Ventilation):
# Check if any of the ventilation parameters is an array instance.
# Note that most of the ventilation parameters are part of the WindowOpening class (inheritance).
if (isinstance(vent, WindowOpening) and (
not all(np.isscalar(value) for value in vent.outside_temp.values) or
not np.isscalar(vent.window_height) or
not np.isscalar(vent.opening_length) or
(isinstance(vent, HingedWindow) and not np.isscalar(vent.window_width)))):
raise ValueError("Ventilation parameters and diameter cannot be arrays at the same time.")
# The q_air_mech parameter is only part of the HEPAFilter class, and
# the air_exch parameter is only part of the AirChange class.
if (isinstance(vent, HEPAFilter) and not np.isscalar(vent.q_air_mech) or
isinstance(vent, AirChange) and not np.isscalar(vent.air_exch)):
raise ValueError("Ventilation rate and diameter cannot be arrays at the same time.")
infected_population = self.concentration_model.infected infected_population = self.concentration_model.infected
if (isinstance(infected_population, InfectedPopulation) if isinstance(infected_population, InfectedPopulation) and not np.isscalar(infected_population.expiration.diameter) and not (
and not np.isscalar(infected_population.expiration.diameter)): all(np.isscalar(self.concentration_model.virus.decay_constant(self.concentration_model.room.humidity, self.concentration_model.room.inside_temp.value(time)) +
# Verify if the ventilation is initialized as MultipleVentilation. self.concentration_model.ventilation.air_exchange(self.concentration_model.room, time)) for time in self.concentration_model.state_change_times())):
if isinstance(self.concentration_model.ventilation, MultipleVentilation): raise ValueError("If the diameter is an array, none of the ventilation parameters, room volume or virus decay constant can be arrays at the same time.")
for vent in self.concentration_model.ventilation.ventilations:
verify_ventilation(vent)
else:
verify_ventilation(self.concentration_model.ventilation)
# Check if the room volume is an array instance.
if not np.isscalar(self.concentration_model.room.volume):
raise ValueError("Room volume and diameter cannot be arrays at the same time.")
# Virus decay constant depends on the room humidity and inside_temp parameters.
if (not all(np.isscalar(value) for value in self.concentration_model.room.inside_temp.values) or
not np.isscalar(self.concentration_model.room.humidity)):
raise ValueError("Virus decay constant and diameter cannot be arrays at the same time.")
def long_range_fraction_deposited(self) -> _VectorisedFloat: def long_range_fraction_deposited(self) -> _VectorisedFloat:
""" """

View file

@ -323,12 +323,12 @@ def test_probabilistic_exposure_probability(exposed_population, cm,
def test_diameter_vectorisation_window_opening(diameter_dependent_model, sr_model, active, outside_temp, def test_diameter_vectorisation_window_opening(diameter_dependent_model, sr_model, active, outside_temp,
window_height, opening_length, cases_model): window_height, opening_length, cases_model):
concentration = replace(diameter_dependent_model, concentration = replace(diameter_dependent_model,
ventilation=models.WindowOpening(active=active, ventilation=models.SlidingWindow(active=active,
outside_temp=outside_temp, outside_temp=outside_temp,
window_height=window_height, window_height=window_height,
opening_length=opening_length) opening_length=opening_length)
) )
with pytest.raises(ValueError, match="Ventilation parameters and diameter cannot be arrays at the same time."): with pytest.raises(ValueError, match="If the diameter is an array, none of the ventilation parameters, room volume or virus decay constant can be arrays at the same time."):
models.ExposureModel(concentration, sr_model, populations[0], cases_model) models.ExposureModel(concentration, sr_model, populations[0], cases_model)
@ -341,7 +341,7 @@ def test_diameter_vectorisation_hinged_window(diameter_dependent_model, sr_model
opening_length=1., opening_length=1.,
window_width=np.array([1., 0.5])) window_width=np.array([1., 0.5]))
) )
with pytest.raises(ValueError, match="Ventilation parameters and diameter cannot be arrays at the same time."): with pytest.raises(ValueError, match="If the diameter is an array, none of the ventilation parameters, room volume or virus decay constant can be arrays at the same time."):
models.ExposureModel(concentration, sr_model, populations[0], cases_model) models.ExposureModel(concentration, sr_model, populations[0], cases_model)
@ -350,7 +350,7 @@ def test_diameter_vectorisation_HEPA_filter(diameter_dependent_model, sr_model,
concentration = replace(diameter_dependent_model, concentration = replace(diameter_dependent_model,
ventilation = models.HEPAFilter(active=models.PeriodicInterval(period=120, duration=120), q_air_mech=np.array([0.5, 1.])) ventilation = models.HEPAFilter(active=models.PeriodicInterval(period=120, duration=120), q_air_mech=np.array([0.5, 1.]))
) )
with pytest.raises(ValueError, match="Ventilation rate and diameter cannot be arrays at the same time."): with pytest.raises(ValueError, match="If the diameter is an array, none of the ventilation parameters, room volume or virus decay constant can be arrays at the same time."):
models.ExposureModel(concentration, sr_model, populations[1], cases_model) models.ExposureModel(concentration, sr_model, populations[1], cases_model)
@ -359,23 +359,22 @@ def test_diameter_vectorisation_air_change(diameter_dependent_model, sr_model, c
concentration = replace(diameter_dependent_model, concentration = replace(diameter_dependent_model,
ventilation = models.AirChange(active=models.PeriodicInterval(period=120, duration=120), air_exch=np.array([0.5, 1.])) ventilation = models.AirChange(active=models.PeriodicInterval(period=120, duration=120), air_exch=np.array([0.5, 1.]))
) )
with pytest.raises(ValueError, match="Ventilation rate and diameter cannot be arrays at the same time."): with pytest.raises(ValueError, match="If the diameter is an array, none of the ventilation parameters, room volume or virus decay constant can be arrays at the same time."):
models.ExposureModel(concentration, sr_model, populations[2], cases_model) models.ExposureModel(concentration, sr_model, populations[2], cases_model)
@pytest.mark.parametrize( @pytest.mark.parametrize(
"volume, inside_temp, humidity, error", [ "inside_temp, humidity, error_message", [
[np.array([50, 100]), models.PiecewiseConstant((0., 24.), (293,)), 0.3, [models.PiecewiseConstant((0., 24.), (np.array([293., 300.]),)), 0.3,
"Room volume and diameter cannot be arrays at the same time."], # Verify room volume vectorisation "If the diameter is an array, none of the ventilation parameters, room volume or virus decay constant can be arrays at the same time."], # Verify room inside_temp vectorisation
[50, models.PiecewiseConstant((0., 24.), (np.array([293., 300.]),)), 0.3, [models.PiecewiseConstant((0., 24.), (293.,)), np.array([0.3, 0.5]),
"Virus decay constant and diameter cannot be arrays at the same time."], # Verify room inside_temp vectorisation "If the diameter is an array, none of the ventilation parameters, room volume or virus decay constant can be arrays at the same time."], # Verify room humidity vectorisation
[50, models.PiecewiseConstant((0., 24.), (293.,)), np.array([0.3, 0.5]),
"Virus decay constant and diameter cannot be arrays at the same time."], # Verify room humidity vectorisation
] ]
) )
def test_diameter_vectorisation_room(diameter_dependent_model, sr_model, cases_model, volume, inside_temp, humidity, error): def test_diameter_vectorisation_room(diameter_dependent_model, sr_model, cases_model, inside_temp, humidity, error_message):
concentration = replace(diameter_dependent_model, concentration = replace(diameter_dependent_model,
room = models.Room(volume=volume, inside_temp=inside_temp, humidity=humidity)) room = models.Room(volume=50, inside_temp=inside_temp, humidity=humidity))
with pytest.raises(ValueError, match=error): # The vectorised volume is not considered in the air_exchange method for the AirChange class.
with pytest.raises(ValueError, match=error_message):
models.ExposureModel(concentration, sr_model, populations[0], cases_model) models.ExposureModel(concentration, sr_model, populations[0], cases_model)