Skip to content

Commit

Permalink
Use actual Enum for constants and types
Browse files Browse the repository at this point in the history
  • Loading branch information
kretep committed Aug 29, 2024
1 parent 634ffd6 commit 3d76b18
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 48 deletions.
8 changes: 5 additions & 3 deletions src/paradigma/constants.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
class DataColumns:
from enum import Enum

class DataColumns(Enum):
"""
Enum for the data channels in tsdf.
"""
Expand All @@ -11,7 +13,7 @@ class DataColumns:
PPG = "green"
TIME = "time"

class DataUnits:
class DataUnits(Enum):
"""
Enum for the data channel unit types in tsdf.
"""
Expand All @@ -21,7 +23,7 @@ class DataUnits:
""" The rotation is in degrees per second. """


class TimeUnit:
class TimeUnit(Enum):
"""
Enum for the `time` channel unit types in tsdf.
"""
Expand Down
6 changes: 3 additions & 3 deletions src/paradigma/gait_analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,9 @@ def extract_arm_swing_features(input_path: Union[str, Path], output_path: Union[
# perform principal component analysis on the gyroscope signals to obtain the angular velocity in the
# direction of the swing of the arm
df[config.velocity_colname] = pca_transform_gyroscope(
df=df,
y_gyro_colname=DataColumns.GYROSCOPE_Y,
z_gyro_colname=DataColumns.GYROSCOPE_Z,
df=df,
y_gyro_colname=DataColumns.GYROSCOPE_Y.value,
z_gyro_colname=DataColumns.GYROSCOPE_Z.value,
pred_gait_colname=config.pred_gait_colname
)

Expand Down
30 changes: 17 additions & 13 deletions src/paradigma/gait_analysis_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ def __init__(self) -> None:

self.time_colname = 'time'

self.l_accelerometer_cols: List[str] = [
DataColumns.ACCELEROMETER_X,
DataColumns.ACCELEROMETER_Y,
DataColumns.ACCELEROMETER_Z
self.l_accelerometer_cols: List[str] = [ # strings, not DataColumns, as we'll edit them
"accelerometer_x",
"accelerometer_y",
"accelerometer_z",
]

self.l_gravity_cols: List[str] = [f'grav_{x}' for x in self.l_accelerometer_cols]
Expand Down Expand Up @@ -95,7 +95,7 @@ def __init__(self) -> None:
self.time_filename = 'gait_time.bin'
self.values_filename = 'gait_values.bin'

self.l_accel_cols = [DataColumns.ACCELEROMETER_X, DataColumns.ACCELEROMETER_Y, DataColumns.ACCELEROMETER_Z]
self.l_accel_cols = [DataColumns.ACCELEROMETER_X.value, DataColumns.ACCELEROMETER_Y.value, DataColumns.ACCELEROMETER_Z.value]

self.time_colname = 'time'

Expand Down Expand Up @@ -140,15 +140,15 @@ def initialize_column_names(self, time_colname='time', pred_gait_colname='pred_g
self.segment_nr_colname = segment_nr_colname

self.l_accelerometer_cols: List[str] = [
DataColumns.ACCELEROMETER_X,
DataColumns.ACCELEROMETER_Y,
DataColumns.ACCELEROMETER_Z
DataColumns.ACCELEROMETER_X.value,
DataColumns.ACCELEROMETER_Y.value,
DataColumns.ACCELEROMETER_Z.value
]

self.l_gyroscope_cols: List[str] = [
DataColumns.GYROSCOPE_X,
DataColumns.GYROSCOPE_Y,
DataColumns.GYROSCOPE_Z
DataColumns.GYROSCOPE_X.value,
DataColumns.GYROSCOPE_Y.value,
DataColumns.GYROSCOPE_Z.value
]

self.l_gravity_cols: List[str] = [f'grav_{x}' for x in self.l_accelerometer_cols]
Expand Down Expand Up @@ -225,8 +225,12 @@ def __init__(self) -> None:
self.time_filename = 'arm_swing_time.bin'
self.values_filename = 'arm_swing_values.bin'

self.l_accel_cols = [DataColumns.ACCELEROMETER_X, DataColumns.ACCELEROMETER_Y, DataColumns.ACCELEROMETER_Z]
self.l_gyro_cols = [DataColumns.GYROSCOPE_X, DataColumns.GYROSCOPE_Y, DataColumns.GYROSCOPE_Z]
self.l_accel_cols = [DataColumns.ACCELEROMETER_X.value,
DataColumns.ACCELEROMETER_Y.value,
DataColumns.ACCELEROMETER_Z.value]
self.l_gyro_cols = [DataColumns.GYROSCOPE_X.value,
DataColumns.GYROSCOPE_Y.value,
DataColumns.GYROSCOPE_Z.value]


class ArmSwingQuantificationConfig:
Expand Down
6 changes: 3 additions & 3 deletions src/paradigma/heart_rate_analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ def extract_signal_quality_features(input_path: str, classifier_path: str, outpu
# load data
metadata_time_ppg, metadata_samples_ppg = read_metadata(input_path, "PPG_meta.json", "PPG_time.bin", "PPG_samples.bin")
df_ppg = tsdf.load_dataframe_from_binaries([metadata_time_ppg, metadata_samples_ppg], tsdf.constants.ConcatenationType.columns)
arr_ppg = df_ppg[DataColumns.PPG].to_numpy()
relative_time_ppg = df_ppg[DataColumns.TIME].to_numpy()
arr_ppg = df_ppg[DataColumns.PPG.value].to_numpy()
relative_time_ppg = df_ppg[DataColumns.TIME.value].to_numpy()

metadata_time_acc, metadata_samples_acc = read_metadata(input_path, "accelerometer_meta.json", "accelerometer_time.bin", "accelerometer_samples.bin")
df_acc = tsdf.load_dataframe_from_binaries([metadata_time_acc, metadata_samples_acc], tsdf.constants.ConcatenationType.columns)
arr_acc = df_acc[[DataColumns.ACCELEROMETER_X, DataColumns.ACCELEROMETER_Y, DataColumns.ACCELEROMETER_Z]].to_numpy()
arr_acc = df_acc[[DataColumns.ACCELEROMETER_X.value, DataColumns.ACCELEROMETER_Y.value, DataColumns.ACCELEROMETER_Z.value]].to_numpy()

sampling_frequency_ppg = config.sampling_frequency_ppg
sampling_frequency_imu = config.sampling_frequency_imu
Expand Down
23 changes: 12 additions & 11 deletions src/paradigma/imu_preprocessing.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def preprocess_imu_data(input_path: Union[str, Path], output_path: Union[str, Pa

# convert to relative seconds from delta milliseconds
df[config.time_colname] = transform_time_array(
time_array=df[config.time_colname],
time_array=df[config.time_colname.value],
scale_factor=1000,
input_unit_type = TimeUnit.difference_ms,
output_unit_type = TimeUnit.relative_ms)
Expand All @@ -39,7 +39,7 @@ def preprocess_imu_data(input_path: Union[str, Path], output_path: Union[str, Pa
resampling_frequency=config.sampling_frequency)

if config.side_watch == 'left':
df[DataColumns.ACCELEROMETER_X] *= -1
df[DataColumns.ACCELEROMETER_X.value] *= -1

for col in config.d_channels_accelerometer.keys():

Expand All @@ -61,7 +61,7 @@ def preprocess_imu_data(input_path: Union[str, Path], output_path: Union[str, Pa

# Store data
for sensor, units in zip(['accelerometer', 'gyroscope'], ['g', config.rotation_units]):
df_sensor = df[[config.time_colname] + [x for x in df.columns if sensor in x]]
df_sensor = df[[config.time_colname.value] + [x for x in df.columns if sensor in x]]

metadata_samples.channels = [x for x in df.columns if sensor in x]
metadata_samples.units = list(np.repeat(units, len(metadata_samples.channels)))
Expand All @@ -75,8 +75,8 @@ def preprocess_imu_data(input_path: Union[str, Path], output_path: Union[str, Pa
def transform_time_array(
time_array: pd.Series,
scale_factor: float,
input_unit_type: str,
output_unit_type: str,
input_unit_type: TimeUnit,
output_unit_type: TimeUnit,
start_time: float = 0.0,
) -> np.ndarray:
"""
Expand All @@ -88,9 +88,9 @@ def transform_time_array(
The time array in milliseconds to transform.
scale_factor : float
The scale factor to apply to the time array.
input_unit_type : str
input_unit_type : TimeUnit
The time unit type of the input time array. Raw PPP data was in `TimeUnit.difference_ms`.
output_unit_type : str
output_unit_type : TimeUnit
The time unit type of the output time array. The processing is often done in `TimeUnit.relative_ms`.
start_time : float, optional
The start time of the time array in UNIX milliseconds (default is 0.0)
Expand Down Expand Up @@ -129,8 +129,8 @@ def transform_time_array(

def resample_data(
df: pd.DataFrame,
time_column : str,
time_unit_type: str,
time_column : DataColumns,
time_unit_type: TimeUnit,
unscaled_column_names: List[str],
resampling_frequency: int,
scale_factors: List[float] = [],
Expand Down Expand Up @@ -177,15 +177,16 @@ def resample_data(
t_resampled = np.arange(start_time, time_abs_array[-1], 1 / resampling_frequency)

# create dataframe
df = pd.DataFrame(t_resampled, columns=[time_column])
df = pd.DataFrame(t_resampled, columns=[time_column.value])

# interpolate IMU - maybe a separate method?
for j, sensor_col in enumerate(unscaled_column_names):
if not np.all(np.diff(time_abs_array) > 0):
raise ValueError("time_abs_array is not strictly increasing")

cs = CubicSpline(time_abs_array, scaled_values.T[j])
df[sensor_col] = cs(df[time_column])
#TODO: isn't sensor_col of type DataColumns?
df[sensor_col] = cs(df[time_column.value])

return df

Expand Down
16 changes: 8 additions & 8 deletions src/paradigma/ppg_preprocessing.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,16 @@ def preprocess_ppg_data(tsdf_meta_ppg: tsdf.TSDFMetadata, tsdf_meta_imu: tsdf.TS

# Transform the time arrays to absolute milliseconds
start_time_ppg = parse_iso8601_to_datetime(metadata_time_ppg.start_iso8601).timestamp()
df_imu[DataColumns.TIME] = paradigma.imu_preprocessing.transform_time_array(
time_array=df_imu[DataColumns.TIME],
df_imu[DataColumns.TIME.value] = paradigma.imu_preprocessing.transform_time_array(
time_array=df_imu[DataColumns.TIME.value],
scale_factor=1000,
input_unit_type = paradigma.constants.TimeUnit.difference_ms,
output_unit_type = paradigma.constants.TimeUnit.absolute_ms,
start_time = start_time_ppg)

start_time_imu = parse_iso8601_to_datetime(metadata_time_imu.start_iso8601).timestamp()
df_ppg[DataColumns.TIME] = paradigma.imu_preprocessing.transform_time_array(
time_array=df_ppg[DataColumns.TIME],
df_ppg[DataColumns.TIME.value] = paradigma.imu_preprocessing.transform_time_array(
time_array=df_ppg[DataColumns.TIME.value],
scale_factor=1000,
input_unit_type = paradigma.constants.TimeUnit.difference_ms,
output_unit_type = paradigma.constants.TimeUnit.absolute_ms,
Expand Down Expand Up @@ -122,16 +122,16 @@ def preprocess_ppg_data(tsdf_meta_ppg: tsdf.TSDFMetadata, tsdf_meta_imu: tsdf.TS
df_ppg_proc = df_ppg_proc.drop(columns=[col])
df_ppg_proc = df_ppg_proc.rename(columns={f'filt_{col}': col})

df_imu_proc[DataColumns.TIME] = paradigma.imu_preprocessing.transform_time_array(
time_array=df_imu_proc[DataColumns.TIME],
df_imu_proc[DataColumns.TIME.value] = paradigma.imu_preprocessing.transform_time_array(
time_array=df_imu_proc[DataColumns.TIME.value],
scale_factor=1,
input_unit_type=paradigma.constants.TimeUnit.absolute_ms,
output_unit_type=paradigma.constants.TimeUnit.relative_ms,
start_time=start_time_ppg,
)

df_ppg_proc[DataColumns.TIME] = paradigma.imu_preprocessing.transform_time_array(
time_array=df_ppg_proc[DataColumns.TIME],
df_ppg_proc[DataColumns.TIME.value] = paradigma.imu_preprocessing.transform_time_array(
time_array=df_ppg_proc[DataColumns.TIME.value],
scale_factor=1,
input_unit_type=paradigma.constants.TimeUnit.absolute_ms,
output_unit_type=paradigma.constants.TimeUnit.relative_ms,
Expand Down
14 changes: 7 additions & 7 deletions src/paradigma/preprocessing_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,14 @@ def __init__(self) -> None:
self.rotation_units = 'deg/s'

self.d_channels_accelerometer = {
DataColumns.ACCELEROMETER_X: self.acceleration_units,
DataColumns.ACCELEROMETER_Y: self.acceleration_units,
DataColumns.ACCELEROMETER_Z: self.acceleration_units,
DataColumns.ACCELEROMETER_X.value: self.acceleration_units,
DataColumns.ACCELEROMETER_Y.value: self.acceleration_units,
DataColumns.ACCELEROMETER_Z.value: self.acceleration_units,
}
self.d_channels_gyroscope = {
DataColumns.GYROSCOPE_X: self.rotation_units,
DataColumns.GYROSCOPE_Y: self.rotation_units,
DataColumns.GYROSCOPE_Z: self.rotation_units,
DataColumns.GYROSCOPE_X.value: self.rotation_units,
DataColumns.GYROSCOPE_Y.value: self.rotation_units,
DataColumns.GYROSCOPE_Z.value: self.rotation_units,
}
self.d_channels_imu = {**self.d_channels_accelerometer, **self.d_channels_gyroscope}

Expand All @@ -58,7 +58,7 @@ def __init__(self) -> None:
self.time_filename = 'PPG_time.bin'

self.d_channels_ppg = {
DataColumns.PPG: 'none'
DataColumns.PPG.value: 'none'
}

self.sampling_frequency = 30

0 comments on commit 3d76b18

Please sign in to comment.