___________________________________________________________________________________________________________________ MONETARY INCENTIVE DELAY TASK ___________________________________________________________________________________________________________________ Script Author: Katja Borchert, Ph.D. (katjab@millisecond.com) for Millisecond Software, LLC Date: 08-28-2015 last updated: 03-10-2020 by K. Borchert (katjab@millisecond.com) for Millisecond Software, LLC Script Copyright © 03-10-2020 Millisecond Software ___________________________________________________________________________________________________________________ BACKGROUND INFO ___________________________________________________________________________________________________________________ This script implements the Monetary Incentive Delay Task; a task to induce anticipation of reward and punishment within a simple reaction time task. The implemented procedure is based on: Knutson, B., Westdorp, A., Kaiser, E., & Hommer, D. (2000). FMRI visualization of brain activity during a monetary incentive delay task. Neuroimage, 12(1), 20-27 ___________________________________________________________________________________________________________________ TASK DESCRIPTION ___________________________________________________________________________________________________________________ Participants are asked to respond to a brief target shape that follows 2 different cues: one an incentive cue (e.g. an orange shape) and the other a nonincentive cue (e.g. a blue shape). Responses to nonincentive targets (aka targets following nonincentive cues) never have an impact on money gained or money lost; nevertheless participants receive verbal feedback whether they were fast enough or not. Responses to incentive targets have different consequences depending on three different reward conditions: Control vs. Reward vs. Punishment. In the Reward condition, participants who respond fast enough to a target that follows an incentive cue get a monetary reward (e.g. $1). If they are not fast enough, no money is won. In the Punishment condition, participants who respond fast enough to a target that follows an incentive cue do not lose any money (e.g. $1). If they fail to respond in time, they lose money (e.g. $1). In the control condition, there is no difference between incentive and nonincentive targets. Participants can neither win any money, nor can they lose any. ___________________________________________________________________________________________________________________ DURATION ___________________________________________________________________________________________________________________ the default set-up of the script takes appr. 30 minutes to complete ___________________________________________________________________________________________________________________ DATA FILE INFORMATION ___________________________________________________________________________________________________________________ The default data stored in the data files are: (1) Raw data file: 'monetaryincentivedelaytask_raw*.iqdat' (a separate file for each participant) build: The specific Inquisit version used (the 'build') that was run computer.platform: the platform the script was run on (win/mac/ios/android) date, time, date and time script was run subject, group, with the current subject/groupnumber script.sessionid: with the current session id blockcode, blocknum: the name and number of the current block (built-in Inquisit variable) trialcode, trialnum: the name and number of the currently recorded trial (built-in Inquisit variable) Note: trialnum is a built-in Inquisit variable; it counts all trials run; even those that do not store data to the data file such as feedback trials. Thus, trialnum may not reflect the number of main trials run per block. values.exp_condition: 0 = control condition; 1 = Reward condition; 2 = Punishment Condition values.order: 'reward->punish' vs. 'punish->reward' values.incentive_condition: 1 = incentive; 2 = nonincentive values.delayduration: the current delay duration in ms values.targetduration: the current target duration in ms (also the response window) expressions.baselineRT60: the 60th percentile reaction time (in ms) based on mean and standard deviation: X = z-score(60th percentile)*SD + mean stimulusitem: the presented stimuli in order of trial presentation (only static elements) response: the participant's response (here: scancode of response button) correct: the correctness of the response (1 = correct; 0 = incorrect) latency: the response latency (in ms) values.total_control: the total earned in control condition values.total_reward: the total earned in reward condition values.total_punishment: the total earned in punishment condition (2) Summary data file: 'monetaryincentivedelaytask_summary*.iqdat' (a separate file for each participant) computer.platform: the platform the script was run on (win/mac/ios/android) script.startdate: date script was run script.starttime: time script was started script.subjectid: assigned subject id number script.groupid: assigned group id number script.sessionid: assigned session id number script.elapsedtime: time it took to run script (in ms); measured from onset to offset of script script.completed: 0 = script was not completed (prematurely aborted); 1 = script was completed (all conditions run) values.order: 'reward->punish' vs. 'punish->reward' expressions.meanRT_baseline:the baseline mean reaction time in ms expressions.SD_baseline: the standard deviation of the baseline reaction times in ms expressions.baselineRT60: the 60th percentile reaction time (in ms) based on mean and standard deviation: X = z-score(60th percentile)*SD + mean values.total_control: the total earned in control condition values.total_reward: the total earned in reward condition values.total_punishment: the total earned in punishment condition expressions.propCorrect_IncentiveReward: proportion correct for incentive trials in the reward condition expressions.propCorrect_NonIncentiveReward: proportion correct for nonincentive trials in the reward condition expressions.propCorrect_IncentivePunishment: proportion correct for incentive trials in the punishment condition expressions.propCorrect_NonIncentivePunishment: proportion correct for nonincentive trials in the punishment condition expressions.propCorrect_IncentiveControl: proportion correct for incentive trials in the control condition expressions.propCorrect_NonIncentiveControl: proportion correct for nonincentive trials in the control condition ___________________________________________________________________________________________________________________ EXPERIMENTAL SET-UP ___________________________________________________________________________________________________________________ 3 conditions: Control vs. Reward vs. Punishment, tested within in a blocked design. All participants start with the Control condition. The assignment to Reward -> Punishment vs. Punishment -> Reward is counterbalanced by groupnumber (odd groupnumbers start with Reward; even groupnumbers start with Punishment) In each condition: - 100 trials - 20 incentive trials - 80 nonincentive trials => The order is randomized with the constraint that incentive trials cannot be presented consecutively - the color for incentive/nonincentive trials is different for each condition Trial Sequence (6000ms): cue (500ms) -> random delay* (4000-4500ms)-> target (variable, duration = 60th percentile RT)** -> Feedback (500ms) -> ITI (variable to round trial sequence duration to ~6s) *Random Delay: is controlled by list.delay under section Editable Lists **Target Durations: in this script, the targetduration is set to the 60th percentile RT as assessed during baseline ~ 60% correct performance Knutson et al (2000) report to have used targetdurations beween 160ms and 260ms (p.21) Note: if the 60th percentile > 500ms the script aborts automatically (500ms is the max. possible target duration given all other default trial durations) ___________________________________________________________________________________________________________________ STIMULI ___________________________________________________________________________________________________________________ cues/targets: squares (size can be controlled via parameters.stimsize under section Editable Values) targets: white in all conditions Control: incentive cue: red; nonincentive cue: green Reward: incentive cue: orange; nonincentive cue: blue Punishment: incentive cue: yellow; nonincentive cue: pink ___________________________________________________________________________________________________________________ INSTRUCTIONS ___________________________________________________________________________________________________________________ are not original to Knutson et al (2000) - they can be edited under section Editable Instructions ___________________________________________________________________________________________________________________ EDITABLE CODE ___________________________________________________________________________________________________________________ check below for (relatively) easily editable parameters, stimuli, instructions etc. Keep in mind that you can use this script as a template and therefore always "mess" with the entire code to further customize your experiment. The parameters you can change are: /responsekey: the response key (default: " " = Spacebar) /cueduration: the duration of the cue in ms (default: 500) /feedbackduration: the duration of the feedback in ms (default: 500) /trialduration: the duration of a complete trial sequence in ms (default: 6000) /Reward_win: the number of points ($) won in the Reward condition (default: 1) /Punishment_loss: the number of points ($) lost in the Punishment condition (default: 1) /punishment_startamount: the amount of money provided at the beginning of the punishment condition (default: 20) /reward_startamount: the amount of money provided at the beginning of the reward condition (default: 0) /control_startamount: the amount of money provided at the beginning of the control condition (default: 0) /stimsize: the size of the cues/targets as percentages of canvas height (default: 10%) /presenttotal: true = present the "Total earned" throughout Reward and Punishment Blocks. false = does not present the "Total earned" throughout Reward and Punishment Blocks. Note: the expressions under Editable values can be changed to change the 10 targetdurations. ************************************************************************************************************** ************************************************************************************************************** EDITABLE parameters: change editable values here ************************************************************************************************************** ************************************************************************************************************** / responsekey = " " / cueduration = 500 / feedbackduration = 500 / trialduration = 6000 / Reward_win = 1 / Punishment_loss = 1 / punishment_startamount = 20 / reward_startamount = 0 / control_startamount = 0 / stimsize = 10% / presenttotal = true ************************************************************************************************************** ************************************************************************************************************** EDITABLE STIMULI: change editable stimuli here ************************************************************************************************************** ************************************************************************************************************** / 1 = "Good Job! You WIN." / 2 = "Good Job!" / 3 = "Too slow. You did NOT win." / 4 = "Too slow." / 5 = "Good Job! You did NOT lose." / 6 = "Too slow. You LOSE." ************************************************************************************************************** ************************************************************************************************************** EDITABLE INSTRUCTIONS: change instructions here ************************************************************************************************************** ************************************************************************************************************** / fontstyle = ("Arial", 3.00%, false, false, false, false, 5, 1) /file = "intro.htm" /file = "baseline.htm" /file = "teststart.htm" /file = "control.htm" /file = "control2.htm" /file = "reward.htm" /file = "reward2.htm" /file = "rewardend.htm" /file = "punishment.htm" /file = "punishment2.htm" /file = "punishmentend.htm" /file = "end.htm" This alert appears on screen if the 40th percentile of baseline reaction times falls below 100ms or above 500ms (max. possible duration) / items = ("reaction times are outside of boundaries. Script will be aborted.") / vjustify = center / fontstyle = ("Arial", 5%, false, false, false, false, 5, 1) / position = (50%, 50%) / txcolor = white / erase = false **************************************************************************************************** general instruction expressions: adjust the instruction text depending on device used to run script **************************************************************************************************** / buttoninstruct1 = if (computer.touch && !computer.haskeyboard) {"SPACE response button which will be located at the bottom of your screen";} else {"SPACEBAR";} / buttoninstruct2 = if (computer.touch && !computer.haskeyboard) {"response button";} else {"SPACEBAR";} ************************************************************************************************************** ************************************************************************************************************** EDITABLE LISTS: change editable lists here ************************************************************************************************************** ************************************************************************************************************** / items = (4000, 4100, 4200, 4300, 4400, 4500) / replace = true ************************************************************************************************************** !!!REMAINING CODE: Customize after careful consideration only!!! ************************************************************************************************************** ************************************************************************************************************** ************************************************************************************************************** DEFAULTS ************************************************************************************************************** ************************************************************************************************************** script requires Inquisit 6.1.0.0 or higher / canvasaspectratio = (4,3) / minimumversion = "6.1.0.0" / fontstyle = ("Arial", 3%, false, false, false, false, 5, 1) / txbgcolor = black / txcolor = (white) / screencolor = black ************************************************************************************************************** ************************************************************************************************************** DATA ************************************************************************************************************** ************************************************************************************************************** Note: data file explanations under User Manual Information at the top *********************** raw data file *********************** / columns = (build, computer.platform, date, time, subject, group, script.sessionid, blockcode, blocknum, trialcode, trialnum, values.exp_condition, values.order, values.incentive_condition, values.delayduration, values.targetduration, expressions.baselineRT60, stimulusitem, response, correct, latency, values.total_control, values.total_reward, values.total_punishment) *********************** summary data file *********************** / columns = (computer.platform, script.startdate, script.starttime, script.subjectid, script.groupid, script.sessionid, script.elapsedtime, script.completed, values.order, expressions.meanRT_baseline, expressions.SD_baseline, expressions.baselineRT60, values.total_control, values.total_reward, values.total_punishment, expressions.propCorrect_IncentiveReward, expressions.propCorrect_NonIncentiveReward, expressions.propCorrect_IncentivePunishment, expressions.propCorrect_NonIncentivePunishment, expressions.propCorrect_IncentiveControl, expressions.propCorrect_NonIncentiveControl) ************************************************************************************************************** ************************************************************************************************************** VALUES: automatically updated ************************************************************************************************************** ************************************************************************************************************** /order: 'reward->punish' vs. 'punish->reward' /exp_condition: 0 = control condition; 1 = Reward condition; 2 = Punishment Condition /incentive_condition: 1 = incentive; 2 = nonincentive /delayduration: the current delay duration in ms /targetduration: the current target duration in ms /total: helper variable that stores the total money for the current block /total_control: the total earned in control condition /total_reward: the total earned in reward condition /total_punishment: the total earned in punishment condition /feedback: stores the itemnumber of the current feedback stimulus /iti: stores the duration of the current iti duration / order = "" / exp_condition = 1 / incentive_condition = 1 / delayduration = 0 / targetduration = 0 / total = 0 / total_control = 0 / total_reward = 0 / total_punishment = 0 / feedback = 0 / iti = 0 ************************************************************************************************************** ************************************************************************************************************** EXPRESSIONS ************************************************************************************************************** ************************************************************************************************************** IMPORTANT NOTE: with the default settings of trialduration = 6000ms cueduration = 500ms max. delay = 4500ms feedback = 500ms the max. targetduration that is possible is 500ms. Knutson et al (2000) report to have used targetdurations beween 160ms and 260ms (p.21)- /meanRT_baseline: determines the baseline mean reaction time in ms /SD_baseline: determines the standard deviation of the baseline reaction times in ms /baselineRT60: determines the 60th percentile reaction time (in ms) based on mean and standard deviation: X = z-score(60th percentile)*SD + mean (60th percentile = 60% of all reaction times lie below it) /determineDuration: determines the target Duration for a given trial (rounds baselineRT60 to the nearest digit) /propCorrect_IncentiveReward: proportion correct for incentive trials in the reward condition /propCorrect_NonIncentiveReward: proportion correct for nonincentive trials in the reward condition /propCorrect_IncentivePunishment: proportion correct for incentive trials in the punishment condition /propCorrect_NonIncentivePunishment:proportion correct for nonincentive trials in the punishment condition /propCorrect_IncentiveControl: proportion correct for incentive trials in the control condition /propCorrect_NonIncentiveControl: proportion correct for nonincentive trials in the control condition / meanRT_baseline = list.baselineRT.mean / SD_baseline = list.baselineRT.standarddeviation / baselineRT60 = 0.2533*expressions.SD_baseline + expressions.meanRT_baseline / determineDuration = round(expressions.baselineRT60) / propCorrect_IncentiveReward = list.successIncentive_Reward.mean / propCorrect_NonIncentiveReward = list.successNonIncentive_Reward.mean / propCorrect_IncentivePunishment = list.successIncentive_Punishment.mean / propCorrect_NonIncentivePunishment = list.successNonIncentive_Punishment.mean / propCorrect_IncentiveControl = list.successIncentive_Control.mean / propCorrect_NonIncentiveControl = list.successNonIncentive_Control.mean ************************************************************************************************************** ************************************************************************************************************** INSTRUCTIONS ************************************************************************************************************** ************************************************************************************************************** ************************************************************************************************************** ************************************************************************************************************** STIMULI ************************************************************************************************************** ************************************************************************************************************** / shape = rectangle / size = (parameters.stimsize * 0.75, parameters.stimsize) / position = (50%, 50%) / color = red / shape = rectangle / size = (parameters.stimsize * 0.75, parameters.stimsize) / position = (50%, 50%) / color = red / shape = rectangle / size = (parameters.stimsize * 2 * 0.75, parameters.stimsize * 2) / position = (50%, 50%) / color = black / shape = rectangle / size = (parameters.stimsize * 0.75, parameters.stimsize) / position = (50%, 50%) / color = white / items = feedback / select = values.feedback / vjustify = center / fontstyle = ("Arial", 5%, false, false, false, false, 5, 1) / items = (" Total = $<%values.total%> ") / vjustify = center / fontstyle = ("Arial", 3%, false, false, false, false, 5, 1) / position = (50%, 90%) / txcolor = gray / erase = false ************************************************************************************************************** ************************************************************************************************************** LISTS ************************************************************************************************************** ************************************************************************************************************** Note: list.baselineRT fills during runtime with all baseline latencies Note: the following lists store the success (1) and failures (0) for each experimental condition, separately for incentive/nonincentive trials ************************************************************************************************************** ************************************************************************************************************** TRIALS ************************************************************************************************************** ************************************************************************************************************** Note: trial.baseline presents a simple reaction time task * after a variable duration (randomly sampled with replacement), the target appears and participant has to press the responsekey as fast as possible * latencies are stored in list.baselineRT / ontrialbegin = [ values.delayduration = list.delay.nextvalue; trial.baseline.insertstimulustime(shape.target, values.delayduration); ] / validresponse = (parameters.responsekey) / beginresponsetime = values.delayduration / ontrialend = [ trial.baseline.resetstimulusframes(); list.baselineRT.insertitem(trial.baseline.latency, 1); ] / skip = [ expressions.baselineRT60 < 500 ] / stimulusframes = [1 = alert] / trialduration = 1000 / ontrialend = [ script.abort(); ] Note: * trial presents cue (programmed as static stimulus) and target (programmed as dynamic stimulus) * takes in responses at onset of target * times out after response OR after (cueduration+delay+targetduration) whichever comes first * calculates values.iti and calls trial.feedback / ontrialbegin = [ values.incentive_condition = 1; values.iti=0; values.targetduration = expressions.determineDuration; values.delayduration = list.delay.nextvalue; trial.incentive.insertstimulustime(shape.eraser, parameters.cueduration); trial.incentive.insertstimulustime(shape.target, (parameters.cueduration + values.delayduration)); ] / stimulustimes = [0 = incentivecue, total] / beginresponsetime = parameters.cueduration + values.delayduration / response = timeout(values.targetduration) / validresponse = (parameters.responsekey) / correctresponse = (parameters.responsekey) / monkeyresponse = (parameters.responsekey) / ontrialend = [ trial.incentive.resetstimulusframes(); values.iti = parameters.trialduration - parameters.cueduration - values.delayduration - trial.incentive.latency - parameters.feedbackduration; if (values.exp_condition == 0) { list.successIncentive_Control.insertitem(trial.incentive.correct, 1); } else if (values.exp_condition == 1) { list.successIncentive_Reward.insertitem(trial.incentive.correct, 1); } else if (values.exp_condition == 2) { list.successIncentive_Punishment.insertitem(trial.incentive.correct, 1); } ; ] / branch = [return trial.feedback;] Notes: * trial presents cue (programmed as static stimulus) and target (programmed as dynamic stimulus) * takes in responses at onset of target * times out after response OR after (cueduration+delay+targetduration) whichever comes first * calculates values.iti and calls trial.feedback / ontrialbegin = [ values.incentive_condition = 2; values.iti=0; values.targetduration = expressions.determineDuration; values.delayduration = list.delay.nextvalue; trial.nonincentive.insertstimulustime(shape.eraser, parameters.cueduration); trial.nonincentive.insertstimulustime(shape.target, (parameters.cueduration + values.delayduration)); ] / stimulustimes = [0 = nonincentivecue, total] / beginresponsetime = parameters.cueduration + values.delayduration / responseinterrupt = immediate / response = timeout(values.targetduration) / validresponse = (parameters.responsekey) / correctresponse = (parameters.responsekey) / monkeyresponse = (parameters.responsekey) / ontrialend = [ trial.nonincentive.resetstimulusframes(); values.iti = parameters.trialduration - parameters.cueduration - values.delayduration - trial.nonincentive.latency - parameters.feedbackduration; if (values.exp_condition == 0) { list.successNonIncentive_Control.insertitem(trial.nonincentive.correct, 1); } else if (values.exp_condition == 1) { list.successNonIncentive_Reward.insertitem(trial.nonincentive.correct, 1); } else if (values.exp_condition == 2) { list.successNonIncentive_Punishment.insertitem(trial.nonincentive.correct, 1); }; ] / branch = [return trial.feedback;] Note: trial.feedback presents the appropriate feedback for a predetermined duration (Note: code that determines the feedback can be found under BLOCKS) IF the current trial was an incentive trial, trial.feedback calls a nonincentive trial next to avoid consecutive incentive trials / ontrialbegin = [ if (values.feedback == 1 || values.feedback == 2 || values.feedback == 5) { text.feedback.textcolor = green; } else { text.feedback.textcolor = red; }; ] / stimulusframes = [1 = feedback, total] / timeout = parameters.feedbackduration / posttrialpause = values.iti / recorddata = false / branch = [ if (values.incentive_condition == 1) { return trial.nonincentive; }; ] ************************************************************************************************************** ************************************************************************************************************** BLOCKS ************************************************************************************************************** ************************************************************************************************************** Note: runs the baseline trials to assess baseline RT / onblockbegin = [ values.exp_condition = "baseline"; values.incentive_condition = 0; ] / preinstructions = (baseline) / postinstructions = (testStart) / trials = [ 1-10 = baseline; 11 = baselineAlert; ] Note: block.control/reward/punishment run 100 trials: 20 incentive, 80 nonincentive trials. The order is randomized with the constraint that incentive trials cannot be presented consecutively. To prevent consecutive incentive trials, each incentive trial is followed by a nonincentive trial (this is programmed on the trial level via branch commands) => 20 incentive trials (followed automatically by 20 nonincentive trials) + 60 nonincentive trials => 80 trials called on the block level. The blocks differ in the feedback presented and calculations of total points. / preinstructions = (Control, Control2) / onblockbegin = [ values.exp_condition = 0; values.total_control = parameters.control_startamount; values.total = values.total_control; text.total.textcolor = black; shape.incentivecue.color = red; shape.nonincentivecue.color = green; ] / trials = [1-80 = noreplace(incentive, nonincentive, nonincentive, nonincentive)] / ontrialend = [ if (values.incentive_condition == 1){ if (trial.incentive.correct) { values.feedback = 2; } else if (trial.incentive.error) { values.feedback = 4; }; } else if (values.incentive_condition == 2){ if (trial.nonincentive.correct) { values.feedback = 2; } else if (trial.nonincentive.error) { values.feedback = 4; }; }; ] / preinstructions = (Reward, Reward2) / postinstructions = (RewardEnd) / onblockbegin = [ values.exp_condition = 1; values.total_reward = parameters.reward_startamount; values.total = values.total_reward if (parameters.presenttotal == 1){ text.total.textcolor = gray; } else { text.total.textcolor = black; }; shape.incentivecue.color = orange; shape.nonincentivecue.color = blue ] / trials = [1-80 = noreplace(incentive, nonincentive, nonincentive, nonincentive)] / ontrialend = [ if (values.incentive_condition == 1){ if (trial.incentive.correct && script.currenttrial != "feedback" ) { values.total_reward += parameters.Reward_win; values.feedback = 1; values.total = values.total_reward; } else if (trial.incentive.error) { values.feedback = 3; }; } else if (values.incentive_condition == 2){ if (trial.nonincentive.correct) { values.feedback = 2; } else if (trial.nonincentive.error) { values.feedback = 4; }; }; ] / preinstructions = (Punishment, Punishment2) / postinstructions = (PunishmentEnd) / onblockbegin = [ values.exp_condition = 2; values.total_punishment = parameters.punishment_startamount; values.total = values.total_punishment; if (parameters.presenttotal == 1){ text.total.textcolor = gray; } else { text.total.textcolor = black; }; shape.incentivecue.color = yellow; shape.nonincentivecue.color = pink ] / trials = [1-80 = noreplace(incentive, nonincentive, nonincentive, nonincentive)] / ontrialend = [ if (values.incentive_condition == 1){ if (trial.incentive.correct) { values.feedback = 5; } else if (trial.incentive.error && script.currenttrial != "feedback") { values.total_punishment -= parameters.Punishment_loss; values.total = values.total_punishment; values.feedback = 6; }; } else if (values.incentive_condition == 2){ if (trial.nonincentive.correct) { values.feedback = 2; } else if (trial.nonincentive.error) { values.feedback = 4; }; }; ] ************************************************************************************************************** ************************************************************************************************************** EXPERIMENT ************************************************************************************************************** ************************************************************************************************************** Note: order of reward and punishment blocks (after control) counterbalanced by groupnumber odd groupnumbers -> reward, punishment even groupnumbers -> punishment, reward / groups = (1 of 2) / preinstructions = (Intro) / postinstructions = (End) / onexptbegin = [values.order="reward->punish"] / blocks = [ 1 = baseline; 2 = control; 3 = reward; 4 = punishment; ] / groups = (2 of 2) / preinstructions = (Intro) / postinstructions = (End) / onexptbegin = [values.order="punish->reward"] / blocks = [ 1 = baseline; 2 = control; 3 = punishment; 4 = reward; ] / latencydistribution = normal(230,10) ************************************************************************************************************** End of File **************************************************************************************************************