Проблемы синхронизации Psychopy PyGaze EyeTribe Eyetracker (многопоточность)

У меня есть эксперимент, в котором я показываю стимулы с помощью PsychoPy/PyGaze и отслеживаю движения глаз с помощью айтрекера EyeTribe. В этом эксперименте я обновляю размер двух визуальных стимулов в каждом кадре (при частоте 60 Гц). Я заранее подготавливаю каждый кадр, а потом просматриваю все экранные объекты и представляю их. При этом воспроизводится непрерывный звук. Когда я запускаю этот эксперимент в фиктивном режиме (движение мыши используется как симуляция положения взгляда), для визуального представления не возникает проблем с синхронизацией. Однако, когда я запускаю эксперимент во время отслеживания взгляда, время визуального представления перестает быть точным (более высокая изменчивость продолжительности кадров).

Я попытался больше изучить многопоточность, но в сценарии pytribe PyGaze я не могу найти никаких доказательств того, что один поток ожидает события, исходящего от потока отслеживания глаз. Итак, я понятия не имею, как выяснить, что вызывает проблемы со временем или как это решить? (Надеюсь, я объяснил проблему достаточно конкретно).


person Hanne    schedule 15.06.2016    source источник


Ответы (2)


Это хуже, чем просто необходимость в отдельном потоке для отслеживания взгляда и рендеринга стимула. Что вам действительно нужно, так это отдельный процесс, который позволяет избежать глобальной блокировки интерпретатора python (GIL). GIL предотвращает запуск разных потоков на разных процессорах.

Для повышения временной точности я бы рекомендовал вам переключиться с pygaze на iohub (который, как мне кажется, также поддерживает eyetribe). iohub действительно работает на другом ядре машины, где это возможно, так что ваши стимулы и данные о глазах могут обрабатываться независимо во времени, и он обрабатывает всю синхронизацию за вас.

person Jon    schedule 15.06.2016
comment
Дорогой Джон. Спасибо за ответ. Я запустил вашу демонстрацию timeByFrames с отслеживанием взгляда и без него с помощью iohub. Без отслеживания глаз я получаю среднюю частоту кадров 16,7 мс (SD = 1,29) и 0,4 % пропущенных кадров, в то время как я получаю в среднем 13,6 мс (SD = 2,18) с 2 % пропущенных кадров с отслеживанием взгляда. Мой процессор: Intel(R) Core(TM) i5-5300U CPU 2,30 ГГц. Как время визуального представления может идти быстрее, чем частота обновления моего монитора? Влияет ли процесс слежения за взглядом каким-либо образом на блокировку вертикального пустого интервала? - person Hanne; 17.06.2016
comment
Я просто добавляю этот комментарий, если кто-нибудь когда-нибудь столкнется с теми же проблемами. Время визуальной презентации хорошее с iohub, если я запускаю свой скрипт из командной строки вместо Spyder. - person Hanne; 23.06.2016
comment
Спасибо за информацию Ханне. Я всегда немного волновался, что spyder будет замедлять работу для людей, потому что он (предположительно) имеет различные дополнительные функции для отладки. Кстати, если приведенный выше ответ работает для вас, не могли бы вы отметить его как ответ/правильный? ваше здоровье - person Jon; 24.06.2016

Добавление к ответу Джона: Ханна также написала о проблеме по электронной почте, и оказалось, что она проводила свои эксперименты из Spyder. При запуске из командной строки проблем с синхронизацией быть не должно. (Очевидно, что GIL все еще существует, но на практике это не влияет на синхронизацию экрана.)

Чтобы предотвратить проблемы в будущем, я добавил класс, который позволяет запускать EyeTribe в параллельном процессе. См.: https://github.com/esdalmaijer/PyTribe/blob/master/pytribe.py#L365

Пример использования:

if __name__ == "__main__":

    from pygaze.display import Display
    from pygaze.screen import Screen
    from pytribe import ParallelEyeTribe

    disp = Display()

    scr = Screen()
    scr.draw_fixation(fixtype='cross')

    tracker = ParallelEyeTribe()


    tracker.start_recording()

    disp.fill(scr)
    disp.show()
    tracker.log("Stimulus onset")

    time.sleep(10)

    disp.show()
    tracker.log("Stimulus offset")
    tracker.stop_recording()

    tracker.close()
    disp.close()
person esdalmaijer    schedule 02.08.2016