A Python package for wrist-worn accelerometer data processing.
Welcome to wristpy, a Python library designed for processing and analyzing wrist-worn accelerometer data. This library provides a set of tools for loading sensor information, calibrating raw accelerometer data, calculating physical activity metrics (ENMO derived) and sleep metrics (angle-Z derived), finding non-wear periods, and detecting sleep periods (onset and wakeup times). Additionally, we provide access to other sensor data that may be recorded by the watch, including; temperature, luminosity, capacitive sensing, battery voltage, and all metadata.
The package currently supports the following formats:
| Format | Manufacturer | Device | Implementation status |
|---|---|---|---|
| GT3X | Actigraph | wGT3X-BT | ✅ |
| BIN | GENEActiv | GENEActiv | ✅ |
Special Note
The idle_sleep_mode for Actigraph watches will lead to uneven sampling rates during periods of no motion (read about this here). Consequently, this causes issues when implementing wristpy's non-wear and sleep detection. As of this moment, we fill in the missing acceleration data with the assumption that the watch is perfectly idle in the face-up position (Acceleration vector = [0, 0, -1]). The data is filled in at the same sampling rate as the raw acceleration data. In the special circumstance when acceleration samples are not evenly spaced, the data is resampled to the highest effective sampling rate to ensure linearly sampled data.
The main processing pipeline of the wristpy module can be described as follows:
- Data loading: sensor data is loaded using
actfast, and aWatchDataobject is created to store all sensor data - Data calibration: A post-manufacturer calibration step can be applied, to ensure that the acceleration sensor is measuring 1g force during periods of no motion. There are three possible options:
None,gradient,ggir. - Data imputation In the special case when dealing with the Actigraph
idle_sleep_mode == enabled, the gaps in acceleration are filled in after calibration, to avoid biasing the calibration phase. - Metrics Calculation: Calculates various metrics on the calibrated data, namely ENMO (Euclidean norm , minus one) and angle-Z (angle of acceleration relative to the x-y axis).
- Non-wear detection: We find periods of non-wear based on the acceleration data. Specifically, the standard deviation of the acceleration values in a given time window, along each axis, is used as a threshold to decide
wearornot wear. - Sleep Detection: Using the HDCZ1 and HSPT2 algorithms to analyze changes in arm angle we are able to find periods of sleep. We find the sleep onset-wakeup times for all sleep windows detected.
- Physical activity levels: Using the enmo data (aggregated into epoch 1 time bins, 5 second default) we compute activity levels into the following categories: inactivity, light activity, moderate activity, vigorous activity. The default threshold values have been chosen based on the values presented in the Hildenbrand 2014 study3.
wristpy depends on
libomp, a system-level dependency that is not always installed by default on macOS. Install it via:brew install libomp
Install the wristpy package from PyPI via:
pip install wristpywristpy provides three flexible interfaces: a command-line tool for direct execution, an importable Python library, and a Docker image for containerized deployment.
wristpy /input/file/path.gt3x -o /save/path/file_name.csv -c gradientwristpy /path/to/files/input_dir -o /path/to/files/output_dir -c gradient -O .csvwristpy --helpfrom wristpy.core import orchestrator
# Define input file path and output location
# Support for saving as .csv and .parquet
input_path = '/path/to/your/file.gt3x'
output_path = '/path/to/save/file_name.csv'
# Run the orchestrator
results = orchestrator.run(
input=input_path,
output=output_path,
calibrator='gradient', # Choose between 'ggir', 'gradient', or 'none'
)
#Data available in results object
physical_activity_metric = results.physical_activity_metric
anglez = results.anglez
physical_activity_levels = results.physical_activity_levels
nonwear_array = results.nonwear_epoch
sleep_windows = results.sleep_windows_epochfrom wristpy.core import orchestrator
# Define input file path and output location
input_path = '/path/to/files/input_dir'
output_path = '/path/to/files/output_dir'
# Run the orchestrator
# Specify the output file type, support for saving as .csv and .parquet
results_dict = orchestrator.run(
input=input_path,
output=output_path,
calibrator='gradient', # Choose between 'ggir', 'gradient', or 'none'
output_filetype = '.csv'
)
#Data available in dictionary of results.
subject1 = results_dict['subject1']
physical_activity_metric = subject1.physical_activity_metric
anglez = subject1.anglez
physical_activity_levels = subject1.physical_activity_levels
nonwear_array = subject1.nonwear_epoch
sleep_windows = subject1.sleep_windows_epoch-
Install Docker: Ensure you have Docker installed on your system. Get Docker
-
Pull the Docker image:
docker pull cmidair/wristpy:main
-
Run the Docker image with your data:
docker run -it --rm \ -v "/local/path/to/data:/data" \ -v "/local/path/to/output:/output" \ cmidair/wristpy:main
Replace
/local/path/to/datawith the path to your input data directory and/local/path/to/outputwith where you want results saved.To run a single file, we simply need to modify the mounting structure for the docker call slightly:
docker run -it --rm \ -v "/local/path/to/data/file.bin:/data/file.bin" \ -v "/local/path/to/output:/output" \ cmidair/wristpy:main
The Docker image supports multiple input variables to customize processing. You can set these by simply chaining these inputs as you would for the CLI input:
docker run -it --rm \
-v "/local/path/to/data/file.bin:/data/file.bin" \
-v "/local/path/to/output:/output" \
cmidair/wristpy:main /data --output /output --epoch-length 5 --nonwear-algorithm ggir --nonwear-algorithm detach --thresholds 0.1 0.2 0.4For more details on available options, see the orchestrator documentation.
- van Hees, V.T., Sabia, S., Jones, S.E. et al. Estimating sleep parameters using an accelerometer without sleep diary. Sci Rep 8, 12975 (2018). https://doi.org/10.1038/s41598-018-31266-z
- van Hees, V. T., et al. A Novel, Open Access Method to Assess Sleep Duration Using a Wrist-Worn Accelerometer. PLoS One 10, e0142533 (2015). https://doi.org/10.1371/journal.pone.0142533
- Hildebrand, M., et al. Age group comparability of raw accelerometer output from wrist- and hip-worn monitors. Medicine and Science in Sports and Exercise, 46(9), 1816-1824 (2014). https://doi.org/10.1249/mss.0000000000000289
