Psychology/Neuroscience Experiments
in MATLAB Built on Psychtoolbox
MATLAB software built on Psychtoolbox for neuroscience/psychology experiments

Psychtoolbox is a popular MATLAB toolbox for neuroscience and psychology experiments. Building experiments in MATLAB with Psychtoolbox allows a degree of flexibility and precision that is essential in many research niches. However, it can be a technical and time consuming process. Redundancy is also a problem as reusing stimuli and functionality means reintegrating code across different experiments or even reinventing it across labs.

PsychBench is software for MATLAB built on Psychtoolbox. It is a broad suite aimed to make building Psychtoolbox-based experiments faster, easier, and less repetitive—while retaining the flexibility and precision. Work at the level of experiment and stimulus concepts, with more technical control available as needed. An open-source MATLAB + Psychtoolbox library comes with a range of stimulus and functionality types which work anywhere in any experiment. If the library doesn't have what you need, you can add your own. Run experiments locally or export them to run online in VPixx Pack&Go.

Download PsychBench beta (free)
for MATLAB with Psychtoolbox – Windows/macOS/Linux

This link downloads the MATLAB function pb_install.m. Run it from the MATLAB command line. You can type help pb_install for more information.

You'll also need...

Windows / macOS / Linux – 64-bit

MATLAB R2019b or later

PsychBench does not run in GNU Octave.

Psychtoolbox most recent version

Psychtoolbox requires GStreamer (free):
        Windows: GStreamer 64-bit MSVC runtime 1.22.5
        macOS (Intel and ARM): GStreamer runtime 1.22.5
        Linux: generally already installed

System requirement details >

Update history >

Experiments

You can work with a MATLAB script, spreadsheet tables, or a combination of the two...

Coding method

In the coding method of making an experiment we use a MATLAB script. That said, it's not really code in the usual sense, more like a list of statements setting parameters. Define each trial by making objects of various types—e.g. picture, sound, keyPress, or more specialized types like linearDotMask, bmlWalker, etc. Any object works anywhere in any experiment. Set properties you want to change from default using dot syntax. You only need to define each distinct trial once, and in any order, so you can use for loops through conditions to do it easily (or multiple for loops in more complex experiments). Finally set a list of distinct trials to run through, adding any repetition and ordering there. PsychBench includes little tools for various kinds of randomization and counterbalancing.

For example, the script below defines three distinct trials. It runs two repetitions of each, all in random order. In each trial a picture of a different shape shows at a height of 8 degrees visual angle and stops showing when the subject responds by any key press. Experiment results report picture file name and response latency for each trial.

<cdcm>% Mark start of experiment script<cdcm>
newExperiment

<cdcm>% Define 3 distinct trials<cdcm>
<cdkm>for<cdkm> fileName = [<cdsm>"sphere.png" "cube.png" "hourglass.png"<cdsm>]
    picture = pictureObject;
    picture.fileName = fileName;
    picture.height = 8;
    picture.end.response = true;
    picture.report = <cdsm>"fileName"<cdsm>;
   
    recorder = keyPressObject;
    recorder.report = <cdsm>"responseLatency"<cdsm>;
   
    addTrial(picture, recorder);
<cdkm>end<cdkm>

<cdcm>% Want 2 repetitions of each distinct trial in random order<cdcm>
nn = randomOrder(rep(1:3, 2));
setTrialList(nn)

<cdcm>% Run experiment<cdcm>
results = runExperiment;

This is just a toy example. Many dozens of properties are available for timing, visual options, response options, options specific to picture and keyPress objects, and more. We can implement any number of conditions of any kind, blocks, intros, breaks, outros, syncs, any kind of ordering, randomization, counterbalancing, etc. Methods like staircases, adjustment, scanners, online experiments, and more are available. For complex experiments you can lay out values in spreadsheet tables and load them into the script. See below for feature highlights.

For more realistic examples, see stroopDemo.m. Or for something more complex wisconsinDemo.m. Or see a list of all demos.

(Without PsychBench)

Just for comparison, here is some compact Psychtoolbox code that would run the same experiment as above, with the same timing precision and error handling. The difference in length and complexity is noticeable here and balloons up for more realistic experiments.

<cdkm>try<cdkm>
    <cdcm>% Parameters<cdcm>
    fileNames = {<cdsm>'sphere.png' 'cube.png' 'hourglass.png'<cdsm>};
    pictureHeight_deg = 8;
    screenHeight_cm = 17.9;
    screenDistance_cm = 55;
    iti = 0.75;
   
    <cdcm>% Open on-screen window<cdcm>
    [n_window, windowRect] = Screen(<cdsm>'OpenWindow'<cdsm>, 0, [0 0 0]);
    flipInterval = Screen(<cdsm>'GetFlipInterval'<cdsm>, n_window);
   
    <cdcm>% Pause keyboard output to MATLAB command line<cdcm>
    ListenChar(2)    
   
    <cdcm>% Make 3 textures from pictures<cdcm>
    <cdkm>for<cdkm> n_trialDef = 1:3
        data = imread(fileNames{n_trialDef});
       
        nn_textures(n_trialDef) = Screen(<cdsm>'MakeTexture'<cdsm>, n_window, data);
       
        sourceRect = RectOfMatrix(data);
        sourceHeight = RectHeight(sourceRect);
        targetHeight = 2*screenDistance_cm*tand(pictureHeight_deg/2)/screenHeight_cm*RectHeight(windowRect);
        r = targetHeight/sourceHeight;
        targetRect = CenterRect(ScaleRect(sourceRect, r, r), windowRect);
        targetRects(n_trialDef,:) = targetRect; <cdcm>%#ok<*SAGROW><cdcm>
    <cdkm>end<cdkm>
   
    <cdcm>% Run 2x3 trials in random order<cdcm>
    nn_trialDefs = Shuffle(repmat(1:3, 1, 2));
    <cdkm>for<cdkm> n_trial = 1:6
        n_trialDef = nn_trialDefs(n_trial);
        fileName = fileNames{n_trialDef};
        n_texture = nn_textures(n_trialDef);
        targetRect = targetRects(n_trialDef,:);
       
            Screen(<cdsm>'DrawTexture'<cdsm>, n_window, n_texture, [], targetRect)
        <cdkm>if<cdkm> n_trial == 1
            t0 = [];
        <cdkm>else<cdkm>
            t0 = tf+iti-0.5*flipInterval;
        <cdkm>end<cdkm>
            t0 = Screen(<cdsm>'Flip'<cdsm>, n_window, t0);
            [keyIsDown, t] = KbCheck;
           
        <cdkm>while<cdkm> ~keyIsDown
            Screen(<cdsm>'DrawTexture'<cdsm>, n_window, n_texture, [], targetRect)
            Screen(<cdsm>'Flip'<cdsm>, n_window);
            [keyIsDown, t] = KbCheck;
        <cdkm>end<cdkm>
       
            tf = Screen(<cdsm>'Flip'<cdsm>, n_window);
       
        latency = t-t0;
        results(n_trial,:) = {fileName latency};            
    <cdkm>end<cdkm>
   
    <cdcm>%Resume keyboard output to MATLAB command line<cdcm>
    ListenChar(0)

    <cdcm>% Close on-screen window and textures<cdcm>
    Screen(<cdsm>'CloseAll'<cdsm>)
<cdkm>catch<cdkm> X
    <cdcm>% Close on-screen window and textures on error<cdcm>
    ListenChar(0)
    Screen(<cdsm>'CloseAll'<cdsm>)
    rethrow(X)
<cdkm>end<cdkm>

Visual method

The full visual method is an option for experiments of low to moderate complexity. The concepts are the same as in the coding method but we lay everything out in tables. You can use any spreadsheet app for this, but Google Sheets allows dropdown menus, quick docs, and starting from examples. When done, save/export to an Excel file, use the command loadExperiment in MATLAB to load it, and runExperiment to run (same as the coding method from that point). For example, the two tables below would make the experiment from above.

Feature highlights

In the coding method make an experiment in a MATLAB script for full flexibility. Optionally take a semi-visual approach by laying out values in spreadsheet tables and loading them into your script using the tool loadSheet. Or in the visual method make low to moderate complexity experiments fully in any spreadsheet app (Google Sheets allows dropdown menus and quick docs).
Complete flexibility in experiment structure: Implement any number of conditions of any kind, trial blocks, intros, breaks, outros, syncs, repetition, ordering, randomization, counterbalancing, etc.
Dedicated tools for various kinds of randomization and counterbalancing, including counterbalancing simultaneously with respect to any number of variables independently or jointly.
Everything in an experiment is an object, and any object works anywhere in any experiment. Objects have dozens of properties depending on object type. Omit setting any property to leave it at default.
If the open source object type library doesn't have what you need, you can add to it with your own MATLAB + Psychtoolbox code.
Set objects to start/end based on times or durations or on flexible cues like other objects, responses from subject, triggers, and more. Further timing is available through object types like sequence (e.g. for change blindness experiments).
Precise timing and time measurement, including optional time-buffering stimulus onsets/offsets, and careful synchronization across modalities (visual, auditory, etc.). A technical summary of timing processes is available.
Properties all visual objects have allow setting position on screen, drift/movement, layering, rotation, flip, transparency, intensity, contrast, convolution, noise, gamma, custom shaders, additive blending, and more. More specific functionality is in each object type.
Default units of degrees visual angle for all values relating to distance on screen, including deg, deg/sec (e.g. speed), cycles/deg (e.g. spatial frequency), etc. Optionally use other units like px, cm, proportion of window size, etc.
Stereo display by most of the modes available in Psychtoolbox.
Record any visual stimulus to image file, series of image files, or movie file using recordElements.
Sound playback and recording built on Psychtoolbox's PortAudio functions.
Core response functionality including recording responses, times and latencies, translating response values, scoring, and more. More specific functionality is in each response handler object type (keyboard, mouse, button box, etc.).
Use system-independent key names.
Test any experiment by running it in auto response mode to simulate a subject run unattended.
Customizable experiment results output drawing from any object properties or custom information, saved in both .mat and .csv files.
Sync experiments with external devices like scanners within or across trials. Set timing relative to sync with zero drift.
Method of adjustment experiments where the subject can adjust object properties in real time. More specific functionality is in each adjuster object type (key press, mouse, etc.).
Staircase any property of any object using staircase objects (fixed step, QUEST, etc.).
Save and resume an experiment run to split it across multiple sessions.
Export experiments to run online in VPixx Pack&Go.

Open-source object type library

PsychBench comes with a library of open-source MATLAB + Psychtoolbox object types.
We add new object types regularly. Please contact us with requests.

Visual

Auditory

Response handlers

Adjusters

Other

Custom code

If the library doesn't have the stimuli you need for an experiment, you can write your own code in MATLAB + Psychtoolbox. The approach is to write it as a new object type in your library—this allows you to use and reuse the code anywhere in the form of objects, parameterize and get outputs from it in the form of properties, and have it click with all core functionality (e.g. timing, core visual options, results output, working with staircases, etc.). A specialized programming framework and offloading core functionality to PsychBench makes this process efficient. You can make a quick type for just your experiments, or you can make a durable type with more flexibility and a fuller interface for other users. All the standard types that come with PsychBench are open source, so you can use them as examples and/or build off them.

Sharing object types

You can share an object type with other people just by zipping its folder and emailing it.

You can also contribute an object type to the library that comes with PsychBench. If you would like to do this, please contact us. We would be happy to credit you. And thank-you!

Getting started / Making an experiment >

Demos and examples >

All documentation >

PsychBench has been supported by