diff --git a/app-config/auth-service/auth_service/__init__.py b/app-config/auth-service/auth_service/__init__.py index 74dbd5cc..1f8d34ba 100644 --- a/app-config/auth-service/auth_service/__init__.py +++ b/app-config/auth-service/auth_service/__init__.py @@ -13,7 +13,6 @@ from keycloak.aio.realm import KeycloakRealm from tornado.web import Application, RequestHandler import tornado.log - LOG = logging.getLogger(__name__) diff --git a/app-config/auth-service/setup.py b/app-config/auth-service/setup.py index da5e0253..130df3f8 100644 --- a/app-config/auth-service/setup.py +++ b/app-config/auth-service/setup.py @@ -8,12 +8,10 @@ https://packaging.python.org/guides/distributing-packages-using-setuptools/ from pathlib import Path from setuptools import setup, find_packages - HERE = Path(__file__).parent.absolute() with (HERE / 'README.md').open('rt') as fh: LONG_DESCRIPTION = fh.read().strip() - REQUIREMENTS: dict = { 'core': [ 'aiohttp', @@ -27,7 +25,6 @@ REQUIREMENTS: dict = { ], } - setup( name='auth-service', version="0.0.1", diff --git a/cara/apps/calculator/__init__.py b/cara/apps/calculator/__init__.py index d7b15698..40a13f1a 100644 --- a/cara/apps/calculator/__init__.py +++ b/cara/apps/calculator/__init__.py @@ -25,7 +25,6 @@ from . import model_generator from .report_generator import ReportGenerator, calculate_report_data from .user import AuthenticatedUser, AnonymousUser - # The calculator version is based on a combination of the model version and the # semantic version of the calculator itself. The version uses the terms # "{MAJOR}.{MINOR}.{PATCH}" to describe the 3 distinct numbers constituting a version. diff --git a/cara/apps/calculator/markdown_tools.py b/cara/apps/calculator/markdown_tools.py index ba964d5c..fee2e05d 100644 --- a/cara/apps/calculator/markdown_tools.py +++ b/cara/apps/calculator/markdown_tools.py @@ -3,7 +3,6 @@ import re import jinja2 import mistune - HEADER_PATTERN = re.compile(r'\n(#+)(.*)') diff --git a/cara/apps/calculator/model_generator.py b/cara/apps/calculator/model_generator.py index c7ebd410..8e92f361 100644 --- a/cara/apps/calculator/model_generator.py +++ b/cara/apps/calculator/model_generator.py @@ -16,13 +16,10 @@ from .. import calculator from cara.monte_carlo.data import activity_distributions, virus_distributions, mask_distributions, short_range_distances from cara.monte_carlo.data import expiration_distribution, expiration_BLO_factors, expiration_distributions, short_range_expiration_distributions - LOG = logging.getLogger(__name__) - minutes_since_midnight = typing.NewType('minutes_since_midnight', int) - # Used to declare when an attribute of a class must have a value provided, and # there should be no default value used. _NO_DEFAULT = object() @@ -365,7 +362,7 @@ class FormData: ventilation = models.HVACMechanical( active=always_on, q_air_mech=self.air_supply) - # this is a minimal, always present source of ventilation, due + # This is a minimal, always present source of ventilation, due # to the air infiltration from the outside. # See CERN-OPEN-2021-004, p. 12. infiltration_ventilation = models.AirChange(active=always_on, air_exch=0.25) @@ -583,8 +580,6 @@ class FormData: present_intervals = [] - # def add_interval(start, end): - current_time = start LOG.debug(f"starting time march at {_hours2timestring(current_time/60)} to {_hours2timestring(finish/60)}") diff --git a/cara/data/__init__.py b/cara/data/__init__.py index 31195ba7..9e6a523f 100644 --- a/cara/data/__init__.py +++ b/cara/data/__init__.py @@ -11,7 +11,7 @@ MONTH_NAMES = [ def get_hourly_temperatures_celsius_per_hour(coordinates): wx_station_id = nearest_wx_station( longitude=coordinates[1], latitude=coordinates[0])[0] - # average temperature of each month, hour per hour (from midnight to 11 pm) + # Average temperature of each month, hour per hour (from midnight to 11 pm) return {month.replace(month, MONTH_NAMES[i][:3]): [t - 273.15 for t in temp] for i, (month, temp) in enumerate(wx_data()[wx_station_id].items())} diff --git a/cara/models.py b/cara/models.py index f539c2e2..42695ca5 100644 --- a/cara/models.py +++ b/cara/models.py @@ -56,7 +56,6 @@ oneoverln2 = 1 / np.log(2) _VectorisedFloat = typing.Union[float, np.ndarray] _VectorisedInt = typing.Union[int, np.ndarray] - Time_t = typing.TypeVar('Time_t', float, int) BoundaryPair_t = typing.Tuple[Time_t, Time_t] BoundarySequence_t = typing.Union[typing.Tuple[BoundaryPair_t, ...], typing.Tuple] @@ -130,7 +129,7 @@ class PeriodicInterval(Interval): @dataclass(frozen=True) class PiecewiseConstant: - # TODO: implement rather a periodic version (24-hour period), where + # TODO: Implement rather a periodic version (24-hour period), where # transition_times and values have the same length. #: transition times at which the function changes value (hours). @@ -161,7 +160,7 @@ class PiecewiseConstant: return value def interval(self) -> Interval: - # build an Interval object + # Build an Interval object present_times = [] for t1, t2, value in zip(self.transition_times[:-1], self.transition_times[1:], self.values): @@ -170,7 +169,7 @@ class PiecewiseConstant: return SpecificInterval(present_times=tuple(present_times)) def refine(self, refine_factor=10) -> "PiecewiseConstant": - # build a new PiecewiseConstant object with a refined mesh, + # Build a new PiecewiseConstant object with a refined mesh, # using a linear interpolation in-between the initial mesh points refined_times = np.linspace(self.transition_times[0], self.transition_times[-1], (len(self.transition_times)-1) * refine_factor+1) @@ -482,7 +481,7 @@ Virus.types = { transmissibility_factor=1.0, ), 'SARS_CoV_2_ALPHA': SARSCoV2( - # also called VOC-202012/01 + # Also called VOC-202012/01 viral_load_in_sputum=1e9, infectious_dose=50., viable_to_RNA_ratio = 0.5, @@ -630,19 +629,19 @@ class _ExpirationBase: @property def particle(self) -> Particle: """ - the Particle object representing the aerosol - here the default one + The Particle object representing the aerosol - here the default one """ return Particle() def aerosols(self, mask: Mask): """ - total volume of aerosols expired per volume of air (mL/cm^3). + Total volume of aerosols expired per volume of air (mL/cm^3). """ raise NotImplementedError("Subclass must implement") def jet_origin_concentration(self): """ - concentration of viruses at the jet origin (mL/m3). + Concentration of viruses at the jet origin (mL/m3). """ raise NotImplementedError("Subclass must implement") @@ -657,7 +656,7 @@ class Expiration(_ExpirationBase): #: diameter of the aerosol in microns diameter: _VectorisedFloat - #: total concentration of aerosols per unit volume of expired air + #: Total concentration of aerosols per unit volume of expired air # (in cm^-3), integrated over all aerosol diameters (corresponding # to c_n,i in Eq. (4) of https://doi.org/10.1101/2021.10.14.21264988) cn: float = 1. @@ -665,7 +664,7 @@ class Expiration(_ExpirationBase): @property def particle(self) -> Particle: """ - the Particle object representing the aerosol + The Particle object representing the aerosol """ return Particle(diameter=self.diameter) @@ -675,7 +674,7 @@ class Expiration(_ExpirationBase): def volume(d): return (np.pi * d**3) / 6. - # final result converted from microns^3/cm3 to mL/cm^3 + # Final result converted from microns^3/cm3 to mL/cm^3 return self.cn * (volume(self.diameter) * (1 - mask.exhale_efficiency(self.diameter))) * 1e-12 @@ -684,7 +683,7 @@ class Expiration(_ExpirationBase): def volume(d): return (np.pi * d**3) / 6. - # final result converted from microns^3/cm3 to mL/m3 + # Final result converted from microns^3/cm3 to mL/m3 return self.cn * volume(self.diameter) * 1e-6 @@ -792,7 +791,7 @@ class _PopulationWithVirus(Population): def aerosols(self): """ - total volume of aerosols expired per volume of air (mL/cm^3). + Total volume of aerosols expired per volume of air (mL/cm^3). """ raise NotImplementedError("Subclass must implement") @@ -833,7 +832,7 @@ class _PopulationWithVirus(Population): @property def particle(self) -> Particle: """ - the Particle object representing the aerosol expired by the + The Particle object representing the aerosol expired by the population - here we take the default Particle object """ return Particle() @@ -846,7 +845,7 @@ class EmittingPopulation(_PopulationWithVirus): def aerosols(self): """ - total volume of aerosols expired per volume of air (mL/cm^3). + Total volume of aerosols expired per volume of air (mL/cm^3). Here arbitrarily set to 1 as the full emission rate is known. """ return 1. @@ -875,7 +874,7 @@ class InfectedPopulation(_PopulationWithVirus): def aerosols(self): """ - total volume of aerosols expired per volume of air (mL/cm^3). + Total volume of aerosols expired per volume of air (mL/cm^3). """ return self.expiration.aerosols(self.mask) @@ -897,7 +896,7 @@ class InfectedPopulation(_PopulationWithVirus): @property def particle(self) -> Particle: """ - the Particle object representing the aerosol - here the default one + The Particle object representing the aerosol - here the default one """ return self.expiration.particle @@ -924,7 +923,6 @@ class ConcentrationModel: h = 1.5 # Deposition rate (h^-1) k = (vg * 3600) / h - #todo: Inside_temp needs to be exposed/added to the room; return ( k + self.virus.decay_constant(self.room.humidity, self.room.inside_temp.value(time)) + self.ventilation.air_exchange(self.room, time) @@ -1274,8 +1272,10 @@ class ExposureModel: self.concentration_model.evaporation_factor) def _long_range_normed_exposure_between_bounds(self, time1: float, time2: float) -> _VectorisedFloat: - """The number of virions per meter^3 between any two times, normalized - by the emission rate of the infected population""" + """ + The number of virions per meter^3 between any two times, normalized + by the emission rate of the infected population + """ exposure = 0. for start, stop in self.exposed.presence.boundaries(): if stop < time1: @@ -1315,7 +1315,7 @@ class ExposureModel: diameter = self.concentration_model.infected.particle.diameter if not np.isscalar(diameter) and diameter is not None: - # we compute first the mean of all diameter-dependent quantities + # We compute first the mean of all diameter-dependent quantities # to perform properly the Monte-Carlo integration over # particle diameters (doing things in another order would # lead to wrong results for the probability of infection). @@ -1323,11 +1323,11 @@ class ExposureModel: aerosols * fdep).mean() else: - # in the case of a single diameter or no diameter defined, + # In the case of a single diameter or no diameter defined, # one should not take any mean at this stage. dep_exposure_integrated = self._long_range_normed_exposure_between_bounds(time1, time2)*aerosols*fdep - # then we multiply by the diameter-independent quantity emission_rate_per_aerosol, + # Then we multiply by the diameter-independent quantity emission_rate_per_aerosol, # and parameters of the vD equation (i.e. BR_k and n_in). deposited_exposure += (dep_exposure_integrated * emission_rate_per_aerosol * self.exposed.activity.inhalation_rate * @@ -1361,7 +1361,7 @@ class ExposureModel: # Aerosols not considered given the formula for the initial # concentration at mouth/nose. if diameter is not None and not np.isscalar(diameter): - # we compute first the mean of all diameter-dependent quantities + # We compute first the mean of all diameter-dependent quantities # to perform properly the Monte-Carlo integration over # particle diameters (doing things in another order would # lead to wrong results for the probability of infection). @@ -1370,24 +1370,24 @@ class ExposureModel: - np.array(short_range_lr_exposure * fdep).mean() * self.concentration_model.infected.activity.exhalation_rate) else: - # in the case of a single diameter or no diameter defined, + # In the case of a single diameter or no diameter defined, # one should not take any mean at this stage. this_deposited_exposure = (short_range_jet_exposure * fdep - short_range_lr_exposure * fdep * self.concentration_model.infected.activity.exhalation_rate) - # multiply by the (diameter-independent) inhalation rate + # Multiply by the (diameter-independent) inhalation rate deposited_exposure += (this_deposited_exposure * interaction.activity.inhalation_rate /dilution) - # then we multiply by diameter-independent quantities: viral load + # Then we multiply by diameter-independent quantities: viral load # and fraction of infected virions f_inf = self.concentration_model.infected.fraction_of_infectious_virus() deposited_exposure *= (f_inf * self.concentration_model.virus.viral_load_in_sputum * (1 - self.exposed.mask.inhale_efficiency())) - # long-range concentration + # Long-range concentration deposited_exposure += self.long_range_deposited_exposure_between_bounds(time1, time2) return deposited_exposure @@ -1404,7 +1404,7 @@ class ExposureModel: return deposited_exposure * self.repeats def infection_probability(self) -> _VectorisedFloat: - # viral dose (vD) + # Viral dose (vD) vD = self.deposited_exposure() # oneoverln2 multiplied by ID_50 corresponds to ID_63. diff --git a/cara/monte_carlo/__init__.pyi b/cara/monte_carlo/__init__.pyi index 5a184e17..17a15f49 100644 --- a/cara/monte_carlo/__init__.pyi +++ b/cara/monte_carlo/__init__.pyi @@ -1,4 +1,5 @@ from typing import Any + # For now we disable all type-checking in the monte-carlo submodule. def __getattr__(name) -> Any: ... diff --git a/cara/monte_carlo/data.py b/cara/monte_carlo/data.py index d043f688..b4f047c4 100644 --- a/cara/monte_carlo/data.py +++ b/cara/monte_carlo/data.py @@ -8,7 +8,6 @@ from scipy.stats import weibull_min import cara.monte_carlo as mc from cara.monte_carlo.sampleable import LogCustom, LogNormal,LogCustomKernel,CustomKernel,Uniform, Custom - sqrt2pi = np.sqrt(2.*np.pi) sqrt2 = np.sqrt(2.) @@ -26,7 +25,7 @@ class BLOmodel: vol. 42, no. 12, pp. 839 – 851, 2011, https://doi.org/10.1016/j.jaerosci.2011.07.009). """ - #: factors assigned to resp. the B, L and O modes. They are + #: Factors assigned to resp. the B, L and O modes. They are # charateristics of the kind of expiratory activity (e.g. breathing, # speaking, singing, or shouting). These are applied on top of the # cn concentrations (see below), and depend on the kind of activity @@ -37,11 +36,11 @@ class BLOmodel: # total concentration of aerosols for each mode. cn: typing.Tuple[float, float, float] = (0.06, 0.2, 0.0010008) - # mean of the underlying normal distributions (represents the log of a + # Mean of the underlying normal distributions (represents the log of a # diameter in microns), for resp. the B, L and O modes. mu: typing.Tuple[float, float, float] = (0.989541, 1.38629, 4.97673) - # std deviation of the underlying normal distribution, for resp. + # Std deviation of the underlying normal distribution, for resp. # the B, L and O modes. sigma: typing.Tuple[float, float, float] = (0.262364, 0.506818, 0.585005) diff --git a/cara/monte_carlo/models.py b/cara/monte_carlo/models.py index f47d3416..4ab55363 100644 --- a/cara/monte_carlo/models.py +++ b/cara/monte_carlo/models.py @@ -7,7 +7,6 @@ import cara.models from .sampleable import SampleableDistribution, _VectorisedFloatOrSampleable - _ModelType = typing.TypeVar('_ModelType') diff --git a/cara/monte_carlo/sampleable.py b/cara/monte_carlo/sampleable.py index fe6e72d3..1d887f12 100644 --- a/cara/monte_carlo/sampleable.py +++ b/cara/monte_carlo/sampleable.py @@ -5,7 +5,6 @@ from sklearn.neighbors import KernelDensity # type: ignore import cara.models - # Declare a float array type of a given size. # There is no better way to declare this currently, unfortunately. float_array_size_n = np.ndarray diff --git a/cara/state.py b/cara/state.py index 4c2bf8f0..ddbd73a3 100644 --- a/cara/state.py +++ b/cara/state.py @@ -13,7 +13,6 @@ from contextlib import contextmanager import dataclasses import typing - Datamodel_T = typing.TypeVar('Datamodel_T') dataclass_instance = typing.Any diff --git a/cara/tests/apps/calculator/test_webapp.py b/cara/tests/apps/calculator/test_webapp.py index 6255f527..65ae284d 100644 --- a/cara/tests/apps/calculator/test_webapp.py +++ b/cara/tests/apps/calculator/test_webapp.py @@ -9,6 +9,7 @@ from cara.apps.calculator.report_generator import generate_permalink _TIMEOUT = 20. + @pytest.fixture def app(): return cara.apps.calculator.make_app() diff --git a/cara/tests/conftest.py b/cara/tests/conftest.py index ef4bff1d..2f9a3dc9 100644 --- a/cara/tests/conftest.py +++ b/cara/tests/conftest.py @@ -21,7 +21,7 @@ def baseline_concentration_model(): activity=models.Activity.types['Light activity'], known_individual_emission_rate=970 * 50, host_immunity=0., - # superspreading event, where ejection factor is fixed based + # Superspreading event, where ejection factor is fixed based # on Miller et al. (2020) - 50 represents the infectious dose. ), evaporation_factor=0.3, diff --git a/cara/tests/models/test_exposure_model.py b/cara/tests/models/test_exposure_model.py index 896c1c6b..667ebf0b 100644 --- a/cara/tests/models/test_exposure_model.py +++ b/cara/tests/models/test_exposure_model.py @@ -20,7 +20,7 @@ class KnownNormedconcentration(models.ConcentrationModel): normed_concentration_function: typing.Callable = lambda x: 0 def infectious_virus_removal_rate(self, time: float) -> models._VectorisedFloat: - # very large decay constant -> same as constant concentration + # Very large decay constant -> same as constant concentration return 1.e50 def _normed_concentration_limit(self, time: float) -> models._VectorisedFloat: diff --git a/cara/tests/models/test_mask.py b/cara/tests/models/test_mask.py index 4a71d13c..08004fa1 100644 --- a/cara/tests/models/test_mask.py +++ b/cara/tests/models/test_mask.py @@ -4,6 +4,7 @@ import pytest from cara import models + @pytest.mark.parametrize( "η_inhale, expected_inhale_efficiency", [ diff --git a/cara/tests/models/test_piecewiseconstant.py b/cara/tests/models/test_piecewiseconstant.py index a0ba14f0..9ef3befb 100644 --- a/cara/tests/models/test_piecewiseconstant.py +++ b/cara/tests/models/test_piecewiseconstant.py @@ -6,12 +6,12 @@ from cara import data def test_piecewiseconstantfunction_wrongarguments(): - # number of values should be 1+number of transition times + # Number of values should be 1+number of transition times pytest.raises(ValueError, models.PiecewiseConstant, (0, 1), (0, 0)) pytest.raises(ValueError, models.PiecewiseConstant, (0,), (0, 0)) - # two transition times cannot be equal + # Two transition times cannot be equal pytest.raises(ValueError, models.PiecewiseConstant, (0, 2, 2), (0, 0)) - # unsorted transition times are not allowed + # Unsorted transition times are not allowed pytest.raises(ValueError, models.PiecewiseConstant, (2, 0), (0, 0)) # If vectors, must all be same length. diff --git a/cara/tests/models/test_virus.py b/cara/tests/models/test_virus.py index 83f4d1f0..650da211 100644 --- a/cara/tests/models/test_virus.py +++ b/cara/tests/models/test_virus.py @@ -4,6 +4,7 @@ import pytest from cara import models + @pytest.mark.parametrize( "inside_temp, humidity, expected_halflife, expected_decay_constant", [ diff --git a/cara/tests/test_expiration.py b/cara/tests/test_expiration.py index af2bab06..b9a04cf9 100644 --- a/cara/tests/test_expiration.py +++ b/cara/tests/test_expiration.py @@ -43,7 +43,7 @@ def test_multiple(): @retry(tries=10) -# expected values obtained from analytical formulas +# Expected values obtained from analytical formulas @pytest.mark.parametrize( "BLO_weights, expected_aerosols", [ diff --git a/cara/tests/test_full_algorithm.py b/cara/tests/test_full_algorithm.py index 968ebfc0..d03e344f 100644 --- a/cara/tests/test_full_algorithm.py +++ b/cara/tests/test_full_algorithm.py @@ -24,6 +24,7 @@ sqrt2pi = np.sqrt(2.*np.pi) sqrt2 = np.sqrt(2.) ln2 = np.log(2) + @dataclass(frozen=True) class SimpleConcentrationModel: """ @@ -34,54 +35,54 @@ class SimpleConcentrationModel: times. """ - #: infected people presence interval + #: Infected people presence interval infected_presence: Interval - #: viral load (RNA copies / mL) + #: Viral load (RNA copies / mL) viral_load: _VectorisedFloat - #: breathing rate (m^3/h) + #: Breathing rate (m^3/h) breathing_rate: _VectorisedFloat - #: room volume (m^3) + #: Room volume (m^3) room_volume: _VectorisedFloat - #: ventilation rate (air changes per hour) - including HEPA + #: Ventilation rate (air changes per hour) - including HEPA lambda_ventilation: _VectorisedFloat #: BLO factors BLO_factors: typing.Tuple[float, float, float] - #: number of infected people + #: Number of infected people num_infected: int = 1 - #: relative humidity RH + #: Relative humidity RH humidity: float = 0.3 - #: minimum particle diameter considered (microns) + #: Minimum particle diameter considered (microns) diameter_min: float = 0.1 - #: maximum particle diameter considered (microns) + #: Maximum particle diameter considered (microns) diameter_max: float = 30. - #: evaporation factor + #: Evaporation factor evaporation: float = 0.3 #: cn (cm^-3) for resp. the B, L and O modes. Corresponds to the # total concentration of aerosols for each mode. cn: typing.Tuple[float, float, float] = (0.06, 0.2, 0.0010008) - # mean of the underlying normal distributions (represents the log of a + # Mean of the underlying normal distributions (represents the log of a # diameter in microns), for resp. the B, L and O modes. mu: typing.Tuple[float, float, float] = (0.989541, 1.38629, 4.97673) - # std deviation of the underlying normal distribution, for resp. + # Std deviation of the underlying normal distribution, for resp. # the B, L and O modes. sigma: typing.Tuple[float, float, float] = (0.262364, 0.506818, 0.585005) def removal_rate(self) -> _VectorisedFloat: """ - removal rate lambda in h^-1, excluding the deposition rate. + Removal rate lambda in h^-1, excluding the deposition rate. """ hl_calc = ((ln2/((0.16030 + 0.04018*(((293-273.15)-20.615)/10.585) +0.02176*(((self.humidity*100)-45.235)/28.665) @@ -94,7 +95,7 @@ class SimpleConcentrationModel: @method_cache def deposition_removal_coefficient(self) -> float: """ - coefficient in front of gravitational deposition rate, in h^-1.microns^-2 + Coefficient in front of gravitational deposition rate, in h^-1.microns^-2 Note: 0.4512 = 1.88e-4 * 3600 / 1.5 """ return 0.4512*(self.evaporation/2.5)**2 @@ -102,7 +103,7 @@ class SimpleConcentrationModel: @method_cache def aerosol_volume(self,diameter: float) -> float: """ - particle volume in microns^3 + Particle volume in microns^3 """ return 4*np.pi/3. * (diameter/2.)**3 @@ -110,7 +111,7 @@ class SimpleConcentrationModel: def Np(self,diameter: float, BLO_factors: typing.Tuple[float, float, float]) -> float: """ - number of emitted particles per unit volume (BLO model) + Number of emitted particles per unit volume (BLO model) in cm^-3.ln(micron)^-1 """ result = 0. @@ -122,7 +123,7 @@ class SimpleConcentrationModel: def vR(self,diameter: float) -> float: """ - emission rate per unit diameter, in RNA copies / h / micron + Emission rate per unit diameter, in RNA copies / h / micron """ return (self.Np(diameter, self.BLO_factors) * self.aerosol_volume(diameter) * 1e-6) @@ -145,7 +146,7 @@ class SimpleConcentrationModel: def concentration(self,t: float) -> _VectorisedFloat: """ - concentration at a given time t + Concentration at a given time t """ trans_times = sorted(self.infected_presence.transition_times()) if t==trans_times[0]: @@ -187,28 +188,28 @@ class SimpleShortRangeModel: This assumes no mask wearing. """ - #: time intervals in which a short-range interaction occurs + #: Time intervals in which a short-range interaction occurs interaction_interval: SpecificInterval - #: tuple with interpersonal distanced from infected person (m) + #: Tuple with interpersonal distanced from infected person (m) distance : _VectorisedFloat = 0.854 - #: breathing rate (m^3/h) + #: Breathing rate (m^3/h) breathing_rate: _VectorisedFloat = 0.51 - #: tuple with BLO factors + #: Tuple with BLO factors BLO_factors: typing.Tuple[float, float, float] = (1,0,0) - #: minimum diameter for integration (short-range only) (microns) + #: Minimum diameter for integration (short-range only) (microns) diameter_min: float = 0.1 - #: maximum diameter for integration (short-range only) (microns) + #: Maximum diameter for integration (short-range only) (microns) diameter_max: float = 100. - #: mouth opening diameter (m) + #: Mouth opening diameter (m) D: float = 0.02 - #: duration of the expiration (s) + #: Duration of the expiration (s) tstar: float = 2. #: Streamwise and radial penetration coefficients @@ -220,27 +221,27 @@ class SimpleShortRangeModel: @method_cache def dilution_factor(self) -> _VectorisedFloat: """ - computes dilution factor at a certain distance x + Computes dilution factor at a certain distance x based on Wei JIA matlab script. """ x = np.array(self.distance) dilution = np.empty(x.shape, dtype=np.float64) - # expired flow rate during the expiration period, m^3/s + # Expired flow rate during the expiration period, m^3/s Q0 = np.array(self.breathing_rate/3600) - # the expired flow velocity at the noozle (mouth opening), m/s + # The expired flow velocity at the noozle (mouth opening), m/s u0 = np.array(Q0/(np.pi/4. * self.D**2)) - # parameters in the jet-like stage + # Parameters in the jet-like stage # position of virtual origin x01 = self.D/2/self.Cr1 - # time of virtual origin + # Time of virtual origin t01 = (x01/self.Cx1)**2 * (Q0*u0)**(-0.5) - # transition point (in m) + # Transition point (in m) xstar = np.array(self.Cx1*(Q0*u0)**0.25*(self.tstar + t01)**0.5 - x01) - # dilution factor at the transition point xstar + # Dilution factor at the transition point xstar Sxstar = np.array(2.*self.Cr1*(xstar+x01)/self.D) - # calculate dilution factor at the short-range distance x + # Calculate dilution factor at the short-range distance x dilution[x <= xstar] = 2.*self.Cr1*(x[x <= xstar] + x01)/self.D dilution[x > xstar] = Sxstar[x > xstar]*(1. + self.Cr2*(x[x > xstar] - xstar[x > xstar]) @@ -250,7 +251,7 @@ class SimpleShortRangeModel: def jet_concentration(self,conc_model: SimpleConcentrationModel) -> _VectorisedFloat: """ - virion concentration at the origin of the jet (close to + Virion concentration at the origin of the jet (close to the mouth of the infected person), in m^-3 we perform the integral of Np(d)*V(d) over diameter analytically """ @@ -269,7 +270,7 @@ class SimpleShortRangeModel: def concentration(self, conc_model: SimpleConcentrationModel, time: float) -> _VectorisedFloat: """ - compute the short-range part of the concentration, and add it + Compute the short-range part of the concentration, and add it to the long-range concentration """ if self.interaction_interval.triggered(time): @@ -293,25 +294,25 @@ class SimpleExposureModel(SimpleConcentrationModel): interaction intervals are within presence intervals of the infected. """ - #: fraction of infected viruses + #: Fraction of infected viruses finf: _VectorisedFloat = 0.5 - #: host immunity factor (0. for not immune) + #: Host immunity factor (0. for not immune) HI: _VectorisedFloat = 0. - #: infectious dose (ID50) + #: Infectious dose (ID50) ID50: _VectorisedFloat = 50. - #: transmissibility factor w.r.t. original strain + #: Transmissibility factor w.r.t. original strain # (<1 means more transmissible) transmissibility: _VectorisedFloat = 1. - #: list of short-range interaction models + #: List of short-range interaction models sr_models: typing.Tuple[SimpleShortRangeModel, ...] = () def fdep(self, diameter: float, evaporation: float) -> float: """ - fraction deposited + Fraction deposited """ d = diameter * evaporation IFrac = 1 - 0.5 * (1 - (1 / (1 + (0.00076*(d**2.8))))) @@ -327,7 +328,7 @@ class SimpleExposureModel(SimpleConcentrationModel): A general function to compute the main integral over diameters """ def integrand(diameter): - # function to return the integrand + # Function to return the integrand a = self.deposition_removal_coefficient() a_dsquare = a*diameter**2 return -(self.vR(diameter)*self.fdep(diameter,evaporation)/( @@ -345,7 +346,7 @@ class SimpleExposureModel(SimpleConcentrationModel): Same as f but with fdep included in the integral. """ def integrand(diameter): - # function to return the integrand + # Function to return the integrand a = self.deposition_removal_coefficient() a_dsquare = a*diameter**2 return (self.vR(diameter)*self.fdep(diameter,evaporation) @@ -357,7 +358,7 @@ class SimpleExposureModel(SimpleConcentrationModel): def total_concentration(self, t: float): """ - total concentration at time t + Total concentration at time t """ res = self.concentration(t) for sr_mod in self.sr_models: @@ -368,7 +369,7 @@ class SimpleExposureModel(SimpleConcentrationModel): def integrated_longrange_concentration(self,t1: float,t2: float, evaporation: float) -> _VectorisedFloat: """ - background (long-range) concentration integrated from t1 to t2 + Background (long-range) concentration integrated from t1 to t2 assuming both t1 and t2 are within a single presence interval. This includes the deposition fraction (fdep). """ @@ -413,7 +414,7 @@ class SimpleExposureModel(SimpleConcentrationModel): @method_cache def integrated_shortrange_concentration(self) -> _VectorisedFloat: """ - short-range concentration integrated over interaction times and + Short-range concentration integrated over interaction times and diameters. This includes the deposition fraction (fdep). """ result = 0. @@ -436,7 +437,7 @@ class SimpleExposureModel(SimpleConcentrationModel): def dose(self) -> _VectorisedFloat: """ - total deposited dose (integrated over time and over particle + Total deposited dose (integrated over time and over particle diameters), including short and long-range. """ result = 0. @@ -450,7 +451,7 @@ class SimpleExposureModel(SimpleConcentrationModel): def probability_infection(self): """ - total probability of infection + Total probability of infection """ return (1. - np.exp(-self.dose() * ln2 * (1-self.HI) /(self.ID50 * self.transmissibility) )) * 100. @@ -766,7 +767,7 @@ def test_longrange_exposure_with_distributions(c_model_distr): ) -# tests on the concentration with short-range should be skipped until +# Tests on the concentration with short-range should be skipped until # one finds a way to avoid the large variability of the concentration # with short-range 'Speaking' or 'Shouting' interactions @pytest.mark.skip diff --git a/cara/tests/test_known_quantities.py b/cara/tests/test_known_quantities.py index 055c587b..19314824 100644 --- a/cara/tests/test_known_quantities.py +++ b/cara/tests/test_known_quantities.py @@ -38,7 +38,7 @@ def baseline_periodic_hepa(): def test_concentrations(baseline_concentration_model): - # expected concentrations were computed analytically + # Expected concentrations were computed analytically ts = [0, 4, 5, 7, 10] concentrations = [baseline_concentration_model.concentration(float(t)) for t in ts] npt.assert_allclose( @@ -73,7 +73,7 @@ def build_model(interval_duration): activity=models.Activity.types['Light activity'], known_individual_emission_rate=970 * 50, host_immunity=0., - # superspreading event, where ejection factor is fixed based + # Superspreading event, where ejection factor is fixed based # on Miller et al. (2020) - 50 represents the infectious dose. ), evaporation_factor=0.3, @@ -91,7 +91,7 @@ def test_concentrations_startup(): def test_r0(baseline_exposure_model): - # expected r0 was computed with a trapezoidal integration, using + # Expected r0 was computed with a trapezoidal integration, using # a mesh of 100'000 pts per exposed presence interval. r0 = baseline_exposure_model.reproduction_number() npt.assert_allclose(r0, 771.380385) @@ -376,7 +376,7 @@ def build_exposure_model(concentration_model, short_range_model): ) -# expected deposited exposure were computed with a trapezoidal integration, using +# Expected deposited exposure were computed with a trapezoidal integration, using # a mesh of 100'000 pts per exposed presence interval. @pytest.mark.parametrize( "month, expected_deposited_exposure", @@ -396,7 +396,7 @@ def test_exposure_hourly_dep(month,expected_deposited_exposure, baseline_sr_mode deposited_exposure = m.deposited_exposure() npt.assert_allclose(deposited_exposure, expected_deposited_exposure) -# expected deposited exposure were computed with a trapezoidal integration, using +# Expected deposited exposure were computed with a trapezoidal integration, using # a mesh of 100'000 pts per exposed presence interval and 25 pts per hour # for the temperature discretization. @pytest.mark.parametrize( diff --git a/cara/tests/test_monte_carlo.py b/cara/tests/test_monte_carlo.py index b948f4b9..d709e6c1 100644 --- a/cara/tests/test_monte_carlo.py +++ b/cara/tests/test_monte_carlo.py @@ -7,7 +7,6 @@ import cara.models import cara.monte_carlo.models as mc_models import cara.monte_carlo.sampleable - MODEL_CLASSES = [ cls for cls in vars(cara.models).values() if dataclasses.is_dataclass(cls) diff --git a/cara/tests/test_monte_carlo_full_models.py b/cara/tests/test_monte_carlo_full_models.py index eaa7b35e..ffbaef42 100644 --- a/cara/tests/test_monte_carlo_full_models.py +++ b/cara/tests/test_monte_carlo_full_models.py @@ -16,7 +16,6 @@ toronto_coordinates = (43.667, 79.400) toronto_hourly_temperatures_celsius_per_hour = data.get_hourly_temperatures_celsius_per_hour( toronto_coordinates) - # Toronto hourly temperatures as piecewise constant function (in Kelvin). TorontoTemperatures_hourly = { month: models.PiecewiseConstant( @@ -28,7 +27,6 @@ TorontoTemperatures_hourly = { for month, temperatures in toronto_hourly_temperatures_celsius_per_hour.items() } - # Same Toronto temperatures on a finer temperature mesh (every 6 minutes). TorontoTemperatures = { month: TorontoTemperatures_hourly[month].refine(refine_factor=10) @@ -36,7 +34,7 @@ TorontoTemperatures = { } -# references values for infection_probability and expected new cases +# References values for infection_probability and expected new cases # in the following tests, were obtained from the feature/mc branch @pytest.fixture def shared_office_mc(): diff --git a/cara/tests/test_predefined_distributions.py b/cara/tests/test_predefined_distributions.py index 8a670c58..959565f7 100644 --- a/cara/tests/test_predefined_distributions.py +++ b/cara/tests/test_predefined_distributions.py @@ -5,8 +5,7 @@ import pytest from cara.monte_carlo.data import activity_distributions, virus_distributions - -# mean & std deviations from https://doi.org/10.1101/2021.10.14.21264988 (Table 3) +# Mean & std deviations from https://doi.org/10.1101/2021.10.14.21264988 (Table 3) # NOTE: a mistake was corrected for the std deviation of the # "Moderate exercise" case (0.37 in the report, but should be 0.34) @pytest.mark.parametrize( @@ -28,7 +27,7 @@ def test_activity_distributions(distribution, mean, std): npt.assert_allclose(activity.inhalation_rate.std(), std, atol=0.01) -# mean & std deviations from https://doi.org/10.1101/2021.10.14.21264988 (Table 3) +# Mean & std deviations from https://doi.org/10.1101/2021.10.14.21264988 (Table 3) # - with a refined precision on the values @pytest.mark.parametrize( "distribution, mean, std",[ diff --git a/cara/tests/test_sampleable_distribution.py b/cara/tests/test_sampleable_distribution.py index c780e3df..162f2e88 100644 --- a/cara/tests/test_sampleable_distribution.py +++ b/cara/tests/test_sampleable_distribution.py @@ -11,7 +11,7 @@ from cara.monte_carlo import sampleable ] ) def test_normal(mean, std): - # test that the sample has approximately the right mean, + # Test that the sample has approximately the right mean, # std deviation and distribution function. sample_size = 2000000 samples = sampleable.Normal(mean, std).generate_samples(sample_size) @@ -32,7 +32,7 @@ def test_normal(mean, std): ] ) def test_lognormal(mean_gaussian, std_gaussian): - # test that the sample has approximately the right mean, + # Test that the sample has approximately the right mean, # std deviation and distribution function. sample_size = 2000000 samples = sampleable.LogNormal(mean_gaussian, std_gaussian @@ -58,7 +58,7 @@ def test_lognormal(mean_gaussian, std_gaussian): [False, True], ) def test_custom(use_kernel): - # test that the sample has approximately the right distribution + # Test that the sample has approximately the right distribution # function, with both Custom and CustomKernel method. The latter # is less accurate for smooth functions. # the distribution function is an inverted parabola, with maximum 0.15, @@ -87,7 +87,7 @@ def test_custom(use_kernel): def test_logcustomkernel(): - # test that the sample has approximately the right distribution + # Test that the sample has approximately the right distribution # function, for the LogCustomKernel. # the distribution function is an inverted parabola vs. the log of # the variable (normalized)