Contents

Present a drifting gabor patch with cogent

drift speed discrimination task, or adaptation task Elliot Freeman 0207

p.dataFile = 'speedDiscrimData';  % name of file to save data into
p.condition = 1;                  % use this to identify the type of block
p.gam = 2.2;                      % p.gamma value from calibration procedure
p.contrast = .5;                  % p.contrast of gabor patch
p.windowmode = 0;                 % 0: small window; 1: full screen
p.horizontalResolution = 1024;    % horizontal screen resolution in pixels: select from [640 800 1024 1152 1280 1600]
p.imageFile = 'gaborMovie';       % filename of image matrix
p.RGB = [1 1 1];                  % maximum luminance of horizontalResolution guns (before scaling by overall p.contrast)
p.contrast = 1;                   % overall p.contrast of images
p.refreshRate = 75;               % refresh rate of screen in hertz
p.trialDuration = 100;            % duration of each stimulus presentation (ms)
p.ISI = 500;                      % inter stimulus interval (ms)
p.fixPos = [0 0];                 % X and Y position of stimulus
p.stimPos = [0 100];              % X and Y position of stimulus
p.fixSize = 5;                    % size of fixation point
p.nTrial = 10;                    % number of trials
p.escapeKey = 52;                 % code for escape key
p.responseKeys = [97 98];         % codes for left and right-arrow keys
p.baseLineStimulus = 5;           % speed of non-target stimulus (how many times movie is played per second)
p.minMaxLevels = [5 20];          % minimum and maximum increment to use in target
p.nLevels = 5;                    % number of levels of stimulus increments
p.nBlocks = 1;                    % number of blocks
p.magnification = 2;              % scale to magnify stimulus

first check if a data file of the same name already exists

first add .mat suffix to datafile name if missing

dataFile = p.dataFile;
[PATHSTR,NAME,EXT,VERSN] = fileparts(dataFile);
if isempty(EXT)
    dataFile = [dataFile '.mat'];
end
if exist(dataFile, 'file')                              % choice of saving a new file, overwriting or aborting
    button = questdlg('Data file already exists. What to do?', '', 'Append', 'Overwrite', 'Save New', 'Append');
    switch button
        case 'Overwrite'
            drawnow;        % this makes dialogue box go away
        case 'Save New'
            [filename, pathname] = uiputfile('*.mat', 'Save data as');  % select new datafile
            p.dataFile = fullfile(pathname, filename);
            drawnow;
        case 'Append'
            load dataFile;
            drawnow;
        otherwise break;
    end
end
Error: A BREAK statement appeared outside of a loop. Use RETURN instead.

seed random number generator

rand('state',sum(100*clock));

load movie matrix

load(p.imageFile, 'im');                                  % load movie matrix
[sX sY nFrames] = size(im);                             % get dimensions and number of frames

computed constants

bg = .5 .^ (1/p.gam);                                     % calculate p.gamma corrected mid-gray background value
stimValues = linspace( p.minMaxLevels(1), p.minMaxLevels(2), p.nLevels);   % how much each level modulates baseline stimulus value

start cogent

resVal = [640 800 1024 1152 1280 1600];                 % possible screen resolutions
resCode = find(p.horizontalResolution == resVal);         % select one
config_display(p.windowmode,resCode,[bg bg bg], [1 1 1]); % configure graphics window
config_keyboard;                                        % set up keyboard
start_cogent;                                           % start cogent

make fixation sprites

fixSprite = 1000;
cgMakeSprite(fixSprite, p.fixSize, p.fixSize, bg, bg, bg);             % make a new sprite
cgSetSprite(fixSprite);
cgEllipse(p.fixPos(1), p.fixPos(2), p.fixSize, p.fixSize, [1 1 1], 'f');
fixSprite = 1000;
cgMakeSprite(fixSprite+1, p.fixSize, p.fixSize, bg, bg, bg);             % make a new sprite
cgSetSprite(fixSprite+1);
cgEllipse(p.fixPos(1), p.fixPos(2), p.fixSize, p.fixSize, [0 0 0], 'f');
cgSetSprite(0);

create each movie frame in a separate sprite

for iFrame = 1:nFrames                                  % loop through frames
    imF = im(:,:,iFrame);                                  % extract frame from movie matrix

    % To load the images into sprites, Cogent needs a three column matrix:
    % each column contains the luminance values for Red Green and Blue
    % respectively. To make this matrix,
    % (1) transpose each image frame (explanation below) and
    % (2) scale each column by the appropriate values of RGB to manipulate
    % the colour of the resulting image

    imR = imF' * p.RGB(1);                                  % vector for red guns
    imG = imF' * p.RGB(2);                                  % vector for green guns
    imB = imF' * p.RGB(3);                                  % vector for blue guns

    % (3) now squash each R G or B image into a single column vector
    % (4) and horizontally concatenate into three column matrix
    imRGB = [imR(:) imG(:) imB(:)];                                  % now compile in to three-column matrix

    % finally apply overall contrast scaling, recenter values on 0.5, gamma correct
    imRGB0 = imRGB .* p.contrast;                          % apply contrast modulation to whole matrix
    imRGB1 = ( imRGB0 +1 ) /2;                            % convert values of -1->1 to 0->1 (gray is now .5)
    imRGB_gamma = imRGB1 .^ ( 1/ p.gam );                   % apply p.gamma correction to image

    % make a new sprite and put image into it
    cgMakeSprite(iFrame, sX, sY, bg, bg, bg);             % make a new sprite
    cgloadarray(iFrame, sX,sY,imRGB_gamma);               % load image frame into sprite
end

block loop

% initialize variables
abortFlag = 0;                                                  % reset flag for aborting experiment
trialData = [];                                                 % clear record of trial data

for iblock = 1: p.nBlocks

    %% wait for any key (escape to quit)
    cgflip(bg, bg, bg);                                         % blank screen
    cgtext(sprintf('Block %d', iblock), 0,100);
    cgflip(bg, bg, bg);                                         % blank screen
    [ keyout, t, n ] = waitkeydown(inf);                        % wait forever for a key to be preset
    if keyout == p.escapeKey || abortFlag                         % if the key was 'escape' or the abortFlag was set
        break                                                   % jump to end of experiment where data can be saved
    end

    %% random sequence of stimulus modulations
    stimLevels0 = repmat(1:p.nLevels, 1, ceil(p.nTrial / p.nLevels)); % every level gets repeated the same number of times
    randomIndices = randperm(length(stimLevels0));              %  randomly permuted vector of indices
    stimLevels = stimLevels0(randomIndices);                    % use random vector to reorder levels

    %% trial sequence
    for iTrial = 1: p.nTrial
        targetInterval = round(rand(1)) + 1;                        % which interval has the target? random binary choice: 1 or 2 (first or second)

        %% put up fixation
        cgflip(bg, bg, bg);
        cgDrawSprite(fixSprite, p.fixPos(1), p.fixPos(2));          % put spot in fixation position
        cgDrawSprite(fixSprite, p.stimPos(1), p.stimPos(2));        % also a placeholder for the stimulus location
        cgflip(bg, bg, bg);

        wait(500);                                                 % delay before trial

        % two interval forced-choice procedure: target and non-target
        % intervals in unpredictable order; subject has to choose which
        % contained the target.
        for iInterval = 1:2                                          % interval loop
            if iInterval == targetInterval                           % in the target interval...
                thisStimValue = stimValues(stimLevels(iInterval));   % pick current target value
            else                                                     % in the non-target interval...
                thisStimValue = p.baseLineStimulus;                    % set to baseline value
            end

            %% work out how fast to play movie
            framesPerSecond = (thisStimValue) * nFrames;             % how many frames shown per second
            frameIncrement = framesPerSecond / p.refreshRate;          % how much to increment frame count every screen refresh

            %% display movie
            wait(p.ISI);
            iFrame = 0;
            t0 = time;
            while time < (t0 + p.trialDuration)
                iFrame = iFrame + frameIncrement;
                mFrame = mod(iFrame-1, nFrames)+1;
                cgDrawSprite(mFrame, p.stimPos(1), p.stimPos(2), sX * p.magnification, sY * p.magnification);
                cgDrawSprite(fixSprite, p.fixPos(1), p.fixPos(2));
                cgflip(bg, bg, bg);
            end

            cgDrawSprite(fixSprite, p.fixPos(1), p.fixPos(2));        % white fixation spot between intervals
            cgflip(bg, bg, bg);
        end

        %% collect responses
        cgDrawSprite(fixSprite+1, p.fixPos(1), p.fixPos(2));           % black fixation dot to prompt response
        cgflip(bg, bg, bg);
        clearkeys;                                                     % clear keyboard buffer of any previous entries
        [ keyout, rt, n ] = waitkeydown(inf, [p.responseKeys p.escapeKey]);            % wait forever for one of the response keys to be preset
        if any(keyout == p.escapeKey)                                   % abort sequence
            abortFlag = 1;                                              % when we exit trial loop, block loop is still active. Pass back abortFlag to quit block loop
            break;                                                      % exit trial loop
        end
        whichKey = find(keyout(1) == p.responseKeys);                    % check whether the first keypress was the left or right-arrow key
        correct = (whichKey == targetInterval);                        % check if subject correctly chose target interval (1=correct)
        trialData(iTrial,:) = [thisStimValue targetInterval whichKey correct rt];   % compile results for this trial
        disp(trialData(iTrial,:));                                     % display result on console
    end % trial loop

    %% compile results into structure and save
    [z,tm]=dos('time /T');    [z,d]=dos('date /T');

    data.time = [d tm];                           % timestamp
    data.trialData = trialData;                   % record of trial stimulus and response
    data.condition = p.condition                  % condition code
    results(end + 1).data = data;                  % append data structure to results structure
    results(end + 1).params = p;                   % append parameters to results structure too
    save(p.dataFile, 'results');                  % save results to disk

end % block loop
stop_cogent