Controlling Screen luminance during a VEP

Hello fellow Psychtoolbox users,

I am a new masters student in vision science at Ohio Sate University and am working on a project involving visually evoked potentials in the occipital lobe. I have used the psychtoolbox to code a simple VEP that is just a monitor that flashes black and white at a specific frequency. I have some decent previous matlab experience, but I am new to psychtoolbox. I am looking for a way to code a control over screen luminance into my VEP script. Essentially, we want to be able to select a value for the luminance, plug that into the function, and have the code adjust the screen brightness as the VEP is running to maintain the average luminance. Does anyone know how this might be possible?

Here is my code - it’s about 60 lines of text. Sorry I couldn’t figure out how to attach the .txt file.

function bwssvep(freq)

if ~exist('freq','var') || isempty(freq)
    freq = 11;
end

if ~exist('baseColor1','var') || isempty(baseColor1)
    baseColor1 = [0 0 0 1];
end

if ~exist('baseColor2','var') || isempty(baseColor2)
    baseColor2 = [1 1 1 1];
end

% Setup defaults and unit color range:
PsychDefaultSetup(2);

oldSyncLevel = Screen('Preference', 'SkipSyncTests', 2);

screenid = max(Screen('Screens'));

PsychImaging('PrepareConfiguration');
PsychImaging('AddTask', 'General', 'FloatingPoint32BitIfPossible');
[win, winRect] = PsychImaging('OpenWindow', screenid, baseColor1);

ifi = Screen('GetFlipInterval', win);

% Preperatory flip
time = 1/freq;
total_iterations=10/time;

for n=1:total_iterations

vbl = Screen('Flip', win);
tstart = vbl + ifi; %start is on the next frame

while vbl < tstart + time
   
    Screen('FillRect',win, baseColor1);
    vbl = Screen('Flip', win, vbl + 0.5 * ifi);

end

% Preperatory flip
vbl = Screen('Flip', win);
tstart = vbl + ifi; %start is on the next frame

while vbl < tstart + time
    
    Screen('FillRect',win, baseColor2);
    vbl = Screen('Flip', win, vbl + 0.5 * ifi);

end

n;
end
% Close onscreen window, release all resources:
sca;

% Restore old settings for sync-tests:
Screen('Preference', 'SkipSyncTests', oldSyncLevel);

It is kind of unclear exactly what you want to do. Luminance is a physical measure of emitted light energy, brightness is a subjective perception (two things can have the same luminance but different perceived brightness); I assume you are not working on subjective brightness perception. You need a photometer to measure your luminous output across the whole range (from [0 0 0] to [1 1 1]), this gets you the relationship between your floating point RGB numbers and what physical light level is emitted. Then normally you need to correct the non-linearity of your display as most have a gamma curve adjustment. Once you have a correction curve, you apply it with PTB and now you know precisely how your RGB value relates to the luminous output, and you can flicker at values plus/minus a given point on that curve to result in the same averaged luminance but a range of different contrasts.

This plot is taken from one of my monitors, top-left showing the non-linear raw luminances (filled dots), and the corrected luminances (open circles) for the [RGB] combined and [R] [G] and [B] channels separately. These measurements were made using a SpectroCal II from CRS, but any photometer will do…

For flicker-VEP, we prefer to use square / sinewave gratings or checkerboards and reverse the phase, but full field flash also works depending on your scientific question…

1 Like

Thank you so much for your response. I was wondering if there was a way to control output without a photometer, but we were just able to get one for our lab so we will be using that.

There are a bunch of PTB scripts like CalibrateMonitotPhotometer.m and friends that should help. The code that generated my plot above (supports i1Pro from VPixx and ColorCal/Spectrocal from CRS) is found here. The simplest route is to estimate a gamma value and the correct, but more accurately is to fit a model then invert it to apply to the linear values.

1 Like