pulse2percept.stimuli.psychophysics.grating

pulse2percept.stimuli.psychophysics.grating(spatial_freq=1, temporal_freq=0, direction=0, phase=0, contrast=1, fov=10, shape=(256, 256), time=None, mask=None)[source]

Sinusoidal grating

Rasterize a sinusoidal luminance grating of a given spatial frequency, drift rate, and direction, and place it in a Scene.

The gray level at visual-field coordinate (x, y) and time t is 0.5 + contrast / 2 * cos(2 pi fs u - 2 pi ft t + phase), where u = x cos(direction) + y sin(direction) is the distance along the drift axis in dva, fs is spatial_freq in cycles/dva, and ft is temporal_freq in Hz. The pattern therefore drifts along direction at temporal_freq / spatial_freq dva/s.

Added in version 0.11.0.

Parameters:
  • spatial_freq (float or Quantity, optional) – Spatial frequency in cycles per degree of visual angle (e.g. 2 / dva). One cycle is 1 / spatial_freq dva wide, whatever shape is. Its components along x and y must both stay strictly below the Nyquist frequency of the corresponding angular pixel pitch.

  • temporal_freq (float or Quantity, optional) – Drift rate in Hz (e.g. 4 * Hz), non-negative: direction alone says which way the grating drifts. 0 leaves the pattern static; any other rate requires time.

  • direction (float or Quantity, optional) – Drift direction, in degrees counterclockwise from the positive x axis (e.g. 90 * deg): 0 right, 90 up, 180 left, 270 down. The bars run perpendicular to it, so direction=0 gives vertical bars drifting rightwards.

  • phase (float or Quantity, optional) – Spatial phase in degrees, at fixation and at t = 0. 0 puts a luminance peak at the center of the frame.

  • contrast (float, optional) – Michelson contrast in [0, 1] around mean gray 0.5: the pattern spans 0.5 +/- contrast / 2.

  • fov (float or (width, height), optional) – How much of the visual field the scene covers, in dva. A scalar is the horizontal extent, and the vertical one follows from shape.

  • shape ((rows, cols), optional) – Size of the rasterized frame, in pixels. Raster resolution only: it does not enter the spatial frequency.

  • time (array_like or None, optional) – Sample times in ms (e.g. np.arange(0, 500, 10)), which the scene’s source carries as a VideoStimulus. None gives a static ImageStimulus instead, and is only allowed when temporal_freq is 0. There is no default frame rate, so a scalar duration is rejected. Consecutive samples must advance the drift by less than half a temporal cycle.

  • mask ({'gauss', 'circle', None}, optional) –

    Radial aperture applied to the pattern, which fades to mean gray outside it. Isotropic in dva and centered on fixation:

    • 'gauss': a 2D Gaussian whose 3rd standard deviation lies at the aperture radius

    • 'circle': the largest circle that fits into fov

    • None: no aperture

Returns:

scene

Return type:

Scene

Examples

A static 2 cycles/dva grating across 10 degrees:

>>> from pulse2percept.stimuli import psychophysics
>>> from pulse2percept.units import dva
>>> scene = psychophysics.grating(spatial_freq=2 / dva, fov=10 * dva)
>>> type(scene.source).__name__
'ImageStimulus'

The same grating drifting upwards at 4 Hz, sampled every 10 ms:

>>> import numpy as np
>>> from pulse2percept.units import deg, Hz
>>> scene = psychophysics.grating(spatial_freq=2 / dva,
...                               temporal_freq=4 * Hz,
...                               direction=90 * deg, fov=10 * dva,
...                               time=np.arange(0, 500, 10))
>>> type(scene.source).__name__
'VideoStimulus'