Using Monte-Carlo approach in calculator; hard-coding the sample size for now

This commit is contained in:
Nicolas Mounet 2021-06-04 13:43:35 +02:00
parent 2f61cf1a96
commit 8473398403
2 changed files with 24 additions and 20 deletions

View file

@ -8,7 +8,9 @@ import numpy as np
from cara import models
from cara import data
import cara.monte_carlo as mc
from .. import calculator
from cara.monte_carlo.data import activity_distributions, virus_distributions
LOG = logging.getLogger(__name__)
@ -20,7 +22,7 @@ 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()
_SAMPLE_SIZE = 50000
@dataclass
class FormData:
@ -275,9 +277,9 @@ class FormData:
mask = models.Mask.types[self.mask_type if self.mask_wearing_option == "mask_on" else 'No mask']
return mask
def infected_population(self) -> models.InfectedPopulation:
def infected_population(self) -> mc.InfectedPopulation:
# Initializes the virus
virus = models.Virus.types[self.virus_type]
virus = virus_distributions[self.virus_type]
scenario_activity_and_expiration = {
'office': (
@ -315,12 +317,12 @@ class FormData:
}
[activity_defn, expiration_defn] = scenario_activity_and_expiration[self.activity_type]
activity = models.Activity.types[activity_defn]
activity = activity_distributions[activity_defn]
expiration = build_expiration(expiration_defn)
infected_occupants = self.infected_people
infected = models.InfectedPopulation(
infected = mc.InfectedPopulation(
number=infected_occupants,
virus=virus,
presence=self.infected_present_interval(),
@ -330,7 +332,7 @@ class FormData:
)
return infected
def exposed_population(self) -> models.Population:
def exposed_population(self) -> mc.Population:
scenario_activity = {
'office': 'Seated',
'controlroom-day': 'Seated',
@ -345,14 +347,14 @@ class FormData:
}
activity_defn = scenario_activity[self.activity_type]
activity = models.Activity.types[activity_defn]
activity = activity_distributions[activity_defn]
infected_occupants = self.infected_people
# The number of exposed occupants is the total number of occupants
# minus the number of infected occupants.
exposed_occupants = self.total_people - infected_occupants
exposed = models.Population(
exposed = mc.Population(
number=exposed_occupants,
presence=self.exposed_present_interval(),
activity=activity,
@ -560,14 +562,14 @@ def model_from_form(form: FormData) -> models.ExposureModel:
room = models.Room(volume=volume, humidity=humidity)
# Initializes and returns a model with the attributes defined above
return models.ExposureModel(
concentration_model=models.ConcentrationModel(
return mc.ExposureModel(
concentration_model=mc.ConcentrationModel(
room=room,
ventilation=form.ventilation(),
infected=form.infected_population(),
),
exposed=form.exposed_population()
)
).build_model(size=_SAMPLE_SIZE)
def baseline_raw_form_data():

View file

@ -38,12 +38,13 @@ def calculate_report_data(model: models.ExposureModel):
t_start, t_end = model_start_end(model)
times = list(np.linspace(t_start, t_end, resolution))
concentrations = [model.concentration_model.concentration(time) for time in times]
concentrations = [np.mean(model.concentration_model.concentration(time))
for time in times]
highest_const = max(concentrations)
prob = model.infection_probability()
er = model.concentration_model.infected.emission_rate_when_present()
prob = np.mean(model.infection_probability())
er = np.mean(model.concentration_model.infected.emission_rate_when_present())
exposed_occupants = model.exposed.number
expected_new_cases = model.expected_new_cases()
expected_new_cases = np.mean(model.expected_new_cases())
repeated_events = []
for n in [1, 2, 3, 4, 5]:
@ -52,8 +53,8 @@ def calculate_report_data(model: models.ExposureModel):
repeated_events.append(
RepeatEvents(
repeats=n,
probability_of_infection=repeat_model.infection_probability(),
expected_new_cases=repeat_model.expected_new_cases(),
probability_of_infection=np.mean(repeat_model.infection_probability()),
expected_new_cases=np.mean(repeat_model.expected_new_cases()),
)
)
@ -243,7 +244,8 @@ def comparison_plot(scenarios: typing.Dict[str, models.ExposureModel]):
t_start, t_end = model_start_end(model)
times = np.linspace(t_start, t_end, resolution)
datetimes = [datetime(1970, 1, 1) + timedelta(hours=time) for time in times]
concentrations = [model.concentration_model.concentration(time) for time in times]
concentrations = [np.mean(model.concentration_model.concentration(time))
for time in times]
if name in dash_styled_scenarios:
ax.plot(datetimes, concentrations, label=name, linestyle='--')
@ -267,8 +269,8 @@ def comparison_report(scenarios: typing.Dict[str, models.ExposureModel]):
statistics = {}
for name, model in scenarios.items():
statistics[name] = {
'probability_of_infection': model.infection_probability(),
'expected_new_cases': model.expected_new_cases(),
'probability_of_infection': np.mean(model.infection_probability()),
'expected_new_cases': np.mean(model.expected_new_cases()),
}
return {
'plot': img2base64(_figure2bytes(comparison_plot(scenarios))),