Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tutorial ppg #106

Merged
merged 72 commits into from
Jan 14, 2025
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
0cb88b0
Start heart rate estimation including tfd
KarsVeldkamp Dec 3, 2024
d1b0bca
Merge branch 'main' of https://github.com/biomarkersParkinson/paradig…
KarsVeldkamp Dec 3, 2024
0c639e1
stash updates
KarsVeldkamp Dec 3, 2024
4d0b4ab
Merge branch 'main' of https://github.com/biomarkersParkinson/paradig…
KarsVeldkamp Dec 4, 2024
9b17130
update based on merge conflicts
KarsVeldkamp Dec 4, 2024
6184107
update hr main function
KarsVeldkamp Dec 6, 2024
747a427
Merge branch 'main' of https://github.com/biomarkersParkinson/paradig…
KarsVeldkamp Dec 6, 2024
ab3e4bf
update minor stuff matlab files
KarsVeldkamp Dec 6, 2024
44190aa
change tfd parameters to dict
KarsVeldkamp Dec 6, 2024
e3c8703
First steps to refactoring to numpy
Erikpostt Dec 11, 2024
53e9665
Merge branch 'main' of https://github.com/biomarkersParkinson/paradig…
KarsVeldkamp Dec 11, 2024
bd0f46f
Finalizing heart rate pipeline plus renaming preprocessing to acc ins…
KarsVeldkamp Dec 11, 2024
3aad804
setting execution count to null
KarsVeldkamp Dec 11, 2024
937ea0e
fix output types
KarsVeldkamp Dec 11, 2024
9938768
fixing pytype due to old configs
KarsVeldkamp Dec 11, 2024
8ede2ae
fix min_hr_samples pytype error
KarsVeldkamp Dec 12, 2024
3037503
remove irrelevant config
KarsVeldkamp Dec 30, 2024
122f955
resolved comments PR reviewer
KarsVeldkamp Dec 30, 2024
e59b811
Merge branch 'main' of https://github.com/biomarkersParkinson/paradig…
KarsVeldkamp Dec 30, 2024
c720677
remove data type since it causes pytype error
KarsVeldkamp Dec 30, 2024
5a0ec6b
clear execution count
KarsVeldkamp Dec 30, 2024
dfa313d
Merge branch 'pandas-to-numpy-ppg' of https://github.com/biomarkersPa…
KarsVeldkamp Dec 30, 2024
8d76ba0
import heart_rate_estimation
KarsVeldkamp Dec 31, 2024
e3b526b
Merge branch 'main' of https://github.com/biomarkersParkinson/paradig…
KarsVeldkamp Dec 31, 2024
2bff61c
merge updates
KarsVeldkamp Dec 31, 2024
6a1298f
Merge branch 'create-prepared-data' of https://github.com/biomarkersP…
KarsVeldkamp Jan 2, 2025
e571514
update ppg_analysis
KarsVeldkamp Jan 2, 2025
b907cf6
Merge branch 'main' of https://github.com/biomarkersParkinson/paradig…
KarsVeldkamp Jan 2, 2025
07072a9
replace df to numpy arrays
KarsVeldkamp Jan 4, 2025
0a1858a
fix notebook
KarsVeldkamp Jan 4, 2025
c3d78cf
adding accelerometer feature
KarsVeldkamp Jan 6, 2025
4d660df
fix type error list vs float
KarsVeldkamp Jan 6, 2025
b32e2cb
implement accelerometer feature
KarsVeldkamp Jan 6, 2025
5a3a63a
update matlab file based on refactoring
KarsVeldkamp Jan 7, 2025
0733465
fixing types, docstrings and readibility
KarsVeldkamp Jan 7, 2025
517069a
Merge branch 'pandas-to-numpy-ppg' of https://github.com/biomarkersPa…
KarsVeldkamp Jan 7, 2025
be35838
adding documentation acc feature
KarsVeldkamp Jan 7, 2025
d8676c1
add documentation of autocorrelation
KarsVeldkamp Jan 7, 2025
8136edc
Merge branch 'pandas-to-numpy-ppg' of https://github.com/biomarkersPa…
KarsVeldkamp Jan 7, 2025
f0b8b11
adjust classification and HR estimation based on accelerometer
KarsVeldkamp Jan 7, 2025
26fa21e
Made requested changes
KarsVeldkamp Jan 8, 2025
5bcf723
fix config
KarsVeldkamp Jan 8, 2025
dfeb348
Merge branch 'main' of https://github.com/biomarkersParkinson/paradig…
KarsVeldkamp Jan 8, 2025
6ef509a
adding aggregation heart rate
KarsVeldkamp Jan 9, 2025
f05769d
Merge branch 'main' of https://github.com/biomarkersParkinson/paradig…
KarsVeldkamp Jan 9, 2025
c8ce22f
Merge branch 'main' of https://github.com/biomarkersParkinson/paradig…
KarsVeldkamp Jan 10, 2025
324a721
update aggregates
KarsVeldkamp Jan 10, 2025
de8be11
remove config
KarsVeldkamp Jan 10, 2025
0b717fb
Merge branch 'main' of https://github.com/biomarkersParkinson/paradig…
KarsVeldkamp Jan 10, 2025
8250869
Merge branch 'heart-rate-aggregation' of https://github.com/biomarker…
KarsVeldkamp Jan 10, 2025
4e9b41c
add start tutorial
KarsVeldkamp Jan 10, 2025
9c62e31
aggregation implementation with dictionary
KarsVeldkamp Jan 10, 2025
e10afd9
Merge branch 'main' of https://github.com/biomarkersParkinson/paradig…
KarsVeldkamp Jan 10, 2025
6848312
add lines for consistency
KarsVeldkamp Jan 10, 2025
25de2c6
moved windoweddataextractor to segmenting
KarsVeldkamp Jan 10, 2025
001facd
Merge branch 'heart-rate-aggregation' of https://github.com/biomarker…
KarsVeldkamp Jan 10, 2025
af9306e
Merge branch 'main' of https://github.com/biomarkersParkinson/paradig…
KarsVeldkamp Jan 10, 2025
e4cd003
resolve merge conflict
KarsVeldkamp Jan 10, 2025
35c107b
update loading + preprocessing with seperate functionality
KarsVeldkamp Jan 12, 2025
d630160
update tutorial notebook and corresponding notebook
KarsVeldkamp Jan 13, 2025
345aac0
Merge branch 'main' of https://github.com/biomarkersParkinson/paradig…
KarsVeldkamp Jan 13, 2025
3175d06
Update test to io function
KarsVeldkamp Jan 13, 2025
9967cc3
Merge branch 'main' of https://github.com/biomarkersParkinson/paradig…
KarsVeldkamp Jan 13, 2025
2f860ef
update tutorial and notebook with simplified loading of the data
KarsVeldkamp Jan 13, 2025
6f2efa2
Reset execution counts in notebook cells
Erikpostt Jan 13, 2025
1eb821e
update execution_counts and output
KarsVeldkamp Jan 13, 2025
40e768a
Updates from PR feedback
KarsVeldkamp Jan 13, 2025
9f1442e
Merge branch 'main' of https://github.com/biomarkersParkinson/paradig…
KarsVeldkamp Jan 13, 2025
854d5fc
Merge branch 'main' into tutorial-ppg
KarsVeldkamp Jan 13, 2025
81c6580
Merge branch 'tutorial-ppg' of https://github.com/biomarkersParkinson…
KarsVeldkamp Jan 13, 2025
440160c
fix type error
KarsVeldkamp Jan 13, 2025
529744e
made final feedback
KarsVeldkamp Jan 14, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions docs/notebooks/ppg/ppg_analysis.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
"metadata": {},
"outputs": [],
"source": [
"import importlib.resources\n",
"import pickle\n",
"from pathlib import Path\n",
"\n",
"from paradigma.config import PPGConfig, IMUConfig, SignalQualityFeatureExtractionConfig, SignalQualityFeatureExtractionAccConfig, SignalQualityClassificationConfig, HeartRateExtractionConfig\n",
Expand Down Expand Up @@ -67,8 +69,8 @@
"metadata": {},
"outputs": [],
"source": [
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you don't use, e.g., metadata_time, you can call the function as df_ppg, _, _ = ... such that there are no objects assigned that hold memory.

"df_ppg, metadata_time, metadata_values = load_tsdf_dataframe(path_to_prepared_data / ppg_prefix, prefix = ppg_prefix)\n",
"df_imu, metadata_time, metadata_values = load_tsdf_dataframe(path_to_prepared_data / imu_prefix, prefix = imu_prefix)"
"df_ppg, _, _ = load_tsdf_dataframe(path_to_prepared_data / ppg_prefix, prefix = ppg_prefix)\n",
"df_imu, _, _ = load_tsdf_dataframe(path_to_prepared_data / imu_prefix, prefix = imu_prefix)"
]
},
{
Expand Down Expand Up @@ -121,8 +123,11 @@
"metadata": {},
"outputs": [],
"source": [
"full_path_to_classifier_package = path_to_assets / ppg_classifier_package_filename\n",
"with importlib.resources.files('paradigma.assets').joinpath(ppg_classifier_package_filename).open('rb') as f:\n",
" clf_package = pickle.load(f)\n",
"config = SignalQualityClassificationConfig()\n",
"df_sqa = signal_quality_classification(df_features, config, path_to_classifier)"
"df_sqa = signal_quality_classification(df_features, config, clf_package)"
]
},
{
Expand Down
69 changes: 46 additions & 23 deletions docs/tutorials/heart_rate_analysis.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,21 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"This tutorial shows how to extract heart rate estimates using photoplethysmography (PPG) data and accelerometer data. The pipeline consists of a stepwise approach ot determine signal quality, assessing both PPG morphology and accounting for periodic artifacts using the accelerometer. Based on the signal quality, we extract high-quality segments and estimate the heart rate for every 2 s using the smoothed pseudo Wigner-Ville Distribution. "
"This tutorial shows how to extract heart rate estimates using photoplethysmography (PPG) data and accelerometer data. The pipeline consists of a stepwise approach to determine signal quality, assessing both PPG morphology and accounting for periodic artifacts using the accelerometer. Based on the signal quality, we extract high-quality segments and estimate the heart rate for every 2 s using the smoothed pseudo Wigner-Ville Distribution. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Load example data"
"## Load data"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Example PPG + accelerometer (from IMU files) data from a participant of the Personalized Parkinson Project is loaded. The data was prepared as explained in `data_preparation.ipynb`. The prepared IMU data contains both accelerometer and gyroscope data, but only accelerometer is used in this pipeline alongside the PPG data. We load the corresponding dataframes using the `load_tsdf_dataframe function`."
"This pipeline requires accelerometer and PPG data to run. In this example we loaded data from a participant of the Personalized Parkinson Project. We load the corresponding dataframes using the `load_tsdf_dataframe function`. The channel `green` represents the values obtained with PPG using green light."
]
},
{
Expand Down Expand Up @@ -329,8 +329,8 @@
"ppg_prefix = 'PPG'\n",
"imu_prefix = 'IMU'\n",
"\n",
"df_ppg, metadata_time, metadata_values = load_tsdf_dataframe(path_to_prepared_data / ppg_prefix, prefix = ppg_prefix)\n",
"df_imu, metadata_time, metadata_values = load_tsdf_dataframe(path_to_prepared_data / imu_prefix, prefix = imu_prefix)\n",
"df_ppg, _, _ = load_tsdf_dataframe(path_to_prepared_data / ppg_prefix, prefix = ppg_prefix)\n",
"df_imu, _, _ = load_tsdf_dataframe(path_to_prepared_data / imu_prefix, prefix = imu_prefix)\n",
"\n",
"display(df_ppg, df_imu)"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do users know what "green" means?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, I have added a brief sentence to the documentation

]
Expand All @@ -346,7 +346,9 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"The first step after loading the data is to preprocess the data. Preprocessing starts by extracting the data where there is both PPG and IMU data. In this way, we discard the the first or last part of the segment when e.g. the PPG segment is recorded longer than the accelerometer. After this step, the preprocess_ppg_data function resamples the values of both PPG and accelerometer data using uniformly distributed timestamps, since the sampling rate of both sensors is fixed but not uniform. After this, a bandpass filter (butterworth, 4th-order, cut-off frequencies: [0.4, 3.5]) is applied to the PPG signal and a high-pass (butterworth, 4th-order, cut-off: 0.2 Hz) filter is applied to the accelerometer. "
"The first step after loading the data is preprocessing. This begins by isolating segments containing both PPG and IMU data, discarding portions where one modality (e.g., PPG) extends beyond the other, such as when the PPG recording is longer than the accelerometer data. After this step, the preprocess_ppg_data function resamples the PPG and accelerometer data to uniformly distributed timestamps, addressing the fixed but non-uniform sampling rates of the sensors. After this, a bandpass Butterworth filter (4th-order, bandpass frequencies: 0.4--3.5 Hz) is applied to the PPG signal, while a high-pass Butterworth filter (4th-order, cut-off frequency: 0.2 Hz) is applied to the accelerometer data.\n",
"\n",
"Note: the printed shapes are the data points (rows) and the data columns (rows x columns). The number of rows of the overlapping segments of PPG and accelerometer are not exactly the same due to sampling differences (other sensors and possibly other sampling frequencies). "
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you meant to say (rows, columns), with each row corresponding to a single data points? Now it looks like rows are data points, and rows x columns are data columns.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I made slight adjustments in this sentence

]
},
{
Expand All @@ -358,8 +360,12 @@
"name": "stdout",
"output_type": "stream",
"text": [
"Shape of the original data: (64775, 2) (72947, 4)\n",
"Shape of the overlapping segments: (64775, 2) (64361, 4)\n"
"Original data shapes:\n",
"- PPG data: (64775, 2)\n",
"- Accelerometer data: (72947, 4)\n",
"Overlapping data shapes:\n",
"- PPG data: (64775, 2)\n",
"- Accelerometer data: (64361, 4)\n"
]
},
{
Expand Down Expand Up @@ -678,6 +684,14 @@
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"The default window length for the signal quality feature extraction is set to 6 seconds.\n",
"The default step size for the signal quality feature extraction is set to 1 seconds.\n"
]
},
{
"data": {
"text/html": [
Expand Down Expand Up @@ -927,17 +941,18 @@
"[639 rows x 12 columns]"
]
},
"execution_count": 27,
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from paradigma.config import SignalQualityFeatureExtractionConfig, SignalQualityFeatureExtractionAccConfig\n",
"from paradigma.heart_rate.heart_rate_analysis import extract_signal_quality_features\n",
"\n",
"ppg_config = SignalQualityFeatureExtractionConfig()\n",
"acc_config = SignalQualityFeatureExtractionAccConfig()\n",
"print(\"The default window length for the signal quality feature extraction is set to\", ppg_config.window_length_s, \"seconds.\")\n",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This cell is a bit cluttered. Try to add some whitespaces

  • imports
  • configs
  • prints
  • function
  • print

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This also applies to some other cells.

"print(\"The default step size for the signal quality feature extraction is set to\", ppg_config.window_step_length_s, \"seconds.\")\n",
"df_features = extract_signal_quality_features(ppg_config, df_ppg_proc, acc_config, df_acc_proc)\n",
"df_features\n"
]
Expand All @@ -953,7 +968,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"A trained logistic classifier is used to classify PPG signal quality and returns the `pred_sqa_proba`, which is the posterior probability of a PPG window to look like the typical PPG morphology (higher probability indicates toward the typical PPG morphology). The relative power feature from the accelerometer is compared to a threshold for periodic artifacts and therefore `pred_sqa_acc_label` returns a label indicating probably periodic motion artifacts (label 0) or no periodic motion artifacts (label 1). "
"A trained logistic classifier is used to predicts PPG signal quality and returns the `pred_sqa_proba`, which is the posterior probability of a PPG window to look like the typical PPG morphology (higher probability indicates toward the typical PPG morphology). The relative power feature from the accelerometer is compared to a threshold for periodic artifacts and therefore `pred_sqa_acc_label` returns a label indicating predicted periodic motion artifacts (label 0) or no periodic motion artifacts (label 1). "
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

predicts = predict
returns = return (as in, "is used to return", but could also be "returns" as in "and it returns")

]
},
{
Expand Down Expand Up @@ -1064,7 +1079,7 @@
"[639 rows x 2 columns]"
]
},
"execution_count": 28,
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
Expand All @@ -1090,14 +1105,21 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"For heart rate estimation, we extract segments of `config.tfd_length`. Using a 2-step approach, we calculate the smoothed-pseudo Wigner-Ville Distribution to obtain the frequency content of the PPG signal over time. For every 2-second window, we identified the frequency with the highest power for each data point and assigned the average of these frequency as the heart rate in that 2-second window. "
"For heart rate estimation, we extract segments of `config.tfd_length`. We calculate the smoothed-pseudo Wigner-Ville Distribution (SPWVD) to obtain the frequency content of the PPG signal over time. We extract for every timestamp in the SPWVD for the frequency with the highest power. For every non-overlapping 2-second window we average the corresponding frequencies to obtain a heart rate per window. "
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"... SPWVD for the ..." should be "... SPWVD the ..."

]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"The default minimal window length for the heart rate extraction is set to 10 seconds.\n"
]
},
{
"data": {
"text/html": [
Expand All @@ -1119,7 +1141,7 @@
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>rel_time</th>\n",
" <th>time</th>\n",
" <th>heart_rate</th>\n",
" </tr>\n",
" </thead>\n",
Expand Down Expand Up @@ -1159,16 +1181,16 @@
"</div>"
],
"text/plain": [
" rel_time heart_rate\n",
"0 56.0 86.404715\n",
"1 58.0 86.640472\n",
"2 60.0 86.345776\n",
"3 62.0 84.872299\n",
"4 64.0 84.872299\n",
"5 66.0 84.194499"
" time heart_rate\n",
"0 56.0 86.404715\n",
"1 58.0 86.640472\n",
"2 60.0 86.345776\n",
"3 62.0 84.872299\n",
"4 64.0 84.872299\n",
"5 66.0 84.194499"
]
},
"execution_count": 29,
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
Expand All @@ -1178,6 +1200,7 @@
"from paradigma.heart_rate.heart_rate_analysis import estimate_heart_rate\n",
"\n",
"config = HeartRateExtractionConfig()\n",
"print(\"The default minimal window length for the heart rate extraction is set to\", config.tfd_length, \"seconds.\")\n",
"df_hr = estimate_heart_rate(df_sqa, df_ppg_proc, config)\n",
"df_hr"
]
Expand All @@ -1193,7 +1216,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"The final step is to aggregate all 2-second heart rate estimates. In the current example, the mode and 99th percentile are calculated. The mode represent the resting heart rate while the 99th percentile indicates the maximum heart rate. In Parkinson's disease, we expect that these two measures could reflect autonomic (dys)functioning."
"The final step is to aggregate all 2-second heart rate estimates. In the current example, the mode and 99th percentile are calculated. We hypothesize that the mode gives representation of the resting heart rate while the 99th percentile indicates the maximum heart rate. In Parkinson's disease, we expect that these two measures could reflect autonomic (dys)functioning. The `nr_hr_est` in the metadata indicates on how many 2-second windows these aggregates are determined."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure, but should "... indicates on how many ..." be "... indicates based on how many ..."?

Also try to be consistent in using "2-second" or "2 s". I think I saw "2 s" somewhere.

]
},
{
Expand Down
2 changes: 1 addition & 1 deletion src/paradigma/heart_rate/heart_rate_analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ def estimate_heart_rate(df_sqa: pd.DataFrame, df_ppg_preprocessed: pd.DataFrame,
t_hr_rel[hr_pos:hr_pos + n_hr] = hr_time
hr_pos += n_hr

df_hr = pd.DataFrame({"rel_time": t_hr_rel, "heart_rate": v_hr_rel})
df_hr = pd.DataFrame({"time": t_hr_rel, "heart_rate": v_hr_rel})

return df_hr

Expand Down
12 changes: 5 additions & 7 deletions src/paradigma/preprocessing.py
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If people collect both accelerometer and PPG data, longitudinally, this function actually might make sense to have as a utility in the toolbox. I would move it to util.py therefore. I would leave all "necessary" functionalities in preprocessing.py.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do think this functionality is tsdf-specific, so we should think about how a user using csv or other formats could do this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure where you exactly referring to but I assume this is to scan_and_sync_segments? This is on my list to remove it from preprocessing and set it to util or another place and it is tsdf-specific indeed

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then also the extract_meta_from_tsdf_files will be removed in the preprocessing.py

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes apologies, it's about scan_and_sync_segments. Check.

Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ def preprocess_imu_data_io(path_to_input: str | Path, path_to_output: str | Path
write_df_data(metadata_time, metadata_values, path_to_output, f'{sensor}_meta.json', df_sensor)


def scan_and_sync_segments(input_path_ppg, input_path_imu):
def scan_and_sync_segments(input_path_ppg: str | Path, input_path_imu: str | Path) -> Tuple[List[tsdf.TSDFMetadata], List[tsdf.TSDFMetadata]]:
"""
Scan for available TSDF metadata files in the specified directories and synchronize the data segments based on the metadata start and end times.

Expand Down Expand Up @@ -309,9 +309,9 @@ def preprocess_ppg_data(df_ppg: pd.DataFrame, df_imu: pd.DataFrame, ppg_config:
df_acc = df_imu.drop(cols_to_drop, axis=1)

# Extract overlapping segments
print("Shape of the original data:", df_ppg.shape, df_acc.shape)
print(f"Original data shapes:\n- PPG data: {df_ppg.shape}\n- Accelerometer data: {df_acc.shape}")
df_ppg_overlapping, df_acc_overlapping = extract_overlapping_segments(df_ppg, df_acc)
print("Shape of the overlapping segments:", df_ppg_overlapping.shape, df_acc_overlapping.shape)
print(f"Overlapping data shapes:\n- PPG data: {df_ppg_overlapping.shape}\n- Accelerometer data: {df_acc_overlapping.shape}")

# Resample accelerometer data
df_acc_proc = resample_data(
Expand Down Expand Up @@ -372,12 +372,10 @@ def preprocess_ppg_data_io(tsdf_meta_ppg: tsdf.TSDFMetadata, tsdf_meta_imu: tsdf
Metadata for the IMU data.
output_path : Union[str, Path]
Path to store the preprocessed data.
ppg_config : PPGPreprocessingConfig
ppg_config : PPGConfig
Configuration object for PPG preprocessing.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMUConfig

imu_config : IMUPreprocessingConfig
imu_config : IMUConfig
Configuration object for IMU preprocessing.
sensor: str
Name of the sensor data to be preprocessed.

Returns
-------
Expand Down
Loading