Skip to contents

Generate stimuli for a two-image forced-choice reverse correlation task.

Usage

generateStimuli2IFC(
  base_face_files,
  n_trials = 770,
  img_size = 512,
  stimulus_path,
  label = "rcic",
  use_same_parameters = TRUE,
  seed = 1,
  maximize_baseimage_contrast = TRUE,
  noise_type = "sinusoid",
  nscales = 5,
  sigma = 25,
  ncores = default_ncores(),
  return_as_dataframe = FALSE,
  save_as_png = TRUE,
  save_rdata = TRUE
)

Arguments

base_face_files

Named list of base image files, e.g. list(aName = 'baseface.jpg'). JPEG and PNG images are accepted, recognised by a .png, .jpg or .jpeg extension. Each name labels that base image's stimulus files and is the key generateCI uses to find it in the .Rdata file, so every element needs a unique name. Each image must be square and exactly img_size pixels wide: rcicr does not resize base images. All of this is checked before any stimuli are generated, and an error names the offending entry.

n_trials

Number of trials. Each trial gets two images per base image: one with the noise added (original) and one with it subtracted (inverted).

img_size

Width and height of the square stimulus images, in pixels. It must be divisible by 2^(nscales - 1), because the finest scale tiles the image with that many patches per side.

stimulus_path

Directory to save the stimuli and the .Rdata file to. Required unless both save_as_png and save_rdata are FALSE; there is no default. The directory is created if it does not exist; to just try the function out, use tempdir().

label

Label put at the start of each file name.

use_same_parameters

Boolean: all base images share one set of noise parameters (TRUE) or each gets its own (FALSE).

seed

Seed for the random number generator, for reproducibility. It is saved in the .Rdata file with the session's RNGkind(), and the default InfoVal reference replays it under that kind. With seed = NULL there is nothing to replay, so InfoVal references for that file need an explicit response_seed. The caller's own random stream is left as it was: the next random number drawn after this call is the one that would have been drawn without it.

maximize_baseimage_contrast

Boolean: rescale the base image's pixel values to maximize its contrast. A base image with no contrast at all, every pixel the same value, cannot be rescaled and is rejected with an error. It can still be used with maximize_baseimage_contrast = FALSE.

noise_type

Noise pattern type: sinusoid (default) or gabor.

nscales

Number of spatial scales (default: 5). Each additional scale adds a higher spatial frequency. img_size must be divisible by 2^(nscales - 1).

sigma

Sigma of the Gabor patches when noise_type = 'gabor' (default: 25).

ncores

Number of CPU cores to use (default: detectCores() - 1; 2 under R CMD check, per CRAN policy). Each core runs a worker holding its own copy of the noise basis and a render's working memory: 0.8 to 1 GB per worker at 512 pixels in https://github.com/rdotsch/rcicr/blob/main/analyses/worker-memory.md. No more workers start than there are trials.

return_as_dataframe

Boolean: return a data frame with the raw noise of the generated stimuli (default: FALSE), one row per pixel and one column per trial. With the default use_same_parameters = TRUE every base image shares the same noise, so that is all of it. With use_same_parameters = FALSE and more than one base image, only the first base image's noise is returned, because one column per trial cannot hold several. The stimuli are still written for every base image, and save_rdata = TRUE records every parameter set, so nothing is missing from the files.

save_as_png

Boolean: write the stimuli to disk as PNG images (default: TRUE). They are named <label>_<base label>_<seed>_<trial>_ori.png and _inv.png, with no time, so a later call into the same folder with the same label, base label and seed would write the same names. Existing PNGs are never overwritten: the call stops before generating or writing anything, and also stops when two base labels name the same file on this file system (for example, labels differing only in case). Use a different label or stimulus_path, or, to regenerate a stimulus set on purpose, delete its PNGs and its .Rdata file first. While PNGs are being written, a second call into the same folder with the same seed stops.

save_rdata

Boolean: save the .Rdata file with the stimulus parameters (default: TRUE). Computing classification images needs that file, so keep this TRUE; the argument exists mainly for internal use. The file is named <label>_seed_<seed>_time_<month>_<day>_<year>_<hour>_<minute>.Rdata, for the minute the call started. An existing file of that name is never overwritten: the call stops before generating anything. So does a call into the same folder with the same seed, started in the same minute, while another is still running.

Value

Nothing: everything is saved to files. vignette("stored-data", package = "rcicr") lists what the .Rdata file holds. With return_as_dataframe = TRUE, the data frame described there.

Details

Saves the stimuli as PNGs, together with an .Rdata file holding the parameters used to generate each stimulus. Analysing the responses later requires that file.

See also

vignette("getting-started", package = "rcicr") for the shortest working example; vignette("reverse-correlation-walkthrough", package = "rcicr"), section "Generating stimuli", for choosing the settings; vignette("recipes", package = "rcicr"), "Noise-only stimuli", for stimuli without a face.

Examples

# a synthetic square grayscale image stands in for a real base face photo
base_face <- tempfile(fileext = ".png")
png::writePNG(matrix(runif(32 * 32), 32, 32), base_face)

generateStimuli2IFC(
  base_face_files = list(face = base_face),
  n_trials = 4,
  img_size = 32,
  stimulus_path = tempfile("stimuli"),
  seed = 1,
  ncores = 1,
  nscales = 1
)
#> 
  |                                                                            
  |                                                                      |   0%
  |                                                                            
  |==================                                                    |  25%
  |                                                                            
  |===================================                                   |  50%
  |                                                                            
  |====================================================                  |  75%
  |                                                                            
  |======================================================================| 100%