[visionegg] DaqKeyboard and ResponseControl classes
- From: Hubertus Becker <Hubertus.Becker@xxxxxxx>
- To: visionegg@xxxxxxxxxxxxx
- Date: Fri, 27 May 2005 21:16:36 +0200
Hi all,
I needed a solution to collect the responses and response times
of volunteers during a psychophysical experiment. So I needed
access to the keyboard during a presentation is running. One
way to achieve this is to use the pygame module (as described
in dots_simple_loop.py). But I want to keep the source code for
the stimulus as short and clean as possible. I also like to use
controllers in the Vision Egg...
For collecting responses and response times from the keyboard I
wrote two classes: DaqKeyboard and ResponseControl. Please look
at the attached files and let me know what you think about it.
Maybe their are useful for the Vision Egg community.
Best
Hubertus
================================================================
DaqKeyboard.py
================================================================
# The Vision Egg: DaqKeyboard
#
# Author(s): Hubertus Becker <hubertus.becker@xxxxxxxxxxxxxxxx>
# Copyright: (C) 2005 by Hertie Institute for Clinical Brain Research,
# Department of Cognitive Neurology, University of Tuebingen
# URL: http://www.hubertus-becker.de/resources/visionegg/
#
# This library is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as
# published by the Free Software Foundation; either version 2.1 of
# the License, or (at your option) any later version.
#
# $Revision: 1.1 $ $Date: 2005/05/27 17:19:25 $
"""
Data acquisition and triggering over the keyboard.
This module was programmed using information from the web site
http://www.pygame.org/docs/ref/pygame_key.html
"""
####################################################################
#
# Import all the necessary packages
#
####################################################################
import VisionEgg
import VisionEgg.Core
import VisionEgg.FlowControl
import VisionEgg.Daq
import VisionEgg.ParameterTypes as ve_types
import sys
import pygame
__version__ = VisionEgg.release_name
__cvs__ = '$Revision: 1.1 $'.split()[1]
__date__ = ' '.join('$Date: 2005/05/27 17:18:49 $'.split()[1:3])
__author__ = 'Hubertus Becker <hubertus.becker@xxxxxxxxxxxxxxxx>'
# Use Python's bool constants if available, make aliases if not
try:
True
except NameError:
True = 1==1
False = 1==0
####################################################################
#
# KeyboardInput
#
####################################################################
class KeyboardInput(VisionEgg.Daq.Input):
def get_pygame_data(self):
"""Get keyboard input (return values are in pygame.locals.*
notation)."""
keys = pygame.key.get_pressed()
return [k for k, v in enumerate(keys) if v]
def get_string_data(self):
"""Get keyboard input (return values are converted to keyboard symbols
(strings))."""
pressed = self.get_pygame_data()
keys_pressed = []
for k in pressed: # Convert integers to keyboard symbols (strings)
keys_pressed.append(pygame.key.name(k))
return keys_pressed
get_data = get_string_data # Create alias
####################################################################
#
# KeyboardTriggerInController
#
####################################################################
class KeyboardTriggerInController(VisionEgg.FlowControl.Controller):
"""Use the keyboard to trigger the presentation."""
def __init__(self,key=pygame.locals.K_1):
VisionEgg.FlowControl.Controller.__init__(
self,
return_type=ve_types.Integer,
eval_frequency=VisionEgg.FlowControl.Controller.EVERY_FRAME)
self.key = key
def during_go_eval(self):
return 1
def between_go_eval(self):
for event in pygame.event.get():
# if (event.type == pygame.locals.KEYUP) or (event.type ==
pygame.locals.KEYDOWN):
if event.type == pygame.locals.KEYDOWN:
if event.key == self.key:
return 1
else:
return 0
================================================================
ResponseControl
================================================================
# The Vision Egg: ResponseControl
#
# Author(s): Hubertus Becker <hubertus.becker@xxxxxxxxxxxxxxxx>
# Copyright: (C) 2005 by Hertie Institute for Clinical Brain Research,
# Department of Cognitive Neurology, University of Tuebingen
# URL: http://www.hubertus-becker.de/resources/visionegg/
#
# This library is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as
# published by the Free Software Foundation; either version 2.1 of
# the License, or (at your option) any later version.
#
# $Revision: 1.1 $ $Date: 2005/05/27 17:18:49 $
"""
Response control during a presentation is running.
"""
####################################################################
#
# Import all the necessary packages
#
####################################################################
try:
import logging
import logging.handlers
except ImportError:
import VisionEgg.py_logging as logging
import VisionEgg
import VisionEgg.Core
import VisionEgg.FlowControl
import VisionEgg.Daq
import VisionEgg.DaqLPT
import DaqKeyboard
import VisionEgg.ParameterTypes as ve_types
import pygame
__version__ = VisionEgg.release_name
__cvs__ = '$Revision: 1.1 $'.split()[1]
__date__ = ' '.join('$Date: 2005/05/27 17:59:49 $'.split()[1:3])
__author__ = 'Hubertus Becker <hubertus.becker@xxxxxxxxxxxxxxxx>'
# Use Python's bool constants if available, make aliases if not
try:
True
except NameError:
True = 1==1
False = 1==0
####################################################################
#
# ResponseController
#
####################################################################
class ResponseController(VisionEgg.FlowControl.Controller):
"""This abstract base class defines the interface to any
ResponseController.
This module provides an interface to collect responses during a
presentation is running. To interface with real data acquisition devices,
use a module that subclasses the classes defined here.
"""
def _reset(self):
self.responses = []
self.responses_since_go = []
self.time_responses_since_go = []
self.first_responses_since_go = []
self.time_first_responses_since_go = None
self.status_first_responses_since_go = False
self.last_responses_since_go = []
self.time_last_responses_since_go = None
def __init__(self, **kw):
self._reset()
def get_responses(self):
"""Returns the responses in the current frame."""
return self.responses
get_data = get_responses # For backward compatibility
def get_responses_since_go(self):
"""Returns all responses since the main 'go' loop has been
started."""
return self.responses_since_go
def get_time_responses_since_go(self):
"""Returns the time stamps for all responses since the main 'go'
loop has been started."""
return self.time_responses_since_go
def get_first_response_since_go(self, index=0):
"""Returns the first response since the main 'go' loop has been
started."""
if self.first_responses_since_go == []:
return []
else:
return self.first_responses_since_go[index]
def get_first_responses_since_go(self):
"""Returns the first responses since the main 'go' loop has been
started."""
return self.first_responses_since_go
def get_time_first_response_since_go(self):
"""Returns the time stamp for first responses since the main 'go'
loop has been started."""
return self.time_first_responses_since_go
get_time_first_responses_since_go = get_time_first_response_since_go
def get_last_response_since_go(self, index=0):
"""Returns the last response since the main 'go' loop has been
started."""
if self.last_responses_since_go == []:
return []
else:
return self.last_responses_since_go[index]
def get_last_responses_since_go(self):
"""Returns the last responses since the main 'go' loop has been
started."""
return self.last_responses_since_go
def get_time_last_response_since_go(self):
"""Returns the time stamp for last response since the main 'go'
loop has been started."""
return self.time_last_responses_since_go
get_time_last_responses_since_go = get_time_last_response_since_go
def between_go_eval(self):
"""Evaluate between runs of the main 'go' loop.
Override this method in subclasses."""
raise RuntimeError("%s: Definition of between_go_eval() in abstract
base class ResponseController must be overriden."%(str(self),))
def during_go_eval(self):
"""Evaluate during the main 'go' loop.
Override this method in subclasses."""
raise RuntimeError("%s: Definition of during_go_eval() in abstract
base class ResponseController must be overriden."%(str(self),))
####################################################################
#
# KeyboardResponseController
#
####################################################################
#class KeyboardResponseController(VisionEgg.ReponseController):
class KeyboardResponseController(ResponseController):
"""Use the keyboard to collect responses during a presentation is
running."""
def __init__(self):
VisionEgg.FlowControl.Controller.__init__(self,
return_type=ve_types.get_type(None),
eval_frequency=VisionEgg.FlowControl.Controller.EVERY_FRAME,
temporal_variables=VisionEgg.FlowControl.Controller.TIME_SEC_SINCE_GO
)
self.input = DaqKeyboard.KeyboardInput()
def between_go_eval(self):
return None # Ignore keyboard
def during_go_eval(self):
if self.time_sec_since_go <= 0.01: # Reset it every presentation
self._reset()
# self.responses = self.input.get_pygame_data()
self.responses = self.input.get_string_data()
if len(self.responses) > 0:
self.responses_since_go.append(self.responses)
self.time_responses_since_go.append(self.time_sec_since_go)
if self.status_first_responses_since_go == False:
self.time_first_responses_since_go = self.time_sec_since_go
self.first_responses_since_go = self.responses
self.status_first_responses_since_go = True
self.time_last_responses_since_go = self.time_sec_since_go
self.last_responses_since_go = self.responses
return None
--
Hubertus Becker, Hertie Institute for Clinical Brain Research
Department of Cognitive Neurology, Visual Perception Laboratory
University of Tuebingen, Hoppe-Seyler-Str. 3, D-72076 Tuebingen
Homepage: http://www.hubertus-becker.de (GnuPG-Key available)
Other related posts:
- » [visionegg] DaqKeyboard and ResponseControl classes