psychopy.org | Reference | Downloads | Github

Iohub eye-tracking function

Hello,

I’ve successfully used the following eye-tracking code (iohub) to check coordinates, only in the past I called the ‘check_eyes’ code within each trial itself for each stimuli (greatly expanding my code). When I try to call it from a function outside of my main experiment loop, I get the error ‘global name ‘EventConstants’ is not defined’. I have set EventConstants as a global variable, but I cannot think of any other way to fix this. I have condensed the problem to the small bit of code below to illustrate what gives me this error.

from psychopy.iohub.client import launchHubServer

    window = visual.Window(fullscr=True,color=("black"), allowGUI=True, monitor='testMonitor', units='deg')

    gaze_ok_region = visual.Circle(window, radius=120, units='pix')

    runtime_settings = dict()
    runtime_settings['sampling_rate'] = 500
    runtime_settings['track_eyes'] = 'RIGHT'
    iohub_config = {'eyetracker.hw.sr_research.eyelink.EyeTracker':
                    {'name': 'tracker',
                     #'simulation_mode': True,
                     'model_name': 'EYELINK 1000 DESKTOP',
                     'runtime_settings': runtime_settings
                     },
                    }
                   
    io = launchHubServer(**iohub_config) 

    keyboard = io.devices.keyboard
    display = io.devices.display
    tracker = io.devices.tracker

    def check_eyes():                      #check eye positions & give feedback if wrong
        # get eye sample & check correct position
        global eyes3, EventConstants
        eye_samples = tracker.getEvents(EventConstants.MONOCULAR_EYE_SAMPLE)
        for es in eye_samples:
            if es.status == 0:
                gpos = es.gaze_x, es.gaze_y
            else:
                gpos=None
            if not isinstance(gpos, (tuple, list)):
                pass
            elif  gaze_ok_region.contains(gpos):
                pass
            else:
                eyes3 = "0"
                warning_beep.play()
                break
               
    def trial():
        global eyes3, EventConstants
        check_eyes()
       
    trial() 

I have no eye-tracker here, but this should work regardless, and indeed it does work if I remove the ‘check_eyes’ code from the function and paste it right into my main experiment loop. If I could call it from a function each time I wanted it, I could shave a lot of code from my main loop.

Cheers,
Steve

In the code you included, I don’t see anywhere where EventConstants is actually declared/assigned: You’ve told your functions it’s a global variable, but it needs to be given a value either with an assignment (EventConstants = something), or, more likely in this case, you’re missing an import.

If I remember correctly, you need to add this line after your first import:

from psychopy.iohub.constants import EventConstants

And then after that, you won’t actually need to use the ‘global’ statement before EventConstants.

The whole ‘The global variable “whatevs” can not be found’ is a little misleading, in that you could take it to mean your variable should be global. What that error actually means in most cases is that the variable was never given a value or doesn’t exist, global or otherwise. Hopefully I’m making sense.

1 Like

Oh yes I see. You’re right, the global variable here was misleading. Thanks for your clear response, it helped a lot; it didn’t occur to me that I might have been missing an import. Strange how I don’t need to import ‘EventConstants’ if I’m running the code directly in the experiment routine on a frame by frame basis. The import did fix the issue though.

Glad that worked! As to whether it’s imported in the original script, maybe there’s some type of wildcard import like this?:

from psychopy.iohub.constants import *