OS (e.g. Win10): Win10 PsychoPy version (e.g. 1.84.x): 2021.2.3 Standard Standalone? (y/n) If not then what?: What are you trying to achieve?: make Eyetracking work, with Tobii TX300
What did you try to make it work?: make Eyetracking work, with Tobii TX300
What specifically went wrong when you tried that?: I have sound files and want to track the pupil. I tried working with the builder, to connect the Eyetracker with my psychopy skript and everything seems to be running, but when i look at my output Data file, it is almost empty or at least i dont get any pupil data. I have tried many solutions, but nothing has worked for me so far, because most of the time it has to be changed in the coder, but I havent worked with python before. I tried to work along this: GitHub - aleksandernitka/EyeTracking_Tobii_PsychoPy_IOHUB: a short guide on how to use iohub when using Tobii Eye Trackers with PsychoPy Builder. but sadly it didnt help.
Maybe someone has a idea, ow I can run my experiemnt and get the pupil data. Thanks, timon.
Do you need to access the pupil data while the experiment is running, or only after the experiment is complete (i.e. from a data file)? Both can be done, but the code you would need to add to your experiment will differ depending on what you want to do.
I would like to add here that I’ve used the Titta package (GitHub - marcus-nystrom/Titta: Python and PsychoPy interface to Tobii eye trackers using Tobii Pro SDK)for a Tobii X2-30 to collect pupil data in PsychoPy and think it’s great (it works with most Tobii trackers). If, interested, I can send you a template experiment I created in builder that collects data and outputs a nice txt file with all relevant data.
I want to love the built in ET components, but do I hate the hdf5 file output…
When using iohub, all the eye samples are saved to a hdf5 file in the data folder. The file name should have the same name as your other results files, but with a .hdf5 extension.
HDF5 files can be also be viewed using the HDFView application.
To really make use of the events in the hdf5 file, your experiment will also need to save start and stop trial info so that the events can be split into trials when you read them. This is usually done by sending experiment messages to the hdf5 file during the experiment, or using a condition variables table and saving trial start and stop times to two columns of that table.
If you do not like working with the hdf5 file format, you can always read the samples yourself during the experiment and save your own results file.
I’m working on a couple other hdf5 file reading demo’s that I hope will be included with the next release in January:
read eye samples and groups them into trials using experiment Messages
read eye samples and groups them into trials using the condition variables table. This version also saves the trial condition variables as extra columns for each sample.
They both will work reading hdf5 files created using the psychopy/demos/coder/iohub/eyetracking/gcCursor/run.py Coder demo.
For example, reading MonocularEyeSamples and grouping them into trials based on ‘TRIAL_START’ and ‘TRIAL_END’ experiment messages:
import sys, os
from psychopy import core
import psychopy.iohub
from psychopy.iohub.datastore.util import displayDataFileSelectionDialog, ExperimentDataAccessUtility
SAVE_EVENT_TYPE = 'MonocularEyeSampleEvent'
SAVE_EVENT_FIELDS = ['time', 'gaze_x', 'gaze_y', 'pupil_measure1', 'status']
def getTime():
return core.getTime()
if __name__ == '__main__':
# Select the hdf5 file to process.
data_file_path = displayDataFileSelectionDialog(psychopy.iohub.module_directory(getTime))
if data_file_path is None:
print("File Selection Canceled, exiting...")
sys.exit(0)
data_file_path = data_file_path[0]
dpath, dfile = os.path.split(data_file_path)
datafile = ExperimentDataAccessUtility(dpath, dfile)
# Create a table of trial_index, trial_start_time, trial_end_time for each trial by
# getting the time of 'TRIAL_START' and 'TRIAL_END' experiment messages.
trial_times = []
trial_start_msgs = datafile.getEventTable('MessageEvent').where('text == b"TRIAL_START"')
for mix, msg in enumerate(trial_start_msgs):
trial_times.append([mix+1, msg['time'], 0])
trial_end_msgs = datafile.getEventTable('MessageEvent').where('text == b"TRIAL_END"')
for mix, msg in enumerate(trial_end_msgs):
trial_times[mix][2] = msg['time']
scount = 0
# str prototype used to select samples within a trial time period
sample_select_proto = "(time >= %f) & (time <= %f)"
# Open a file to save the tab delimited output to.
#
output_file_name = "%s.txt" % (dfile[:-5])
with open(output_file_name, 'w') as output_file:
print('Writing Data to %s:\n' % (output_file_name))
# Save header row to file
column_names = ['TRIAL_INDEX', ] + SAVE_EVENT_FIELDS
output_file.write('\t'.join(column_names))
output_file.write('\n')
for tindex, tstart, tstop in trial_times:
trial_samples = datafile.getEventTable(SAVE_EVENT_TYPE).where(sample_select_proto % (tstart, tstop))
# Save a row for each eye sample within the trial period
for sample in trial_samples:
sample_data = [str(sample[c]) for c in SAVE_EVENT_FIELDS]
output_file.write('\t'.join([str(tindex),]+sample_data))
output_file.write('\n')
scount += 1
if scount % 100 == 0:
sys.stdout.write('.')
print("\n\nWrote %d samples." % scount)
datafile.close()
Hi @sol , so do I get it right, that I have to set a hdf5 file first with events and then run the experiment? Because I sadly still dont undestand, how to get my eyetracking data with the script I created in the builder. When I run my experiment with the builder, I get a hdf5 file, but there are no data, that i want. When I run the experiment you gave me, I get a textdocument data file, which is nice, but I dont know, what exactly I have to change, to get the pupil data, that I want. If i get it right, I can set the start and end points from my routines, that I have created in the builder? This is something I have to do, but I dont know how. My question is: Can I get the pupil data, just with a psychopy experiment, which I have done in the builder or do I need the coder too, because I dont have any experience in python?
Maybe you can have a look at my experiment. I uploaded it her: https://github.com/Timon-Ludwigs/psychopyExperiment/blob/main/Eyetracker_Psychopy_experiment_10-10-21.py
It is very long, because i created a new routine in the builder, for every soundfile, because I hoped that this will allow me to get a better output for the pupil data. It is not nice, but i just need the eyetracking results.
You should be able to run your Builder experiment and then run a python script that processes / parses the hdf5 file that was saved.
The eye samples should be automatically saved to the hdf5 file. Tobii will save BinocularEyeSample events that will be in the BinocularEyeSampleEvent hdf5 table.
To be able to split the saved sample data into trials, you will need to use a Code component in the experiment to write a message to the hdf5 file indicating when each trial starts and stops.
To save experiment messages to the hdf5 file you need to send them from a code component in Builder. For example at the start of a trial routine you could send:
io.sendMessageEvent(text="TRIAL_START")
and at the end:
io.sendMessageEvent(text="TRIAL_END")
To use the hdf5 file you currently need to have a script that can parse it, like an adapted version of the one included above.
Would you like me to post a version of one of the Builder demo’s that writes out trial start and stop messages as well as a version of the above parsing script that works with BinocularEyeSamples?
so did I get it right, that I first run my experiment and after my experiment created the hdf5 file, I use it as input for the script that can parse it?
I just tried using io.sendMessageEvent(text=“TRIAL_START”) and io.sendMessageEvent(text=“TRIAL_END”) at the beginning and end of every trial routine in the coder, but sadly the experiement didnt run.
The version of the builder that can write start and stop masseges and the parsing script would be nice.
Please find an example builder project attached. I’ve added a code component send_trial_msgs to the trial routine that sends a start and stop trial message to the hdf5 file. Update the project’s EyeTracking properties to set the sampling rate for your Tobii; the one I have was running at 60 Hz.
After running the project there will be a hdf5 file in the data folder.
Open the attached readBinocSamplesUsingTrialMessages.py script in Coder and run it. Select the hdf5 file that was saved by the experiment. It will save a .txt file in the same directory as the script.
I have another question. My experiement runs perfectly thanks to your help. But I dont understand, why there are alway 0.5 seconds of missing data, everytime the experiement goes from one item to another. In the data file there are just 0.5 seconds, wehre the eyetracker does not give any data. I ran your experiment aswell and there it was the same thing. Maybe you know what is going on.
If you mean that there is a gap in samples between the end of one trial and the start of the next trial, that is expected since the eye tracker recording is starting / stopping each trial and it takes a bit of time to finish one trail and start the next (stopping and starting eye tracker recording itself can take time).
Looking at the Python code generated for the Builder demo I provided, each trial ends up doing things in this order:
Send “TRIAL_START” message
Start eye tracker recording
prepare / draw trial stim code
trial logic …
Stop eye tracker recording
End of trial code
Send “TRIAL_END” message
repeat 1 - 7 for each trial
If you want to start recording after calibration and continue recording until the end of the trial block, you can use a code component to start and then another to stop eye tracker recording. Please see the attached example:
It starts eye tracker recording in instr->code->End Routine and stops recording after the trails have run in end_recording->code_2->Begin Routine.
You will still have some delay between finishing one trial and starting the next, but the iti should be less since the eye tracker is not starting / stopping recording each trial.
Hi @sol ,
I tried your experiment today and there was no delay, thats really good. The problem is, that we dont work with a loop, because we want to control the amount of time that is passed between the trials and the start point where a picture ended and a new one starts. So I tried to project your experiment on ours, but it didnt work. Do you have a example on how to avoid the gap in samples between the trials, if we always use a new trial in the psychopy builder? Probably the way created the experiment is not the best, but it works except of the gaps in samples every time a new trial starts. Eyetracker_Psychopy_experiment_10-10-21.psyexp (34.2 KB)
I uploaded a example, maybe this helps to understand my problem. Maybe you know a better way.
If each of the routines in your project is a trial,try putting a code component to start recording right after calibration and another code component to end recording at the end of the experiment.
I’ve attached a version of your project file with this added; I was not able to actually test it because I do not have the needed image or sound stim.
I already tried that, because I wanted to create the same experiement that you did with the loop. Sadly this did not work for me. Maybe I can work with the loop aswell, but I have not figured it out yet. Do you have another Idea, how I can avoid the gap in samples?