---
title: "Anatomy of an eyeris Object"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Anatomy of an eyeris Object}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

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

## 📦 Key Components

When preprocessing `.asc` EyeLink files with `eyeris`, returned objects will be
of the class `eyeris`, and will contain key components used throughout the
package's backend.

The key components are:

- `file`: the original file path of the source `.asc` file
- `timeseries`: a list of data frames (1 df per identified recording block per file) which contains the following columns:
  - `block`: block number
  - `time_orig`: raw tracker time (ms)
  - `time_secs`: normalized tracker time, starting at 0 (seconds)
  - `eye_x`: eye position x-coordinate
  - `eye_y`: eye position y-coordinate
  - `eye`: which eye (Left or Right) the recorded data are sourced from
  - `hz`: tracker sampling rate (hz)
  - `type`: whether source data were recorded using the `diameter` or `area` method
  - `pupil_raw`: raw recorded pupil source data in arbitrary units (a.u.) 

You'll notice that for each preprocessing step run, a new column will be added after
the `pupil_raw` column; these new columns follow a structure where each subsequent
step is appended to the previous columns name 
(i.e., `pupil_raw_{previous steps}_{current_step}`). To illustrate:

  - `pupil_raw` -> `pupil_raw_deblink` -> `pupil_raw_deblink_detransient` -> and so on...
  
- `events`: a list of data frames containing trial event messages and timestamps
- `blinks`: a list of data frames containing start/stop/durations for blinks
- `info`: EyeLink EDF header data parsed into a data frame
- `latest`: internal tracker used for assessing which steps have been run so far
- `confounds`: a list of data frames containing confounding variables for each preprocessing step (see: 📊 `summarize_confounds()`)
- `params`: detailed list of steps run and parameters passed to each step
- `epoch_{name}`: list of data frames for any given epoched timeseries

<div class="alert alert-light">
💡 <strong>Note:</strong> This vignette describes the structure of an `eyeris` object as returned by the main preprocessing pipeline.

1. Understanding these components will help you interpret results, debug issues, and extend the pipeline for your own research needs. 

2. Furthermore, binocular data will have a `left` and `right` component to the `eyeris` object, which will contain the same components as the main `eyeris` object. 

3. There is also a phantom `raw_binocular_object` component to the `eyeris` object, which contains the raw binocular data used internally to perform the binocular correlation analysis and plotting.
</div>

Now that we've explained what you can expect to see after running the `eyeris`
`glassbox()` function, we'll demonstrate what the `glassbox()` wrapper is
generally comprised of in terms of the steps and defaults that are implemented.

## 🧱 Building Blocks Under the Hood

While we strongly recommend against manually constructing the pipeline as will
be shown below (given that using the `glassbox()` will provide maximum
opportunities for reproducibility and reduction of accidental errors), more
advanced users may want to see how the individual steps can be used like
building blocks to iteratively test out parameters, switch steps around / remove
steps
(**_again, we strongly recommend against doing this unless you know what_**
**_you're doing_**), etc.

### The Default `glassbox()` Steps and Parameters, Deconstructed:

The chunk below is the **complete, end-to-end reference pipeline**. It reproduces
the default `glassbox()` recipe step-by-step, with every `eyeris` preprocessing
function chained together exactly as the wrapper calls them internally. Use it as
a copy-paste template whenever you need to inspect, reorder, or swap out
individual steps (e.g., during parameter optimization):

```{r, eval=FALSE}
system.file("extdata", "memory.asc", package = "eyeris") |>
  eyeris::load_asc(block = "auto") |>
  eyeris::deblink(extend = 50) |>
  eyeris::detransient(n = 16) |>
  eyeris::interpolate() |>
  eyeris::lpfilt(wp = 4, ws = 8, rp = 1, rs = 35, plot_freqz = TRUE) |>
  # eyeris::downsample(target_fs = 100) |>  # optional (read docs before enabling)
  # eyeris::bin(bins_per_second = 10) |>  # optional (read docs before enabling)
  # eyeris::detrend() |>  # optional (read docs before enabling)
  eyeris::zscore() |>
  eyeris::summarize_confounds()
```

Each line above maps directly to one exported preprocessing function. Click any
function below to jump to its help page, where you'll find its parameters and a
worked example:

| Step | Function | What it does |
|------|----------|--------------|
| 1. Load | `eyeris::load_asc()` | Parse the raw `.asc` file into an `eyeris` object |
| 2. Deblink | `eyeris::deblink()` | NA-pad samples surrounding blink artifacts |
| 3. Detransient | `eyeris::detransient()` | Remove physiologically implausible jumps |
| 4. Interpolate | `eyeris::interpolate()` | Linearly fill in missing samples |
| 5. Lowpass filter | `eyeris::lpfilt()` | Smooth the pupil time series |
| _(optional)_ Downsample | `eyeris::downsample()` | Decimate to a lower sampling rate (anti-aliased) |
| _(optional)_ Bin | `eyeris::bin()` | Average samples within fixed time bins |
| _(optional)_ Detrend | `eyeris::detrend()` | Remove a linear trend from the time series |
| 6. Z-score | `eyeris::zscore()` | Standardize to mean 0 and SD 1 |
| _(summary)_ Confounds | `eyeris::summarize_confounds()` | Tabulate per-step data-quality metrics |

<div class="alert alert-light">
💡 <strong>Note:</strong> <code>downsample()</code> and <code>bin()</code> are
mutually exclusive (enable at most one), and <code>detrend()</code> is disabled
in the default <code>glassbox()</code> recipe. See each function's help page for
guidance before enabling these optional steps.
</div>

<div class="alert alert-light" style="padding-bottom: 0;">
  💡 **For more detailed information on the implementation of functions within**
     **the `glassbox()` and thus how to create your own custom pipeline**
     **extensions that conform to the `eyeris` protocol, see the:**
     [🧩 Building your own Custom Pipeline Extensions vignette](custom-extensions.html).
</div>

---

## 📚 Citing `eyeris`

<div class="alert alert-light" style="padding-bottom: 0;">
  If you use the `eyeris` package in your research, please cite it!
  
  Run the following in R to get the citation:
</div>

```{r}
citation("eyeris")
```
