paradigma 0.2.0__py3-none-any.whl → 0.3.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,106 +1,150 @@
1
1
  from typing import Dict, List
2
2
 
3
- from paradigma.constants import DataColumns
3
+ from paradigma.constants import DataColumns, DataUnits
4
4
 
5
5
 
6
- class GaitFeatureExtractionConfig:
6
+
7
+ class IMUConfig:
8
+ """
9
+ Base class for Gait feature extraction and Gait detection configurations, based on the IMU data (accelerometer, gyroscope).
10
+ """
11
+ def __init__(self):
12
+
13
+ self.time_colname = DataColumns.TIME
14
+
15
+ self.l_accelerometer_cols: List[str] = [
16
+ DataColumns.ACCELEROMETER_X,
17
+ DataColumns.ACCELEROMETER_Y,
18
+ DataColumns.ACCELEROMETER_Z,
19
+ ]
20
+ self.l_gyroscope_cols: List[str] = [
21
+ DataColumns.GYROSCOPE_X,
22
+ DataColumns.GYROSCOPE_Y,
23
+ DataColumns.GYROSCOPE_Z,
24
+ ]
25
+
26
+ self.l_gravity_cols: List[str] = [
27
+ DataColumns.GRAV_ACCELEROMETER_X,
28
+ DataColumns.GRAV_ACCELEROMETER_Y,
29
+ DataColumns.GRAV_ACCELEROMETER_Z,
30
+ ]
31
+
32
+ def set_sensor(self, sensor: str) -> None:
33
+ """Sets the sensor and derived filenames"""
34
+ self.sensor: str = sensor
35
+ self.set_filenames(sensor)
36
+
37
+ def set_filenames(self, prefix: str) -> None:
38
+ """Sets the filenames based on the prefix,
39
+
40
+ Parameters
41
+ ----------
42
+ prefix : str
43
+ The prefix for the filenames.
44
+ """
45
+ self.meta_filename = f"{prefix}_meta.json"
46
+ self.time_filename = f"{prefix}_time.bin"
47
+ self.values_filename = f"{prefix}_samples.bin"
48
+
49
+ def set_filenames_values(self, prefix: str) -> None:
50
+ """Sets the filenames based on the prefix,
51
+
52
+ Parameters
53
+ ----------
54
+ prefix : str
55
+ The prefix for the filenames.
56
+ """
57
+ self.meta_filename = f"{prefix}_meta.json"
58
+ self.time_filename = f"{prefix}_time.bin"
59
+ self.values_filename = f"{prefix}_values.bin"
60
+
61
+
62
+ class GaitFeatureExtractionConfig (IMUConfig):
7
63
 
8
64
  def __init__(self) -> None:
9
- self.set_sensor('accelerometer')
65
+ super().__init__()
66
+ self.set_sensor("accelerometer")
10
67
  self.set_sampling_frequency(100)
11
68
 
12
- self.window_type: str = 'hann'
69
+ self.window_type: str = "hann"
13
70
  self.verbose: int = 0
14
-
71
+
15
72
  self.window_length_s: int = 6
16
73
  self.window_step_size_s: int = 1
17
74
 
18
75
  # cepstral coefficients
19
- self.cc_low_frequency = 0
20
- self.cc_high_frequency = 25
76
+ self.cc_low_frequency: int = 0
77
+ self.cc_high_frequency: int = 25
21
78
  self.n_dct_filters_cc: int = 20
22
79
  self.n_coefficients_cc: int = 12
23
-
80
+
24
81
  self.d_frequency_bandwidths: Dict[str, List[float]] = {
25
- 'power_below_gait': [0.3, 0.7],
26
- 'power_gait': [0.7, 3.5],
27
- 'power_tremor': [3.5, 8],
28
- 'power_above_tremor': [8, self.sampling_frequency]
82
+ "power_below_gait": [0.3, 0.7],
83
+ "power_gait": [0.7, 3.5],
84
+ "power_tremor": [3.5, 8],
85
+ "power_above_tremor": [8, self.sampling_frequency],
29
86
  }
30
87
 
31
- self.time_colname = 'time'
32
-
33
- self.l_accelerometer_cols: List[str] = [
34
- DataColumns.ACCELEROMETER_X,
35
- DataColumns.ACCELEROMETER_Y,
36
- DataColumns.ACCELEROMETER_Z
88
+
89
+ self.l_window_level_cols: List[str] = [
90
+ "id",
91
+ "window_nr",
92
+ "window_start",
93
+ "window_end",
37
94
  ]
95
+ self.l_data_point_level_cols: List[str] = (
96
+ self.l_accelerometer_cols + self.l_gravity_cols
97
+ )
38
98
 
39
- self.l_gravity_cols: List[str] = [f'grav_{x}' for x in self.l_accelerometer_cols]
40
- self.l_window_level_cols: List[str] = ['id', 'window_nr', 'window_start', 'window_end']
41
- self.l_data_point_level_cols: List[str] = self.l_accelerometer_cols + self.l_gravity_cols
42
-
43
99
  # TODO: generate this dictionary using object attributes (self.X) and parameters (e.g., n_dct_filters for cc)
44
100
  self.d_channels_values: Dict[str, str] = {
45
- f'grav_{self.sensor}_x_mean': 'g',
46
- f'grav_{self.sensor}_y_mean': 'g',
47
- f'grav_{self.sensor}_z_mean': 'g',
48
- f'grav_{self.sensor}_x_std': 'g',
49
- f'grav_{self.sensor}_y_std': 'g',
50
- f'grav_{self.sensor}_z_std': 'g',
51
- f'{self.sensor}_x_power_below_gait': 'g^2/Hz',
52
- f'{self.sensor}_y_power_below_gait': 'g^2/Hz',
53
- f'{self.sensor}_z_power_below_gait': 'g^2/Hz',
54
- f'{self.sensor}_x_power_gait': 'g^2/Hz',
55
- f'{self.sensor}_y_power_gait': 'g^2/Hz',
56
- f'{self.sensor}_z_power_gait': 'g^2/Hz',
57
- f'{self.sensor}_x_power_tremor': 'g^2/Hz',
58
- f'{self.sensor}_y_power_tremor': 'g^2/Hz',
59
- f'{self.sensor}_z_power_tremor': 'g^2/Hz',
60
- f'{self.sensor}_x_power_above_tremor': 'g^2/Hz',
61
- f'{self.sensor}_y_power_above_tremor': 'g^2/Hz',
62
- f'{self.sensor}_z_power_above_tremor': 'g^2/Hz',
63
- f'{self.sensor}_x_dominant_frequency': 'Hz',
64
- f'{self.sensor}_y_dominant_frequency': 'Hz',
65
- f'{self.sensor}_z_dominant_frequency': 'Hz',
66
- f'std_norm_acc': 'g',
101
+ f"grav_{self.sensor}_x_mean": DataUnits.GRAVITY,
102
+ f"grav_{self.sensor}_y_mean": DataUnits.GRAVITY,
103
+ f"grav_{self.sensor}_z_mean": DataUnits.GRAVITY,
104
+ f"grav_{self.sensor}_x_std": DataUnits.GRAVITY,
105
+ f"grav_{self.sensor}_y_std": DataUnits.GRAVITY,
106
+ f"grav_{self.sensor}_z_std": DataUnits.GRAVITY,
107
+ f"{self.sensor}_x_power_below_gait": DataUnits.POWER_SPECTRAL_DENSITY,
108
+ f"{self.sensor}_y_power_below_gait": DataUnits.POWER_SPECTRAL_DENSITY,
109
+ f"{self.sensor}_z_power_below_gait": DataUnits.POWER_SPECTRAL_DENSITY,
110
+ f"{self.sensor}_x_power_gait": DataUnits.POWER_SPECTRAL_DENSITY,
111
+ f"{self.sensor}_y_power_gait": DataUnits.POWER_SPECTRAL_DENSITY,
112
+ f"{self.sensor}_z_power_gait": DataUnits.POWER_SPECTRAL_DENSITY,
113
+ f"{self.sensor}_x_power_tremor": DataUnits.POWER_SPECTRAL_DENSITY,
114
+ f"{self.sensor}_y_power_tremor": DataUnits.POWER_SPECTRAL_DENSITY,
115
+ f"{self.sensor}_z_power_tremor": DataUnits.POWER_SPECTRAL_DENSITY,
116
+ f"{self.sensor}_x_power_above_tremor": DataUnits.POWER_SPECTRAL_DENSITY,
117
+ f"{self.sensor}_y_power_above_tremor": DataUnits.POWER_SPECTRAL_DENSITY,
118
+ f"{self.sensor}_z_power_above_tremor": DataUnits.POWER_SPECTRAL_DENSITY,
119
+ f"{self.sensor}_x_dominant_frequency": DataUnits.FREQUENCY,
120
+ f"{self.sensor}_y_dominant_frequency": DataUnits.FREQUENCY,
121
+ f"{self.sensor}_z_dominant_frequency": DataUnits.FREQUENCY,
122
+ "std_norm_acc": DataUnits.GRAVITY,
67
123
  }
68
124
 
69
- for cc_coef in range(1, self.n_coefficients_cc+1):
70
- self.d_channels_values[f'cc_{cc_coef}_{self.sensor}'] = 'g'
71
-
72
- # TODO: move to higher level config class (duplicate in armswing feature extraction)
73
- def set_sensor(self, sensor: str) -> None:
74
- """ Sets the sensor and derived filenames """
75
- self.sensor: str = sensor
76
- self.meta_filename: str = f'{self.sensor}_meta.json'
77
- self.values_filename: str = f'{self.sensor}_samples.bin'
78
- self.time_filename: str = f'{self.sensor}_time.bin'
125
+ for cc_coef in range(1, self.n_coefficients_cc + 1):
126
+ self.d_channels_values[f"cc_{cc_coef}_{self.sensor}"] = "g"
79
127
 
80
128
  def set_sampling_frequency(self, sampling_frequency: int) -> None:
81
- """ Sets the sampling frequency and derived variables """
129
+ """Sets the sampling frequency and derived variables"""
82
130
  self.sampling_frequency: int = sampling_frequency
83
131
  self.spectrum_low_frequency: int = 0 # Hz
84
132
  self.spectrum_high_frequency: int = int(self.sampling_frequency / 2) # Hz
85
133
  self.filter_length: int = self.spectrum_high_frequency - 1
86
134
 
87
135
 
88
- class GaitDetectionConfig:
136
+ class GaitDetectionConfig(IMUConfig):
89
137
 
90
138
  def __init__(self) -> None:
91
- self.classifier_file_name = 'gd_classifier.pkl'
92
- self.thresholds_file_name = 'gd_threshold.txt'
93
-
94
- self.meta_filename = 'gait_meta.json'
95
- self.time_filename = 'gait_time.bin'
96
- self.values_filename = 'gait_values.bin'
139
+ super().__init__()
140
+ self.classifier_file_name = "gd_classifier.pkl"
141
+ self.thresholds_file_name = "gd_threshold.txt"
97
142
 
98
- self.l_accel_cols = [DataColumns.ACCELEROMETER_X, DataColumns.ACCELEROMETER_Y, DataColumns.ACCELEROMETER_Z]
143
+ self.set_filenames_values("gait")
99
144
 
100
- self.time_colname = 'time'
101
145
 
102
146
 
103
- class ArmSwingFeatureExtractionConfig:
147
+ class ArmSwingFeatureExtractionConfig(IMUConfig):
104
148
 
105
149
  def initialize_window_length_fields(self, window_length_s: int) -> None:
106
150
  self.window_length_s = window_length_s
@@ -117,10 +161,10 @@ class ArmSwingFeatureExtractionConfig:
117
161
  self.spectrum_high_frequency = int(sampling_frequency / 2)
118
162
 
119
163
  self.d_frequency_bandwidths = {
120
- 'power_below_gait': [0.3, 0.7],
121
- 'power_gait': [0.7, 3.5],
122
- 'power_tremor': [3.5, 8],
123
- 'power_above_tremor': [8, sampling_frequency]
164
+ "power_below_gait": [0.3, 0.7],
165
+ "power_gait": [0.7, 3.5],
166
+ "power_tremor": [3.5, 8],
167
+ "power_above_tremor": [8, sampling_frequency],
124
168
  }
125
169
 
126
170
  # cepstral coefficients
@@ -129,41 +173,32 @@ class ArmSwingFeatureExtractionConfig:
129
173
  self.n_dct_filters_cc: int = 20
130
174
  self.n_coefficients_cc: int = 12
131
175
 
132
- def initialize_column_names(self, time_colname='time', pred_gait_colname='pred_gait',
133
- angle_smooth_colname='angle_smooth', angle_colname='angle',
134
- velocity_colname='velocity', segment_nr_colname='segment_nr') -> None:
135
- self.time_colname = time_colname
136
- self.pred_gait_colname = pred_gait_colname
137
- self.angle_smooth_colname = angle_smooth_colname
138
- self.angle_colname = angle_colname
139
- self.velocity_colname = velocity_colname
140
- self.segment_nr_colname = segment_nr_colname
176
+ def initialize_column_names(
177
+ self
178
+ ) -> None:
141
179
 
142
- self.l_accelerometer_cols: List[str] = [
143
- DataColumns.ACCELEROMETER_X,
144
- DataColumns.ACCELEROMETER_Y,
145
- DataColumns.ACCELEROMETER_Z
146
- ]
180
+ self.pred_gait_colname=DataColumns.PRED_GAIT
181
+ self.angle_smooth_colname: str = DataColumns.ANGLE_SMOOTH
182
+ self.angle_colname=DataColumns.ANGLE
183
+ self.velocity_colname=DataColumns.VELOCITY
184
+ self.segment_nr_colname=DataColumns.SEGMENT_NR
147
185
 
148
- self.l_gyroscope_cols: List[str] = [
149
- DataColumns.GYROSCOPE_X,
150
- DataColumns.GYROSCOPE_Y,
151
- DataColumns.GYROSCOPE_Z
152
- ]
153
-
154
- self.l_gravity_cols: List[str] = [f'grav_{x}' for x in self.l_accelerometer_cols]
155
186
 
156
- self.l_data_point_level_cols = self.l_accelerometer_cols + self.l_gyroscope_cols + self.l_gravity_cols + [
157
- angle_smooth_colname, velocity_colname
158
- ]
187
+ self.l_data_point_level_cols: List[str] = (
188
+ self.l_accelerometer_cols
189
+ + self.l_gyroscope_cols
190
+ + self.l_gravity_cols
191
+ + [self.angle_smooth_colname, self.velocity_colname]
192
+ )
159
193
 
160
194
  def __init__(self) -> None:
195
+ super().__init__()
161
196
  # general
162
- self.sensor = 'IMU'
163
- self.units = 'degrees'
197
+ self.sensor = "IMU"
198
+ self.units = "degrees"
164
199
 
165
200
  # windowing
166
- self.window_type = 'hann'
201
+ self.window_type = "hann"
167
202
  self.initialize_window_length_fields(3)
168
203
 
169
204
  self.initialize_sampling_frequency_fields(100)
@@ -171,72 +206,59 @@ class ArmSwingFeatureExtractionConfig:
171
206
  self.initialize_column_names()
172
207
 
173
208
  self.d_channels_values = {
174
- 'angle_perc_power': 'proportion',
175
- 'range_of_motion': 'deg',
176
- 'forward_peak_ang_vel_mean': 'deg/s',
177
- 'forward_peak_ang_vel_std': 'deg/s',
178
- 'backward_peak_ang_vel_mean': 'deg/s',
179
- 'backward_peak_ang_vel_std': 'deg/s',
180
- 'std_norm_acc': 'g',
181
- 'grav_accelerometer_x_mean': 'g',
182
- 'grav_accelerometer_x_std': 'g',
183
- 'grav_accelerometer_y_mean': 'g',
184
- 'grav_accelerometer_y_std': 'g',
185
- 'grav_accelerometer_z_mean': 'g',
186
- 'grav_accelerometer_z_std': 'g',
187
- 'accelerometer_x_power_below_gait': 'X',
188
- 'accelerometer_x_power_gait': 'X',
189
- 'accelerometer_x_power_tremor': 'X',
190
- 'accelerometer_x_power_above_tremor': 'X',
191
- 'accelerometer_x_dominant_frequency': 'Hz',
192
- 'accelerometer_y_power_below_gait': 'X',
193
- 'accelerometer_y_power_gait': 'X',
194
- 'accelerometer_y_power_tremor': 'X',
195
- 'accelerometer_y_power_above_tremor': 'X',
196
- 'accelerometer_y_dominant_frequency': 'Hz',
197
- 'accelerometer_z_power_below_gait': 'X',
198
- 'accelerometer_z_power_gait': 'X',
199
- 'accelerometer_z_power_tremor': 'X',
200
- 'accelerometer_z_power_above_tremor': 'X',
201
- 'accelerometer_z_dominant_frequency': 'Hz',
202
- 'angle_dominant_frequency': 'Hz',
209
+ "angle_perc_power": "proportion",
210
+ "range_of_motion": "deg",
211
+ "forward_peak_ang_vel_mean": DataUnits.ROTATION,
212
+ "forward_peak_ang_vel_std": DataUnits.ROTATION,
213
+ "backward_peak_ang_vel_mean": DataUnits.ROTATION,
214
+ "backward_peak_ang_vel_std": DataUnits.ROTATION,
215
+ "std_norm_acc": DataUnits.GRAVITY,
216
+ "grav_accelerometer_x_mean": DataUnits.GRAVITY,
217
+ "grav_accelerometer_x_std": DataUnits.GRAVITY,
218
+ "grav_accelerometer_y_mean": DataUnits.GRAVITY,
219
+ "grav_accelerometer_y_std": DataUnits.GRAVITY,
220
+ "grav_accelerometer_z_mean": DataUnits.GRAVITY,
221
+ "grav_accelerometer_z_std": DataUnits.GRAVITY,
222
+ "accelerometer_x_power_below_gait": "X",
223
+ "accelerometer_x_power_gait": "X",
224
+ "accelerometer_x_power_tremor": "X",
225
+ "accelerometer_x_power_above_tremor": "X",
226
+ "accelerometer_x_dominant_frequency": DataUnits.FREQUENCY,
227
+ "accelerometer_y_power_below_gait": "X",
228
+ "accelerometer_y_power_gait": "X",
229
+ "accelerometer_y_power_tremor": "X",
230
+ "accelerometer_y_power_above_tremor": "X",
231
+ "accelerometer_y_dominant_frequency": DataUnits.FREQUENCY,
232
+ "accelerometer_z_power_below_gait": "X",
233
+ "accelerometer_z_power_gait": "X",
234
+ "accelerometer_z_power_tremor": "X",
235
+ "accelerometer_z_power_above_tremor": "X",
236
+ "accelerometer_z_dominant_frequency": DataUnits.FREQUENCY,
237
+ "angle_dominant_frequency": DataUnits.FREQUENCY,
203
238
  }
204
239
 
205
- for sensor in ['accelerometer', 'gyroscope']:
206
- for cc_coef in range(1, self.n_coefficients_cc+1):
207
- self.d_channels_values[f'cc_{cc_coef}_{sensor}'] = 'g'
208
-
209
-
210
- # TODO: move to higher level config class (duplicate in gait feature extraction)
211
- def set_sensor(self, sensor: str) -> None:
212
- """ Sets the sensor and derived filenames """
213
- self.sensor: str = sensor
214
- self.meta_filename: str = f'{self.sensor}_meta.json'
215
- self.values_filename: str = f'{self.sensor}_samples.bin'
216
- self.time_filename: str = f'{self.sensor}_time.bin'
240
+ for sensor in ["accelerometer", "gyroscope"]:
241
+ for cc_coef in range(1, self.n_coefficients_cc + 1):
242
+ self.d_channels_values[f"cc_{cc_coef}_{sensor}"] = DataUnits.GRAVITY
217
243
 
218
244
 
219
- class ArmSwingDetectionConfig:
245
+ class ArmSwingDetectionConfig(IMUConfig):
220
246
 
221
247
  def __init__(self) -> None:
222
- self.classifier_file_name = 'asd_classifier.pkl'
248
+ super().__init__()
249
+ self.classifier_file_name = "asd_classifier.pkl"
223
250
 
224
- self.meta_filename = 'arm_swing_meta.json'
225
- self.time_filename = 'arm_swing_time.bin'
226
- self.values_filename = 'arm_swing_values.bin'
251
+ self.set_filenames_values("arm_swing")
227
252
 
228
- self.l_accel_cols = [DataColumns.ACCELEROMETER_X, DataColumns.ACCELEROMETER_Y, DataColumns.ACCELEROMETER_Z]
229
- self.l_gyro_cols = [DataColumns.GYROSCOPE_X, DataColumns.GYROSCOPE_Y, DataColumns.GYROSCOPE_Z]
230
253
 
231
254
 
232
- class ArmSwingQuantificationConfig:
255
+ class ArmSwingQuantificationConfig(IMUConfig):
233
256
 
234
257
  def __init__(self) -> None:
235
- self.meta_filename = 'arm_swing_meta.json'
236
- self.time_filename = 'arm_swing_time.bin'
237
- self.values_filename = 'arm_swing_values.bin'
258
+ super().__init__()
259
+ self.set_filenames_values("arm_swing")
238
260
 
239
- self.pred_arm_swing_colname = 'pred_arm_swing'
261
+ self.pred_arm_swing_colname = DataColumns.PRED_ARM_SWING
240
262
 
241
263
  self.window_length_s = 3
242
264
  self.window_step_size = 0.75
@@ -1,4 +1,4 @@
1
- from typing import List, Tuple
1
+ from typing import List, Tuple, Union
2
2
  import pickle
3
3
  import pandas as pd
4
4
  import numpy as np
@@ -72,7 +72,7 @@ def extract_ppg_features(arr_ppg: np.ndarray, sampling_frequency: int) -> np.nda
72
72
  # print(features_df)
73
73
 
74
74
 
75
- def peakdet(v: np.ndarray, delta, x: np.ndarray=None) -> Tuple[List[Tuple[int, float]], List[Tuple[int, float]]]:
75
+ def peakdet(v: np.ndarray, delta, x: Union[np.ndarray, None]=None) -> Tuple[List[Tuple[int, float]], List[Tuple[int, float]]]:
76
76
  """
77
77
  Detect peaks in a vector.
78
78
 
@@ -1,3 +1,4 @@
1
+ from pathlib import Path
1
2
  from typing import List, Union
2
3
  import numpy as np
3
4
  import pandas as pd
@@ -10,10 +11,11 @@ from paradigma.util import write_data, read_metadata
10
11
  from paradigma.preprocessing_config import IMUPreprocessingConfig
11
12
 
12
13
 
13
- def preprocess_imu_data(input_path: str, output_path: str, config: IMUPreprocessingConfig) -> None:
14
+ def preprocess_imu_data(input_path: Union[str, Path], output_path: Union[str, Path], config: IMUPreprocessingConfig) -> None:
14
15
 
15
16
  # Load data
16
- metadata_time, metadata_samples = read_metadata(input_path, config.meta_filename, config.time_filename, config.values_filename)
17
+ metadata_time, metadata_samples = read_metadata(str(input_path), str(config.meta_filename),
18
+ str(config.time_filename), str(config.values_filename))
17
19
  df = tsdf.load_dataframe_from_binaries([metadata_time, metadata_samples], tsdf.constants.ConcatenationType.columns)
18
20
 
19
21
  # Rename columns
@@ -24,14 +26,14 @@ def preprocess_imu_data(input_path: str, output_path: str, config: IMUPreprocess
24
26
  df[config.time_colname] = transform_time_array(
25
27
  time_array=df[config.time_colname],
26
28
  scale_factor=1000,
27
- input_unit_type = TimeUnit.difference_ms,
28
- output_unit_type = TimeUnit.relative_ms)
29
+ input_unit_type = TimeUnit.DIFFERENCE_MS,
30
+ output_unit_type = TimeUnit.RELATIVE_MS)
29
31
 
30
32
 
31
33
  df = resample_data(
32
34
  df=df,
33
35
  time_column=config.time_colname,
34
- time_unit_type=TimeUnit.relative_ms,
36
+ time_unit_type=TimeUnit.RELATIVE_MS,
35
37
  unscaled_column_names = list(config.d_channels_imu.keys()),
36
38
  scale_factors=metadata_samples.scale_factors,
37
39
  resampling_frequency=config.sampling_frequency)
@@ -71,10 +73,10 @@ def preprocess_imu_data(input_path: str, output_path: str, config: IMUPreprocess
71
73
  write_data(metadata_time, metadata_samples, output_path, f'{sensor}_meta.json', df_sensor)
72
74
 
73
75
  def transform_time_array(
74
- time_array: np.ndarray,
76
+ time_array: pd.Series,
75
77
  scale_factor: float,
76
- input_unit_type: TimeUnit,
77
- output_unit_type: TimeUnit,
78
+ input_unit_type: str,
79
+ output_unit_type: str,
78
80
  start_time: float = 0.0,
79
81
  ) -> np.ndarray:
80
82
  """
@@ -82,14 +84,14 @@ def transform_time_array(
82
84
 
83
85
  Parameters
84
86
  ----------
85
- time_array : np.ndarray
87
+ time_array : pd.Series
86
88
  The time array in milliseconds to transform.
87
89
  scale_factor : float
88
90
  The scale factor to apply to the time array.
89
- input_unit_type : TimeUnit
90
- The time unit type of the input time array. Raw PPP data was in `TimeUnit.difference_ms`.
91
- output_unit_type : TimeUnit
92
- The time unit type of the output time array. The processing is often done in `TimeUnit.relative_ms`.
91
+ input_unit_type : str
92
+ The time unit type of the input time array. Raw PPP data was in `TimeUnit.DIFFERENCE_MS`.
93
+ output_unit_type : str
94
+ The time unit type of the output time array. The processing is often done in `TimeUnit.RELATIVE_MS`.
93
95
  start_time : float, optional
94
96
  The start time of the time array in UNIX milliseconds (default is 0.0)
95
97
 
@@ -98,28 +100,28 @@ def transform_time_array(
98
100
  time_array
99
101
  The transformed time array in milliseconds, with the specified time unit type.
100
102
  """
101
- # Scale time array and transform to relative time (`TimeUnit.relative_ms`)
102
- if input_unit_type == TimeUnit.difference_ms:
103
+ # Scale time array and transform to relative time (`TimeUnit.RELATIVE_MS`)
104
+ if input_unit_type == TimeUnit.DIFFERENCE_MS:
103
105
  # Convert a series of differences into cumulative sum to reconstruct original time series.
104
106
  time_array = np.cumsum(np.double(time_array)) / scale_factor
105
- elif input_unit_type == TimeUnit.absolute_ms:
107
+ elif input_unit_type == TimeUnit.ABSOLUTE_MS:
106
108
  # Set the start time if not provided.
107
109
  if np.isclose(start_time, 0.0, rtol=1e-09, atol=1e-09):
108
110
  start_time = time_array[0]
109
111
  # Convert absolute time stamps into a time series relative to start_time.
110
112
  time_array = (time_array - start_time) / scale_factor
111
- elif input_unit_type == TimeUnit.relative_ms:
113
+ elif input_unit_type == TimeUnit.RELATIVE_MS:
112
114
  # Scale the relative time series as per the scale_factor.
113
115
  time_array = time_array / scale_factor
114
116
 
115
- # Transform the time array from `TimeUnit.relative_ms` to the specified time unit type
116
- if output_unit_type == TimeUnit.absolute_ms:
117
+ # Transform the time array from `TimeUnit.RELATIVE_MS` to the specified time unit type
118
+ if output_unit_type == TimeUnit.ABSOLUTE_MS:
117
119
  # Converts time array to absolute time by adding the start time to each element.
118
120
  time_array = time_array + start_time
119
- elif output_unit_type == TimeUnit.difference_ms:
121
+ elif output_unit_type == TimeUnit.DIFFERENCE_MS:
120
122
  # Creates a new array starting with 0, followed by the differences between consecutive elements.
121
123
  time_array = np.diff(np.insert(time_array, 0, start_time))
122
- elif output_unit_type == TimeUnit.relative_ms:
124
+ elif output_unit_type == TimeUnit.RELATIVE_MS:
123
125
  # The array is already in relative format, do nothing.
124
126
  pass
125
127
  return time_array
@@ -127,11 +129,11 @@ def transform_time_array(
127
129
 
128
130
  def resample_data(
129
131
  df: pd.DataFrame,
130
- time_column : DataColumns,
131
- time_unit_type: TimeUnit,
132
- unscaled_column_names: list,
132
+ time_column : str,
133
+ time_unit_type: str,
134
+ unscaled_column_names: List[str],
133
135
  resampling_frequency: int,
134
- scale_factors: list = [],
136
+ scale_factors: List[float] = [],
135
137
  start_time: float = 0.0,
136
138
  ) -> pd.DataFrame:
137
139
  """
@@ -143,9 +145,9 @@ def resample_data(
143
145
  The data to resample.
144
146
  time_column : str
145
147
  The name of the time column.
146
- time_unit_type : TimeUnit
147
- The time unit type of the time array. The method currently works only for `TimeUnit.relative_ms`.
148
- unscaled_column_names : list
148
+ time_unit_type : str
149
+ The time unit type of the time array. The method currently works only for `TimeUnit.RELATIVE_MS`.
150
+ unscaled_column_names : List[str]
149
151
  The names of the columns to resample.
150
152
  resampling_frequency : int
151
153
  The frequency to resample the data to.
@@ -160,7 +162,7 @@ def resample_data(
160
162
  The resampled data.
161
163
  """
162
164
  # We need a start_time if the time is in absolute time format
163
- if time_unit_type == TimeUnit.absolute_ms and start_time == 0.0:
165
+ if time_unit_type == TimeUnit.ABSOLUTE_MS and start_time == 0.0:
164
166
  raise ValueError("start_time is required for absolute time format")
165
167
 
166
168
  # get time and values
@@ -183,6 +185,7 @@ def resample_data(
183
185
  raise ValueError("time_abs_array is not strictly increasing")
184
186
 
185
187
  cs = CubicSpline(time_abs_array, scaled_values.T[j])
188
+ #TODO: isn't sensor_col of type DataColumns?
186
189
  df[sensor_col] = cs(df[time_column])
187
190
 
188
191
  return df