#!/usr/bin/env python # -*- coding: utf-8 -*- """ This experiment was created using PsychoPy3 Experiment Builder (v2020.1.3), on Октябрь 04, 2020, at 20:26 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 import psychopy psychopy.useVersion('2020.1.3') from psychopy import locale_setup from psychopy import prefs prefs.hardware['audioLib'] = 'pyo' prefs.hardware['audioLatencyMode'] = '3' from psychopy import sound, gui, visual, core, data, event, logging, clock, parallel, microphone 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.1.3' expName = 'peavler' # from the Builder filename that created this script expInfo = {'participant': '', 'session': 'experiment'} 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:\\GoogleDisk\\Neurotech_lab\\cogLoad_project\\scripts\\peavlerRepl\\v15\\peavler_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 wavDirName = filename + '_wav' if not os.path.isdir(wavDirName): os.makedirs(wavDirName) # to hold .wav files # Setup the Window win = visual.Window( size=[200, 200], fullscr=False, screen=0, winType='pyglet', allowGUI=True, allowStencil=False, monitor='testMonitor', color=[0, 0, 0], colorSpace='rgb', blendMode='avg', useFBO=True, units='height') # Enable sound input/output: microphone.switchOn() # 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 "Randomizer" RandomizerClock = core.Clock() from numpy.random import choice import random from numpy import arange, concatenate def randomDigits(numOfReps): if numOfReps<=10: return choice(10, size=numOfReps, replace=False) else: arr1 = list(choice(10, size=10, replace=False)) arr2 = list(choice(10, size=numOfReps-10, replace=False)) while arr2[0] == arr1[-1]: random.shuffle(arr2) return arr1+arr2 from zmq_socket import ZMQsocket from time import sleep, time #remote_ip = '192.168.0.2' remote_ip = '127.0.0.1' print('Make sure the ports match with Pupil Capture Remote Plugin and the one in zmq_pocket.py') port = '50020' socket = ZMQsocket(remote_ip,port) socket.connect() # socket.start_calibration() # Grab the time module for timesync time_fn = time # Sync time print(socket.set_time(time_fn)) # # Start the notifications plugin socket.notify({'subject': 'start_plugin', 'name': 'Annotation_Capture', 'args': {}}) # socket.start_recording() # commenting this out to test something, needs to be uncommented later. core.wait(0.005) ## send name of the participant as a trigger socket.annotation(str('Participant number '+expInfo['participant']), 0) print(str('Participant number '+expInfo['participant'])) core.wait(10.005) # Initialize components for Routine "instruction" instructionClock = core.Clock() blockN=1 trigger_instr_EEG = parallel.ParallelPort(address='0x0378') instruction_text = visual.TextStim(win=win, name='instruction_text', text='default text', font='Arial', pos=(0, 0), height=0.056, wrapWidth=None, ori=0, color='white', colorSpace='rgb', opacity=1, languageStyle='LTR', depth=-2.0); start_sound = sound.Sound('A', secs=-1, stereo=True, hamming=True, name='start_sound') start_sound.setVolume(1) exclamationMark = visual.TextStim(win=win, name='exclamationMark', text='!', font='Arial', pos=(0, 0), height=0.076, wrapWidth=None, ori=0, color=[1,1,1], colorSpace='rgb', opacity=1, languageStyle='LTR', depth=-4.0); # Initialize components for Routine "baseline_3s" baseline_3sClock = core.Clock() trigger_baseline_EEG = parallel.ParallelPort(address='0x0378') fixCross = visual.ImageStim( win=win, name='fixCross', image='num/FixCross.png', mask=None, ori=0, pos=(0, 0), size=None, color=[1,1,1], colorSpace='rgb', opacity=1, flipHoriz=False, flipVert=False, texRes=128, interpolate=True, depth=-2.0) # Initialize components for Routine "digits" digitsClock = core.Clock() trigger_digits_EEG = parallel.ParallelPort(address='0x0378') sound_digit = sound.Sound('A', secs=-1, stereo=True, hamming=True, name='sound_digit') sound_digit.setVolume(1) FixCross_answ = visual.ImageStim( win=win, name='FixCross_answ', image='num/FixCross.png', mask=None, ori=0, pos=(0, 0), size=None, color=[1,1,1], colorSpace='rgb', opacity=1, flipHoriz=False, flipVert=False, texRes=128, interpolate=True, depth=-3.0) # Initialize components for Routine "retention_1s" retention_1sClock = core.Clock() trigger_retention_EEG = parallel.ParallelPort(address='0x0378') fixCross_1s = visual.ImageStim( win=win, name='fixCross_1s', image='num/FixCross.png', mask=None, ori=0, pos=(0, 0), size=None, color=[1,1,1], colorSpace='rgb', opacity=1, flipHoriz=False, flipVert=False, texRes=128, interpolate=True, depth=-2.0) # Initialize components for Routine "repeat" repeatClock = core.Clock() trigger_mic_EEG = parallel.ParallelPort(address='0x0378') mic_image = visual.ImageStim( win=win, name='mic_image', image='num/mic_white.png', mask=None, ori=0, pos=(0, 0), size=(0.67, 0.36), color=[1,1,1], colorSpace='rgb', opacity=1, flipHoriz=False, flipVert=False, texRes=128, interpolate=True, depth=-4.0) # Initialize components for Routine "end_block" end_blockClock = core.Clock() trigger_endBlock_EEG = parallel.ParallelPort(address='0x0378') end = sound.Sound('A', secs=-1, stereo=True, hamming=True, name='end') end.setVolume(1) FixCross_end = visual.ImageStim( win=win, name='FixCross_end', image='num/FixCross.png', mask=None, ori=0, pos=(0, 0), size=None, color=[1,1,1], colorSpace='rgb', opacity=0, flipHoriz=False, flipVert=False, texRes=128, interpolate=True, depth=-3.0) # Initialize components for Routine "rest" restClock = core.Clock() trigger_rest_EEG = parallel.ParallelPort(address='0x0378') rest_instruction = visual.TextStim(win=win, name='rest_instruction', text='default text', font='Arial', pos=(0, 0), height=0.056, wrapWidth=None, ori=0, color='white', colorSpace='rgb', opacity=1, languageStyle='LTR', depth=-2.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 # set up handler to look after randomisation of conditions etc trialSet_9 = data.TrialHandler(nReps=1, method='sequential', extraInfo=expInfo, originPath=-1, trialList=data.importConditions('rest_inst.xlsx'), seed=None, name='trialSet_9') thisExp.addLoop(trialSet_9) # add the loop to the experiment thisTrialSet_9 = trialSet_9.trialList[0] # so we can initialise stimuli with some values # abbreviate parameter names if possible (e.g. rgb = thisTrialSet_9.rgb) if thisTrialSet_9 != None: for paramName in thisTrialSet_9: exec('{} = thisTrialSet_9[paramName]'.format(paramName)) for thisTrialSet_9 in trialSet_9: currentLoop = trialSet_9 # abbreviate parameter names if possible (e.g. rgb = thisTrialSet_9.rgb) if thisTrialSet_9 != None: for paramName in thisTrialSet_9: exec('{} = thisTrialSet_9[paramName]'.format(paramName)) # ------Prepare to start Routine "Randomizer"------- continueRoutine = True # update component parameters for each repeat # 3 listen + 12 remember + 3 listen trials per block l1 = choice([0,1,2],3,replace=False) r = choice(arange(3,15),12,replace=False) l2 = choice([15,16,17],3,replace=False) trialsOrder = concatenate([l1,r,l2]) # keep track of which components have finished RandomizerComponents = [] for thisComponent in RandomizerComponents: 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") RandomizerClock.reset(-_timeToFirstFrame) # t0 is time of first possible flip frameN = -1 # -------Run Routine "Randomizer"------- while continueRoutine: # get current time t = RandomizerClock.getTime() tThisFlip = win.getFutureFlipTime(clock=RandomizerClock) 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 RandomizerComponents: 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 "Randomizer"------- for thisComponent in RandomizerComponents: if hasattr(thisComponent, "setAutoDraw"): thisComponent.setAutoDraw(False) # the Routine "Randomizer" was not non-slip safe, so reset the non-slip timer routineTimer.reset() # set up handler to look after randomisation of conditions etc trials = data.TrialHandler(nReps=1, method='sequential', extraInfo=expInfo, originPath=-1, trialList=data.importConditions('repNums_'+str(int(expInfo['participant'])%2)+'.xlsx', selection=trialsOrder), 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 "instruction"------- continueRoutine = True # update component parameters for each repeat ## ET trigger ## # listen or remember trials socket.annotation(str(trialType_trCode), 0) ## info about current trial print('\nSet number: {}/9\nBlock number: {}/162\nLength of the string: {}\nTrial type: {}'.format(setN, blockN, numOfReps, trialType)) blockN=blockN+1 instruction_text.setColor(instrCol, colorSpace='rgb') instruction_text.setText(inst) start_sound.setSound('num/start.wav', hamming=True) start_sound.setVolume(1, log=False) # keep track of which components have finished instructionComponents = [trigger_instr_EEG, instruction_text, start_sound, exclamationMark] for thisComponent in instructionComponents: 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") instructionClock.reset(-_timeToFirstFrame) # t0 is time of first possible flip frameN = -1 # -------Run Routine "instruction"------- while continueRoutine: # get current time t = instructionClock.getTime() tThisFlip = win.getFutureFlipTime(clock=instructionClock) tThisFlipGlobal = win.getFutureFlipTime(clock=None) frameN = frameN + 1 # number of completed frames (so 0 is the first frame) # update/draw components on each frame # *trigger_instr_EEG* updates if trigger_instr_EEG.status == NOT_STARTED and t >= 0.0-frameTolerance: # keep track of start time/frame for later trigger_instr_EEG.frameNStart = frameN # exact frame index trigger_instr_EEG.tStart = t # local t and not account for scr refresh trigger_instr_EEG.tStartRefresh = tThisFlipGlobal # on global time win.timeOnFlip(trigger_instr_EEG, 'tStartRefresh') # time at next scr refresh trigger_instr_EEG.status = STARTED trigger_instr_EEG.setData(int(trialType_trCode)) if trigger_instr_EEG.status == STARTED: # is it time to stop? (based on global clock, using actual start) if tThisFlipGlobal > trigger_instr_EEG.tStartRefresh + 0.02-frameTolerance: # keep track of stop time/frame for later trigger_instr_EEG.tStop = t # not accounting for scr refresh trigger_instr_EEG.frameNStop = frameN # exact frame index win.timeOnFlip(trigger_instr_EEG, 'tStopRefresh') # time at next scr refresh trigger_instr_EEG.status = FINISHED trigger_instr_EEG.setData(int(0)) # *instruction_text* updates if instruction_text.status == NOT_STARTED and tThisFlip >= 0.5-frameTolerance: # keep track of start time/frame for later instruction_text.frameNStart = frameN # exact frame index instruction_text.tStart = t # local t and not account for scr refresh instruction_text.tStartRefresh = tThisFlipGlobal # on global time win.timeOnFlip(instruction_text, 'tStartRefresh') # time at next scr refresh instruction_text.setAutoDraw(True) if instruction_text.status == STARTED: # is it time to stop? (based on global clock, using actual start) if tThisFlipGlobal > instruction_text.tStartRefresh + 1-frameTolerance: # keep track of stop time/frame for later instruction_text.tStop = t # not accounting for scr refresh instruction_text.frameNStop = frameN # exact frame index win.timeOnFlip(instruction_text, 'tStopRefresh') # time at next scr refresh instruction_text.setAutoDraw(False) # start/stop start_sound if start_sound.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance: # keep track of start time/frame for later start_sound.frameNStart = frameN # exact frame index start_sound.tStart = t # local t and not account for scr refresh start_sound.tStartRefresh = tThisFlipGlobal # on global time start_sound.play(when=win) # sync with win flip # *exclamationMark* updates if exclamationMark.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance: # keep track of start time/frame for later exclamationMark.frameNStart = frameN # exact frame index exclamationMark.tStart = t # local t and not account for scr refresh exclamationMark.tStartRefresh = tThisFlipGlobal # on global time win.timeOnFlip(exclamationMark, 'tStartRefresh') # time at next scr refresh exclamationMark.setAutoDraw(True) if exclamationMark.status == STARTED: # is it time to stop? (based on global clock, using actual start) if tThisFlipGlobal > exclamationMark.tStartRefresh + 0.5-frameTolerance: # keep track of stop time/frame for later exclamationMark.tStop = t # not accounting for scr refresh exclamationMark.frameNStop = frameN # exact frame index win.timeOnFlip(exclamationMark, 'tStopRefresh') # time at next scr refresh exclamationMark.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 instructionComponents: 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 "instruction"------- for thisComponent in instructionComponents: if hasattr(thisComponent, "setAutoDraw"): thisComponent.setAutoDraw(False) if trigger_instr_EEG.status == STARTED: trigger_instr_EEG.setData(int(0)) trials.addData('trigger_instr_EEG.started', trigger_instr_EEG.tStart) trials.addData('trigger_instr_EEG.stopped', trigger_instr_EEG.tStop) trials.addData('instruction_text.started', instruction_text.tStartRefresh) trials.addData('instruction_text.stopped', instruction_text.tStopRefresh) start_sound.stop() # ensure sound has stopped at end of routine trials.addData('start_sound.started', start_sound.tStartRefresh) trials.addData('start_sound.stopped', start_sound.tStopRefresh) trials.addData('exclamationMark.started', exclamationMark.tStartRefresh) trials.addData('exclamationMark.stopped', exclamationMark.tStopRefresh) # the Routine "instruction" was not non-slip safe, so reset the non-slip timer routineTimer.reset() # ------Prepare to start Routine "baseline_3s"------- continueRoutine = True routineTimer.add(3.000000) # update component parameters for each repeat # 105,109,113 - remember 5,9,13 digits socket.annotation(str(100+numOfReps), 0) # EEG trigger eegTr = 100+numOfReps # keep track of which components have finished baseline_3sComponents = [trigger_baseline_EEG, fixCross] for thisComponent in baseline_3sComponents: 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") baseline_3sClock.reset(-_timeToFirstFrame) # t0 is time of first possible flip frameN = -1 # -------Run Routine "baseline_3s"------- while continueRoutine and routineTimer.getTime() > 0: # get current time t = baseline_3sClock.getTime() tThisFlip = win.getFutureFlipTime(clock=baseline_3sClock) tThisFlipGlobal = win.getFutureFlipTime(clock=None) frameN = frameN + 1 # number of completed frames (so 0 is the first frame) # update/draw components on each frame # *trigger_baseline_EEG* updates if trigger_baseline_EEG.status == NOT_STARTED and t >= 0.0-frameTolerance: # keep track of start time/frame for later trigger_baseline_EEG.frameNStart = frameN # exact frame index trigger_baseline_EEG.tStart = t # local t and not account for scr refresh trigger_baseline_EEG.tStartRefresh = tThisFlipGlobal # on global time win.timeOnFlip(trigger_baseline_EEG, 'tStartRefresh') # time at next scr refresh trigger_baseline_EEG.status = STARTED trigger_baseline_EEG.setData(int(eegTr)) if trigger_baseline_EEG.status == STARTED: # is it time to stop? (based on global clock, using actual start) if tThisFlipGlobal > trigger_baseline_EEG.tStartRefresh + 0.02-frameTolerance: # keep track of stop time/frame for later trigger_baseline_EEG.tStop = t # not accounting for scr refresh trigger_baseline_EEG.frameNStop = frameN # exact frame index win.timeOnFlip(trigger_baseline_EEG, 'tStopRefresh') # time at next scr refresh trigger_baseline_EEG.status = FINISHED trigger_baseline_EEG.setData(int(0)) # *fixCross* updates if fixCross.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance: # keep track of start time/frame for later fixCross.frameNStart = frameN # exact frame index fixCross.tStart = t # local t and not account for scr refresh fixCross.tStartRefresh = tThisFlipGlobal # on global time win.timeOnFlip(fixCross, 'tStartRefresh') # time at next scr refresh fixCross.setAutoDraw(True) if fixCross.status == STARTED: # is it time to stop? (based on global clock, using actual start) if tThisFlipGlobal > fixCross.tStartRefresh + 3.0-frameTolerance: # keep track of stop time/frame for later fixCross.tStop = t # not accounting for scr refresh fixCross.frameNStop = frameN # exact frame index win.timeOnFlip(fixCross, 'tStopRefresh') # time at next scr refresh fixCross.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 baseline_3sComponents: 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 "baseline_3s"------- for thisComponent in baseline_3sComponents: if hasattr(thisComponent, "setAutoDraw"): thisComponent.setAutoDraw(False) if trigger_baseline_EEG.status == STARTED: trigger_baseline_EEG.setData(int(0)) trials.addData('trigger_baseline_EEG.started', trigger_baseline_EEG.tStart) trials.addData('trigger_baseline_EEG.stopped', trigger_baseline_EEG.tStop) trials.addData('fixCross.started', fixCross.tStartRefresh) trials.addData('fixCross.stopped', fixCross.tStopRefresh) # set up handler to look after randomisation of conditions etc present_sounds = data.TrialHandler(nReps=1, method='sequential', extraInfo=expInfo, originPath=-1, trialList=data.importConditions('sounds.xlsx', selection=randomDigits(numOfReps)), seed=None, name='present_sounds') thisExp.addLoop(present_sounds) # add the loop to the experiment thisPresent_sound = present_sounds.trialList[0] # so we can initialise stimuli with some values # abbreviate parameter names if possible (e.g. rgb = thisPresent_sound.rgb) if thisPresent_sound != None: for paramName in thisPresent_sound: exec('{} = thisPresent_sound[paramName]'.format(paramName)) for thisPresent_sound in present_sounds: currentLoop = present_sounds # abbreviate parameter names if possible (e.g. rgb = thisPresent_sound.rgb) if thisPresent_sound != None: for paramName in thisPresent_sound: exec('{} = thisPresent_sound[paramName]'.format(paramName)) # ------Prepare to start Routine "digits"------- continueRoutine = True # update component parameters for each repeat digit = int(sounds[4:][:-4]) socket.annotation(digit, 0) sound_digit.setSound(sounds, hamming=True) sound_digit.setVolume(1, log=False) # keep track of which components have finished digitsComponents = [trigger_digits_EEG, sound_digit, FixCross_answ] for thisComponent in digitsComponents: 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") digitsClock.reset(-_timeToFirstFrame) # t0 is time of first possible flip frameN = -1 # -------Run Routine "digits"------- while continueRoutine: # get current time t = digitsClock.getTime() tThisFlip = win.getFutureFlipTime(clock=digitsClock) tThisFlipGlobal = win.getFutureFlipTime(clock=None) frameN = frameN + 1 # number of completed frames (so 0 is the first frame) # update/draw components on each frame # *trigger_digits_EEG* updates if trigger_digits_EEG.status == NOT_STARTED and t >= 0.0-frameTolerance: # keep track of start time/frame for later trigger_digits_EEG.frameNStart = frameN # exact frame index trigger_digits_EEG.tStart = t # local t and not account for scr refresh trigger_digits_EEG.tStartRefresh = tThisFlipGlobal # on global time win.timeOnFlip(trigger_digits_EEG, 'tStartRefresh') # time at next scr refresh trigger_digits_EEG.status = STARTED trigger_digits_EEG.setData(int(digit)) if trigger_digits_EEG.status == STARTED: # is it time to stop? (based on global clock, using actual start) if tThisFlipGlobal > trigger_digits_EEG.tStartRefresh + 0.02-frameTolerance: # keep track of stop time/frame for later trigger_digits_EEG.tStop = t # not accounting for scr refresh trigger_digits_EEG.frameNStop = frameN # exact frame index win.timeOnFlip(trigger_digits_EEG, 'tStopRefresh') # time at next scr refresh trigger_digits_EEG.status = FINISHED trigger_digits_EEG.setData(int(0)) # start/stop sound_digit if sound_digit.status == NOT_STARTED and t >= 0.0-frameTolerance: # keep track of start time/frame for later sound_digit.frameNStart = frameN # exact frame index sound_digit.tStart = t # local t and not account for scr refresh sound_digit.tStartRefresh = tThisFlipGlobal # on global time sound_digit.play() # start the sound (it finishes automatically) # *FixCross_answ* updates if FixCross_answ.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance: # keep track of start time/frame for later FixCross_answ.frameNStart = frameN # exact frame index FixCross_answ.tStart = t # local t and not account for scr refresh FixCross_answ.tStartRefresh = tThisFlipGlobal # on global time win.timeOnFlip(FixCross_answ, 'tStartRefresh') # time at next scr refresh FixCross_answ.setAutoDraw(True) if FixCross_answ.status == STARTED: # is it time to stop? (based on global clock, using actual start) if tThisFlipGlobal > FixCross_answ.tStartRefresh + 2.0-frameTolerance: # keep track of stop time/frame for later FixCross_answ.tStop = t # not accounting for scr refresh FixCross_answ.frameNStop = frameN # exact frame index win.timeOnFlip(FixCross_answ, 'tStopRefresh') # time at next scr refresh FixCross_answ.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 digitsComponents: 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 "digits"------- for thisComponent in digitsComponents: if hasattr(thisComponent, "setAutoDraw"): thisComponent.setAutoDraw(False) if trigger_digits_EEG.status == STARTED: trigger_digits_EEG.setData(int(0)) present_sounds.addData('trigger_digits_EEG.started', trigger_digits_EEG.tStart) present_sounds.addData('trigger_digits_EEG.stopped', trigger_digits_EEG.tStop) sound_digit.stop() # ensure sound has stopped at end of routine present_sounds.addData('sound_digit.started', sound_digit.tStart) present_sounds.addData('sound_digit.stopped', sound_digit.tStop) present_sounds.addData('FixCross_answ.started', FixCross_answ.tStartRefresh) present_sounds.addData('FixCross_answ.stopped', FixCross_answ.tStopRefresh) # the Routine "digits" was not non-slip safe, so reset the non-slip timer routineTimer.reset() thisExp.nextEntry() # completed 1 repeats of 'present_sounds' # ------Prepare to start Routine "retention_1s"------- continueRoutine = True routineTimer.add(1.000000) # update component parameters for each repeat socket.annotation(171, 0) # keep track of which components have finished retention_1sComponents = [trigger_retention_EEG, fixCross_1s] for thisComponent in retention_1sComponents: 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") retention_1sClock.reset(-_timeToFirstFrame) # t0 is time of first possible flip frameN = -1 # -------Run Routine "retention_1s"------- while continueRoutine and routineTimer.getTime() > 0: # get current time t = retention_1sClock.getTime() tThisFlip = win.getFutureFlipTime(clock=retention_1sClock) tThisFlipGlobal = win.getFutureFlipTime(clock=None) frameN = frameN + 1 # number of completed frames (so 0 is the first frame) # update/draw components on each frame # *trigger_retention_EEG* updates if trigger_retention_EEG.status == NOT_STARTED and t >= 0.0-frameTolerance: # keep track of start time/frame for later trigger_retention_EEG.frameNStart = frameN # exact frame index trigger_retention_EEG.tStart = t # local t and not account for scr refresh trigger_retention_EEG.tStartRefresh = tThisFlipGlobal # on global time win.timeOnFlip(trigger_retention_EEG, 'tStartRefresh') # time at next scr refresh trigger_retention_EEG.status = STARTED trigger_retention_EEG.setData(int(171)) if trigger_retention_EEG.status == STARTED: # is it time to stop? (based on global clock, using actual start) if tThisFlipGlobal > trigger_retention_EEG.tStartRefresh + 0.02-frameTolerance: # keep track of stop time/frame for later trigger_retention_EEG.tStop = t # not accounting for scr refresh trigger_retention_EEG.frameNStop = frameN # exact frame index win.timeOnFlip(trigger_retention_EEG, 'tStopRefresh') # time at next scr refresh trigger_retention_EEG.status = FINISHED trigger_retention_EEG.setData(int(0)) # *fixCross_1s* updates if fixCross_1s.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance: # keep track of start time/frame for later fixCross_1s.frameNStart = frameN # exact frame index fixCross_1s.tStart = t # local t and not account for scr refresh fixCross_1s.tStartRefresh = tThisFlipGlobal # on global time win.timeOnFlip(fixCross_1s, 'tStartRefresh') # time at next scr refresh fixCross_1s.setAutoDraw(True) if fixCross_1s.status == STARTED: # is it time to stop? (based on global clock, using actual start) if tThisFlipGlobal > fixCross_1s.tStartRefresh + 1.0-frameTolerance: # keep track of stop time/frame for later fixCross_1s.tStop = t # not accounting for scr refresh fixCross_1s.frameNStop = frameN # exact frame index win.timeOnFlip(fixCross_1s, 'tStopRefresh') # time at next scr refresh fixCross_1s.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 retention_1sComponents: 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 "retention_1s"------- for thisComponent in retention_1sComponents: if hasattr(thisComponent, "setAutoDraw"): thisComponent.setAutoDraw(False) if trigger_retention_EEG.status == STARTED: trigger_retention_EEG.setData(int(0)) trials.addData('trigger_retention_EEG.started', trigger_retention_EEG.tStart) trials.addData('trigger_retention_EEG.stopped', trigger_retention_EEG.tStop) trials.addData('fixCross_1s.started', fixCross_1s.tStartRefresh) trials.addData('fixCross_1s.stopped', fixCross_1s.tStopRefresh) # ------Prepare to start Routine "repeat"------- continueRoutine = True # update component parameters for each repeat socket.annotation('180', 0) if skip_mic==1: continueRoutine = False mic_1 = microphone.AdvAudioCapture(name='mic_1', saveDir=wavDirName, stereo=False, chnl=0) # keep track of which components have finished repeatComponents = [trigger_mic_EEG, mic_1, mic_image] for thisComponent in repeatComponents: 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") repeatClock.reset(-_timeToFirstFrame) # t0 is time of first possible flip frameN = -1 # -------Run Routine "repeat"------- while continueRoutine: # get current time t = repeatClock.getTime() tThisFlip = win.getFutureFlipTime(clock=repeatClock) tThisFlipGlobal = win.getFutureFlipTime(clock=None) frameN = frameN + 1 # number of completed frames (so 0 is the first frame) # update/draw components on each frame # *trigger_mic_EEG* updates if trigger_mic_EEG.status == NOT_STARTED and t >= 0.0-frameTolerance: # keep track of start time/frame for later trigger_mic_EEG.frameNStart = frameN # exact frame index trigger_mic_EEG.tStart = t # local t and not account for scr refresh trigger_mic_EEG.tStartRefresh = tThisFlipGlobal # on global time win.timeOnFlip(trigger_mic_EEG, 'tStartRefresh') # time at next scr refresh trigger_mic_EEG.status = STARTED trigger_mic_EEG.setData(int(180)) if trigger_mic_EEG.status == STARTED: # is it time to stop? (based on global clock, using actual start) if tThisFlipGlobal > trigger_mic_EEG.tStartRefresh + 0.02-frameTolerance: # keep track of stop time/frame for later trigger_mic_EEG.tStop = t # not accounting for scr refresh trigger_mic_EEG.frameNStop = frameN # exact frame index win.timeOnFlip(trigger_mic_EEG, 'tStopRefresh') # time at next scr refresh trigger_mic_EEG.status = FINISHED trigger_mic_EEG.setData(int(0)) # *mic_1* updates if mic_1.status == NOT_STARTED and t >= 0-frameTolerance: # keep track of start time/frame for later mic_1.frameNStart = frameN # exact frame index mic_1.tStart = t # local t and not account for scr refresh mic_1.tStartRefresh = tThisFlipGlobal # on global time win.timeOnFlip(mic_1, 'tStartRefresh') # time at next scr refresh mic_1.status = STARTED mic_1.record(sec=micDuration, block=False) # start the recording thread if mic_1.status == STARTED and not mic_1.recorder.running: mic_1.status = FINISHED # *mic_image* updates if mic_image.status == NOT_STARTED and tThisFlip >= 0-frameTolerance: # keep track of start time/frame for later mic_image.frameNStart = frameN # exact frame index mic_image.tStart = t # local t and not account for scr refresh mic_image.tStartRefresh = tThisFlipGlobal # on global time win.timeOnFlip(mic_image, 'tStartRefresh') # time at next scr refresh mic_image.setAutoDraw(True) if mic_image.status == STARTED: # is it time to stop? (based on global clock, using actual start) if tThisFlipGlobal > mic_image.tStartRefresh + micDuration-frameTolerance: # keep track of stop time/frame for later mic_image.tStop = t # not accounting for scr refresh mic_image.frameNStop = frameN # exact frame index win.timeOnFlip(mic_image, 'tStopRefresh') # time at next scr refresh mic_image.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 repeatComponents: 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 "repeat"------- for thisComponent in repeatComponents: if hasattr(thisComponent, "setAutoDraw"): thisComponent.setAutoDraw(False) if trigger_mic_EEG.status == STARTED: trigger_mic_EEG.setData(int(0)) trials.addData('trigger_mic_EEG.started', trigger_mic_EEG.tStart) trials.addData('trigger_mic_EEG.stopped', trigger_mic_EEG.tStop) # mic_1 stop & responses mic_1.stop() # sometimes helpful if not mic_1.savedFile: mic_1.savedFile = None # store data for trials (TrialHandler) trials.addData('mic_1.filename', mic_1.savedFile) trials.addData('mic_1.started', mic_1.tStart) trials.addData('mic_1.stopped', mic_1.tStop) trials.addData('mic_image.started', mic_image.tStartRefresh) trials.addData('mic_image.stopped', mic_image.tStopRefresh) # the Routine "repeat" was not non-slip safe, so reset the non-slip timer routineTimer.reset() # ------Prepare to start Routine "end_block"------- continueRoutine = True # update component parameters for each repeat socket.annotation('190', 0) end.setSound('num/end_block.wav', hamming=True) end.setVolume(1, log=False) # keep track of which components have finished end_blockComponents = [trigger_endBlock_EEG, end, FixCross_end] for thisComponent in end_blockComponents: 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") end_blockClock.reset(-_timeToFirstFrame) # t0 is time of first possible flip frameN = -1 # -------Run Routine "end_block"------- while continueRoutine: # get current time t = end_blockClock.getTime() tThisFlip = win.getFutureFlipTime(clock=end_blockClock) tThisFlipGlobal = win.getFutureFlipTime(clock=None) frameN = frameN + 1 # number of completed frames (so 0 is the first frame) # update/draw components on each frame # *trigger_endBlock_EEG* updates if trigger_endBlock_EEG.status == NOT_STARTED and t >= 0.0-frameTolerance: # keep track of start time/frame for later trigger_endBlock_EEG.frameNStart = frameN # exact frame index trigger_endBlock_EEG.tStart = t # local t and not account for scr refresh trigger_endBlock_EEG.tStartRefresh = tThisFlipGlobal # on global time win.timeOnFlip(trigger_endBlock_EEG, 'tStartRefresh') # time at next scr refresh trigger_endBlock_EEG.status = STARTED trigger_endBlock_EEG.setData(int(190)) if trigger_endBlock_EEG.status == STARTED: # is it time to stop? (based on global clock, using actual start) if tThisFlipGlobal > trigger_endBlock_EEG.tStartRefresh + 0.02-frameTolerance: # keep track of stop time/frame for later trigger_endBlock_EEG.tStop = t # not accounting for scr refresh trigger_endBlock_EEG.frameNStop = frameN # exact frame index win.timeOnFlip(trigger_endBlock_EEG, 'tStopRefresh') # time at next scr refresh trigger_endBlock_EEG.status = FINISHED trigger_endBlock_EEG.setData(int(0)) # start/stop end if end.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance: # keep track of start time/frame for later end.frameNStart = frameN # exact frame index end.tStart = t # local t and not account for scr refresh end.tStartRefresh = tThisFlipGlobal # on global time end.play(when=win) # sync with win flip # *FixCross_end* updates if FixCross_end.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance: # keep track of start time/frame for later FixCross_end.frameNStart = frameN # exact frame index FixCross_end.tStart = t # local t and not account for scr refresh FixCross_end.tStartRefresh = tThisFlipGlobal # on global time win.timeOnFlip(FixCross_end, 'tStartRefresh') # time at next scr refresh FixCross_end.setAutoDraw(True) if FixCross_end.status == STARTED: # is it time to stop? (based on global clock, using actual start) if tThisFlipGlobal > FixCross_end.tStartRefresh + 5.0-frameTolerance: # keep track of stop time/frame for later FixCross_end.tStop = t # not accounting for scr refresh FixCross_end.frameNStop = frameN # exact frame index win.timeOnFlip(FixCross_end, 'tStopRefresh') # time at next scr refresh FixCross_end.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 end_blockComponents: 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_block"------- for thisComponent in end_blockComponents: if hasattr(thisComponent, "setAutoDraw"): thisComponent.setAutoDraw(False) if trigger_endBlock_EEG.status == STARTED: trigger_endBlock_EEG.setData(int(0)) trials.addData('trigger_endBlock_EEG.started', trigger_endBlock_EEG.tStart) trials.addData('trigger_endBlock_EEG.stopped', trigger_endBlock_EEG.tStop) end.stop() # ensure sound has stopped at end of routine trials.addData('end.started', end.tStartRefresh) trials.addData('end.stopped', end.tStopRefresh) trials.addData('FixCross_end.started', FixCross_end.tStartRefresh) trials.addData('FixCross_end.stopped', FixCross_end.tStopRefresh) # the Routine "end_block" was not non-slip safe, so reset the non-slip timer routineTimer.reset() thisExp.nextEntry() # completed 1 repeats of 'trials' # ------Prepare to start Routine "rest"------- continueRoutine = True # update component parameters for each repeat socket.annotation('100', 0) rest_instruction.setColor('white', colorSpace='rgb') rest_instruction.setText(rest_inst ) key_resp_2.keys = [] key_resp_2.rt = [] _key_resp_2_allKeys = [] if rest_cond == 1: print("COME IN") # keep track of which components have finished restComponents = [trigger_rest_EEG, rest_instruction, key_resp_2] for thisComponent in restComponents: 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") restClock.reset(-_timeToFirstFrame) # t0 is time of first possible flip frameN = -1 # -------Run Routine "rest"------- while continueRoutine: # get current time t = restClock.getTime() tThisFlip = win.getFutureFlipTime(clock=restClock) tThisFlipGlobal = win.getFutureFlipTime(clock=None) frameN = frameN + 1 # number of completed frames (so 0 is the first frame) # update/draw components on each frame # *trigger_rest_EEG* updates if trigger_rest_EEG.status == NOT_STARTED and t >= 0.0-frameTolerance: # keep track of start time/frame for later trigger_rest_EEG.frameNStart = frameN # exact frame index trigger_rest_EEG.tStart = t # local t and not account for scr refresh trigger_rest_EEG.tStartRefresh = tThisFlipGlobal # on global time win.timeOnFlip(trigger_rest_EEG, 'tStartRefresh') # time at next scr refresh trigger_rest_EEG.status = STARTED trigger_rest_EEG.setData(int(100)) if trigger_rest_EEG.status == STARTED: # is it time to stop? (based on global clock, using actual start) if tThisFlipGlobal > trigger_rest_EEG.tStartRefresh + 0.02-frameTolerance: # keep track of stop time/frame for later trigger_rest_EEG.tStop = t # not accounting for scr refresh trigger_rest_EEG.frameNStop = frameN # exact frame index win.timeOnFlip(trigger_rest_EEG, 'tStopRefresh') # time at next scr refresh trigger_rest_EEG.status = FINISHED trigger_rest_EEG.setData(int(0)) # *rest_instruction* updates if rest_instruction.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance: # keep track of start time/frame for later rest_instruction.frameNStart = frameN # exact frame index rest_instruction.tStart = t # local t and not account for scr refresh rest_instruction.tStartRefresh = tThisFlipGlobal # on global time win.timeOnFlip(rest_instruction, 'tStartRefresh') # time at next scr refresh rest_instruction.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=['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 restComponents: 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 "rest"------- for thisComponent in restComponents: if hasattr(thisComponent, "setAutoDraw"): thisComponent.setAutoDraw(False) if trigger_rest_EEG.status == STARTED: trigger_rest_EEG.setData(int(0)) trialSet_9.addData('trigger_rest_EEG.started', trigger_rest_EEG.tStart) trialSet_9.addData('trigger_rest_EEG.stopped', trigger_rest_EEG.tStop) trialSet_9.addData('rest_instruction.started', rest_instruction.tStartRefresh) trialSet_9.addData('rest_instruction.stopped', rest_instruction.tStopRefresh) # check responses if key_resp_2.keys in ['', [], None]: # No response was made key_resp_2.keys = None trialSet_9.addData('key_resp_2.keys',key_resp_2.keys) if key_resp_2.keys != None: # we had a response trialSet_9.addData('key_resp_2.rt', key_resp_2.rt) trialSet_9.addData('key_resp_2.started', key_resp_2.tStartRefresh) trialSet_9.addData('key_resp_2.stopped', key_resp_2.tStopRefresh) # the Routine "rest" was not non-slip safe, so reset the non-slip timer routineTimer.reset() thisExp.nextEntry() # completed 1 repeats of 'trialSet_9' thisExp.addData("globalClockTime", globalClock.getTime()) thisExp.nextEntry() socket.stop_recording() print('Script completed.') # 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()