added correct pelt suggestion for transition times
This commit is contained in:
parent
69c1c10f6e
commit
c83b5cdcab
3 changed files with 26 additions and 12 deletions
|
|
@ -359,14 +359,13 @@ class CO2Data(BaseRequestHandler):
|
|||
Returns a list of tuples containing (index, X-axis value) for the detected significant changes.
|
||||
"""
|
||||
|
||||
times = CO2_data['times']
|
||||
CO2_values = CO2_data['CO2']
|
||||
times: list = CO2_data['times']
|
||||
CO2_values: list = CO2_data['CO2']
|
||||
|
||||
if len(times) != len(CO2_values):
|
||||
raise ValueError("times and CO2 values must have the same length.")
|
||||
|
||||
# Convert the input lists to numpy arrays for use with the ruptures library
|
||||
times_np = np.array(times)
|
||||
# Convert the input list to a numpy array for use with the ruptures library
|
||||
CO2_np = np.array(CO2_values)
|
||||
|
||||
# Define the model for change point detection (Radial Basis Function kernel)
|
||||
|
|
@ -378,7 +377,14 @@ class CO2Data(BaseRequestHandler):
|
|||
# Predict change points using the Pelt algorithm with a penalty value of 15
|
||||
result = algo.predict(pen=15)
|
||||
|
||||
return [times_np[idx] for idx in result[:-1]]
|
||||
# Find local minima and maxima
|
||||
segments = np.split(np.arange(len(CO2_values)), result)
|
||||
merged_segments = [np.hstack((segments[i], segments[i + 1])) for i in range(len(segments) - 1)]
|
||||
result_set = set()
|
||||
for segment in merged_segments[:-2]:
|
||||
result_set.add(times[CO2_values.index(min(CO2_np[segment]))])
|
||||
result_set.add(times[CO2_values.index(max(CO2_np[segment]))])
|
||||
return list(result_set)
|
||||
|
||||
def generate_ventilation_plot(self, CO2_data: dict, transition_times: typing.Optional[list] = None, ventilation_values: typing.Optional[list] = None):
|
||||
times = CO2_data['times']
|
||||
|
|
@ -411,7 +417,9 @@ class CO2Data(BaseRequestHandler):
|
|||
return
|
||||
|
||||
if endpoint.rstrip('/') == 'plot':
|
||||
self.finish({'CO2_plot': self.generate_ventilation_plot(form.CO2_data, self.find_change_points_with_pelt(form.CO2_data))})
|
||||
transition_times = self.find_change_points_with_pelt(form.CO2_data)
|
||||
self.finish({'CO2_plot': self.generate_ventilation_plot(form.CO2_data, transition_times),
|
||||
'transition_times': [round(el, 2) for el in transition_times]})
|
||||
else:
|
||||
executor = loky.get_reusable_executor(
|
||||
max_workers=self.settings['handler_worker_pool_size'],
|
||||
|
|
|
|||
|
|
@ -190,7 +190,9 @@ class CO2FormData(model_generator.FormData):
|
|||
def ventilation_transition_times(self) -> typing.Tuple[float, ...]:
|
||||
# Check what type of ventilation is considered for the fitting
|
||||
if self.fitting_ventilation_type == 'fitting_natural_ventilation':
|
||||
return tuple(self.fitting_ventilation_states)
|
||||
vent_states = self.fitting_ventilation_states
|
||||
vent_states.append(self.CO2_data['times'][-1])
|
||||
return tuple(vent_states)
|
||||
else:
|
||||
return tuple((self.CO2_data['times'][0], self.CO2_data['times'][-1]))
|
||||
|
||||
|
|
|
|||
|
|
@ -215,10 +215,10 @@ function validateCO2Form() {
|
|||
const max_presence_time = Math.max(elapsed_time_infected, elapsed_time_exposed);
|
||||
const max_transition_time = parsedValue[parsedValue.length - 1] * 60;
|
||||
|
||||
if (max_transition_time < max_presence_time) {
|
||||
if (max_transition_time > max_presence_time) {
|
||||
insertErrorFor(
|
||||
$("#DIVCO2_fitting_result"),
|
||||
`The last transition time (${parsedValue[parsedValue.length - 1]}) should be after the last presence time (${max_presence_time / 60}).<br />`
|
||||
`The last transition time (${parsedValue[parsedValue.length - 1]}) should be before the last presence time (${max_presence_time / 60}).<br />`
|
||||
);
|
||||
submit = false;
|
||||
}
|
||||
|
|
@ -297,6 +297,7 @@ function formatCO2DataForm(CO2_data_form) {
|
|||
let CO2_mapping = {};
|
||||
CO2_data_form.map((el) => {
|
||||
let element = $(`[name=${el}]`).first();
|
||||
|
||||
// Validate checkboxes
|
||||
if (element.prop('type') == "checkbox") {
|
||||
CO2_mapping[element.attr('name')] = String(+element.prop('checked'));
|
||||
|
|
@ -306,7 +307,9 @@ function formatCO2DataForm(CO2_data_form) {
|
|||
CO2_mapping[element.attr('name')] = $(
|
||||
`[name=${element.attr('name')}]:checked`
|
||||
).first().val();
|
||||
else CO2_mapping[element.attr('name')] = element.val();
|
||||
else {
|
||||
CO2_mapping[element.attr('name')] = element.val();
|
||||
}
|
||||
});
|
||||
return CO2_mapping;
|
||||
}
|
||||
|
|
@ -320,9 +323,10 @@ function plotCO2Data(url) {
|
|||
}).then((response) =>
|
||||
response
|
||||
.json()
|
||||
.then((json_response) =>
|
||||
.then((json_response) => {
|
||||
$("#CO2_data_plot").attr("src", json_response["CO2_plot"])
|
||||
)
|
||||
$("#fitting_ventilation_states").val(`[${json_response["transition_times"]}]`)
|
||||
})
|
||||
.then($("#DIVCO2_fitting_to_submit").show())
|
||||
.catch((error) => console.log(error))
|
||||
);
|
||||
|
|
|
|||
Loading…
Reference in a new issue