diff --git a/cara/apps/calculator/report_generator.py b/cara/apps/calculator/report_generator.py index 07d560c0..e78aba80 100644 --- a/cara/apps/calculator/report_generator.py +++ b/cara/apps/calculator/report_generator.py @@ -230,40 +230,40 @@ def non_zero_percentage(percentage: int) -> str: def manufacture_alternative_scenarios(form: FormData) -> typing.Dict[str, mc.ExposureModel]: scenarios = {} + if (form.short_range_option == "short_range_no"): + # Two special option cases - HEPA and/or FFP2 masks. + FFP2_being_worn = bool(form.mask_wearing_option == 'mask_on' and form.mask_type == 'FFP2') + if FFP2_being_worn and form.hepa_option: + FFP2andHEPAalternative = dataclass_utils.replace(form, mask_type='Type I') + scenarios['Base scenario with HEPA filter and Type I masks'] = FFP2andHEPAalternative.build_mc_model() + if not FFP2_being_worn and form.hepa_option: + noHEPAalternative = dataclass_utils.replace(form, mask_type = 'FFP2') + noHEPAalternative = dataclass_utils.replace(noHEPAalternative, mask_wearing_option = 'mask_on') + noHEPAalternative = dataclass_utils.replace(noHEPAalternative, hepa_option=False) + scenarios['Base scenario without HEPA filter, with FFP2 masks'] = noHEPAalternative.build_mc_model() - # Two special option cases - HEPA and/or FFP2 masks. - FFP2_being_worn = bool(form.mask_wearing_option == 'mask_on' and form.mask_type == 'FFP2') - if FFP2_being_worn and form.hepa_option: - FFP2andHEPAalternative = dataclass_utils.replace(form, mask_type='Type I') - scenarios['Base scenario with HEPA filter and Type I masks'] = FFP2andHEPAalternative.build_mc_model() - if not FFP2_being_worn and form.hepa_option: - noHEPAalternative = dataclass_utils.replace(form, mask_type = 'FFP2') - noHEPAalternative = dataclass_utils.replace(noHEPAalternative, mask_wearing_option = 'mask_on') - noHEPAalternative = dataclass_utils.replace(noHEPAalternative, hepa_option=False) - scenarios['Base scenario without HEPA filter, with FFP2 masks'] = noHEPAalternative.build_mc_model() + # The remaining scenarios are based on Type I masks (possibly not worn) + # and no HEPA filtration. + form = dataclass_utils.replace(form, mask_type='Type I') + if form.hepa_option: + form = dataclass_utils.replace(form, hepa_option=False) - # The remaining scenarios are based on Type I masks (possibly not worn) - # and no HEPA filtration. - form = dataclass_utils.replace(form, mask_type='Type I') - if form.hepa_option: - form = dataclass_utils.replace(form, hepa_option=False) + with_mask = dataclass_utils.replace(form, mask_wearing_option='mask_on') + without_mask = dataclass_utils.replace(form, mask_wearing_option='mask_off') - with_mask = dataclass_utils.replace(form, mask_wearing_option='mask_on') - without_mask = dataclass_utils.replace(form, mask_wearing_option='mask_off') + if form.ventilation_type == 'mechanical_ventilation': + #scenarios['Mechanical ventilation with Type I masks'] = with_mask.build_mc_model() + scenarios['Mechanical ventilation without masks'] = without_mask.build_mc_model() - if form.ventilation_type == 'mechanical_ventilation': - #scenarios['Mechanical ventilation with Type I masks'] = with_mask.build_mc_model() - scenarios['Mechanical ventilation without masks'] = without_mask.build_mc_model() + elif form.ventilation_type == 'natural_ventilation': + #scenarios['Windows open with Type I masks'] = with_mask.build_mc_model() + scenarios['Windows open without masks'] = without_mask.build_mc_model() - elif form.ventilation_type == 'natural_ventilation': - #scenarios['Windows open with Type I masks'] = with_mask.build_mc_model() - scenarios['Windows open without masks'] = without_mask.build_mc_model() - - # No matter the ventilation scheme, we include scenarios which don't have any ventilation. - with_mask_no_vent = dataclass_utils.replace(with_mask, ventilation_type='no_ventilation') - without_mask_or_vent = dataclass_utils.replace(without_mask, ventilation_type='no_ventilation') - scenarios['No ventilation with Type I masks'] = with_mask_no_vent.build_mc_model() - scenarios['Neither ventilation nor masks'] = without_mask_or_vent.build_mc_model() + # No matter the ventilation scheme, we include scenarios which don't have any ventilation. + with_mask_no_vent = dataclass_utils.replace(with_mask, ventilation_type='no_ventilation') + without_mask_or_vent = dataclass_utils.replace(without_mask, ventilation_type='no_ventilation') + scenarios['No ventilation with Type I masks'] = with_mask_no_vent.build_mc_model() + scenarios['Neither ventilation nor masks'] = without_mask_or_vent.build_mc_model() return scenarios diff --git a/cara/apps/templates/base/calculator.report.html.j2 b/cara/apps/templates/base/calculator.report.html.j2 index e11456cb..a12c2fa9 100644 --- a/cara/apps/templates/base/calculator.report.html.j2 +++ b/cara/apps/templates/base/calculator.report.html.j2 @@ -106,69 +106,72 @@ let exposed_presence_intervals = {{ exposed_presence_intervals | JSONify }} let short_range_intervals = {{ short_range_intervals | JSONify }} let short_range_activities = {{ short_range_activities | JSONify }} - let alternative_scenarios = {{ alternative_scenarios.stats | JSONify }} draw_plot("concentration_plot")

-
-
Alternative scenarios - -
-
-
-
- {% if form.short_range_option == "short_range_yes" %} - {% if 'Speaking' in form.short_range_interactions|string or 'Shouting' in form.short_range_interactions|string %} - - + + {% if form.short_range_option == "short_range_no" %} +
+
Alternative scenarios + +
+
+
+
+ {% if form.short_range_option == "short_range_yes" %} + {% if 'Speaking' in form.short_range_interactions|string or 'Shouting' in form.short_range_interactions|string %} + + + {% endif %} {% endif %} - {% endif %} -
- -
- {% block report_scenarios_summary_table %} - - - - - - - - - - {% for scenario_name, scenario_stats in alternative_scenarios.stats.items() %} - - - - - - {% endfor %} - -
ScenarioP(I)Expected new cases
{{ scenario_name }} {{ scenario_stats.probability_of_infection | non_zero_percentage }}{{ scenario_stats.expected_new_cases | float_format }}
- {% endblock report_scenarios_summary_table %} +
+ +
+ {% block report_scenarios_summary_table %} + + + + + + + + + + {% for scenario_name, scenario_stats in alternative_scenarios.stats.items() %} + + + + + + {% endfor %} + +
ScenarioP(I)Expected new cases
{{ scenario_name }} {{ scenario_stats.probability_of_infection | non_zero_percentage }}{{ scenario_stats.expected_new_cases | float_format }}
+ {% endblock report_scenarios_summary_table %} +
+
+

Notes for alternative scenarios:
+

    +
  1. This graph shows the concentration of infectious quanta in the air. The filtration of Type I and FFP2 masks, if worn, applies not only to the emission rate but also to the individual exposure (i.e. inhalation). + For this reason, scenarios with different types of mask will show the same concentration on the graph but have different absorbed doses and infection probabilities.
  2. +
  3. If you have selected more sophisticated options, such as HEPA filtration or FFP2 masks, this will be indicated in the plot as the "base scenario", representing the inputs inserted in the form.
    + The other alternative scenarios shown for comparison will not include either HEPA filtration or FFP2 masks.
  4. +
+
+

-
-

Notes for alternative scenarios:
-

    -
  1. This graph shows the concentration of infectious quanta in the air. The filtration of Type I and FFP2 masks, if worn, applies not only to the emission rate but also to the individual exposure (i.e. inhalation). - For this reason, scenarios with different types of mask will show the same concentration on the graph but have different absorbed doses and infection probabilities.
  2. -
  3. If you have selected more sophisticated options, such as HEPA filtration or FFP2 masks, this will be indicated in the plot as the "base scenario", representing the inputs inserted in the form.
    - The other alternative scenarios shown for comparison will not include either HEPA filtration or FFP2 masks.
  4. -
-
-

-
+ {% endif %} {% endblock report_results %} {% block report_footer %}