added tests for all the different scenarios

This commit is contained in:
lrdossan 2024-08-29 10:08:30 +02:00
parent a217a83fcc
commit 7918779157
2 changed files with 48 additions and 18 deletions

View file

@ -102,7 +102,8 @@ class CO2FormData(FormData):
"""
Perform change point detection using scipy library (find_peaks method) with rolling average of data.
Incorporate existing state change candidates and adjust the result accordingly.
Returns a list of the detected ventilation state changes.
Returns a list of the detected ventilation state changes, discarding any contribution
of occupancy state changes.
"""
times: list = self.CO2_data['times']
CO2_values: list = self.CO2_data['CO2']
@ -178,6 +179,12 @@ class CO2FormData(FormData):
return sorted(state_change_times)
def ventilation_transition_times(self) -> typing.List[float]:
'''
Check if the last time from the input data is
included in the ventilation ventilations state.
Given that the last time is a required state change,
if not included, this method adds it.
'''
vent_states = self.fitting_ventilation_states
last_time_from_input = self.CO2_data['times'][-1]
if (vent_states and last_time_from_input != vent_states[-1]): # The last time value is always needed for the last ACH interval.

View file

@ -47,40 +47,62 @@ def test_integrated_concentration(simple_co2_conc_model):
@pytest.mark.parametrize(
"scenario_data, room_volume, total_people, start, finish, state_changes", [
["office_scenario_1_sensor_data", 102, 4, "14:00", "17:30", (14.78, 15.10, 15.53, 15.87, 16.52, 16.83)],
["office_scenario_2_sensor_data", 60, 2, "08:38", "17:30", (10.17, 12.45, 14.50)], # Second should be 12.87
"scenario_data, room_volume, max_total_people, start, finish, state_changes", [
["office_scenario_1_sensor_data", 102, 4, "14:00", "17:30", (14.78, 15.1, 15.53, 15.87, 16.52, 16.83)],
["office_scenario_2_sensor_data", 60, 2, "08:38", "17:30", (10.17, 12.45, 14.5)], # Second should be 12.87
["meeting_scenario_1_sensor_data", 83, 3, "09:04", "11:45", (10.37, 11.07)],
["meeting_scenario_2_sensor_data", 83, 4, "13:40", "16:40", (14.37, 14.70, 14.98, 15.33, 15.68, 16.02)]
["meeting_scenario_2_sensor_data", 83, 4, "13:40", "16:40", (14.37, 14.72, 15, 15.33, 15.68, 16.03)]
]
)
def test_find_change_points(scenario_data, room_volume, total_people, start, finish, state_changes, request):
def test_find_change_points(scenario_data, room_volume, max_total_people, start, finish, state_changes, request):
'''
Specific test of the find_change_points method using the
scipy find_peaks and specific smoothing techniques. Only
the ventilation state changes are target for detection.
'''
CO2_form_model: CO2FormData = CO2FormData(
CO2_data=request.getfixturevalue(scenario_data),
fitting_ventilation_states=[],
exposed_start=start,
exposed_finish=finish,
total_people=total_people,
total_people=max_total_people,
room_volume=room_volume,
)
find_points = CO2_form_model.find_change_points()
assert np.allclose(find_points, state_changes, rtol=1e-2)
def test_predictive_model_accuracy(data_registry, office_scenario_2_sensor_data):
@pytest.mark.parametrize(
"scenario_data, room_volume, occupancy, presence_interval, all_state_changes", [
["office_scenario_1_sensor_data", 102, (4,), (14, 17.5), (14, 14.25, 14.78, 15.1, 15.53, 15.87, 16.52, 16.83, 17.5)],
["office_scenario_2_sensor_data", 60, (2, 0, 2), (8.62, 11.93, 12.42, 17.5), (8.62, 10.17, 12.45, 14.5, 17.5, 20.)],
["meeting_scenario_1_sensor_data", 83, (2, 3, 2, 3), (9.07, 9.32, 9.75, 10.75, 11.75), (9.07, 10.37, 11.07, 11.75)],
["meeting_scenario_2_sensor_data", 83, (2, 3, 4), (13.67, 13.75, 15.87, 16.67), (13.67, 14.37, 14.72, 15.00, 15.33, 15.68, 16.03, 16.67)]
]
)
def test_predictive_model_accuracy(data_registry, scenario_data, room_volume, occupancy, presence_interval, all_state_changes, request):
'''
Specific test corresponding to the template data from a simulation day
in one office in Geneva. The room volume, number of people and ventilation
transition times correspond to the real occurencies in the simulation day.
Specific test corresponding to specific data files of four
different occurencies (2 office and 2 meeting room scenarios).
The room volume, number of people and ventilation transition times
correspond to the real occurencies in the simulation days.
Note that the last time from the input file is considered as a ventilation
state change.
'''
input_fitting_data = request.getfixturevalue(scenario_data)
fitting_model: models.CO2DataModel = models.CO2DataModel(
data_registry=data_registry,
room_volume=59.787,
number=2,
presence=models.SpecificInterval(((8.63, 11.95), (12.42, 17.5))),
ventilation_transition_times=(8.63, 10.17, 12.89, 14.5, 17.5, 22.),
times=office_scenario_2_sensor_data['times'],
CO2_concentrations=office_scenario_2_sensor_data['CO2'],
room_volume=room_volume,
number=models.IntPiecewiseConstant(
transition_times=presence_interval,
values=occupancy
),
presence=None,
ventilation_transition_times=all_state_changes,
times=input_fitting_data['times'],
CO2_concentrations=input_fitting_data['CO2'],
)
# Get fitting results
fitting_results: typing.Dict = fitting_model.CO2_fit_params()
@ -90,7 +112,8 @@ def test_predictive_model_accuracy(data_registry, office_scenario_2_sensor_data)
return np.sqrt(np.mean(((actual - predicted) / actual) ** 2)) * 100
# Calculate RMSEP metric
rmsep = root_mean_square_error_percentage(np.array(office_scenario_2_sensor_data['CO2']), np.array(predictive_CO2))
rmsep = root_mean_square_error_percentage(np.array(input_fitting_data['CO2']), np.array(predictive_CO2))
acceptable_rmsep = 10 # Threshold of 10% for the accepted error margin
assert rmsep <= acceptable_rmsep, f"RMSEP {rmsep} exceeds acceptable threshold {acceptable_rmsep}"