diff --git a/cara/apps/calculator/__init__.py b/cara/apps/calculator/__init__.py index e099853b..09023af4 100644 --- a/cara/apps/calculator/__init__.py +++ b/cara/apps/calculator/__init__.py @@ -1,10 +1,12 @@ import json from pathlib import Path +import jinja2 from tornado.web import Application, RequestHandler, StaticFileHandler import cara.models +from datetime import datetime def build_model(request: dict) -> cara.models.Model: return None @@ -34,6 +36,34 @@ class ConcentrationModel(RequestHandler): self.write(response_json) +class StaticModel(RequestHandler): + def get(self): + + import cara.apps.expert + model = cara.apps.expert.baseline_model + + now = datetime.now() + time = now.strftime("%d/%m/%Y %H:%M:%S") + request = {'the': 'form', 'request': 'data'} + context = {'model': model, 'request': request, 'creation_date': time, 'model_version': 'Beta v1.0.0', + 'simulation_name': 'SAMPLE', 'room_number': '40/1-02A', 'room_volume': 30, 'mechanical_ventilation': 'Yes', + 'air_supply': 1, 'air_changes': 2, 'windows_number': 5, 'window_height': 2, 'window_width': 1, + 'opening_distance': 0.05, 'windows_open': '20 minutes every 2 hours', 'hepa_filtration': 'No', 'total_people': 8, + 'infected_people': 7, 'activity_type': 'Office work – typical scenario with all persons seated, talking', + 'activity_start': '00:00', 'activity_finish': '01:15', 'exposure_start': '00:00', 'exposure_finish': '01:15', + 'single_event_date': '5th November', 'lunch_option': 'Yes', 'lunch_start': '00:00', 'lunch_finish': '01:15', + 'coffee_option': 'Yes', 'coffee_number': 4,'coffee_duration': 15, 'coffee_start1': '00:00', 'coffee_finish1': '00:00', + 'coffee_start2': '00:00','coffee_finish2': '00:00', 'coffee_start3': '00:00', 'coffee_finish3': '00:00', + 'coffee_start4': '00:00', 'coffee_finish4': '00:00', 'mask_wearing': 'Yes', + 'infection_probability': round(model.infection_probability(), 2), 'reproduction_rate': 2} + + p = Path(__file__).parent / 'templates' + env = jinja2.Environment( + loader=jinja2.FileSystemLoader(Path(p))) + template = env.get_template('report.html.j2') + self.write(template.render(**context)) + + def make_app(debug=False, prefix='/calculator'): static_dir = Path(__file__).absolute().parent / 'static' urls = [ @@ -43,6 +73,9 @@ def make_app(debug=False, prefix='/calculator'): ( prefix + r'/api/calculator', ConcentrationModel ), + ( + prefix + r'/baseline-model/result', StaticModel + ), ( prefix + r'/static/(.*)', StaticFileHandler, diff --git a/cara/apps/calculator/static/css/report.css b/cara/apps/calculator/static/css/report.css new file mode 100644 index 00000000..eb4363a5 --- /dev/null +++ b/cara/apps/calculator/static/css/report.css @@ -0,0 +1,43 @@ +#body { + top: 10px; + left: 20px; + bottom: 20px; + right: 20px; + padding: 20px; +} + +.image { + display: flex; + align-items: center; + justify-content: center; + font-size: 13pt; +} + +h1{ + text-align: center; +} + +.subtitle { + text-align: center; + font-size: 13pt; + padding-bottom: 15pt; +} + +p.data_title { + font-weight: bold; +} + +p.data_text { + padding-left: 30px; + padding-left:1em; +} + +p.data_subtext { + padding-left: 60px; + margin-left:-3em; +} + +p.result_title { + font-weight: bold; + font-size: 15pt; +} diff --git a/cara/apps/calculator/static/images/disclaimer.jpg b/cara/apps/calculator/static/images/disclaimer.jpg new file mode 100644 index 00000000..bb12e798 Binary files /dev/null and b/cara/apps/calculator/static/images/disclaimer.jpg differ diff --git a/cara/apps/calculator/templates/report.html.j2 b/cara/apps/calculator/templates/report.html.j2 new file mode 100644 index 00000000..c714ec60 --- /dev/null +++ b/cara/apps/calculator/templates/report.html.j2 @@ -0,0 +1,91 @@ + + + + + + + + + + + +

+ VERY IMPORTANT DISCLAIMER

+ +

Output from CARA - COVID Airborne Risk Assessment tool

+ +

Created {{ creation_date }} using model version {{ model_version }}


+ +

Simulation Name: {{ simulation_name }}

+

Room Number: {{ room_number }}

+ +

Input data:

+ + +

Ventilation data:

+ + +

Event data:

+ + +

Break data:

+ + + + +

Mask wearing:

+ + +

Results:

+

In this scenario, the estimated probability of one exposed occupant getting infected (Pi) is {{ infection_probability }} % and the estimated basic reproduction rate (R0) rate is {{ reproduction_rate }}. If you have selected a recurrent event, this is the probability per day, and is cumulative over the number of days.

+

Exposure graph: + + + \ No newline at end of file