SMI Eyetracker iViewXAPi

Hi folks,

is there a better way to utilize an SMI Red Eyetracker than using their iViewXAPI.py? It seems the code has not been updated since 2013.

For example, the iViewXAPI.iV_SaveData function does not seem to work; currently I am using their callback interface to save events and samples (as demonstrated in their callbackdemo.py). However, I still can’t figure out how to send images such that they appear on the Eyetracker Laptop. Does anybody know how to do that?

In any case, the interface is not really nice in general. I have seen that iohub has eyetracking functionality, but the documentation is not ready yet (see here). Can somebody point me to a working example? When will the docs be ready?

Thanks for your help!

Cheers,
Fabian

Hi Fabian,

First of all, the psychopy.org documentation is missing, but you can find generally accurate documentation here: http://www.isolver-solutions.com/iohubdocs/iohub/api_and_manual/device_details/eyetracker.html

Second, I successfully used PsychoPy and iohub with the iViewX API last year on a SMI RED500 system. I needed very minimal things from it, but once I got the eye-tracker talking to psychopy it looked like I could get it to do whatever I wanted. I was also able to port the whole thing to an EyeLink system a couple months ago with minimal difficulty.

The setup I was on had a separate computer for stimulus presentation and the eye-tracker control, and those two computers were connected on a closed network. I ran iViewX on the eye-tracker control computer and psychopy on the stimulus computer, and just having iViewX running was all I needed, everything else was python. Using iohub I connected to the eye-tracker and the basically just sampled from it in psychopy whenever I wanted to, built my own data structure for the info I got back, and saved what I needed in a CSV. Very simple, but it did what I needed it to do.
EDIT: I just remembered that I needed the API installed on the stimulus presentation computer to make it all work. Important detail!

You should be able to get something working with an iohub_config.yaml file, the relevant piece of which is at the bottom of this post. In your psychopy script, all you should need to start with is:

from psychopy.iohub import launchHubServer
io=launchHubServer(iohub_config_name='iohub_config.yaml')
tracker=io.devices.tracker

Then, when you want to run calibration:

calib = tracker.runSetupProcedure('CALIBRATION_STATE')

And then to start getting data, the following two lines:

tracker.setRecordingState(True) 
tracker.enableEventReporting(True)

From there out you can just ask the eye-tracker for information whenever you need it. I only wanted fixation location, so every call after that is simply:

gpos = tracker.getLastGazePosition()

But there are getEvents functions which can get you much more complete information. Hope all that helps!

Here’s my iohub_config info:

SMI iView Config

- eyetracker.hw.smi.iviewx.EyeTracker:
    name: tracker
    save_events: True
    stream_events: True
    event_buffer_length: 1024
    monitor_event_types: [ BinocularEyeSampleEvent, FixationStartEvent, FixationEndEvent]
    network_settings:
        send_ip_address: 169.254.101.116
        send_port: 4444
        receive_ip_address: 169.254.10.231
        receive_port: 5555	            
    runtime_settings:
        sampling_rate: 250
        track_eyes: BINOCULAR_AVERAGED
        sample_filtering:
            FILTER_ALL: FILTER_OFF            
        vog_settings:
            pupil_measure_types: PUPIL_DIAMETER
    calibration:
        type: NINE_POINTS
        auto_pace: Yes
        pacing_speed: SLOW
        screen_background_color: 125
        target_type: CIRCLE_TARGET
        target_attributes:
            target_size: 30
            target_color: 239
            target_inner_color: RED
        show_validation_accuracy_window: False
    model_name: RED
3 Likes

Thank you, Jonathan, this looks promising! I will try it out at work on Friday.

Hi again,

I followed your advice, but I still get an error. Concretely, upon calling

io = launchHubServer(iohub_config_name = 'iohub_config.yaml')

I get the following

Traceback (most recent call last):
  File "C:\Users\Labor\Desktop\social-comparison\test-main.py", line 15, in <module>
    io = launchHubServer(iohub_config_name='iohub_config.yaml')
  File "C:\Program Files (x86)\PsychoPy2\lib\site-packages\psychopy-1.84.2-py2.7.egg\psychopy\iohub\client\__init__.py", line 1425, in launchHubServer
    monitor_devices_config=io_config.get('monitor_devices')
AttributeError: 'list' object has no attribute 'get'

I checked the source (here), and I get the problem – although I’m not sure what ‘Loader’ is doing. How have you avoided the error?

Hm, I was hoping iohub wouldn’t require you to define the display, but I guess it does. OK, I think this should fix it:

  1. In psychopy, go to tools > monitor center, and create a new monitor called “SMI” with the dimensions and viewing distance of the monitor you will be showing the stimuli on. Make sure it saves your monitor configuration, the monitor center window is pretty kludgy.

  2. Use the stuff below as your iohub_config.yaml file. In the ‘display’ section, change the width, height, and viewing distance to match whatever you put in monitor center. If it’s a two-screen setup, set device_number to 1 if the monitor is the secondary display (i.e. the one that does not have the desktop on it), 0 otherwise. If it gets cranky about displaying on the wrong monitor just change it (modern computers are bad about monitor indexing).

    monitor_devices:
    - Display:
    name: display
    reporting_unit_type: pix
    device_number: 1
    physical_dimensions:
    width: 435
    height: 310
    unit_type: mm
    default_eye_distance:
    surface_center: 600
    unit_type: mm
    psychopy_monitor_name: SMI

     - Keyboard:
         name: kb
    
     - Mouse:
         name: mouse
    
     - Experiment:
         name: experimentRuntime
    
     - eyetracker.hw.smi.iviewx.EyeTracker:
         name: tracker
         save_events: True
         stream_events: True
         event_buffer_length: 1024
         monitor_event_types: [ BinocularEyeSampleEvent, FixationStartEvent, FixationEndEvent]
         network_settings:
             send_ip_address: 169.254.101.116
             send_port: 4444
             receive_ip_address: 169.254.10.231
             receive_port: 5555	            
         runtime_settings:
             sampling_rate: 250
             track_eyes: BINOCULAR_AVERAGED
             sample_filtering:
                 FILTER_ALL: FILTER_OFF            
             vog_settings:
                 pupil_measure_types: PUPIL_DIAMETER
         calibration:
             type: NINE_POINTS
             auto_pace: Yes
             pacing_speed: SLOW
             screen_background_color: 125
             target_type: CIRCLE_TARGET
             target_attributes:
                 target_size: 30
                 target_color: 239
                 target_inner_color: RED
             show_validation_accuracy_window: False
         model_name: RED
    

    data_store:
    enable: True

Hi Jonathon,

thanks so much for your reply. However, now I get a different error (see below). Any further ideas? I really appreciate your help!

Error during device creation ....
<type 'exceptions.TypeError'>
TypeError("'NoneType' object has no attribute '__getitem__'",)
['  File "C:\\Program Files (x86)\\PsychoPy2\\lib\\site-packages\\psychopy-1.84.2-py2.7.egg\\psychopy\\iohub\\server.py", line 591, in createNewMonitoredDevice\n    device_instance_and_config=self.addDeviceToMonitor(device_class_name,deviceConfig)\n',
 '  File "C:\\Program Files (x86)\\PsychoPy2\\lib\\site-packages\\psychopy-1.84.2-py2.7.egg\\psychopy\\iohub\\server.py", line 781, in addDeviceToMonitor\n    deviceInstance=DeviceClass(dconfig=device_config)\n',
 '  File "C:\\Program Files (x86)\\PsychoPy2\\lib\\site-packages\\psychopy-1.84.2-py2.7.egg\\psychopy\\iohub\\devices\\display\\__init__.py", line 62, in __init__\n    self._addRuntimeInfoToDisplayConfig()\n',
 '  File "C:\\Program Files (x86)\\PsychoPy2\\lib\\site-packages\\psychopy-1.84.2-py2.7.egg\\psychopy\\iohub\\devices\\display\\__init__.py", line 506, in _addRuntimeInfoToDisplayConfig\n    self._createPsychopyCalibrationFile()\n',
 '  File "C:\\Program Files (x86)\\PsychoPy2\\lib\\site-packages\\psychopy-1.84.2-py2.7.egg\\psychopy\\iohub\\devices\\display\\__init__.py", line 660, in _createPsychopyCalibrationFile\n    psychoMonitor.setSizePix(list(self.getPixelResolution()))\n',
 '  File "C:\\Program Files (x86)\\PsychoPy2\\lib\\site-packages\\psychopy-1.84.2-py2.7.egg\\psychopy\\iohub\\devices\\display\\__init__.py", line 193, in getPixelResolution\n    return self.getConfiguration()[\'runtime_info\'][\'pixel_resolution\']\n']
Error during device creation ....
<class 'psychopy.iohub.util.exception_tools.ioHubError'>
ioHubError:
Args: ('Error during device creation ....',)

['  File "C:\\Program Files (x86)\\PsychoPy2\\lib\\site-packages\\psychopy-1.84.2-py2.7.egg\\psychopy\\iohub\\server.py", line 520, in __init__\n    self.createNewMonitoredDevice(device_class_name,deviceConfig)\n',
 '  File "C:\\Program Files (x86)\\PsychoPy2\\lib\\site-packages\\psychopy-1.84.2-py2.7.egg\\psychopy\\iohub\\server.py", line 603, in createNewMonitoredDevice\n    raise ioHubError("Error during device creation ....")\n']
<class 'psychopy.iohub.util.exception_tools.ioHubError'>
ioHubError:
Args: ('Error during device creation ....',)

['  File "C:\\Program Files (x86)\\PsychoPy2\\lib\\site-packages\\psychopy-1.84.2-py2.7.egg\\psychopy\\iohub\\launchHubProcess.py", line 35, in run\n    s = ioServer(rootScriptPathDir, ioHubConfig)\n',
 '  File "C:\\Program Files (x86)\\PsychoPy2\\lib\\site-packages\\psychopy-1.84.2-py2.7.egg\\psychopy\\iohub\\server.py", line 524, in __init__\n    raise ioHubError("Error during device creation ....")\n']
Traceback (most recent call last):
  File "C:\Users\Labor\Desktop\social-comparison\main.py", line 78, in <module>
    io = launchHubServer(iohub_config_name = 'iohub_config.yaml')
  File "C:\Program Files (x86)\PsychoPy2\lib\site-packages\psychopy-1.84.2-py2.7.egg\psychopy\iohub\client\__init__.py", line 1504, in launchHubServer
    return ioHubConnection(ioConfig)
  File "C:\Program Files (x86)\PsychoPy2\lib\site-packages\psychopy-1.84.2-py2.7.egg\psychopy\iohub\client\__init__.py", line 285, in __init__
    self.iohub_status = self._startServer(ioHubConfig, ioHubConfigAbsPath)
  File "C:\Program Files (x86)\PsychoPy2\lib\site-packages\psychopy-1.84.2-py2.7.egg\psychopy\iohub\client\__init__.py", line 943, in _startServer
    isDataAvail=self._serverStdOutHasData()
  File "C:\Program Files (x86)\PsychoPy2\lib\site-packages\psychopy-1.84.2-py2.7.egg\psychopy\iohub\client\__init__.py", line 1052, in _serverStdOutHasData
    raise e
pywintypes.error: (109, 'PeekNamedPipe', 'Die Pipe wurde beendet.')

OK, I have one thought for a possible quick-fix: Are you running psychopy as an administrator? If not, try that. Track down the psychopy.exe in your program files, right click, properties, compatibility, check ‘run as administrator’ (if you’re on Windows 10, earlier versions might be slightly different but the properties tab should still get you there).

Beyond that I’m not sure why you’re getting the error, but I can at least explain what the error seems to be about. The short version is that it’s failing to create your display, for some reason.

When you launch iohub, it goes through the config file and tries to create and connect to each of the devices listed in it, which in this case should be the monitor (display), tracker, keyboard, and mouse. The error is saying that it failed, and the lines it’s referring to in that first block of errors refers to trying to create the monitor specifically. So, it’s trying to get in touch with the display, but for some reason it’s drawing a blank.

It’s the kind of error you might get if the monitor isn’t saved to the psychopy monitor center, or the information in the monitor center is mismatched with the information in the config file. I’m assuming you did create the monitor in the monitor center, so I’m not sure why it’s having an issue unless it’s some kind of permissions problem with psychopy not running as an administrator. I’d say check everything in your monitor center again, maybe add “from psychopy import monitors” to the top of your code (doubt it will make a difference but who knows), and beyond that I’m afraid I’m out of ideas.

Unfortunately, this did not work. I created the monitor, added the line of code, and triple checked if everything was set correctly, but somehow it still failed to create the monitor.

I’m trying to get an smi eye tracker set up on PsychoPy3 standalone, and I’m wondering whether my problems result from not having the API installed as you mention. How did you detect that this was an issue?

Here is my original post:

I didn’t see anything obviously wrong with your yaml file in the other thread, so maybe, but I have a vague memory that lacking the api generated a different error involving it failing to connect to the tracker, not iohub failing to start. However you will eventually need it. As for how I found out, I believe it was an article on the old smi support site which may or may not still exist.

One thing you could try is the iohub demos, which aren’t eye tracker specific but will help you isolate whether it’s just about starting iohub, period, or something about this specific yaml file or the eye tracker specifically. You can find them under the demos menu in coder view.

1 Like

Thank you very much for looking over my yaml file! You helped me narrow down possible causes. :+1:

I will work myself through the iohub demos. Unfortunately, I find it difficult do pinpoint the cause of my errors because some demos don’t run irrespective of my issue (see https://github.com/psychopy/psychopy/issues/2224#issuecomment-456058983).