psychopy.org | Reference | Downloads | Github

Auto draw stimulus with custom draw logic

I am trying to debug some eyetracker issues and am interested in making a stimulus object to help me do this by showing the gaze position on the screen in real time (similar to what’s in the demos).

I want this to be an object I can just drop into any script to help debug without having to add logic to update the position and draw it everywhere throughout the script. I thought a clever way to do this might be to subclass a PsychoPy stimulus object, extend the draw method to pull gaze position data from the eyetracker, and then set autoDraw to be True. However I’ve run into a number of issues.

Here is a simple example of what I thought might work:

class GazeStim(GratingStim):

    def __init__(self, win, tracker):

        self.tracker = tracker
        super(GratingStim, self).__init__(win)
        self.setAutoDraw(True)

    def draw(self):

        gaze = self.tracker.getLastGazePosition()
        if isinstance(gaze, (tuple, list)):
            gaze = pix2deg(np.array(gaze), self.win.monitor)
            self.pos = gaze
            self.opacity = 1
        else:
            self.opacity = 0

        super(GratingStim, self).draw()

However this fails with:

Traceback (most recent call last):
  File "experiment.py", line 630, in <module>
    main(sys.argv[1:])
  File "experiment.py", line 87, in main
    experiment_loop(p, win, stims, design, tracker)
  File "experiment.py", line 178, in experiment_loop
    stims["instruct"].draw()
  File "/Users/mwaskom/anaconda/envs/psychopy/lib/python2.7/site-packages/cregg-0.1.dev0-py2.7.egg/cregg/main.py", line 239, in draw
    self.win.flip()
  File "/Users/mwaskom/anaconda/envs/psychopy/lib/python2.7/site-packages/psychopy/visual/window.py", line 541, in flip
    thisStim.draw()
  File "experiment.py", line 134, in draw
    super(GratingStim, self).draw()
  File "/Users/mwaskom/anaconda/envs/psychopy/lib/python2.7/site-packages/psychopy/visual/basevisual.py", line 929, in draw
    raise NotImplementedError('Stimulus classes must override visual.BaseVisualStim.draw')
NotImplementedError: Stimulus classes must override visual.BaseVisualStim.draw

which I find confusing.

Has anyone implemented this sort of thing or can someone provide some tips for the right way to approach this task?

Nice idea and you’re doing nearly all the right things but I think you’re calling the the super-class of the GratingStim, rather than the super of your sub-class. The super of GratingStim doesn’t have draw() implemented so complains.

Change the line super(GratingStim, self).draw() to be either

super(GazeStim, self).draw()

or possibly just

GratingStim.draw(self)

Ah, yes. Thanks for catching that. Guess it’s why they removed the confusing arguments to super in Python 3…