UI modifications and CO2 fitting calculation on form side

This commit is contained in:
Luis Aleixo 2023-06-22 09:40:18 +02:00
parent 15d28e1711
commit 147cfe757e
5 changed files with 91 additions and 43 deletions

View file

@ -100,13 +100,17 @@ class CO2FormData:
return instance
def build_model(self) -> models.CO2Data:
population_presence=self.population_present_interval()
last_time_present = population_presence.boundaries()[-1][-1]
last_present_time_index = next((index for index, time in enumerate(self.CO2_data['times'])
if time > last_time_present), len(self.CO2_data['times']))
return models.CO2Data(
room_volume=self.room_volume,
number=self.total_people,
presence=self.population_present_interval(),
ventilation_transition_times=self.ventilation_transition_times(),
times=self.CO2_data['times'],
CO2_concentrations=self.CO2_data['CO2']
presence=population_presence,
ventilation_transition_times=self.ventilation_transition_times(last_time_present),
times=self.CO2_data['times'][:last_present_time_index],
CO2_concentrations=self.CO2_data['CO2'][:last_present_time_index],
)
def _compute_breaks_in_interval(self, start, finish, n_breaks, duration) -> models.BoundarySequence_t:
@ -310,9 +314,10 @@ class CO2FormData:
breaks=breaks,
)
def ventilation_transition_times(self) -> typing.Tuple[float, ...]:
def ventilation_transition_times(self, last_present_time) -> typing.Tuple[float, ...]:
if self.ventilation_type == 'natural_ventilation' and self.window_opening_regime == 'windows_open_periodically':
return tuple(sorted(set(models.PeriodicInterval(self.windows_frequency,
self.windows_duration, min(self.infected_start, self.exposed_start)/60).transition_times())))
transition_times = sorted(models.PeriodicInterval(self.windows_frequency,
self.windows_duration, min(self.infected_start, self.exposed_start)/60).transition_times())
return tuple(filter(lambda x: x < last_present_time, transition_times))
else:
return (min(self.infected_start/60, self.exposed_start/60), max(self.infected_finish/60, self.exposed_finish/60)) # all day long
return tuple((min(self.infected_start, self.exposed_start)/60, max(self.infected_finish, self.exposed_finish)/60), ) # all day long

View file

@ -436,10 +436,24 @@ class FormData:
def ventilation(self) -> models._VentilationBase:
always_on = models.PeriodicInterval(period=120, duration=120)
periodic_interval = models.PeriodicInterval(self.windows_frequency, self.windows_duration, min(self.infected_start, self.exposed_start)/60)
if self.CO2_data_option:
ventilations = []
if self.ventilation_type == 'natural_ventilation' and self.window_opening_regime == 'windows_open_periodically':
for index, time in enumerate(sorted(list(periodic_interval.transition_times()))[:-1]):
if index < len(self.CO2_fitting_result['ventilation_values']):
ventilations.append(models.AirChange(active=models.SpecificInterval(present_times=((time, time + self.windows_duration/60), )),
air_exch=self.CO2_fitting_result['ventilation_values'][index]))
else: break
else:
ventilations.append(models.AirChange(active=always_on, air_exch=self.CO2_fitting_result['ventilation_values'][0]))
return models.MultipleVentilation(tuple(ventilations))
# Initializes a ventilation instance as a window if 'natural_ventilation' is selected, or as a HEPA-filter otherwise
if self.ventilation_type == 'natural_ventilation':
if self.window_opening_regime == 'windows_open_periodically':
window_interval = models.PeriodicInterval(self.windows_frequency, self.windows_duration, min(self.infected_start, self.exposed_start)/60)
window_interval = periodic_interval
else:
window_interval = always_on
@ -521,7 +535,7 @@ class FormData:
elif (self.activity_type == 'precise'):
activity_defn, expiration_defn = self.generate_precise_activity_expiration()
if self.CO2_data_option:
if self.CO2_data_option:
activity = mc.Activity(self.CO2_fitting_result['exhalation_rate'], self.CO2_fitting_result['exhalation_rate'])
else:
activity = activity_distributions[activity_defn]

View file

@ -74,9 +74,9 @@ function displayJsonToHtmlTable(jsonData) {
if (i < 5) {
htmlData +=
"<tr><td>" +
Math.round(row["Times"] * 10) / 10 +
row["Times"].toFixed(2) +
"</td><td>" +
Math.round(row["CO2"] * 10) / 10 +
row["CO2"].toFixed(2) +
"</td></tr>";
}
structure["times"].push(row["Times"]);
@ -85,8 +85,8 @@ function displayJsonToHtmlTable(jsonData) {
if (jsonLength >= 5) htmlData += "<tr><td> ... </td><td> ... </td></tr>";
table.innerHTML = htmlData;
console.log(structure);
format.value = JSON.stringify(structure);
$('#generate_fitting_data').prop("disabled", false);
} else {
table.innerHTML = "There is no data in Excel";
}
@ -160,6 +160,7 @@ function submit_fitting_algorithm(url) {
}
function clear_fitting_algorithm() {
$('#generate_fitting_data').prop("disabled", true);
$("#display_excel_data tbody").remove();
$('#CO2_fitting_result').val('');
$('#formatted_data').val('');

View file

@ -493,10 +493,36 @@ function on_coffee_break_option_change() {
}
}
function ventilation_from_fitting(condition) {
let CO2_data_options = $('input[type=radio][name=ventilation_type]');
let hepa_options = $('input[type=radio][name=hepa_option]');
if (condition) {
$('input[type=radio][id=no_ventilation]').click();
CO2_data_options.each(function (index){
$(this).prop("disabled", true);
});
hepa_options.each(function (index){
$(this).prop("disabled", true);
});
$('#DIVhepa_amount').after($('#window_opening_regime'));
}
else {
CO2_data_options.each(function (index){
$(this).prop("disabled", false);
});
hepa_options.each(function (index){
$(this).prop("disabled", false);
});
$('#DIVopening_distance').after($('#window_opening_regime'));
}
}
function on_CO2_data_option_change() {
CO2_data_options = $('input[type=radio][name=CO2_data_option]');
CO2_data_options.each(function (index){
if (this.checked) {
// if (this.id == 'CO2_data_yes') ventilation_from_fitting(true);
// else if (this.id == 'CO2_data_no') ventilation_from_fitting(false);
getChildElement($(this)).show();
require_fields(this);
}

View file

@ -269,44 +269,46 @@
<div class="col-md-5"><label class="col-form-label">Width of window (m): </label></div>
<div class="col-md-5"><input type="number" step="any" id="window_width" class="non_zero disabled form-control" name="window_width" placeholder="Width" min="0" data-has-radio="#window_hinged"></div>
</div>
<div class="form-group row tabbed">
<div class="form-group row tabbed" id="DIVopening_distance">
<div class="col-md-5"><label class="col-form-label">Opening distance (m): </label></div>
<div class="col-md-5"><input type="number" step="any" id="opening_distance" class="non_zero form-control" name="opening_distance" placeholder="Opening distance" min="0"></div>
</div>
<div class='sub_title'>Window open:
<div data-tooltip="Permanently or periodically - e.g. open the window for 10 minutes (duration) every 60 minutes (frequency).">
<span class="tooltip_text">?</span>
<div id="window_opening_regime">
<div class='sub_title'>Window open:
<div data-tooltip="Permanently or periodically - e.g. open the window for 10 minutes (duration) every 60 minutes (frequency).">
<span class="tooltip_text">?</span>
</div>
</div>
</div>
<input class="ml-2" type="radio" id="windows_open_permanently" name="window_opening_regime" value="windows_open_permanently" onclick="require_fields(this)" checked="checked"></span>
<label for="windows_open_permanently" class="col-form-label ml-2">Permanently</label>
<input class="ml-2" type="radio" id="windows_open_periodically" name="window_opening_regime" value="windows_open_periodically" onclick="require_fields(this)" data-enables="#DIVperiodic_opening"></span>
<label for="windows_open_periodically" class="col-form-label ml-2 mr-2">Periodically</label>
<div id="DIVperiodic_opening">
<div class="form-group row tabbed">
<div class="col-md-5"><label for="window_duration" class="col-form-label ml-2">Duration (min):</label></div>
<div class="col-md-5"><input type="number" step="any" id="windows_duration" class="non_zero form-control" name="windows_duration" value="10" min="1" data-has-radio="#windows_open_periodically"></div>
</div>
<div class="form-group row tabbed">
<div class="col-md-5"><label for="window_frequency" class="col-form-label ml-2">Frequency (min):</label></div>
<div class="col-md-5"><input type="number" step="any" id="windows_frequency" class="non_zero form-control" name="windows_frequency" value="60" min="1" data-has-radio="#windows_open_periodically"></div>
<input class="ml-2" type="radio" id="windows_open_permanently" name="window_opening_regime" value="windows_open_permanently" onclick="require_fields(this)" checked="checked"></span>
<label for="windows_open_permanently" class="col-form-label ml-2">Permanently</label>
<input class="ml-2" type="radio" id="windows_open_periodically" name="window_opening_regime" value="windows_open_periodically" onclick="require_fields(this)" data-enables="#DIVperiodic_opening"></span>
<label for="windows_open_periodically" class="col-form-label ml-2 mr-2">Periodically</label>
<div id="DIVperiodic_opening">
<div class="form-group row tabbed">
<div class="col-md-5"><label for="window_duration" class="col-form-label ml-2">Duration (min):</label></div>
<div class="col-md-5"><input type="number" step="any" id="windows_duration" class="non_zero form-control" name="windows_duration" value="10" min="1" data-has-radio="#windows_open_periodically"></div>
</div>
<div class="form-group row tabbed">
<div class="col-md-5"><label for="window_frequency" class="col-form-label ml-2">Frequency (min):</label></div>
<div class="col-md-5"><input type="number" step="any" id="windows_frequency" class="non_zero form-control" name="windows_frequency" value="60" min="1" data-has-radio="#windows_open_periodically"></div>
</div>
</div>
</div>
</div>
<br/>
<div class='sub_title'>HEPA filtration:</div>
<div>
<input type="radio" id="hepa_yes" name="hepa_option" value=1 onclick="require_fields(this)" data-enables="#DIVhepa_amount">
<label for="hepa_yes" class="col-form-label ml-2">Yes</label>
<input class="ml-2" type="radio" id="hepa_no" name="hepa_option" value=0 onclick="require_fields(this)" checked="checked">
<label for="hepa_no" class="col-form-label ml-2">No</label>
</div>
<div class="form-group row tabbed" id="DIVhepa_amount">
<div class="col-md-5"><label for="hepa_amount" class="col-form-label">Flow rate (m³ / hour):</label></div>
<div class="col-md-5"><input type="number" step="any" id="hepa_amount" class="non_zero form-control" name="hepa_amount" placeholder="Flow rate" min="0" data-has-radio="#hepa_yes"></div>
</div>
<div>
<input type="radio" id="hepa_yes" name="hepa_option" value=1 onclick="require_fields(this)" data-enables="#DIVhepa_amount">
<label for="hepa_yes" class="col-form-label ml-2">Yes</label>
<input class="ml-2" type="radio" id="hepa_no" name="hepa_option" value=0 onclick="require_fields(this)" checked="checked">
<label for="hepa_no" class="col-form-label ml-2">No</label>
</div>
<div class="form-group row tabbed" id="DIVhepa_amount">
<div class="col-md-5"><label for="hepa_amount" class="col-form-label">Flow rate (m³ / hour):</label></div>
<div class="col-md-5"><input type="number" step="any" id="hepa_amount" class="non_zero form-control" name="hepa_amount" placeholder="Flow rate" min="0" data-has-radio="#hepa_yes"></div>
</div>
<hr width="80%">
</div>
@ -675,7 +677,7 @@
</div>
<!-- CO2 Modal -->
<div class="modal fade" id="DIVCO2_data" tabindex="-1" role="dialog" aria-labelledby="CO2_values_title" aria-hidden="true">
<div class="modal fade" id="DIVCO2_data" tabindex="-1" role="dialog" aria-labelledby="CO2_values_title" aria-hidden="true" data-backdrop="static">
<div class="modal-dialog modal-lg" role="document" overflow: visible>
<div class="modal-content">
<div class="modal-header">
@ -711,7 +713,7 @@
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary dismiss_btn_frm_field" data-dismiss="modal" onclick="clear_fitting_algorithm()">Clear all</button>
<button type="button" id="generate_fitting_data" class="btn btn-primary close_btn_frm_field" onclick="submit_fitting_algorithm('{{ get_calculator_url() }}/co2-fit')">Fit data</button>
<button type="button" id="generate_fitting_data" class="btn btn-primary close_btn_frm_field" onclick="submit_fitting_algorithm('{{ get_calculator_url() }}/co2-fit')" disabled>Fit data</button>
<button type="button" style="display: none" id="save_and_dismiss_dialog" class="btn btn-primary close_btn_frm_field" data-dismiss="modal">Save and close</button>
</div>
</div>