## ----include = FALSE----------------------------------------------------------
knitr::opts_chunk$set(
  collapse = TRUE,
  eval = FALSE,
  comment = "#>"
)
#> library(rgl)
#> knitr::knit_hooks$set(webgl = hook_webgl)

## ----setup--------------------------------------------------------------------
library(diegr)
library(rlang)

## -----------------------------------------------------------------------------
# install.packages("diegr")
# # or for development version:
# # install.packages("devtools")
# devtools::install_github("gerslovaz/diegr")

## -----------------------------------------------------------------------------
# # The function for interactive boxplot of signal assumes
# # pre-filtered data input
# # example: subject 1 and channel E34 in time points from 10 to 20
# subdata <- epochdata |>
#   pick_data(subject_rg = 1, sensor_rg = "E34")
# boxplot_epoch(subdata, amplitude = "signal", time_lim = 10:20)
# 
# # customizing the output title and axis labels using |> operator
# p1 <- boxplot_epoch(subdata, amplitude = "signal", time_lim = 10:20)
# p1 |> plotly::layout(xaxis = list(title = ""),
#                      yaxis = list(title = "Amplitude"),
#                      title = list(text = "Outlier detection for subject 1 and channel E34",
#                                   font = list(size = 11, color = "darkblue"))
#                      )
# # note: the output is not plotted to reduce the vignette file size

## -----------------------------------------------------------------------------
# # Example: outlier detection for both subjects and channel E34 using IQR method
# # The column in which we are looking for outliers is specified by the `amplitude` argument
# epochdata |>
#   pick_data(sensor_rg = "E34") |>
# outliers_epoch(amplitude = "signal", method = "iqr")

## -----------------------------------------------------------------------------
# preparing data for later visualisation 
# filtering signal without outlier epochs 14 and 15
# and computing epoch level jackknife average from baseline corrected data
# Note: data filtering is possible both using the pick_data() function or dplyr commands
edata <- epochdata |>
  pick_data(subject_rg = 2, epoch_rg = 1:13) |>
  baseline_correction(baseline_range = 1:10)

s1 <- edata |>
  dplyr::filter(time == 10) |>
  compute_mean(amplitude = "signal_base", level = "epoch",
               domain = "space", type = "jack")

## ----fig.alt="An average amplitude time-series plot showing the brain's electrical activity (in microvolts) over time (in milliseconds), time-locked to a stimulus event at 0 ms. The red line represents the average amplitude, and the shaded red area represents the confidence interval."----
# computing jackknife average from channel E65 
s2 <- edata |>
  pick_data(sensor_rg = "E65") |>
  compute_mean(amplitude = "signal_base", level = "epoch",
               domain = "time", type = "jack")

# plotting the average, the zero time point (stimulus) is set to 10
plot_time_mean(s2, t0 = 10)

## ----fig.show='hold', fig.alt="A schematic representations of an HD-EEG sensor net, showing the arrangement of 204 labeled channels distributed across the entire scalp area together with denser point mesh created for interpolation."----
# creating a mesh with default settings
sensors204 <- unique(epochdata$sensor)
M1 <- point_mesh(template = "HCGSN256", sensor_select = sensors204)
# plot output in 2D
plot_point_mesh(M1$D2, sensor_select = sensors204)

# creating a circular mesh, only 2D coordinates
M2 <- point_mesh(dimension = 2, n = 3000, template = "HCGSN256",
                 sensor_select = sensors204, type = "circle")
# plotting a mesh - function allows different options of the result plot
plot_point_mesh(M2$D2, sensor_select = sensors204, col_sensors = "purple",
                label_sensors = TRUE, cex = 0.1)

## ----fig.show='hold', fig.alt="Fig 1: A top-down topographic map of a high-density EEG amplitude in topographic colour scale with contours and black points on sensor locations. The amplitude legend is on the left side of the scalp projection. Fig 2: The same plot without contours and legend, but with sensor labels as text displayed together with black point on sensor positions. Fig 3: A ggplot divided into three panels with topographic maps of average signal (middle) and its lower (left) and upper (right) confidence interval bounds. The colour legend position is bottom of the facets."----
# Plot average topographic map of baseline corrected signal for subject 1 
# from the time point 10 (the time of the stimulus)
# the outlier epoch 14 is extracted before computing average

# preparing data
data_base <- epochdata |>
  pick_data(subject_rg = 1, time_rg = 1:10) |>
  baseline_correction(baseline_range = 1:10)

data_mean <- data_base |>
  pick_data(epoch_rg = 1:13, time_rg = 10) |>
  compute_mean(amplitude = "signal_base", type = "point",
               domain = "space")

# plotting the base topographic polygon map with contours and legend
# interval (-30,15) is selected in consideration of the signal progress
topo_plot(data = data_mean, amplitude = "average", 
          col_range = c(-30, 15), contour = TRUE)

# plotting the same map without contours and legend 
# but with sensor labels and adding the title
g1 <- topo_plot(data = data_mean, amplitude = "average",
                col_range = c(-30, 15),
                label_sensors = TRUE, show_legend = FALSE)
g1 + ggplot2::ggtitle("Subject 1, time of the stimulus")

# plotting the average together with CI bounds using plot_topo_mean
plot_topo_mean(data = data_mean, template = "HCGSN256", col_range = c(-30, 15))

## -----------------------------------------------------------------------------
# # plotting the scalp polygon map of previously prepared signal s1
# #open3d()
# scalp_plot(s1, amplitude = "average", col_range = c(-30, 15))
# 
# # note: the output is not plotted to reduce the vignette file size

## -----------------------------------------------------------------------------
# # filtering the example data
# s1e05 <- epochdata |>
#   pick_data(subject_rg = 1, epoch_rg = 5, time_rg = 10:20)
# 
# # Plot animation with setting the range of time and t0 = 10 indicating the time of the stimulus:
# animate_topo(s1e05, amplitude = "signal", t_lim = c(0,50), t0 = 10)
# 
# # Export the gif animation - this code will create the animation inside your working directory.
# # If you want to export it elsewhere, set the whole path in output_path parameter.
# animate_topo(s1e05, amplitude = "signal", t_lim = c(0,50),
#              t0 = 10, output_path = "example_animation.gif")

## -----------------------------------------------------------------------------
# # Plot animation with default mesh and triangulation:
# animate_scalp(s1e05, amplitude = "signal")
# # export the video - the .mp4 extension is required for correct functioning
# rgl::par3d(windowRect = c(100, 100, 800, 800))
# animate_scalp(s1e05, amplitude = "signal",
#               frames_dir = "your_frames_dir_path",
#               output_path = "your_created_video_path.mp4")

## -----------------------------------------------------------------------------
# #open3d()
# scalp_plot(s1, amplitude = "average", col_range = c(-30,15))
# rgl::play3d(rgl::spin3d(axis = c(0, 0, 1), rpm = 10), duration = 10)
# 
# # note: the output is not plotted to reduce the vignette file size

## -----------------------------------------------------------------------------
# # using IQR method for selected sensor from central region
# dataE59 <- epochdata |>
#   pick_data(sensor_rg = "E59")
# outliers_epoch(dataE59, method = "iqr")
# 
# # verify results by visual inspection (for each subject separately)
# dataE59 |>
#   dplyr::filter(subject == 1) |>
#   interactive_waveforms(amplitude = "signal", level = "epoch",
#                         t0 = 10)
# dataE59 |>
#   dplyr::filter(subject == 2) |>
#   interactive_waveforms(amplitude = "signal", level = "epoch",
#                         t0 = 10)

## -----------------------------------------------------------------------------
subjects_base <- epochdata |>
  pick_data(epoch_rg = 1:13) |>
  baseline_correction(baseline_range = 1:10)

## -----------------------------------------------------------------------------
subjects_mean <- subjects_base |>
  dplyr::filter(time == 35) |>
  compute_mean(amplitude = "signal_base", domain = "space",
               level = "epoch", R = 1000)

## -----------------------------------------------------------------------------
# prepare a mesh for plotting
M <- point_mesh(dimension = 2, n = 4000, template = "HCGSN256",
                sensor_select = unique(subjects_mean$sensor),
                type = "polygon")
# compute consistent col_range across subjects
# a) find the range of average amplitude
range(subjects_mean$average) 
# -15.634288   8.609518
# b) make the range symmetric
cr_subjects <- c(-16,16)

## -----------------------------------------------------------------------------
# # plot the average topographic maps with the same color range for both subjects
# subjects_mean |>
#   dplyr::filter(subject == 1) |>
#   plot_topo_mean(mesh = M, template = "HCGSN256",
#                  col_range = cr_subjects, contour = TRUE)
# 
# subjects_mean |>
#   dplyr::filter(subject == 2) |>
#   plot_topo_mean(mesh = M, template = "HCGSN256",
#                  col_range = cr_subjects, contour = TRUE)
# 
# # note: the output is not plotted to reduce the vignette file size

## ----fig.show='hold', fig.alt="A top-down topographic map of a high-density EEG amplitude difference of two subjects in red-blue colour scale with contours and black points on sensor locations. The amplitude legend is on the left side of the scalp projection."----
# compute difference
subjects_diff <- subjects_mean |>
  dplyr::group_by(.data$sensor) |>
  dplyr::reframe(
    diff = .data$average[.data$subject == "1"] - .data$average[.data$subject == "2"]
  )
# create colour scale
CS1 <- create_scale(col_range = range(subjects_diff$diff), type = "redblue")
# display the plot: positive difference values (i.e., average for subject 1 higher than for subject 2)
# are displayed in shades of red, negative values in shades of blue
topo_plot(subjects_diff, amplitude = "diff", mesh = M,
          template = "HCGSN256", col_scale = CS1)

