When short range interactions are set, remove alternative scenarios option
This commit is contained in:
parent
4c0daa36e3
commit
052758cc01
2 changed files with 85 additions and 82 deletions
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
</script>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card bg-light mb-3">
|
||||
<div class="card-header"><strong>Alternative scenarios</strong>
|
||||
<button class="icon_button p-0 float-right" data-toggle="collapse" href="#collapseAlternativeScenarios" role="button" aria-expanded="false" aria-controls="collapseAlternativeScenarios">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-chevron-expand" viewBox="0 0 16 16">
|
||||
<path fill-rule="evenodd" d="M3.646 9.146a.5.5 0 0 1 .708 0L8 12.793l3.646-3.647a.5.5 0 0 1 .708.708l-4 4a.5.5 0 0 1-.708 0l-4-4a.5.5 0 0 1 0-.708zm0-2.292a.5.5 0 0 0 .708 0L8 3.207l3.646 3.647a.5.5 0 0 0 .708-.708l-4-4a.5.5 0 0 0-.708 0l-4 4a.5.5 0 0 0 0 .708z"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div class="collapse" id="collapseAlternativeScenarios">
|
||||
<div class="card-body">
|
||||
<div>
|
||||
{% if form.short_range_option == "short_range_yes" %}
|
||||
{% if 'Speaking' in form.short_range_interactions|string or 'Shouting' in form.short_range_interactions|string %}
|
||||
<button class="btn btn-sm btn-primary" id="button_alternative_full_exposure" disabled>Show full exposure</button>
|
||||
<button class="btn btn-sm btn-primary ml-0" id="button_alternative_hide_high_concentration">Hide high concentration</button>
|
||||
|
||||
{% if form.short_range_option == "short_range_no" %}
|
||||
<div class="card bg-light mb-3">
|
||||
<div class="card-header"><strong>Alternative scenarios</strong>
|
||||
<button class="icon_button p-0 float-right" data-toggle="collapse" href="#collapseAlternativeScenarios" role="button" aria-expanded="false" aria-controls="collapseAlternativeScenarios">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-chevron-expand" viewBox="0 0 16 16">
|
||||
<path fill-rule="evenodd" d="M3.646 9.146a.5.5 0 0 1 .708 0L8 12.793l3.646-3.647a.5.5 0 0 1 .708.708l-4 4a.5.5 0 0 1-.708 0l-4-4a.5.5 0 0 1 0-.708zm0-2.292a.5.5 0 0 0 .708 0L8 3.207l3.646 3.647a.5.5 0 0 0 .708-.708l-4-4a.5.5 0 0 0-.708 0l-4 4a.5.5 0 0 0 0 .708z"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div class="collapse" id="collapseAlternativeScenarios">
|
||||
<div class="card-body">
|
||||
<div>
|
||||
{% if form.short_range_option == "short_range_yes" %}
|
||||
{% if 'Speaking' in form.short_range_interactions|string or 'Shouting' in form.short_range_interactions|string %}
|
||||
<button class="btn btn-sm btn-primary" id="button_alternative_full_exposure" disabled>Show full exposure</button>
|
||||
<button class="btn btn-sm btn-primary ml-0" id="button_alternative_hide_high_concentration">Hide high concentration</button>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
<div id="alternative_scenario_plot" style="height: 400px"></div>
|
||||
<script type="application/javascript">
|
||||
draw_alternative_scenarios_plot("concentration_plot", "alternative_scenario_plot");
|
||||
</script>
|
||||
<br>
|
||||
{% block report_scenarios_summary_table %}
|
||||
<table class="table w-auto">
|
||||
<thead class="thead-light">
|
||||
<tr>
|
||||
<th>Scenario</th>
|
||||
<th>P(I)</th>
|
||||
<th>Expected new cases</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for scenario_name, scenario_stats in alternative_scenarios.stats.items() %}
|
||||
<tr>
|
||||
<td> {{ scenario_name }}</td>
|
||||
<td> {{ scenario_stats.probability_of_infection | non_zero_percentage }}</td>
|
||||
<td style="text-align:right">{{ scenario_stats.expected_new_cases | float_format }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endblock report_scenarios_summary_table %}
|
||||
<div id="alternative_scenario_plot" style="height: 400px"></div>
|
||||
<script type="application/javascript">
|
||||
let alternative_scenarios = {{ alternative_scenarios.stats | JSONify }}
|
||||
draw_alternative_scenarios_plot("concentration_plot", "alternative_scenario_plot");
|
||||
</script>
|
||||
<br>
|
||||
{% block report_scenarios_summary_table %}
|
||||
<table class="table w-auto">
|
||||
<thead class="thead-light">
|
||||
<tr>
|
||||
<th>Scenario</th>
|
||||
<th>P(I)</th>
|
||||
<th>Expected new cases</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for scenario_name, scenario_stats in alternative_scenarios.stats.items() %}
|
||||
<tr>
|
||||
<td> {{ scenario_name }}</td>
|
||||
<td> {{ scenario_stats.probability_of_infection | non_zero_percentage }}</td>
|
||||
<td style="text-align:right">{{ scenario_stats.expected_new_cases | float_format }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endblock report_scenarios_summary_table %}
|
||||
</div>
|
||||
<br/>
|
||||
<p class="data_text"> <strong> Notes for alternative scenarios: </strong><br>
|
||||
<ol>
|
||||
<li>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.</li>
|
||||
<li>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.<br>
|
||||
The other alternative scenarios shown for comparison will not include either HEPA filtration or FFP2 masks.</li>
|
||||
</ol>
|
||||
<br>
|
||||
</p>
|
||||
</div>
|
||||
<br/>
|
||||
<p class="data_text"> <strong> Notes for alternative scenarios: </strong><br>
|
||||
<ol>
|
||||
<li>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.</li>
|
||||
<li>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.<br>
|
||||
The other alternative scenarios shown for comparison will not include either HEPA filtration or FFP2 masks.</li>
|
||||
</ol>
|
||||
<br>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock report_results %}
|
||||
|
||||
{% block report_footer %}
|
||||
|
|
|
|||
Loading…
Reference in a new issue