# Source code for psychopy.visual.filters

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""Various useful functions for creating filters and textures
(e.g. for PatchStim)
"""

# Part of the PsychoPy library
# Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2022 Open Science Tools Ltd.

import numpy
from numpy.fft import fft2, ifft2, fftshift, ifftshift

[docs]def makeGrating(res, ori=0.0, # in degrees cycles=1.0, phase=0.0, # in degrees gratType="sin", contr=1.0): """Make an array containing a luminance grating of the specified params :Parameters: res: integer the size of the resulting matrix on both dimensions (e.g 256) ori: float or int (default=0.0) the orientation of the grating in degrees cycles:float or int (default=1.0) the number of grating cycles within the array phase: float or int (default=0.0) the phase of the grating in degrees (NB this differs to most PsychoPy phase arguments which use units of fraction of a cycle) gratType: 'sin', 'sqr', 'ramp' or 'sinXsin' (default="sin") the type of grating to be 'drawn' contr: float (default=1.0) contrast of the grating :Returns: a square numpy array of size resXres """ # to prevent the sinusoid ever being exactly at zero (for sqr wave): tiny = 0.0000000000001 ori *= -numpy.pi / 180. phase *= numpy.pi / 180. cyclesTwoPi = cycles * 2.0 * numpy.pi xrange, yrange = numpy.mgrid[ 0.0:cyclesTwoPi:(cyclesTwoPi / res), 0.0:cyclesTwoPi:(cyclesTwoPi / res)] sin, cos = numpy.sin, numpy.cos if gratType == "none": res = 2 intensity = numpy.ones((res, res), float) elif gratType == "sin": intensity = contr * sin(xrange * sin(ori) + yrange * cos(ori) + phase) elif gratType == "ramp": intensity = contr * (xrange * cos(ori) + yrange * sin(ori)) / (2 * numpy.pi) elif gratType == "sqr": # square wave (symmetric duty cycle) intensity = numpy.where(sin(xrange * sin(ori) + yrange * cos(ori) + phase + tiny) >= 0, 1, -1) elif gratType == "sinXsin": intensity = sin(xrange) * sin(yrange) else: # might be a filename of an image # try: # im = Image.open(gratType) # except Exception: # logging.error("couldn't find tex...", gratType) # return # # todo: opened it, now what? raise ValueError("Invalid value for parameter `gratType`.") return intensity