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 - -
+
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 @@

Ventilation data: