#!/usr/bin/env python # -*- coding: utf-8 -*- """ This experiment was created using PsychoPy3 Experiment Builder (v2020.2.10), on April 27, 2021, at 20:29 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 = '2020.2.10' expName = 'independent-randomisation' # from the Builder filename that created this script expInfo = {'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='C:\\Users\\p0071480\\Documents\\Pavlovia\\vespr\\independent-randomisation\\independent-randomisation_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 after the window creation # Setup the Window win = visual.Window( size=(1024, 768), fullscr=True, screen=0, winType='pyglet', allowGUI=False, allowStencil=False, monitor='testMonitor', color=[0,0,0], colorSpace='rgb', blendMode='avg', useFBO=True, units='height') # 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 "start" startClock = core.Clock() text_instruct = visual.TextStim(win=win, name='text_instruct', text='Is the letter on the left or the right?\n\nPress the left or right arrow key to respond.\n\nPlease press the spacebar to start.', font='Arial', pos=(0, 0), height=0.05, wrapWidth=None, ori=0, color='white', colorSpace='rgb', opacity=1, languageStyle='LTR', depth=-1.0); key_instruct = keyboard.Keyboard() # Initialize components for Routine "loadA" loadAClock = core.Clock() listA=[] # Initialize components for Routine "trial" trialClock = core.Clock() sides=[-.3,.3] corrAns='' score = 0 text_letter = visual.TextStim(win=win, name='text_letter', text='default text', font='Arial', pos=[0,0], height=0.1, wrapWidth=None, ori=0, color='white', colorSpace='rgb', opacity=1, languageStyle='LTR', depth=-1.0); text_number = visual.TextStim(win=win, name='text_number', text='default text', font='Arial', pos=[0,0], height=0.1, wrapWidth=None, ori=0, color='white', colorSpace='rgb', opacity=1, languageStyle='LTR', depth=-2.0); key_resp = keyboard.Keyboard() # Initialize components for Routine "end" endClock = core.Clock() text = visual.TextStim(win=win, name='text', text='default text', font='Arial', pos=(0, 0), height=0.1, wrapWidth=None, ori=0, color='white', colorSpace='rgb', opacity=1, languageStyle='LTR', depth=0.0); key_resp_2 = keyboard.Keyboard() # 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 "start"------- continueRoutine = True # update component parameters for each repeat key_instruct.keys = [] key_instruct.rt = [] _key_instruct_allKeys = [] # keep track of which components have finished startComponents = [text_instruct, key_instruct] for thisComponent in startComponents: 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") startClock.reset(-_timeToFirstFrame) # t0 is time of first possible flip frameN = -1 # -------Run Routine "start"------- while continueRoutine: # get current time t = startClock.getTime() tThisFlip = win.getFutureFlipTime(clock=startClock) tThisFlipGlobal = win.getFutureFlipTime(clock=None) frameN = frameN + 1 # number of completed frames (so 0 is the first frame) # update/draw components on each frame # *text_instruct* updates if text_instruct.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance: # keep track of start time/frame for later text_instruct.frameNStart = frameN # exact frame index text_instruct.tStart = t # local t and not account for scr refresh text_instruct.tStartRefresh = tThisFlipGlobal # on global time win.timeOnFlip(text_instruct, 'tStartRefresh') # time at next scr refresh text_instruct.setAutoDraw(True) # *key_instruct* updates waitOnFlip = False if key_instruct.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance: # keep track of start time/frame for later key_instruct.frameNStart = frameN # exact frame index key_instruct.tStart = t # local t and not account for scr refresh key_instruct.tStartRefresh = tThisFlipGlobal # on global time win.timeOnFlip(key_instruct, 'tStartRefresh') # time at next scr refresh key_instruct.status = STARTED # keyboard checking is just starting waitOnFlip = True win.callOnFlip(key_instruct.clock.reset) # t=0 on next screen flip win.callOnFlip(key_instruct.clearEvents, eventType='keyboard') # clear events on next screen flip if key_instruct.status == STARTED and not waitOnFlip: theseKeys = key_instruct.getKeys(keyList=['space'], waitRelease=False) _key_instruct_allKeys.extend(theseKeys) if len(_key_instruct_allKeys): key_instruct.keys = _key_instruct_allKeys[-1].name # just the last key pressed key_instruct.rt = _key_instruct_allKeys[-1].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 startComponents: 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 "start"------- for thisComponent in startComponents: if hasattr(thisComponent, "setAutoDraw"): thisComponent.setAutoDraw(False) # the Routine "start" was not non-slip safe, so reset the non-slip timer routineTimer.reset() # set up handler to look after randomisation of conditions etc loading_loop = data.TrialHandler(nReps=3, method='random', extraInfo=expInfo, originPath=-1, trialList=data.importConditions('stimuli.xlsx', selection='0:10'), seed=None, name='loading_loop') thisExp.addLoop(loading_loop) # add the loop to the experiment thisLoading_loop = loading_loop.trialList[0] # so we can initialise stimuli with some values # abbreviate parameter names if possible (e.g. rgb = thisLoading_loop.rgb) if thisLoading_loop != None: for paramName in thisLoading_loop: exec('{} = thisLoading_loop[paramName]'.format(paramName)) for thisLoading_loop in loading_loop: currentLoop = loading_loop # abbreviate parameter names if possible (e.g. rgb = thisLoading_loop.rgb) if thisLoading_loop != None: for paramName in thisLoading_loop: exec('{} = thisLoading_loop[paramName]'.format(paramName)) # ------Prepare to start Routine "loadA"------- continueRoutine = True # update component parameters for each repeat listA.append(str(int(colA))) # keep track of which components have finished loadAComponents = [] for thisComponent in loadAComponents: 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") loadAClock.reset(-_timeToFirstFrame) # t0 is time of first possible flip frameN = -1 # -------Run Routine "loadA"------- while continueRoutine: # get current time t = loadAClock.getTime() tThisFlip = win.getFutureFlipTime(clock=loadAClock) tThisFlipGlobal = win.getFutureFlipTime(clock=None) frameN = frameN + 1 # number of completed frames (so 0 is the first frame) # update/draw components on each frame # 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 loadAComponents: 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 "loadA"------- for thisComponent in loadAComponents: if hasattr(thisComponent, "setAutoDraw"): thisComponent.setAutoDraw(False) # the Routine "loadA" was not non-slip safe, so reset the non-slip timer routineTimer.reset() # completed 3 repeats of 'loading_loop' # set up handler to look after randomisation of conditions etc trials = data.TrialHandler(nReps=1, method='random', extraInfo=expInfo, originPath=-1, trialList=data.importConditions('stimuli.xlsx'), seed=None, name='trials') thisExp.addLoop(trials) # add the loop to the experiment thisTrial = trials.trialList[0] # so we can initialise stimuli with some values # abbreviate parameter names if possible (e.g. rgb = thisTrial.rgb) if thisTrial != None: for paramName in thisTrial: exec('{} = thisTrial[paramName]'.format(paramName)) for thisTrial in trials: currentLoop = trials # abbreviate parameter names if possible (e.g. rgb = thisTrial.rgb) if thisTrial != None: for paramName in thisTrial: exec('{} = thisTrial[paramName]'.format(paramName)) # ------Prepare to start Routine "trial"------- continueRoutine = True # update component parameters for each repeat thisA=listA.pop() shuffle(sides) if sides[0]>0: corrAns='right' else: corrAns='left' thisExp.addData('Answer',corrAns) text_letter.setPos((sides[0], 0)) text_letter.setText(colB) text_number.setPos((sides[1], 0)) text_number.setText(thisA) key_resp.keys = [] key_resp.rt = [] _key_resp_allKeys = [] # keep track of which components have finished trialComponents = [text_letter, text_number, key_resp] for thisComponent in trialComponents: 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") trialClock.reset(-_timeToFirstFrame) # t0 is time of first possible flip frameN = -1 # -------Run Routine "trial"------- while continueRoutine: # get current time 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 # *text_letter* updates if text_letter.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance: # keep track of start time/frame for later text_letter.frameNStart = frameN # exact frame index text_letter.tStart = t # local t and not account for scr refresh text_letter.tStartRefresh = tThisFlipGlobal # on global time win.timeOnFlip(text_letter, 'tStartRefresh') # time at next scr refresh text_letter.setAutoDraw(True) # *text_number* updates if text_number.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance: # keep track of start time/frame for later text_number.frameNStart = frameN # exact frame index text_number.tStart = t # local t and not account for scr refresh text_number.tStartRefresh = tThisFlipGlobal # on global time win.timeOnFlip(text_number, 'tStartRefresh') # time at next scr refresh text_number.setAutoDraw(True) # *key_resp* updates waitOnFlip = False if key_resp.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance: # keep track of start time/frame for later key_resp.frameNStart = frameN # exact frame index key_resp.tStart = t # local t and not account for scr refresh key_resp.tStartRefresh = tThisFlipGlobal # on global time win.timeOnFlip(key_resp, 'tStartRefresh') # time at next scr refresh key_resp.status = STARTED # keyboard checking is just starting waitOnFlip = True win.callOnFlip(key_resp.clock.reset) # t=0 on next screen flip win.callOnFlip(key_resp.clearEvents, eventType='keyboard') # clear events on next screen flip if key_resp.status == STARTED and not waitOnFlip: theseKeys = key_resp.getKeys(keyList=['left', 'right'], waitRelease=False) _key_resp_allKeys.extend(theseKeys) if len(_key_resp_allKeys): key_resp.keys = _key_resp_allKeys[0].name # just the first key pressed key_resp.rt = _key_resp_allKeys[0].rt # was this correct? if (key_resp.keys == str(corrAns)) or (key_resp.keys == corrAns): key_resp.corr = 1 else: key_resp.corr = 0 # 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 trialComponents: 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"------- for thisComponent in trialComponents: if hasattr(thisComponent, "setAutoDraw"): thisComponent.setAutoDraw(False) score+=key_resp.corr trials.addData('text_letter.started', text_letter.tStartRefresh) trials.addData('text_letter.stopped', text_letter.tStopRefresh) trials.addData('text_number.started', text_number.tStartRefresh) trials.addData('text_number.stopped', text_number.tStopRefresh) # check responses if key_resp.keys in ['', [], None]: # No response was made key_resp.keys = None # was no response the correct answer?! if str(corrAns).lower() == 'none': key_resp.corr = 1; # correct non-response else: key_resp.corr = 0; # failed to respond (incorrectly) # store data for trials (TrialHandler) trials.addData('key_resp.keys',key_resp.keys) trials.addData('key_resp.corr', key_resp.corr) if key_resp.keys != None: # we had a response trials.addData('key_resp.rt', key_resp.rt) trials.addData('key_resp.started', key_resp.tStartRefresh) trials.addData('key_resp.stopped', key_resp.tStopRefresh) # the Routine "trial" was not non-slip safe, so reset the non-slip timer routineTimer.reset() thisExp.nextEntry() # completed 1 repeats of 'trials' # ------Prepare to start Routine "end"------- continueRoutine = True # update component parameters for each repeat text.setText('You scored '+str(score)+' points.') key_resp_2.keys = [] key_resp_2.rt = [] _key_resp_2_allKeys = [] # keep track of which components have finished endComponents = [text, key_resp_2] for thisComponent in endComponents: 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") endClock.reset(-_timeToFirstFrame) # t0 is time of first possible flip frameN = -1 # -------Run Routine "end"------- while continueRoutine: # get current time t = endClock.getTime() tThisFlip = win.getFutureFlipTime(clock=endClock) tThisFlipGlobal = win.getFutureFlipTime(clock=None) frameN = frameN + 1 # number of completed frames (so 0 is the first frame) # update/draw components on each frame # *text* updates if text.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance: # keep track of start time/frame for later text.frameNStart = frameN # exact frame index text.tStart = t # local t and not account for scr refresh text.tStartRefresh = tThisFlipGlobal # on global time win.timeOnFlip(text, 'tStartRefresh') # time at next scr refresh text.setAutoDraw(True) # *key_resp_2* updates waitOnFlip = False if key_resp_2.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance: # keep track of start time/frame for later key_resp_2.frameNStart = frameN # exact frame index key_resp_2.tStart = t # local t and not account for scr refresh key_resp_2.tStartRefresh = tThisFlipGlobal # on global time win.timeOnFlip(key_resp_2, 'tStartRefresh') # time at next scr refresh key_resp_2.status = STARTED # keyboard checking is just starting waitOnFlip = True win.callOnFlip(key_resp_2.clock.reset) # t=0 on next screen flip win.callOnFlip(key_resp_2.clearEvents, eventType='keyboard') # clear events on next screen flip if key_resp_2.status == STARTED and not waitOnFlip: theseKeys = key_resp_2.getKeys(keyList=['y', 'n', 'left', 'right', 'space'], waitRelease=False) _key_resp_2_allKeys.extend(theseKeys) if len(_key_resp_2_allKeys): key_resp_2.keys = _key_resp_2_allKeys[-1].name # just the last key pressed key_resp_2.rt = _key_resp_2_allKeys[-1].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 endComponents: 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 "end"------- for thisComponent in endComponents: if hasattr(thisComponent, "setAutoDraw"): thisComponent.setAutoDraw(False) thisExp.addData('text.started', text.tStartRefresh) thisExp.addData('text.stopped', text.tStopRefresh) # check responses if key_resp_2.keys in ['', [], None]: # No response was made key_resp_2.keys = None thisExp.addData('key_resp_2.keys',key_resp_2.keys) if key_resp_2.keys != None: # we had a response thisExp.addData('key_resp_2.rt', key_resp_2.rt) thisExp.addData('key_resp_2.started', key_resp_2.tStartRefresh) thisExp.addData('key_resp_2.stopped', key_resp_2.tStopRefresh) thisExp.nextEntry() # the Routine "end" was not non-slip safe, so reset the non-slip timer routineTimer.reset() # 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', delim='auto') 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()