marcus-nystrom / Titta

Python and PsychoPy interface to Tobii eye trackers using Tobii Pro SDK
Other
61 stars 25 forks source link

Problem with function save_data() #46

Closed giadd22 closed 7 months ago

giadd22 commented 7 months ago

Hi! I'm working on a project with the eye tracker Tobii pro spectrum. I'm having some problems with the save.data() function in Tobii.py, as in the code I'm implementing for my experiment I'm supposed to save the data of each trial (which lasts 10 seconds), so putting the function in this loop at the first iteration it saves the data. Still, it crashes right after giving the error I'm attaching. I wanted to ask you if this could be a problem with the function because I saw in the Tobii.py file that it also takes into account the calibration data so it could be that by iterating these are missing. Or maybe it could be another problem that escapes me at the moment. Let me know, thank you very much.

Ready to record data for: texture_1_21_1. Press 'Enter' to start. Recording data for: texture_1_21_1 Took 0.0668187141418457 s to save the data Iteration completed: texture_1_21_1 Ready to record data for: texture_1_1_1. Press 'Enter' to start. Recording data for: texture_1_1_1 Traceback (most recent call last):

File ~\anaconda3\Lib\site-packages\spyder_kernels\py3compat.py:356 in compat_exec exec(code, globals, locals)

File c:\users\administrator\desktop\titta-master\titta-master\demo_experiment\texturexptry.py:452 main()

File c:\users\administrator\desktop\titta-master\titta-master\demo_experiment\texturexptry.py:408 in main tracker.save_data()

File ~\anaconda3\Lib\site-packages\titta\Tobii.py:1865 in save_data d['level'] = [t.name for t in d['level']]

UnboundLocalError: cannot access local variable 'd' where it is not associated with a value image

marcus-nystrom commented 7 months ago

Thanks! Was indeed an indentation error. The correct code should be:

    if len(l) > 0:
        d =  {}
        for key in list(l[0].keys()):
            d[key] = [i[key] for i in l]

        # Convert to prevent warning when saving to Hdf5 (see notifications above)
        d['level'] = [t.name for t in d['level']]
        d['source'] = [t.name for t in d['source']]

        # Save log file
        pd.DataFrame.from_dict(d).to_hdf(fname + '.h5', key='log')

    print(f'Took {time.time() - t0} s to save the data')

I've committed a fix and will include it in a new release as soon as I can. Meanwhile, you can pull the most recent code from GitHub or modify the code yourself.

giadd22 commented 7 months ago

Thank you very much, but I still get the same error, maybe I am doing something wrong and using that function in a loop that requires saving the recorded data for 10 seconds does not work here.

dcnieho commented 7 months ago

Is it the same error on a different line? See https://github.com/marcus-nystrom/Titta/commit/458e8a1e004cbec7d61d4d6a81ac6440a24232a4, you need to indent a line underneath as well

giadd22 commented 7 months ago

yes the same error, I used the tobii.py file you modified earlier, but still even trying to put the save_data function outside the for loop but calling it twice for two different saves gives me the same error, it seems it doesn't like to be called several times in the same code.

marcus-nystrom commented 7 months ago

I have tested it on my side and it works to save in a loop after the fix. I have published a new version with this update, so upgrade titta and try again: python -m pip install titta --upgrade

You can then try this minimal example:

# Import relevant modules
from psychopy import visual, core
from titta import Titta

# Create an instance of titta
et_name = 'Tobii Pro Spectrum'
settings = Titta.get_defaults(et_name)

# Connect to eye tracker and calibrate
tracker = Titta.Connect(settings)
tracker.init()

# Window set-up (this color will be used for calibration)
win = visual.Window(size=(1920, 1080))
tracker.calibrate(win)

for i in range(2):
    # Start recording
    tracker.start_recording(gaze=True)

    # Show your stimuli
    win.flip()
    core.wait(1)

    # Stop recording
    tracker.stop_recording(gaze=True)

    # Close window and save data
    tracker.save_data()

win.close()