On 29/12/2010 02:30, Alex Holcombe wrote:
> Dear Psychopyers,
>
> I need to create two rotating radial red-green (or blue-yellow, etc.)
> grating annuli, like shown here:
> http://www.psych.usyd.edu.au/staff/alexh/research/trackingPairing/radialMulticoloredGratings.png
> Actually, even better than alternating between two colors as shown in
> the picture, would instead be to alternate among three colors, e.g.
> red-green-blue as one goes around the circle. However, I'd settle for
> two colors.
To create a 3-color progression you would need to create a 256x256x3
numpy array of your colour sequence and pass that to the RadialStim as a
texture, but right now it doesn't support that (PatchStim does, and I
should be able to make this possible in Radial too).
> The drawing must be fast, so that I can update the two annuli at 120
> Hz. How should I do this in PsychoPy?
> I see two solutions, but each has possible stumbling blocks I need
> help with:
>
> 1. Use RadialStim with tex='sqr', and mask the inner part to create an
> annulus. I can set the color of one patch using RadialStim's *color*
> parameter, however, the other color cannot be chosen, but rather is
> created essentially by multiplying -1 by the RGB value of the *color*.
> For example, if color=[1,-1,-1] and contrast=1, then the other color
> appears to be cyan (-1,1,1). Is there a way to control the other
> color, perhaps by creating a custom texture?
To create two different colors you should just create two separate stimuli::
#!/usr/bin/env python
from psychopy import visual, event, core
globalClock = core.Clock()
win = visual.Window([800,800])
#make two wedges (in opposite contrast) and alternate them for flashing
ring1 = visual.RadialStim(win, tex='sqrXsqr', color=[-1,-1,1],size=1,
mask=[0,0,1,1,0,0,0,0,0,0,], radialCycles=0, angularCycles=8,
interpolate=False)
ring2 = visual.RadialStim(win, tex='sqrXsqr', color=[1,-1,-1],size=1,
mask=[0,0,0,0,0,0,1,1,0,0,], radialCycles=0, angularCycles=8,
interpolate=False)
t=0
rotationRate = 0.01 #revs per sec
while t<5:#for 5 secs
t=globalClock.getTime()
ring1.setOri(t*rotationRate*360.0)
ring1.draw()
ring2.setOri(-t*rotationRate*360.0)
ring2.draw()
win.flip()
win.close()
> Second possible problem: the documentation for RadialStim says "it
> also takes longer to draw than a typical PatchStim, so not recommended
> for tasks where high frame rates are needed."
>
Suck it and see - check your frame times for the code above. Radial
stimuli draw a large number of triangles, approximating a circle. This
is done in an efficient manner though with nearly all the calculations
being done on the graphics card if it supports opengl 2. Yes, because
the gfx card is doing the calculations it will make a difference having
a good one, but I'd be surprised if you need one as fancy as $1200!
> 2. Use visual.PatchStim with a custom 256x256x3 arraytexture, a la
> customTextures.py demo. I suppose that this method can allow the
> creation of arbitrary stimuli, including my multicolored annuli.
> However, I presume that this routine is not fast enough to support
> high frame rates?
>
If you're creating the stimulus just once and rotating it unchanged then
this could work, because you won't need to call the texture creation
code. But the code will be less intuitive (a circular image in a square
texture) and if you do anything that requires a new texture (e.g. a
change in radial SF) you'll possibly drop a frame during the update.
Basically, I think the radialstim will allow you more options as your
experiment evolves, provided the card does the drawing fast enough.
All the best,
Jon
--
Dr. Jonathan Peirce
Nottingham Visual Neuroscience
On 29/12/2010 02:30, Alex Holcombe wrote:
> Dear Psychopyers,
>
> I need to create two rotating radial red-green (or blue-yellow, etc.)
> grating annuli, like shown here:
> http://www.psych.usyd.edu.au/staff/alexh/research/trackingPairing/radialMulticoloredGratings.png
> Actually, even better than alternating between two colors as shown in
> the picture, would instead be to alternate among three colors, e.g.
> red-green-blue as one goes around the circle. However, I'd settle for
> two colors.
I was wrong - I had already implemented the option to provide an rgb
(NxNx3) array to the RadialStim. I've updated the docs to reflect that,
but the below shows you how too. Beware to set the color to [1,1,1] if
you're setting an rgb array as the texture::
#!/usr/bin/env python
#rotate flashing wedge
from psychopy import visual, event, core
import numpy as np
#create texture (note imperfect rounding of 64/3)
rgb = np.zeros([64,64,3])-1#start with all channels in all locs = -1
rgb[:, 0:(64/3), 0]=1 #bottom 1/3rd of the first channel=1
rgb[:, (64/3):(64*2/3), 1]=1 #middle 1/3rd of the 2nd channel=1
rgb[:, (64*2/3):(64*3/3), 2]=1 #top 1/3rd of the 3rd channel=1
globalClock = core.Clock()
win = visual.Window([800,800])
#make two wedges (in opposite contrast) and alternate them for flashing
ring1 = visual.RadialStim(win, tex=rgb, color=[1,1,1],size=1,