Search code examples
pythonmultithreadingpsychopyexperimental-design

Hardware Synchronization for Scientific Experiment


I am new to python as well as scientific experimental setups. My experimental setup includes that subjects would be shown some visual stimuli which is programmed in Python. While subjects are looking at those visual stimuli their eyes' data would be recorded using an eye tracker (Pupil Labs). Pupil Labs is an open source platform, it also provides this facility that it broadcasts data (i.e. gaze or eye movements) to a server using TCP socket.

Now I am planning to log all the data, like when a particular stimuli is displayed as well as logging eye movement's data received from server. Problem is to synchronize these two things like at particular time some 'xyz' stimuli was shown and I want log what exactly the eye data was at that particular time.

I am writing the code in Python, so far what happening is there is a main program which shows stimuli using psychopy library. In that main program there is a thread which receives data from server.

I want to know how can I synchronize this task. I am new to such task also I am not sure what to look for over internet. I will be grateful for your help.


Solution

  • Looking at the docs, Pupil Labs eye tracking events have a timestamp set by the system clock on your computer, relative to some epoch time (Jan 1, 1970 on unix systems). Similarly, you can find timestamps for events in pychopy which will show up in your experiment logs.

    Once you have collected your data, read in your pupil data and convert it to numpy arrays (pupil_time, pupil_x, and pupil_y). Next load in your pyschopy data. The time stamps in pyschopy may be stored relative to the start of your experiment, in which case you will have to add the experiment start time to the stimulus presentation times (the start time should be available somewhere in the stored data).

    Given pupil_time, pupil_x, pupil_y arrays you can then plot pupil motion during your experiment:

    import matplotlib.pyplot as plt
    import numpy as np
    
    # time since stimulus presentation, in seconds
    t = np.linspace(0, 4, 400)  
    
    # time since stimulus presentation, relative to pupil data time
    abs_t = t + stimulus_presentation_timestamp
    
    # plot interpolated eye position from pupil data
    px, py = np.interp(abs_t, pupil_time, pupil_x), np.interp(abs_t, pupil_time, pupil_y)
    plt.plot(px, py)
    plt.show()
    

    You may not want to interpolate the data If the Pupil Labs software only records the location after each saccade, then using searchsorted to find the last recorded pupil location prior to time t may be more appropriate.


    Update 2016-05-23: use t_abs for interpolating eye position