diff --git a/caimira/apps/calculator/model_generator.py b/caimira/apps/calculator/model_generator.py index 475ca028..49fb639a 100644 --- a/caimira/apps/calculator/model_generator.py +++ b/caimira/apps/calculator/model_generator.py @@ -114,7 +114,7 @@ class FormData: 'infected_lunch_finish': '13:30', 'infected_lunch_option': True, 'infected_lunch_start': '12:30', - 'infected_people': _NO_DEFAULT, + 'infected_people': 1, 'infected_start': '08:30', 'inside_temp': _NO_DEFAULT, 'location_latitude': _NO_DEFAULT, diff --git a/caimira/apps/calculator/report_generator.py b/caimira/apps/calculator/report_generator.py index a4cadd35..f171fe01 100644 --- a/caimira/apps/calculator/report_generator.py +++ b/caimira/apps/calculator/report_generator.py @@ -131,7 +131,7 @@ def calculate_report_data(form: FormData, model: models.ExposureModel) -> typing ]) prob = np.array(model.infection_probability()).mean() - prob_specific_event = np.array(model.total_probability_rule()).mean() + prob_probabilistic_exposure = np.array(model.total_probability_rule()).mean() er = np.array(model.concentration_model.infected.emission_rate_when_present()).mean() exposed_occupants = model.exposed.number expected_new_cases = np.array(model.expected_new_cases()).mean() @@ -148,7 +148,7 @@ def calculate_report_data(form: FormData, model: models.ExposureModel) -> typing "cumulative_doses": list(cumulative_doses), "long_range_cumulative_doses": list(long_range_cumulative_doses), "prob_inf": prob, - "prob_specific_event": prob_specific_event, + "prob_probabilistic_exposure": prob_probabilistic_exposure, "emission_rate": er, "exposed_occupants": exposed_occupants, "expected_new_cases": expected_new_cases, @@ -274,13 +274,13 @@ def manufacture_alternative_scenarios(form: FormData) -> typing.Dict[str, mc.Exp return scenarios -def scenario_statistics(mc_model: mc.ExposureModel, sample_times: typing.List[float], specific_event: bool): +def scenario_statistics(mc_model: mc.ExposureModel, sample_times: typing.List[float], probabilistic_exposure: bool): model = mc_model.build_model(size=_DEFAULT_MC_SAMPLE_SIZE) - if (specific_event): + if (probabilistic_exposure): # It means we have data to calculate the total_probability_rule - prob_specific_event = np.array(model.total_probability_rule()).mean() + prob_probabilistic_exposure = np.array(model.total_probability_rule()).mean() else: - prob_specific_event = 0. + prob_probabilistic_exposure = 0. return { 'probability_of_infection': np.mean(model.infection_probability()), @@ -289,7 +289,7 @@ def scenario_statistics(mc_model: mc.ExposureModel, sample_times: typing.List[fl np.mean(model.concentration(time)) for time in sample_times ], - 'prob_specific_event': prob_specific_event, + 'prob_probabilistic_exposure': prob_probabilistic_exposure, } @@ -312,16 +312,16 @@ def comparison_report( statistics = {} if (form.short_range_option == "short_range_yes" and form.exposure_option == "p_probabilistic_exposure"): - specific_event = True + probabilistic_exposure = True else: - specific_event = False + probabilistic_exposure = False with executor_factory() as executor: results = executor.map( scenario_statistics, scenarios.values(), [sample_times] * len(scenarios), - [specific_event] * len(scenarios), + [probabilistic_exposure] * len(scenarios), timeout=60, ) diff --git a/caimira/apps/calculator/static/css/form.css b/caimira/apps/calculator/static/css/form.css index 4543fefc..dd08db56 100644 --- a/caimira/apps/calculator/static/css/form.css +++ b/caimira/apps/calculator/static/css/form.css @@ -66,7 +66,7 @@ content: attr(data-tooltip); padding: 10px 18px; min-width: 50px; - max-width: 200px; + max-width: 220px; width: max-content; width: -moz-max-content; border-radius: 6px; @@ -113,4 +113,4 @@ transition-delay: 0.5s; /* Starting after the grow effect */ transition-duration: 0.2s; transform: translateX(-50%) scaleY(1); -} \ No newline at end of file +} diff --git a/caimira/apps/calculator/static/js/form.js b/caimira/apps/calculator/static/js/form.js index 79a0b277..6ed6c0b3 100644 --- a/caimira/apps/calculator/static/js/form.js +++ b/caimira/apps/calculator/static/js/form.js @@ -63,9 +63,11 @@ function require_fields(obj) { break; case "p_probabilistic_exposure": require_population(true); + require_infected(false); break; case "p_deterministic_exposure": require_population(false); + require_infected(true); break; case "mask_on": require_mask(true); @@ -184,6 +186,10 @@ function require_population(option) { require_input_field("#ascertainment_bias", option); } +function require_infected(option) { + require_input_field("#infected_people", option); +} + function require_mask(option) { $("#mask_type_1").prop('required', option); $("#mask_type_ffp2").prop('required', option); @@ -281,7 +287,7 @@ function on_hepa_option_change() { }) } -function on_p_recurrent_change() { +function on_exposure_change() { p_recurrent = $('input[type=radio][name=exposure_option]') p_recurrent.each(function (index) { if (this.checked) { @@ -569,6 +575,8 @@ function validate_form(form) { // Validate cases < population if ($("#p_probabilistic_exposure").prop('checked')) { + // Set number of infected people as 1 + $("#infected_people").val(1); var geographicPopulationObj = document.getElementById("geographic_population"); var geographicCasesObj = document.getElementById("geographic_cases"); removeErrorFor(geographicCasesObj); @@ -913,9 +921,9 @@ $(document).ready(function () { // When the exposure_option changes we want to make its respective // children show/hide. - $("input[type=radio][name=exposure_option]").change(on_p_recurrent_change); + $("input[type=radio][name=exposure_option]").change(on_exposure_change); // Call the function now to handle forward/back button presses in the browser. - on_p_recurrent_change(); + on_exposure_change(); // When the mask_wearing_option changes we want to make its respective // children show/hide. diff --git a/caimira/apps/templates/base/calculator.form.html.j2 b/caimira/apps/templates/base/calculator.form.html.j2 index c658a7d3..6698b0bf 100644 --- a/caimira/apps/templates/base/calculator.form.html.j2 +++ b/caimira/apps/templates/base/calculator.form.html.j2 @@ -303,8 +303,9 @@ Event data: -
Here we capture the information about the event being simulated. First enter the number of occupants in the space, if you have a (small) variation in the number of people, please input the average or consider using the expert tool. Within the number of people occupying the space, you should specify how many are infected.
-As an example, for a shared office with 4 people, where one person is infected, we enter 4 occupants and 1 infected person.
In case one would like to simulate an event happening at a given time and location, where the epidemiological situation is known, the tool allows for an estimation of the probability of on-site transmission, considering the chances that a given person in the event is infected. -The user will need to select Specific event, input the number of inhabitants and the the weekly (7-day rolling average) value of new reported laboratory - confirmed cases at the event location, as well as the confidence level of these inputs. +The user will need to select Probabilistic event, input the number of inhabitants and the the weekly (7-day rolling average) value of new reported laboratory - confirmed cases at the event location, as well as the confidence level of these inputs. The 7-day rolling average consists in the average of the previous 3 days to subsequent 3 days, generally reported by the different public health authorities (e.g. in Switzerland here). These two inputs need to the related, i.e. the values of reported new cases and the number of inhabitants shall correspond to the a same geographical location. For example:
The confidence level allows for an ascertainment bias to the data. The user can add the following options:
Depending on the epidemiological situation in the choosen location, the public health surveillance can be more or less active. The confidence level will provide an ascertainment bias to the data collected by the user.
-The higher the incidence rate (i.e. new cases / population) the higher are the chances of having at least one infected occupant participating to the event. -For general and recurrent layout simply select the Recurrent exposure option.
+The higher the incidence rate (i.e. new cases / population) the higher are the chances of having at least one infected occupant participating to the event.
For general and recurrent layout simply select the Deterministic exposure option. As an example, for a shared office with 4 people, where one person is infected, we enter 4 occupants and 1 infected person.