Coverage for pyrc \ tests \ test_temperature_data.py: 14%
42 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-13 16:59 +0200
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-13 16:59 +0200
1# -------------------------------------------------------------------------------
2# Copyright (C) 2026 Joel Kimmich, Tim Jourdan
3# ------------------------------------------------------------------------------
4# License
5# This file is part of PyRC, distributed under GPL-3.0-or-later.
6# ------------------------------------------------------------------------------
8import numpy as np
9from scipy.interpolate import CubicSpline, PchipInterpolator
10from scipy.optimize import minimize
11import matplotlib.pyplot as plt
14def smooth_hourly_data(times, hourly_values, mean_measured_flags):
15 times = np.asarray(times)
16 hourly_values = np.asarray(hourly_values)
18 mid_times = (times[:-1] + times[1:]) / 2
19 init_guess = np.interp(mid_times, times, hourly_values)
21 def objective(mid_vals):
22 all_times = np.concatenate([times, mid_times])
23 all_vals = np.concatenate([hourly_values, mid_vals])
24 sort_idx = np.argsort(all_times)
25 spline = CubicSpline(all_times[sort_idx], all_vals[sort_idx])
27 integral_means = np.array([
28 spline.integrate(times[i], times[i + 1]) / (times[i + 1] - times[i])
29 for i in range(len(hourly_values) - 1)
30 ])
31 residual = integral_means - hourly_values[1:]
32 residual[~mean_measured_flags] = 0
33 return np.sum(residual ** 2)
35 result = minimize(objective, init_guess, method="L-BFGS-B")
36 optimized_mid_vals = result.x
38 all_times_final = np.concatenate([times, mid_times])
39 all_vals_final = np.concatenate([hourly_values, optimized_mid_vals])
40 sort_idx_final = np.argsort(all_times_final)
41 final_spline = CubicSpline(all_times_final[sort_idx_final], all_vals_final[sort_idx_final])
43 return final_spline
46# Example usage:
47if __name__ == '__main__':
48 _times = np.arange(0, 24) # hourly from 0 to 24
49 times_shifted = _times - 0.5
50 _hourly_values = np.array([
51 16.2,
52 17.2,
53 17.4,
54 17.1,
55 16.6,
56 16.0,
57 16.1,
58 17.1,
59 17.4,
60 17.9,
61 19.4,
62 22.2,
63 23.1,
64 23.3,
65 24.6,
66 25.4,
67 25.9,
68 26.0,
69 25.9,
70 23.8,
71 22.8,
72 21.1,
73 20.2,
74 19.3,
75 ])
76 _mean_measured_flags = np.zeros(24, dtype=bool) # True for hourly mean, False for snapshots
78 # Compute spline
79 my_splint = PchipInterpolator(times_shifted, _hourly_values)
80 # interp_func = smooth_hourly_data(_times, _hourly_values, _mean_measured_flags)
82 # Fine resolution for smooth plot
83 fine_times = np.linspace(times_shifted[0], times_shifted[-1], 500)
84 smooth_values = my_splint(fine_times)
86 # Plot
87 plt.figure(figsize=(10, 5))
88 plt.plot(fine_times, smooth_values, label="Spline interpolation")
89 plt.step(_times, _hourly_values, where="pre", label="Hourly mean values", color="r")
90 # plt.scatter(_times, _hourly_values, color="r", zorder=5)
91 plt.xlabel("Time (hours)")
92 plt.ylabel("Value")
93 plt.legend()
94 plt.grid(True)
95 plt.tight_layout()
96 plt.show()