From 65904cdb98fbf146e441f986dd62ed72e73f1156 Mon Sep 17 00:00:00 2001 From: hyang336 Date: Wed, 2 Oct 2024 20:00:33 -0700 Subject: [PATCH 1/6] Update epoch.R --- R/epoch.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/epoch.R b/R/epoch.R index 392ea01..062c158 100644 --- a/R/epoch.R +++ b/R/epoch.R @@ -434,7 +434,7 @@ epoch_manually <- function(eyeris, ts_list, hz) { ), .after = time_orig ) |> - dplyr::mutate(!!!metadata_vals) + dplyr::mutate(!!!metadata_vals[i,]) epochs[[i]] <- current_epoch } From 73b089d883eaf2d4dbaa472149f5806758cd947a Mon Sep 17 00:00:00 2001 From: shawn Date: Fri, 4 Oct 2024 01:04:59 -0700 Subject: [PATCH 2/6] hotfix: resolve #93 by @hyang336 (fix linting error) PR #87 --- R/epoch.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/epoch.R b/R/epoch.R index 062c158..69a858c 100644 --- a/R/epoch.R +++ b/R/epoch.R @@ -434,7 +434,7 @@ epoch_manually <- function(eyeris, ts_list, hz) { ), .after = time_orig ) |> - dplyr::mutate(!!!metadata_vals[i,]) + dplyr::mutate(!!!metadata_vals[i, ]) epochs[[i]] <- current_epoch } From 08d86f13322ab2b422b8220ac49d2947078f0ab4 Mon Sep 17 00:00:00 2001 From: shawn Date: Fri, 4 Oct 2024 01:07:18 -0700 Subject: [PATCH 3/6] fix #92, fix #95, fix #96: conflicts between epoching and baseline parameters --- R/epoch.R | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/R/epoch.R b/R/epoch.R index 69a858c..af60a26 100644 --- a/R/epoch.R +++ b/R/epoch.R @@ -147,10 +147,11 @@ epoch_pupil <- function(x, prev_op, evs, lims, label, c_bline, a_bline, timestamped_events <- x |> purrr::pluck("events") - timestamps <- get_timestamps(evs, timestamped_events, msg_s, msg_e, lims) - - timestamps_s <- timestamps$start - timestamps_e <- timestamps$end + if (!is.list(evs)) { + timestamps <- get_timestamps(evs, timestamped_events, msg_s, msg_e, lims) + timestamps_s <- timestamps$start + timestamps_e <- timestamps$end + } # run 1 of 4 possible epoch modes if (is.character(evs) && length(evs) == 1) { @@ -232,20 +233,28 @@ epoch_pupil <- function(x, prev_op, evs, lims, label, c_bline, a_bline, get_timestamps <- function(evs, timestamped_events, msg_s, msg_e, limits, baseline_mode = FALSE) { + start_ts <- NULL end_ts <- NULL - if (baseline_mode) { + if (baseline_mode) { ## baseline calculation enabled start_ts <- parse_timestamps(evs, timestamped_events, msg_s) if (!is.na(msg_e)) { end_ts <- parse_timestamps(evs, timestamped_events, msg_e) } - } else { + } else { ## baseline calculation disabled if (!is.list(evs)) { start_ts <- parse_timestamps(evs, timestamped_events, msg_s) + } + + if (is.list(evs)) { + msg_s <- msg_s[[1]]$msg + msg_e <- msg_e[[1]]$msg + } - if (!endsWith(msg_s, "*")) { - if (!is.na(evs[2])) { + if (!any(is.na(msg_e))) { + if (!any(endsWith(msg_s, "*"))) { + if (!any(is.na(evs[2]))) { end_ts <- parse_timestamps(evs, timestamped_events, msg_e) } } else { @@ -276,7 +285,7 @@ make_epoch_label <- function(evs, label, epoched_data) { epoch_id <- sanitize_event_tag(evs[1]) } else if (is.null(label) && is.list(evs)) { epoch_id <- sanitize_event_tag(paste0( - epoched_data$start_msg[1], epoched_data$end_msg[1] + epoched_data[[1]]$start_msg[1], epoched_data[[1]]$end_msg[1] )) } else { epoch_id <- paste0("epoch_", label) @@ -298,7 +307,7 @@ parse_events_and_metadata <- function(events, metadata_template) { event_messages <- events |> dplyr::pull(text) - if (endsWith(metadata_template, "*")) { # wildcard mode + if (any(endsWith(metadata_template, "*"))) { # wildcard mode prefix <- substr(metadata_template, 1, nchar(metadata_template) - 1) for (char in special_chars) { # escape special chars From ae236df761a341be44a8d0310fd8fdb3b3d4a8a6 Mon Sep 17 00:00:00 2001 From: shawn Date: Fri, 4 Oct 2024 01:08:38 -0700 Subject: [PATCH 4/6] fix #94: bug in example epoching code --- R/epoch.R | 9 ++++----- man/epoch.Rd | 9 ++++----- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/R/epoch.R b/R/epoch.R index af60a26..5c510b2 100644 --- a/R/epoch.R +++ b/R/epoch.R @@ -93,14 +93,14 @@ #' #' eye_preproc |> #' eyeris::epoch( -#' events = "PROBE_{type}_{trial}", -#' limits = c(0, 1) # grab the 1 second post event +#' events = "PROBE_START_{trial}", +#' limits = c(0, 1) # grab the 1 second following probe onset #' ) #' #' eye_preproc |> #' eyeris::epoch( -#' events = "PROBE_{type}_{trial}", -#' limits = c(-2, 1), # grab 2 seconds prior to and 1 second post event +#' events = "PROBE_START_{trial}", +#' limits = c(-2, 1), # 2 seconds prior to and 1 second after probe onset #' label = "prePostProbe" # custom epoch label name #' ) #' @@ -121,7 +121,6 @@ #' data.frame(time = c(11245956), msg = NA) # end events #' ) #' ) -#' } #' #' @export epoch <- function(eyeris, events, limits = NULL, label = NULL, diff --git a/man/epoch.Rd b/man/epoch.Rd index 88bc4d7..3b5c346 100644 --- a/man/epoch.Rd +++ b/man/epoch.Rd @@ -122,14 +122,14 @@ eye_preproc |> eye_preproc |> eyeris::epoch( - events = "PROBE_{type}_{trial}", - limits = c(0, 1) # grab the 1 second post event + events = "PROBE_START_{trial}", + limits = c(0, 1) # grab the 1 second following probe onset ) eye_preproc |> eyeris::epoch( - events = "PROBE_{type}_{trial}", - limits = c(-2, 1), # grab 2 seconds prior to and 1 second post event + events = "PROBE_START_{trial}", + limits = c(-2, 1), # 2 seconds prior to and 1 second after probe onset label = "prePostProbe" # custom epoch label name ) @@ -150,6 +150,5 @@ eye_preproc |> data.frame(time = c(11245956), msg = NA) # end events ) ) -} } From d91b5b15962c5e15d8becf8910084ed790584ce3 Mon Sep 17 00:00:00 2001 From: shawn Date: Fri, 4 Oct 2024 01:09:40 -0700 Subject: [PATCH 5/6] resolve #91: add example code for baselining --- R/epoch.R | 55 +++++++++++++++++++++++++++++++++++++++++++++++----- man/epoch.Rd | 54 ++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 99 insertions(+), 10 deletions(-) diff --git a/R/epoch.R b/R/epoch.R index 5c510b2..a17a72c 100644 --- a/R/epoch.R +++ b/R/epoch.R @@ -58,11 +58,15 @@ #' @param baseline_events Similar to `events`, `baseline_events`, you can supply #' either (1) a single string representing the event message to center the #' baseline calculation around, as indicated by `baseline_period`; or (2) a -#' vector containing both `start` and `end` event message strings -- here, -#' `baseline_period` will be ignored and the duration of each baseline period -#' that the mean will be calculated on will be the number of samples between -#' each matched `start` and `end` event message pair, as opposed to a specified -#' fixed duration (as described in 1). +#' single vector containing both a `start` and an `end` event message string -- +#' here, `baseline_period` will be ignored and the duration of each baseline +#' period that the mean will be calculated on will be the number of samples +#' between each matched `start` and `end` event message pair, as opposed to a +#' specified fixed duration (as described in 1). Please note, providing a list +#' of trial-level start/end message pairs (like in the `events` parameter) to +#' manually indicate unique start/end chunks for baselining is currently +#' unsupported. Though, we intend to add this feature in a later version of +#' `eyeris`, given it likely won't be a heavily utilized / in demand feature. #' @param baseline_period A vector of 2 values (start, end) in seconds, #' indicating the window of data that will be used to perform the baseline #' correction, which will be centered around the single string "start" message @@ -122,6 +126,47 @@ #' ) #' ) #' +#' # examples with baseline arguments enabled +#' +#' # example 1: use mean of 1-s preceding "PROBE_START" (i.e. "DELAY_STOP") +#' to perform subtractive baselining of the 1-s PROBE epochs. +#' eye_preproc |> +#' eyeris::epoch( +#' events = "PROBE_START_{trial}", +#' limits = c(0, 1), # grab 0 seconds prior to and 1 second post PROBE event +#' label = "prePostProbe", # custom epoch label name +#' calc_baseline = TRUE, +#' apply_baseline = TRUE, +#' baseline_type = "sub", # "sub"tractive baseline calculation is default +#' baseline_events = "DELAY_STOP_*", +#' baseline_period = c(-1, 0) +#' ) +#' +#' # example 2: use mean of time period between set start/end event messages +#' (i.e. between "DELAY_START" and "DELAY_STOP"). In this case, the +#' `baseline_period` argument will be ignored since both a "start" and "end" +#' message string are provided to the `baseline_events` argument. +#' eye_preproc |> +#' eyeris::epoch( +#' events = "PROBE_START_{trial}", +#' limits = c(0, 1), # grab 0 seconds prior to and 1 second post PROBE event +#' label = "prePostProbe", # custom epoch label name +#' calc_baseline = TRUE, +#' apply_baseline = TRUE, +#' baseline_type = "sub", # "sub"tractive baseline calculation is default +#' baseline_events = c("DELAY_START_*", +#' "DELAY_STOP_*") +#' ) +#' +#' # additional (potentially helpful) example +#' start_events <- data.frame(time = c(11243355, 11247588), +#' msg = c("TRIALID 0", "TRIALID 1")) +#' end_events <- data.frame(time = c(11245956, 11250506), +#' msg = c("RESPONSE_0", "RESPONSE_1")) +#' eye_prepoc |> +#' eyeris::epoch(events = list(start_events, end_events)) +#' } + #' @export epoch <- function(eyeris, events, limits = NULL, label = NULL, calc_baseline = FALSE, apply_baseline = FALSE, diff --git a/man/epoch.Rd b/man/epoch.Rd index 3b5c346..120dc71 100644 --- a/man/epoch.Rd +++ b/man/epoch.Rd @@ -77,11 +77,15 @@ the pupil from the latest preprocessing step.} \item{baseline_events}{Similar to \code{events}, \code{baseline_events}, you can supply either (1) a single string representing the event message to center the baseline calculation around, as indicated by \code{baseline_period}; or (2) a -vector containing both \code{start} and \code{end} event message strings -- here, -\code{baseline_period} will be ignored and the duration of each baseline period -that the mean will be calculated on will be the number of samples between -each matched \code{start} and \code{end} event message pair, as opposed to a specified -fixed duration (as described in 1).} +single vector containing both a \code{start} and an \code{end} event message string -- +here, \code{baseline_period} will be ignored and the duration of each baseline +period that the mean will be calculated on will be the number of samples +between each matched \code{start} and \code{end} event message pair, as opposed to a +specified fixed duration (as described in 1). Please note, providing a list +of trial-level start/end message pairs (like in the \code{events} parameter) to +manually indicate unique start/end chunks for baselining is currently +unsupported. Though, we intend to add this feature in a later version of +\code{eyeris}, given it likely won't be a heavily utilized / in demand feature.} \item{baseline_period}{A vector of 2 values (start, end) in seconds, indicating the window of data that will be used to perform the baseline @@ -151,4 +155,44 @@ eye_preproc |> ) ) +# examples with baseline arguments enabled + +# example 1: use mean of 1-s preceding "PROBE_START" (i.e. "DELAY_STOP") +to perform subtractive baselining of the 1-s PROBE epochs. +eye_preproc |> + eyeris::epoch( + events = "PROBE_START_{trial}", + limits = c(0, 1), # grab 0 seconds prior to and 1 second post PROBE event + label = "prePostProbe", # custom epoch label name + calc_baseline = TRUE, + apply_baseline = TRUE, + baseline_type = "sub", # "sub"tractive baseline calculation is default + baseline_events = "DELAY_STOP_*", + baseline_period = c(-1, 0) + ) + +# example 2: use mean of time period between set start/end event messages +(i.e. between "DELAY_START" and "DELAY_STOP"). In this case, the +`baseline_period` argument will be ignored since both a "start" and "end" +message string are provided to the `baseline_events` argument. +eye_preproc |> + eyeris::epoch( + events = "PROBE_START_{trial}", + limits = c(0, 1), # grab 0 seconds prior to and 1 second post PROBE event + label = "prePostProbe", # custom epoch label name + calc_baseline = TRUE, + apply_baseline = TRUE, + baseline_type = "sub", # "sub"tractive baseline calculation is default + baseline_events = c("DELAY_START_*", + "DELAY_STOP_*") + ) + +# additional (potentially helpful) example + start_events <- data.frame(time = c(11243355, 11247588), + msg = c("TRIALID 0", "TRIALID 1")) + end_events <- data.frame(time = c(11245956, 11250506), + msg = c("RESPONSE_0", "RESPONSE_1")) + eye_prepoc |> + eyeris::epoch(events = list(start_events, end_events)) +} } From 42bf8d07925fa51a3dae111ce105e3712646ea82 Mon Sep 17 00:00:00 2001 From: shawn Date: Fri, 4 Oct 2024 01:10:10 -0700 Subject: [PATCH 6/6] update readme.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 291dcea..c43104d 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -# `eyeris`: create and run flexible and reproducible pupillometry preprocessing pipelines in R +# `eyeris`: create and run flexible and reproducible pupillometry preprocessing pipelines in R