---
title: "Frequency analysis"
author: "Matt Craddock"
date: "`r Sys.Date()`"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Frequency analysis}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r setup, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
```


Periodicity is commonly observed in EEG signals. For example, oscillations in the alpha frequency range (approximately 8-13 Hz) were one of the first signals observed in the human EEG. One method of analysing this periodicity is to calculate the Power Spectral Density using a method such as Welch's FFT.

## Frequency analysis

In `eegUtils`, this can be achieved using `compute_psd()` and `plot_psd()`. With epoched data, `compute_psd()` calculates the PSD for each trial separately. `compute_psd()` returns a `data.frame` with spectral power at each resolved frequency and for each electrode. Note that `plot_psd()` can be called directly on `eeg_data` or `eeg_epochs` objects without first having to `compute_psd()`. With epoched data, it will compute the PSD for each epoch and then average over epochs before plotting.

```{r create-psd}
library(eegUtils)
demo_psd <- compute_psd(demo_epochs)
plot_psd(demo_epochs)
```


## Time-frequency analysis

Frequency analysis necessarily discards temporal information. One problem is that it assumes stationarity - that the signal remains stable in terms of frequency and power across the whole analysed time window. However, this is rarely the case with EEG data, which exhibits dynamics across a wide range of timescales.

Time-frequency analysis is a method of accounting for non-stationarity by decomposing the signal using a moving-window analysis, tiling the time-frequency space to resolve power over relatively shorter time-windows.

In `eegUtils`, `compute_tfr()` can be used to calculate a time-frequency representation of `eeg_epochs()`. Currently, this is achieved using Morlet wavelets. Morlet wavelets are used to window the signal, controlling spectral leakage and time-frequency specificity. Morlet wavelets have a user-defined temporal extent, which in turn determines the frequency extent. We define the temporal extent of our wavelets by **cycles**; we define it as an integer number of cycles at each frequency of interest.

```{r calc-tfr}
demo_tfr <- compute_tfr(demo_epochs,
                        method = "morlet",
                        foi = c(4, 30),
                        n_freq = 12,
                        n_cycles = 3)
demo_tfr
```

Note that the characteristics of the wavelets, in terms of temporal and frequency standard deviations, are stored inside the `eeg_tfr` object:

```{r morlet-res}
demo_tfr$freq_info$morlet_resolution
```

The results of the time-frequency transformation can be plotted using the `plot_tfr()` function.

```{r tfr-plot}
plot_tfr(demo_tfr)
```

Baseline correction is common in the literature, which can serve two purposes. Several different methods are possible. both for plotting only, and as a modification to the `eeg_tfr` object using `rm_baseline()`.

```{r db-plot}
plot_tfr(demo_tfr, baseline_type = "absolute", baseline = c(-.1, 0))
plot_tfr(demo_tfr, baseline_type = "db", baseline = c(-.1, 0))
```


