psychopy.org | Reference | Downloads | Github

Two apertures in Eye-Tracking experiment

OS: Win10
PsychoPy version: v3.2.4
Standard Standalone?: y
What are you trying to achieve?: Gaze-contingent Eye-Tracking experiment with two apertures (one for each eye)

What did you try to make it work?: Put one image and two aperture components in the routine

What specifically went wrong when you tried that?: Only one apertures seems to show up

Hello all, I’m trying to set up an Eye-Tracking experiment with gaze-contingent masks. The aperture component fits very well what I’m trying to do, that is, position the viewing window exactly where the observer fixates his/her gaze. The thing is now my supervisor asked me to use two masks (one for each eye) and I just can’t find a way of doing that with the aperture component. I’ve read some threads where people used two patchStims, but I couldn’t reproduce that.

What I’m trying to achieve is something similar to the image below. If anyone has some advice, I’d be really grateful.

Thanks!

You’ve hit upon a limitation of Builder, in that it only really allows one aperture to be in effect at a time:

https://www.psychopy.org/builder/components/aperture.html

The result you want is possible, but would require a little manual drawing of stimuli by inserting a code component.

I’m a bit rusty on this, but I think you would simply enable the aperture and position it at one eye’s coordinates and then draw the stimulus, and then shift the aperture and to the other eye coordinates and draw the stimulus again.

Thank you so much for your reply.

If I get it right, I should do something like this in the “Each Frame” tab of the code component?

aperturePos = getRightEye()
image.draw()
aperturePos = getLeftEye()
image.draw()

I tried something similar by simulating with the mouse before moving to the Eye-Tracker, but it didn’t work sadly.

Can you explain what actually went wrong? “It didn’t work” doesn’t give us much to go on.

I apologize.
It means I didn’t succeed at showing two moving apertures by using the code I presented above. Only one aperture keeps on showing.
I simulated it by using the central coordinate (0,0) and the mouse component position, for further switching to both eyes, but the outcome was that only one aperture kept showing. Either at the center or at the mouse position. Which one depended which was the last code line (either aperturePos = (0,0) or aperturePos = mouse.getPos())

Is the image you are drawing one created in Builder, via a graphical component? That might conflict with your custom code, as Builder will also be drawing the image stimulus itself.

As importantly, you should also create your aperture in code too, to avoid conflicts with the one Builder creates. i.e. delete both the image and aperture components and do everything in code. You can cheat by looking at the code Builder uses to create them. e.g. name them something prominent like “XXX” and then generate a script. Search through that the generated .py file to find “XXX” and copy and paste that code into your code component, in the “begin experiment” tab. Then you can delete the graphical components, knowing that you can now create versions of your own, completely under your control (remembering to give them sensible names again).

Also the order of the components is important. e.g. the code component needs to be below any stimulus components that you want to appear behind what you are drawing in code.

1 Like

Thank you for your support. I did exactly what you said and it worked fine.

For the record, this is the code I used:

Begin experiment:

mouseC = event.Mouse()

win.allowStencil = True

image = visual.ImageStim(
    win=win,
    name='image', units='pix', 
    image='img.png', mask=None,
    ori=0, pos=(0, 0), size=(1920,1080),
    color=[1,1,1], colorSpace='rgb', opacity=1,
    flipHoriz=False, flipVert=False,
    texRes=128, interpolate=True, depth=0.0)
aperture = visual.Aperture(
    win=win, name='aperture',
    units='pix', size=(251,251), pos=(0,0))
aperture.disable()

Begin Routine:

aperture.enabled = True
image.autoDraw = False

Each frame:

aperture.pos = mouseC.getPos()
image.draw()

aperture.pos = (0,0)
image.draw()
1 Like