---
title: "Read `ephys` data"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Read `ephys` data}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r setup, include = FALSE, echo = FALSE, results='hide'}
# Sys.setenv("IEEGIO_PKGDOWN" = "TRUE")
if (identical(Sys.getenv("IEEGIO_PKGDOWN", unset = ""), "")) {
  knitr::opts_chunk$set(
    collapse = TRUE,
    comment = "#>",
    eval = FALSE
  )
} else {
  knitr::opts_chunk$set(
    collapse = TRUE,
    comment = "#>"
  )
  cache_dir <- tools::R_user_dir("ieegio", "cache")
  dir.create(cache_dir, showWarnings = FALSE, recursive = TRUE)
  cache_dir <- normalizePath(cache_dir, mustWork = TRUE)
  options("ieegio.extract_path", cache_dir)
}
```

`ieegio` supports reading from multiple data formats, such as `EDF(+)/BDF(+)`, `BrainVision`, `BCI2000`, `BlackRock NEV/NSx`. Most of these readers have similar interface.

To start, please load `ieegio`. This vignette uses sample data. Please feel free to replace the sample path with your own data path.

```{r sample}
library(ieegio)
edf_path <- ieegio_sample_data("edfPlusD.edf")
```

Here is a basic example that reads in the sample `EDF` data and creates a `FileCache` object that stores the signals channel-by-channel for fast access:

```{r read_edf}
edf <- read_edf(edf_path, verbose = FALSE)
print(edf)
```

You can check header, channel table, and annotations via the following methods:

```{r edf_methods}
header <- edf$get_header()
str(header)

chan_tbl <- edf$get_channel_table()
print(chan_tbl, nrows = 2, topn = 2)

annot <- edf$get_annotations()
annot
```

You can also query a channel by calling the `get_channel` method.

```{r get_channel}
# get Channel 1
channel <- edf$get_channel(1)
channel
```

A channel can also be looked up by its label instead of its number, which saves
a round trip through the channel table:

```{r get_channel_label}
edf$get_channel("squarewave")
```

The `channel` contains the following elements:

* `type`: a character indicating the original file type;
* `info`: list of basic information such as `Channel` number, `Label`, acquisition `SampleRate`, and `Unit` of the signals;
* `continuous`: a logical value whether the time frames are continuous;
* `time`: a numeric vector of time in seconds for each point;
* `value`: a numeric vector of the signal value, often converted from digital to analog trace.

Using such information, it is straightforward to plot the channel data:

```{r plot_channel}
plot(
  x = channel$time, y = channel$value,
  xlab = "Time", ylab = channel$info$Unit,
  main = channel$info$Label,
  type = "p", pch = ".", col = "green", lwd = 2
)
```



## Writing `EDF` files

To save signals back out, build each channel with `as_edf_channel` and hand the
list to `write_edf`. A channel is either a signal vector or an annotation table:

```{r write_edf}
signal <- sin(seq(0, 10, by = 0.01))

channels <- list(
  as_edf_channel(signal, channel_num = 1,
                 sample_rate = 200, label = "sine"),

  as_edf_channel(
    data.frame(
      timestamp = c(0, 5),
      comments = c("start", "end")
    ),
    channel_num = 2
  )
)

out_path <- tempfile(fileext = ".edf")
write_edf(channels = channels, con = out_path)
```

Reading it back gives the signal and the annotations:

```{r write_edf_verify}
written <- read_edf(out_path, extract_path = tempfile(), verbose = FALSE)
written$get_channel("sine")
written$get_annotations()
```

```{r write_edf_cleanup, echo = FALSE, results='hide'}
written$delete()
unlink(out_path)
```

```{r teardown, echo=FALSE, results='hide'}
cache_dir <- tools::R_user_dir("ieegio", "cache")
if (file.exists(cache_dir)) {
  unlink(cache_dir, recursive = TRUE, force = TRUE)
}
```
