diff --git a/qmra/risk_assessment/exports.py b/qmra/risk_assessment/exports.py new file mode 100644 index 0000000..1c68fb7 --- /dev/null +++ b/qmra/risk_assessment/exports.py @@ -0,0 +1,97 @@ +from zipfile import ZipFile +import base64 +from django.db.models import QuerySet +from django.template.loader import render_to_string + +from qmra.risk_assessment.models import RiskAssessment, RiskAssessmentResult, Inflow, Treatment +import pandas as pd + +from qmra.risk_assessment.plots import risk_plots + + +def inflows_as_df(inflows: QuerySet[Inflow]): + dfs = [] + for inflow in inflows.all(): + dfs += [pd.DataFrame({ + "Pathogen": [inflow.pathogen], + "Minimum Concentration": [inflow.min], + "Maximum Concentration": [inflow.max], + })] + return pd.concat(dfs) + + +def treatments_as_df(treatments: QuerySet[Treatment]) -> pd.DataFrame: + dfs = [] + for t in treatments.all(): + dfs += [pd.DataFrame({ + "Treatment": [t.name] * 3, + "Pathogen group": ["Viruses", "Bacteria", "Protozoa"], + "Maximum LRV": [t.viruses_max, t.bacteria_max, t.protozoa_max], + "Minimum LRV": [t.viruses_min, t.bacteria_min, t.protozoa_min] + })] + return pd.concat(dfs) + + +def risk_assessment_result_as_df(pathogen: str, r: RiskAssessmentResult) -> pd.DataFrame: + return pd.DataFrame({ + ("", "pathogen"): [pathogen] * 2, + ("", "stat"): ["Maximum LRV", "Minimum LRV"], + ("Infection prob.", "min"): [ + r.infection_maximum_lrv_min, r.infection_minimum_lrv_min + ], + ("Infection prob.", "25%"): [ + r.infection_maximum_lrv_q1, r.infection_minimum_lrv_q1 + ], + ("Infection prob.", "50%"): [ + r.infection_maximum_lrv_median, r.infection_minimum_lrv_median + ], + ("Infection prob.", "75%"): [ + r.infection_maximum_lrv_q3, r.infection_minimum_lrv_q3 + ], + ("Infection prob.", "max"): [ + r.infection_maximum_lrv_max, r.infection_minimum_lrv_max + ], + ("DALYs pppy", "min"): [ + r.dalys_maximum_lrv_min, r.dalys_minimum_lrv_min + ], + ("DALYs pppy", "25%"): [ + r.dalys_maximum_lrv_q1, r.dalys_minimum_lrv_q1 + ], + ("DALYs pppy", "50%"): [ + r.dalys_maximum_lrv_median, r.dalys_minimum_lrv_median + ], + ("DALYs pppy", "75%"): [ + r.dalys_maximum_lrv_q3, r.dalys_minimum_lrv_q3 + ], + ("DALYs pppy", "max"): [ + r.dalys_maximum_lrv_max, r.dalys_minimum_lrv_max + ], + }) + + +def results_as_df(results: dict[str, RiskAssessmentResult]) -> pd.DataFrame: + dfs = [] + for pathogen, r in results.items(): + dfs += [risk_assessment_result_as_df(pathogen, r)] + return pd.concat(dfs) + + +def risk_assessment_as_zip(buffer, risk_assessment: RiskAssessment): + inflows = inflows_as_df(risk_assessment.inflows) + treatments = treatments_as_df(risk_assessment.treatments) + results = results_as_df({r.pathogen: r for r in risk_assessment.results.all()}) + plots = risk_plots(risk_assessment.results.all(), "png") + report = render_to_string("assessment-result-export.html", + context=dict(results=risk_assessment.results.all(), + infection_risk=risk_assessment.infection_risk, + risk_plot_data=base64.b64encode(plots[0]).decode("utf-8"), + daly_plot_data=base64.b64encode(plots[1]).decode("utf-8"))) + with ZipFile(buffer, mode="w") as archive: + archive.mkdir("exposure-assessment") + archive.mkdir("results-plots") + archive.writestr("exposure-assessment/inflows.csv", inflows.to_csv(sep=",", decimal=".", index=False)) + archive.writestr("exposure-assessment/treatments.csv", treatments.to_csv(sep=",", decimal=".", index=False)) + archive.writestr(f"{risk_assessment.name}-result.csv", results.to_csv(sep=",", decimal=".", index=False)) + archive.writestr(f"{risk_assessment.name}-report.html", report) + archive.writestr("results-plots/infection-probability.png", plots[0]) + archive.writestr("results-plots/dalys-pppy.png", plots[1]) diff --git a/qmra/risk_assessment/forms.py b/qmra/risk_assessment/forms.py index a37cfbe..2629180 100644 --- a/qmra/risk_assessment/forms.py +++ b/qmra/risk_assessment/forms.py @@ -34,7 +34,7 @@ def __init__(self, *args, **kwargs): self.helper.form_tag = False self.helper.label_class = "text-muted small" self.helper.layout = Layout( - Row(Column("name"), Column("description")), + Row(Column("name"), Column("description"), css_id="name-and-description"), Row(Column("exposure_name"), Column("events_per_year"), Column("volume_per_event"), css_id="exposure-form-fieldset"), # Row("source_name", css_id="source-form") ) diff --git a/qmra/risk_assessment/plots.py b/qmra/risk_assessment/plots.py index bc7b853..274fe4b 100644 --- a/qmra/risk_assessment/plots.py +++ b/qmra/risk_assessment/plots.py @@ -26,7 +26,7 @@ COLOR_SEQS = dict(min=MIN_COLOR_SEQ, max=MAX_COLOR_SEQ, none=NONE_COLOR_SEQ) -def risk_plots(risk_assessment_results, risk_category="none"): +def risk_plots(risk_assessment_results, output_type="div"): infection_prob_fig = go.Figure() dalys_fig = go.Figure() for i, r in enumerate(risk_assessment_results): @@ -111,7 +111,7 @@ def risk_plots(risk_assessment_results, risk_category="none"): dalys_fig.update_traces( marker_size=8 ) - - return plot(infection_prob_fig, output_type="div", config={'displayModeBar': False}, include_plotlyjs=False), \ - plot(dalys_fig, output_type="div", config={'displayModeBar': False}, include_plotlyjs=False) - + if output_type == "div": + return plot(infection_prob_fig, output_type="div", config={'displayModeBar': False}, include_plotlyjs=False), \ + plot(dalys_fig, output_type="div", config={'displayModeBar': False}, include_plotlyjs=False) + return infection_prob_fig.to_image(format=output_type), dalys_fig.to_image(format=output_type) diff --git a/qmra/risk_assessment/templates/assessment-configurator.html b/qmra/risk_assessment/templates/assessment-configurator.html index 9ed6912..e804abd 100644 --- a/qmra/risk_assessment/templates/assessment-configurator.html +++ b/qmra/risk_assessment/templates/assessment-configurator.html @@ -11,7 +11,7 @@

Risk assessment parameters

{% include "risk-assessment-form-fieldset.html" with risk_assessment_form=risk_assessment_form %} {% include "inflows-form-fieldset.html" with inflow_form=inflow_form source_name_field=risk_assessment_form.source_name %} {% include "treatments-form-fieldset.html" with treatment_form=treatment_form add_treatment_form=add_treatment_form %} -
+
@@ -20,19 +20,19 @@

Risk assessment parameters