Merge branch 'develop/UI-updates' into 'master'

Updates to form UI

See merge request cara/cara!119
This commit is contained in:
Philip James Elson 2020-12-10 19:38:55 +00:00
commit 6208777d05
8 changed files with 150 additions and 119 deletions

View file

@ -61,10 +61,11 @@ Please enter the number, height and width and opening distance of the windows (i
If there are multiple windows of different sizes, you should take an average.
The window opening distance (in m) is:
* In the case of Sliding or Side-Hung option, the length the window is moved open
* In case of Top- or Bottom-Hung, the distance between the fixed frame and the movable glazed part when open
Window opening distance example (image of open window and measuring tape):
* In the case of Sliding or Side-Hung option, the length the window is moved open.
_Window opening distance example (image of open window and measuring tape):_
![Window Opening Distance](static/images/window_opening.png "How to measure window opening distance")
* In case of Top- or Bottom-Hung, the distance between the fixed frame and the movable glazed part when open.
**Notes**: If you are unsure about the opening distance for the window, it is recommended to choose a conservative value (5 cms, 0.05m or 10cms, 0.10m).
@ -72,7 +73,7 @@ If you open the window at different distances throughout the day, choose an aver
When using natural ventilation, the circulation of air is simulated as a function of the difference between the temperature inside the room and the outside air temperature. The average outdoor temperature for each hour of the day has been computed for every month of the year based on historical data for Geneva, Switzerland.
It is therefore very important to enter the correct time and date in the event data section.
Finally, you must specify when the windows are open - all the time (always), or for 10 minutes every 2 hours.
Finally, you must specify if the windows are open permanently (at all the times), or periodically (in intervals for a certain duration and frequency - both in minutes) - e.g. open the window for 10 minutes (duration) every 60 minutes (frequency).
#### No ventilation
This option assumes there is neither Mechanical nor Natural ventilation in the simulation.

View file

@ -43,6 +43,8 @@ class FormData:
total_people: int
ventilation_type: str
volume_type: str
windows_duration: float
windows_frequency: float
window_height: float
window_type: str
window_width: float
@ -121,6 +123,8 @@ class FormData:
total_people=int(form_data['total_people']),
ventilation_type=form_data['ventilation_type'],
volume_type=form_data['volume_type'],
windows_duration=float(form_data['windows_duration']),
windows_frequency=float(form_data['windows_frequency']),
window_height=float(form_data['window_height']),
window_type=form_data['window_type'],
window_width=float(form_data['window_width']),
@ -138,7 +142,7 @@ class FormData:
# 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 == 'interval':
window_interval = models.PeriodicInterval(120, 10)
window_interval = models.PeriodicInterval(self.windows_frequency, self.windows_duration)
else:
window_interval = always_on
@ -424,7 +428,7 @@ def baseline_raw_form_data():
'mask_type': 'Type I',
'mask_wearing': 'removed',
'mechanical_ventilation_type': '',
'model_version': 'v1.1.0',
'model_version': 'v1.2.0',
'opening_distance': '0.2',
'recurrent_event_month': 'January',
'room_number': '123',
@ -434,11 +438,13 @@ def baseline_raw_form_data():
'total_people': '10',
'ventilation_type': 'natural',
'volume_type': 'room_volume',
'windows_duration': '',
'windows_frequency': '',
'window_height': '2',
'window_type': 'sliding',
'window_width': '2',
'windows_number': '1',
'windows_open': 'interval'
'windows_open': 'always'
}
@ -449,7 +455,7 @@ MASK_TYPES = {'Type I', 'FFP2'}
MASK_WEARING = {'continuous', 'removed'}
VENTILATION_TYPES = {'natural', 'mechanical', 'no-ventilation'}
VOLUME_TYPES = {'room_volume', 'room_dimensions'}
WINDOWS_OPEN = {'always', 'interval', 'breaks', 'not-applicable'}
WINDOWS_OPEN = {'always', 'interval', 'not-applicable'}
WINDOWS_TYPES = {'sliding', 'hinged', 'not-applicable'}

View file

@ -113,6 +113,29 @@ def minutes_to_time(minutes: int) -> str:
return f"{hour_string}:{minute_string}"
def readable_minutes(minutes: int) -> str:
time = minutes
unit = " minute"
if time % 60 == 0:
time = minutes/60
unit = " hour"
if time != 1:
unit += "s"
if time.is_integer():
time = "{:0.0f}".format(time)
else:
time = "{0:.2f}".format(time)
return time + unit
def non_zero_percentage (percentage: int) -> str:
if percentage < 0.01:
return "<0.01%"
else:
return "{:0.0f}%".format(percentage)
def manufacture_alternative_scenarios(form: FormData) -> typing.Dict[str, models.ExposureModel]:
scenarios = {}
@ -223,6 +246,8 @@ def build_report(model: models.ExposureModel, form: FormData):
loader=jinja2.FileSystemLoader([cara_templates, calculator_templates]),
undefined=jinja2.StrictUndefined,
)
env.filters['non_zero_percentage'] = non_zero_percentage
env.filters['readable_minutes'] = readable_minutes
env.filters['minutes_to_time'] = minutes_to_time
env.filters['float_format'] = "{0:.2f}".format
env.filters['int_format'] = "{:0.0f}".format

View file

@ -10,6 +10,10 @@
color: red;
}
.tabbed {
padding-left: 15pt;
}
#disclaimer,#code_license {
font-size: 9pt;
}

View file

@ -1,7 +1,7 @@
/* -------HTML structure------- */
function getChildElement(elem) {
// Get the element named in the given element's data-enables attribute.
return $("#" + elem.data("enables"));
return $(elem.data("enables"));
}
function insertErrorFor(referenceNode, text) {
@ -49,6 +49,12 @@ function require_fields(obj) {
require_air_changes(false);
require_air_supply(true);
break;
case "interval":
require_venting(true);
break;
case "always":
require_venting(false);
break;
case "hepa_yes":
require_hepa(true);
break;
@ -95,14 +101,14 @@ function unrequire_fields(obj) {
function require_room_volume(option) {
require_input_field("#room_volume", option);
disable_input_field("#room_volume", !option);
set_disabled_status("#room_volume", !option);
}
function require_room_dimensions(option) {
require_input_field("#floor_area", option);
require_input_field("#ceiling_height", option);
disable_input_field("#floor_area", !option);
disable_input_field("#ceiling_height", !option);
set_disabled_status("#floor_area", !option);
set_disabled_status("#ceiling_height", !option);
}
function require_mechanical_ventilation(option) {
@ -122,34 +128,38 @@ function require_natural_ventilation(option) {
$("#window_hinged").prop('required', option);
$("#always").prop('required', option);
$("#interval").prop('required', option);
$("#window_sliding").prop('checked', option);
require_window_width(false);
}
function require_window_width(option) {
require_input_field("#window_width", option);
disable_input_field("#window_width", !option);
set_disabled_status("#window_width", !option);
}
function require_air_changes(option) {
require_input_field("#air_changes", option);
disable_input_field("#air_changes", !option);
set_disabled_status("#air_changes", !option);
}
function require_air_supply(option) {
require_input_field("#air_supply", option);
disable_input_field("#air_supply", !option);
set_disabled_status("#air_supply", !option);
}
function require_venting(option) {
require_input_field("#windows_duration", option);
require_input_field("#windows_frequency", option);
set_disabled_status("#windows_duration", !option);
set_disabled_status("#windows_frequency", !option);
}
function require_single_event(option) {
require_input_field("#single_event_date", option);
disable_input_field("#single_event_date", !option);
set_disabled_status("#single_event_date", !option);
}
function require_recurrent_event(option) {
$("#recurrent_event_month").prop('required', option);
disable_input_field("#recurrent_event_month", !option);
set_disabled_status("#recurrent_event_month", !option);
}
function require_lunch(option) {
@ -182,7 +192,7 @@ function require_mask(option) {
function require_hepa(option) {
require_input_field("#hepa_amount", option);
disable_input_field("#hepa_amount", !option);
set_disabled_status("#hepa_amount", !option);
}
function require_input_field(id, option) {
@ -192,7 +202,7 @@ function require_input_field(id, option) {
}
}
function disable_input_field(id, option) {
function set_disabled_status(id, option) {
if (option)
$(id).addClass("disabled");
else
@ -228,10 +238,9 @@ function on_ventilation_type_change() {
} else {
getChildElement($(this)).hide();
unrequire_fields(this);
// Clear the inputs for this newly hidden child element.
// Clear inputs for this newly hidden child element.
getChildElement($(this)).find('input').not('input[type=radio]').val('');
getChildElement($(this)).find('input[type=radio]').prop("checked", false);
getChildElement($(this)).find('input').prop("required", false);
}
});
}
@ -259,75 +268,28 @@ function show_disclaimer() {
}
}
$(".has_radio").on('click', function(event){
click_radio(this.id);
$("[data-has-radio]").on('click', function(event){
$($(this).data("has-radio")).click();
});
$(".has_radio").on('change', function(event){
click_radio(this.id);
$("[data-has-radio]").on('change', function(event){
$($(this).data("has-radio")).click();
});
function click_radio(id) {
switch (id) {
case "room_volume":
$("#room_type_volume").click();
break;
case "floor_area":
case "ceiling_height":
$("#room_type_dimensions").click();
break;
case "air_supply":
$("#air_type_supply").click();
break;
case "air_changes":
$("#air_type_changes").click();
break;
case "window_width":
$("#window_hinged").click();
break;
case "hepa_amount":
$("#hepa_yes").click();
break;
case "single_event_date":
$("#event_type_single").click();
break;
case "recurrent_event_month":
$("#event_type_recurrent").click();
break;
default:
break;
}
}
/* -------Form validation------- */
function validate_form(form) {
var submit = true;
//Validate all non zero values
$("input[required].non_zero").each(function() {
if (!validateValue(this)) {
// Activity times and lunch break times are co-dependent
// -> So if 1 fails it doesn't make sense to check the rest
//Validate all finish times
$("input[required].finish_time").each(function() {
if (!validateFinishTime(this)) {
submit = false;
}
});
//Validate all dates
if (submit) {
$("input[required].datepicker").each(function() {
if (!validateDate(this)) {
submit = false;
}
});
}
//Validate all times
if (submit) {
$("input[required].finish_time").each(function() {
if (!validateFinishTime(this)) {
submit = false;
}
});
}
//Validate all lunch breaks
if (submit) {
$("input[required].lunch").each(function() {
@ -337,7 +299,7 @@ function validate_form(form) {
});
}
//Check if breaks length >= activity length
//Validate breaks length < activity length
if (submit) {
var activityBreaksObj= document.getElementById("activity_breaks");
removeErrorFor(activityBreaksObj);
@ -363,6 +325,32 @@ function validate_form(form) {
}
}
//Validate all non zero values
$("input[required].non_zero").each(function() {
if (!validateValue(this)) {
submit = false;
}
});
//Validate all dates
$("input[required].datepicker").each(function() {
if (!validateDate(this)) {
submit = false;
}
});
//Validate window venting duration < venting frequency
if (!$("#windows_duration").hasClass("disabled")) {
var windowsDurationObj = document.getElementById("windows_duration");
var windowsFrequencyObj = document.getElementById("windows_frequency");
removeErrorFor(windowsFrequencyObj);
if (parseInt(windowsDurationObj.value) >= parseInt(windowsFrequencyObj.value)) {
insertErrorFor(windowsFrequencyObj, "Duration >= Frequency");
submit = false;
}
}
return submit;
}
@ -487,12 +475,8 @@ $(document).ready(function () {
// Call the function now to handle forward/back button presses in the browser.
on_ventilation_type_change();
//Same for other options
require_fields($("input[name='lunch_option']:checked"));
require_fields($("input[name='volume_type']:checked"));
require_fields($("input[name='mechanical_ventilation_type']:checked"));
require_fields($("input[name='window_type']:checked"));
require_fields($("input[name='hepa_option']:checked"));
//Check all radio buttons previously selected
$("input[type=radio]:checked").each(function() {require_fields(this)});
// Setup the maximum number of people at page load (to handle back/forward),
// and update it when total people is changed.
@ -517,11 +501,6 @@ $(document).ready(function () {
$(".start_time[data-lunch-for]").each(function() {validateLunchBreak($(this).data('time-group'))});
$("[data-lunch-for]").change(function() {validateLunchBreak($(this).data('time-group'))});
$("[data-lunch-break]").change(function() {validateLunchBreak($(this).data('lunch-break'))});
var radioValue = $("input[name='event_type']:checked");
if (radioValue.val()) {
require_fields(radioValue.get(0));
}
});
/* -------Debugging------- */

View file

@ -1,6 +1,6 @@
{% extends "layout.html.j2" %}
{% set MODEL_VERSION="v1.1.0" %}
{% set MODEL_VERSION="v1.2.0" %}
{% set DEBUG=False %}
{% set active_page="calculator/" %}
@ -46,12 +46,12 @@
</div><br>
<input type="radio" id="room_type_volume" name="volume_type" value="room_volume" onclick="require_fields(this)" tabindex="-1" required>
<label for="room_type_volume">Room volume:</label> &nbsp;&nbsp;
<input type="number" step="any" id="room_volume" class="non_zero has_radio" name="room_volume" placeholder="Room volume (m³)" min="0"><br>
<input type="number" step="any" id="room_volume" class="non_zero" name="room_volume" placeholder="Room volume (m³)" min="0" data-has-radio="#room_type_volume"><br>
<input type="radio" id="room_type_dimensions" name="volume_type" value="room_dimensions" onclick="require_fields(this)" tabindex="-1" required>
<label for="room_type_dimensions">Floor area:</label> &nbsp;&nbsp;
<input type="number" step="any" id="floor_area" class="non_zero has_radio" name="floor_area" placeholder="Room floor area (m²)" min="0"><br>
<input type="number" step="any" id="floor_area" class="non_zero" name="floor_area" placeholder="Room floor area (m²)" min="0" data-has-radio="#room_type_dimensions"><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <label for="room_type_dimensions">Ceiling height:</label> &nbsp;&nbsp;
<input type="number" step="any" id="ceiling_height" class="non_zero has_radio" name="ceiling_height" placeholder="Room ceiling height (m²)" min="0" ><br>
<input type="number" step="any" id="ceiling_height" class="non_zero" name="ceiling_height" placeholder="Room ceiling height (m²)" min="0" data-has-radio="#room_type_dimensions"><br>
<hr width="80%">
<!-- Ventilation Options -->
@ -62,21 +62,21 @@
Ventilation type:
<input type="radio" id="no_ventilation" name="ventilation_type" value="no-ventilation" checked>
<label for="no_ventilation">No ventilation</label>&nbsp;&nbsp;
<input type="radio" id="mechanical" name="ventilation_type" value="mechanical" data-enables="DIVmechanical_ventilation">
<input type="radio" id="mechanical" name="ventilation_type" value="mechanical" data-enables="#DIVmechanical_ventilation">
<label for="mechanical">Mechanical</label>&nbsp;&nbsp;
<input type="radio" id="natural" name="ventilation_type" value="natural" data-enables="DIVnatural_ventilation">
<input type="radio" id="natural" name="ventilation_type" value="natural" data-enables="#DIVnatural_ventilation">
<label for="natural">Natural</label><br>
<div id="DIVmechanical_ventilation" style="display:none">
<div id="DIVmechanical_ventilation" class="tabbed" style="display:none">
<input type="radio" id="air_type_supply" name="mechanical_ventilation_type" value="air_supply" onclick="require_fields(this)" tabindex="-1">
<label for="air_type_supply">Air supply flow rate</label> &nbsp;&nbsp;
<input type="number" step="any" id="air_supply" class="non_zero has_radio" name="air_supply" min="0" placeholder="(m³ / hour)"><br>
<input type="number" step="any" id="air_supply" class="non_zero" name="air_supply" min="0" placeholder="(m³ / hour)" data-has-radio="#air_type_supply"><br>
<input type="radio" id="air_type_changes" name="mechanical_ventilation_type" value="air_changes" onclick="require_fields(this)" tabindex="-1">
<label for="air_type_changes">Air changes per hour</label> &nbsp;&nbsp;
<input type="number" step="any" id="air_changes" class="non_zero has_radio" name="air_changes" min="0" placeholder="(h⁻¹) only fresh air"><br>
<input type="number" step="any" id="air_changes" class="non_zero" name="air_changes" min="0" placeholder="(h⁻¹) only fresh air" data-has-radio="#air_type_changes"><br>
</div>
<div id="DIVnatural_ventilation" style="display:none">
<div id="DIVnatural_ventilation" class="tabbed" style="display:none">
Number of windows: <input type="number" id="windows_number" class="non_zero" name="windows_number" min="1"><br>
Height of window: <input type="number" step="any" id="window_height" class="non_zero" name="window_height" placeholder="meters" min="0"><br>
Window type:
@ -84,12 +84,15 @@
<label for="window_sliding">Sliding / Side-Hung</label>&nbsp;&nbsp;
<input type="radio" id="window_hinged" name="window_type" value="hinged" onclick="require_fields(this)">
<label for="window_hinged">Top- or Bottom-Hung</label>&nbsp;&nbsp;<br>
Width of window: <input type="number" step="any" id="window_width" class="non_zero has_radio disabled" name="window_width" placeholder="meters" min="0"><br>
Width of window: <input type="number" step="any" id="window_width" class="non_zero disabled" name="window_width" placeholder="meters" min="0" data-has-radio="#window_hinged"><br>
Opening distance: <input type="number" step="any" id="opening_distance" class="non_zero" name="opening_distance" placeholder="meters" min="0"><br>
Windows open: <input type="radio" id="always" name="windows_open" value="always">
<label for="always">Always</label> &nbsp;&nbsp;
<input type="radio" id="interval" name="windows_open" value="interval">
<label for="interval">10 min / 2h</label>
Windows open:</span><br>
<span class="tabbed"><input type="radio" id="always" name="windows_open" value="always" onclick="require_fields(this)" checked="checked"></span>
<label for="always">Permanently</label><br>
<span class="tabbed"><input type="radio" id="interval" name="windows_open" value="interval" onclick="require_fields(this)"></span>
<label for="interval">Periodically:</label>&nbsp;&nbsp;
<input type="number" step="any" id="windows_duration" class="disabled" name="windows_duration" placeholder="Duration (min)" min="1" data-has-radio="#interval"> /
<input type="number" step="any" id="windows_frequency" class="disabled" name="windows_frequency" placeholder="Frequency (min)" min="1" data-has-radio="#interval">
<br>
</div>
@ -98,7 +101,7 @@
<label for="hepa_no">No</label>&nbsp;&nbsp;
<input type="radio" id="hepa_yes" name="hepa_option" value=1 onclick="require_fields(this)">
<label for="hepa_yes">Yes</label>&nbsp;&nbsp;
<input type="number" step="any" id="hepa_amount" class="non_zero has_radio disabled" name="hepa_amount" placeholder="(m³ / hour)" min="0">
<input type="number" step="any" id="hepa_amount" class="non_zero disabled" name="hepa_amount" placeholder="(m³ / hour)" min="0" data-has-radio="#hepa_yes">
<hr width="80%">
<b>Face masks:</b>
@ -154,10 +157,10 @@
<input type="radio" id="event_type_single" name="event_type" value="single_event" onclick="require_fields(this)" tabindex="-1" required>
<label for="event_type_single">Single event</label> &nbsp;&nbsp;
<label for="event_type_single">Date: </label>
<input type="text" id="single_event_date" class="datepicker has_radio" name="single_event_date" placeholder="dd/mm/yyyy"><br>
<input type="text" id="single_event_date" class="datepicker" name="single_event_date" placeholder="dd/mm/yyyy" data-has-radio="#event_type_single"><br>
<input type="radio" id="event_type_recurrent" name="event_type" value="recurrent_event" onclick="require_fields(this)" tabindex="-1" required>
<label for="event_type_recurrent">Recurrent usage</label>
<select id="recurrent_event_month" name="recurrent_event_month" class="has_radio" >
<select id="recurrent_event_month" name="recurrent_event_month" data-has-radio="#event_type_recurrent">
<option value="January">January</option>
<option value="February">February</option>
<option value="March">March</option>
@ -215,8 +218,8 @@
This tool simulates the long range airborne spread SARS-CoV-2 virus in a finite volume and estimates the risk of COVID-19 infection. It is based on current scientific data and can be used to compare the effectiveness of different mitigation measures.<br>
<b>Ventilation data:</b> <br>
<ul>
<li>Mechanical ventilation = check the flow rates with the concerned technical department.</li>
<li>Natural ventilation = the type of window. The opening distance is between the fixed frame and movable part when open (commonly used values are window height = 1.6m and window opening = 0.15m).</li>
<li>Mechanical ventilation = the HVAC supply of fresh air. Check the flow rates with the concerned technical department.</li>
<li>Natural ventilation = the type of window opening. The opening distance is between the fixed frame and movable part when open (commonly used values are window opening between 0.6 and 0.15 m). In case of periodic opening, specify the duration (e.g. for 10 min) and frequency (e.g. every 60 min).</li>
<li>HEPA filtration = the air flow of the device. The following values are based on the different fan velocities of a specific commercial device proposed by the HSE Unit:</li>
<ul>
<li>Level 6 (max) = 430 m<sup>3</sup>/h (noisy)</li>

View file

@ -33,7 +33,7 @@
<p class="data_title">Ventilation data:</p>
<ul>
<li><p class="data_text">Mechanical ventilation:
{% if form.ventilation_type == "mechanical"%}
{% if form.ventilation_type == "mechanical" %}
Yes </p></li>
<ul>
<li><p class="data_subtext">
@ -61,7 +61,14 @@
Sliding / Side-Hung</p></li>
{% endif %}
<li><p class="data_subtext">Opening distance: {{ form.opening_distance }} m</p></li>
<li><p class="data_subtext">Windows open: {{ form.windows_open }}</p></li>
<li><p class="data_subtext">Windows open:
{% if form.windows_open == "interval" %}
Periodically for {{ form.windows_duration | readable_minutes}}
every {{ form.windows_frequency | readable_minutes}}
{% elif form.windows_open == "always" %}
Permanently
{% endif %}
</p></li>
</ul>
<p class="data_subtext data_italic">When using the natural ventilation option, air flows are calculated using averaged hourly temperatures for the Geneva region, based on historical data for the month selected.</p>
{% else %}
@ -90,7 +97,7 @@
Call Centre = typical office-like scenario with all persons seated, all talking continuously.
{% elif form.activity_type == "library" %}
Library = Library scenario with all persons seated, breathing and not talking.
{% elif form.activity_type == "workshop" %}
{% elif form.activity_type == "workshop" %}
Workshop = assembly workshop environment, all persons doing moderate physical activity, talking 50% of the time.
{% elif form.activity_type == "training" %}
Training one person (the trainer) standing, talking, all others seated, talking quietly (whispering). It is assumed the trainer is the infected person, for the worst case scenario.
@ -171,7 +178,7 @@
{% for repeat_event in repeated_events %}
<tr>
<td>{{ repeat_event.repeats }}</td>
<td>{{ repeat_event.probability_of_infection | int_format }}%</td>
<td>{{ repeat_event.probability_of_infection | non_zero_percentage }}</td>
<td style="text-align:right">{{ repeat_event.expected_new_cases | float_format }}</td>
</tr>
{% endfor %}
@ -194,7 +201,7 @@
{% for scenario_name, scenario_stats in alternative_scenarios.stats.items() %}
<tr>
<td>{{ scenario_name }}</td>
<td>{{ scenario_stats.probability_of_infection | int_format }}%</td>
<td>{{ scenario_stats.probability_of_infection | non_zero_percentage }}</td>
<td style="text-align:right">{{ scenario_stats.expected_new_cases | float_format }}</td>
</tr>
{% endfor %}

View file

@ -39,6 +39,8 @@ def test_ventilation_slidingwindow(baseline_form):
window_height=1.6, opening_length=0.6,
)
baseline_form.ventilation_type = 'natural'
baseline_form.windows_duration = 10
baseline_form.windows_frequency = 120
baseline_form.windows_open = 'interval'
baseline_form.window_type = 'sliding'
baseline_form.event_type = 'recurrent_event'
@ -60,6 +62,8 @@ def test_ventilation_hingedwindow(baseline_form):
window_height=1.6, window_width=1., opening_length=0.6,
)
baseline_form.ventilation_type = 'natural'
baseline_form.windows_duration = 10
baseline_form.windows_frequency = 120
baseline_form.windows_open = 'interval'
baseline_form.window_type = 'hinged'
baseline_form.event_type = 'recurrent_event'
@ -118,6 +122,8 @@ def test_ventilation_window_hepa(baseline_form):
ventilation = models.MultipleVentilation((window,hepa))
baseline_form.ventilation_type = 'natural'
baseline_form.windows_duration = 10
baseline_form.windows_frequency = 120
baseline_form.windows_open = 'interval'
baseline_form.event_type = 'recurrent_event'
baseline_form.recurrent_event_month = 'December'