R/eegr.R

Defines functions show_eeg eeg_session extract_epochs epoch_size

Documented in eeg_session epoch_size extract_epochs show_eeg

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
}
limads/eegr documentation built on May 3, 2019, 3:21 p.m.