By avtobin - 10/28/2015
Within a parametric n-back task, I'm trying to code an 'if' statement to send out a marker to the parallel port specific to the current level of n-back on trial begin (so I can record ERPs and differentiate later between n-back loads). So, I think I need the program to evaluate an if statement each trial to select markers 1, 2 or 3 for a correct response under conditions 1, 2, or 3-back, and similarly select makers 4, 5, or 6 for incorrect responses under conditions 1, 2 or 3-back. Within the script there are 3 types of trials: start responses, non-target responses and target responses. I've copied and pasted the script below - currently its only programmed to send out a marker '1' for incorrect responses and '2' for correct responses. New to coding and any help would be appreciated :)
DEFAULTS
requires Inquisit 4.0.0.0 or higher
<defaults> / lptaddresses = (lpt3 = 0xE800) /minimumversion = "4.0.0.0" / screencolor = black </defaults> /canvasaspectratio = (4,3)
************************************************************************************************************************************************************************
************************************************************************************************************************************************************************ CUSTOM VALUES
********************* editable parameters ********************* /StartN = 2the starting N !!!Note: if the starting N changes other changes may need to be made, e.g. instructions /LastN = 4the last N run !!!Note: if the last N changes, other changes may need to be made /RepetitionPractice = 1Number of repretitions per level N during pactice (default for practice is 1) /RepetitionTest = 3Number of repetitions per level N during testing (default for test is 3) /debugmode = 0debugmode = 1: targetalerts are shown on screen, debugmode = 0, no targetalerts are shown (default)
<values> /StartN = 1 /LastN = 3
/RepetitionTest = 3 /debugmode = 0 </values>
********************* updated at runtime *********************
/completed:0 = script was not completed (script was prematurely aborted); 1 = script was completed (all conditions run)
minus1:contains the stimulusitemnumber of the stimulus in the trial preceding the current one minus2:contains the stimulusitemnumber of the stimulus shown 2 trials before the current one minus3:contains the stimulusitemnumber of the stimulus shown 3 trials before the current one minus4:contains the stimulusitemnumber of the stimulus shown 4 trials before the current one stim:contains the current stimulusitem stimnumber:contains the current stimulusitemnumber N:the lag between a target and the stimulus it repeats currenttarget:contains the stimulusnumber of the current target (a target in N = 0 trials is a stimulus with the same stimulus number as stored in target0) Hits:codes the number of correctly identifiying a target FalseA:codes the number of times a participant identifies a non-target as a target Misses:codes the number of times a participant misses to identify a target CorrReject:codes the number of times a participant correctly identifies a non-target (and does nothing) values.TotalHits:the number of total hits across all experimental blocks values.TotalFA:the number of total false alarms across all experimental blocks values.TotalBlocks:the total number of experimental blocks run values.DV:dependent variable (DV) in Jaeggi et al (2010): the proportion of (TotalHits - TotalFA)/number of total blocks starttrialcounter:keeps track of how many start trials have been run repetitioncounter:keeps track of how many times an experimental block has been run
<values > /completed = 0 /minus1 = 0 /minus2 = 0 /minus3 = 0
/N = 0 /currenttarget = 0 /Hits = 0 /FalseA = 0 /Misses = 0 /CorrReject = 0 /TotalHits = 0 /TotalFA = 0 /DV = 0 /TotalBlocks = 0 /starttrialcounter = 0 /repetitioncounter = 0 </values>
**************************ADDITIONAL N-LEVELS************************************* * if additional N-levels are needed, create and add further "minusN" values and set them to 0, Example: N = 5 /minus5 = 0
************************************************************************************************************************************************************************
************************************************************************************************************************************************************************ EXPRESSIONS
expressions.selectinstruct helps to select the adequate instructions for adaptive n-back testing
<expressions> /selectinstruct = values.N + 1 </expressions> ************************************************************************************************************************************************************************
************************************************************************************************************************************************************************ DATA COLLECTION
this implementation suggests to collect the following information: date:Date of Experiment time:Time of Day subject:Subjectnumber values.N:the type of N-back trial blockcode:the name of the current block values.TotalBlocks:the total number of experimental blocks run trialcode:the name of the current trial stimulusitem:the file of the stimulus shown during a trial stimulusnumber:the item number of the stimulus shown during a trial values.currenttarget:the item number of the current target response:the response of the participant correct:the correctness of the response latency:how fast a participant responded within the 3000ms timeframe, if at all values.Hits:the sum of Hits in a block values.FalseA:the sum of False Alarms in a block values. Misses:the sum of Misses in a block values.CorrReject:the sum of Correct Rejections in a block values.TotalHits:the sum of total hits across all experimental blocks values.TotalFA:the number of total false alarms across all experimental blocks values.DV:the proportion of (TotalHits - TotalFA)/number of experimental blocks
***************** raw data *****************
<data> /file = "SingleTaskNback_rawdata.iqdat" /columns = [date, time, subject, values.N, blockcode, values.TotalBlocks, trialcode, trialnum, stimulusitem, stimulusnumber, values.currenttarget, response, correct, latency, values.Hits, values.FalseA, values.Misses, values.CorrReject, values.TotalHits, values.TotalFA, values.DV] / separatefiles = true </data>
***************** summary data ***************** script.startdate:date script was run script.starttime:time script was started script.subjectid:subject id number script.groupid:group id number script.elapsedtime:time it took to run script (in ms) /completed:0 = script was not completed (script was prematurely aborted); 1 = script was completed (all conditions run)
values.TotalHits:the sum of total hits across all experimental blocks values.TotalFA:the number of total false alarms across all experimental blocks values.DV:the proportion of (TotalHits - TotalFA)/number of experimental blocks
<summarydata > /file = "SingleTaskNback_summary.iqdat" /columns = [script.startdate, script.starttime, script.subjectid, script.groupid, script.elapsedtime, values.completed, values.TotalHits, values.TotalFA, values.DV] </summarydata>
************************************************************************************************************************************************************************
************************************************************************************************************************************************************************ INSTRUCTIONS
***********INSTRUCTION SLIDES***************************** *******CODE CHANGES: If you would like to run different levels of N in practice/experimental trials, change/add the necessary instruction slides as well as pay attention to the changes necessary under "Instruction Blocks"
* Slides 1-5 are ORIGINAL* instructions for N=2-4, kindly provided by Jaeggi et al. (*one minor change: use of SPACEBAR instead of anykey to advance) <item Nback_startinstructions> /1 = "SingleNbackInstructions_start alice.gif" /2 = "SingleNbackInstructions_N1 alice.gif" /3 = "SingleNbackInstructions_N2 alice.gif" /4 = "SingleNbackInstructions_N3 alice.gif"
</item>
NOTE: *the remaining items/instructions provided (for N=0, N=1) were modelled after them -> "SingleNbackInstructions_N1 alice.gif" -> "SingleNbackInstructions_practice012.gif" -> "SingleNbackInstructions_practice123.gif" -> "SingleNbackInstructions_practice0123.gif"
*original slide
</item> NOTE: *the remaining items/instructions provided (for N=0, N=1) were modelled after them: -> "SingleNbackInstructions_practiceend0123.gif", -> "SingleNbackInstructions_practiceend012.gif", -> "SingleNbackInstructions_practiceend123.gif"
*slides to start experimental trials/end experiment <item startendslides> /1 = "StartExpt.gif" /2 = "ThankYouSlide.gif" </item>
*Instructions for individual experimental N-levels (not original) <item expinstructions> /1 = "SingleNbackInstructionsN1exp alice.gif" /2 = "SingleNbackInstructionsN2exp alice.gif" /3 = "SingleNbackInstructionsN3exp alice.gif" /4 = "SingleNbackInstructionsN4exp alice.gif" </item>
***********INSTRUCTION IMAGE SELECTION****************************************** <picture SingleNbackinstructions_start> / items = Nback_startinstructions / select = sequence / size = (100%, 100%) </picture>
<picture StartExp_slide> / items = startendslides / select = 1 / size = (100%, 100%) </picture>
<picture EndExp_slide> / items = startendslides /select = 2 / size = (100%, 100%) </picture>
*instructions for individual experimental trials are selected depending on level of N <picture expinstructionslide> /items = expinstructions /select = expressions.selectinstruct /size = (100%, 100%) </picture>
***********INSTRUCTION TRIALS******************************************* <trial Nbackinstruct_starttrial> / stimulusframes = [1 = SingleNbackinstructions_start] / validresponse = (57) / recorddata = false </trial>
<trial StartExp_trial> / stimulusframes = [1 = StartExp_slide] / validresponse = (57) / recorddata = false </trial>
<trial expinstructiontrial> / stimulusframes = [1 = expinstructionslide] / validresponse = (57) / recorddata = false </trial>
*****stores TotalHits, TotalFA, and DV into datafile <trial EndExp_trial> / stimulusframes = [1 = EndExp_slide] / validresponse = (57) / recorddata = false </trial>
*************INSTRUCTION BLOCKS*************************************************************************************
ATTENTION: PRACTICE BLOCKS (1) This block sets the beginning N value for practice trials (here: values.N = values.StartN) (2) runs original instructions 1-5, for N=2-4, if more/fewer than three N examples are given adjust /trials = [1-X.....] <block Nbackinstruct_start> / trials = [1-5 = Nbackinstruct_starttrial] / recorddata = false / onblockbegin = [values.N = values.StartN] </block>
EXPERIMENTAL BLOCKS (1) This block sets the starting value of N (here: values.N = values.StartN) <block StartExp> / trials = [1 = StartExp_trial] / recorddata = false / onblockbegin = [ values.N = values.StartN; values.TotalHits = 0; values.TotalFA = 0; values.TotalBlocks = 0; values.DV = 0 ] </block>
<port EEGsignal> / port = lpt3 / subport = data / items = ("00000001") </port>
<port EEGsignal2> / port = lpt3 / subport = data / items = ("00000010") </port>
<port EEGsignaloff> / port = lpt3 / subport = data / items = ("00000000") </port>
<block EndExp> / trials = [1 = EndExp_trial] </block>
************************************************************************************************************************************************************************
************************************************************************************************************************************************************************ SUMMARY PAGES
*A feedback page that is presented at the end of each practice block
<instruct > / fontstyle = ("Arial", 2.67%, false, false, false, false, 5, 0) / txcolor = (255, 255, 255) / screencolor = (0, 0, 0) / windowsize = (70%, 60%) </instruct>
<page BlockSummary> ^^ FEEDBACK ^^ ^^CORRECT: <% ((values.Hits + values.CorrReject) /20) * 100 %>% of the times </page>
************************************************************************************************************************************************************************
************************************************************************************************************************************************************************ SHAPES *yellow on black background *original shapes, kindly provided by Jaeggi et al (2010)
<item shapes> / 1 = "no.1 alice.gif" / 2 = "no.2 alice.gif" / 3 = "no.3 alice.gif" / 4 = "no.4 alice.gif" / 5 = "no.5 alice.gif" / 6 = "no.6 alice.gif" / 7 = "no.7 alice.gif" / 8 = "no.8 alice.gif"
</item> ************************************************************************************************************************************************************************
************************************************************************************************************************************************************************ STIMULI-SELECTION
****List Variable to select current index of notargetvalue picture
*list.notargetvalue selects any of the 9 numbers but the one selected for targetvalue <list notargetvalue> /items = (1, 2, 3, 4, 5, 6, 7, 8) / not = (values.currenttarget) / replace = true </list>
***randomly selects one of the shapes <picture startshape> / items = shapes /select = replace /size = (40%, 40%) </picture>
***selects any shape but the established target <picture nontargetshape> / items = shapes / select = notargetvalue /size = (40%, 40%) </picture>
***selects the item with the same item number as the established target <picture targetshape> /items = shapes /select = values.currenttarget /size = (40%, 40%) </picture>
************************************************************************************************************************************************************************
************************************************************************************************************************************************************************ FEEDBACK MESSAGES FOR PRACTICE TRIALS ONLY <text ErrorFeedback> / items = ("ERROR") / fontstyle = ("Arial", 5.00%, true, false, false, false, 5, 0) / txcolor = (255, 0, 0) / txbgcolor = (0, 0, 0) / position = (50%, 70%) </text>
<text CorrectFeedback> / items = ("CORRECT") / fontstyle = ("Arial", 5.00%, true, false, false, false, 5, 0) / txcolor = (0, 255, 0) / txbgcolor = (0, 0, 0) / position = (50%, 70%) </text>
************************************************************************************************************************************************************************
************************************************************************************************************************************************************************ ASSISTANT STIMULI
*****acts as an eraser after showing the key stimuli for 500ms, staying on for the remainder of the 3000ms dedicated to each trial <shape eraser> / shape = rectangle / size = (100%, 100%) / color = (0, 0, 0) </shape>
*****Debug Code: <text targetalert> /items = ("target") /position = (50%, 80%) /txcolor = (black) /txbgcolor = (black) / fontstyle = ("Arial", 3%, true, false, false, false, 5, 1) </text> ************************************************************************************************************************************************************************
************************************************************************************************************************************************************************ TRIALS *there are 3 types of trials 1. start: presented at beginning of block when number of trials too small for Target trials; they can present any of the stimuli (N = 0, start trial presents the target shape) 2. nontarget:trials that present stimuli that do not repeat the stimulus of n-trials before 3. target:trials that present Target stimuli
*start trial runs N-times (unless N = 0, then it runs N = 1 time) <trial start> / stimulustimes = [0 = startshape; 300 = eraser; 0 = EEGsignal; 20 = EEGsignaloff] / validresponse = (noresponse, 30) / correctresponse = (noresponse) / ontrialbegin = [ {if (values.N == 1) values.currenttarget = values.minus1}; {if (values.N == 2) values.currenttarget = values.minus2}; {if (values.N == 3) values.currenttarget = values.minus3};
values.starttrialcounter += 1; ] / ontrialend = [ {if (values.N == 0) values.currenttarget = picture.startshape.currentitemnumber};
values.minus3 = values.minus2; values.minus2 = values.minus1; values.minus1 = picture.startshape.currentitemnumber ] / responsetime = 0 /trialduration = 1750 /branch = [if (values.starttrialcounter < values.N) trial.start] </trial>
<trial nontarget> / stimulustimes = [0 = nontargetshape; 300 = eraser; 0 = EEGsignal; 20 = EEGsignaloff] /validresponse = (noresponse, 30) / correctresponse = (noresponse) / ontrialbegin = [ {if (values.N == 1) values.currenttarget = values.minus1}; {if (values.N == 2) values.currenttarget = values.minus2}; {if (values.N == 3) values.currenttarget = values.minus3};
]
/ ontrialend = [
values.minus3 = values.minus2; values.minus2 = values.minus1; values.minus1 = picture.nontargetshape.currentitemnumber; values.CorrReject = values.CorrReject + trial.nontarget.correct; values.FalseA = values.FalseA + trial.nontarget.error; values.TotalFA = values.TotalFA + trial.nontarget.error; values.DV = (values.TotalHits - values.TotalFA)/values.TotalBlocks;
] / responsetime = 0 / trialduration = 1750 </trial>
**if target, press the letter "A" (code: 30) <trial target> / stimulustimes = [0 = targetshape, targetalert; 300 = eraser; 0 = EEGsignal2; 20 = EEGsignaloff ] /validresponse = (noresponse, 30) / correctresponse = (30) / ontrialbegin = [ {if (values.N == 1) values.currenttarget = values.minus1}; {if (values.N == 2) values.currenttarget = values.minus2}; {if (values.N == 3) values.currenttarget = values.minus3};
]
/ ontrialend = [
values.minus3 = values.minus2; values.minus2 = values.minus1; values.minus1 = picture.targetshape.currentitemnumber; values.Hits = values.Hits+ trial.target.correct; values.Misses = values.Misses + trial.target.error; values.TotalHits = values.TotalHits + trial.target.correct; values.DV = (values.TotalHits - values.TotalFA)/values.TotalBlocks; ] / responsetime = 0 / trialduration = 1750 </trial>
********************************ADDITIONAL N-LEVELS*****************************************************
For each trial type: (1) add {if (values.N == X) values.currenttarget = values.minusX};, e.g. N = 5 / ontrialbegin = [ ..... {if (values.N == 1) values.currenttarget = values.minus1}; {if (values.N == 2) values.currenttarget = values.minus2}; {if (values.N == 3) values.currenttarget = values.minus3}; {if (values.N == 4) values.currenttarget = values.minus4}; =>{if (values.N == 5) values.currenttarget = values.minus5}; ] (2) add values.minusX = values.minus(X-1) e.g. N = 5 - largest N goes on top of the list / ontrialend = [ =>values.minus5 = values.minus4; values.minus4 = values.minus3; values.minus3 = values.minus2; values.minus2 = values.minus1; values.minus1 = picture.targetshape.currentitemnumber; .... ]
************************************************************************************************************************************************************************
************************************************************************************************************************************************************************
EXPERIMENTAL-BLOCKS
* Block starts with (a) Instructiontrial (b) N start-trials that cannot present Targets yet (no data collected) (c) 20 Experimental trials * Experimental trials: ratio targets : nontargets = 6 : 14 = 3 : 7
<block s_ntask> / onblockbegin = [ values.currenttarget = 0; values.minus1 = 0; values.minus2 = 0; values.minus3 = 0; values.Hits = 0; values.FalseA = 0; values.Misses = 0; values.CorrReject = 0; values.TotalBlocks += 1; values.starttrialcounter = 0; values.repetitioncounter += 1; ] / trials = [1 = expinstructiontrial; 2 = start; 3 - 22 = noreplace(nontarget, nontarget, nontarget, nontarget, nontarget, nontarget, nontarget, target, target, target)] / screencolor = (0, 0, 0) / branch = [if (values.N == values.LastN && values.repetitioncounter == values.RepetitionTest) {values.repetitioncounter = 0; block.EndExp}] / branch = [if (values.repetitioncounter < 3) block.s_ntask else { values.N += 1; values.repetitioncounter = 0; block.s_ntask}] </block>
***********************************************ADDITIONAL N-LEVELS******************************************************** (1) add values.minusX = 0 to / onblockbegin = [ values.currenttarget = 0; values.minus1 = 0; values.minus2 = 0; values.minus3 = 0; values.minus4 = 0; ..... ]
Example: N = 5 / onblockbegin = [ values.currenttarget = 0; values.minus1 = 0; values.minus2 = 0; values.minus3 = 0; values.minus4 = 0; values.minus5 = 0; ..... ]
************************************************************************************************************************************************************************
************************************************************************************************************************************************************************ EXPERIMENT
*After running the initial instructions, participants work through practice blocks for N = 2 to N = 4 (initial N run can be altered under: INSTRUCTIONS -> INSTRUCTION BLOCKS) * After practice, participants work through 3 blocks for each of the following level of N: N = 2, N = 3, N = 4 * if you want to run the Experiment with Target Alerts: use debug as your subject id <expt> /onexptbegin = [if (values.debugmode == 1) text.targetalert.textcolor = (red)] / blocks = [ 1 = Nbackinstruct_start; 2 = StartExp; 3 = s_ntask ] /onexptend = [values.completed = 1] </expt>
************************************************************************************************************************************************************************ End of Script ************************************************************************************************************************************************************************
|
By Dave - 10/28/2015
Like any other stimulus element (<text>, <picture>, etc.), <port> elements can have multiple items. Simply enter the three items corresponding to your three N-levels and select the desired one according to the current N-level. There should be no need whatsoever for any additional conditional logic.
<port EEGsignal> / items = ("00000001", "00000010", "00000011") / select = values.N ... </port>
|
By avtobin - 10/29/2015
Ok, thankyou for this suggestion. I did try something similar, and couldn't get the program to select the right signal according to the n-back level. I will give this approach another try
|
|