From 722278b154f6930e00b3bb5a76eb4b63eada500d Mon Sep 17 00:00:00 2001 From: Luis Aleixo Date: Mon, 24 Jan 2022 15:01:16 +0100 Subject: [PATCH] Corrected typing types and fixed tests --- cara/apps/calculator/model_generator.py | 14 ++++++-------- cara/apps/calculator/report_generator.py | 8 ++++---- cara/apps/expert.py | 5 ++--- cara/models.py | 16 ++++++++-------- cara/tests/conftest.py | 2 ++ cara/tests/models/test_concentration_model.py | 4 ++++ cara/tests/models/test_exposure_model.py | 6 ++++++ cara/tests/test_infected_population.py | 2 ++ cara/tests/test_known_quantities.py | 8 ++++++++ cara/tests/test_monte_carlo.py | 2 ++ cara/tests/test_monte_carlo_full_models.py | 16 ++++++++++++++++ 11 files changed, 60 insertions(+), 23 deletions(-) diff --git a/cara/apps/calculator/model_generator.py b/cara/apps/calculator/model_generator.py index 4ded107d..9de11436 100644 --- a/cara/apps/calculator/model_generator.py +++ b/cara/apps/calculator/model_generator.py @@ -78,7 +78,7 @@ class FormData: window_width: float windows_number: int window_opening_regime: str - short_range_option: str + short_range_option: bool short_range_interactions: list #: The default values for undefined fields. Note that the defaults here @@ -132,7 +132,7 @@ class FormData: 'windows_number': 0, 'window_opening_regime': 'windows_open_permanently', 'short_range_option': False, - 'short_range_interactions': [], + 'short_range_interactions': '[]', } @classmethod @@ -422,12 +422,12 @@ class FormData: number=infected_occupants, virus=virus, presence=self.infected_present_interval(), - short_range_presence=self.short_range_intervals(), - short_range_activities=self.short_range_activities(), mask=self.mask(), activity=activity, expiration=expiration, host_immunity=0., + short_range_presence=self.short_range_intervals(), + short_range_activities=self.short_range_activities(), ) return infected @@ -456,7 +456,6 @@ class FormData: exposed = mc.Population( number=exposed_occupants, presence=self.exposed_present_interval(), - short_range_presence=self.short_range_interactions, activity=activity, mask=self.mask(), host_immunity=0., @@ -632,14 +631,13 @@ class FormData: breaks=self.infected_lunch_break_times() + self.infected_coffee_break_times(), ) - def short_range_intervals(self) -> models.Interval: + def short_range_intervals(self) -> typing.List[models.SpecificInterval]: if (self.short_range_interactions): short_range_intervals = [] for interaction in self.short_range_interactions: start_time = time_string_to_minutes(interaction['start_time']) duration = float(interaction['duration']) short_range_intervals.append(models.SpecificInterval((start_time/60, (start_time + duration)/60))) - return short_range_intervals else: return [] @@ -650,7 +648,7 @@ class FormData: breaks=self.exposed_lunch_break_times() + self.exposed_coffee_break_times(), ) - def short_range_activities(self): + def short_range_activities(self) -> typing.List[str]: if (self.short_range_interactions): return [interaction['activity'] for interaction in self.short_range_interactions] else: diff --git a/cara/apps/calculator/report_generator.py b/cara/apps/calculator/report_generator.py index ec8230c2..7a11c1b0 100644 --- a/cara/apps/calculator/report_generator.py +++ b/cara/apps/calculator/report_generator.py @@ -98,14 +98,14 @@ def interesting_times(model: models.ExposureModel, approx_n_pts=100) -> typing.L def short_range_interesting_times(model: models.ExposureModel, times: typing.List[float]) -> typing.List[float]: - short_range_times = [] + short_range_times : typing.List[float] = [] for period in model.concentration_model.infected.short_range_presence: - start, finish = period.boundaries() + start, finish = tuple(period.boundaries()) short_range_times = short_range_times + [time for time in times if time > start and time < finish] return short_range_times -def jet_origin_concentrations(model: models.ExposureModel) -> models._ExpirationBase: +def jet_origin_concentrations(model: models.ExposureModel) -> typing.List[float]: return [initial_concentrations_mouth[activity] for activity in model.concentration_model.infected.short_range_activities] @@ -113,7 +113,7 @@ def short_range_initial_concentrations(model: models.ExposureModel, time: float) dilution = dilution_factor(np.linspace(0.1, 2., 1000)) jet_origin_initial_concentrations = jet_origin_concentrations(model) for index, interaction in enumerate(model.concentration_model.infected.short_range_presence): - start, finish = interaction.boundaries() + start, finish = tuple(interaction.boundaries()) if start <= time <= finish: expiration = build_expiration(model.concentration_model.infected.short_range_activities[index]) single_exposure_model = dataclass_utils.nested_replace( diff --git a/cara/apps/expert.py b/cara/apps/expert.py index e779558a..8198f2d1 100644 --- a/cara/apps/expert.py +++ b/cara/apps/expert.py @@ -496,19 +496,18 @@ baseline_model = models.ExposureModel( number=1, virus=models.Virus.types['SARS_CoV_2'], presence=models.SpecificInterval(((8., 12.), (13., 17.))), - short_range_presence=[], - short_range_activities=[], mask=models.Mask.types['No mask'], activity=models.Activity.types['Seated'], expiration=models.Expiration.types['Speaking'], host_immunity=0., + short_range_presence=[], + short_range_activities=[], ), evaporation_factor=0.3, ), exposed=models.Population( number=10, presence=models.SpecificInterval(((8., 12.), (13., 17.))), - short_range_presence=[], activity=models.Activity.types['Seated'], mask=models.Mask.types['No mask'], host_immunity=0., diff --git a/cara/models.py b/cara/models.py index 3092a6ea..b8f0e4a2 100644 --- a/cara/models.py +++ b/cara/models.py @@ -32,7 +32,7 @@ or length N arrays, where N is the number of parameterisations to run; N must be the same for all parameters of a single model. """ -from dataclasses import dataclass +from dataclasses import dataclass, field import typing import numpy as np @@ -678,9 +678,6 @@ class Population: #: The times in which the people are in the room. presence: Interval - #: Short range interactions - short_range_presence: list - #: The kind of mask being worn by the people. mask: Mask @@ -701,6 +698,12 @@ class _PopulationWithVirus(Population): #: The virus with which the population is infected. virus: Virus + #: Short range interactions + short_range_presence: typing.List[SpecificInterval] + + #: The type of expiractory activities in the short range interactions + short_range_activities: typing.List[str] + @method_cache def fraction_of_infectious_virus(self) -> _VectorisedFloat: """ @@ -751,10 +754,7 @@ class EmittingPopulation(_PopulationWithVirus): @dataclass(frozen=True) class InfectedPopulation(_PopulationWithVirus): #: The type of expiration that is being emitted whilst doing the activity. - expiration: _ExpirationBase - - #: The type of expiractory activities in the short range interactions - short_range_activities: list + expiration: _ExpirationBase @method_cache def fraction_of_infectious_virus(self) -> _VectorisedFloat: diff --git a/cara/tests/conftest.py b/cara/tests/conftest.py index 27ce9f1d..45cdbef4 100644 --- a/cara/tests/conftest.py +++ b/cara/tests/conftest.py @@ -23,6 +23,8 @@ def baseline_model(): host_immunity=0., # superspreading event, where ejection factor is fixed based # on Miller et al. (2020) - 50 represents the infectious dose. + short_range_presence=[], + short_range_activities=[], ), evaporation_factor=0.3, ) diff --git a/cara/tests/models/test_concentration_model.py b/cara/tests/models/test_concentration_model.py index 432b4d80..16d5b5b0 100644 --- a/cara/tests/models/test_concentration_model.py +++ b/cara/tests/models/test_concentration_model.py @@ -47,6 +47,8 @@ def test_concentration_model_vectorisation(override_params): ), expiration=models._ExpirationBase.types['Breathing'], host_immunity=0., + short_range_presence=[], + short_range_activities=[], ), evaporation_factor=0.3, ) @@ -69,6 +71,8 @@ def simple_conc_model(): virus=models.Virus.types['SARS_CoV_2'], expiration=models.Expiration.types['Breathing'], host_immunity=0., + short_range_presence=[], + short_range_activities=[], ), evaporation_factor=0.3, ) diff --git a/cara/tests/models/test_exposure_model.py b/cara/tests/models/test_exposure_model.py index 8b572daf..5b674207 100644 --- a/cara/tests/models/test_exposure_model.py +++ b/cara/tests/models/test_exposure_model.py @@ -66,6 +66,8 @@ def known_concentrations(func): virus=models.Virus.types['SARS_CoV_2_ALPHA'], expiration=models.Expiration.types['Speaking'], host_immunity=0., + short_range_presence=[], + short_range_activities=[], ) normed_func = lambda x: func(x) / dummy_infected_population.emission_rate_when_present() return KnownNormedconcentration(dummy_room, dummy_ventilation, @@ -154,6 +156,8 @@ def conc_model(): # superspreading event, where ejection factor is fixed based # on Miller et al. (2020) - 50 represents the infectious dose. host_immunity=0., + short_range_presence=[], + short_range_activities=[], ), evaporation_factor=0.3, ) @@ -197,6 +201,8 @@ def test_infectious_dose_vectorisation(): ), expiration=models.Expiration.types['Speaking'], host_immunity=0., + short_range_presence=[], + short_range_activities=[], ) cm = known_concentrations(lambda t: 1.2) cm = replace(cm, infected=infected_population) diff --git a/cara/tests/test_infected_population.py b/cara/tests/test_infected_population.py index 8856d312..66714f96 100644 --- a/cara/tests/test_infected_population.py +++ b/cara/tests/test_infected_population.py @@ -37,6 +37,8 @@ def test_infected_population_vectorisation(override_params): ), expiration=cara.models._ExpirationBase.types['Breathing'], host_immunity=0., + short_range_presence=[], + short_range_activities=[], ) emission_rate = infected.emission_rate(10) assert isinstance(emission_rate, np.ndarray) diff --git a/cara/tests/test_known_quantities.py b/cara/tests/test_known_quantities.py index 9fc10597..9910a848 100644 --- a/cara/tests/test_known_quantities.py +++ b/cara/tests/test_known_quantities.py @@ -76,6 +76,8 @@ def build_model(interval_duration): host_immunity=0., # superspreading event, where ejection factor is fixed based # on Miller et al. (2020) - 50 represents the infectious dose. + short_range_presence=[], + short_range_activities=[], ), evaporation_factor=0.3, ) @@ -238,6 +240,8 @@ def build_hourly_dependent_model( activity=models.Activity.types['Light activity'], known_individual_emission_rate=970 * 50, host_immunity=0, + short_range_presence=[], + short_range_activities=[], ), evaporation_factor=0.3, ) @@ -261,6 +265,8 @@ def build_constant_temp_model(outside_temp, intervals_open=((7.5, 8.5),)): activity=models.Activity.types['Light activity'], known_individual_emission_rate=970 * 50, host_immunity=0., + short_range_presence=[], + short_range_activities=[], ), evaporation_factor=0.3, ) @@ -291,6 +297,8 @@ def build_hourly_dependent_model_multipleventilation(month, intervals_open=((7.5 activity=models.Activity.types['Light activity'], known_individual_emission_rate=970 * 50, host_immunity=0., + short_range_presence=[], + short_range_activities=[], ), evaporation_factor=0.3, ) diff --git a/cara/tests/test_monte_carlo.py b/cara/tests/test_monte_carlo.py index 1a7fc8a9..c51bcbeb 100644 --- a/cara/tests/test_monte_carlo.py +++ b/cara/tests/test_monte_carlo.py @@ -55,6 +55,8 @@ def baseline_mc_model() -> cara.monte_carlo.ConcentrationModel: activity=cara.models.Activity.types['Light activity'], expiration=cara.models.Expiration.types['Breathing'], host_immunity=0., + short_range_presence=[], + short_range_activities=[], ), evaporation_factor=0.3, ) diff --git a/cara/tests/test_monte_carlo_full_models.py b/cara/tests/test_monte_carlo_full_models.py index 71a630b0..90466d96 100644 --- a/cara/tests/test_monte_carlo_full_models.py +++ b/cara/tests/test_monte_carlo_full_models.py @@ -42,6 +42,8 @@ def shared_office_mc(): activity=activity_distributions['Seated'], expiration=build_expiration({'Speaking': 0.33, 'Breathing': 0.67}), host_immunity=0., + short_range_presence=[], + short_range_activities=[], ), evaporation_factor=0.3, ) @@ -84,6 +86,8 @@ def classroom_mc(): activity=activity_distributions['Light activity'], expiration=build_expiration('Speaking'), host_immunity=0., + short_range_presence=[], + short_range_activities=[], ), evaporation_factor=0.3, ) @@ -117,6 +121,8 @@ def ski_cabin_mc(): activity=activity_distributions['Moderate activity'], expiration=build_expiration('Speaking'), host_immunity=0., + short_range_presence=[], + short_range_activities=[], ), evaporation_factor=0.3, ) @@ -156,6 +162,8 @@ def skagit_chorale_mc(): activity=activity_distributions['Moderate activity'], expiration=build_expiration('Shouting'), host_immunity=0., + short_range_presence=[], + short_range_activities=[], ), evaporation_factor=0.3, ) @@ -195,6 +203,8 @@ def bus_ride_mc(): activity=activity_distributions['Seated'], expiration=build_expiration('Speaking'), host_immunity=0., + short_range_presence=[], + short_range_activities=[], ), evaporation_factor=0.3, ) @@ -229,6 +239,8 @@ def gym_mc(): activity=activity_distributions['Heavy exercise'], expiration=expiration_distributions['Breathing'], host_immunity=0., + short_range_presence=[], + short_range_activities=[], ), evaporation_factor=0.3, ) @@ -263,6 +275,8 @@ def waiting_room_mc(): activity=activity_distributions['Seated'], expiration=build_expiration({'Speaking': 0.3, 'Breathing': 0.7}), host_immunity=0., + short_range_presence=[], + short_range_activities=[], ), evaporation_factor=0.3, ) @@ -340,6 +354,8 @@ def test_small_shared_office_Geneva(mask_type, month, expected_pi, activity=activity_distributions['Seated'], expiration=build_expiration({'Speaking': 0.33, 'Breathing': 0.67}), host_immunity=0., + short_range_presence=[], + short_range_activities=[], ), evaporation_factor=0.3, )