---
title: "Non-wear detection from ActiGraph data"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Non-wear detection from ActiGraph data}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r setup, echo = FALSE}
knitr::opts_chunk$set(
  echo = TRUE, warning = FALSE, message = FALSE, collapse = TRUE,
  comment = "#>", out.width = "75%", fig.asp = 1 / 1.6, fig.width = 5
)
pckg <- c("actigraph.sleepr", "dplyr", "lubridate", "ggplot2")
inst <- suppressMessages(lapply(pckg, library, character.only = TRUE))
theme_set(theme_light())
```

The `actigraph.sleepr` package implements two non-wear detection algorithms: Troiano (Troiano et al. 2008) and Choi (Choi et al. 2011). For illustration let's use one day of sample data recorded by a GT3X+ monitor. See the [sleep vignette](detect-sleep.html) for details on reading AGD files and collapsing epochs.

```{r }
file_10s <- system.file("extdata", "ActiSleepPlus-RawData-Day01.agd",
  package = "actigraph.sleepr"
)
agdb_60s <- read_agd(file_10s) %>%
  collapse_epochs(60) %>%
  mutate(date = lubridate::as_date(timestamp)) %>%
  select(date, timestamp, starts_with("axis")) %>%
  group_by(date)
agdb_60s
```

Long stretches that consist almost entirely of zero counts (zero epochs) suggest that the device wasn't worn at all and therefore should be excluded from downstream analysis.

### Non-wear detection with the Troiano algorithm

The Troiano algorithm for detecting periods of non-wear formalizes a technique used to analyze the 2003-2004 NHANES data; the original SAS source code can be found at https://riskfactor.cancer.gov/tools/nhanes_pam/. The method has some flexibility as a non-wear period can contain a few nonzero epochs of artifactual movement (spikes).

`activity_threshold`
 : Highest activity level to be considered "zero"; an epoch with activity exceeding the threshold is considered a "spike". The default threshold is 0.

`min_period_len`
 : Minimum number of consecutive zero epoch to start a non-wear period. The default is 60.

`max_nonzero_count`
 : Epochs with activity greater than `max_nonzero_count` are labeled "zero". The default is `Inf`.

`spike_tolerance`
 : Also known as artifactual movement interval. At most `spike_tolerance` "nonzero" epochs can occur in sequence during a non-wear period without interrupting it. The default is 2.

`spike_stoplevel`
 : An activity spike that exceeds `spike_stoplevel` counts ends a non-wear period, even if the spike tolerance has not been reached. The default is 100.

`use_magnitude`
 : If true, the magnitude of the vector (axis1, axis2, axis3) is used to measure activity; otherwise the axis1 value is used. The default is FALSE.
 
`endat_nnz_seq`
 : If true, a non-wear period ends with a run of nonzero epochs that is longer than `spike_tolerance`. This corresponds to the option *"Require consecutive epochs outside of the activity threshold"* in ActiLife's Wear Time Validation menu. The default is TRUE.

The Troiano algorithm specifies that a non-wear period starts with `min_length` consecutive epochs/minutes of zero activity and ends with more than `spike_tolerance` epochs/minutes of nonzero activity.

```{r }
periods_nonwear <- agdb_60s %>% apply_troiano(min_period_len = 45)
periods_nonwear
```

The parameter settings of the Troiano algorithm are stored as attributes.

```{r }
tail(attributes(periods_nonwear), 8)
```

Once non-wear periods are detected, we can further screen those intervals. For example, we can ignore non-wear periods that are too short.

```{r }
periods_nonwear %>% filter(length >= 60)
```

Or we can flag 24-hour day as invalid if the device was worn only for a short period of time.

```{r }
# Find the periods during which the device was worn
periods_wear <- complement_periods(
  periods_nonwear, agdb_60s,
  period_start, period_end
)
periods_wear

# Label each epoch with the period_id of the wear period it falls in
# or with NA if the epoch falls outside a wear period
agdb_wear <- combine_epochs_periods(
  agdb_60s, periods_wear,
  period_start, period_end
)
agdb_wear

# Once we add the wear/nonwear information, it is straightforward to
# compute summary statistics or join with external minute-by-minute data
agdb_wear %>%
  group_by(period_id, .add = TRUE) %>%
  summarise(
    time_worn = n(),
    ave_counts = mean(axis1),
    .groups = "drop_last"
  )
```

### Non-wear detection with the Choi algorithm

The Choi algorithm extends the Troiano algorithm by requiring that short spikes of artifactual movement during a non-wear period are preceded and followed by \code{min_window_len} consecutive zero epochs.

`min_period_len`
 : Minimum number of consecutive zero epoch to start a non-wear period. The default is 90.

`min_window_len`
 : The minimum number of consecutive "zero" epochs immediately preceding and following a spike of artifactual movement. The default is 30.

`spike_tolerance`
 : Also known as artifactual movement interval. At most `spike_tolerance` "nonzero" epochs can occur in sequence during a non-wear period without interrupting it. The default is 2.

`use_magnitude`
 : If true, the magnitude of the vector (axis1, axis2, axis3) is used to measure activity; otherwise the axis1 value is used. The default is FALSE.
 
```{r }
periods_nonwear <- agdb_60s %>% apply_choi(
  min_period_len = 45,
  min_window_len = 10
)
periods_nonwear
```

Again, the parameter settings are saved as attributes.

```{r }
tail(attributes(periods_nonwear), 5)
```

### References

Troiano, Richard P, David Berrigan, Kevin W Dodd, Louise C Mâsse, Timothy Tilert, and Margaret McDowell. 2008. “Physical Activity in the United States Measured by Accelerometer.” *Medicine & Science in Sports & Exercise* 40 (1): 181–88.

Choi, Leena, Zhouwen Liu, Charles E. Matthews, and Maciej S. Buchowski. 2011. “Validation of Accelerometer Wear and Nonwear Time Classification Algorithm.” *Medicine & Science in Sports & Exercise* 43 (2): 357–64.
