How to create Motion reversal stimulus of certain frequency(GIF samples provided)

Hi PsychoPy community :wave:t2:

Does anyone knows which Stimuls should I use to achieve this:

sample

Also, I need it to have horizontal and vertical motion pattern at specific frequency.

Any comments can be usage to guide me to the right direction. Provide codes to generate and animate stimuli will be great.

What have I done so far

I tried a few visual stimulus from PsychoPy, and I am guessing this is closest to RadialStim. Here is my code.

from psychopy import visual, core, event #import some libraries from PsychoPy

#create a window
mywin = visual.Window([800,600],monitor="testMonitor", units="deg")

#create some stimuli
stim = visual.RadialStim(win=mywin, size=3)

#draw the stimuli and update the window
while True: #this creates a never-ending loop
    stim.draw()
    mywin.flip()

    if len(event.getKeys())>0:
        break
    event.clearEvents()

#cleanup
mywin.close()
core.quit()

This piece of code will draw this stimulus as shown below:

Screenshot 2020-11-04 at 9.10.10 PM

If it is RadialStim, the questions are:

  • how to reduce the size of the inner rectangles? So it looks like the GIF above.
  • how to animate it, to have horizontal and vertical motion pattern at specific frequency

Jingles

Correct.

It isn’t just the size of the inner wedges that is changing: it looks like a non-linear transformation applied to the whole stimulus. You need to be able to define the mathematical form of that transformation if you are to replicate it: hopefully that is specified in the original paper somewhere?

The PsychoPy RadialStim appears to have constant width wedges. I suspect to overcome that, you might need to override one of its functions, like _updateVerticesBase() or _updateTextureCoords() as shown here: https://www.psychopy.org/_modules/psychopy/visual/radial.html#RadialStim._updateVerticesBase (or do something fancier with OpenGL) to define the locations yourself to match what you need. @jon might be able to suggest what the best approach might be. Be warned, this sort of customisation won’t be trivial: you’ll need to understand both the geometry and implement the code.

This bit is simple. You just need to update the .pos attribute of the stimulus on each frame. Look at the demo under the demos menu → stimuli → rotatingFlashingWedge.py

That demo updates the orientation of the stimulus dynamically, which shows the principle of what to do.

Thanks @Michael for your response. It has been helpful. I have reference rotatingFlashingWedge.py.

Correct me if I am wrong. It is not possible to animate smoothly from a visual.RadialStim to another (like the GIF shown above). We can only “flash”, to show this stimulus or to show another. If smooth animate between 2 stimuli configuration is desired, I have to design multiple stimuli for each frame–by tweaking the parameters radialCycles and angularCycles.

No, anything is possible. That example is just that, an example of one thing you can do. e.g. you could instead easily smoothly vary the size of the wedges of a single stimulus dynamically across a series of frames, just as in that example you smoothly vary the orientation.

But RadialStim seems to currently be set up to have each wedge within the stimulus as the same width at any point in time. That is where you would need to get sophisticated, to get variation in wedge widths within the stimulus. Varying across time will be straightforward once you solve that issue.

Think of it as having just one stimulus, but changing its attributes on each frame - don’t get caught up with that particular demo, which shows an alternation between two stimuli. You could delete one of the stimuli in that demo: then you would be seeing a smooth animation of just one stimulus. If you were changing the cycle frequency on each frame rather than the orientation, that would be a linear alternative to the non-linear transformations above. It might be worth doing as a first step to get familiar with basic animation.

1 Like

To have narrower squares you just need to use the angularCycles parameter for the stimulus. (how many cycles around the ring)

To slide the rings in and out you just need to use the radialPhase parameter (between 0 and 1 although then loops around)

1 Like