Hi,
For the purpose of mapping out the retinotopy of visual cortex with fMRI I’m trying to implement a rotating checkerboard stimulus in MWorks (see attachment for a static and Methods; Schmid Lab; Newcastle University for an animated example).
I looked at the DriftingGrating and DynamicDots stimuli and tried to dive into OpenGL but now I am a little stuck. Since the radial checkerboard pattern that we would like to use contains curved lines an implementation with only OpenGL primitives (drawing polygons) seems a little difficult to me. Is that true or am I missing something?
I thought then that a good solution could be to use a fragment shader. For that, is there MWorks functionality I could make use of? I saw the discussion in MWorks: Discussion and looked at Bram’s plugin. Would something like that still be the way to go for a shader-based stimulus?
I’d be happy about any help.
Best,
Joscha
Attachment: wtDSN.png (26.9 KB)
Hi Joscha,
A shader would certainly work. MWorks doesn’t have any built-in support for shader-based stimuli, so you’d have to handle all the details yourself. (Be aware that if you aren’t already familiar with shader development, the learning curve is pretty steep.)
Do all the bands of the checkerboard rotate with the same rate and direction? If so, then another, easier option would be to dynamically generate a texture (for example, using Quartz 2D) and then rotate it to create the animation.
Depending on your exact requirements, there may be other options. Can you tell me more about how you want the stimulus to function?
Cheers,
Chris Stawarz
Hi Chris,
Thanks for the feedback.The bands should indeed all rotate with the same rate and direction. In addition we would like to be able to mask parts of checkerboard to create annuli and wedges.
I’ll look into the Quartz option next week. Do you have advice on how to use it with MWorks?
Thanks again,
Joscha
Hi Chris,
For now, I think it would make sense for me to just create a RotatingImage class that loads a picture and rotates it at a certain speed (I’m used to Matlab/Python and can easily create the picture there, but not yet with Quartz).
Do you think I should start from the ImageStimulus class in mworks/core/Core/Stimuli/StandardStimuli.cpp?
Is there a reason why the ImageStimulus class does not (yet) make use of the ROTATION property of the parent class BasicTransformStimulus?
Cheers and thanks,
Joscha
Hi Joscha,
Image stimuli do support rotation. If you’re willing to pre-generate your checkerboard patterns, then you can use an image stimulus together with a frame list stimulus to achieve smooth rotation.
The attached example experiment and associated image (just a modified version of your example image) demonstrate how to do this. Here are the key points:
- The frame list has
loop
and autoplay
set to YES
.
- The stimulus group defining the frame list’s frames contains only the image stimulus.
- The image stimulus’
rotation
parameter is an expression that depends on the current time and the deg_per_sec
variable.
- The frame list is live queued, so the image will re-evaluate the rotation expression each time it draws itself (i.e. every frame).
This approach has the great advantage of not requiring a new stimulus type, which will save you some time. If you have any questions, please let me know.
Cheers,
Chris
Hi Chris,
This is perfect, thanks so much. I didn’t check whether changing the rotation property actually did something because it’s not available in the custom inspector view. I still have some questions though:
- How is the scaling actually done (algorithm)? Is there a way to present images as they are without scaling?
- To create an annulus or ring, can you think of an easy way for masking the outer part? For the inner part I would just overlay a circle with the background color (see attachment). If no, I’ll just generate the image at the right size.
Thanks again,
Joscha
Hi Joscha,
How is the scaling actually done (algorithm)?
Images are mipmapped. The exact function used is ilutGLBindMipmaps.
Is there a way to present images as they are without scaling?
No, MWorks doesn’t support that at present.
To create an annulus or ring, can you think of an easy way for masking the outer part? For the inner part I would just overlay a circle with the background color (see attachment). If no, I’ll just generate the image at the right size.
One option is to generate a mask image, with a transparent, circular center and everything else set to the background color, and present that on top of the primary image. I can’t think of any better options at the moment.
Chris
Hi Chris,
I managed to come up with a way to generate the necessary images in matching sizes. However, I have some trouble to understand the scaling of the images:
The checkerboard and the mask I generated have the same vertical size (1080 pixels). If I set the vertical size in the MWEditor to be the same for both they do not end up being the same size on the screen but the checkerboard is always bigger. Am I doing something wrong?
Thanks for any help and best wishes,
Joscha
Hi Joscha,
MWorks’ handling of non-square images is a bit counterintuitive (to me, at least). If you want to preserve the image’s aspect ratio on screen, x_size
and y_size
must be equal (which they are in your example). When drawn, the larger dimension spans the full specified size, while the smaller dimension is scaled to maintain the original aspect ratio. (If you’re curious, there are some more details and rationale in this discussion.)
In your example, the mask image drawn on screen is 30 degrees wide and 16.875 degrees tall, which maintains its 16/9 aspect ratio. Since the checkerboard image is square, none of this aspect-ratio-preserving business applies, so the image just fills the bounds you provide. To make it match the height of the mask, you should set its size to 16.875 in both dimensions.
Cheers,
Chris
Thanks for the help Chris. Our stimulus works perfectly now.
Joscha