| Title: | Estimate Sleep Stages and Respiratory Events from Accelerometry Data |
|---|---|
| Description: | Wraps the 'AcceleRest' model from Lorenzen et al. (2026) <doi:10.64898/2026.01.28.26345056> <https://github.com/NielsRLorenzen/AcceleRest> to estimate sleep stages and respiratory events from wrist-worn 'accelerometry' data. Provides functions to download the model code and pretrained weights and to run the model using 'reticulate'. |
| Authors: | John Muschelli [aut, cre] (ORCID: <https://orcid.org/0000-0001-6469-1750>) |
| Maintainer: | John Muschelli <[email protected]> |
| License: | GPL (>= 3) |
| Version: | 0.1.0 |
| Built: | 2026-11-13 13:25:46 UTC |
| Source: | https://github.com/jhuwit/rester |
rester Cache DirectoryThe default location for the downloaded AcceleRest code and weights. It
can be set using options(rester.cache_dir = ) or the RESTER_CACHE_DIR
environment variable, and otherwise is
tools::R_user_dir("rester", "cache").
ar_cache_dir()ar_cache_dir()
A character path. The directory is not created.
ar_cache_dir()ar_cache_dir()
Downloads the source archive of
https://github.com/NielsRLorenzen/AcceleRest at a fixed commit and
extracts the files needed to build the models (hubconf.py and the
accelerest Python package). The code is downloaded rather than bundled
as the AcceleRest repository does not declare a license.
ar_download_repo( repo_dir = ar_cache_dir(), ref = .ar_default_ref, overwrite = FALSE, quiet = TRUE, ... ) ar_extract_repo(zip_file, repo_dir = ar_cache_dir()) ar_have_repo(repo_dir = ar_cache_dir())ar_download_repo( repo_dir = ar_cache_dir(), ref = .ar_default_ref, overwrite = FALSE, quiet = TRUE, ... ) ar_extract_repo(zip_file, repo_dir = ar_cache_dir()) ar_have_repo(repo_dir = ar_cache_dir())
repo_dir |
directory to extract the code into. The code is placed
in |
ref |
git commit, tag, or branch of AcceleRest to download |
overwrite |
If |
quiet |
passed to |
... |
additional arguments to pass to |
zip_file |
a source archive of AcceleRest, e.g. downloaded from GitHub |
The path to the extracted repository. ar_have_repo returns
a logical.
## Not run: # downloads the AcceleRest code to ar_cache_dir() path = ar_download_repo() ## End(Not run) ar_have_repo()## Not run: # downloads the AcceleRest code to ar_cache_dir() path = ar_download_repo() ## End(Not run) ar_have_repo()
Reads the example 12 hours of 30Hz wrist accelerometry data included in the
package (the same recording as in the sleeper package), reconstructing
the time stamps (stored rounded to the second) from the sample rate.
ar_example_data(n_hours = NULL)ar_example_data(n_hours = NULL)
n_hours |
number of hours of data to read (up to 12). |
A tibble with columns time, X, Y, and Z, with the
sample_rate attribute set to 30.
data = ar_example_data(n_hours = 0.01) head(data)data = ar_example_data(n_hours = 0.01) head(data)
Builds the multi-head AcceleRest model from downloaded code and weights
(see ar_setup()). All heads share a single encoder backbone.
ar_load_model( model = NULL, repo_dir = ar_cache_dir(), weights_dir = ar_cache_dir(), device = NULL )ar_load_model( model = NULL, repo_dir = ar_cache_dir(), weights_dir = ar_cache_dir(), device = NULL )
model |
the prediction heads to include, one or more of
|
repo_dir |
directory with the downloaded code, see
|
weights_dir |
directory with the downloaded weights, see
|
device |
|
A Python torch module.
# Runs only after ar_setup(), so Python is not set up otherwise if (ar_have_repo() && ar_have_weights("linear_sleepstages") && ar_python_modules_installed()) { model = ar_load_model("linear_sleepstages") }# Runs only after ar_setup(), so Python is not set up otherwise if (ar_have_repo() && ar_have_weights("linear_sleepstages") && ar_python_modules_installed()) { model = ar_load_model("linear_sleepstages") }
Extracts the torch state dictionary (the named parameter tensors) from a
downloaded weights file.
ar_load_weights( model = "linear_sleepstages", weights_dir = ar_cache_dir(), as_r = TRUE )ar_load_weights( model = "linear_sleepstages", weights_dir = ar_cache_dir(), as_r = TRUE )
model |
a single model name, see |
weights_dir |
directory where the weights are (to be) stored.
If |
as_r |
If |
A named list of arrays or a Python object.
# Runs only after ar_setup(), so Python is not set up otherwise if (ar_have_weights("linear_sleepstages") && ar_python_modules_installed()) { sd = ar_load_weights("linear_sleepstages") names(sd)[1:5] }# Runs only after ar_setup(), so Python is not set up otherwise if (ar_have_weights("linear_sleepstages") && ar_python_modules_installed()) { sd = ar_load_weights("linear_sleepstages") names(sd)[1:5] }
rester
Check for the Python Modules Used by rester
ar_python_modules_installed()ar_python_modules_installed()
A logical value indicating whether all Python modules needed
by rester can be found.
# Checking starts Python, which installs the Python packages, so this # runs only after ar_setup() if (ar_have_repo() && ar_have_weights()) { ar_python_modules_installed() }# Checking starts Python, which installs the Python packages, so this # runs only after ar_setup() if (ar_have_repo() && ar_have_weights()) { ar_python_modules_installed() }
AcceleRest expects 30Hz, gravity-calibrated data without gaps. Device
files (.cwa, .gt3x, .bin, optionally compressed) are read with
actiread::acti_read(), and CSV files with readr::read_csv(). Gaps
(all-zero rows from ActiGraph idle sleep mode, and missing values) are
filled with the last observation carried forward using
actibase::acti_fill_zeros(), as ActiLife does. The data are then
low-pass filtered, calibrated, and resampled to 30Hz with the actipy
Python module, using the same settings as the AcceleRest command-line
tool. .h5 files must already be preprocessed, with an
axes x samples array in data/accelerometry.
ar_read( file, sample_rate = NULL, fill_zeros = TRUE, lowpass_hz = 15, calibrate_gravity = TRUE, detect_nonwear = FALSE, verbose = FALSE, ... )ar_read( file, sample_rate = NULL, fill_zeros = TRUE, lowpass_hz = 15, calibrate_gravity = TRUE, detect_nonwear = FALSE, verbose = FALSE, ... )
file |
a |
sample_rate |
sample rate (Hz) of the data. If |
fill_zeros |
If |
lowpass_hz, calibrate_gravity, detect_nonwear
|
preprocessing options
passed to |
verbose |
print diagnostic messages |
... |
additional arguments passed to |
A list with the Python (numpy) array of 3 x samples data
(accelerometry), the time of the first sample (start_time, NULL
for .h5 files), and actipy information about the data (info).
# Runs only after ar_setup(), so Python is not set up otherwise if (ar_have_repo() && ar_have_weights() && ar_python_modules_installed()) { data = ar_example_data(n_hours = 0.1) out = ar_read(data) out$start_time }# Runs only after ar_setup(), so Python is not set up otherwise if (ar_have_repo() && ar_have_weights() && ar_python_modules_installed()) { data = ar_example_data(n_hours = 0.1) out = ar_read(data) out$start_time }
Runs ar_download_repo() and ar_download_weights().
ar_setup( model = NULL, cache_dir = ar_cache_dir(), overwrite = FALSE, quiet = TRUE, ... )ar_setup( model = NULL, cache_dir = ar_cache_dir(), overwrite = FALSE, quiet = TRUE, ... )
model |
the models to download, see |
cache_dir |
directory to store the code and weights in |
overwrite |
If |
quiet |
passed to |
... |
additional arguments to pass to |
A list with the repository path and the weights data.frame.
## Not run: # downloads the AcceleRest code and ~100MB of weights to ar_cache_dir() ar_setup() ## End(Not run)## Not run: # downloads the AcceleRest code and ~100MB of weights to ar_cache_dir() ar_setup() ## End(Not run)
The pretrained weights released at
https://github.com/NielsRLorenzen/AcceleRest/releases.
The heads "linear_sleepstages", "lstm_sleepstages", and
"linear_respevents" are used for prediction; the autoencoder weights are
the pretrained (not fine-tuned) backbones.
ar_weights(weights_dir = NULL, release = .ar_default_release) ar_have_weights( model = NULL, weights_dir = ar_cache_dir(), quiet = TRUE, release = .ar_default_release ) ar_download_weights( model = NULL, weights_dir = ar_cache_dir(), overwrite = FALSE, quiet = TRUE, release = .ar_default_release, ... )ar_weights(weights_dir = NULL, release = .ar_default_release) ar_have_weights( model = NULL, weights_dir = ar_cache_dir(), quiet = TRUE, release = .ar_default_release ) ar_download_weights( model = NULL, weights_dir = ar_cache_dir(), overwrite = FALSE, quiet = TRUE, release = .ar_default_release, ... )
weights_dir |
directory where the weights are (to be) stored.
If |
release |
the GitHub release tag of the weights |
model |
the models to check or download. Defaults to the three prediction heads. |
quiet |
If |
overwrite |
If |
... |
additional arguments to pass to |
A data.frame with the model name, file, URL, expected size
in bytes, and the class labels (for prediction heads).
ar_weights() ar_have_weights() ## Not run: # downloads ~35MB per model to ar_cache_dir() files = ar_download_weights("linear_sleepstages") ## End(Not run)ar_weights() ar_have_weights() ## Not run: # downloads ~35MB per model to ar_cache_dir() files = ar_download_weights("linear_sleepstages") ## End(Not run)
Runs the AcceleRest model on 30-second epochs of wrist-worn accelerometry. Predictions are made over context windows of 256 epochs (about 2.1 hours), so at least that much data is needed; predictions for an epoch are averaged across the overlapping windows covering it.
estimate_rest( file, model = NULL, cache_dir = ar_cache_dir(), repo_dir = cache_dir, weights_dir = cache_dir, context_window_shift = 1L, max_batch_size = 16L, device = NULL, ... )estimate_rest( file, model = NULL, cache_dir = ar_cache_dir(), repo_dir = cache_dir, weights_dir = cache_dir, context_window_shift = 1L, max_batch_size = 16L, device = NULL, ... )
file |
a |
model |
the prediction heads to include, one or more of
|
cache_dir |
directory with the downloaded code and weights, see
|
repo_dir |
directory with the downloaded code, see
|
weights_dir |
directory with the downloaded weights, see
|
context_window_shift |
number of 30-second epochs to shift consecutive context windows. Smaller is slower but averages over more windows. |
max_batch_size |
number of context windows per forward pass. Higher is faster but uses more memory. |
device |
|
... |
additional arguments passed to |
A named list with a tibble for each head, with the epoch
number, start time of the epoch (NA for .h5 files), the
probability of each class, and the most probable class (prediction).
Epochs with no valid data have NA values. Sleep stage classes are
deep, light, rem, and wake; respiratory event classes are no_event and
event. The actipy information about the data is in attr(x, "info").
Lorenzen NR, Brink-Kjaer A, Jennum PJ, Mignot E (2026). AcceleRest: A Physiology-Aware Masked Autoencoder for Wrist Accelerometer-based Sleep Staging and Apnea Evaluation. medRxiv. doi:10.64898/2026.01.28.26345056
# Runs only after ar_setup(), so Python is not set up otherwise if (ar_have_repo() && ar_have_weights("linear_sleepstages") && ar_python_modules_installed()) { data = ar_example_data(n_hours = 2.5) out = estimate_rest(data, model = "linear_sleepstages", context_window_shift = 32L) head(out$linear_sleepstages) }# Runs only after ar_setup(), so Python is not set up otherwise if (ar_have_repo() && ar_have_weights("linear_sleepstages") && ar_python_modules_installed()) { data = ar_example_data(n_hours = 2.5) out = estimate_rest(data, model = "linear_sleepstages", context_window_shift = 32L) head(out$linear_sleepstages) }
estimate_rest with Python in a Separate ProcessRun estimate_rest with Python in a Separate Process
py_estimate_rest( ..., pyenv_function = function() { rester::py_require_rester() }, show = FALSE )py_estimate_rest( ..., pyenv_function = function() { rester::py_require_rester() }, show = FALSE )
... |
arguments to pass to |
pyenv_function |
function that sets up Python in the child process.
By default, it uses |
show |
Logical, whether to show the standard output on the
screen while the child process is running, passed to |
Output from estimate_rest().
# Runs only after ar_setup(), so Python is not set up otherwise if (requireNamespace("callr", quietly = TRUE) && ar_have_repo() && ar_have_weights("linear_sleepstages")) { data = ar_example_data(n_hours = 2.5) out = py_estimate_rest(data, model = "linear_sleepstages", context_window_shift = 32L) }# Runs only after ar_setup(), so Python is not set up otherwise if (requireNamespace("callr", quietly = TRUE) && ar_have_repo() && ar_have_weights("linear_sleepstages")) { data = ar_example_data(n_hours = 2.5) out = py_estimate_rest(data, model = "linear_sleepstages", context_window_shift = 32L) }
py_require for rester
Declares the Python packages needed to run AcceleRest using
reticulate::py_require(). This is called when rester is loaded, so
calling it directly is only needed if you pass additional arguments.
py_require_rester(...)py_require_rester(...)
... |
arguments to pass to |
The output of reticulate::py_require(), invisibly.
# Only declares the requirements; nothing is installed until Python starts py_require_rester()# Only declares the requirements; nothing is installed until Python starts py_require_rester()