Merge branch 'feature/github_issues' into 'master'
Added current scenario for the alternative scenarios & GitHub issues See merge request cara/cara!367
This commit is contained in:
commit
379b5091a8
4 changed files with 50 additions and 45 deletions
|
|
@ -227,12 +227,14 @@ def manufacture_alternative_scenarios(form: FormData) -> typing.Dict[str, mc.Exp
|
|||
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 (form.hepa_option and form.mask_wearing_option == 'mask_on' and 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()
|
||||
if not (not form.hepa_option and FFP2_being_worn):
|
||||
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.
|
||||
|
|
@ -245,17 +247,22 @@ def manufacture_alternative_scenarios(form: FormData) -> typing.Dict[str, mc.Exp
|
|||
|
||||
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 not (form.mask_wearing_option == 'mask_off'):
|
||||
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()
|
||||
if not (form.mask_wearing_option == 'mask_off'):
|
||||
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()
|
||||
|
||||
if not (form.mask_wearing_option == 'mask_on' and form.mask_type == 'Type I' and form.ventilation_type == 'no_ventilation'):
|
||||
scenarios['No ventilation with Type I masks'] = with_mask_no_vent.build_mc_model()
|
||||
if not (form.mask_wearing_option == 'mask_off' and form.ventilation_type == 'no_ventilation'):
|
||||
scenarios['Neither ventilation nor masks'] = without_mask_or_vent.build_mc_model()
|
||||
|
||||
else:
|
||||
no_short_range_alternative = dataclass_utils.replace(form, short_range_interactions=[])
|
||||
|
|
@ -278,11 +285,19 @@ def scenario_statistics(mc_model: mc.ExposureModel, sample_times: typing.List[fl
|
|||
|
||||
|
||||
def comparison_report(
|
||||
report_data: typing.Dict[str, typing.Any],
|
||||
scenarios: typing.Dict[str, mc.ExposureModel],
|
||||
sample_times: typing.List[float],
|
||||
executor_factory: typing.Callable[[], concurrent.futures.Executor],
|
||||
):
|
||||
statistics = {}
|
||||
statistics = {
|
||||
'Current scenario' : {
|
||||
'probability_of_infection': report_data['prob_inf'],
|
||||
'expected_new_cases': report_data['expected_new_cases'],
|
||||
'concentrations': report_data['concentrations'],
|
||||
}
|
||||
}
|
||||
|
||||
with executor_factory() as executor:
|
||||
results = executor.map(
|
||||
scenario_statistics,
|
||||
|
|
@ -293,6 +308,7 @@ def comparison_report(
|
|||
|
||||
for (name, model), model_stats in zip(scenarios.items(), results):
|
||||
statistics[name] = model_stats
|
||||
|
||||
return {
|
||||
'stats': statistics,
|
||||
}
|
||||
|
|
@ -330,11 +346,11 @@ class ReportGenerator:
|
|||
}
|
||||
|
||||
scenario_sample_times = interesting_times(model)
|
||||
|
||||
context.update(calculate_report_data(form, model))
|
||||
report_data = calculate_report_data(form, model)
|
||||
context.update(report_data)
|
||||
alternative_scenarios = manufacture_alternative_scenarios(form)
|
||||
context['alternative_scenarios'] = comparison_report(
|
||||
alternative_scenarios, scenario_sample_times, executor_factory=executor_factory,
|
||||
report_data, alternative_scenarios, scenario_sample_times, executor_factory=executor_factory,
|
||||
)
|
||||
context['permalink'] = generate_permalink(base_url, self.calculator_prefix, form)
|
||||
context['calculator_prefix'] = self.calculator_prefix
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
bottom: 20px;
|
||||
right: 20px;
|
||||
padding: 20px;
|
||||
-webkit-print-color-adjust: exact; /* chrome & webkit browsers */
|
||||
print-color-adjust: exact; /*firefox & IE */
|
||||
}
|
||||
|
||||
h1 {
|
||||
|
|
@ -61,24 +63,6 @@ p.notes {
|
|||
width: 100pt;
|
||||
}
|
||||
|
||||
.red_bkg {
|
||||
color: #000000;
|
||||
background-color: #CD5C5C;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.yellow_bkg {
|
||||
color: #000000;
|
||||
background-color: #FFFF00;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.green_bkg {
|
||||
color: #000000;
|
||||
background-color: #90EE90;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.icon_button {
|
||||
border: none;
|
||||
background: none;
|
||||
|
|
@ -133,15 +117,16 @@ p.notes {
|
|||
.icon_button {
|
||||
display: none!important;
|
||||
}
|
||||
.card {
|
||||
page-break-inside: avoid;
|
||||
}
|
||||
.pi-image {
|
||||
max-height: 9em;
|
||||
}
|
||||
.pi-box {
|
||||
max-width: 260px!important;
|
||||
}
|
||||
.card {
|
||||
page-break-inside: avoid!important;
|
||||
break-inside: avoid!important;
|
||||
}
|
||||
#link-results {
|
||||
display: none;
|
||||
}
|
||||
|
|
@ -172,6 +157,7 @@ p.notes {
|
|||
border-radius: 100px;
|
||||
z-index: 1;
|
||||
-webkit-print-color-adjust: exact!important;
|
||||
print-color-adjust: exact!important;
|
||||
}
|
||||
|
||||
.intro-banner-vdo-play-btn i {
|
||||
|
|
|
|||
|
|
@ -605,8 +605,9 @@ function draw_alternative_scenarios_plot(concentration_plot_svg_id, alternative_
|
|||
.text('Mean concentration (virions/m³)');
|
||||
|
||||
// Legend bounding box.
|
||||
max_key_length = Math.max(...(Object.keys(data_for_scenarios).map(el => el.length)));
|
||||
var legendBBox = vis.append('rect')
|
||||
.attr('width', 275)
|
||||
.attr('width', 8.25 * max_key_length )
|
||||
.attr('height', 25 * (Object.keys(data_for_scenarios).length))
|
||||
.attr('stroke', 'lightgrey')
|
||||
.attr('stroke-width', '2')
|
||||
|
|
@ -711,10 +712,10 @@ function draw_alternative_scenarios_plot(concentration_plot_svg_id, alternative_
|
|||
var div_height = document.getElementById(concentration_plot_svg_id).clientHeight;
|
||||
graph_width = div_width;
|
||||
graph_height = div_height
|
||||
if (div_width >= 900) { // For screens with width > 900px legend can be on the graph's right side.
|
||||
if (div_width >= 1200) { // For screens with width > 900px legend can be on the graph's right side.
|
||||
var margins = { top: 30, right: 20, bottom: 50, left: 60 };
|
||||
div_width = 900;
|
||||
graph_width = div_width * (2/3);
|
||||
div_width = 1200;
|
||||
graph_width = 600;
|
||||
const svg_margins = {'margin-left': '0rem'};
|
||||
Object.entries(svg_margins).forEach(([prop,val]) => vis.style(prop,val));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
{% extends "base/calculator.report.html.j2" %}
|
||||
|
||||
{% set cern_level = 'green-1' %} <!-- green-1, yellow-2, orange-3, red-4 -->
|
||||
{% set orange_prob_lim = 2 %}
|
||||
{% set red_prob_lim = 10 %}
|
||||
|
||||
{% if form.short_range_option == "short_range_yes" %}
|
||||
{% set scenario = alternative_scenarios.stats.values() | first %}
|
||||
|
|
@ -9,10 +11,10 @@
|
|||
{% set long_range_prob_inf = prob_inf %}
|
||||
{% endif %}
|
||||
|
||||
{% if ((long_range_prob_inf > 10) or (expected_new_cases >= 1)) %}
|
||||
{% if ((long_range_prob_inf > red_prob_lim) or (expected_new_cases >= 1)) %}
|
||||
{% set long_range_scale_warning = 'red' %}
|
||||
{% set long_range_warning_color= 'bg-danger' %}
|
||||
{% elif (2 <= long_range_prob_inf <= 10) %}
|
||||
{% elif (orange_prob_lim <= long_range_prob_inf <= red_prob_lim) %}
|
||||
{% set long_range_scale_warning = 'orange' %}
|
||||
{% set long_range_warning_color = 'bg-warning' %}
|
||||
{% else %}
|
||||
|
|
@ -20,8 +22,8 @@
|
|||
{% set long_range_warning_color = 'bg-success' %}
|
||||
{% endif %}
|
||||
|
||||
{% if ((prob_inf > 10) or (expected_new_cases >= 1)) %} {% set scale_warning = 'red' %}
|
||||
{% elif (2 <= prob_inf <= 10) %} {% set scale_warning = 'orange' %}
|
||||
{% if ((prob_inf > red_prob_lim) or (expected_new_cases >= 1)) %} {% set scale_warning = 'red' %}
|
||||
{% elif (orange_prob_lim <= prob_inf <= red_prob_lim) %} {% set scale_warning = 'orange' %}
|
||||
{% else %} {% set scale_warning = 'green' %}
|
||||
{% endif %}
|
||||
|
||||
|
|
@ -135,12 +137,12 @@
|
|||
</thead>
|
||||
<tbody>
|
||||
{% for scenario_name, scenario_stats in alternative_scenarios.stats.items() %}
|
||||
{%if (( scenario_stats.probability_of_infection > 15) or (scenario_stats.expected_new_cases >= 1)) %}
|
||||
<tr class="red_bkg">
|
||||
{% elif (5 <= scenario_stats.probability_of_infection <= 15) %}
|
||||
<tr class="yellow_bkg">
|
||||
{% elif (scenario_stats.probability_of_infection < 5) %}
|
||||
<tr class="green_bkg">
|
||||
{%if (( scenario_stats.probability_of_infection > red_prob_lim) or (scenario_stats.expected_new_cases >= 1)) %}
|
||||
<tr class="alert-danger">
|
||||
{% elif (orange_prob_lim <= scenario_stats.probability_of_infection <= red_prob_lim) %}
|
||||
<tr class="alert-warning">
|
||||
{% elif (scenario_stats.probability_of_infection < orange_prob_lim) %}
|
||||
<tr class="alert-success">
|
||||
{% endif%}
|
||||
<td> {{ scenario_name }}</td>
|
||||
<td> {{ scenario_stats.probability_of_infection | non_zero_percentage }}</td>
|
||||
|
|
|
|||
Loading…
Reference in a new issue