library(stringr)
library(dplyr)
library(methods)
library(ggplot2)
#' An S4 class representing an EEG session
#' @slot signal The actual EEG recording
#' @slot epochs Named list of vectors representing individual epochs
#' @slot spec_epochs FFT of epochs
#' @n Full lenght of recording
#' @srate Integer representing the sampling rate
EEGSession <- setClass("EEGSession",
slots=list(
signal="numeric",
epochs="list",
spec_epochs="list",
n="integer",
srate="integer"
)
)
#' Displays EEG session
show_eeg <- function(eeg) {
epochs_d <- diff(eeg@events)
str_c("EEG session\n",
"Running time : ", eeg@n / eeg@srate, "\n",
"Sampling rate : ", eeg@srate, "\n",
"Peak voltage (+): ", max(eeg@signal), "\n",
"Peak voltage (-): ", min(eeg@signal), "\n",
"Min epoch size (samples) : ", min(epochs_d), "\n",
"Median epoch size (samples) : ", median(epochs_d), "\n",
"Max epoch size (samples) : ", max(epochs_d), "\n"
)
}
setMethod("show", signature="EEGSession", definition = show_eeg)
#' Instantiate a new EEG session
#' @param signal Vector of raw voltage recordings
#' @param srate Integer specifying samples/second
#' @param onset Vector of signal indices (possibly named) where events of interest started
#' @param ends Vector of signal indices where events of interest ended
#' @param e_size Optional argument. If offset was not informed, consider events as ending at onset+e_size
#' @return An EEGSession S4 object
#' @examples
#' eeg_session(signal, 1000L, c(1000,2000))
eeg_session <- function(signal, srate, onset, ends=NULL, e_size=NULL) {
n <- length(signal)
invalid_index <- which(onset <= 0)
off_index <- which(onset > n)
idx_msg <- str_c("Supply value between 1-", n)
if(any(invalid_index)) {
stop(str_c("Index ", invalid_index[1], " is invalid.", idx_msg))
}
if(any(off_index)) {
stop(str_c("Index ", off_index[1], " greater than signal range. ", n = length(signal)))
}
if(srate < 1) {
stop("Invalid sampling rate")
}
if(any(names(onset) == NULL)) {
print("Unnamed event vector. Names set to ev_1, ev2 ... ev_n")
names(onset) <- str_c("ev_", 1:n)
}
epochs <- list()
ev_names <- names(onset)
if(!is.null(ends)) {
idx <- 1
for(e in ev_names) {
epochs[[e]] <- signal[onset[e] : ends[idx]]
idx <- idx + 1
}
} else {
if(!is.null(epoch_size)) {
for(e in ev_names) {
epochs[[e]] <- signal[onset[e] : (onset[e] + e_size - 1)]
}
} else {
stop("Need to inform either a vector of offsets or a constant epoch_size")
}
}
# Deal with recordings that might not have "final" event
spec_epochs <- lapply(epochs, short_fft)
EEGSession(signal=signal, epochs=epochs,
spec_epochs = spec_epochs, srate=srate, n=n)
}
#' Given a regex, limit the epochs list to the labels that match it
extract_epochs <- function(eeg, cond_rgx) {
eeg@epochs[str_detect(names(eeg@epochs), cond_rgx)]
}
#' Return epoch size common to all epochs. Error if any is different from the first.
epoch_size <- function(epochs) {
fst_size <- length(use_epochs[[1]])
e_sizes <- sapply(epochs, length)
wrong_sizes <- which(e_sizes != fst_size)
if(any(wrong_sizes)) {
stop(
str_c("Epoch ", names(wrong_sizes[1]), " (", wrong_sizes[1],
") samples is of different size than the first epoch (",
fst_size, ") samples"
)
)
}
fst_size
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.