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

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# ------------------------------------------------------------------------------ 

7 

8import numpy as np 

9from scipy.interpolate import CubicSpline, PchipInterpolator 

10from scipy.optimize import minimize 

11import matplotlib.pyplot as plt 

12 

13 

14def smooth_hourly_data(times, hourly_values, mean_measured_flags): 

15 times = np.asarray(times) 

16 hourly_values = np.asarray(hourly_values) 

17 

18 mid_times = (times[:-1] + times[1:]) / 2 

19 init_guess = np.interp(mid_times, times, hourly_values) 

20 

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]) 

26 

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) 

34 

35 result = minimize(objective, init_guess, method="L-BFGS-B") 

36 optimized_mid_vals = result.x 

37 

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]) 

42 

43 return final_spline 

44 

45 

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 

77 

78 # Compute spline 

79 my_splint = PchipInterpolator(times_shifted, _hourly_values) 

80 # interp_func = smooth_hourly_data(_times, _hourly_values, _mean_measured_flags) 

81 

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) 

85 

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()