diff --git a/cara/apps/calculator/model_generator.py b/cara/apps/calculator/model_generator.py
index 3280aba0..efef71a9 100644
--- a/cara/apps/calculator/model_generator.py
+++ b/cara/apps/calculator/model_generator.py
@@ -48,6 +48,17 @@ class FormData:
if value == "":
form_data[key] = "0"
+ validation_tuples = [('activity_type', ACTIVITY_TYPES),
+ ('event_type', EVENT_TYPES),
+ ('mechanical_ventilation_type', MECHANICAL_VENTILATION_TYPES),
+ ('mask_wearing', MASK_WEARING),
+ ('ventilation_type', VENTILATION_TYPES),
+ ('volume_type', VOLUME_TYPES),
+ ('windows_open', WINDOWS_OPEN)]
+ for key, valid_set in validation_tuples:
+ if form_data[key] not in valid_set:
+ raise ValueError(f"{form_data[key]} is not a valid value for {key}")
+
return cls(
activity_finish=time_string_to_minutes(form_data['activity_finish']),
activity_start=time_string_to_minutes(form_data['activity_start']),
@@ -89,11 +100,14 @@ class FormData:
def ventilation(self) -> models.Ventilation:
# Initializes a ventilation instance as a window if 'natural' is selected, or as a HEPA-filter otherwise
if self.ventilation_type == 'natural':
- if self.windows_open == '10 min / 2h':
+ if self.windows_open == 'interval':
period, duration = 120, 10
+ elif self.windows_number == 'breaks':
+ # TODO: Implement windows open in breaks
+ period, duration = 120, 120
else:
period, duration = 120, 120
- # I multiply the opening width by the number of windows to simulate the correct window area
+
if self.event_type == 'single_event':
month_number = int(self.single_event_date.split('/')[1])
month = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'][month_number - 1]
@@ -103,6 +117,7 @@ class FormData:
inside_temp = models.PiecewiseConstant((0, 24), (293,))
outside_temp = models.GenevaTemperatures[month]
+ # I multiply the opening width by the number of windows to simulate the correct window area
ventilation = models.WindowOpening(active=models.PeriodicInterval(period=period, duration=duration),
inside_temp=inside_temp, outside_temp=outside_temp, cd_b=0.6,
window_height=self.window_height,
@@ -190,8 +205,7 @@ def model_from_form(form: FormData, tmp_raw_form_data) -> models.Model:
# Initializes a mask of type 1 if mask wearing is "continuous", otherwise instantiates the mask attribute as
# the "No mask"-mask
- # TODO: figure out the possible values of mask_wearing in the form
- mask = models.Mask.types['Type I' if d['mask_wearing'] == "Continuous" else 'No mask']
+ mask = models.Mask.types['Type I' if d['mask_wearing'] == "continuous" else 'No mask']
# A dictionary containing the mapping of activities listed in the UI to the activity level and expiration level
# of the infected and exposed occupants respectively.
@@ -264,6 +278,15 @@ def baseline_raw_form_data():
}
+ACTIVITY_TYPES = {'office', 'training', 'workshop'}
+EVENT_TYPES = {'single_event', 'recurrent_event'}
+MECHANICAL_VENTILATION_TYPES = {'air_changes', 'air_supply'}
+MASK_WEARING = {'continuous', 'removed'}
+VENTILATION_TYPES = {'natural', 'mechanical'}
+VOLUME_TYPES = {'room_volume', 'room_dimensions'}
+WINDOWS_OPEN = {'always', 'interval', 'breaks'}
+
+
def time_string_to_minutes(time: str) -> int:
"""
Converts time from string-format to an integer number of minutes after 00:00
diff --git a/cara/apps/calculator/report_generator.py b/cara/apps/calculator/report_generator.py
index a4fc0c36..22f84977 100644
--- a/cara/apps/calculator/report_generator.py
+++ b/cara/apps/calculator/report_generator.py
@@ -69,6 +69,15 @@ def plot(times, concentrations):
return fig
+def minutes_to_string(minutes: int) -> str:
+ minute_string = str(minutes % 60)
+ minute_string = "0" * (2 - len(minute_string)) + minute_string
+ hour_string = str(minutes // 60)
+ hour_string = "0" * (2 - len(hour_string)) + hour_string
+
+ return f"{hour_string}:{minute_string}"
+
+
def build_report(model: models.Model, form: FormData):
now = datetime.now()
time = now.strftime("%d/%m/%Y %H:%M:%S")
@@ -76,7 +85,8 @@ def build_report(model: models.Model, form: FormData):
context = {
'model': model,
- 'request': request,
+ 'request': request,
+ 'form': form,
'creation_date': time,
'model_version': 'Beta v1.0.0',
'simulation_name': form.simulation_name,
@@ -94,16 +104,16 @@ def build_report(model: models.Model, form: FormData):
'total_people': form.total_people,
'infected_people': form.infected_people,
'activity_type': form.activity_type,
- 'activity_start': form.activity_start,
- 'activity_finish': form.activity_finish,
- 'exposure_start': '00:00',
- 'exposure_finish': '01:15',
+ 'activity_start': minutes_to_string(form.activity_start),
+ 'activity_finish': minutes_to_string(form.activity_finish),
+ 'infected_start': minutes_to_string(826),
+ 'infected_finish': minutes_to_string(827),
'event_type': form.event_type,
'single_event_date': form.single_event_date,
'recurrent_event_month': form.recurrent_event_month,
'lunch_option': form.lunch_option,
- 'lunch_start': form.lunch_start,
- 'lunch_finish': form.lunch_finish,
+ 'lunch_start': minutes_to_string(form.lunch_start),
+ 'lunch_finish': minutes_to_string(form.lunch_finish),
'coffee_breaks': form.coffee_breaks,
'coffee_duration': form.coffee_duration,
'coffee_times': [['00:00','00:00'], ['00:00','00:00'], ['00:00','00:00'], ['00:00','00:00']],
diff --git a/cara/apps/calculator/static/form.html b/cara/apps/calculator/static/form.html
index bd4c9df8..409b60f1 100644
--- a/cara/apps/calculator/static/form.html
+++ b/cara/apps/calculator/static/form.html
@@ -41,9 +41,9 @@ Beta v1.0.0 Please send feedback to
@@ -56,8 +56,8 @@ Beta v1.0.0 Please send feedback to
-
- Ventilation data: Mechanical ventilation:
- {% if ventilation_type == "mechanical_ventilation"%}
+ {% if ventilation_type == "mechanical"%}
Yes Air supply flow rate: {{ air_supply }} Natural ventilation:
- {% if ventilation_type == "natural_ventilation"%}
+ {% if ventilation_type == "natural"%}
Yes Number of windows: {{ windows_number }}
+
HEPA filtration:
diff --git a/cara/apps/calculator/templates/report.html.j2 b/cara/apps/calculator/templates/report.html.j2
index b716814f..8c29bb1b 100644
--- a/cara/apps/calculator/templates/report.html.j2
+++ b/cara/apps/calculator/templates/report.html.j2
@@ -24,7 +24,7 @@
Activity type: - {% if activity_type == "office work" %} + {% if activity_type == "office" %} Office work – typical scenario with all persons seated, talking. {% elif activity_type == "workshop" %} Workshop = assembly workshop environment, all persons doing light exercise, talking. @@ -74,7 +74,7 @@
Exposure time (presence of infected person):
Start time: {{ exposure_start }}    End time: {{ exposure_finish }}
Start time: {{ infected_start }}    End time: {{ infected_finish }}
Single event on {{ single_event_date }}