Table Of Contents

Previous topic

psychopy.iohub Specific Requirements

Next topic

ioHub Devices and Device Events

This Page

Quick links

Starting the psychopy.iohub Process

To use ioHub within your PsychoPy Coder experiment script, ioHub needs to be started at the start of the experiment script. The easiest way to do this is by calling the launchHubServer function.

launchHubServer function

psychopy.iohub.client.launchHubServer(**kwargs)

Starts the ioHub Server subprocess, and return a psychopy.iohub.client.ioHubConnection object that is used to access enabled iohub device’s events, get events, and control the ioHub process during the experiment.

By default (no kwargs specified), the ioHub server does not create an ioHub HDF5 file, events are available to the experiment program at runtime. The following Devices are enabled by default:

  • Keyboard: named ‘keyboard’, with runtime event reporting enabled.
  • Mouse: named ‘mouse’, with runtime event reporting enabled.
  • Monitor: named ‘monitor’.
  • Experiment: named ‘experiment’.

To customize how the ioHub Server is initialized when started, use one or more of the following keyword arguments when calling the function:

kwarg Name Value Type Description
experiment_code str, <= 24 char If experiment_code is provided, an ioHub HDF5 file will be created for the session.
session_code str, <= 24 char When specified, used as the name of the ioHub HDF5 file created for the session.
experiment_info dict Can be used to save the following experiment metadata fields:
 
  • code: str, <= 24 char
  • title: str, <= 48 char
  • description: str, < 256 char
  • version: str, <= 6 char
session_info dict Can be used to save the following session metadata fields:
 
  • code: str, <= 24 char
  • name: str, <= 48 char
  • comments: str, < 256 char
  • user_variables: dict
datastore_name str Used to provide an ioHub HDF5 file name different than the session_code.
psychopy_monitor_name str Provides the path of a PsychoPy Monitor Center config file. Information like display size is read and used to update the ioHub Display Device config.
iohub_config_name str Specifies the name of the iohub_config.yaml file that contains the ioHub Device list to be used by the ioHub Server. i.e. the ‘device_list’ section of the yaml file.

iohub.device.path

Multiple Device’s can be specified using separate kwarg entries.

dict Add an ioHub Device by using the device class path as the key, and the device’s configuration in a dict value.

Examples

  1. Wait for the ‘q’ key to be pressed:

    from psychopy.iohub.client import launchHubServer
    
    # Start the ioHub process. 'io' can now be used during the
    # experiment to access iohub devices and read iohub device events.
    io=launchHubServer()
    
    print "Press any Key to Exit Example....."
    
    # Wait until a keyboard event occurs
    keys = io.devices.keyboard.waitForKeys(['q',])
    
    print("Key press detected: {}".format(keys))
    print("Exiting experiment....")
    
    # Stop the ioHub Server
    io.quit()
    
  2. Use a XInput compliant game pad (e.g. Xbox 360 controller):

    from psychopy.iohub.client import launchHubServer
    
    # Create an iohub_config kwargs dict and indicate that ioHub
    # should connect to a XInput compliant game pad using the
    # default devices settings.
    iohub_config = dict()
    iohub_config['xinput.Gamepad'] = dict()
    
    # Start the ioHub Server Process and access the gamepad and
    # keyboard devices.
    io = launchHubServer(**iohub_config)
    gamepad = io.getDevice('gamepad')
    keyboard = io.devices.keyboard
    
    if gamepad:
        print("Press 'A' button on controller to make it rumble.")
        print("To Exit the Demo, press any Keyboard key.....")
    
        while not keyboard.getPresses():
            # Get any new events from the game pad
            for gp_evt in gamepad.getEvents():
                # Check if the gamepad button 'A' was pressed....
                if 'A' in gp_evt.buttons:
                    # Rumble the game pad for 1 second:
                    #   - low frequency motor @ 50%
                    #   - high frequency motor @ 25%
                    # setRumble() returns as soon as the
                    # ioHub Server has started the requested action.
                    rt, rd = gamepad.setRumble(50.0, 25.0, 1.0)
                    print("Started Rumbling....")
                    io.wait(0.01)
    else:
        print("XInput device connection failed.")
    print("Exiting demo....")
    # Stop the ioHub Server
    io.quit()
    

Please see the psychopy/demos/coder/iohub/launchHub.py demo for examples of different ways to use the launchHubServer function.

ioHubConnection Class

The psychopy.iohub.ioHubConnection object returned from the launchHubServer function provides methods for controlling the iohub process and accessing iohub devices and events.

class psychopy.iohub.client.ioHubConnection(ioHubConfig=None, ioHubConfigAbsPath=None)

ioHubConnection is responsible for creating, sending requests to, and reading replies from the ioHub Process. This class is also used to shut down and disconnect the ioHub Server process.

The ioHubConnection class is also used as the interface to any ioHub Device instances that have been created so that events from the device can be monitored. These device objects can be accessed via the ioHubConnection .devices attribute, providing ‘dot name’ access to enabled devices. Alternatively, the .getDevice(name) method can be used and will return None if the device name specified does not exist.

Using the .devices attribute is handy if you know the name of the device to be accessed and you are sure it is actually enabled on the ioHub Process.

An example of accessing a device using the .devices attribute:

# get the Mouse device, named mouse
mouse=hub.devices.mouse
mouse_position = mouse.getPosition()

print 'mouse position: ', mouse_position

# Returns something like:
# >> mouse position:  [-211.0, 371.0]
getDevice(deviceName)

Returns the ioHubDeviceView that has a matching name (based on the device : name property specified in the ioHub_config.yaml for the experiment). If no device with the given name is found, None is returned. Example, accessing a Keyboard device that was named ‘kb’

keyboard = self.getDevice('kb')
kb_events= keyboard.getEvent()

This is the same as using the ‘natural naming’ approach supported by the .devices attribute, i.e:

keyboard = self.devices.kb
kb_events= keyboard.getEvent()

However the advantage of using getDevice(device_name) is that an exception is not created if you provide an invalid device name, or if the device is not enabled on the ioHub server; None is returned instead.

Parameters:deviceName (str) – Name given to the ioHub Device to be returned
Returns:The ioHubDeviceView instance for deviceName.
getEvents(device_label=None, as_type='namedtuple')

Retrieve any events that have been collected by the ioHub Process from monitored devices since the last call to getEvents() or clearEvents().

By default all events for all monitored devices are returned, with each event being represented as a namedtuple of all event attributes.

When events are retrieved from an event buffer, they are removed from that buffer as well.

If events are only needed from one device instead of all devices, providing a valid device name as the device_label argument will result in only events from that device being returned.

Events can be received in one of several object types by providing the optional as_type property to the method. Valid values for as_type are the following str values:

  • ‘list’: Each event is a list of ordered attributes.
  • ‘namedtuple’: Each event is converted to a namedtuple object.
  • ‘dict’: Each event converted to a dict object.
  • ‘object’: Each event is converted to a DeviceEvent subclass
    based on the event’s type.
Parameters:
  • device_label (str) – Name of device to retrieve events for. If None ( the default ) returns device events from all devices.
  • as_type (str) – Returned event object type. Default: ‘namedtuple’.
Returns:

List of event objects; object type controlled by ‘as_type’.

Return type:

tuple

clearEvents(device_label='all')

Clears unread events from the ioHub Server’s Event Buffer(s) so that unneeded events are not discarded.

If device_label is ‘all’, ( the default ), then events from both the ioHub Global Event Buffer and all Device Event Buffer’s are cleared.

If device_label is None then all events in the ioHub Global Event Buffer are cleared, but the Device Event Buffers are unaffected.

If device_label is a str giving a valid device name, then that Device Event Buffer is cleared, but the Global Event Buffer is not affected.

Parameters:device_label (str) – device name, ‘all’, or None
Returns:None
sendMessageEvent(text, category='', offset=0.0, sec_time=None)

Create and send an Experiment MessageEvent to the ioHub Server for storage in the ioDataStore hdf5 file.

Note

MessageEvents can be thought of as DeviceEvents from the virtual PsychoPy Process “Device”.

Parameters:
  • text (str) – The text message for the message event. 128 char max.
  • category (str) – A str grouping code for the message. Optional. 32 char max.
  • offset (float) – Optional sec.msec offset applied to the message event time stamp. Default 0.
  • sec_time (float) – Absolute sec.msec time stamp for the message in. If not provided, or None, then the MessageEvent is time stamped when this method is called using the global timer (core.getTime()).
Returns:

True

Return type:

bool

createTrialHandlerRecordTable(trials, cv_order=None)

Create a condition variable table in the ioHub data file based on the a psychopy TrialHandler. By doing so, the iohub data file can contain the DV and IV values used for each trial of an experiment session, along with all the iohub device events recorded by iohub during the session.

Example psychopy code usage:

# Load a trial handler and
# create an associated table in the iohub data file
#
from psychopy.data import TrialHandler, importConditions

exp_conditions=importConditions('trial_conditions.xlsx')
trials = TrialHandler(exp_conditions, 1)

# Inform the ioHub server about the TrialHandler
#
io.createTrialHandlerRecordTable(trials)

# Read a row of the trial handler for
# each trial of your experiment
#
for trial in trials:
    # do whatever...


# During the trial, trial variable values can be updated
#
trial['TRIAL_START']=flip_time

# At the end of each trial, before getting
# the next trial handler row, send the trial
# variable states to iohub so they can be stored for future
# reference.
#
io.addTrialHandlerRecord(trial.values())
addTrialHandlerRecord(cv_row)

Adds the values from a TriaHandler row / record to the iohub data file for future data analysis use.

Parameters:cv_row
Returns:None
getTime()

Deprecated Method: Use Computer.getTime instead. Remains here for testing time bases between processes only.

setPriority(level='normal', disable_gc=False)

See Computer.setPriority documentation, where current process will be the iohub process.

getPriority()

See Computer.getPriority documentation, where current process will be the iohub process.

getProcessAffinity()

Returns the current ioHub Process affinity setting, as a list of ‘processor’ id’s (from 0 to getSystemProcessorCount()-1). A Process’s Affinity determines which CPU’s or CPU cores a process can run on. By default the ioHub Process can run on any CPU or CPU core.

This method is not supported on OS X at this time.

Parameters:None
Returns:
A list of integer values between 0 and
Computer.getSystemProcessorCount()-1, where values in the list indicate processing unit indexes that the ioHub process is able to run on.
Return type:list
setProcessAffinity(processor_list)

Sets the ioHub Process Affinity based on the value of processor_list.

A Process’s Affinity determines which CPU’s or CPU cores a process can run on. By default the ioHub Process can run on any CPU or CPU core.

The processor_list argument must be a list of ‘processor’ id’s; integers in the range of 0 to Computer.processing_unit_count-1, representing the processing unit indexes that the ioHub Server should be allowed to run on.

If processor_list is given as an empty list, the ioHub Process will be able to run on any processing unit on the computer.

This method is not supported on OS X at this time.

Parameters:processor_list (list) – A list of integer values between 0 and Computer.processing_unit_count-1, where values in the list indicate processing unit indexes that the ioHub process is able to run on.
Returns:None
flushDataStoreFile()

Manually tell the ioDataStore to flush any events it has buffered in memory to disk.”.

Parameters:None
Returns:None
startCustomTasklet(task_name, task_class_path, **class_kwargs)

Instruct the iohub server to start running a custom tasklet given by task_class_path. It is important that the custom task does not block for any significant amount of time, or the processing of events by the iohub server will be negatively effected.

See the customtask.py demo for an example of how to make a long running task not block the rest of the iohub server.

stopCustomTasklet(task_name)

Instruct the iohub server to stop the custom task that was previously started by calling self.startCustomTasklet(….). task_name identifies which custom task should be stopped and must match the task_name of a previously started custom task.

shutdown()

Tells the ioHub Server to close all ioHub Devices, the ioDataStore, and the connection monitor between the PsychoPy and ioHub Processes. Then end the server process itself.

Parameters:None
Returns:None
quit()

Same as the shutdown() method, but has same name as PsychoPy core.quit() so maybe easier to remember.

_startServer(ioHubConfig=None, ioHubConfigAbsPath=None)

Starts the ioHub Process, storing it’s process id, and creating the experiment side device representation for IPC access to public device methods.

_createDeviceList(monitor_devices_config)

Create client side iohub device views.

_addDeviceView(dev_cls_name, dev_config)

Add an iohub device view to self.devices

_sendToHubServer(tx_data)

General purpose local <-> iohub server process UDP based request - reply code. The method blocks until the request is fulfilled and and a response is received from the ioHub server.

Parameters:tx_data (tuple) – data to send to iohub server

Return (object): response from the ioHub Server process.

_sendExperimentInfo(experimentInfoDict)

Sends the experiment info from the experiment config file to the ioHub Server, which passes it to the ioDataStore, determines if the experiment already exists in the hdf5 file based on ‘experiment_code’, and returns a new or existing experiment ID based on that criteria.

_sendSessionInfo(sess_info)

Sends the experiment session info from the experiment config file and the values entered into the session dialog to the ioHub Server, which passes it to the ioDataStore.

The dataStore determines if the session already exists in the experiment file based on ‘session_code’, and returns a new session ID if session_code is not in use by the experiment.

static eventListToObject()

Convert an ioHub event currently in list value format into the correct ioHub.devices.DeviceEvent subclass for the given event type.

static eventListToDict()

Convert an ioHub event currently in list value format into the event as a dictionary of attribute name, attribute values.

static eventListToNamedTuple()

Convert an ioHub event currently in list value format into the namedtuple format for an event.