From f7bce0ef2414197afb3b27368a4bf69e8933dab2 Mon Sep 17 00:00:00 2001 From: Luis Aleixo Date: Mon, 1 Aug 2022 09:42:44 +0200 Subject: [PATCH] added verification for diameter independent parameters --- caimira/models.py | 39 +++++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/caimira/models.py b/caimira/models.py index 4a96be97..738ffa6a 100644 --- a/caimira/models.py +++ b/caimira/models.py @@ -1310,10 +1310,6 @@ class ShortRangeModel: class ExposureModel: """ Represents the exposure to a concentration of virions in the air. - NOTE: the infection probability formula assumes that if the diameter - is an array, then none of the ventilation parameters, room volume or virus - decay constant, are arrays as well. - TODO: implement a check this is the case, in __post_init__ """ #: The virus concentration model which this exposure model should consider. concentration_model: ConcentrationModel @@ -1330,6 +1326,41 @@ class ExposureModel: #: The number of times the exposure event is repeated (default 1). repeats: int = 1 + def __post_init__(self): + """ + The infection probability formula assumes that if the diameter + is an array, then none of the ventilation parameters, room volume or virus + decay constant, are arrays as well. + """ + infected_population = self.concentration_model.infected + if (isinstance(infected_population, InfectedPopulation) + and not np.isscalar(infected_population.expiration.particle.diameter)): + # Due to the infiltration ventilation (0.25ACH), the ventilation is initialized as MultipleVentilation. + if isinstance(self.concentration_model.ventilation, MultipleVentilation): + for vent in self.concentration_model.ventilation.ventilations: + # 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 + (isinstance(vent, HingedWindow) and not np.isscalar(vent.window_width)))): + raise ValueError("Ventilation parameter(s) and diameter cannot be arrays at the same time.") + # The window_width parameter is only part of the HingedWindow class. + if ((isinstance(vent, HingedWindow)) and not np.isscalar(vent.window_width)): + raise ValueError("Ventilation parameter(s) 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.") + # 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: """ The fraction of particles actually deposited in the respiratory