Coverage for tests / test_activity_pim.py: 100%

119 statements  

« prev     ^ index     » next       coverage.py v7.13.4, created at 2026-02-26 21:14 +0000

1 

2import os 

3import pytest 

4from datetime import datetime 

5from numpy import arange, ones, zeros 

6from pandas import read_csv 

7from physiodsp.sensors.imu.base import IMUData 

8from physiodsp.activity.pim import PIMAlgorithm 

9 

10 

11test_folder_path = os.path.dirname(os.path.realpath(__file__)) 

12 

13 

14@pytest.mark.parametrize( 

15 "n_samples,fs", 

16 [ 

17 (128, 32), 

18 (256, 64), 

19 (512, 100) 

20 ] 

21) 

22def test_pim_algorithm(n_samples, fs): 

23 """Test PIM algorithm with various parameters""" 

24 df = read_csv(os.path.join(test_folder_path, "accelerometer.csv"), usecols=["x", "y", "z"]) 

25 timestamp_start = datetime.now().timestamp() 

26 timestamps = timestamp_start + arange(start=0, step=1/fs, stop=int(n_samples/fs)) 

27 imu_data = IMUData( 

28 timestamps=timestamps, 

29 x=df.x.values[:n_samples], 

30 y=df.y.values[:n_samples], 

31 z=df.z.values[:n_samples], 

32 fs=fs 

33 ) 

34 pim = PIMAlgorithm() 

35 result = pim.estimate(imu_data) 

36 assert hasattr(result, 'values_x') 

37 assert hasattr(result, 'values_y') 

38 assert hasattr(result, 'values_z') 

39 assert len(result.values_x) == n_samples 

40 assert len(result.values_y) == n_samples 

41 assert len(result.values_z) == n_samples 

42 assert (result.values_x >= 0).all() 

43 assert (result.values_y >= 0).all() 

44 assert (result.values_z >= 0).all() 

45 

46 

47def test_pim_absolute_values(): 

48 """Test that PIM correctly computes absolute values""" 

49 n_samples = 64 

50 fs = 32 

51 timestamp_start = datetime.now().timestamp() 

52 timestamps = timestamp_start + arange(start=0, step=1/fs, stop=int(n_samples/fs)) 

53 x_data = arange(-10, 10, 20/n_samples) 

54 y_data = arange(-5, 5, 10/n_samples) 

55 z_data = arange(-2, 2, 4/n_samples) 

56 imu_data = IMUData( 

57 timestamps=timestamps, 

58 x=x_data, 

59 y=y_data, 

60 z=z_data, 

61 fs=fs 

62 ) 

63 pim = PIMAlgorithm() 

64 result = pim.estimate(imu_data) 

65 import numpy as np 

66 assert np.allclose(result.values_x, np.abs(x_data)) 

67 assert np.allclose(result.values_y, np.abs(y_data)) 

68 assert np.allclose(result.values_z, np.abs(z_data)) 

69 

70 

71def test_pim_positive_values(): 

72 """Test PIM with already positive values""" 

73 n_samples = 128 

74 fs = 32 

75 timestamp_start = datetime.now().timestamp() 

76 timestamps = timestamp_start + arange(start=0, step=1/fs, stop=int(n_samples/fs)) 

77 x_data = ones(n_samples) * 0.5 

78 y_data = ones(n_samples) * 0.3 

79 z_data = ones(n_samples) * 0.7 

80 imu_data = IMUData( 

81 timestamps=timestamps, 

82 x=x_data, 

83 y=y_data, 

84 z=z_data, 

85 fs=fs 

86 ) 

87 pim = PIMAlgorithm() 

88 result = pim.estimate(imu_data) 

89 import numpy as np 

90 assert np.allclose(result.values_x, x_data) 

91 assert np.allclose(result.values_y, y_data) 

92 assert np.allclose(result.values_z, z_data) 

93 

94 

95def test_pim_zero_values(): 

96 """Test PIM with zero values""" 

97 n_samples = 64 

98 fs = 32 

99 timestamp_start = datetime.now().timestamp() 

100 timestamps = timestamp_start + arange(start=0, step=1/fs, stop=int(n_samples/fs)) 

101 x_data = zeros(n_samples) 

102 y_data = zeros(n_samples) 

103 z_data = zeros(n_samples) 

104 imu_data = IMUData( 

105 timestamps=timestamps, 

106 x=x_data, 

107 y=y_data, 

108 z=z_data, 

109 fs=fs 

110 ) 

111 pim = PIMAlgorithm() 

112 result = pim.estimate(imu_data) 

113 assert (result.values_x == 0).all() 

114 assert (result.values_y == 0).all() 

115 assert (result.values_z == 0).all() 

116 

117 

118def test_pim_algorithm_properties(): 

119 """Test basic properties of PIM algorithm""" 

120 pim = PIMAlgorithm() 

121 assert pim.algorithm_name == "PIMAlgorithm" 

122 assert pim.version == "v0.1.0" 

123 assert hasattr(pim, '_aggregation_window') 

124 assert pim._aggregation_window == 5 

125 

126 

127def test_pim_estimate_returns_self(): 

128 """Test that estimate method returns self for method chaining""" 

129 df = read_csv(os.path.join(test_folder_path, "accelerometer.csv"), usecols=["x", "y", "z"]) 

130 timestamp_start = datetime.now().timestamp() 

131 timestamps = timestamp_start + arange(start=0, step=1/32, stop=4) 

132 imu_data = IMUData( 

133 timestamps=timestamps, 

134 x=df.x.values[:128], 

135 y=df.y.values[:128], 

136 z=df.z.values[:128], 

137 fs=32 

138 ) 

139 pim = PIMAlgorithm() 

140 result = pim.estimate(imu_data) 

141 assert result is pim 

142 

143 

144def test_pim_data_preservation(): 

145 """Test that original IMU data is not modified""" 

146 n_samples = 64 

147 fs = 32 

148 timestamp_start = datetime.now().timestamp() 

149 timestamps = timestamp_start + arange(start=0, step=1/fs, stop=int(n_samples/fs)) 

150 x_data = arange(-10, 10, 20/n_samples) 

151 y_data = arange(-5, 5, 10/n_samples) 

152 z_data = arange(-2, 2, 4/n_samples) 

153 x_copy = x_data.copy() 

154 y_copy = y_data.copy() 

155 z_copy = z_data.copy() 

156 imu_data = IMUData( 

157 timestamps=timestamps, 

158 x=x_data, 

159 y=y_data, 

160 z=z_data, 

161 fs=fs 

162 ) 

163 pim = PIMAlgorithm() 

164 pim.estimate(imu_data) 

165 import numpy as np 

166 assert np.allclose(imu_data.x, x_copy) 

167 assert np.allclose(imu_data.y, y_copy) 

168 assert np.allclose(imu_data.z, z_copy) 

169 

170 

171def test_pim_mixed_values(): 

172 """Test PIM with mixed positive and negative values""" 

173 n_samples = 100 

174 fs = 50 

175 timestamp_start = datetime.now().timestamp() 

176 timestamps = timestamp_start + arange(start=0, step=1/fs, stop=int(n_samples/fs)) 

177 x_data = arange(-5, 5, 10/n_samples) 

178 y_data = arange(0, 10, 10/n_samples) 

179 z_data = arange(-10, 0, 10/n_samples) 

180 imu_data = IMUData( 

181 timestamps=timestamps, 

182 x=x_data, 

183 y=y_data, 

184 z=z_data, 

185 fs=fs 

186 ) 

187 pim = PIMAlgorithm() 

188 result = pim.estimate(imu_data) 

189 import numpy as np 

190 assert np.allclose(result.values_x, np.abs(x_data)) 

191 assert np.allclose(result.values_y, np.abs(y_data)) 

192 assert np.allclose(result.values_z, np.abs(z_data)) 

193 assert (result.values_x >= 0).all() 

194 assert (result.values_y >= 0).all() 

195 assert (result.values_z >= 0).all()