Source code for paat.sleep

"""
Sleep Module
------------

*paat.sleep* provides functions to detect periods of sleep in the raw
acceleration signals.

"""
import os

os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'

import pandas as pd
import numpy as np
import tensorflow as tf
import keras


[docs] def detect_time_in_bed_weitz2024(data, sample_freq, resampled_frequency="1min", means=None, stds=None, model=None): """ Infer time in bed from raw acceleration signal using the method of Weitz et al. (2025). References ---------- Weitz, M., Syed, S., Hopstock, L. A., Morseth, B., Henriksen, A., & Horsch, A. (2025). Automatic time in bed detection from hip-worn accelerometers for large epidemiological studies: The Tromsø Study. *PLOS ONE*, 20(5), e0321558. https://doi.org/10.1371/journal.pone.0321558 Parameters ---------- data : DataFrame a DataFrame containg the raw acceleration data sample_freq : int the sampling frequency in which the data was recorded resampled_frequency : str (optional) a str indicating to what frequency the data should be resampled. This depends on the model used to predict, defaults to 1min. means : array_like (optional) a numpy array with the channel means, will be calculated for the sample if not specified stds : array_like (optional) a numpy array with the channel stds, will be calculated for the sample if not specified model : keras.Model (optional) a loaded keras custom model. Returns ------- predicted_time_in_bed : np.array (n_samples,) a numpy array indicating whether the values of the acceleration data were spent in bed """ n_data = len(data) if resampled_frequency: data = data[['X', 'Y', 'Z']].resample(resampled_frequency).mean() # Order data as YXZ as this is how the model was trained X = data.reset_index()[["Y", "X", "Z"]].values.copy() # If no means and stds are given, calculate subject's mean and std # to normalize by this if not means or not stds: means, stds = X.mean(axis=0), X.std(axis=0) # Normalize input X = (X - means) / stds # Load model if not specified if not model: model_path = os.path.join(os.path.pardir, os.path.dirname(__file__), 'models', 'TIB_model.pb') model= keras.layers.TFSMLayer(model_path, call_endpoint='serving_default') predictions = (model(X[np.newaxis])["output_0"].numpy().squeeze() >= .5) seconds = pd.Timedelta(resampled_frequency).seconds # Slices the predictions to the length of the provided data # This can be relecant if the provided data has incomplete minutes at the start or the end predictions = np.repeat(predictions, seconds * sample_freq)[:n_data] return predictions