3.1. What PsychoPy provides
The primary functions of PsychoPy were designed to handle stimulus display and timing. They allow the user to generate a window (or full-screen presentation) and provide some basic stimuli to use within that window (e.g. random-dot-kinematograms, drifting grating stimuli, text, photographic images). In addition to the stimuli provided (or modifications of them), the user can generate entirely new stimuli by issuing OpenGL commands directly to the window, or combine pre-packaged stimuli with their own commands. In addition to the visual presentation, for which it was originally designed, PsychoPy is able to present stereo auditory stimuli using the computer sound card. Responses can easily be gathered via the keyboard and mouse, by standard devices such as joysticks, or by more elaborate hardware via the serial or parallel ports.
PsychoPy also provides a graphical-user-interface (GUI) application called MonitorCenter to manage calibration of monitors and store information from previous calibrations. The user simply inputs the dimensions of the monitor and its distance (using the GUI) allowing PsychoPy to convert units between various coordinate systems such as degrees of visual angle, centimeters or pixels. In addition MonitorCenter also stores gamma-correction parameters for the monitor, which are then applied automatically during experimental scripts. Furthermore, if a Spectrascan PR650 is connected to the serial port MonitorCenter can also perform a fully automated calibration at the touch of a button. This calibration will measure the luminance at a series of intensity levels and fit the optimum gamma-function to each gun. The PR650 will also measure the intensity spectrum for each gun to allow transformations between various color spaces. The result is that experimental scripts can simply request an image, for example, of a 2° width, with spatial frequency of 3c/° with an isoluminant red/green chromaticity. PsychoPy will perform all the necessary spatial and chromatic calculations for the user. Although other packages, such as PsychToolbox, may provide scripts that help the user with these sorts of manipulations, none has such a simple automated approach allowing the user to refer to their stimuli directly in real-world units ().
The MoniterCenter application provides the experimenter with a handy tool to provide information about their monitor to perform fully automated calibrations with a PR650, and to store information and notes from previous calibrations.
To aid in experimental control a number of functions are also provided to deal with common designs such as staircase procedures or methods of constant stimuli. For example, the user can create a ‘handler’ for a staircase procedure with various settings such as the desired step size(s) and start point for the staircase. On each trial the handler will automatically provide the next intensity level for the stimulus in the staircase based on the previous response of the participant (for complete example of such an experiment see Tutorial 1 on the project website). These handlers can also help to store information about the experiment, such as stimulus parameters, the pseudo-random order of the stimuli, etc.
Finally, a series of functions are provided to aid in data analysis, such as fitting of curves and the use of statistical resampling methods. For example, the following example script (Code Snippet 1) takes a list of intensity values and the mean responses at those intensities. The PsychoPy class FitWeibull then fits a psychometric function to the data. From this we can retrieve the parameters of the fit, request the value of the function at some given intensity values, or the inverse at some given response value(s).
3.2. Ease of use
The syntax of the Python language and the PsychoPy library is remarkably easy to understand, especially to anyone with experience in object-oriented languages. As an example, Code Snippet 2 generates a window in which it draws a Gabor of 50% contrast whose grating drifts at a rate of 3 Hz.
As with any language the particular syntax takes time to learn but Python has numerous advantages over Matlab®
. Most notable is the fact that it was built from scratch as an object-oriented language. For the developer this makes it easier to use and reuse code. For the user, the code remains readable and it becomes extremely easy to identify what functions apply to what types of object. In Code Snippet 2 a clock object is created, which has the method getTime() associated with it. Under the object-oriented programming model the user can create as many clock objects as they choose each of which can return its own (different) time. Another advantage to Python is the ability to name the arguments given to a function with unused arguments being given some default value. In the code below the Window object has numerous additional arguments not shown here (to control the color of the window, whether it appears full screen, etc.) but these were not needed in this instance. The argument naming feature means that we didn’t need to specify all the arguments in their correct order up to the argument that we did actually wish to use (in this case units = “deg”). There are many additional features to the language, like the ability to concatenate strings directly (“Hell” + “o” = “Hello”) or the wide range of available data types, but these are beyond the scope of the current paper. Many additional demo programs including screenshots are available on the project website (www.PsychoPy.org
3.3. Temporal accuracy and speed
The timing precision is one of the most critical issues for a neuroscience experiment. As you might expect from a platform-independent package, the timing precision of PsychoPy is at least partly dependent on the system clock on which it is running. On most computers this is accurate to the order of microseconds and should have sub-millisecond precision on any modern machine for the purpose of measuring user responses.
For the purposes of synchronizing to a video display, PsychoPy uses a double-buffered display method and the buffer swapping is synchronized to the vertical blank period of the screen, provided that the graphics card in question supports that function (most do). This means that all drawing commands are sent to a hidden copy of the screen and then, when given the command to update, the hidden copy swaps with the currently displayed screen image. When synchronized to the vertical blank, no other commands will be executed until this screen flipping has occurred. Provided that all drawing to the hidden buffer can be completed within the time between vertical blanks (11.7 ms at a refresh rate of 85 Hz) this method provides an extremely robust timing mechanism. The question of whether or not all drawing commands are completed within the necessary time is dependent on the complexity of drawing, the speed of the computer, and its graphics card, but typically the drawing of several hundred moderately complex stimuli is possible. For random-dot stimuli, thousands of simple elements can be rendered within a frame (up to 3500 could be drawn without dropping any frames on a test system with an AMD Athlon 3000+, 512 MB RAM, nVidia GeForceFX 5500). Around 80 Gabor stimuli can be drawn with an updated position/phase/orientation within a single frame. Many more can be drawn if their position is constant. Critically, PsychoPy will optionally test for and report dropped frames throughout the experiment.
For occasions where even more (or more complex) stimuli are necessary, C/C++ extensions can be added to the package to increase the speed of the rendering. For precise synchronization with external hardware, the parallel port and serial port provide very fast methods for sending TTL pulses and characters or other data.
3.4. Hardware extensions
PsychoPy has very simple methods to access the parallel and serial ports where available, making interfaces for hardware easy to build. It already provides support for Bits++ (Cambridge Research Systems, Cambridge, UK), Spectrascan PR650 (Photo Research, California, USA), fORP MRI response box (Current Designs Inc., Philadelphia, USA) but should be able to interface with almost anything that uses serial or parallel ports or emulates a computer device such as mouse, keyboard or joystick. In fact, since Python is extensible in C, it should be capable of interfacing with any piece of hardware for which the user has a driver.
To provide the experimenter with greater range of stimulus contrasts than are available using standard graphics cards (with 8 or 10 bit digital–analogue-converters, DACs), PsychoPy integrates with the Bits++ hardware. The Bits++ unit sits between the digital video output of the video card and provides a 14-bit VGA signal out to the monitor. This system provides 14-bit DACS whose outputs are set via lookup-tables that be changed effortlessly every frame (or even within a frame). In its standard mode a lookup table inside the Bits++ unit contains 256 values (corresponding to the output values from the monitor) which correspond to any choice of 14-bit values to be passed to the monitor.1
The system is independent of computer platform or of any particular software library and is relatively inexpensive way to produce stimuli with very precise contrast values.
Other devices such as the SpectraScan PR650 can be controlled by the serial port of the computer (or via a USB adaptor that mimics a serial port, where none are available). This is the means by which, for instance, the MonitorCenter instructs the PR650 to make a measurement during automated calibrations and the means by which it retrieves the luminance and/or intensity spectrum after that measurement. The serial port is also one means by which PsychoPy scripts can receive input from the fORP MRI response box allowing the recording of triggers from magnetic resonance imaging (MRI) hardware and responses from MR-compatible button-boxes. The fORP system can simply emulate keyboard presses via the USB port if a serial port is unavailable.
3.5. Mechanisms for support
Support for the software is primarily maintained through the website at http://www.psychopy.org
. The site is wiki-based, allowing users themselves to directly edit the pages and contribute to or correct documentation. There is also a mailing list through which the users can get support from the original author and also provide support for peers. PsychoPy's code itself is simple, transparent and included with the software so that it too can be modified and improved by the users themselves.