Run asleep Model on Data
Run asleep with Python
Usage
asleep(
file,
outdir = NULL,
min_wear_hours = 22L,
time_shift = "0",
report_light_and_temp = FALSE,
pytorch_device = c("cpu", "cuda:0"),
sample_rate = NULL,
verbose = TRUE,
force_download = FALSE
)
py_asleep(
...,
pyenv_function = function() {
reticulate::py_require(c("asleep @ git+https://github.com/muschellij2/asleep.git",
"argparse", "numpy", "pandas", "importlib"), python_version = "3.8")
reticulate::import("asleep")
},
show = FALSE
)Arguments
- file
accelerometry file to process, including CSV, CWA, GT3X, and
GENEActivbin files- outdir
output directory for CSVs and outputs
- min_wear_hours
Min wear time in hours to be eligible for summary statistics computation. The sleepnet paper uses 22
- time_shift
The number hours to shift forward or backward from the current device time. e.g. +1 or -1
- report_light_and_temp
If true, it adds mean temp, and light columns to the predictions
- pytorch_device
device to use for prediction for PyTorch.
- sample_rate
Sample rate for the data, currently not used.
- verbose
print diagnostic messages
- force_download
force a download of the model, passed to
sl_download_models()- ...
arguments to pass to asleep
- pyenv_function
function that loads the forest Python package. By default, it uses reticulate::py_import("asleep") to import the package. If this function has an args argument, the output of pyenv_function will be re-assigned to args.
- show
Logical, whether to show the standard output on the screen while the child process is running, passed to
callr::r()
Examples
# \donttest{
file = system.file("extdata/example_sleep.csv.gz", package = "asleep")
stopifnot(file.exists(file))
if (asleep_check()) {
sl_download_models()
out = try({asleep(file = file, verbose = 2L)})
if (inherits(out, "try-error")) {
message(out)
reticulate::py_last_error()
} else {
pred = out$predictions
}
}
#> Downloading uv...
#> Done!
#> Checking Data
#> File is:/home/runner/work/_temp/Library/asleep/extdata/example_sleep.csv.gz
#> Downloading models if not already present
#> Parsing raw data
#> Transforming data for model input
#> Data shape for data2model: (480, 3, 900)
#> Data shape for times: (480,)
#> Data shape for nonwear: (480,)
#> Detecting sleep windows
#> args$outdir/tmp/RtmpYJuSuh/file19e16da5607d
#> ssl_sleep_path: /tmp/RtmpYJuSuh/file19e16da5607d/ssl_sleep.npy, exists:FALSE
#> data2model
#> array([[[-0.704 , -0.72079488, -0.66515385, ..., -0.69130774,
#> -0.69115383, -0.6903333 ],
#> [ 0.413 , 0.419 , 0.42884615, ..., 0.42430774,
#> 0.42807678, 0.44416667],
#> [-0.54 , -0.56166666, -0.57858971, ..., -0.55976925,
#> -0.59274354, -0.61691666]],
#>
#> [[-0.689 , -0.61469231, -0.58484615, ..., -0.62961541,
#> -0.62735884, -0.62341669],
#> [ 0.469 , 0.42923077, 0.43343586, ..., 0.466 ,
#> 0.46 , 0.45547223],
#> [-0.648 , -0.55720514, -0.58207693, ..., -0.57223075,
#> -0.57330765, -0.56950002]],
#>
#> [[-0.625 , -0.62246154, -0.63430771, ..., -0.73707666,
#> -0.73812797, -0.74825001],
#> [ 0.457 , 0.45953846, 0.46923078, ..., 0.18476925,
#> 0.19420501, 0.20291666],
#> [-0.56 , -0.548 , -0.56430771, ..., -0.64523075,
#> -0.6363847 , -0.65150002]],
#>
#> ...,
#>
#> [[-0.032 , -0.032 , -0.032 , ..., -0.032 ,
#> -0.032 , -0.032 ],
#> [-0.123 , -0.123 , -0.123 , ..., -0.123 ,
#> -0.123 , -0.123 ],
#> [-0.988 , -0.988 , -0.988 , ..., -0.988 ,
#> -0.988 , -0.988 ]],
#>
#> [[-0.032 , -0.032 , -0.032 , ..., -0.032 ,
#> -0.032 , -0.032 ],
#> [-0.123 , -0.123 , -0.123 , ..., -0.123 ,
#> -0.123 , -0.123 ],
#> [-0.988 , -0.988 , -0.988 , ..., -0.988 ,
#> -0.988 , -0.988 ]],
#>
#> [[-0.032 , -0.032 , -0.032 , ..., -0.032 ,
#> -0.032 , -0.032 ],
#> [-0.123 , -0.123 , -0.123 , ..., -0.123 ,
#> -0.123 , -0.123 ],
#> [-0.988 , -0.988 , -0.988 , ..., -0.988 ,
#> -0.988 , -0.988 ]]])
#> non_wear
#> array([False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False, False, False, False, False, False, False,
#> False, False, False])
#> Running SleepNet
#> SleepNet outdir: /tmp/RtmpYJuSuh/file19e16da5607d
#> Upstream ssl model path: /home/runner/.cache/R/reticulate/uv/cache/archive-v0/qYB7v8CH_3K8YlPg/lib/python3.8/site-packages/asleep/ssl.joblib.lzma, exists: TRUE
#> SleepNet weight URL: https://github.com/OxWearables/asleep/releases/download/0.4.9/sleepnet_apr_16_2024.mdl
#> SleepNet artifact ssl_sleep: /tmp/RtmpYJuSuh/file19e16da5607d/ssl_sleep.npy, exists: TRUE
#> SleepNet artifact y_pred: /tmp/RtmpYJuSuh/file19e16da5607d/y_pred.npy, exists: FALSE
#> SleepNet artifact pred_prob: /tmp/RtmpYJuSuh/file19e16da5607d/pred_prob.npy, exists: FALSE
#> SleepNet artifact x_npy: /tmp/RtmpYJuSuh/file19e16da5607d/X.npy, exists: TRUE
#> SleepNet artifact x_npy_gz: /tmp/RtmpYJuSuh/file19e16da5607d/X.npy.gz, exists: FALSE
#> SleepNet artifact npid: /tmp/RtmpYJuSuh/file19e16da5607d/npid.npy, exists: TRUE
#> Mapping SleepNet predictions back to original time series
#> Generating predictions dataframe
#> Generating sleep block df and indicate the longest block per day
#> Generating daily summary statistics
#> Creating outputs
# }
# \donttest{
file = system.file("extdata/example_sleep.csv.gz", package = "asleep")
df = readr::read_csv(file)
#> Rows: 432000 Columns: 4
#> ── Column specification ────────────────────────────────────────────────────────
#> Delimiter: ","
#> dbl (3): x, y, z
#> dttm (1): time
#>
#> ℹ Use `spec()` to retrieve the full column specification for this data.
#> ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
if (asleep_check()) {
out = asleep(file = df)
st = out$predictions
if (requireNamespace("ggplot2", quietly = TRUE) &&
requireNamespace("tidyr", quietly = TRUE) &&
requireNamespace("dplyr", quietly = TRUE)) {
d = st[1:250,] %>%
dplyr::mutate(
time = lubridate::as_datetime(time),
time_end = dplyr::lead(time)
) %>%
dplyr::filter(!is.na(time_end))
raw = df %>% dplyr::filter(time >= min(d$time) & time <= max(d$time))
dat = raw %>%
tidyr::gather(axis, value, -time)
d = d %>% dplyr::mutate(activity_y = as.numeric(sleep_wake == "sleep"))
dat %>%
ggplot2::ggplot(ggplot2::aes(x = time, y = value, colour = axis)) +
ggplot2::geom_step() +
ggplot2::geom_segment(
data = d,
ggplot2::aes(
x = time, xend = time_end,
y = activity_y, yend = activity_y,
linetype = sleep_wake
),
colour = "black", linewidth = 1, inherit.aes = FALSE
) +
ggplot2::labs(linetype = "Sleep/wake")
}
}
#> Checking Data
#> Writing file to CSV...
#> Parsing raw data
#> Transforming data for model input
#> Data shape for data2model: (480, 3, 900)
#> Data shape for times: (480,)
#> Data shape for nonwear: (480,)
#> Detecting sleep windows
#> Running SleepNet
#> Mapping SleepNet predictions back to original time series
#> Generating predictions dataframe
#> Generating sleep block df and indicate the longest block per day
#> Generating daily summary statistics
#> Creating outputs
# }