#### Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Supported by

# Using custom image for calibration using eye tribe tracker

Hi,
I wish to use a custom animation with sound instead of point calibration for eye tribe. I wanted to know if it is possible in Pygaze. If so, how?

• Currently, this option is not supported. However, it should be relatively easy to implement such a thing yourself, using a bit of class inheritance (or just by redefining the existing code):

The fixation target is drawn using the draw_calibration_target function. It simply uses the existing function to draw a drift correction target, which in turn uses the existing function for drawing a fixation dot. However, you could replace this by whatever code you want, for example by code that draws an image and plays a sound. You could do this by changing the source code, or by applying class inheritance, by doing something like this:

from pygaze._eyetracker.libeyetribe import EyeTribeTracker

class CustomEyeTribeTracker(EyeTribeTracker)

def draw_calibration_target(self, x, y):

# Do whatever you like here.

from pygaze.display import Display

disp = Display()
tracker = CustomEyeTribeTracker(disp)

tracker.calibrate()

tracker.close()
disp.close()

• Thanks Edwin,
I am using the inbuilt pygaze in open sesame environment. So I wanted to know, to implement according to my requirement should I replace the pygaze_int with an inline script containing the above piece of code or is there any another way which I haven't understood of?

• Hi,
I am still trying to figure out how to implement it? I do not want to change the source code so I will be applying the class inheritance.
I am defining the steps to implement the same, kindly suggest changes if wrong:
1. I will use pygaze_int.
2. In this, I will untick the calibrate option.
3. I will define a new inline script whereby I will place the above code. ( In this I have a doubt. If I close my custom eye tracker won't that also close the calibration? Will the same setting of calibration be there for the default eye tracker as set by pygaze_int ?)

• edited September 2016

Please suggest the problem in the following code:

from psychopy import visual, core, event, sound
import itertools
from pygaze._eyetracker.libeyetribe import EyeTribeTracker

class CustomEyeTribeTracker(EyeTribeTracker):

def draw_calibration_target(self, x, y):

win = visual.Window(
size=[100, 100], color=(0.5, 0.5, 0.5),fullscr=None, allowGUI=None,
monitor="testMonitor", units="deg")

calib_target = visual.ImageStim( win=win, name='Calibration target',units='pix',
image='C:/Users/Desktop/Open Sesame/gap_stimuli/img_gap_cloud.png', mask=None, ori=0, pos=(25, 0),
size=50.0,color=[1,1,1], colorSpace='rgb', opacity=1, flipHoriz=False, flipVert=False, texRes=128, interpolate=True, depth=-1.0)

CS_onsetsound_gap = sound.Sound('C:/Users/Desktop/Open  Sesame/gap_stimuli/snd_gap_rew03.wav', secs=-1)
CS_onsetsound_gap.setVolume(1)
CS_onsetsound_gap.play()

clock1 = core.Clock()

t=0
clock1.reset()
dur_calibration=1.0 # time for one entire cycle

# the movement of target from center right to center top
for x,y in itertools.izip(range(25,-1,-1), range(0,26)):
if clock1.getTime() > dur_calibration/4: #for exactly 0.5 secs
break
else:
calib_target.setPos([x,y])
calib_target.setOri(clock1.getTime()* 500)
calib_target.draw()
win.flip()

# the movement of target from center top to center left
for x,y in itertools.izip(range(0,-26,-1), range(25,-1,-1)):
if clock1.getTime() > dur_calibration/2: #for exactly 0.5 secs
break
else:
calib_target.setPos([x,y])
calib_target.setOri(clock1.getTime()* 500)
calib_target.draw()
win.flip()

# the movement of target from center left to center bottom
for x,y in itertools.izip(range(-25,1), range(0,-26,-1)):
if clock1.getTime() > 3 * dur_calibration/4: #for exactly 0.5 secs
break
else:
calib_target.setPos([x,y])
calib_target.setOri(clock1.getTime()* 500)
calib_target.draw()
win.flip()

# the movement of target from center bottom to center right
for x,y in itertools.izip(range(0,26), range(-25,1)):
if clock1.getTime() > dur_calibration: #for exactly 0.5 secs
break
else:
calib_target.setPos([x,y])
calib_target.setOri(clock1.getTime()* 500)
calib_target.draw()
win.flip()

win.close()

from pygaze.display import Display

disp = Display()
tracker = CustomEyeTribeTracker(disp)

tracker.calibrate()

tracker.close()
disp.close()


When I run it I get the following error:

File "C:\Program Files (x86)\OpenSesame\lib\site-packages\libopensesame\inline_script.py", line 102, in run
self.experiment.python_workspace._exec(self.crun)
File "C:\Program Files (x86)\OpenSesame\lib\site-packages\libopensesame\python_workspace.py", line 161, in _exec
exec(bytecode, self._globals)
File "<string>", line 79, in <module>
File "C:\Program Files (x86)\OpenSesame\lib\site-packages\pygaze\_eyetracker\libeyetribe.py", line 129, in __init__
self.eyetribe = EyeTribe(logfilename=logfile)
File "C:\Program Files (x86)\OpenSesame\lib\site-packages\pygaze\_eyetracker\pytribe.py", line 40, in __init__
self._logfile = codecs.open('%s.tsv' % (logfilename), 'w', u'utf-8')
File "C:\Program Files (x86)\OpenSesame\lib\codecs.py", line 896, in open
file = __builtin__.open(filename, mode, buffering)
IOError: [Errno 13] Permission denied: 'default.tsv'

• You can also monkeypatch the code by simply replacing draw_calibration_target() like so:

eyetracker.draw_calibration_target = my_function
eyetracker.calibrate()


Where my_function is your custom calibration-target function. Does that make sense? This avoids you from having to subclass anything.

You'll have to disable calibration in pygaze_init, otherwise you'll start with a calibration using the default target.

(Disclaimer: This untested and sent from my phone. But the logic should work.)

There's much bigger issues in the world, I know. But I first have to take care of the world I know.
cogsci.nl/smathot

• edited September 2016

There's a few issues in your code, for example that you generate a new Window instead of using the existing one. And example of what I had in mind:

def draw_calibration_target(self, x, y):

"""
Draws the calibration target.

arguments

x       --  The X coordinate
y       --  The Y coordinate
"""

self.screen.clear()
self.screen.draw_image('C:\my_image.png', pos=(x,y))
self.disp.fill(self.screen)
self.disp.show()


Where 'C:\my_image.png' is the full path to an image that you'd like to show. (This is an example; you could also show a brief animation.)

Also, I didn't realise you were doing this within OpenSesame. That might complicate things, depending on whether you are planning on using the plug-ins or not. Also, the inline_code might have to look slightly different from my example, which is intended for use directly in Python.

Finally, the error you copied in suggests that the error is actually with your file. You didn't have the permission to write to 'default.tsv', which could mean that it's in a read-only folder, or that you had in open in a different programme. (If you're on Windows, the OS can prevent you from writing to a file that is already opened by different software.)

Cheers,
Edwin

PS: @sebastiaan, thanks for enriching my vocabulary with the term 'monkeypatch'! Hahaha! (BTW, Urban Dictionary doesn't agree.)

• Hi guys,
Thank you for the response. I think I was able to do it using monkey patch but I am still unsure.
After every calibration I am getting the following error with the msg saying calibration failed

File "C:\Program Files (x86)\OpenSesame\lib\site-packages\libqtopensesame\misc\process.py", line 140, in run
exp.run()
File "C:\Program Files (x86)\OpenSesame\lib\site-packages\libopensesame\experiment.py", line 414, in run
self.items.execute(self.var.start)
File "C:\Program Files (x86)\OpenSesame\lib\site-packages\libopensesame\item_store.py", line 89, in execute
self.run(name)
File "C:\Program Files (x86)\OpenSesame\lib\site-packages\libopensesame\item_store.py", line 104, in run
self[name].run()
File "C:\Program Files (x86)\OpenSesame\lib\site-packages\libopensesame\sequence.py", line 51, in run
self.experiment.items.run(_item)
File "C:\Program Files (x86)\OpenSesame\lib\site-packages\libopensesame\item_store.py", line 104, in run
self[name].run()
File "C:\Program Files (x86)\OpenSesame\lib\site-packages\share\opensesame_plugins\pygaze_init\pygaze_init.py", line 214, in run
self.experiment.pygaze_eyetracker.calibrate()
File "C:\Program Files (x86)\OpenSesame\lib\site-packages\pygaze_eyetracker\libeyetribe.py", line 352, in calibrate
noise = sum(var) / float(len(var))
ZeroDivisionError: float division by zero

I also try running a normal calibration procedure for eye tribe but I am again getting the same problem so I think this has to do with the code in general and not something from my side. Kindly suggest

• edited September 2018

Dear all, I want to do a similar thing with Tobii (image for calibration), I have a problem when I run ,

 disp = PsychoPyDisplay()
eyetracker = TobiiProTracker(disp)
eyetracker.calibration()


Opensesame it show me this error:

for s in screen.screen:,
AttributeError: OSScreen instance has no attribute 'screen'

I think, I have to pass Screen to the Display. But I don't know how.

• Ops... I move the calibration in the "run" fase!!!
The calibration starts but my function is ignored and the default calibration is executed.

• hi bilancino, I'm using tobii too. And I changed the calibration point to picture by changing the code in this line(https://github.com/esdalmaijer/PyGaze/blob/fe5ffe85ddb3e6bd979b627af1d3005968e71186/pygaze/_eyetracker/libtobii.py#L385) to:

  self.screen.draw_image(