---
title: HRF Generators
author: Bradley R. Buchsbaum
date: '`r Sys.Date()`'
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{HRF Generators}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
params:
  family: red
  preset: homage
css: albers.css
resource_files:
- albers.css
- albers.js
includes:
  in_header: |-
    <script src="albers.js"></script>
    <script>document.addEventListener('DOMContentLoaded',function(){document.body.classList.add('palette-red');});</script>

---

```{r setup, include = FALSE}
if (requireNamespace("ggplot2", quietly = TRUE)) ggplot2::theme_set(ggplot2::theme_minimal())
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>",
  fig.width = 7,
  fig.height = 5,
  message = FALSE,
  warning = FALSE
)
library(fmrihrf)
library(ggplot2)
library(dplyr)
library(tidyr)
```

## Why Generators?

Most pre-defined HRFs in `fmrihrf` (like `HRF_SPMG1` or `HRF_GAUSSIAN`) are ready-to-use objects.
However, some HRFs are actually *generators*. A generator is a function that
creates a new HRF object when you call it. This allows you to specify the number
of basis functions (`nbasis`) and the time span (`span`) at creation time.

The library provides generators for flexible basis sets such as B-splines and
finite impulse response (FIR) models. They are available through the internal
`HRF_REGISTRY` and are also returned by `list_available_hrfs()` with type
"generator".

```{r list-generators}
list_available_hrfs(details = TRUE) %>%
  dplyr::filter(type == "generator")
```

## Creating a Basis with a Generator

To obtain an actual HRF object from a generator, simply call the generator
function with your desired parameters. For example, to create a B-spline basis
with 8 functions spanning 32 seconds:

```{r create-basis}
# Create a B-spline basis using gen_hrf
bs8 <- gen_hrf(hrf_bspline, N = 8, span = 32)
print(bs8)
```

The returned value is a standard `HRF` object, so you can evaluate it or use it
in model formulas like any other HRF.

```{r eval-basis}
times <- seq(0, 32, by = 0.5)
mat <- bs8(times)
head(mat)
```

## Visualising FIR Basis Functions

Here is a quick look at an FIR basis generated with 10 bins over a 20 second
window:

```{r fir-basis}
# Use the pre-defined FIR basis or create one with gen_hrf
fir10 <- HRF_FIR  # Pre-defined FIR with 12 basis functions
resp <- fir10(times)

fir_df <- data.frame(Time = times, resp)
fir_long <- tidyr::pivot_longer(fir_df, -Time)

ggplot(fir_long, aes(Time, value, colour = name)) +
  geom_line(linewidth = 1) +
  labs(title = "Finite Impulse Response Basis",
       x = "Time (s)", y = "Response") +
  theme_minimal() +
  theme(legend.position = "none")
```

<!-- ## Using `getHRF`

The helper `getHRF()` is an internal function that selects either a pre-defined object or a generator based on
name. This functionality is not exposed in the public API.

```{r gethrf, eval=FALSE}
# Internal usage only:
# custom_fir <- getHRF("fir", nbasis = 6, span = 18)
# custom_fir
``` -->

## Summary

Generator functions are simple factories that let you customise flexible HRF
bases. They return normal `HRF` objects, which means you can evaluate them,
combine them with decorators, or insert them into regressors just like the
built-in HRFs.
