diff --git a/caimira/apps/calculator/__init__.py b/caimira/apps/calculator/__init__.py index ea869fec..1ce280fe 100644 --- a/caimira/apps/calculator/__init__.py +++ b/caimira/apps/calculator/__init__.py @@ -386,21 +386,33 @@ class CO2Data(BaseRequestHandler): 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): + def generate_ventilation_plot(self, CO2_data: dict, + transition_times: typing.Optional[list] = None, + ventilation_values: typing.Optional[list] = None, + predictive_CO2: typing.Optional[list] = None): times = CO2_data['times'] CO2_data = CO2_data['CO2'] + def time_to_hour(time: float) -> str: + minutes = int(np.floor((time % 1) * 60)) + minutes_to_display = f'0{minutes}' if minutes < 10 else minutes + return f'{int(np.floor(time))}:{minutes_to_display}' + fig = plt.figure(figsize=(7, 4), dpi=110) - plt.plot(times, CO2_data) + plt.plot(times, CO2_data, label='Input CO₂') if (transition_times): for index, time in enumerate(transition_times): plt.axvline(x = time, color = 'grey', linewidth=0.5, linestyle='--') + plt.text(x = time + 0.04, y = max(predictive_CO2) if predictive_CO2 else max(CO2_data), s=time_to_hour(time)) if ventilation_values: y_location = (CO2_data[min(range(len(times)), key=lambda i: abs(times[i]-time))]) plt.text(x = time + 0.04, y = y_location, s="{:.2g}".format(ventilation_values[index])) + if (predictive_CO2): + plt.plot(times, predictive_CO2, label='Predictive CO₂') plt.xlabel('Time of day') plt.ylabel('Concentration (ppm)') + plt.legend(loc='lower right') return img2base64(_figure2bytes(fig)) async def post(self, endpoint: str) -> None: @@ -431,9 +443,14 @@ class CO2Data(BaseRequestHandler): report = await asyncio.wrap_future(report_task) result = dict(report.CO2_fit_params()) + ventilation_transition_times = report.ventilation_transition_times + result['fitting_ventilation_type'] = form.fitting_ventilation_type - result['transition_times'] = report.ventilation_transition_times - result['CO2_plot'] = self.generate_ventilation_plot(form.CO2_data, report.ventilation_transition_times[:-1], result['ventilation_values']) + result['transition_times'] = ventilation_transition_times + result['CO2_plot'] = self.generate_ventilation_plot(form.CO2_data, + ventilation_transition_times[:-1], + result['ventilation_values'], + result['predictive_CO2']) self.finish(result) diff --git a/caimira/models.py b/caimira/models.py index 2f04a0bb..4da916ce 100644 --- a/caimira/models.py +++ b/caimira/models.py @@ -1540,8 +1540,8 @@ class CO2DataModel: exhalation_rate = res_dict['x'][0] ventilation_values = res_dict['x'][1:] - - return {"exhalation_rate": exhalation_rate, "ventilation_values": list(ventilation_values)} + predictive_CO2 = self.CO2_concentrations_from_params(exhalation_rate=exhalation_rate, ventilation_values=ventilation_values) + return {"exhalation_rate": exhalation_rate, "ventilation_values": list(ventilation_values), 'predictive_CO2': list(predictive_CO2)} @dataclass(frozen=True)