Include a scenario graph in the report.

This commit is contained in:
Phil Elson 2020-11-06 11:01:59 +01:00
parent d9b880d056
commit 0f2f306ff3
2 changed files with 49 additions and 5 deletions

View file

@ -1,7 +1,12 @@
import base64
from datetime import datetime
import io
from pathlib import Path
import jinja2
import matplotlib
matplotlib.use('agg')
import matplotlib.pyplot as plt
import numpy as np
from cara import models
@ -10,13 +15,19 @@ from .model_generator import FormData
def calculate_report_data(model: models.Model):
resolution = 600
times = list(np.linspace(0, 10, resolution))
# TODO: Have this for exposed not infected.
t_start = model.infected.presence.boundaries()[0][0]
t_end = model.infected.presence.boundaries()[-1][1]
times = list(np.linspace(t_start, t_end, resolution))
concentrations = [model.concentration(time) for time in times]
highest_const = max(concentrations)
prob = model.infection_probability()
er = model.infected.emission_rate(0.1)
exposed_occupants = model.exposed_occupants
r0 = prob * exposed_occupants / 100
return {
"times": times,
"concentrations": concentrations,
@ -25,14 +36,46 @@ def calculate_report_data(model: models.Model):
"emission_rate": er,
"exposed_occupants": exposed_occupants,
"R0": r0,
"scenario_plot_src": embed_figure(plot(times, concentrations)),
}
def embed_figure(figure) -> str:
# Draw the scenario graph.
img_data = io.BytesIO()
figure.savefig(img_data, format='png', bbox_inches="tight")
plt.close()
img_data.seek(0)
pic_hash = base64.b64encode(img_data.read()).decode('ascii')
# A src suitable for a tag such as f'<img id="scenario_concentration_plot" src="{result}">.
return f'data:image/png;base64,{pic_hash}'
def plot(times, concentrations):
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
ax.plot(times, concentrations)
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)
ax.set_xlabel('Hours from start of event')
ax.set_ylabel('Concentration ($q/m^3$)')
ax.set_title('Concentration of infectious quanta aerosols')
# top = max([0.75, max(concentrations)])
# print(max(concentrations))
# ax.set_ylim(bottom=1e-4, top=top)
return fig
def build_report(model: models.Model, form: FormData):
now = datetime.now()
time = now.strftime("%d/%m/%Y %H:%M:%S")
request = {"the": "form", "request": "data"}
context = {
'model': model,
'model': model,
'request': request,
'creation_date': time,
'model_version': 'Beta v1.0.0',
@ -65,8 +108,6 @@ def build_report(model: models.Model, form: FormData):
'coffee_duration': form.coffee_duration,
'coffee_times': [['00:00','00:00'], ['00:00','00:00'], ['00:00','00:00'], ['00:00','00:00']],
'mask_wearing': form.mask_wearing,
'infection_probability': round(model.infection_probability(), 2),
'reproduction_rate': 2
}
context.update(calculate_report_data(model))

View file

@ -121,8 +121,11 @@
</ul>
<p class="result_title">Results:</p>
<p class="data_text"> In this scenario, the estimated probability of one exposed occupant getting infected P(i) is {{ infection_probability }} % and the estimated basic reproduction rate (R0) is {{ reproduction_rate }}.<p>
<p class="data_text">
In this scenario, the estimated probability of one exposed occupant getting infected P(i) is {{ "{:#.2g}".format(prob_inf) }}% and the estimated basic reproduction rate (R0) is {{ "{:#.2g}".format(R0) }}.
<p>
<p class="data_title">Exposure graph:</p>
<img id="scenario_concentration_plot" src="{{ scenario_plot_src }}">
<br><br><br><br><br><br><br>
<div style="border: 2px solid black; padding: 15px;">