From fd29e810598ddc78377ce1e8366f0b50188f8620 Mon Sep 17 00:00:00 2001 From: tiborauer <tibor.auer@gmail.com> Date: Tue, 12 Nov 2019 15:32:16 +0000 Subject: [PATCH] FINAL --- README.md | 2 +- three-back.psyexp | 133 ++++++++-------- three-back.py | 234 +++++++++++++++------------- three-back_lastrun.py | 351 ------------------------------------------ 4 files changed, 194 insertions(+), 526 deletions(-) delete mode 100644 three-back_lastrun.py diff --git a/README.md b/README.md index 164e44d..3a82cec 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,2 @@ -# Three-Back +# n-Back task diff --git a/three-back.psyexp b/three-back.psyexp index b756bdf..cefca3d 100644 --- a/three-back.psyexp +++ b/three-back.psyexp @@ -1,18 +1,18 @@ <?xml version="1.0" ?> -<PsychoPy2experiment encoding="utf-8" version="3.2.4"> +<PsychoPy2experiment encoding="utf-8" version="3.2.0"> <Settings> <Param name="Audio latency priority" updates="None" val="use prefs" valType="str"/> <Param name="Audio lib" updates="None" val="use prefs" valType="str"/> <Param name="Completed URL" updates="None" val="" valType="str"/> <Param name="Data filename" updates="None" val="u'data/%s_%s_%s' % (expInfo['participant'], expName, expInfo['date'])" valType="code"/> <Param name="Enable Escape" updates="None" val="True" valType="bool"/> - <Param name="Experiment info" updates="None" val="{'backN': '3', 'probability': '0.2', 'participant': '', 'session': '001'}" valType="code"/> + <Param name="Experiment info" updates="None" val="{'participant': '', 'session': '001', 'backN': '3', 'probability': '0.2'}" valType="code"/> <Param name="Force stereo" updates="None" val="True" valType="bool"/> <Param name="Full-screen window" updates="None" val="False" valType="bool"/> <Param name="HTML path" updates="None" val="html" valType="str"/> <Param name="Incomplete URL" updates="None" val="" valType="str"/> <Param name="JS libs" updates="None" val="packaged" valType="str"/> - <Param name="Monitor" updates="None" val="Monitor" valType="str"/> + <Param name="Monitor" updates="None" val="Alienware Laptop Monitor" valType="str"/> <Param name="Save csv file" updates="None" val="False" valType="bool"/> <Param name="Save excel file" updates="None" val="False" valType="bool"/> <Param name="Save log file" updates="None" val="True" valType="bool"/> @@ -25,7 +25,7 @@ <Param name="Use version" updates="None" val="" valType="str"/> <Param name="Window size (pixels)" updates="None" val="[1600, 900]" valType="code"/> <Param name="blendMode" updates="None" val="avg" valType="str"/> - <Param name="color" updates="None" val="$[-1,-1,-1]" valType="str"/> + <Param name="color" updates="None" val="$[1,1,1]" valType="str"/> <Param name="colorSpace" updates="None" val="rgb" valType="str"/> <Param name="expName" updates="None" val="three-back" valType="str"/> <Param name="exportHTML" updates="None" val="on Sync" valType="str"/> @@ -34,44 +34,44 @@ <Routines> <Routine name="Instructions"> <TextComponent name="instructions"> - <Param name="color" updates="constant" val="white" valType="str"/> + <Param name="color" updates="constant" val="black" valType="str"/> <Param name="colorSpace" updates="constant" val="rgb" valType="str"/> <Param name="disabled" updates="None" val="False" valType="bool"/> <Param name="durationEstim" updates="None" val="" valType="code"/> <Param name="flip" updates="constant" val="" valType="str"/> <Param name="font" updates="constant" val="Arial" valType="str"/> <Param name="languageStyle" updates="None" val="LTR" valType="str"/> - <Param name="letterHeight" updates="constant" val="2.4" valType="code"/> + <Param name="letterHeight" updates="constant" val="1" valType="code"/> <Param name="name" updates="None" val="instructions" valType="code"/> <Param name="opacity" updates="constant" val="1" valType="code"/> <Param name="ori" updates="constant" val="0" valType="code"/> <Param name="pos" updates="constant" val="(0, 0)" valType="code"/> - <Param name="saveStartStop" updates="None" val="True" valType="bool"/> + <Param name="saveStartStop" updates="None" val="False" valType="bool"/> <Param name="startEstim" updates="None" val="" valType="code"/> <Param name="startType" updates="None" val="time (s)" valType="str"/> <Param name="startVal" updates="None" val="0.0" valType="code"/> <Param name="stopType" updates="None" val="condition" valType="str"/> <Param name="stopVal" updates="constant" val="False" valType="code"/> <Param name="syncScreenRefresh" updates="None" val="True" valType="bool"/> - <Param name="text" updates="constant" val="Press SPACE to start" valType="str"/> + <Param name="text" updates="constant" val="$"The n-back task presents stimuli sequentially and require you to decide if the current stimulus is the same as one presented n-numbers previous (or back).\n"&#10;+ "\n"&#10;+ "For example, the 3-back you will indicate if the current number matches the number presented 3 places previous\n"&#10;+ "(e.g. A H G A B G B shows that 'A' and 'G' have matches in this sequence).\n"&#10;+ "\n"&#10;+ f"This is an {expInfo['backN']}-back task.\n"&#10;+ f"Press SPACE if the current stimulus is the same a {expInfo['backN']} places previous.\n"&#10;+ "\n"&#10;+ "Press SPACE bar when ready to start." " valType="str"/> <Param name="units" updates="None" val="from exp settings" valType="str"/> - <Param name="wrapWidth" updates="constant" val="" valType="code"/> + <Param name="wrapWidth" updates="constant" val="30" valType="code"/> </TextComponent> - <KeyboardComponent name="key_start"> + <KeyboardComponent name="instructions_key"> <Param name="allowedKeys" updates="constant" val="'space'" valType="code"/> <Param name="correctAns" updates="constant" val="" valType="str"/> <Param name="disabled" updates="None" val="False" valType="bool"/> <Param name="discard previous" updates="constant" val="False" valType="bool"/> <Param name="durationEstim" updates="None" val="" valType="code"/> <Param name="forceEndRoutine" updates="constant" val="True" valType="bool"/> - <Param name="name" updates="None" val="key_start" valType="code"/> - <Param name="saveStartStop" updates="None" val="True" valType="bool"/> + <Param name="name" updates="None" val="instructions_key" valType="code"/> + <Param name="saveStartStop" updates="None" val="False" valType="bool"/> <Param name="startEstim" updates="None" val="" valType="code"/> <Param name="startType" updates="None" val="time (s)" valType="str"/> <Param name="startVal" updates="None" val="0.0" valType="code"/> <Param name="stopType" updates="None" val="duration (s)" valType="str"/> <Param name="stopVal" updates="constant" val="" valType="code"/> - <Param name="store" updates="constant" val="last key" valType="str"/> + <Param name="store" updates="constant" val="nothing" valType="str"/> <Param name="storeCorrect" updates="constant" val="False" valType="bool"/> <Param name="syncScreenRefresh" updates="constant" val="False" valType="bool"/> </KeyboardComponent> @@ -84,7 +84,7 @@ <Param name="saveFrameValue" updates="constant" val="never" valType="str"/> <Param name="saveStartExp" updates="constant" val="False" valType="bool"/> <Param name="saveStartRoutine" updates="constant" val="False" valType="bool"/> - <Param name="saveStartStop" updates="None" val="True" valType="bool"/> + <Param name="saveStartStop" updates="None" val="False" valType="bool"/> <Param name="startEstim" updates="None" val="" valType="code"/> <Param name="startExpValue" updates="constant" val="np.array(['A','B','C','D','E','F','G','H'])" valType="code"/> <Param name="startFrameValue" updates="None" val="" valType="code"/> @@ -96,49 +96,50 @@ <Param name="syncScreenRefresh" updates="None" val="False" valType="bool"/> </VariableComponent> </Routine> - <Routine name="trial_n"> - <CodeComponent name="trial_n_code"> - <Param name="Begin Experiment" updates="constant" val="prevN = np.array([])" valType="extendedCode"/> - <Param name="Begin JS Experiment" updates="constant" val="" valType="extendedCode"/> - <Param name="Begin JS Routine" updates="constant" val="" valType="extendedCode"/> - <Param name="Begin Routine" updates="constant" val="if (currentLoop.thisN < int(expInfo['backN'])) or (np.random.uniform() > float(expInfo['probability'])):&#10; stimleft = np.delete(stimuli,[np.argwhere(stimuli==i) for i in prevN])&#10; stimulus = np.random.choice(stimleft)&#10;else:&#10; stimulus = prevN[-int(expInfo['backN'])]" valType="extendedCode"/> - <Param name="Code Type" updates="None" val="Py" valType="str"/> - <Param name="Each Frame" updates="constant" val="" valType="extendedCode"/> - <Param name="Each JS Frame" updates="constant" val="" valType="extendedCode"/> - <Param name="End Experiment" updates="constant" val="" valType="extendedCode"/> - <Param name="End JS Experiment" updates="constant" val="" valType="extendedCode"/> - <Param name="End JS Routine" updates="constant" val="" valType="extendedCode"/> - <Param name="End Routine" updates="constant" val="thisExp.addData('tial_n_letter.stim', stimulus)&#10;prevN = np.hstack((prevN,stimulus))&#10;prevN = prevN[-3:]" valType="extendedCode"/> - <Param name="disabled" updates="None" val="False" valType="bool"/> - <Param name="name" updates="None" val="trial_n_code" valType="code"/> - </CodeComponent> - <PolygonComponent name="trial_n_screen"> + <Routine name="trial_back"> + <TextComponent name="text"> + <Param name="color" updates="constant" val="white" valType="str"/> + <Param name="colorSpace" updates="constant" val="rgb" valType="str"/> <Param name="disabled" updates="None" val="False" valType="bool"/> <Param name="durationEstim" updates="None" val="" valType="code"/> - <Param name="fillColor" updates="constant" val="$[-1,-1,-1]" valType="str"/> - <Param name="fillColorSpace" updates="constant" val="rgb" valType="str"/> - <Param name="interpolate" updates="constant" val="linear" valType="str"/> - <Param name="lineColor" updates="constant" val="$[1,1,1]" valType="str"/> - <Param name="lineColorSpace" updates="constant" val="rgb" valType="str"/> - <Param name="lineWidth" updates="constant" val="1" valType="code"/> - <Param name="nVertices" updates="constant" val="4" valType="int"/> - <Param name="name" updates="None" val="trial_n_screen" valType="code"/> + <Param name="flip" updates="constant" val="" valType="str"/> + <Param name="font" updates="constant" val="Arial" valType="str"/> + <Param name="languageStyle" updates="None" val="LTR" valType="str"/> + <Param name="letterHeight" updates="constant" val="2.5" valType="code"/> + <Param name="name" updates="None" val="text" valType="code"/> <Param name="opacity" updates="constant" val="1" valType="code"/> <Param name="ori" updates="constant" val="0" valType="code"/> <Param name="pos" updates="constant" val="(0, 0)" valType="code"/> <Param name="saveStartStop" updates="None" val="True" valType="bool"/> - <Param name="shape" updates="constant" val="rectangle" valType="str"/> - <Param name="size" updates="constant" val="(2, 2)" valType="code"/> <Param name="startEstim" updates="None" val="" valType="code"/> <Param name="startType" updates="None" val="time (s)" valType="str"/> <Param name="startVal" updates="None" val="0.0" valType="code"/> <Param name="stopType" updates="None" val="duration (s)" valType="str"/> - <Param name="stopVal" updates="constant" val="2" valType="code"/> + <Param name="stopVal" updates="constant" val="1.0" valType="code"/> <Param name="syncScreenRefresh" updates="None" val="True" valType="bool"/> - <Param name="units" updates="None" val="norm" valType="str"/> - </PolygonComponent> - <TextComponent name="tial_n_letter"> - <Param name="color" updates="constant" val="white" valType="str"/> + <Param name="text" updates="set every repeat" val="$[t['stimulus'] for t in loop_n.trialList]" valType="str"/> + <Param name="units" updates="None" val="from exp settings" valType="str"/> + <Param name="wrapWidth" updates="constant" val="" valType="code"/> + </TextComponent> + </Routine> + <Routine name="trial"> + <CodeComponent name="trial_code"> + <Param name="Begin Experiment" updates="constant" val="prevN = np.array([])" valType="extendedCode"/> + <Param name="Begin JS Experiment" updates="constant" val="" valType="extendedCode"/> + <Param name="Begin JS Routine" updates="constant" val="" valType="extendedCode"/> + <Param name="Begin Routine" updates="constant" val="if (currentLoop.thisN < int(expInfo['backN'])) or (np.random.uniform() > float(expInfo['probability'])):&#10; stimleft = np.delete(stimuli,[np.argwhere(stimuli==i) for i in prevN])&#10; stimulus = np.random.choice(stimleft)&#10; correctResponse = None&#10;else:&#10; stimulus = prevN[-int(expInfo['backN'])]&#10; correctResponse = 'space'" valType="extendedCode"/> + <Param name="Code Type" updates="None" val="Py" valType="str"/> + <Param name="Each Frame" updates="constant" val="" valType="extendedCode"/> + <Param name="Each JS Frame" updates="constant" val="" valType="extendedCode"/> + <Param name="End Experiment" updates="constant" val="" valType="extendedCode"/> + <Param name="End JS Experiment" updates="constant" val="" valType="extendedCode"/> + <Param name="End JS Routine" updates="constant" val="" valType="extendedCode"/> + <Param name="End Routine" updates="constant" val="thisExp.addData('tial_stimulus.stim', stimulus)&#10;prevN = np.hstack((prevN,stimulus))&#10;prevN = prevN[-3:]" valType="extendedCode"/> + <Param name="disabled" updates="None" val="False" valType="bool"/> + <Param name="name" updates="None" val="trial_code" valType="code"/> + </CodeComponent> + <TextComponent name="trial_stimulus"> + <Param name="color" updates="constant" val="black" valType="str"/> <Param name="colorSpace" updates="constant" val="rgb" valType="str"/> <Param name="disabled" updates="None" val="False" valType="bool"/> <Param name="durationEstim" updates="None" val="" valType="code"/> @@ -146,7 +147,7 @@ <Param name="font" updates="constant" val="Arial" valType="str"/> <Param name="languageStyle" updates="None" val="LTR" valType="str"/> <Param name="letterHeight" updates="constant" val="2.5" valType="code"/> - <Param name="name" updates="None" val="tial_n_letter" valType="code"/> + <Param name="name" updates="None" val="trial_stimulus" valType="code"/> <Param name="opacity" updates="constant" val="1" valType="code"/> <Param name="ori" updates="constant" val="0" valType="code"/> <Param name="pos" updates="constant" val="(0, 0)" valType="code"/> @@ -161,37 +162,29 @@ <Param name="units" updates="None" val="from exp settings" valType="str"/> <Param name="wrapWidth" updates="constant" val="" valType="code"/> </TextComponent> - </Routine> - <Routine name="trial_back"> - <TextComponent name="text"> - <Param name="color" updates="constant" val="white" valType="str"/> - <Param name="colorSpace" updates="constant" val="rgb" valType="str"/> + <KeyboardComponent name="trial_resp"> + <Param name="allowedKeys" updates="constant" val="'space'" valType="code"/> + <Param name="correctAns" updates="constant" val="$correctResponse" valType="str"/> <Param name="disabled" updates="None" val="False" valType="bool"/> + <Param name="discard previous" updates="constant" val="True" valType="bool"/> <Param name="durationEstim" updates="None" val="" valType="code"/> - <Param name="flip" updates="constant" val="" valType="str"/> - <Param name="font" updates="constant" val="Arial" valType="str"/> - <Param name="languageStyle" updates="None" val="LTR" valType="str"/> - <Param name="letterHeight" updates="constant" val="2.5" valType="code"/> - <Param name="name" updates="None" val="text" valType="code"/> - <Param name="opacity" updates="constant" val="1" valType="code"/> - <Param name="ori" updates="constant" val="0" valType="code"/> - <Param name="pos" updates="constant" val="(0, 0)" valType="code"/> + <Param name="forceEndRoutine" updates="constant" val="False" valType="bool"/> + <Param name="name" updates="None" val="trial_resp" valType="code"/> <Param name="saveStartStop" updates="None" val="True" valType="bool"/> <Param name="startEstim" updates="None" val="" valType="code"/> <Param name="startType" updates="None" val="time (s)" valType="str"/> <Param name="startVal" updates="None" val="0.0" valType="code"/> <Param name="stopType" updates="None" val="duration (s)" valType="str"/> - <Param name="stopVal" updates="constant" val="1.0" valType="code"/> - <Param name="syncScreenRefresh" updates="None" val="True" valType="bool"/> - <Param name="text" updates="set every repeat" val="$[t['stimulus'] for t in loop_n.trialList]" valType="str"/> - <Param name="units" updates="None" val="from exp settings" valType="str"/> - <Param name="wrapWidth" updates="constant" val="" valType="code"/> - </TextComponent> + <Param name="stopVal" updates="constant" val="2" valType="code"/> + <Param name="store" updates="constant" val="first key" valType="str"/> + <Param name="storeCorrect" updates="constant" val="True" valType="bool"/> + <Param name="syncScreenRefresh" updates="constant" val="True" valType="bool"/> + </KeyboardComponent> </Routine> </Routines> <Flow> <Routine name="Instructions"/> - <LoopInitiator loopType="TrialHandler" name="loop_n"> + <LoopInitiator loopType="TrialHandler" name="loop"> <Param name="Selected rows" updates="None" val="" valType="str"/> <Param name="conditions" updates="None" val="None" valType="str"/> <Param name="conditionsFile" updates="None" val="" valType="str"/> @@ -199,10 +192,10 @@ <Param name="isTrials" updates="None" val="True" valType="bool"/> <Param name="loopType" updates="None" val="sequential" valType="str"/> <Param name="nReps" updates="None" val="20" valType="code"/> - <Param name="name" updates="None" val="loop_n" valType="code"/> + <Param name="name" updates="None" val="loop" valType="code"/> <Param name="random seed" updates="None" val="" valType="code"/> </LoopInitiator> - <Routine name="trial_n"/> - <LoopTerminator name="loop_n"/> + <Routine name="trial"/> + <LoopTerminator name="loop"/> </Flow> </PsychoPy2experiment> diff --git a/three-back.py b/three-back.py index 91b4b78..ee5549b 100644 --- a/three-back.py +++ b/three-back.py @@ -1,8 +1,8 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- """ -This experiment was created using PsychoPy3 Experiment Builder (v3.2.4), - on november 12, 2019, at 02:43 +This experiment was created using PsychoPy3 Experiment Builder (v3.2.0), + on November 12, 2019, at 15:31 If you publish work using this script the most relevant publication is: Peirce J, Gray JR, Simpson S, MacAskill M, Höchenberger R, Sogo H, Kastman E, Lindeløv JK. (2019) @@ -33,9 +33,9 @@ _thisDir = os.path.dirname(os.path.abspath(__file__)) os.chdir(_thisDir) # Store info about the experiment session -psychopyVersion = '3.2.4' +psychopyVersion = '3.2.0' expName = 'three-back' # from the Builder filename that created this script -expInfo = {'backN': '3', 'probability': '0.2', 'participant': '', 'session': '001'} +expInfo = {'participant': '', 'session': '001', 'backN': '3', 'probability': '0.2'} dlg = gui.DlgFromDict(dictionary=expInfo, sortKeys=False, title=expName) if dlg.OK == False: core.quit() # user pressed cancel @@ -65,7 +65,7 @@ frameTolerance = 0.001 # how close to onset before 'same' frame win = visual.Window( size=[1600, 900], fullscr=False, screen=0, winType='pyglet', allowGUI=True, allowStencil=False, - monitor='Monitor', color=[-1,-1,-1], colorSpace='rgb', + monitor='Alienware Laptop Monitor', color=[1,1,1], colorSpace='rgb', blendMode='avg', useFBO=True, units='deg') # store frame rate of monitor if we can measure it @@ -81,34 +81,36 @@ defaultKeyboard = keyboard.Keyboard() # Initialize components for Routine "Instructions" InstructionsClock = core.Clock() instructions = visual.TextStim(win=win, name='instructions', - text='Press SPACE to start', + text="The n-back task presents stimuli sequentially and require you to decide if the current stimulus is the same as one presented n-numbers previous (or back).\n" ++ "\n" ++ "For example, the 3-back you will indicate if the current number matches the number presented 3 places previous\n" ++ "(e.g. A H G A B G B shows that 'A' and 'G' have matches in this sequence).\n" ++ "\n" ++ f"This is an {expInfo['backN']}-back task.\n" ++ f"Press SPACE if the current stimulus is the same a {expInfo['backN']} places previous.\n" ++ "\n" ++ "Press SPACE bar when ready to start." , font='Arial', - pos=(0, 0), height=2.4, wrapWidth=None, ori=0, - color='white', colorSpace='rgb', opacity=1, + pos=(0, 0), height=1, wrapWidth=30, ori=0, + color='black', colorSpace='rgb', opacity=1, languageStyle='LTR', depth=0.0); -key_start = keyboard.Keyboard() +instructions_key = keyboard.Keyboard() # Set experiment start values for variable component stimuli stimuli = np.array(['A','B','C','D','E','F','G','H']) stimuliContainer = [] -# Initialize components for Routine "trial_n" -trial_nClock = core.Clock() +# Initialize components for Routine "trial" +trialClock = core.Clock() prevN = np.array([]) -trial_n_screen = visual.Rect( - win=win, name='trial_n_screen',units='norm', - width=(2, 2)[0], height=(2, 2)[1], - ori=0, pos=(0, 0), - lineWidth=1, lineColor=[1,1,1], lineColorSpace='rgb', - fillColor=[-1,-1,-1], fillColorSpace='rgb', - opacity=1, depth=-1.0, interpolate=True) -tial_n_letter = visual.TextStim(win=win, name='tial_n_letter', +trial_stimulus = visual.TextStim(win=win, name='trial_stimulus', text='default text', font='Arial', pos=(0, 0), height=2.5, wrapWidth=None, ori=0, - color='white', colorSpace='rgb', opacity=1, + color='black', colorSpace='rgb', opacity=1, languageStyle='LTR', - depth=-2.0); + depth=-1.0); +trial_resp = keyboard.Keyboard() # Create some handy timers globalClock = core.Clock() # to track the time since experiment started @@ -116,10 +118,10 @@ routineTimer = core.CountdownTimer() # to track time remaining of each (non-sli # ------Prepare to start Routine "Instructions"------- # update component parameters for each repeat -key_start.keys = [] -key_start.rt = [] +instructions_key.keys = [] +instructions_key.rt = [] # keep track of which components have finished -InstructionsComponents = [instructions, key_start] +InstructionsComponents = [instructions, instructions_key] for thisComponent in InstructionsComponents: thisComponent.tStart = None thisComponent.tStop = None @@ -159,26 +161,23 @@ while continueRoutine: win.timeOnFlip(instructions, 'tStopRefresh') # time at next scr refresh instructions.setAutoDraw(False) - # *key_start* updates - if key_start.status == NOT_STARTED and t >= 0.0-frameTolerance: + # *instructions_key* updates + if instructions_key.status == NOT_STARTED and t >= 0.0-frameTolerance: # keep track of start time/frame for later - key_start.frameNStart = frameN # exact frame index - key_start.tStart = t # local t and not account for scr refresh - key_start.tStartRefresh = tThisFlipGlobal # on global time - win.timeOnFlip(key_start, 'tStartRefresh') # time at next scr refresh - key_start.status = STARTED + instructions_key.frameNStart = frameN # exact frame index + instructions_key.tStart = t # local t and not account for scr refresh + instructions_key.tStartRefresh = tThisFlipGlobal # on global time + win.timeOnFlip(instructions_key, 'tStartRefresh') # time at next scr refresh + instructions_key.status = STARTED # keyboard checking is just starting - key_start.clock.reset() # now t=0 - if key_start.status == STARTED: - theseKeys = key_start.getKeys(keyList=['space'], waitRelease=False) + if instructions_key.status == STARTED: + theseKeys = instructions_key.getKeys(keyList=['space'], waitRelease=False) if len(theseKeys): theseKeys = theseKeys[0] # at least one key was pressed # check for quit: if "escape" == theseKeys: endExpNow = True - key_start.keys = theseKeys.name # just the last key pressed - key_start.rt = theseKeys.rt # a response ends the routine continueRoutine = False @@ -203,51 +202,44 @@ while continueRoutine: for thisComponent in InstructionsComponents: if hasattr(thisComponent, "setAutoDraw"): thisComponent.setAutoDraw(False) -thisExp.addData('instructions.started', instructions.tStartRefresh) -thisExp.addData('instructions.stopped', instructions.tStopRefresh) -# check responses -if key_start.keys in ['', [], None]: # No response was made - key_start.keys = None -thisExp.addData('key_start.keys',key_start.keys) -if key_start.keys != None: # we had a response - thisExp.addData('key_start.rt', key_start.rt) -thisExp.addData('key_start.started', key_start.tStart) -thisExp.addData('key_start.stopped', key_start.tStop) -thisExp.nextEntry() # the Routine "Instructions" was not non-slip safe, so reset the non-slip timer routineTimer.reset() # set up handler to look after randomisation of conditions etc -loop_n = data.TrialHandler(nReps=20, method='sequential', +loop = data.TrialHandler(nReps=20, method='sequential', extraInfo=expInfo, originPath=-1, trialList=[None], - seed=None, name='loop_n') -thisExp.addLoop(loop_n) # add the loop to the experiment -thisLoop_n = loop_n.trialList[0] # so we can initialise stimuli with some values -# abbreviate parameter names if possible (e.g. rgb = thisLoop_n.rgb) -if thisLoop_n != None: - for paramName in thisLoop_n: - exec('{} = thisLoop_n[paramName]'.format(paramName)) + seed=None, name='loop') +thisExp.addLoop(loop) # add the loop to the experiment +thisLoop = loop.trialList[0] # so we can initialise stimuli with some values +# abbreviate parameter names if possible (e.g. rgb = thisLoop.rgb) +if thisLoop != None: + for paramName in thisLoop: + exec('{} = thisLoop[paramName]'.format(paramName)) -for thisLoop_n in loop_n: - currentLoop = loop_n - # abbreviate parameter names if possible (e.g. rgb = thisLoop_n.rgb) - if thisLoop_n != None: - for paramName in thisLoop_n: - exec('{} = thisLoop_n[paramName]'.format(paramName)) +for thisLoop in loop: + currentLoop = loop + # abbreviate parameter names if possible (e.g. rgb = thisLoop.rgb) + if thisLoop != None: + for paramName in thisLoop: + exec('{} = thisLoop[paramName]'.format(paramName)) - # ------Prepare to start Routine "trial_n"------- + # ------Prepare to start Routine "trial"------- routineTimer.add(2.000000) # update component parameters for each repeat if (currentLoop.thisN < int(expInfo['backN'])) or (np.random.uniform() > float(expInfo['probability'])): stimleft = np.delete(stimuli,[np.argwhere(stimuli==i) for i in prevN]) stimulus = np.random.choice(stimleft) + correctResponse = None else: stimulus = prevN[-int(expInfo['backN'])] - tial_n_letter.setText(stimulus) + correctResponse = 'space' + trial_stimulus.setText(stimulus) + trial_resp.keys = [] + trial_resp.rt = [] # keep track of which components have finished - trial_nComponents = [trial_n_screen, tial_n_letter] - for thisComponent in trial_nComponents: + trialComponents = [trial_stimulus, trial_resp] + for thisComponent in trialComponents: thisComponent.tStart = None thisComponent.tStop = None thisComponent.tStartRefresh = None @@ -257,52 +249,73 @@ for thisLoop_n in loop_n: # reset timers t = 0 _timeToFirstFrame = win.getFutureFlipTime(clock="now") - trial_nClock.reset(-_timeToFirstFrame) # t0 is time of first possible flip + trialClock.reset(-_timeToFirstFrame) # t0 is time of first possible flip frameN = -1 continueRoutine = True - # -------Run Routine "trial_n"------- + # -------Run Routine "trial"------- while continueRoutine and routineTimer.getTime() > 0: # get current time - t = trial_nClock.getTime() - tThisFlip = win.getFutureFlipTime(clock=trial_nClock) + t = trialClock.getTime() + tThisFlip = win.getFutureFlipTime(clock=trialClock) tThisFlipGlobal = win.getFutureFlipTime(clock=None) frameN = frameN + 1 # number of completed frames (so 0 is the first frame) # update/draw components on each frame - # *trial_n_screen* updates - if trial_n_screen.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance: + # *trial_stimulus* updates + if trial_stimulus.status == NOT_STARTED and tThisFlip >= 0-frameTolerance: # keep track of start time/frame for later - trial_n_screen.frameNStart = frameN # exact frame index - trial_n_screen.tStart = t # local t and not account for scr refresh - trial_n_screen.tStartRefresh = tThisFlipGlobal # on global time - win.timeOnFlip(trial_n_screen, 'tStartRefresh') # time at next scr refresh - trial_n_screen.setAutoDraw(True) - if trial_n_screen.status == STARTED: + trial_stimulus.frameNStart = frameN # exact frame index + trial_stimulus.tStart = t # local t and not account for scr refresh + trial_stimulus.tStartRefresh = tThisFlipGlobal # on global time + win.timeOnFlip(trial_stimulus, 'tStartRefresh') # time at next scr refresh + trial_stimulus.setAutoDraw(True) + if trial_stimulus.status == STARTED: # is it time to stop? (based on global clock, using actual start) - if tThisFlipGlobal > trial_n_screen.tStartRefresh + 2-frameTolerance: + if tThisFlipGlobal > trial_stimulus.tStartRefresh + 0.03-frameTolerance: # keep track of stop time/frame for later - trial_n_screen.tStop = t # not accounting for scr refresh - trial_n_screen.frameNStop = frameN # exact frame index - win.timeOnFlip(trial_n_screen, 'tStopRefresh') # time at next scr refresh - trial_n_screen.setAutoDraw(False) + trial_stimulus.tStop = t # not accounting for scr refresh + trial_stimulus.frameNStop = frameN # exact frame index + win.timeOnFlip(trial_stimulus, 'tStopRefresh') # time at next scr refresh + trial_stimulus.setAutoDraw(False) - # *tial_n_letter* updates - if tial_n_letter.status == NOT_STARTED and tThisFlip >= 0-frameTolerance: + # *trial_resp* updates + waitOnFlip = False + if trial_resp.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance: # keep track of start time/frame for later - tial_n_letter.frameNStart = frameN # exact frame index - tial_n_letter.tStart = t # local t and not account for scr refresh - tial_n_letter.tStartRefresh = tThisFlipGlobal # on global time - win.timeOnFlip(tial_n_letter, 'tStartRefresh') # time at next scr refresh - tial_n_letter.setAutoDraw(True) - if tial_n_letter.status == STARTED: + trial_resp.frameNStart = frameN # exact frame index + trial_resp.tStart = t # local t and not account for scr refresh + trial_resp.tStartRefresh = tThisFlipGlobal # on global time + win.timeOnFlip(trial_resp, 'tStartRefresh') # time at next scr refresh + trial_resp.status = STARTED + # keyboard checking is just starting + waitOnFlip = True + win.callOnFlip(trial_resp.clock.reset) # t=0 on next screen flip + win.callOnFlip(trial_resp.clearEvents, eventType='keyboard') # clear events on next screen flip + if trial_resp.status == STARTED: # is it time to stop? (based on global clock, using actual start) - if tThisFlipGlobal > tial_n_letter.tStartRefresh + 0.03-frameTolerance: + if tThisFlipGlobal > trial_resp.tStartRefresh + 2-frameTolerance: # keep track of stop time/frame for later - tial_n_letter.tStop = t # not accounting for scr refresh - tial_n_letter.frameNStop = frameN # exact frame index - win.timeOnFlip(tial_n_letter, 'tStopRefresh') # time at next scr refresh - tial_n_letter.setAutoDraw(False) + trial_resp.tStop = t # not accounting for scr refresh + trial_resp.frameNStop = frameN # exact frame index + win.timeOnFlip(trial_resp, 'tStopRefresh') # time at next scr refresh + trial_resp.status = FINISHED + if trial_resp.status == STARTED and not waitOnFlip: + theseKeys = trial_resp.getKeys(keyList=['space'], waitRelease=False) + if len(theseKeys): + theseKeys = theseKeys[0] # at least one key was pressed + + # check for quit: + if "escape" == theseKeys: + endExpNow = True + if trial_resp.keys == []: # then this was the first keypress + trial_resp.keys = theseKeys.name # just the first key pressed + trial_resp.rt = theseKeys.rt + # was this 'correct'? + if (trial_resp.keys == str(correctResponse)) or (trial_resp.keys == correctResponse): + trial_resp.corr = 1 + else: + trial_resp.corr = 0 # check for quit (typically the Esc key) if endExpNow or defaultKeyboard.getKeys(keyList=["escape"]): @@ -312,7 +325,7 @@ for thisLoop_n in loop_n: if not continueRoutine: # a component has requested a forced-end of Routine break continueRoutine = False # will revert to True if at least one component still running - for thisComponent in trial_nComponents: + for thisComponent in trialComponents: if hasattr(thisComponent, "status") and thisComponent.status != FINISHED: continueRoutine = True break # at least one component has not yet finished @@ -321,20 +334,33 @@ for thisLoop_n in loop_n: if continueRoutine: # don't flip if this routine is over or we'll get a blank screen win.flip() - # -------Ending Routine "trial_n"------- - for thisComponent in trial_nComponents: + # -------Ending Routine "trial"------- + for thisComponent in trialComponents: if hasattr(thisComponent, "setAutoDraw"): thisComponent.setAutoDraw(False) - thisExp.addData('tial_n_letter.stim', stimulus) + thisExp.addData('tial_stimulus.stim', stimulus) prevN = np.hstack((prevN,stimulus)) prevN = prevN[-3:] - loop_n.addData('trial_n_screen.started', trial_n_screen.tStartRefresh) - loop_n.addData('trial_n_screen.stopped', trial_n_screen.tStopRefresh) - loop_n.addData('tial_n_letter.started', tial_n_letter.tStartRefresh) - loop_n.addData('tial_n_letter.stopped', tial_n_letter.tStopRefresh) + loop.addData('trial_stimulus.started', trial_stimulus.tStartRefresh) + loop.addData('trial_stimulus.stopped', trial_stimulus.tStopRefresh) + # check responses + if trial_resp.keys in ['', [], None]: # No response was made + trial_resp.keys = None + # was no response the correct answer?! + if str(correctResponse).lower() == 'none': + trial_resp.corr = 1; # correct non-response + else: + trial_resp.corr = 0; # failed to respond (incorrectly) + # store data for loop (TrialHandler) + loop.addData('trial_resp.keys',trial_resp.keys) + loop.addData('trial_resp.corr', trial_resp.corr) + if trial_resp.keys != None: # we had a response + loop.addData('trial_resp.rt', trial_resp.rt) + loop.addData('trial_resp.started', trial_resp.tStartRefresh) + loop.addData('trial_resp.stopped', trial_resp.tStopRefresh) thisExp.nextEntry() -# completed 20 repeats of 'loop_n' +# completed 20 repeats of 'loop' # Flip one final time so any remaining win.callOnFlip() diff --git a/three-back_lastrun.py b/three-back_lastrun.py deleted file mode 100644 index 4a69b10..0000000 --- a/three-back_lastrun.py +++ /dev/null @@ -1,351 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -""" -This experiment was created using PsychoPy3 Experiment Builder (v3.2.4), - on november 12, 2019, at 02:41 -If you publish work using this script the most relevant publication is: - - Peirce J, Gray JR, Simpson S, MacAskill M, Höchenberger R, Sogo H, Kastman E, Lindeløv JK. (2019) - PsychoPy2: Experiments in behavior made easy Behav Res 51: 195. - https://doi.org/10.3758/s13428-018-01193-y - -""" - -from __future__ import absolute_import, division - -from psychopy import locale_setup -from psychopy import prefs -from psychopy import sound, gui, visual, core, data, event, logging, clock -from psychopy.constants import (NOT_STARTED, STARTED, PLAYING, PAUSED, - STOPPED, FINISHED, PRESSED, RELEASED, FOREVER) - -import numpy as np # whole numpy lib is available, prepend 'np.' -from numpy import (sin, cos, tan, log, log10, pi, average, - sqrt, std, deg2rad, rad2deg, linspace, asarray) -from numpy.random import random, randint, normal, shuffle -import os # handy system and path functions -import sys # to get file system encoding - -from psychopy.hardware import keyboard - -# Ensure that relative paths start from the same directory as this script -_thisDir = os.path.dirname(os.path.abspath(__file__)) -os.chdir(_thisDir) - -# Store info about the experiment session -psychopyVersion = '3.2.4' -expName = 'three-back' # from the Builder filename that created this script -expInfo = {'backN': '3', 'probability': '0.2', 'participant': '', 'session': '001'} -dlg = gui.DlgFromDict(dictionary=expInfo, sortKeys=False, title=expName) -if dlg.OK == False: - core.quit() # user pressed cancel -expInfo['date'] = data.getDateStr() # add a simple timestamp -expInfo['expName'] = expName -expInfo['psychopyVersion'] = psychopyVersion - -# Data file name stem = absolute path + name; later add .psyexp, .csv, .log, etc -filename = _thisDir + os.sep + u'data/%s_%s_%s' % (expInfo['participant'], expName, expInfo['date']) - -# An ExperimentHandler isn't essential but helps with data saving -thisExp = data.ExperimentHandler(name=expName, version='', - extraInfo=expInfo, runtimeInfo=None, - originPath='D:\\Projects\\three-back\\three-back_lastrun.py', - savePickle=True, saveWideText=True, - dataFileName=filename) -# save a log file for detail verbose info -logFile = logging.LogFile(filename+'.log', level=logging.EXP) -logging.console.setLevel(logging.WARNING) # this outputs to the screen, not a file - -endExpNow = False # flag for 'escape' or other condition => quit the exp -frameTolerance = 0.001 # how close to onset before 'same' frame - -# Start Code - component code to be run before the window creation - -# Setup the Window -win = visual.Window( - size=[1600, 900], fullscr=False, screen=0, - winType='pyglet', allowGUI=True, allowStencil=False, - monitor='Monitor', color=[-1,-1,-1], colorSpace='rgb', - blendMode='avg', useFBO=True, - units='deg') -# store frame rate of monitor if we can measure it -expInfo['frameRate'] = win.getActualFrameRate() -if expInfo['frameRate'] != None: - frameDur = 1.0 / round(expInfo['frameRate']) -else: - frameDur = 1.0 / 60.0 # could not measure, so guess - -# create a default keyboard (e.g. to check for escape) -defaultKeyboard = keyboard.Keyboard() - -# Initialize components for Routine "Instructions" -InstructionsClock = core.Clock() -instructions = visual.TextStim(win=win, name='instructions', - text='Press SPACE to start', - font='Arial', - pos=(0, 0), height=2.4, wrapWidth=None, ori=0, - color='white', colorSpace='rgb', opacity=1, - languageStyle='LTR', - depth=0.0); -key_start = keyboard.Keyboard() -# Set experiment start values for variable component stimuli -stimuli = np.array(['A','B','C','D','E','F','G','H']) -stimuliContainer = [] - -# Initialize components for Routine "trial_n" -trial_nClock = core.Clock() -prevN = np.array([]) -trial_n_screen = visual.Rect( - win=win, name='trial_n_screen',units='norm', - width=(2, 2)[0], height=(2, 2)[1], - ori=0, pos=(0, 0), - lineWidth=1, lineColor=[1,1,1], lineColorSpace='rgb', - fillColor=[-1,-1,-1], fillColorSpace='rgb', - opacity=1, depth=-1.0, interpolate=True) -tial_n_letter = visual.TextStim(win=win, name='tial_n_letter', - text='default text', - font='Arial', - pos=(0, 0), height=2.5, wrapWidth=None, ori=0, - color='white', colorSpace='rgb', opacity=1, - languageStyle='LTR', - depth=-2.0); - -# Create some handy timers -globalClock = core.Clock() # to track the time since experiment started -routineTimer = core.CountdownTimer() # to track time remaining of each (non-slip) routine - -# ------Prepare to start Routine "Instructions"------- -# update component parameters for each repeat -key_start.keys = [] -key_start.rt = [] -# keep track of which components have finished -InstructionsComponents = [instructions, key_start] -for thisComponent in InstructionsComponents: - thisComponent.tStart = None - thisComponent.tStop = None - thisComponent.tStartRefresh = None - thisComponent.tStopRefresh = None - if hasattr(thisComponent, 'status'): - thisComponent.status = NOT_STARTED -# reset timers -t = 0 -_timeToFirstFrame = win.getFutureFlipTime(clock="now") -InstructionsClock.reset(-_timeToFirstFrame) # t0 is time of first possible flip -frameN = -1 -continueRoutine = True - -# -------Run Routine "Instructions"------- -while continueRoutine: - # get current time - t = InstructionsClock.getTime() - tThisFlip = win.getFutureFlipTime(clock=InstructionsClock) - tThisFlipGlobal = win.getFutureFlipTime(clock=None) - frameN = frameN + 1 # number of completed frames (so 0 is the first frame) - # update/draw components on each frame - - # *instructions* updates - if instructions.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance: - # keep track of start time/frame for later - instructions.frameNStart = frameN # exact frame index - instructions.tStart = t # local t and not account for scr refresh - instructions.tStartRefresh = tThisFlipGlobal # on global time - win.timeOnFlip(instructions, 'tStartRefresh') # time at next scr refresh - instructions.setAutoDraw(True) - if instructions.status == STARTED: - if bool(False): - # keep track of stop time/frame for later - instructions.tStop = t # not accounting for scr refresh - instructions.frameNStop = frameN # exact frame index - win.timeOnFlip(instructions, 'tStopRefresh') # time at next scr refresh - instructions.setAutoDraw(False) - - # *key_start* updates - if key_start.status == NOT_STARTED and t >= 0.0-frameTolerance: - # keep track of start time/frame for later - key_start.frameNStart = frameN # exact frame index - key_start.tStart = t # local t and not account for scr refresh - key_start.tStartRefresh = tThisFlipGlobal # on global time - win.timeOnFlip(key_start, 'tStartRefresh') # time at next scr refresh - key_start.status = STARTED - # keyboard checking is just starting - key_start.clock.reset() # now t=0 - if key_start.status == STARTED: - theseKeys = key_start.getKeys(keyList=['space'], waitRelease=False) - if len(theseKeys): - theseKeys = theseKeys[0] # at least one key was pressed - - # check for quit: - if "escape" == theseKeys: - endExpNow = True - key_start.keys = theseKeys.name # just the last key pressed - key_start.rt = theseKeys.rt - # a response ends the routine - continueRoutine = False - - # check for quit (typically the Esc key) - if endExpNow or defaultKeyboard.getKeys(keyList=["escape"]): - core.quit() - - # check if all components have finished - if not continueRoutine: # a component has requested a forced-end of Routine - break - continueRoutine = False # will revert to True if at least one component still running - for thisComponent in InstructionsComponents: - if hasattr(thisComponent, "status") and thisComponent.status != FINISHED: - continueRoutine = True - break # at least one component has not yet finished - - # refresh the screen - if continueRoutine: # don't flip if this routine is over or we'll get a blank screen - win.flip() - -# -------Ending Routine "Instructions"------- -for thisComponent in InstructionsComponents: - if hasattr(thisComponent, "setAutoDraw"): - thisComponent.setAutoDraw(False) -thisExp.addData('instructions.started', instructions.tStartRefresh) -thisExp.addData('instructions.stopped', instructions.tStopRefresh) -# check responses -if key_start.keys in ['', [], None]: # No response was made - key_start.keys = None -thisExp.addData('key_start.keys',key_start.keys) -if key_start.keys != None: # we had a response - thisExp.addData('key_start.rt', key_start.rt) -thisExp.addData('key_start.started', key_start.tStart) -thisExp.addData('key_start.stopped', key_start.tStop) -thisExp.nextEntry() -# the Routine "Instructions" was not non-slip safe, so reset the non-slip timer -routineTimer.reset() - -# set up handler to look after randomisation of conditions etc -loop_n = data.TrialHandler(nReps=20, method='sequential', - extraInfo=expInfo, originPath=-1, - trialList=[None], - seed=None, name='loop_n') -thisExp.addLoop(loop_n) # add the loop to the experiment -thisLoop_n = loop_n.trialList[0] # so we can initialise stimuli with some values -# abbreviate parameter names if possible (e.g. rgb = thisLoop_n.rgb) -if thisLoop_n != None: - for paramName in thisLoop_n: - exec('{} = thisLoop_n[paramName]'.format(paramName)) - -for thisLoop_n in loop_n: - currentLoop = loop_n - # abbreviate parameter names if possible (e.g. rgb = thisLoop_n.rgb) - if thisLoop_n != None: - for paramName in thisLoop_n: - exec('{} = thisLoop_n[paramName]'.format(paramName)) - - # ------Prepare to start Routine "trial_n"------- - routineTimer.add(2.000000) - # update component parameters for each repeat - if (currentLoop.thisN < int(expInfo['backN'])) or (np.random.uniform() > float(expInfo['probability'])): - stimleft = np.delete(stimuli,[np.argwhere(stimuli==i) for i in prevN]) - stimulus = np.random.choice(stimleft) - else: - stimulus = prevN[-int(expInfo['backN'])] - tial_n_letter.setText(stimulus) - # keep track of which components have finished - trial_nComponents = [trial_n_screen, tial_n_letter] - for thisComponent in trial_nComponents: - thisComponent.tStart = None - thisComponent.tStop = None - thisComponent.tStartRefresh = None - thisComponent.tStopRefresh = None - if hasattr(thisComponent, 'status'): - thisComponent.status = NOT_STARTED - # reset timers - t = 0 - _timeToFirstFrame = win.getFutureFlipTime(clock="now") - trial_nClock.reset(-_timeToFirstFrame) # t0 is time of first possible flip - frameN = -1 - continueRoutine = True - - # -------Run Routine "trial_n"------- - while continueRoutine and routineTimer.getTime() > 0: - # get current time - t = trial_nClock.getTime() - tThisFlip = win.getFutureFlipTime(clock=trial_nClock) - tThisFlipGlobal = win.getFutureFlipTime(clock=None) - frameN = frameN + 1 # number of completed frames (so 0 is the first frame) - # update/draw components on each frame - - # *trial_n_screen* updates - if trial_n_screen.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance: - # keep track of start time/frame for later - trial_n_screen.frameNStart = frameN # exact frame index - trial_n_screen.tStart = t # local t and not account for scr refresh - trial_n_screen.tStartRefresh = tThisFlipGlobal # on global time - win.timeOnFlip(trial_n_screen, 'tStartRefresh') # time at next scr refresh - trial_n_screen.setAutoDraw(True) - if trial_n_screen.status == STARTED: - # is it time to stop? (based on global clock, using actual start) - if tThisFlipGlobal > trial_n_screen.tStartRefresh + 2-frameTolerance: - # keep track of stop time/frame for later - trial_n_screen.tStop = t # not accounting for scr refresh - trial_n_screen.frameNStop = frameN # exact frame index - win.timeOnFlip(trial_n_screen, 'tStopRefresh') # time at next scr refresh - trial_n_screen.setAutoDraw(False) - - # *tial_n_letter* updates - if tial_n_letter.status == NOT_STARTED and tThisFlip >= 0-frameTolerance: - # keep track of start time/frame for later - tial_n_letter.frameNStart = frameN # exact frame index - tial_n_letter.tStart = t # local t and not account for scr refresh - tial_n_letter.tStartRefresh = tThisFlipGlobal # on global time - win.timeOnFlip(tial_n_letter, 'tStartRefresh') # time at next scr refresh - tial_n_letter.setAutoDraw(True) - if tial_n_letter.status == STARTED: - # is it time to stop? (based on global clock, using actual start) - if tThisFlipGlobal > tial_n_letter.tStartRefresh + 0.03-frameTolerance: - # keep track of stop time/frame for later - tial_n_letter.tStop = t # not accounting for scr refresh - tial_n_letter.frameNStop = frameN # exact frame index - win.timeOnFlip(tial_n_letter, 'tStopRefresh') # time at next scr refresh - tial_n_letter.setAutoDraw(False) - - # check for quit (typically the Esc key) - if endExpNow or defaultKeyboard.getKeys(keyList=["escape"]): - core.quit() - - # check if all components have finished - if not continueRoutine: # a component has requested a forced-end of Routine - break - continueRoutine = False # will revert to True if at least one component still running - for thisComponent in trial_nComponents: - if hasattr(thisComponent, "status") and thisComponent.status != FINISHED: - continueRoutine = True - break # at least one component has not yet finished - - # refresh the screen - if continueRoutine: # don't flip if this routine is over or we'll get a blank screen - win.flip() - - # -------Ending Routine "trial_n"------- - for thisComponent in trial_nComponents: - if hasattr(thisComponent, "setAutoDraw"): - thisComponent.setAutoDraw(False) - thisExp.addData('tial_n_letter.stim', stimulus) - prevN = np.hstack((prevN,stimulus)) - prevN = prevN[-3:] - loop_n.addData('trial_n_screen.started', trial_n_screen.tStartRefresh) - loop_n.addData('trial_n_screen.stopped', trial_n_screen.tStopRefresh) - loop_n.addData('tial_n_letter.started', tial_n_letter.tStartRefresh) - loop_n.addData('tial_n_letter.stopped', tial_n_letter.tStopRefresh) - thisExp.nextEntry() - -# completed 20 repeats of 'loop_n' - - -# Flip one final time so any remaining win.callOnFlip() -# and win.timeOnFlip() tasks get executed before quitting -win.flip() - -# these shouldn't be strictly necessary (should auto-save) -thisExp.saveAsWideText(filename+'.csv') -thisExp.saveAsPickle(filename) -logging.flush() -# make sure everything is closed down -thisExp.abort() # or data files will save again on exit -win.close() -core.quit() -- GitLab