UI modifications and CO2 fitting calculation on form side
This commit is contained in:
parent
15d28e1711
commit
147cfe757e
5 changed files with 91 additions and 43 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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('');
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
Loading…
Reference in a new issue