Behavioral Analyses

From CCN Wiki
Jump to navigation Jump to search

Behavioral analyses are obviously necessary in a conventional cognitive behavioral study using reaction time and/or accuracy as primary measures of interest. However these data are generally reported for fMRI studies as well, as they are reassurances that participants were performing the task as expected, and can additionally be used to filter out fMRI data associated with periods of inattentiveness or identify participants who may not have been performing the task as directed. Behavioral data generated by our PsychToolBox3 scripts are saved in .mat files. Though the format of these files can be modified, it is a near certainty that any such files will contain fields recording trial-by-trial responses and response latencies which can be analyzed to compute overall accuracy and response time values.

getPTBData.m

A MATLAB script, getPTBData.m has been written to facilitate the extraction of RT and accuracy data from the .mat files generated by our PTB3 scripts. This script should generally function on our experimental data collected at the MRI scanner or in-lab, unless the experimental paradigm necessitates a vastly different organization of the recorded behavioral data. It is assumed that the behavioral data is stored in an expinfo.data structure field within the .mat file, and within the data field can be found the fields conditon (note the typo -- this should probably be fixed at some point), response and rt. Because of the possibility that participants might enter reverse-coded responses (e.g., holding the MRI response keypad upside-down), we take the modal response for each condition as the correct response, under the assumption that participants are not responding by chance. For tasks where high accuracy is expected, this seems reasonable. However, if it seems equally plausible that a participant might get 40% vs. 60% accuracy for a condition, this approach may require some modification to also accept an answer key (and the fMRI setup procedure would need to verify correct response pad orientation). This function takes a list of filenames as an optional parameter, however it is probably more convenient to leave the parameter blank and simply select the .mat files of interest when prompted by the program. RTs and accuracy values are returned as cell arrays of vectors, and cellfun can be used as described in the help for this function to compute the mean RT and task accuracy for each of the selected files.

function [rt, acc, filenames]=getPTBData(filenames) 
%% function [RT, ACC, FILENAMES]=getPTBData(FILENAMES)
% Optional arguments:
%   FILENAMES (string): FILENAMES is a string or a cell array of strings
%   that are filenames of .mat files generated by our PsychToolBox3
%   scripts. If FILENAMES are not supplied, the user will be prompted to
%   select files from their filesystem.
%
% Returns:
% RT: a cell array of trial-by-trial RT vectors (1 for each file in
%   FILENAMES), where the RT for incorrect trials has been replaced with
%   NaN. When computing the mean RT, the user should use nanmean(RT{i})
%   rather than mean(RT{i})because of the possibility that there are NaN
%   values among the RTs.
%
% ACC: a cell array of trial-by-trial accuracy vectors (1 for each file in
%   FILENAMES).
%
% FILENAMES: a cell array of filenames that are inspected by the function.
%   If FILENAMES was provided as a parameter, then this return value will
%   be redundant. However if the filenames parameter was omitted, then this
%   return value will be useful in disambiguating which sets of RT/ACC
%   vectors correspond to which data file, in the even that multiple data
%   files were processed simultaneously.
%
% SAMPLE USAGE:
% [rt, acc, fnames]=getPTBData(); %no filenames provided; prompt to select
% cellfun(@(x) nanmean(x), rt) %compute mean RTs for each data file
% cellfun(@(x) nanmean(x), acc) %compute accuracy for each data file
%
if(~exist('filenames', 'var') || isempty(filenames))
    [f,p]=uigetfile('*.mat', 'Select a PTB Data File', 'MultiSelect', 'on');
    filenames=fullfile(p,f);
end

[rt,acc]=cellfun(@(x) extractData(x), filenames, 'UniformOutput', false);
filenames=filenames';
%helper functions
   function [RT,ACC]=extractData(matfilename)
       matfile=load(matfilename);
       data=matfile.expinfo.data;
       condition=cell2mat({data.conditon}');%per-trial condition
       response=cell2mat({data.response}');%per-trial responses
       conditions=unique(condition);%all unique experimental conditions
       responsecodes=int8(response); %convert text response codes to int
       responsecodes=responsecodes(:,1);%we only need the first column if responses are 2-character eprime '1!', '2@' codes
       %use modal response for each condition to infer the correct
       %response (on the assumption the participant has better than chance
       %accuracy)
       conditioncodes=nan(1,length(conditions));
       for i=1:length(conditions)
           conditioncodes(i)=mode(responsecodes(condition==conditions(i)));
       end
       %Use the conditioncodes to generate an answer key
       answerkey=condition;
       for i=1:length(answerkey)
           answerkey(i)=conditioncodes(conditions==answerkey(i));
       end
       ACC=responsecodes==answerkey; %accuracy vector has a TRUE/1 if the response matches the corresponding answerkey, FALSE/0 otherwise
       RT=cell2mat({data.rt}'); %extract the RT data
       RT(ACC==0)=nan; %remove all RTs where the response was incorrect (accuracy=0 for the trial)
   end
end