---
title: "Getting started with rcicr"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Getting started with rcicr}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

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

`rcicr` implements **reverse correlation image classification**, a technique from
psychophysics for visualizing internal mental representations (for example, of faces).
It works in two stages:

1. **Stimulus generation**: a base image (e.g. a face photo) is combined with random
   visual noise to create pairs of stimuli — an "original" and its pixel-inverted
   counterpart — for a two-image-forced-choice (2IFC) task. Participants pick, on each
   trial, whichever of the pair looks more like some target category (e.g. "trustworthy",
   "happy").
2. **Classification image (CI) computation**: after data collection, the noise patterns
   from stimuli where the participant chose the "original" are averaged together (and
   subtracted for stimuli where the "inverted" version was chosen). The result — the
   classification image — visualizes which visual features were systematically
   associated with the participant's choices.

This vignette walks through both stages using a tiny synthetic example. For the full
treatment — several participants, scaling choices, z-maps and informational value —
see `vignette("reverse-correlation-walkthrough", package = "rcicr")`. For example
datasets and analysis scripts, see
[rcicr_examples](https://github.com/rdotsch/rcicr_examples/).

```{r setup}
library(rcicr)
```

## 1. Generate stimuli

`generateStimuli2IFC()` needs a square base image. Here we generate a synthetic
grayscale image instead of using a real photo, purely so this vignette is
self-contained; in a real study you would pass the path to your base face photo(s)
instead.

```{r generate-base-face}
set.seed(42)
base_face_path <- tempfile(fileext = ".png")
png::writePNG(matrix(runif(64 * 64), 64, 64), base_face_path)
```

Now generate stimuli for a small task: 20 trials, one base image, at a small image
size (kept small here so the vignette builds quickly — a real study would typically
use `img_size = 512` and several hundred trials, following Dotsch & Todorov, 2012).

```{r generate-stimuli, results = "hide"}
stimulus_path <- tempdir()

generateStimuli2IFC(
  base_face_files = list(face = base_face_path),
  n_trials        = 20,
  img_size        = 64,
  stimulus_path   = stimulus_path,
  seed            = 1,
  ncores          = 1,
  save_as_png     = FALSE # set to TRUE to also write stimulus PNGs to stimulus_path
)

rdata_file <- list.files(stimulus_path, pattern = "\\.Rdata$", full.names = TRUE)[1]
```

This writes an `.Rdata` file to `stimulus_path` containing the random noise parameters
used for every trial. **That file is the only link between stimulus generation and
CI computation** — keep it, since every analysis function below needs it via the
`rdata` argument.

## 2. Collect (or, here, simulate) responses

In a real experiment, this is where you would run the 2IFC task and record which
image (original = `1`, inverted = `-1`) each participant chose on each trial. Since
this vignette has no real participant, we simulate random responses instead — a real
analysis would never do this, as random responding contains no signal and yields an
uninformative classification image.

```{r simulate-responses}
responses <- sample(c(1, -1), 20, replace = TRUE)
```

## 3. Compute the classification image

`generateCI()` looks up the noise parameters for the stimuli that were shown, weights
them by the responses, and averages them into a single classification image.

```{r compute-ci}
ci <- generateCI(
  stimuli     = 1:20,
  responses   = responses,
  baseimage   = "face",
  rdata       = rdata_file,
  save_as_png = FALSE
)

names(ci)
```

`ci$ci` is the raw noise, `ci$scaled` is that noise rescaled for display (see
`?generateCI` for the available scaling methods — the default, `'independent'`,
picks the lowest scaling constant that avoids clipping this particular image), and
`ci$combined` overlays the scaled noise on the base image.

```{r plot-ci}
image(ci$combined, col = gray.colors(256), axes = FALSE, asp = 1)
```

Because the responses above were random rather than real data, this classification
image is just noise — with real experimental data, systematic patterns tied to
participants' choices would emerge here instead.

## Next steps

- `batchGenerateCI()` / `batchGenerateCI2IFC()` compute one CI per participant or
  condition from a data frame, optionally followed by `autoscale()` to rescale a whole
  batch of CIs consistently so they stay visually comparable.
- `computeInfoVal2IFC()` computes an "Informational Value" (a z-score-like measure of
  how much signal is in a CI) by comparing it to a simulated null distribution.
- `plotZmap()` visualizes which regions of a CI carry statistically reliable signal.

See each function's help page (e.g. `?generateCI`, `?batchGenerateCI`) for further
options and runnable examples.
