---
title: "Using Custom Methods"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Using Custom Methods}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

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

You can pass a custom function to the `extract_saccades()` alongside the internally implemented method. The function must be declared as follows:
```{r eval = FALSE}
custom_saccade_voting_method <- function(x,
                                         y,
                                         vel,
                                         acc,
                                         sample_rate,
                                         trial,
                                         options) {
                                         
  # implement you method that computes a 0/1 vote per sample
  
  sample_votes
}
```

Arguments that are passed to the function (all vectors/tables have the same length/number of rows):

* `x`, `y` vectors with _monocular_ samples (either for one of the eyes or cyclopean). On the one hand, you can assume that samples are in degrees of visual angle as the package users are warned that using non-standard units may invalidate some internally implemented methods. On the other hand, as you are implementing a custom method for your own data, you can treat them in the units you see fit (input vectors `x` and `y` are not transformed but for averaging in case of cyclopean data).
* `vel` and `acc` are data frames with velocity and acceleration samples. Each table has columns `x` (horizontal component), `y` (vertical component), and `amp` (amplitude). See below for details on velocity computation.
* `sample_rate` scalar value in Hz.
* `trial` vector with trial index per sample.
* `options` a named list with method-specific options. See the example below for how to use them. See also `option_or_default()` function.

Your function must return a vector of the same length as `x` with votes ($1$ if sample is a potential saccade, $0$ otherwise, you can also use logical values).

## Example implementation
Here is an example implementation of an overly simple custom method that labels a sample as a saccade if its velocity exceeds a predefined threshold. It expects the threshold parameter as `"st_velocity_threshold"` member of the list and uses a default threshold of $50 \deg / s$ (an arbitrary number!) if no threshold was provided.

```{r eval = FALSE}
simple_threshold_method <- function(x,
                                    y,
                                    vel,
                                    acc,
                                    sample_rate,
                                    trial,
                                    options) {

  # obtain method parameters or use defaults
  velocity_threshold <- saccadr::option_or_default(options, "st_velocity_threshold", 50)

  # vote on each sample  
  sample_vote <- vel[['amp']] > velocity_threshold
  
  # return votes
  sample_vote
}
```

Once you implemented your method, you can pass it alongside internally implemented methods:
```{r eval=FALSE}
data("single_trial")
saccades <- saccadr::extract_saccades(x = single_trial$x,
                                      y = single_trial$y,
                                      sample_rate = 500,
                                      methods = list("ek", "om", "nh", simple_threshold_method),
                                      options = list("st_velocity_threshold" = 70))
```


