Merge branch 'changes/schema_update' into 'master'
Data registry update (schema v2.1.1) See merge request caimira/caimira!487
This commit is contained in:
commit
c8b6d882cc
11 changed files with 383 additions and 400 deletions
|
|
@ -42,7 +42,7 @@ from .user import AuthenticatedUser, AnonymousUser
|
||||||
# calculator version. If the calculator needs to make breaking changes (e.g. change
|
# calculator version. If the calculator needs to make breaking changes (e.g. change
|
||||||
# form attributes) then it can also increase its MAJOR version without needing to
|
# form attributes) then it can also increase its MAJOR version without needing to
|
||||||
# increase the overall CAiMIRA version (found at ``caimira.__version__``).
|
# increase the overall CAiMIRA version (found at ``caimira.__version__``).
|
||||||
__version__ = "4.15.2"
|
__version__ = "4.15.3"
|
||||||
|
|
||||||
LOG = logging.getLogger("Calculator")
|
LOG = logging.getLogger("Calculator")
|
||||||
|
|
||||||
|
|
@ -573,7 +573,11 @@ def make_app(
|
||||||
|
|
||||||
data_registry = DataRegistry()
|
data_registry = DataRegistry()
|
||||||
data_service = None
|
data_service = None
|
||||||
data_service_enabled = os.environ.get('DATA_SERVICE_ENABLED', 0)
|
try:
|
||||||
|
data_service_enabled = int(os.environ.get('DATA_SERVICE_ENABLED', 0))
|
||||||
|
except ValueError:
|
||||||
|
data_service_enabled = None
|
||||||
|
|
||||||
if data_service_enabled: data_service = DataService.create()
|
if data_service_enabled: data_service = DataService.create()
|
||||||
|
|
||||||
return Application(
|
return Application(
|
||||||
|
|
|
||||||
|
|
@ -159,7 +159,7 @@ class CO2FormData(FormData):
|
||||||
return tuple((self.CO2_data['times'][0], self.CO2_data['times'][-1]))
|
return tuple((self.CO2_data['times'][0], self.CO2_data['times'][-1]))
|
||||||
|
|
||||||
def build_model(self, size=None) -> models.CO2DataModel: # type: ignore
|
def build_model(self, size=None) -> models.CO2DataModel: # type: ignore
|
||||||
size = size or self.data_registry.monte_carlo_sample_size
|
size = size or self.data_registry.monte_carlo['sample_size']
|
||||||
# Build a simple infected and exposed population for the case when presence
|
# Build a simple infected and exposed population for the case when presence
|
||||||
# intervals and number of people are dynamic. Activity type is not needed.
|
# intervals and number of people are dynamic. Activity type is not needed.
|
||||||
infected_presence = self.infected_present_interval()
|
infected_presence = self.infected_present_interval()
|
||||||
|
|
|
||||||
|
|
@ -200,10 +200,10 @@ class VirusFormData(FormData):
|
||||||
|
|
||||||
if self.arve_sensors_option == False:
|
if self.arve_sensors_option == False:
|
||||||
if self.room_heating_option:
|
if self.room_heating_option:
|
||||||
humidity = self.data_registry.room['defaults']['humidity_with_heating']
|
humidity = self.data_registry.room['humidity_with_heating']
|
||||||
else:
|
else:
|
||||||
humidity = self.data_registry.room['defaults']['humidity_without_heating']
|
humidity = self.data_registry.room['humidity_without_heating']
|
||||||
inside_temp = self.data_registry.room['defaults']['inside_temp']
|
inside_temp = self.data_registry.room['inside_temp']
|
||||||
else:
|
else:
|
||||||
humidity = float(self.humidity)
|
humidity = float(self.humidity)
|
||||||
inside_temp = self.inside_temp
|
inside_temp = self.inside_temp
|
||||||
|
|
@ -245,11 +245,11 @@ class VirusFormData(FormData):
|
||||||
)
|
)
|
||||||
|
|
||||||
def build_model(self, sample_size=None) -> models.ExposureModel:
|
def build_model(self, sample_size=None) -> models.ExposureModel:
|
||||||
sample_size = sample_size or self.data_registry.monte_carlo_sample_size
|
sample_size = sample_size or self.data_registry.monte_carlo['sample_size']
|
||||||
return self.build_mc_model().build_model(size=sample_size)
|
return self.build_mc_model().build_model(size=sample_size)
|
||||||
|
|
||||||
def build_CO2_model(self, sample_size=None) -> models.CO2ConcentrationModel:
|
def build_CO2_model(self, sample_size=None) -> models.CO2ConcentrationModel:
|
||||||
sample_size = sample_size or self.data_registry.monte_carlo_sample_size
|
sample_size = sample_size or self.data_registry.monte_carlo['sample_size']
|
||||||
infected_population: models.InfectedPopulation = self.infected_population().build_model(sample_size)
|
infected_population: models.InfectedPopulation = self.infected_population().build_model(sample_size)
|
||||||
exposed_population: models.Population = self.exposed_population().build_model(sample_size)
|
exposed_population: models.Population = self.exposed_population().build_model(sample_size)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ from caimira.store.data_registry import DataRegistry
|
||||||
from ... import monte_carlo as mc
|
from ... import monte_carlo as mc
|
||||||
from .model_generator import VirusFormData
|
from .model_generator import VirusFormData
|
||||||
from ... import dataclass_utils
|
from ... import dataclass_utils
|
||||||
|
from caimira.enums import ViralLoads
|
||||||
|
|
||||||
|
|
||||||
def model_start_end(model: models.ExposureModel):
|
def model_start_end(model: models.ExposureModel):
|
||||||
|
|
@ -168,12 +169,27 @@ def calculate_report_data(form: VirusFormData, model: models.ExposureModel, exec
|
||||||
prob_dist_count, prob_dist_bins = np.histogram(prob/100, bins=100, density=True)
|
prob_dist_count, prob_dist_bins = np.histogram(prob/100, bins=100, density=True)
|
||||||
prob_probabilistic_exposure = np.array(model.total_probability_rule()).mean()
|
prob_probabilistic_exposure = np.array(model.total_probability_rule()).mean()
|
||||||
expected_new_cases = np.array(model.expected_new_cases()).mean()
|
expected_new_cases = np.array(model.expected_new_cases()).mean()
|
||||||
uncertainties_plot_src = img2base64(_figure2bytes(uncertainties_plot(model, prob))) if form.conditional_probability_plot else None
|
|
||||||
exposed_presence_intervals = [list(interval) for interval in model.exposed.presence_interval().boundaries()]
|
exposed_presence_intervals = [list(interval) for interval in model.exposed.presence_interval().boundaries()]
|
||||||
conditional_probability_data = {key: value for key, value in
|
|
||||||
zip(('viral_loads', 'pi_means', 'lower_percentiles', 'upper_percentiles'),
|
|
||||||
manufacture_conditional_probability_data(model, prob))}
|
|
||||||
|
|
||||||
|
if (model.data_registry.virological_data['virus_distributions'][form.virus_type]['viral_load_in_sputum'] == ViralLoads.COVID_OVERALL.value # type: ignore
|
||||||
|
and form.conditional_probability_plot): # Only generate this data if covid_overall_vl_data is selected.
|
||||||
|
|
||||||
|
viral_load_in_sputum: models._VectorisedFloat = model.concentration_model.infected.virus.viral_load_in_sputum
|
||||||
|
viral_loads, pi_means, lower_percentiles, upper_percentiles = manufacture_conditional_probability_data(model, prob)
|
||||||
|
|
||||||
|
uncertainties_plot_src = img2base64(_figure2bytes(uncertainties_plot(prob, viral_load_in_sputum, viral_loads,
|
||||||
|
pi_means, lower_percentiles, upper_percentiles)))
|
||||||
|
conditional_probability_data = {key: value for key, value in
|
||||||
|
zip(('viral_loads', 'pi_means', 'lower_percentiles', 'upper_percentiles'),
|
||||||
|
(viral_loads, pi_means, lower_percentiles, upper_percentiles))}
|
||||||
|
vl_dist = list(np.log10(viral_load_in_sputum))
|
||||||
|
|
||||||
|
else:
|
||||||
|
uncertainties_plot_src = None
|
||||||
|
conditional_probability_data = None
|
||||||
|
vl = model.concentration_model.virus.viral_load_in_sputum
|
||||||
|
if isinstance(vl, np.ndarray): vl_dist = list(np.log10(model.concentration_model.virus.viral_load_in_sputum))
|
||||||
|
else: vl_dist = np.log10(model.concentration_model.virus.viral_load_in_sputum)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"model_repr": repr(model),
|
"model_repr": repr(model),
|
||||||
|
|
@ -194,7 +210,7 @@ def calculate_report_data(form: VirusFormData, model: models.ExposureModel, exec
|
||||||
"expected_new_cases": expected_new_cases,
|
"expected_new_cases": expected_new_cases,
|
||||||
"uncertainties_plot_src": uncertainties_plot_src,
|
"uncertainties_plot_src": uncertainties_plot_src,
|
||||||
"CO2_concentrations": CO2_concentrations,
|
"CO2_concentrations": CO2_concentrations,
|
||||||
"vl_dist": list(np.log10(model.concentration_model.virus.viral_load_in_sputum)),
|
"vl_dist": vl_dist,
|
||||||
"conditional_probability_data": conditional_probability_data,
|
"conditional_probability_data": conditional_probability_data,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -233,8 +249,8 @@ def conditional_prob_inf_given_vl_dist(
|
||||||
for vl_log in viral_loads:
|
for vl_log in viral_loads:
|
||||||
specific_prob = infection_probability[np.where((vl_log-step/2-specific_vl)*(vl_log+step/2-specific_vl)<0)[0]] #type: ignore
|
specific_prob = infection_probability[np.where((vl_log-step/2-specific_vl)*(vl_log+step/2-specific_vl)<0)[0]] #type: ignore
|
||||||
pi_means.append(specific_prob.mean())
|
pi_means.append(specific_prob.mean())
|
||||||
lower_percentiles.append(np.quantile(specific_prob, data_registry.conditional_prob_inf_given_viral_load['lower_percentile']))
|
lower_percentiles.append(np.quantile(specific_prob, 0.05))
|
||||||
upper_percentiles.append(np.quantile(specific_prob, data_registry.conditional_prob_inf_given_viral_load['upper_percentile']))
|
upper_percentiles.append(np.quantile(specific_prob, 0.95))
|
||||||
|
|
||||||
return pi_means, lower_percentiles, upper_percentiles
|
return pi_means, lower_percentiles, upper_percentiles
|
||||||
|
|
||||||
|
|
@ -245,8 +261,8 @@ def manufacture_conditional_probability_data(
|
||||||
):
|
):
|
||||||
data_registry: DataRegistry = exposure_model.data_registry
|
data_registry: DataRegistry = exposure_model.data_registry
|
||||||
|
|
||||||
min_vl = data_registry.conditional_prob_inf_given_viral_load['min_vl']
|
min_vl = 2
|
||||||
max_vl = data_registry.conditional_prob_inf_given_viral_load['max_vl']
|
max_vl = 10
|
||||||
step = (max_vl - min_vl)/100
|
step = (max_vl - min_vl)/100
|
||||||
viral_loads = np.arange(min_vl, max_vl, step)
|
viral_loads = np.arange(min_vl, max_vl, step)
|
||||||
specific_vl = np.log10(exposure_model.concentration_model.virus.viral_load_in_sputum)
|
specific_vl = np.log10(exposure_model.concentration_model.virus.viral_load_in_sputum)
|
||||||
|
|
@ -256,11 +272,12 @@ def manufacture_conditional_probability_data(
|
||||||
return list(viral_loads), list(pi_means), list(lower_percentiles), list(upper_percentiles)
|
return list(viral_loads), list(pi_means), list(lower_percentiles), list(upper_percentiles)
|
||||||
|
|
||||||
|
|
||||||
def uncertainties_plot(exposure_model: models.ExposureModel, prob: models._VectorisedFloat):
|
def uncertainties_plot(infection_probability: models._VectorisedFloat,
|
||||||
fig = plt.figure(figsize=(4, 7), dpi=110)
|
viral_load_in_sputum: models._VectorisedFloat,
|
||||||
|
viral_loads: models._VectorisedFloat,
|
||||||
infection_probability = prob / 100
|
pi_means: models._VectorisedFloat,
|
||||||
viral_loads, pi_means, lower_percentiles, upper_percentiles = manufacture_conditional_probability_data(exposure_model, infection_probability)
|
lower_percentiles: models._VectorisedFloat,
|
||||||
|
upper_percentiles: models._VectorisedFloat):
|
||||||
|
|
||||||
fig, axs = plt.subplots(2, 3,
|
fig, axs = plt.subplots(2, 3,
|
||||||
gridspec_kw={'width_ratios': [5, 0.5] + [1],
|
gridspec_kw={'width_ratios': [5, 0.5] + [1],
|
||||||
|
|
@ -273,8 +290,8 @@ def uncertainties_plot(exposure_model: models.ExposureModel, prob: models._Vecto
|
||||||
|
|
||||||
axs[0, 1].set_visible(False)
|
axs[0, 1].set_visible(False)
|
||||||
|
|
||||||
axs[0, 0].plot(viral_loads, pi_means, label='Predictive total probability')
|
axs[0, 0].plot(viral_loads, np.array(pi_means)/100, label='Predictive total probability')
|
||||||
axs[0, 0].fill_between(viral_loads, lower_percentiles, upper_percentiles, alpha=0.1, label='5ᵗʰ and 95ᵗʰ percentile')
|
axs[0, 0].fill_between(viral_loads, np.array(lower_percentiles)/100, np.array(upper_percentiles)/100, alpha=0.1, label='5ᵗʰ and 95ᵗʰ percentile')
|
||||||
|
|
||||||
axs[0, 2].hist(infection_probability, bins=30, orientation='horizontal')
|
axs[0, 2].hist(infection_probability, bins=30, orientation='horizontal')
|
||||||
axs[0, 2].set_xticks([])
|
axs[0, 2].set_xticks([])
|
||||||
|
|
@ -285,8 +302,8 @@ def uncertainties_plot(exposure_model: models.ExposureModel, prob: models._Vecto
|
||||||
axs[0, 2].set_xlim(0, highest_bar)
|
axs[0, 2].set_xlim(0, highest_bar)
|
||||||
|
|
||||||
axs[0, 2].text(highest_bar * 0.5, 0.5,
|
axs[0, 2].text(highest_bar * 0.5, 0.5,
|
||||||
rf"$\bf{np.round(np.mean(infection_probability) * 100, 1)}$%", ha='center', va='center')
|
rf"$\bf{np.round(np.mean(infection_probability), 1)}$%", ha='center', va='center')
|
||||||
axs[1, 0].hist(np.log10(exposure_model.concentration_model.infected.virus.viral_load_in_sputum),
|
axs[1, 0].hist(np.log10(viral_load_in_sputum),
|
||||||
bins=150, range=(2, 10), color='grey')
|
bins=150, range=(2, 10), color='grey')
|
||||||
axs[1, 0].set_facecolor("lightgrey")
|
axs[1, 0].set_facecolor("lightgrey")
|
||||||
axs[1, 0].set_yticks([])
|
axs[1, 0].set_yticks([])
|
||||||
|
|
@ -442,7 +459,7 @@ def scenario_statistics(
|
||||||
sample_times: typing.List[float],
|
sample_times: typing.List[float],
|
||||||
compute_prob_exposure: bool
|
compute_prob_exposure: bool
|
||||||
):
|
):
|
||||||
model = mc_model.build_model(size=mc_model.data_registry.monte_carlo_sample_size)
|
model = mc_model.build_model(size=mc_model.data_registry.monte_carlo['sample_size'])
|
||||||
if (compute_prob_exposure):
|
if (compute_prob_exposure):
|
||||||
# It means we have data to calculate the total_probability_rule
|
# It means we have data to calculate the total_probability_rule
|
||||||
prob_probabilistic_exposure = model.total_probability_rule()
|
prob_probabilistic_exposure = model.total_probability_rule()
|
||||||
|
|
|
||||||
|
|
@ -214,11 +214,12 @@
|
||||||
draw_histogram("prob_inf_hist", {{ prob_inf }}, {{ prob_inf_sd }});
|
draw_histogram("prob_inf_hist", {{ prob_inf }}, {{ prob_inf_sd }});
|
||||||
</script>
|
</script>
|
||||||
<br>
|
<br>
|
||||||
|
{% if model.data_registry.virological_data['virus_distributions'][form.virus_type]['viral_load_in_sputum'] == 'Ref: Viral load - covid_overal_vl_data' %}
|
||||||
<div class="form-check">
|
<div class="form-check">
|
||||||
<input type="checkbox" id="conditional_probability_plot" class="tabbed form-check-input" name="conditional_probability_plot" value="1" onClick="conditional_probability_plot(this.checked, {{ form.conditional_probability_plot | int }});">
|
<input type="checkbox" id="conditional_probability_plot" class="tabbed form-check-input" name="conditional_probability_plot" value="1" onClick="conditional_probability_plot(this.checked, {{ form.conditional_probability_plot | int }});">
|
||||||
<label id="label_conditional_probability_plot" for="conditional_probability_plot" class="form-check-label col-sm-12">Generate full uncertainty data (as function of the viral load)</label>
|
<label id="label_conditional_probability_plot" for="conditional_probability_plot" class="form-check-label col-sm-12">Generate full uncertainty data (as function of the viral load)</label>
|
||||||
</div>
|
</div>
|
||||||
|
{% endif %}
|
||||||
{% if form.conditional_probability_plot %}
|
{% if form.conditional_probability_plot %}
|
||||||
<div id="conditional_probability_div">
|
<div id="conditional_probability_div">
|
||||||
<img src= "{{ uncertainties_plot_src }}" />
|
<img src= "{{ uncertainties_plot_src }}" />
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,3 @@ from enum import Enum
|
||||||
class ViralLoads(Enum):
|
class ViralLoads(Enum):
|
||||||
COVID_OVERALL = "Ref: Viral load - covid_overal_vl_data"
|
COVID_OVERALL = "Ref: Viral load - covid_overal_vl_data"
|
||||||
SYMPTOMATIC_FREQUENCIES = "Ref: Viral load - symptomatic_vl_frequencies"
|
SYMPTOMATIC_FREQUENCIES = "Ref: Viral load - symptomatic_vl_frequencies"
|
||||||
|
|
||||||
|
|
||||||
class InfectiousDoses(Enum):
|
|
||||||
DISTRIBUTION = "Ref: Infectious dose - infectious_dose_distribution"
|
|
||||||
|
|
||||||
|
|
||||||
class ViableToRNARatios(Enum):
|
|
||||||
DISTRIBUTION = "Ref: Viable to RNA ratio - viable_to_RNA_ratio_distribution"
|
|
||||||
|
|
|
||||||
|
|
@ -879,7 +879,7 @@ class _PopulationWithVirus(Population):
|
||||||
The fraction of infectious virus.
|
The fraction of infectious virus.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.data_registry.population_with_virus['fraction_of_infectious_virus'] # type: ignore
|
return 1
|
||||||
|
|
||||||
def aerosols(self):
|
def aerosols(self):
|
||||||
"""
|
"""
|
||||||
|
|
@ -1052,7 +1052,7 @@ class _ConcentrationModelBase:
|
||||||
(in the same unit as the concentration). Its the value towards which
|
(in the same unit as the concentration). Its the value towards which
|
||||||
the concentration will decay to.
|
the concentration will decay to.
|
||||||
"""
|
"""
|
||||||
return self.data_registry.concentration_model['min_background_concentration'] # type: ignore
|
return self.data_registry.concentration_model['virus_concentration_model']['min_background_concentration'] # type: ignore
|
||||||
|
|
||||||
def normalization_factor(self) -> _VectorisedFloat:
|
def normalization_factor(self) -> _VectorisedFloat:
|
||||||
"""
|
"""
|
||||||
|
|
@ -1242,7 +1242,7 @@ class ConcentrationModel(_ConcentrationModelBase):
|
||||||
|
|
||||||
def __post_init__(self):
|
def __post_init__(self):
|
||||||
if self.evaporation_factor is None:
|
if self.evaporation_factor is None:
|
||||||
self.evaporation_factor = self.data_registry.particle['evaporation_factor']
|
self.evaporation_factor = self.data_registry.expiration_particle['particle']['evaporation_factor']
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def population(self) -> InfectedPopulation:
|
def population(self) -> InfectedPopulation:
|
||||||
|
|
@ -1335,7 +1335,7 @@ class ShortRangeModel:
|
||||||
'''
|
'''
|
||||||
The dilution factor for the respective expiratory activity type.
|
The dilution factor for the respective expiratory activity type.
|
||||||
'''
|
'''
|
||||||
_dilution_factor = self.data_registry.short_range_model['dilution_factor']
|
_dilution_factor = self.data_registry.short_range_model['dilution_factor']
|
||||||
# Average mouth opening diameter (m)
|
# Average mouth opening diameter (m)
|
||||||
mouth_diameter: float = _dilution_factor['mouth_diameter'] # type: ignore
|
mouth_diameter: float = _dilution_factor['mouth_diameter'] # type: ignore
|
||||||
|
|
||||||
|
|
@ -1355,11 +1355,14 @@ class ShortRangeModel:
|
||||||
# Initial velocity of the exhalation airflow (m/s)
|
# Initial velocity of the exhalation airflow (m/s)
|
||||||
u0 = np.array(Q_exh/Am)
|
u0 = np.array(Q_exh/Am)
|
||||||
|
|
||||||
# Duration of the expiration period(s), assuming a 4s breath-cycle
|
# Duration of one breathing cycle
|
||||||
tstar: float = _dilution_factor['tstar'] # type: ignore
|
breathing_cicle: float = _dilution_factor['breathing_cycle'] # type: ignore
|
||||||
|
|
||||||
|
# Duration of the expiration period(s)
|
||||||
|
tstar: float = breathing_cicle / 2
|
||||||
|
|
||||||
# Streamwise and radial penetration coefficients
|
# Streamwise and radial penetration coefficients
|
||||||
_df_pc = _dilution_factor['penetration_coefficients']
|
_df_pc = _dilution_factor['penetration_coefficients'] # type: ignore
|
||||||
𝛽r1: float = _df_pc['𝛽r1'] # type: ignore
|
𝛽r1: float = _df_pc['𝛽r1'] # type: ignore
|
||||||
𝛽r2: float = _df_pc['𝛽r2'] # type: ignore
|
𝛽r2: float = _df_pc['𝛽r2'] # type: ignore
|
||||||
𝛽x1: float = _df_pc['𝛽x1'] # type: ignore
|
𝛽x1: float = _df_pc['𝛽x1'] # type: ignore
|
||||||
|
|
@ -1585,7 +1588,7 @@ class ExposureModel:
|
||||||
#: The number of times the exposure event is repeated (default 1).
|
#: The number of times the exposure event is repeated (default 1).
|
||||||
@property
|
@property
|
||||||
def repeats(self) -> int:
|
def repeats(self) -> int:
|
||||||
return self.data_registry.exposure_model['repeats'] # type: ignore
|
return 1
|
||||||
|
|
||||||
def __post_init__(self):
|
def __post_init__(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -7,84 +7,72 @@ import numpy as np
|
||||||
from scipy import special as sp
|
from scipy import special as sp
|
||||||
from scipy.stats import weibull_min
|
from scipy.stats import weibull_min
|
||||||
|
|
||||||
from caimira.enums import ViralLoads, InfectiousDoses, ViableToRNARatios
|
from caimira.enums import ViralLoads
|
||||||
|
|
||||||
import caimira.monte_carlo.models as mc
|
import caimira.monte_carlo.models as mc
|
||||||
from caimira.monte_carlo.sampleable import LogCustom, LogNormal, Normal, LogCustomKernel, CustomKernel, Uniform, Custom
|
from caimira.monte_carlo.sampleable import LogCustom, LogNormal, Normal, LogCustomKernel, CustomKernel, Uniform, Custom
|
||||||
from caimira.store.data_registry import DataRegistry
|
from caimira.store.data_registry import DataRegistry
|
||||||
|
|
||||||
|
|
||||||
def evaluate_vl(value, data_registry: DataRegistry):
|
def evaluate_vl(root: typing.Dict, value: str, data_registry: DataRegistry):
|
||||||
if value == ViralLoads.COVID_OVERALL.value:
|
if root[value] == ViralLoads.COVID_OVERALL.value:
|
||||||
return covid_overal_vl_data(data_registry)
|
return covid_overal_vl_data(data_registry)
|
||||||
elif value == ViralLoads.SYMPTOMATIC_FREQUENCIES.value:
|
elif root[value] == ViralLoads.SYMPTOMATIC_FREQUENCIES.value:
|
||||||
return symptomatic_vl_frequencies
|
return symptomatic_vl_frequencies
|
||||||
|
elif root[value] == 'Custom':
|
||||||
|
return param_evaluation(root, 'Viral load custom')
|
||||||
else:
|
else:
|
||||||
raise ValueError(f"Invalid ViralLoads value {value}")
|
raise ValueError(f"Invalid ViralLoads value {value}")
|
||||||
|
|
||||||
|
|
||||||
def evaluate_infectd(value, data_registry: DataRegistry):
|
|
||||||
if value == InfectiousDoses.DISTRIBUTION.value:
|
|
||||||
return infectious_dose_distribution(data_registry)
|
|
||||||
else:
|
|
||||||
raise ValueError(f"Invalid InfectiousDoses value {value}")
|
|
||||||
|
|
||||||
|
|
||||||
def evaluate_vtrr(value, data_registry: DataRegistry):
|
|
||||||
if value == ViableToRNARatios.DISTRIBUTION.value:
|
|
||||||
return viable_to_RNA_ratio_distribution(data_registry)
|
|
||||||
else:
|
|
||||||
raise ValueError(f"Invalid ViableToRNARatios value {value}")
|
|
||||||
|
|
||||||
|
|
||||||
sqrt2pi = np.sqrt(2.*np.pi)
|
sqrt2pi = np.sqrt(2.*np.pi)
|
||||||
sqrt2 = np.sqrt(2.)
|
sqrt2 = np.sqrt(2.)
|
||||||
|
|
||||||
|
|
||||||
def custom_distribution_lookup(dict: dict, key_part: str) -> typing.Any:
|
def custom_value_type_lookup(dict: dict, key_part: str) -> typing.Any:
|
||||||
"""
|
"""
|
||||||
Look up a custom distribution based on a partial key.
|
Look up a custom value type based on a partial key.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
dict (dict): The root to search.
|
dict (dict): The root to search.
|
||||||
key_part (str): The distribution key to match.
|
key_part (str): The value type key to match.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
str: The associated distribution.
|
str: The associated value.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
for key, value in dict.items():
|
for key, value in dict.items():
|
||||||
if (key_part in key):
|
if (key_part in key):
|
||||||
return value['associated_distribution']
|
return value['associated_value']
|
||||||
except KeyError:
|
except KeyError:
|
||||||
return f"Key '{key_part}' not found."
|
return f"Key '{key_part}' not found."
|
||||||
|
|
||||||
|
|
||||||
def evaluate_custom_distribution(dist: str, params: typing.Dict) -> typing.Any:
|
def evaluate_custom_value_type(value_type: str, params: typing.Dict) -> typing.Any:
|
||||||
"""
|
"""
|
||||||
Evaluate a custom distribution.
|
Evaluate a custom value type.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
dist (str): The type of distribution.
|
dist (str): The type of value.
|
||||||
params (Dict): The parameters for the distribution.
|
params (Dict): The parameters for the value type.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Any: The generated distribution.
|
Any: The generated value.
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
ValueError: If the distribution type is not recognized.
|
ValueError: If the value type is not recognized.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if dist == 'Linear Space':
|
if value_type == 'Constant value':
|
||||||
return np.linspace(params['start'], params['stop'], params['num'])
|
return params
|
||||||
elif dist == 'Normal':
|
elif value_type == 'Normal distribution':
|
||||||
return Normal(params['normal_mean_gaussian'], params['normal_standard_deviation_gaussian'])
|
return Normal(params['normal_mean_gaussian'], params['normal_standard_deviation_gaussian'])
|
||||||
elif dist == 'Log-normal':
|
elif value_type == 'Log-normal distribution':
|
||||||
return LogNormal(params['lognormal_mean_gaussian'], params['lognormal_standard_deviation_gaussian'])
|
return LogNormal(params['lognormal_mean_gaussian'], params['lognormal_standard_deviation_gaussian'])
|
||||||
elif dist == 'Uniform':
|
elif value_type == 'Uniform distribution':
|
||||||
return Uniform(params['low'], params['high'])
|
return Uniform(params['low'], params['high'])
|
||||||
else:
|
else:
|
||||||
raise ValueError('Bad request - distribution not found.')
|
raise ValueError('Bad request - value type not found.')
|
||||||
|
|
||||||
|
|
||||||
def param_evaluation(root: typing.Dict, param: typing.Union[str, typing.Any]) -> typing.Any:
|
def param_evaluation(root: typing.Dict, param: typing.Union[str, typing.Any]) -> typing.Any:
|
||||||
|
|
@ -104,17 +92,10 @@ def param_evaluation(root: typing.Dict, param: typing.Union[str, typing.Any]) ->
|
||||||
"""
|
"""
|
||||||
value = root.get(param)
|
value = root.get(param)
|
||||||
|
|
||||||
if isinstance(value, str):
|
if isinstance(value, dict):
|
||||||
if value == 'Custom':
|
value_type: str = root[param]['associated_value']
|
||||||
custom_distribution: typing.Dict = custom_distribution_lookup(
|
|
||||||
root, 'custom distribution')
|
|
||||||
for d, p in custom_distribution.items():
|
|
||||||
return evaluate_custom_distribution(d, p)
|
|
||||||
|
|
||||||
elif isinstance(value, dict):
|
|
||||||
dist: str = root[param]['associated_distribution']
|
|
||||||
params: typing.Dict = root[param]['parameters']
|
params: typing.Dict = root[param]['parameters']
|
||||||
return evaluate_custom_distribution(dist, params)
|
return evaluate_custom_value_type(value_type, params)
|
||||||
|
|
||||||
elif isinstance(value, float) or isinstance(value, int):
|
elif isinstance(value, float) or isinstance(value, int):
|
||||||
return value
|
return value
|
||||||
|
|
@ -148,21 +129,21 @@ class BLOmodel:
|
||||||
# total concentration of aerosols for each mode.
|
# total concentration of aerosols for each mode.
|
||||||
@property
|
@property
|
||||||
def cn(self) -> typing.Tuple[float, float, float]:
|
def cn(self) -> typing.Tuple[float, float, float]:
|
||||||
_cn = self.data_registry.BLOmodel['cn']
|
_cn = self.data_registry.expiration_particle['BLOmodel']['cn'] # type: ignore
|
||||||
return (_cn['B'],_cn['L'],_cn['O'])
|
return (_cn['B'],_cn['L'],_cn['O'])
|
||||||
|
|
||||||
# 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.
|
# diameter in microns), for resp. the B, L and O modes.
|
||||||
@property
|
@property
|
||||||
def mu(self) -> typing.Tuple[float, float, float]:
|
def mu(self) -> typing.Tuple[float, float, float]:
|
||||||
_mu = self.data_registry.BLOmodel['mu']
|
_mu = self.data_registry.expiration_particle['BLOmodel']['mu'] # type: ignore
|
||||||
return (_mu['B'], _mu['L'], _mu['O'])
|
return (_mu['B'], _mu['L'], _mu['O'])
|
||||||
|
|
||||||
# Std deviation of the underlying normal distribution, for resp.
|
# Std deviation of the underlying normal distribution, for resp.
|
||||||
# the B, L and O modes.
|
# the B, L and O modes.
|
||||||
@property
|
@property
|
||||||
def sigma(self) -> typing.Tuple[float, float, float]:
|
def sigma(self) -> typing.Tuple[float, float, float]:
|
||||||
_sigma = self.data_registry.BLOmodel['sigma']
|
_sigma = self.data_registry.expiration_particle['BLOmodel']['sigma'] # type: ignore
|
||||||
return (_sigma['B'],_sigma['L'],_sigma['O'])
|
return (_sigma['B'],_sigma['L'],_sigma['O'])
|
||||||
|
|
||||||
def distribution(self, d):
|
def distribution(self, d):
|
||||||
|
|
@ -229,19 +210,12 @@ def activity_distributions(data_registry):
|
||||||
|
|
||||||
|
|
||||||
# From https://doi.org/10.1101/2021.10.14.21264988 and references therein
|
# From https://doi.org/10.1101/2021.10.14.21264988 and references therein
|
||||||
symptomatic_vl_frequencies = LogCustomKernel(
|
def symptomatic_vl_frequencies(data_registry):
|
||||||
np.array((2.46032, 2.67431, 2.85434, 3.06155, 3.25856, 3.47256, 3.66957, 3.85979, 4.09927, 4.27081,
|
return LogCustomKernel(
|
||||||
4.47631, 4.66653, 4.87204, 5.10302, 5.27456, 5.46478, 5.6533, 5.88428, 6.07281, 6.30549,
|
np.array(data_registry.virological_data['symptomatic_vl_frequencies']['log_variable']),
|
||||||
6.48552, 6.64856, 6.85407, 7.10373, 7.30075, 7.47229, 7.66081, 7.85782, 8.05653, 8.27053,
|
np.array(data_registry.virological_data['symptomatic_vl_frequencies']['frequencies']),
|
||||||
8.48453, 8.65607, 8.90573, 9.06878, 9.27429, 9.473, 9.66152, 9.87552)),
|
kernel_bandwidth=data_registry.virological_data['symptomatic_vl_frequencies']['kernel_bandwidth']
|
||||||
np.array((0.001206885, 0.007851618, 0.008078144, 0.01502491, 0.013258014, 0.018528495, 0.020053765,
|
)
|
||||||
0.021896167, 0.022047184, 0.018604005, 0.01547796, 0.018075445, 0.021503523, 0.022349217,
|
|
||||||
0.025097721, 0.032875078, 0.030594727, 0.032573045, 0.034717482, 0.034792991,
|
|
||||||
0.033267721, 0.042887485, 0.036846816, 0.03876473, 0.045016819, 0.040063473, 0.04883754,
|
|
||||||
0.043944602, 0.048142864, 0.041588741, 0.048762031, 0.027921732, 0.033871788,
|
|
||||||
0.022122693, 0.016927718, 0.008833228, 0.00478598, 0.002807662)),
|
|
||||||
kernel_bandwidth=0.1
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
# Weibull distribution with a shape factor of 3.47 and a scale factor of 7.01.
|
# Weibull distribution with a shape factor of 3.47 and a scale factor of 7.01.
|
||||||
|
|
@ -250,86 +224,86 @@ symptomatic_vl_frequencies = LogCustomKernel(
|
||||||
def viral_load(data_registry):
|
def viral_load(data_registry):
|
||||||
return np.linspace(
|
return np.linspace(
|
||||||
weibull_min.ppf(
|
weibull_min.ppf(
|
||||||
data_registry.covid_overal_vl_data['start'],
|
data_registry.virological_data['covid_overal_vl_data']['start'],
|
||||||
c=data_registry.covid_overal_vl_data['shape_factor'],
|
c=data_registry.virological_data['covid_overal_vl_data']['shape_factor'],
|
||||||
scale=data_registry.covid_overal_vl_data['scale_factor']
|
scale=data_registry.virological_data['covid_overal_vl_data']['scale_factor']
|
||||||
),
|
),
|
||||||
weibull_min.ppf(
|
weibull_min.ppf(
|
||||||
data_registry.covid_overal_vl_data['stop'],
|
data_registry.virological_data['covid_overal_vl_data']['stop'],
|
||||||
c=data_registry.covid_overal_vl_data['shape_factor'],
|
c=data_registry.virological_data['covid_overal_vl_data']['shape_factor'],
|
||||||
scale=data_registry.covid_overal_vl_data['scale_factor']
|
scale=data_registry.virological_data['covid_overal_vl_data']['scale_factor']
|
||||||
),
|
),
|
||||||
int(data_registry.covid_overal_vl_data['num'])
|
int(data_registry.virological_data['covid_overal_vl_data']['num'])
|
||||||
)
|
)
|
||||||
def frequencies_pdf(data_registry):
|
def frequencies_pdf(data_registry):
|
||||||
return weibull_min.pdf(
|
return weibull_min.pdf(
|
||||||
viral_load(data_registry),
|
viral_load(data_registry),
|
||||||
c=data_registry.covid_overal_vl_data['shape_factor'],
|
c=data_registry.virological_data['covid_overal_vl_data']['shape_factor'],
|
||||||
scale=data_registry.covid_overal_vl_data['scale_factor']
|
scale=data_registry.virological_data['covid_overal_vl_data']['scale_factor']
|
||||||
)
|
)
|
||||||
def covid_overal_vl_data(data_registry):
|
def covid_overal_vl_data(data_registry):
|
||||||
return LogCustom(
|
return LogCustom(
|
||||||
bounds=(data_registry.covid_overal_vl_data['min_bound'], data_registry.covid_overal_vl_data['max_bound']),
|
bounds=(data_registry.virological_data['covid_overal_vl_data']['min_bound'], data_registry.virological_data['covid_overal_vl_data']['max_bound']),
|
||||||
function=lambda d: np.interp(
|
function=lambda d: np.interp(
|
||||||
d,
|
d,
|
||||||
viral_load(data_registry),
|
viral_load(data_registry),
|
||||||
frequencies_pdf(data_registry),
|
frequencies_pdf(data_registry),
|
||||||
data_registry.covid_overal_vl_data['interpolation_fp_left'],
|
data_registry.virological_data['covid_overal_vl_data']['interpolation_fp_left'],
|
||||||
data_registry.covid_overal_vl_data['interpolation_fp_right']
|
data_registry.virological_data['covid_overal_vl_data']['interpolation_fp_right']
|
||||||
),
|
),
|
||||||
max_function=data_registry.covid_overal_vl_data['max_function']
|
max_function=data_registry.virological_data['covid_overal_vl_data']['max_function']
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# Derived from data in doi.org/10.1016/j.ijid.2020.09.025 and
|
# Derived from data in doi.org/10.1016/j.ijid.2020.09.025 and
|
||||||
# https://iosh.com/media/8432/aerosol-infection-risk-hospital-patient-care-full-report.pdf (page 60)
|
# https://iosh.com/media/8432/aerosol-infection-risk-hospital-patient-care-full-report.pdf (page 60)
|
||||||
def viable_to_RNA_ratio_distribution(data_registry):
|
def viable_to_RNA_ratio_distribution():
|
||||||
return Uniform(data_registry.viable_to_RNA_ratio_distribution['low'], data_registry.viable_to_RNA_ratio_distribution['high'])
|
return Uniform(0.01, 0.6)
|
||||||
|
|
||||||
|
|
||||||
# From discussion with virologists
|
# From discussion with virologists
|
||||||
def infectious_dose_distribution(data_registry):
|
def infectious_dose_distribution():
|
||||||
return Uniform(data_registry.infectious_dose_distribution['low'], data_registry.infectious_dose_distribution['high'])
|
return Uniform(10., 100.)
|
||||||
|
|
||||||
|
|
||||||
# From https://doi.org/10.1101/2021.10.14.21264988 and references therein
|
# From https://doi.org/10.1101/2021.10.14.21264988 and references therein
|
||||||
def virus_distributions(data_registry):
|
def virus_distributions(data_registry):
|
||||||
vd = data_registry.virus_distributions
|
vd = data_registry.virological_data['virus_distributions']
|
||||||
return {
|
return {
|
||||||
'SARS_CoV_2': mc.SARSCoV2(
|
'SARS_CoV_2': mc.SARSCoV2(
|
||||||
viral_load_in_sputum=evaluate_vl(vd['SARS_CoV_2']['viral_load_in_sputum'], data_registry),
|
viral_load_in_sputum=evaluate_vl(vd['SARS_CoV_2'], 'viral_load_in_sputum', data_registry),
|
||||||
infectious_dose=evaluate_infectd(vd['SARS_CoV_2']['infectious_dose'], data_registry),
|
infectious_dose=param_evaluation(vd['SARS_CoV_2'], 'infectious_dose'),
|
||||||
viable_to_RNA_ratio=evaluate_vtrr(vd['SARS_CoV_2']['viable_to_RNA_ratio'], data_registry),
|
viable_to_RNA_ratio=param_evaluation(vd['SARS_CoV_2'], 'viable_to_RNA_ratio'),
|
||||||
transmissibility_factor=vd['SARS_CoV_2']['transmissibility_factor'],
|
transmissibility_factor=vd['SARS_CoV_2']['transmissibility_factor'],
|
||||||
),
|
),
|
||||||
'SARS_CoV_2_ALPHA': mc.SARSCoV2(
|
'SARS_CoV_2_ALPHA': mc.SARSCoV2(
|
||||||
viral_load_in_sputum=evaluate_vl(vd['SARS_CoV_2_ALPHA']['viral_load_in_sputum'], data_registry),
|
viral_load_in_sputum=evaluate_vl(vd['SARS_CoV_2_ALPHA'], 'viral_load_in_sputum', data_registry),
|
||||||
infectious_dose=evaluate_infectd(vd['SARS_CoV_2_ALPHA']['infectious_dose'], data_registry),
|
infectious_dose=param_evaluation(vd['SARS_CoV_2_ALPHA'], 'infectious_dose'),
|
||||||
viable_to_RNA_ratio=evaluate_vtrr(vd['SARS_CoV_2_ALPHA']['viable_to_RNA_ratio'], data_registry),
|
viable_to_RNA_ratio=param_evaluation(vd['SARS_CoV_2_ALPHA'], 'viable_to_RNA_ratio'),
|
||||||
transmissibility_factor=vd['SARS_CoV_2_ALPHA']['transmissibility_factor'],
|
transmissibility_factor=vd['SARS_CoV_2_ALPHA']['transmissibility_factor'],
|
||||||
),
|
),
|
||||||
'SARS_CoV_2_BETA': mc.SARSCoV2(
|
'SARS_CoV_2_BETA': mc.SARSCoV2(
|
||||||
viral_load_in_sputum=evaluate_vl(vd['SARS_CoV_2_BETA']['viral_load_in_sputum'], data_registry),
|
viral_load_in_sputum=evaluate_vl(vd['SARS_CoV_2_BETA'], 'viral_load_in_sputum', data_registry),
|
||||||
infectious_dose=evaluate_infectd(vd['SARS_CoV_2_BETA']['infectious_dose'], data_registry),
|
infectious_dose=param_evaluation(vd['SARS_CoV_2_BETA'], 'infectious_dose'),
|
||||||
viable_to_RNA_ratio=evaluate_vtrr(vd['SARS_CoV_2_BETA']['viable_to_RNA_ratio'], data_registry),
|
viable_to_RNA_ratio=param_evaluation(vd['SARS_CoV_2_BETA'], 'viable_to_RNA_ratio'),
|
||||||
transmissibility_factor=vd['SARS_CoV_2_BETA']['transmissibility_factor'],
|
transmissibility_factor=vd['SARS_CoV_2_BETA']['transmissibility_factor'],
|
||||||
),
|
),
|
||||||
'SARS_CoV_2_GAMMA': mc.SARSCoV2(
|
'SARS_CoV_2_GAMMA': mc.SARSCoV2(
|
||||||
viral_load_in_sputum=evaluate_vl(vd['SARS_CoV_2_GAMMA']['viral_load_in_sputum'], data_registry),
|
viral_load_in_sputum=evaluate_vl(vd['SARS_CoV_2_GAMMA'], 'viral_load_in_sputum', data_registry),
|
||||||
infectious_dose=evaluate_infectd(vd['SARS_CoV_2_GAMMA']['infectious_dose'], data_registry),
|
infectious_dose=param_evaluation(vd['SARS_CoV_2_GAMMA'], 'infectious_dose'),
|
||||||
viable_to_RNA_ratio=evaluate_vtrr(vd['SARS_CoV_2_GAMMA']['viable_to_RNA_ratio'], data_registry),
|
viable_to_RNA_ratio=param_evaluation(vd['SARS_CoV_2_GAMMA'], 'viable_to_RNA_ratio'),
|
||||||
transmissibility_factor=vd['SARS_CoV_2_GAMMA']['transmissibility_factor'],
|
transmissibility_factor=vd['SARS_CoV_2_GAMMA']['transmissibility_factor'],
|
||||||
),
|
),
|
||||||
'SARS_CoV_2_DELTA': mc.SARSCoV2(
|
'SARS_CoV_2_DELTA': mc.SARSCoV2(
|
||||||
viral_load_in_sputum=evaluate_vl(vd['SARS_CoV_2_DELTA']['viral_load_in_sputum'], data_registry),
|
viral_load_in_sputum=evaluate_vl(vd['SARS_CoV_2_DELTA'], 'viral_load_in_sputum', data_registry),
|
||||||
infectious_dose=evaluate_infectd(vd['SARS_CoV_2_DELTA']['infectious_dose'], data_registry),
|
infectious_dose=param_evaluation(vd['SARS_CoV_2_DELTA'], 'infectious_dose'),
|
||||||
viable_to_RNA_ratio=evaluate_vtrr(vd['SARS_CoV_2_DELTA']['viable_to_RNA_ratio'], data_registry),
|
viable_to_RNA_ratio=param_evaluation(vd['SARS_CoV_2_DELTA'], 'viable_to_RNA_ratio'),
|
||||||
transmissibility_factor=vd['SARS_CoV_2_DELTA']['transmissibility_factor'],
|
transmissibility_factor=vd['SARS_CoV_2_DELTA']['transmissibility_factor'],
|
||||||
),
|
),
|
||||||
'SARS_CoV_2_OMICRON': mc.SARSCoV2(
|
'SARS_CoV_2_OMICRON': mc.SARSCoV2(
|
||||||
viral_load_in_sputum=evaluate_vl(vd['SARS_CoV_2_OMICRON']['viral_load_in_sputum'], data_registry),
|
viral_load_in_sputum=evaluate_vl(vd['SARS_CoV_2_OMICRON'], 'viral_load_in_sputum', data_registry),
|
||||||
infectious_dose=evaluate_infectd(vd['SARS_CoV_2_OMICRON']['infectious_dose'], data_registry),
|
infectious_dose=param_evaluation(vd['SARS_CoV_2_OMICRON'], 'infectious_dose'),
|
||||||
viable_to_RNA_ratio=evaluate_vtrr(vd['SARS_CoV_2_OMICRON']['viable_to_RNA_ratio'], data_registry),
|
viable_to_RNA_ratio=param_evaluation(vd['SARS_CoV_2_OMICRON'], 'viable_to_RNA_ratio'),
|
||||||
transmissibility_factor=vd['SARS_CoV_2_OMICRON']['transmissibility_factor'],
|
transmissibility_factor=vd['SARS_CoV_2_OMICRON']['transmissibility_factor'],
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
@ -347,21 +321,21 @@ def mask_distributions(data_registry):
|
||||||
data_registry.mask_distributions['Type I'], 'η_inhale'),
|
data_registry.mask_distributions['Type I'], 'η_inhale'),
|
||||||
η_exhale=param_evaluation(
|
η_exhale=param_evaluation(
|
||||||
data_registry.mask_distributions['Type I'], 'η_exhale')
|
data_registry.mask_distributions['Type I'], 'η_exhale')
|
||||||
if data_registry.mask_distributions['Type I']['Known filtration efficiency of masks when exhaling?'] == 'Yes' else None,
|
if data_registry.mask_distributions['Type I'].get('η_exhale') is not None else None
|
||||||
),
|
),
|
||||||
'FFP2': mc.Mask(
|
'FFP2': mc.Mask(
|
||||||
η_inhale=param_evaluation(
|
η_inhale=param_evaluation(
|
||||||
data_registry.mask_distributions['FFP2'], 'η_inhale'),
|
data_registry.mask_distributions['FFP2'], 'η_inhale'),
|
||||||
η_exhale=param_evaluation(
|
η_exhale=param_evaluation(
|
||||||
data_registry.mask_distributions['FFP2'], 'η_exhale')
|
data_registry.mask_distributions['FFP2'], 'η_exhale')
|
||||||
if data_registry.mask_distributions['FFP2']['Known filtration efficiency of masks when exhaling?'] == 'Yes' else None,
|
if data_registry.mask_distributions['FFP2'].get('η_exhale') is not None else None
|
||||||
),
|
),
|
||||||
'Cloth': mc.Mask(
|
'Cloth': mc.Mask(
|
||||||
η_inhale=param_evaluation(
|
η_inhale=param_evaluation(
|
||||||
data_registry.mask_distributions['Cloth'], 'η_inhale'),
|
data_registry.mask_distributions['Cloth'], 'η_inhale'),
|
||||||
η_exhale=param_evaluation(
|
η_exhale=param_evaluation(
|
||||||
data_registry.mask_distributions['Cloth'], 'η_exhale')
|
data_registry.mask_distributions['Cloth'], 'η_exhale')
|
||||||
if data_registry.mask_distributions['Cloth']['Known filtration efficiency of masks when exhaling?'] == 'Yes' else None,
|
if data_registry.mask_distributions['Cloth'].get('η_exhale') is not None else None
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -392,10 +366,10 @@ def expiration_distribution(
|
||||||
|
|
||||||
|
|
||||||
def expiration_BLO_factors(data_registry):
|
def expiration_BLO_factors(data_registry):
|
||||||
breathing = data_registry.expiration_BLO_factors['Breathing']
|
breathing = data_registry.expiration_particle['expiration_BLO_factors']['Breathing']
|
||||||
speaking = data_registry.expiration_BLO_factors['Speaking']
|
speaking = data_registry.expiration_particle['expiration_BLO_factors']['Speaking']
|
||||||
singing = data_registry.expiration_BLO_factors['Singing']
|
singing = data_registry.expiration_particle['expiration_BLO_factors']['Singing']
|
||||||
shouting = data_registry.expiration_BLO_factors['Shouting']
|
shouting = data_registry.expiration_particle['expiration_BLO_factors']['Shouting']
|
||||||
return {
|
return {
|
||||||
'Breathing': (
|
'Breathing': (
|
||||||
param_evaluation(breathing, 'B'),
|
param_evaluation(breathing, 'B'),
|
||||||
|
|
@ -425,8 +399,8 @@ def expiration_distributions(data_registry):
|
||||||
exp_type: expiration_distribution(
|
exp_type: expiration_distribution(
|
||||||
data_registry=data_registry,
|
data_registry=data_registry,
|
||||||
BLO_factors=BLO_factors,
|
BLO_factors=BLO_factors,
|
||||||
d_min=param_evaluation(data_registry.long_range_expiration_distributions, 'minimum_diameter'),
|
d_min=param_evaluation(data_registry.expiration_particle['long_range_expiration_distributions'], 'minimum_diameter'),
|
||||||
d_max=param_evaluation(data_registry.long_range_expiration_distributions, 'maximum_diameter')
|
d_max=param_evaluation(data_registry.expiration_particle['long_range_expiration_distributions'], 'maximum_diameter')
|
||||||
)
|
)
|
||||||
for exp_type, BLO_factors in expiration_BLO_factors(data_registry).items()
|
for exp_type, BLO_factors in expiration_BLO_factors(data_registry).items()
|
||||||
}
|
}
|
||||||
|
|
@ -437,8 +411,8 @@ def short_range_expiration_distributions(data_registry):
|
||||||
exp_type: expiration_distribution(
|
exp_type: expiration_distribution(
|
||||||
data_registry=data_registry,
|
data_registry=data_registry,
|
||||||
BLO_factors=BLO_factors,
|
BLO_factors=BLO_factors,
|
||||||
d_min=param_evaluation(data_registry.short_range_expiration_distributions, 'minimum_diameter'),
|
d_min=param_evaluation(data_registry.expiration_particle['short_range_expiration_distributions'], 'minimum_diameter'),
|
||||||
d_max=param_evaluation(data_registry.short_range_expiration_distributions, 'maximum_diameter')
|
d_max=param_evaluation(data_registry.expiration_particle['short_range_expiration_distributions'], 'maximum_diameter')
|
||||||
)
|
)
|
||||||
for exp_type, BLO_factors in expiration_BLO_factors(data_registry).items()
|
for exp_type, BLO_factors in expiration_BLO_factors(data_registry).items()
|
||||||
}
|
}
|
||||||
|
|
@ -452,8 +426,8 @@ frequencies = np.array((0.0598036, 0.0946154, 0.1299152, 0.1064905, 0.1099066, 0
|
||||||
def short_range_distances(data_registry):
|
def short_range_distances(data_registry):
|
||||||
return Custom(
|
return Custom(
|
||||||
bounds=(
|
bounds=(
|
||||||
param_evaluation(data_registry.short_range_distances, 'minimum_distance'),
|
param_evaluation(data_registry.short_range_model['conversational_distance'], 'minimum_distance'),
|
||||||
param_evaluation(data_registry.short_range_distances, 'maximum_distance')
|
param_evaluation(data_registry.short_range_model['conversational_distance'], 'maximum_distance')
|
||||||
),
|
),
|
||||||
function=lambda x: np.interp(x, distances, frequencies, left=0., right=0.),
|
function=lambda x: np.interp(x, distances, frequencies, left=0., right=0.),
|
||||||
max_function=0.13
|
max_function=0.13
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from caimira.enums import ViralLoads, InfectiousDoses, ViableToRNARatios
|
from caimira.enums import ViralLoads
|
||||||
|
|
||||||
|
|
||||||
class DataRegistry:
|
class DataRegistry:
|
||||||
|
|
@ -6,34 +6,42 @@ class DataRegistry:
|
||||||
|
|
||||||
version = None
|
version = None
|
||||||
|
|
||||||
BLOmodel = {
|
expiration_particle = {
|
||||||
"cn": {
|
"long_range_expiration_distributions": {
|
||||||
"B": 0.06,
|
"minimum_diameter": 0.1,
|
||||||
"L": 0.2,
|
"maximum_diameter": 30,
|
||||||
"O": 0.0010008,
|
|
||||||
},
|
},
|
||||||
"mu": {
|
"short_range_expiration_distributions": {
|
||||||
"B": 0.989541,
|
"minimum_diameter": 0.1,
|
||||||
"L": 1.38629,
|
"maximum_diameter": 100,
|
||||||
"O": 4.97673,
|
|
||||||
},
|
},
|
||||||
"sigma": {
|
"BLOmodel": {
|
||||||
"B": 0.262364,
|
"cn": {"B": 0.06, "L": 0.2, "O": 0.0010008},
|
||||||
"L": 0.506818,
|
"mu": {"B": 0.989541, "L": 1.38629, "O": 4.97673},
|
||||||
"O": 0.585005,
|
"sigma": {"B": 0.262364, "L": 0.506818, "O": 0.585005},
|
||||||
},
|
},
|
||||||
|
"expiration_BLO_factors": {
|
||||||
|
"Breathing": {"B": 1., "L": 0., "O": 0., },
|
||||||
|
"Speaking": {"B": 1., "L": 1., "O": 1., },
|
||||||
|
"Singing": {"B": 1., "L": 5., "O": 5., },
|
||||||
|
"Shouting": {"B": 1., "L": 5., "O": 5., },
|
||||||
|
},
|
||||||
|
"particle": {
|
||||||
|
"evaporation_factor": 0.3,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
activity_distributions = {
|
activity_distributions = {
|
||||||
"Seated": {
|
"Seated": {
|
||||||
"inhalation_rate": {
|
"inhalation_rate": {
|
||||||
"associated_distribution": "Log-normal",
|
"associated_value": "Log-normal distribution",
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"lognormal_mean_gaussian": -0.6872121723362303,
|
"lognormal_mean_gaussian": -0.6872121723362303,
|
||||||
"lognormal_standard_deviation_gaussian": 0.10498338229297108,
|
"lognormal_standard_deviation_gaussian": 0.10498338229297108,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"exhalation_rate": {
|
"exhalation_rate": {
|
||||||
"associated_distribution": "Log-normal",
|
"associated_value": "Log-normal distribution",
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"lognormal_mean_gaussian": -0.6872121723362303,
|
"lognormal_mean_gaussian": -0.6872121723362303,
|
||||||
"lognormal_standard_deviation_gaussian": 0.10498338229297108,
|
"lognormal_standard_deviation_gaussian": 0.10498338229297108,
|
||||||
|
|
@ -42,14 +50,14 @@ class DataRegistry:
|
||||||
},
|
},
|
||||||
"Standing": {
|
"Standing": {
|
||||||
"inhalation_rate": {
|
"inhalation_rate": {
|
||||||
"associated_distribution": "Log-normal",
|
"associated_value": "Log-normal distribution",
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"lognormal_mean_gaussian": -0.5742377578494785,
|
"lognormal_mean_gaussian": -0.5742377578494785,
|
||||||
"lognormal_standard_deviation_gaussian": 0.09373162411398223,
|
"lognormal_standard_deviation_gaussian": 0.09373162411398223,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"exhalation_rate": {
|
"exhalation_rate": {
|
||||||
"associated_distribution": "Log-normal",
|
"associated_value": "Log-normal distribution",
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"lognormal_mean_gaussian": -0.5742377578494785,
|
"lognormal_mean_gaussian": -0.5742377578494785,
|
||||||
"lognormal_standard_deviation_gaussian": 0.09373162411398223,
|
"lognormal_standard_deviation_gaussian": 0.09373162411398223,
|
||||||
|
|
@ -58,14 +66,14 @@ class DataRegistry:
|
||||||
},
|
},
|
||||||
"Light activity": {
|
"Light activity": {
|
||||||
"inhalation_rate": {
|
"inhalation_rate": {
|
||||||
"associated_distribution": "Log-normal",
|
"associated_value": "Log-normal distribution",
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"lognormal_mean_gaussian": 0.21380242785625422,
|
"lognormal_mean_gaussian": 0.21380242785625422,
|
||||||
"lognormal_standard_deviation_gaussian": 0.09435378091059601,
|
"lognormal_standard_deviation_gaussian": 0.09435378091059601,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"exhalation_rate": {
|
"exhalation_rate": {
|
||||||
"associated_distribution": "Log-normal",
|
"associated_value": "Log-normal distribution",
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"lognormal_mean_gaussian": 0.21380242785625422,
|
"lognormal_mean_gaussian": 0.21380242785625422,
|
||||||
"lognormal_standard_deviation_gaussian": 0.09435378091059601,
|
"lognormal_standard_deviation_gaussian": 0.09435378091059601,
|
||||||
|
|
@ -74,14 +82,14 @@ class DataRegistry:
|
||||||
},
|
},
|
||||||
"Moderate activity": {
|
"Moderate activity": {
|
||||||
"inhalation_rate": {
|
"inhalation_rate": {
|
||||||
"associated_distribution": "Log-normal",
|
"associated_value": "Log-normal distribution",
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"lognormal_mean_gaussian": 0.551771330362601,
|
"lognormal_mean_gaussian": 0.551771330362601,
|
||||||
"lognormal_standard_deviation_gaussian": 0.1894616357138137,
|
"lognormal_standard_deviation_gaussian": 0.1894616357138137,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"exhalation_rate": {
|
"exhalation_rate": {
|
||||||
"associated_distribution": "Log-normal",
|
"associated_value": "Log-normal distribution",
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"lognormal_mean_gaussian": 0.551771330362601,
|
"lognormal_mean_gaussian": 0.551771330362601,
|
||||||
"lognormal_standard_deviation_gaussian": 0.1894616357138137,
|
"lognormal_standard_deviation_gaussian": 0.1894616357138137,
|
||||||
|
|
@ -90,14 +98,14 @@ class DataRegistry:
|
||||||
},
|
},
|
||||||
"Heavy exercise": {
|
"Heavy exercise": {
|
||||||
"inhalation_rate": {
|
"inhalation_rate": {
|
||||||
"associated_distribution": "Log-normal",
|
"associated_value": "Log-normal distribution",
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"lognormal_mean_gaussian": 1.1644665696723049,
|
"lognormal_mean_gaussian": 1.1644665696723049,
|
||||||
"lognormal_standard_deviation_gaussian": 0.21744554768657565,
|
"lognormal_standard_deviation_gaussian": 0.21744554768657565,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"exhalation_rate": {
|
"exhalation_rate": {
|
||||||
"associated_distribution": "Log-normal",
|
"associated_value": "Log-normal distribution",
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"lognormal_mean_gaussian": 1.1644665696723049,
|
"lognormal_mean_gaussian": 1.1644665696723049,
|
||||||
"lognormal_standard_deviation_gaussian": 0.21744554768657565,
|
"lognormal_standard_deviation_gaussian": 0.21744554768657565,
|
||||||
|
|
@ -105,194 +113,216 @@ class DataRegistry:
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
symptomatic_vl_frequencies = {
|
|
||||||
"log_variable": [
|
virological_data = {
|
||||||
2.46032,
|
"symptomatic_vl_frequencies": {
|
||||||
2.67431,
|
"log_variable": [
|
||||||
2.85434,
|
2.46032,
|
||||||
3.06155,
|
2.67431,
|
||||||
3.25856,
|
2.85434,
|
||||||
3.47256,
|
3.06155,
|
||||||
3.66957,
|
3.25856,
|
||||||
3.85979,
|
3.47256,
|
||||||
4.09927,
|
3.66957,
|
||||||
4.27081,
|
3.85979,
|
||||||
4.47631,
|
4.09927,
|
||||||
4.66653,
|
4.27081,
|
||||||
4.87204,
|
4.47631,
|
||||||
5.10302,
|
4.66653,
|
||||||
5.27456,
|
4.87204,
|
||||||
5.46478,
|
5.10302,
|
||||||
5.6533,
|
5.27456,
|
||||||
5.88428,
|
5.46478,
|
||||||
6.07281,
|
5.6533,
|
||||||
6.30549,
|
5.88428,
|
||||||
6.48552,
|
6.07281,
|
||||||
6.64856,
|
6.30549,
|
||||||
6.85407,
|
6.48552,
|
||||||
7.10373,
|
6.64856,
|
||||||
7.30075,
|
6.85407,
|
||||||
7.47229,
|
7.10373,
|
||||||
7.66081,
|
7.30075,
|
||||||
7.85782,
|
7.47229,
|
||||||
8.05653,
|
7.66081,
|
||||||
8.27053,
|
7.85782,
|
||||||
8.48453,
|
8.05653,
|
||||||
8.65607,
|
8.27053,
|
||||||
8.90573,
|
8.48453,
|
||||||
9.06878,
|
8.65607,
|
||||||
9.27429,
|
8.90573,
|
||||||
9.473,
|
9.06878,
|
||||||
9.66152,
|
9.27429,
|
||||||
9.87552,
|
9.473,
|
||||||
],
|
9.66152,
|
||||||
"frequencies": [
|
9.87552,
|
||||||
0.001206885,
|
],
|
||||||
0.007851618,
|
"frequencies": [
|
||||||
0.008078144,
|
0.001206885,
|
||||||
0.01502491,
|
0.007851618,
|
||||||
0.013258014,
|
0.008078144,
|
||||||
0.018528495,
|
0.01502491,
|
||||||
0.020053765,
|
0.013258014,
|
||||||
0.021896167,
|
0.018528495,
|
||||||
0.022047184,
|
0.020053765,
|
||||||
0.018604005,
|
0.021896167,
|
||||||
0.01547796,
|
0.022047184,
|
||||||
0.018075445,
|
0.018604005,
|
||||||
0.021503523,
|
0.01547796,
|
||||||
0.022349217,
|
0.018075445,
|
||||||
0.025097721,
|
0.021503523,
|
||||||
0.032875078,
|
0.022349217,
|
||||||
0.030594727,
|
0.025097721,
|
||||||
0.032573045,
|
0.032875078,
|
||||||
0.034717482,
|
0.030594727,
|
||||||
0.034792991,
|
0.032573045,
|
||||||
0.033267721,
|
0.034717482,
|
||||||
0.042887485,
|
0.034792991,
|
||||||
0.036846816,
|
0.033267721,
|
||||||
0.03876473,
|
0.042887485,
|
||||||
0.045016819,
|
0.036846816,
|
||||||
0.040063473,
|
0.03876473,
|
||||||
0.04883754,
|
0.045016819,
|
||||||
0.043944602,
|
0.040063473,
|
||||||
0.048142864,
|
0.04883754,
|
||||||
0.041588741,
|
0.043944602,
|
||||||
0.048762031,
|
0.048142864,
|
||||||
0.027921732,
|
0.041588741,
|
||||||
0.033871788,
|
0.048762031,
|
||||||
0.022122693,
|
0.027921732,
|
||||||
0.016927718,
|
0.033871788,
|
||||||
0.008833228,
|
0.022122693,
|
||||||
0.00478598,
|
0.016927718,
|
||||||
0.002807662,
|
0.008833228,
|
||||||
],
|
0.00478598,
|
||||||
"kernel_bandwidth": 0.1,
|
0.002807662,
|
||||||
}
|
],
|
||||||
covid_overal_vl_data = {
|
"kernel_bandwidth": 0.1,
|
||||||
"shape_factor": 3.47,
|
|
||||||
"scale_factor": 7.01,
|
|
||||||
"start": 0.01,
|
|
||||||
"stop": 0.99,
|
|
||||||
"num": 30.0,
|
|
||||||
"min_bound": 2,
|
|
||||||
"max_bound": 10,
|
|
||||||
"interpolation_fp_left": 0,
|
|
||||||
"interpolation_fp_right": 0,
|
|
||||||
"max_function": 0.2,
|
|
||||||
}
|
|
||||||
viable_to_RNA_ratio_distribution = {
|
|
||||||
"low": 0.01,
|
|
||||||
"high": 0.6,
|
|
||||||
}
|
|
||||||
infectious_dose_distribution = {
|
|
||||||
"low": 10,
|
|
||||||
"high": 100,
|
|
||||||
}
|
|
||||||
virus_distributions = {
|
|
||||||
"SARS_CoV_2": {
|
|
||||||
"viral_load_in_sputum": ViralLoads.COVID_OVERALL.value,
|
|
||||||
"infectious_dose": InfectiousDoses.DISTRIBUTION.value,
|
|
||||||
"viable_to_RNA_ratio": ViableToRNARatios.DISTRIBUTION.value,
|
|
||||||
"transmissibility_factor": 1,
|
|
||||||
"infectiousness_days": 14,
|
|
||||||
},
|
},
|
||||||
"SARS_CoV_2_ALPHA": {
|
'covid_overal_vl_data': {
|
||||||
"viral_load_in_sputum": ViralLoads.COVID_OVERALL.value,
|
"shape_factor": 3.47,
|
||||||
"infectious_dose": InfectiousDoses.DISTRIBUTION.value,
|
"scale_factor": 7.01,
|
||||||
"viable_to_RNA_ratio": ViableToRNARatios.DISTRIBUTION.value,
|
"start": 0.01,
|
||||||
"transmissibility_factor": 0.78,
|
"stop": 0.99,
|
||||||
"infectiousness_days": 14,
|
"num": 30.0,
|
||||||
|
"min_bound": 2,
|
||||||
|
"max_bound": 10,
|
||||||
|
"interpolation_fp_left": 0,
|
||||||
|
"interpolation_fp_right": 0,
|
||||||
|
"max_function": 0.2,
|
||||||
},
|
},
|
||||||
"SARS_CoV_2_BETA": {
|
"virus_distributions": {
|
||||||
"viral_load_in_sputum": ViralLoads.COVID_OVERALL.value,
|
"SARS_CoV_2": {
|
||||||
"infectious_dose": InfectiousDoses.DISTRIBUTION.value,
|
"viral_load_in_sputum": ViralLoads.COVID_OVERALL.value,
|
||||||
"viable_to_RNA_ratio": ViableToRNARatios.DISTRIBUTION.value,
|
"infectious_dose": {
|
||||||
"transmissibility_factor": 0.8,
|
"associated_value": "Uniform distribution",
|
||||||
"infectiousness_days": 14,
|
"parameters": {"low": 10, "high": 100},
|
||||||
},
|
},
|
||||||
"SARS_CoV_2_GAMMA": {
|
"viable_to_RNA_ratio": {
|
||||||
"viral_load_in_sputum": ViralLoads.COVID_OVERALL.value,
|
'associated_value': 'Uniform distribution',
|
||||||
"infectious_dose": InfectiousDoses.DISTRIBUTION.value,
|
'parameters': {'low': 0.01, 'high': 0.6},
|
||||||
"viable_to_RNA_ratio": ViableToRNARatios.DISTRIBUTION.value,
|
},
|
||||||
"transmissibility_factor": 0.72,
|
"transmissibility_factor": 1,
|
||||||
"infectiousness_days": 14,
|
"infectiousness_days": 14,
|
||||||
},
|
},
|
||||||
"SARS_CoV_2_DELTA": {
|
"SARS_CoV_2_ALPHA": {
|
||||||
"viral_load_in_sputum": ViralLoads.COVID_OVERALL.value,
|
"viral_load_in_sputum": ViralLoads.COVID_OVERALL.value,
|
||||||
"infectious_dose": InfectiousDoses.DISTRIBUTION.value,
|
"infectious_dose": {
|
||||||
"viable_to_RNA_ratio": ViableToRNARatios.DISTRIBUTION.value,
|
"associated_value": "Uniform distribution",
|
||||||
"transmissibility_factor": 0.51,
|
"parameters": {"low": 10, "high": 100},
|
||||||
"infectiousness_days": 14,
|
},
|
||||||
},
|
"viable_to_RNA_ratio": {
|
||||||
"SARS_CoV_2_OMICRON": {
|
'associated_value': 'Uniform distribution',
|
||||||
"viral_load_in_sputum": ViralLoads.COVID_OVERALL.value,
|
'parameters': {'low': 0.01, 'high': 0.6},
|
||||||
"infectious_dose": InfectiousDoses.DISTRIBUTION.value,
|
},
|
||||||
"viable_to_RNA_ratio": ViableToRNARatios.DISTRIBUTION.value,
|
"transmissibility_factor": 0.78,
|
||||||
"transmissibility_factor": 0.2,
|
"infectiousness_days": 14,
|
||||||
"infectiousness_days": 14,
|
},
|
||||||
},
|
"SARS_CoV_2_BETA": {
|
||||||
"SARS_CoV_2_Other": {
|
"viral_load_in_sputum": ViralLoads.COVID_OVERALL.value,
|
||||||
"viral_load_in_sputum": ViralLoads.COVID_OVERALL.value,
|
"infectious_dose": {
|
||||||
"infectious_dose": InfectiousDoses.DISTRIBUTION.value,
|
"associated_value": "Uniform distribution",
|
||||||
"viable_to_RNA_ratio": ViableToRNARatios.DISTRIBUTION.value,
|
"parameters": {"low": 10, "high": 100},
|
||||||
"transmissibility_factor": 0.1,
|
},
|
||||||
"infectiousness_days": 14,
|
"viable_to_RNA_ratio": {
|
||||||
|
'associated_value': 'Uniform distribution',
|
||||||
|
'parameters': {'low': 0.01, 'high': 0.6},
|
||||||
|
},
|
||||||
|
"transmissibility_factor": 0.8,
|
||||||
|
"infectiousness_days": 14,
|
||||||
|
},
|
||||||
|
"SARS_CoV_2_GAMMA": {
|
||||||
|
"viral_load_in_sputum": ViralLoads.COVID_OVERALL.value,
|
||||||
|
"infectious_dose": {
|
||||||
|
"associated_value": "Uniform distribution",
|
||||||
|
"parameters": {"low": 10, "high": 100},
|
||||||
|
},
|
||||||
|
"viable_to_RNA_ratio": {
|
||||||
|
'associated_value': 'Uniform distribution',
|
||||||
|
'parameters': {'low': 0.01, 'high': 0.6},
|
||||||
|
},
|
||||||
|
"transmissibility_factor": 0.72,
|
||||||
|
"infectiousness_days": 14,
|
||||||
|
},
|
||||||
|
"SARS_CoV_2_DELTA": {
|
||||||
|
"viral_load_in_sputum": ViralLoads.COVID_OVERALL.value,
|
||||||
|
"infectious_dose": {
|
||||||
|
"associated_value": "Uniform distribution",
|
||||||
|
"parameters": {"low": 10, "high": 100},
|
||||||
|
},
|
||||||
|
"viable_to_RNA_ratio": {
|
||||||
|
'associated_value': 'Uniform distribution',
|
||||||
|
'parameters': {'low': 0.01, 'high': 0.6},
|
||||||
|
},
|
||||||
|
"transmissibility_factor": 0.51,
|
||||||
|
"infectiousness_days": 14,
|
||||||
|
},
|
||||||
|
"SARS_CoV_2_OMICRON": {
|
||||||
|
"viral_load_in_sputum": ViralLoads.COVID_OVERALL.value,
|
||||||
|
"infectious_dose": {
|
||||||
|
"associated_value": "Uniform distribution",
|
||||||
|
"parameters": {"low": 10, "high": 100},
|
||||||
|
},
|
||||||
|
"viable_to_RNA_ratio": {
|
||||||
|
'associated_value': 'Uniform distribution',
|
||||||
|
'parameters': {'low': 0.01, 'high': 0.6},
|
||||||
|
},
|
||||||
|
"transmissibility_factor": 0.2,
|
||||||
|
"infectiousness_days": 14,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
mask_distributions = {
|
mask_distributions = {
|
||||||
"Type I": {
|
"Type I": {
|
||||||
"η_inhale": {
|
"η_inhale": {
|
||||||
"associated_distribution": "Uniform",
|
"associated_value": "Uniform distribution",
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"low": 0.25,
|
"low": 0.25,
|
||||||
"high": 0.80,
|
"high": 0.80,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"Known filtration efficiency of masks when exhaling?": "No",
|
|
||||||
"factor_exhale": 1,
|
"factor_exhale": 1,
|
||||||
},
|
},
|
||||||
"FFP2": {
|
"FFP2": {
|
||||||
"η_inhale": {
|
"η_inhale": {
|
||||||
"associated_distribution": "Uniform",
|
"associated_value": "Uniform distribution",
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"low": 0.83,
|
"low": 0.83,
|
||||||
"high": 0.91,
|
"high": 0.91,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"Known filtration efficiency of masks when exhaling?": "No",
|
|
||||||
"factor_exhale": 1,
|
"factor_exhale": 1,
|
||||||
},
|
},
|
||||||
"Cloth": {
|
"Cloth": {
|
||||||
"η_inhale": {
|
"η_inhale": {
|
||||||
"associated_distribution": "Uniform",
|
"associated_value": "Uniform distribution",
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"low": 0.05,
|
"low": 0.05,
|
||||||
"high": 0.40,
|
"high": 0.40,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"Known filtration efficiency of masks when exhaling?": "Yes",
|
|
||||||
"η_exhale": {
|
"η_exhale": {
|
||||||
"associated_distribution": "Uniform",
|
"associated_value": "Uniform distribution",
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"low": 0.20,
|
"low": 0.20,
|
||||||
"high": 0.50,
|
"high": 0.50,
|
||||||
|
|
@ -301,50 +331,15 @@ class DataRegistry:
|
||||||
"factor_exhale": 1,
|
"factor_exhale": 1,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
expiration_BLO_factors = {
|
|
||||||
"Breathing": {
|
|
||||||
"B": 1.0,
|
|
||||||
"L": 0.0,
|
|
||||||
"O": 0.0,
|
|
||||||
},
|
|
||||||
"Speaking": {
|
|
||||||
"B": 1.0,
|
|
||||||
"L": 1.0,
|
|
||||||
"O": 1.0,
|
|
||||||
},
|
|
||||||
"Singing": {
|
|
||||||
"B": 1.0,
|
|
||||||
"L": 5.0,
|
|
||||||
"O": 5.0,
|
|
||||||
},
|
|
||||||
"Shouting": {
|
|
||||||
"B": 1.0,
|
|
||||||
"L": 5.0,
|
|
||||||
"O": 5.0,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
long_range_expiration_distributions = {
|
|
||||||
"minimum_diameter": 0.1,
|
|
||||||
"maximum_diameter": 30,
|
|
||||||
}
|
|
||||||
short_range_expiration_distributions = {
|
|
||||||
"minimum_diameter": 0.1,
|
|
||||||
"maximum_diameter": 100,
|
|
||||||
}
|
|
||||||
short_range_distances = {
|
|
||||||
"minimum_distance": 0.5,
|
|
||||||
"maximum_distance": 2.0,
|
|
||||||
}
|
|
||||||
|
|
||||||
####################################
|
####################################
|
||||||
|
|
||||||
room = {
|
room = {
|
||||||
"defaults": {
|
"inside_temp": 293,
|
||||||
"inside_temp": 293,
|
"humidity_with_heating": 0.3,
|
||||||
"humidity_with_heating": 0.3,
|
"humidity_without_heating": 0.5,
|
||||||
"humidity_without_heating": 0.5,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ventilation = {
|
ventilation = {
|
||||||
"natural": {
|
"natural": {
|
||||||
"discharge_factor": {
|
"discharge_factor": {
|
||||||
|
|
@ -353,41 +348,38 @@ class DataRegistry:
|
||||||
},
|
},
|
||||||
"infiltration_ventilation": 0.25,
|
"infiltration_ventilation": 0.25,
|
||||||
}
|
}
|
||||||
particle = {
|
|
||||||
"evaporation_factor": 0.3,
|
|
||||||
}
|
|
||||||
population_with_virus = {
|
|
||||||
"fraction_of_infectious_virus": 1,
|
|
||||||
}
|
|
||||||
concentration_model = {
|
concentration_model = {
|
||||||
"min_background_concentration": 0.0,
|
"virus_concentration_model": {
|
||||||
|
"min_background_concentration": 0.0,
|
||||||
|
},
|
||||||
"CO2_concentration_model": {
|
"CO2_concentration_model": {
|
||||||
"CO2_atmosphere_concentration": 440.44,
|
"CO2_atmosphere_concentration": 440.44,
|
||||||
"CO2_fraction_exhaled": 0.042,
|
"CO2_fraction_exhaled": 0.042,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
short_range_model = {
|
short_range_model = {
|
||||||
"dilution_factor": {
|
"dilution_factor": {
|
||||||
"mouth_diameter": 0.02,
|
"mouth_diameter": 0.02,
|
||||||
"exhalation_coefficient": 2,
|
"exhalation_coefficient": 2,
|
||||||
"tstar": 2,
|
"breathing_cycle": 4,
|
||||||
"penetration_coefficients": {
|
"penetration_coefficients": {
|
||||||
"𝛽r1": 0.18,
|
"𝛽r1": 0.18,
|
||||||
"𝛽r2": 0.2,
|
"𝛽r2": 0.2,
|
||||||
"𝛽x1": 2.4,
|
"𝛽x1": 2.4,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"conversational_distance": {
|
||||||
|
"minimum_distance": 0.5,
|
||||||
|
"maximum_distance": 2.0,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
exposure_model = {
|
|
||||||
"repeats": 1,
|
monte_carlo = {
|
||||||
|
"sample_size": 250000,
|
||||||
}
|
}
|
||||||
conditional_prob_inf_given_viral_load = {
|
|
||||||
"lower_percentile": 0.05,
|
|
||||||
"upper_percentile": 0.95,
|
|
||||||
"min_vl": 2,
|
|
||||||
"max_vl": 10,
|
|
||||||
}
|
|
||||||
monte_carlo_sample_size = 250000
|
|
||||||
population_scenario_activity = {
|
population_scenario_activity = {
|
||||||
"office": {"placeholder": "Office", "activity": "Seated", "expiration": {"Speaking": 1, "Breathing": 2}},
|
"office": {"placeholder": "Office", "activity": "Seated", "expiration": {"Speaking": 1, "Breathing": 2}},
|
||||||
"smallmeeting": {
|
"smallmeeting": {
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ class DataService:
|
||||||
self._host = host
|
self._host = host
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create(cls, host: str = "https://caimira-data-api.app.cern.ch"):
|
def create(cls, host: str = "https://caimira-data-api-qa.app.cern.ch"):
|
||||||
"""Factory."""
|
"""Factory."""
|
||||||
return cls(host)
|
return cls(host)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -186,8 +186,8 @@ def skagit_chorale_mc(data_registry):
|
||||||
presence=models.SpecificInterval(((0, 2.5), )),
|
presence=models.SpecificInterval(((0, 2.5), )),
|
||||||
virus=mc.SARSCoV2(
|
virus=mc.SARSCoV2(
|
||||||
viral_load_in_sputum=10**9,
|
viral_load_in_sputum=10**9,
|
||||||
infectious_dose=infectious_dose_distribution(data_registry),
|
infectious_dose=infectious_dose_distribution(),
|
||||||
viable_to_RNA_ratio=viable_to_RNA_ratio_distribution(data_registry),
|
viable_to_RNA_ratio=viable_to_RNA_ratio_distribution(),
|
||||||
transmissibility_factor=1.,
|
transmissibility_factor=1.,
|
||||||
),
|
),
|
||||||
mask=models.Mask.types['No mask'],
|
mask=models.Mask.types['No mask'],
|
||||||
|
|
@ -230,8 +230,8 @@ def bus_ride_mc(data_registry):
|
||||||
presence=models.SpecificInterval(((0, 1.67), )),
|
presence=models.SpecificInterval(((0, 1.67), )),
|
||||||
virus=mc.SARSCoV2(
|
virus=mc.SARSCoV2(
|
||||||
viral_load_in_sputum=5*10**8,
|
viral_load_in_sputum=5*10**8,
|
||||||
infectious_dose=infectious_dose_distribution(data_registry),
|
infectious_dose=infectious_dose_distribution(),
|
||||||
viable_to_RNA_ratio=viable_to_RNA_ratio_distribution(data_registry),
|
viable_to_RNA_ratio=viable_to_RNA_ratio_distribution(),
|
||||||
transmissibility_factor=1.,
|
transmissibility_factor=1.,
|
||||||
),
|
),
|
||||||
mask=models.Mask.types['No mask'],
|
mask=models.Mask.types['No mask'],
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue