isolver / ioHub

A Python program, running as an independent process, that provides a 'proxy like' service for experiment runtimes ( psychopy ) and devices ( keyboard, mouse, parallel port, eye tracker, ... ).
19 stars 14 forks source link

BUG? hub.getEvents runs forever. #80

Closed dengemann closed 8 years ago

dengemann commented 10 years ago

@isolver I meanwhile established a working setup on Linux Ubuntu 12.04 LTS i386.

This means:

However, when porting the code to my experiment I encounter a weird issue. Similar to your example I request events after each trial. However I'd like to postpone writing and do the response handling first. On about half to two thirds of my trials the presentation frezes on calling hub.GetEvents

This interestingly never happens if I disconnect the eye tracker and run exactly the same code.

The related line is below the comment XXX boom!

Also when commenting out that line the presentation never crashes or hangs. Any ideas @isolver ?


#!/usr/bin/env python
# -*- coding: utf-8

import os
import os.path as op
import numpy as np
from psychopy import visual, core, event
exp_start = core.getTime()
import random
import itertools
import pandas as pd
from psychopy.iohub import (EventConstants, ioHubExperimentRuntime,
                            getCurrentDateTimeString)
origin = os.path.abspath(os.path.curdir)
rt = ioHubExperimentRuntime(origin,  'experiment_config.yaml')
tracker = rt.hub.devices.tracker
display = rt.hub.devices.display
kb = rt.hub.devices.kb
hub = rt.hub

#  details omitted.

shuffle_idx = range(64)
tracker.setRecordingState(True)
for kind, question in questions:
    #tracker.runSetupProcedure()   # commented out for debugging
    print kind
    print question
    win.setColor('#FFFFFF')
    win.flip()
    text_tmp.setText(question)
    text_tmp.draw()
    win.flip()
    k = ['']
    count = 0
    while k[0] not in ['l', 's'] and count < 5:
        k = event.waitKeys()

    random.shuffle(shuffle_idx)
    conditions = [conditions[k] for k in shuffle_idx]
    jitter_times = [jitter_times[k] for k in shuffle_idx]
    win.setColor('#000000')
    win.flip()

    for trial, (condition, time) in enumerate(zip(conditions,
                                                  jitter_times), 1):
        this_times = []
        elog.write('MSG TRIAL-START {0} {1} {2} '
                   '{3}\n'.format(core.getTime(), trial, kind, condition))
        hub.clearEvents('all')
        for ii, stim in enumerate(unpack_condition(condition)):
            this_stim = create_stim(stim)
            durations = {0: fblink, 1: time, 2: fduration, 3: frest}[ii]
            print durations
            trial_start = core.getTime()
            elog.write('MSG TRIAL-EVENT {0} {1} {2} '
                       '{3}\n'.format(trial_start, trial, kind, condition))
            for frame in range(durations):
                this_stim.draw()
                win.flip()
            this_times.append((stim[:-4], core.getTime() - trial_start))
        win.flip()

        # XXX boom! 
        gaze_events = [str(io_event) + '\n' for io_event in hub.getEvents()]
        hub.clearEvents('all')
        win.flip()
        question_mark.draw()
        win.flip()
        key = None
        qstart = core.getTime()
        rtime = None
        while not key in response_keys:
            resp = event.waitKeys(maxWait=3.0)
            if resp is not None:
                key = resp[0]
            else:
                break
        if resp is not None:
            lat = core.getTime() - qstart
        else:
            lat = None

        responses.append({'condition': condition,
                          'question': kind,
                          'response': key,
                          'time': lat,
                          'sex': subject_sex,
                          'age': subject_age,
                          'time_log': ';'.join([im + ':' + ('%0.6f' % t)
                                               for im, t in this_times]),
                          'trial': trial})
        responses[-1].update(dict([k.split('-') for k in
                             condition.split('_')]))
                        # Save any iohub events to a local file
        for io_event in gaze_events:
            this_spec = '%s %s' % (kind, condition)
            if event_header in io_event:
                colnames, values = my_strip(io_event)
                io_event = 'MSG GAZE %s %s' % (this_spec, values)
                if trial == 1 and ii == 1:
                    head = 'MSG NAMES %s ' % this_spec
                    elog.write(head + colnames)
            else:
                io_event = 'MSG UNKOWN %s %s' % (this_spec, io_event)
            elog.write(io_event)

        df = pd.DataFrame(responses)
        df.to_csv(outfname, sep=';')
        for i in range(wait_f_after_trial):
            wait.draw()
            win.flip()

elog.close()
tracker.setConnectionState(False)
isolver commented 10 years ago

Could you also send me your two config files please? Thanks!

On Tue, Oct 8, 2013 at 4:49 PM, Denis A. Engemann notifications@github.comwrote:

@isolver https://github.com/isolver I meanwhile established a working setup on Linux Ubuntu 12.04 LTS i386.

This means:

  • connection issues with Tobii 60 resolved
  • callibration looks excellent
  • the run.py contingent gaze example you recently shared is working perfectly

However, when porting the code to my experiment I encounter a weird issue. Similar to your example I request events after each trial. However I'd like to postpone writing and do the response handling first. On about half to two thirds of my trials the presentation frezes on calling hub.GetEvents

This interestingly never happens if I disconnect the eye tracker and run exactly the same code.

The related line is below the comment XXX boom!

Also when commenting out that line the presentation never crashes or hangs. Any ideas @isolver https://github.com/isolver ?

!/usr/bin/env python# -*- coding: utf-8

import osimport os.path as opimport numpy as npfrom psychopy import visual, core, eventexp_start = core.getTime()import randomimport itertoolsimport pandas as pdfrom psychopy.iohub import (EventConstants, ioHubExperimentRuntime, getCurrentDateTimeString)origin = os.path.abspath(os.path.curdir)rt = ioHubExperimentRuntime(origin, 'experiment_config.yaml')tracker = rt.hub.devices.trackerdisplay = rt.hub.devices.displaykb = rt.hub.devices.kbhub = rt.hub

details omitted.

shuffle_idx = range(64)tracker.setRecordingState(True)for kind, question in questions:

tracker.runSetupProcedure() # commented out for debugging

print kind
print question
win.setColor('#FFFFFF')
win.flip()
text_tmp.setText(question)
text_tmp.draw()
win.flip()
k = ['']
count = 0
while k[0] not in ['l', 's'] and count < 5:
    k = event.waitKeys()
random.shuffle(shuffle_idx)
conditions = [conditions[k] for k in shuffle_idx]
jitter_times = [jitter_times[k] for k in shuffle_idx]
win.setColor('#000000')
win.flip()

for trial, (condition, time) in enumerate(zip(conditions,
                                              jitter_times), 1):
    this_times = []
    elog.write('MSG TRIAL-START {0} {1} {2} '
               '{3}\n'.format(core.getTime(), trial, kind, condition))
    hub.clearEvents('all')
    for ii, stim in enumerate(unpack_condition(condition)):
        this_stim = create_stim(stim)
        durations = {0: fblink, 1: time, 2: fduration, 3: frest}[ii]
        print durations
        trial_start = core.getTime()
        elog.write('MSG TRIAL-EVENT {0} {1} {2} '
                   '{3}\n'.format(trial_start, trial, kind, condition))
        for frame in range(durations):
            this_stim.draw()
            win.flip()
        this_times.append((stim[:-4], core.getTime() - trial_start))
    win.flip()

    # XXX boom!
    gaze_events = [str(io_event) + '\n' for io_event in hub.getEvents()]
    hub.clearEvents('all')
    win.flip()
    question_mark.draw()
    win.flip()
    key = None
    qstart = core.getTime()
    rtime = None
    while not key in response_keys:
        resp = event.waitKeys(maxWait=3.0)
        if resp is not None:
            key = resp[0]
        else:
            break
    if resp is not None:
        lat = core.getTime() - qstart
    else:
        lat = None

    responses.append({'condition': condition,
                      'question': kind,
                      'response': key,
                      'time': lat,
                      'sex': subject_sex,
                      'age': subject_age,
                      'time_log': ';'.join([im + ':' + ('%0.6f' % t)
                                           for im, t in this_times]),
                      'trial': trial})
    responses[-1].update(dict([k.split('-') for k in
                         condition.split('_')]))
                    # Save any iohub events to a local file
    for io_event in gaze_events:
        this_spec = '%s %s' % (kind, condition)
        if event_header in io_event:
            colnames, values = my_strip(io_event)
            io_event = 'MSG GAZE %s %s' % (this_spec, values)
            if trial == 1 and ii == 1:
                head = 'MSG NAMES %s ' % this_spec
                elog.write(head + colnames)
        else:
            io_event = 'MSG UNKOWN %s %s' % (this_spec, io_event)
        elog.write(io_event)

    df = pd.DataFrame(responses)
    df.to_csv(outfname, sep=';')
    for i in range(wait_f_after_trial):
        wait.draw()
        win.flip()

elog.close()tracker.setConnectionState(False)

— Reply to this email directly or view it on GitHubhttps://github.com/isolver/ioHub/issues/80 .

dengemann commented 10 years ago

Could you also send me your two config files please? Thanks!

I actually just copied them from your example after a brief review. I did not touch them otherwise.

isolver commented 10 years ago

OK thanks. where is the questions (dict ?) coming from? I get an error when trying to run saying questions is undefined.

On Wed, Oct 9, 2013 at 7:59 AM, Denis A. Engemann notifications@github.comwrote:

Could you also send me your two config files please? Thanks!

I actually just copied them from your example after a brief review. I did not touch them otherwise.

— Reply to this email directly or view it on GitHubhttps://github.com/isolver/ioHub/issues/80#issuecomment-25965395 .

isolver commented 10 years ago

Actually, I think a chunk of code is missing from what was posted, many variables are not defined at all, like

win temp_text question_mark response_keys responses ... etc...

On Wed, Oct 9, 2013 at 9:46 AM, Sol Simpson sol@isolver-software.comwrote:

OK thanks. where is the questions (dict ?) coming from? I get an error when trying to run saying questions is undefined.

On Wed, Oct 9, 2013 at 7:59 AM, Denis A. Engemann < notifications@github.com> wrote:

Could you also send me your two config files please? Thanks!

I actually just copied them from your example after a brief review. I did not touch them otherwise.

— Reply to this email directly or view it on GitHubhttps://github.com/isolver/ioHub/issues/80#issuecomment-25965395 .

isolver commented 10 years ago

Maybe I need the code chunk that is referenced to in the comment:

#  details omitted.

;)

dengemann commented 10 years ago

@isolver we can move this part to a private conversation. I wanted to expose the general logic here ;-) not the entire experiment.

isolver commented 10 years ago

I believe this was resolved? Please confirm so I can close it. ;)