def runRT(window,ask,test,language,preferred_hand,exp): try: while True: ask(lookup[test][language][preferred_hand]) response = ask(practiceLookup[language]) if event.getKeys(keyList=['escape', 'q']): core.quit() if 'r' in response: print 'r pressed' continue if 'space' in response: break if event.getKeys(keyList=['s']): print "Skipped experiment" return getReady = lookupGetReady[language] error = lookupError[language] wrongkey = lookupwrongKey[language] score=1 while score != 0: score = run(window,clock, ask, error,getReady,wrongkey,language, exp,practice=True) print score #Run experiment run(window,clock, ask, error,getReady,wrongkey,language,exp) except KeyboardInterrupt: raise core.quit()
def wait_check_pause_quit(win, wait_time, quit_keys=["q", "escape"], pause_keys=["space"], check_every=1): """Wait while checking for pause or quit input.""" raise NotImplementedError("This isn't quite finished yet") checks = int(floor(wait_time / check_every)) for _ in range(checks): core.wait(check_every) if event.getKeys(keyList=quit_keys): print "Subject quit execution" core.quit() if event.getKeys(keyList=pause_keys): pause_start = time.time() visual.TextStim(win, text="Experiment paused").draw() win.flip() paused = True while paused: if event.getKeys(keyList=pause_keys): paused = False core.sleep(check_every) pause_end = time.time() pause_duration = pause_end - pause_start remaining = wait_time - checks * check_every if remaining: core.wait(remaining) return pause_duration
def get_rating(input_method, resp_device, timeStamped,trig_collector,win): #if participants don't respond we will set up a null value so we don't get an error thisResp = None thisRT = np.nan if input_method == 'keyboard': for key, RT in event.getKeys(keyList = ['escape', 'q', '1', '2', '3', '4'], timeStamped = timeStamped): if key in ['escape','q']: print 'User Cancelled' if trig_collector: trig_collector.endCollection() quitEXP(True) else: thisResp = key thisRT = timeStamped.getTime() else: thisResp = resp_device.read(1) thisRT = timeStamped.getTime() if len(thisResp) == 0: thisResp = None thisRT = np.nan else: pass # Quickly check for a 'escape' response on the keyboard to quit for key, RT in event.getKeys(keyList = ['escape'], timeStamped = timeStamped): if key in ['escape']: print 'User cancelled' trials.saveAsText(datalog_fn + '_data.csv') if trig_collector: trig_collector.endCollection() quitEXP(True) return thisResp, thisRT
def showUntilKeyPressed(self, text, keyList=[]): """ Show text until a key is pressed. If keyList is empty, it will listen for all keys. """ self._display(text) instructionClock = core.Clock() instructionClock.reset() keyPressed = False eventCheckStarted = False while not keyPressed: t = instructionClock.getTime() if t >= 0.5: # Do not check for events immediatelly, such that people do not accidentally # skip the message. if eventCheckStarted == False: # Remove keyboard events that were sent before the "grace" period had elapsed event.clearEvents(eventType='keyboard') eventCheckStarted = True # Check for keys if keyList == []: theseKeys = event.getKeys() else: theseKeys = event.getKeys(keyList=keyList) if len(theseKeys) > 0: # A key was pressed, return it return theseKeys[0]
def WaitForKeyInput(): text='...' #until return pressed, listen for letter keys & add to text string while event.getKeys(keyList=['return'])==[]: letterlist=event.getKeys(keyList=['0', '1', '2', '3', '4', '5' , '6', '7', '8', '9','backspace','q']) for l in letterlist: if l == 'q': core.quit() #if key isn't backspace, add key pressed to the string if l !='backspace': if text =="...": text=l pressedkeys=l else: text+=l pressedkeys+=(";" + l) #otherwise, take the last letter off the string elif len(text)>0: text=text[:-1] pressedkeys+=(";backspace") #continually redraw text onscreen until return pressed text = unicode(text) print "UNICODE" print text response = visual.TextStim(mywin, height=36,text=text,color="white",pos=(0,-100)) betAsk.draw() response.draw() mywin.flip() core.wait(0.1) RT = trialClock.getTime() event.clearEvents() return text,RT
def show_probe(): stats={'type':'probe'} # clear keybuffer event.getKeys() # set probe to either on- or off-task probe.init_random() fclock.reset() for i in range(fprobe): probe.draw() win.flip() keys=event.getKeys() if key1 in keys: probe.arrow_move(int(key1)) elif key2 in keys: probe.arrow_move(int(key2)) elif key3 in keys: probe.arrow_move(int(key3)) elif key4 in keys: probe.arrow_move(int(key4)) stats['time_probe']=fclock.getTime() stats['response']=probe.current_pos+1 return stats
def show_trial(num): stats={'type':'go' if num!=3 else 'stop', 'number':num, 'nresponses':0} fclock.reset() num=int(num) number.setText("%i"%num) fclock.reset() for i in range(fnumber): number.draw() win.flip() keys=event.getKeys() if set(valid_keys) & set(keys): #intersection on sets if stats['nresponses']==0: stats['response']=1 stats['RT']=fclock.getTime() stats['nresponses']+=1 stats['time_number']=fclock.getTime() fclock.reset() for i in range(fblank): win.flip() keys=event.getKeys() if set(valid_keys) & set(keys): if stats['nresponses']==0: stats['response']=1 stats['RT']=fclock.getTime()+stats['time_number'] stats['nresponses']+=1 stats['time_blank']=fclock.getTime() return stats
def textInput(): #until return pressed, listen for letter keys & add to text string text = '' while event.getKeys(keyList=['escape'])==[]: letterlist=event.getKeys() letterDict = {'space': ' '} # letterlist=event.getKeys(keyList=['0','1','2','3','4','5','6','7','8','9','backspace']) for l in letterlist: if l == 'space': text += ' ' elif l == 'return': text += '\n' #if key isn't backspace, add key pressed to the string elif l != 'backspace': text += l #otherwise, take the last letter off the string elif len(text)>0: text = text[:-1] #continually redraw text onscreen until return pressed textObject = visual.TextStim(win=win, ori=0, name='pause', text=text, font=u'Arial', pos=[0, 0], height=1.0, wrapWidth=None, color=u'white', colorSpace=u'rgb', opacity=1, depth=-1.0) # textReport.draw() textObject.draw() win.flip() text = str(text) event.clearEvents() print text return text
def waitForKeypress(): allKeys = event.getKeys() while len(allKeys)==0: allKeys = event.getKeys() if 'escape' in allKeys[0]: mywin.close() # quit core.quit()
def ask(text='', keyList=[]): """ Ask subject something. Shows question and returns answer (keypress) and reaction time. Defaults to no text and all keys. """ # Draw the TextStims to visual buffer, then show it and reset timing immediately (at stimulus onset) stimText.setText(codecs.decode(text,"utf-8")) spaceText.setText(codecs.decode(spaceLookup[language],"utf-8")) # Set the text height stimText.setHeight(1) spaceText.setHeight(1) # set the text color stimText.setColor('white') spaceText.setColor('white') stimText.draw() spaceText.draw() win.flip() event.clearEvents('keyboard') # Halt everything and wait for (first) responses matching the keys given in the Q object. response = event.waitKeys(keyList=['space','q','r']) if response[0] in keysQuit: # Look at first reponse [0]. Quit everything if quit-key was pressed core.quit() if response[0] in keysBreak: event.clearEvents('keyboard') win.flip() if event.getKeys(keyList=['escape', 'q']): core.quit() if event.getKeys(keyList=['s']): print "Skipped experiment" quit() return response # When answer given, return it.
def doUserInteraction(stim, expectedKeys, timeout, soundFile): global paused if timeout == None or timeout == 0: timeout = sys.maxint startTime = trialClock.getTime() endTime = startTime + timeout response = { "keys": [], "firstKey": None, "lastKey": None, "startTime": startTime, "endTime": endTime, "duration": 0, "timedOut": False, } if soundFile != None: soundFile.play() while(True): stim.setAutoDraw(True) #continuously draws the stimulus to the buffer win.flip() # exposes the stimulus to the screen keys = [] # initializes an empty array to hold the keys that were pressed. # this IF checks 2 things in order to determine which keys are allowed to be pressed: if expectedKeys != None: # Have I specified a list of allowed keys? if len(expectedKeys) != 0: # Have I specified any particular keys (rather than just [] which means All keys? keys = event.getKeys(expectedKeys) # Listen for key presses from a particular subset else: keys = event.getKeys() # Listen for Any key presses. if len(keys) > 0: # If a key was pressed store some values in the object "response" defined above. response["keys"] = keys # put all the responses in here. response["firstKey"] = keys[0] # put the first keypress here response["lastKey"] = keys[len(keys)-1] # put the last keypress here. break #break out of this function elif trialClock.getTime() > endTime: # If the response time window has run out response["timedOut"] = True # indicate that we timed out response["firstKey"] = 'NA' # put 'NA' as the first key pressed break if event.getKeys(['f5']): # This is a "pause" button for the experiment textStim.text = 'Press any key to continue' textStim.pos = (0,-10) paused = 1 stimUntilAnyKey(textStim) textStim.pos = (0,0) #check for quit (the [Esc] key) if event.getKeys(["escape"]): core.quit() #quits the entire experiment - will dump you to the desktop or whatever. stim.setAutoDraw(False) # stop drawing the stimulus to the buffer win.flip() # expose the now blank buffer to the screen response["duration"] = trialClock.getTime() - startTime # keeps track of how long since the stim was drawn to the screen event.clearEvents(eventType=None) # clear the key buffer. return response # ends the function and returns the object "response". Without this return - we would not be able to access any of this data.
def show_instr(instructionText): instruction = visual.TextStim(mywin, text=instructionText,color=(1,1,1),height = 25) instruction.draw() mywin.flip() # wait for key-press allKeys = event.getKeys() while len(allKeys)==0: allKeys = event.getKeys()
def do_break(): breaktext = visual.TextStim(mywin, text="Break\n\nPress <space> to continue...",color=(1,1,1),height = 50) breaktext.draw() mywin.flip() # wait for key-press allKeys = event.getKeys() while len(allKeys)==0: allKeys = event.getKeys()
def Letters3Back(win, ask, language, letters): event.clearEvents() win.setRecordFrameIntervals(True) mouse = event.Mouse(visible=False) list =[random.randint(0,10) for r in xrange(numTrials)] #list = [2,3,2,3,2,3,2,3,4,5,6,7,8,9,8] keyList=[] responses = ['none'] * len(letters) demoDisp = visual.TextStim(win, text = letters[0], height = 4, pos=(0.0, 0.0)) #textstim object that will be displayed counter = 0 # Counter is unused? for x in range(len(letters)): # PREPARE STIMULUS demoDisp.setText(letters[x]) # PRESENT STIMULUS for frameN in range(stimFrames): # Display stimulus demoDisp.draw() win.flip() RT.reset() # Reset timer on onset if frameN == 0: RT.reset() if event.getKeys(['q','escape']): core.quit() # RECORD RESPONSES keyList=event.getKeys(timeStamped=RT) if keyList: # keyList[N][Y], N is response number if multiple keys were pressed. Y=0 is key-name. Y=1 is time if 'space' in keyList[0][0]: #Play sound when key pressed #filesound = sound.Sound(audioPath) #filesound.setVolume(1.0) #filesound.play() #Save responses responses[x]= keyList[0][0] print responses elif keyList == 'q': core.quit() else: #responses.append('none') #No key was pressed continue #if not keyList: # responses.append('none') # PRESENT BLANK for frameN in range(blankFrames): # Blank screen with no response recording RT.reset() win.flip() if event.getKeys(['q']): core.quit() print 'Letters 3-Back task finished...' return responses
def show(win, to_show = [], mouse_btns = [0,1,2], exit_keys = None, buttons = [], delay = 100000, clickReset = True): if mouse_btns == None: mouse_btns = [0,1,2] use_mouse = False use_keybd = True # this is always true to capture the ESC key if len(mouse_btns): use_mouse = True mouse = event.Mouse(win=win) rects = [ button.rect() for r in buttons ] if len(rects): mouse.setVisible(True) rt,b,k,re = -1,None,None,None event.clearEvents() if use_keybd: event.getKeys() if use_mouse: mouse_release(mouse) clock_show=core.Clock() if use_mouse and clickReset: mouse.clickReset() t=0; clock_show.reset() while True: rt = t= clock_show.getTime() if t >= delay: break if (0.0 <= t): for t in to_show: t.draw() for b in buttons: b.draw() if use_mouse: rt, bt, re, ts = mouse_pressed(mouse, mouse_btns, rects = rects) if len(bt) and (len(rects) == 0 or len(re)): break if use_keybd: rt, k = key_pressed(clock_show, exit_keys) if len(k): break win.flip() if use_mouse and len(rects): mouse.setVisible(False) return rt,b,k,re
def draw_fixation(color): while 'space' not in event.getKeys(): [s.setFillColor(color) for s in fixations] [s.draw() for s in fixations] win.flip() if event.getKeys(["escape"]): core.quit() event.clearEvents() win.flip() core.wait(0.5)
def waitBeforeTrial(nDone,respDeadline,expStop,stuffToDrawOnRespScreen): #displayDraw is a function instance to call to draw what want to between trials if dirOrLocalize: betweenTrialsText.setText('CLICK in blue area to continue') clickContinueArea.draw() else: betweenTrialsText.setText('Press SPACE to continue') progressMsg = 'Completed ' + str(nDone) + ' of ' + str(trials.nTotal) + ' trials' nextRemindCountText.setText(progressMsg) event.clearEvents() #clear keypresses and mouse clicks myClock.reset(); if dirOrLocalize: betweenTrialsText.setText('CLICK in blue area to continue') waitingForClick = True while waitingForClick and respClock.getTime() < respDeadline: m_x, m_y = myMouse.getPos() # in the same units as the Window mouseLocationMarker.setPos((m_x, m_y)) #Because mouseLocationMarker is in same units as windowAndMouseUnits, and mouse returns windowAndMouseUnits, this has to work mouse1, mouse2, mouse3 = myMouse.getPressed() if myMouse.isPressedIn(clickContinueArea): waitingForClick = False event.clearEvents() if waitingForClick and (mouse1 or mouse2 or mouse3): myWin.flip(); myWin.flip() #flicker everything to tell user registered your click but it's in wrong place keysPressed = event.getKeys() if 'escape' in keysPressed: expStop = True for x in stuffToDrawOnRespScreen: x.draw() betweenTrialsText.setText('CLICK in blue area to continue') if nDone==0: beforeFirstTrialText.draw() clickContinueArea.draw() mouseLocationMarker.draw() betweenTrialsText.draw() nextRemindCountText.draw() myWin.flip() if not expStop and not waitingForClick: #person never responded, but timed out. Presumably because of autopilot or hit escape waitingForPressBetweenTrials = True betweenTrialsText.setText('While looking at the green dot, press SPACE to continue') while waitingForPressBetweenTrials and myClock.getTime() < respDeadline: if nDone==0: beforeFirstTrialText.draw() respPromptText.draw() betweenTrialsText.draw() for x in stuffToDrawOnRespScreen: x.draw() myWin.flip() for key in event.getKeys(): #check if pressed abort-type key if key in ['escape']: expStop = True; waitingForPressBetweenTrials=False if key in ['space']: waitingForPressBetweenTrials=False return expStop
def show_instruction(screen): """screen is a list of strings that is displayed on one screen""" event.getKeys() # clear buffer r=None if not debug: for i,inst in enumerate(screen): ypos=1-(pad+(i+1)*(2.0-2*pad)/len(screen)) msg=visual.TextStim(win, pos=[0,ypos],text=unicode(inst,"utf-8"), units='norm', height=0.075, #size=(2.0,1.0), alignHoriz='center', alignVert='center', color=stimcolor ,wrapWidth=1.8) msg.draw() win.flip() r=event.waitKeys()[0] return r
def waitForExitPress(time = 0): logging.debug("Waiting for exit key to be pressed") if time == 0: while True: if event.getKeys(["escape"]): logging.debug("User pressed escape") exit() else: waitTimer = core.CountdownTimer(time) while (waitTimer.getTime() > 0): if event.getKeys(["escape"]): logging.debug("User pressed escape") exit()
def draw_fixation(color): """args: color should be a string """ print_message("Color", color) print("Press 'space' to continue") while 'space' not in event.getKeys(): [s.setFillColor(COLOR[color]) for s in fixations] [s.draw() for s in fixations] win.flip() if event.getKeys(["escape"]): core.quit() event.clearEvents() win.flip() core.wait(0.5)
def show_trial(self, trial, feedback=False): # get model and relation model, sequence, relation = self.get_model(trial) # get questions questions = self.get_questions(model, relation, trial) self.filldf(trial, model, sequence, relation, questions) # pre-trial fixation pre_trial_time = self.get_time('pre_trial') self.show_element('fix', pre_trial_time) # show premises if self.send_triggers: for el in ['letter', 'relation']: self.triggers[el] = self.settings['triggers'][el] premise_times = self.show_premises(model, sequence, relation) # change triggers for questions if self.send_triggers: add = self.settings['triggers']['question_add'] for el in ['letter', 'relation']: self.triggers[el] = self.settings['triggers'][el] + add # show questions for q_num, q in enumerate(questions): # clear keyboard buffer event.getKeys() time_and_resp = self.ask_question(q) if feedback: # calculate dataframe row row = (trial - 1) * 3 + q_num # get and check response try: response = time_and_resp[1][0] # check time_and_resp[1] - sometimes None or nan except: response = None if response is not None: response = self.df.loc[row, 'iftrue'] == self.\ resp_mapping[response] else: response = False # choose relevant circle and show circ = 'feedback_' + ['in',''][int(response)] + 'correct' self.show_element(circ, 25) core.wait(0.25) self.window.flip() self.save_responses(trial, q_num, time_and_resp) finish_time = self.get_time('after_trial') self.show_element('btw_pairs', finish_time)
def check_keys(self): """Checks key input""" for keys in event.getKeys(timeStamped=True): k = keys[0] if k in ["escape", "q"]: self.window.close() sys.exit() elif k in ["space"]: for c in range(1, 2): t = Circle(self.window, radius=c) self.stims.append(t) # for c in range (1,2): # t = RadialStim(self.window) # self.stims.append(t) # handle projections elif k in ["s"]: self.warper.changeProjection("spherical", None, (0.5, 0.5)) elif k in ["c"]: self.warper.changeProjection("cylindrical", None, (0.5, 0.5)) elif k in ["n"]: self.warper.changeProjection(None, None, (0.5, 0.5)) elif k in ["f"]: self.warper.changeProjection( "warpfile", # r'C:\WinPython-64bit-2.7.5.3\python-2.7.5.amd64\Lib\site-packages\aibs\Projector\Calibration\standard_4x3.data', r"C:\Users\jayb\Documents\Stash\aibs\Projector\Calibration\InteriorProject24inDome6inMirrorCenter.meshwarp.data", # r'C:\WinPython-64bit-2.7.5.3\python-2.7.5.amd64\Lib\site-packages\aibs\Projector\Calibration\standard_16x9.data', (0.5, 0.5), ) # flip horizontal and vertical elif k in ["h"]: self.warper.changeProjection( self.warper.warp, self.warper.warpfile, flipHorizontal=not self.warper.flipHorizontal ) elif k in ["v"]: self.warper.changeProjection( self.warper.warp, self.warper.warpile, flipVertical=not self.warper.flipVertical ) # move eyepoint elif k in ["down"]: if self.warper.dist_cm > 1: self.warper.dist_cm -= 1 self.warper.changeProjection(self.warper.warp, None, self.warper.eyepoint) elif k in ["up"]: if self.warper.dist_cm < 200: self.warper.dist_cm += 1 self.warper.changeProjection(self.warper.warp, None, self.warper.eyepoint) elif k in ["right"]: if self.warper.eyepoint[0] < 0.9: self.warper.eyepoint = (self.warper.eyepoint[0] + 0.1, self.warper.eyepoint[1]) self.warper.changeProjection(self.warper.warp, None, self.warper.eyepoint) elif k in ["left"]: if self.warper.eyepoint[0] > 0.1: self.warper.eyepoint = (self.warper.eyepoint[0] - 0.1, self.warper.eyepoint[1]) self.warper.changeProjection(self.warper.warp, None, self.warper.eyepoint) self.updateInfo()
def experiment(): list =[random.randint(0,10) for r in xrange(numTrials)] #list = [2,3,2,3,2,3,2,3,4,5,6,7,8,9,8] keyList=[] demoDisp = visual.TextStim(win, text = '', height = 100) #textstim object that will be displayed counter = 0 # Counter is unused? for x in list: # PREPARE STIMULUS demoDisp.setText(x) # PRESENT STIMULUS for frameN in range(stimFrames): # Display stimulus demoDisp.draw() win.flip() # Reset timer on onset if frameN == 0: RT.reset() # PRESENT BLANK for frameN in range(blankFrames): # Blank screen with no response recording win.flip() # RECORD RESPONSES keyList = event.getKeys(timeStamped=RT) # keyList[N][Y], N is response number if multiple keys were pressed. Y=0 is key-name. Y=1 is time if keyList: print keyList[0][0], 'key was pressed after', str(keyList[0][1]), 'seconds' else: print 'no key was pressed'
def waitEvents(self, downOnly=True, timeout=0, escape='escape', wait=0.002): '''Wait for and return the first button press event. Always calls `clearEvents()` first (like PsychoPy keyboard waitKeys). Use `downOnly=False` to include button-release events. `escape` is a list/tuple of keyboard events that, if pressed, will interrupt the bbox wait; `waitKeys` will return `None` in that case. `timeout` is the max time to wait in seconds before returning `None`. `timeout` of 0 means no time-out (= default). ''' self.clearEvents() # e.g., removes UP from previous DOWN if timeout > 0: c = core.Clock() if escape and not type(escape) in [list, tuple]: escape = [escape] while True: if wait: core.wait(wait, 0) # throttle CPU; event RTs come from bbox evt = self.getEvents(downOnly=downOnly) if evt: evt = evt[0] break if escape and event.getKeys(escape) or 0 < timeout < c.getTime(): return return evt
def wait_get_response(p, clock, oddball, wait_time): """Get response info specific to this experiment.""" check_clock = core.Clock() good_resp = False corr, response, resp_rt = 0, 0, -1 while not good_resp: keys = event.getKeys(timeStamped=clock) for key, stamp in keys: if key in p.quit_keys: print "Subject quit execution" core.quit() elif key in p.match_keys: corr = 0 if oddball else 1 response = 1 resp_rt = stamp good_resp = True break elif key in p.nonmatch_keys: corr = 1 if oddball else 0 response = 2 resp_rt = stamp good_resp = True break event.clearEvents() # Possibly exit with nothing if check_clock.getTime() >= wait_time: return corr, response, resp_rt # Wait the rest of the time core.wait(wait_time - resp_rt) return corr, response, resp_rt
def arrow_exp(win, randid ,hand='r'): if hand == 'l': keylist = LH_ARROWS_KEYLIST else: keylist = RH_ARROWS_KEYLIST #Create our stimuli arrow = visual.ImageStim(win=win, image=arrow_image_path, pos=ST_arrow_pos) stim_times = [] for i in range(int(SA_repetition_times)): #Escribimos el circulo arrow.size*= -1 #(hack ;) ) arrow.draw() #Enviamos la pantalla con el circulo win.flip() #Tomamos el tiempo en el que fue enviado stim_times.append(core.getTime()) #Lo mostramos por "SA_duration_time" segundos core.wait(SA_duration_time) #Mandamos pantalla en blanco win.flip() #Mostramos pantalla en blanco por "SA_interval_time" segundos. core.wait(SA_interval_time) #Vemos cuando fueron apretadas las teclas user_times = event.getKeys(keyList=keylist, timeStamped = True) return stim_times, user_times
def present_fb(self, win, score, objects): """Display the feeback for the game. Requires the window, the score, and a list of the objects already on the screen to be presented with the feedback.""" #determine feedback picture and audio based on score if score: fb = self.green_check sound = self.ding else: fb = self.red_x sound = self.honk #check if objects is a list if type(objects)!=list: print 'objects passed to feedback must be a list; instead got {}'.format(type(objects)) core.quit() #display objects and feedback for object in objects: object.draw() fb.draw() win.flip() sound.play() #wait 2 seconds start_time=self.trialClock.getTime() timer=0 while timer<1: timer= self.trialClock.getTime() - start_time these_keys=event.getKeys(keyList=['escape']) if 'escape' in these_keys: core.quit()
def get_key(self, keylist=None, timeout=None): """See openexp._keyboard.legacy""" if keylist == None: keylist = self._keylist if timeout == None: timeout = self.timeout if keylist == None: _keylist = None else: _keylist = keylist + ["escape"] start_time = 1000.0 * self.experiment.clock.getTime() time = start_time while timeout == None or time-start_time <= timeout: time = 1000.0 * self.experiment.clock.getTime() keys = event.getKeys(_keylist, timeStamped=self.experiment.clock) for key, time in keys: time *= 1000.0 if key == "escape": raise openexp.exceptions.response_error( \ "The escape key was pressed.") elif keylist == None or key in keylist: return key, time return 'timeout', time
def get_keyboard(myClock,win, respkeylist): keyResp = None thisRT = np.nan from string import letters, punctuation, digits # allow number pad keys if there's numbers for k in respkeylist: if k in digits: num_k = ['num_' + k] respkeylist += num_k keylist = ['escape'] + respkeylist for key, RT in event.getKeys(keyList=keylist, timeStamped=myClock): if key in ['escape']: quitEXP(True) else: if key in ['num_1', 'num_2', 'num_3', 'num_4', 'num_5', 'num_6', 'num_7', 'num_8', 'num_9', 'num_0']: # allow number pad keys key = key.translate(None, letters) # no letters key = key.translate(None, punctuation) #no underscore else: pass keyResp = key thisRT = RT return keyResp, thisRT
def tapping_exp(win, randid ,hand='r'): if hand == 'l': keylist = LH_TAPPING_KEYLIST else: keylist = RH_TAPPING_KEYLIST #create some stimuli circle = visual.ImageStim(win=win, image=circle_image_path, pos=SA_circle_pos) #draw the stimuli and update the window stim_times = [] for i in range(int(ST_repetition_times)): #Escribimos el circulo circle.draw() #Enviamos la pantalla con el circulo win.flip() #Tomamos el tiempo en el que fue enviado stim_times.append(core.getTime()) #Lo mostramos por "ST_duration_time" segundos core.wait(ST_duration_time) #Mandamos pantalla en blanco win.flip() #Mostramos pantalla en blanco por "ST_interval_time" segundos. core.wait(ST_interval_time) #Vemos cuando fueron apretadas las teclas user_times = event.getKeys(keyList=keylist, timeStamped = True) return stim_times, user_times
def ringScan(scanDict, screenSize=[1024, 768], direction=1.0): #do ring scanLength = float(scanDict['numCycles'] * scanDict['period'] + scanDict['preScanRest']) if scanDict['operatorScreen'] == scanDict['subjectScreen']: screenCount = 1 else: screenCount = 2 thisPlatform = scanDict['platform'] #if there is only one window, need to display the winOp stuff and then clear it screenSize = scanDict['screenSize'] if screenCount == 1: #pop up the Tr info and wait for "ok" winOp = visual.Window([500, 500], monitor='testMonitor', units='norm', screen=scanDict['operatorScreen'], color=[0.0, 0.0, 0.0], colorSpace='rgb') msgScanLength = visual.TextStim(winOp, pos=[0, 0.5], units='norm', height=0.1, text='Scan length (s): %.1f' % scanLength) msgScanTr = visual.TextStim( winOp, pos=[0, 0], units='norm', height=0.1, text='No. of Volumes (at Tr=%.2f): %.1f' % (scanDict['Tr'], scanLength / scanDict['Tr'])) msgOK = visual.TextStim(winOp, pos=[0, -0.5], units='norm', height=0.1, text='Operator, press any key to proceed') msgScanLength.draw() msgScanTr.draw() msgOK.draw() winOp.flip() #wait for keypress thisKey = None while thisKey == None: thisKey = event.waitKeys() if thisKey in ['q', 'escape']: core.quit() #abort else: event.clearEvents() #close the winOp winOp.close() else: winOp = visual.Window([500, 500], monitor='testMonitor', units='norm', screen=scanDict['operatorScreen'], color=[0.0, 0.0, 0.0], colorSpace='rgb') msgScanLength = visual.TextStim(winOp, pos=[0, 0.5], units='norm', height=0.1, text='Scan length (s): %.1f' % scanLength) msgScanTr = visual.TextStim( winOp, pos=[0, 0], units='norm', height=0.1, text='No. of Volumes (at Tr=%.2f): %.1f' % (scanDict['Tr'], scanLength / scanDict['Tr'])) msgScanLength.draw() msgScanTr.draw() winOp.flip() #open subject window winSub = visual.Window(screenSize, monitor=scanDict['monCalFile'], units='deg', screen=scanDict['subjectScreen'], color=[0.0, 0.0, 0.0], colorSpace='rgb', fullscr=False, allowGUI=False) #parse out vars from scanDict IR = scanDict['innerRadius'] OR = scanDict['outerRadius'] #get actual size of window--useful in the functions subWinSize = winSub.size screenSize = numpy.array([subWinSize[0], subWinSize[1]]) fixPercentage = scanDict['fixFraction'] dutyCycle = scanDict['dutyCycle'] fixDuration = 0.2 respDuration = 1.0 dummyLength = int(numpy.ceil(scanLength * 60 / 100)) subjectResponse = numpy.zeros((dummyLength, 1)) subjectResponse[:] = numpy.nan white = [1.0, 1.0, 1.0] gray = [0.0, 0.0, 0.0] black = [-1.0, -1.0, -1.0] gridgray = [0.25, 0.25, 0.25] numRadialCycles = 0.75 / 1.2 numAngularCycles = 4.0 wedgeEdges = numpy.linspace(0.0, 360.0, 9) ringOri = 0.0 #figure out the ring sizes #start with a fixed width ring, given by the duty cycle. #this is a percentage of the total size maxWidth = (OR - IR) * dutyCycle / 100.0 width = maxWidth #print "maxWidth" ,maxWidth #assign starting IR and OR for the actual ring ringIR = IR ringOR = ringIR + maxWidth #set the amplitude of the ring for the sawtooth function ringAmp = OR - IR - maxWidth #print 'ringAmp', ringAmp #print 'OR', OR #print 'IR', IR quitKeys = ['q', 'escape'] radialUnits = 2.0 debugVar = numpy.zeros((int(scanLength * 60), 9)) ringRate = (OR - (IR + width)) / scanDict['period'] contrast = scanDict['contrast'] # ringRadPhi=numpy.zeros((8,1)) # ringRadPhiInit=numpy.zeros((8,1)) ringRadPhiInit = numpy.random.rand(8) ringRadPhi = ringRadPhiInit # for iP in range(8): # ringRadPhiInit[iP]=numpy.random.random()*2.0*math.pi startOR = OR - scanDict['preScanRest'] * ringRate #needs to be direction based? ring1 = visual.RadialStim(winSub, pos=[0, 0], tex='sqrXsqr', radialCycles=numRadialCycles * OR * radialUnits, angularCycles=numAngularCycles, angularPhase=0, size=startOR * radialUnits, color=1, visibleWedge=(wedgeEdges[0], wedgeEdges[8]), radialPhase=ringRadPhiInit[0], contrast=contrast, interpolate=False, autoLog=False) ring2 = visual.RadialStim(winSub, pos=[0, 0], tex='sqrXsqr', radialCycles=numRadialCycles * OR * radialUnits, angularCycles=numAngularCycles, angularPhase=0, size=startOR * radialUnits, color=1, visibleWedge=(wedgeEdges[1], wedgeEdges[8]), radialPhase=ringRadPhiInit[1], contrast=contrast, interpolate=False, autoLog=False) ring3 = visual.RadialStim(winSub, pos=[0, 0], tex='sqrXsqr', radialCycles=numRadialCycles * OR * radialUnits, angularCycles=numAngularCycles, angularPhase=0, size=startOR * radialUnits, color=1, visibleWedge=(wedgeEdges[2], wedgeEdges[8]), radialPhase=ringRadPhiInit[2], contrast=contrast, interpolate=False, autoLog=False) ring4 = visual.RadialStim(winSub, pos=[0, 0], tex='sqrXsqr', radialCycles=numRadialCycles * OR * radialUnits, angularCycles=numAngularCycles, angularPhase=0, size=startOR * radialUnits, color=1, visibleWedge=(wedgeEdges[3], wedgeEdges[8]), radialPhase=ringRadPhiInit[3], contrast=contrast, interpolate=False, autoLog=False) ring5 = visual.RadialStim(winSub, pos=[0, 0], tex='sqrXsqr', radialCycles=numRadialCycles * OR * radialUnits, angularCycles=numAngularCycles, angularPhase=0, size=startOR * radialUnits, color=1, visibleWedge=(wedgeEdges[4], wedgeEdges[8]), radialPhase=ringRadPhiInit[4], contrast=contrast, interpolate=False, autoLog=False) ring6 = visual.RadialStim(winSub, pos=[0, 0], tex='sqrXsqr', radialCycles=numRadialCycles * OR * radialUnits, angularCycles=numAngularCycles, angularPhase=0, size=startOR * radialUnits, color=1, visibleWedge=(wedgeEdges[5], wedgeEdges[8]), radialPhase=ringRadPhiInit[5], contrast=contrast, interpolate=False, autoLog=False) ring7 = visual.RadialStim(winSub, pos=[0, 0], tex='sqrXsqr', radialCycles=numRadialCycles * OR * radialUnits, angularCycles=numAngularCycles, angularPhase=0, size=startOR * radialUnits, color=1, visibleWedge=(wedgeEdges[6], wedgeEdges[8]), radialPhase=ringRadPhiInit[6], contrast=contrast, interpolate=False, autoLog=False) ring8 = visual.RadialStim(winSub, pos=[0, 0], tex='sqrXsqr', radialCycles=numRadialCycles * OR * radialUnits, angularCycles=numAngularCycles, angularPhase=0, size=startOR * radialUnits, color=1, visibleWedge=(wedgeEdges[7], wedgeEdges[8]), radialPhase=ringRadPhiInit[7], contrast=contrast, interpolate=False, autoLog=False) #create a gray circle to mask the inside of the radialStim ringMask = visual.Circle(winSub, radius=startOR - width, edges=32, lineColor=gray, lineColorSpace='rgb', fillColor=gray, fillColorSpace='rgb', autoLog=False, units='deg', opacity=1.0) #try a new mask mask = numpy.zeros((int(OR * 100), 1)) ringRadPhiDelta = ringRadPhiInit #driftFreq = 0.2 #Hz after L&H driftFreq = scanDict['animFreq'] driftReverseFreq = 1.0 #Hz fix0 = visual.Circle(winSub, radius=IR / 2.0, edges=32, lineColor=gray, lineColorSpace='rgb', fillColor=gray, fillColorSpace='rgb', autoLog=False, units='deg') fix1 = visual.ShapeStim(winSub, pos=[0.0, 0.0], vertices=((0.0, -0.15), (0.0, 0.15)), lineWidth=3.0, lineColor=black, lineColorSpace='rgb', fillColor=black, fillColorSpace='rgb', autoLog=False, units='deg') fix2 = visual.ShapeStim(winSub, pos=[0.0, 0.0], vertices=((-0.15, 0), (0.15, 0.0)), lineWidth=3.0, lineColor=black, lineColorSpace='rgb', autoLog=False, units='deg') #add to the fixation with a faint background polar grid gridRadii = numpy.zeros((8, 1)) gridRadii[0] = IR gridRadii[1] = 2 * IR gridRadii[2] = 4 * IR gridRadii[3] = 6 * IR gridRadii[4] = 8 * IR gridRadii[5] = 16 * IR gridRadii[6] = 32 * IR gridRadii[7] = OR gridCircle = visual.Circle(winSub, radius=gridRadii[0], edges=128, lineColor=gridgray, lineColorSpace='rgb', autoLog=False) gridEnds = numpy.zeros((8, 2)) gridEnds[0, 0] = 0 gridEnds[0, 1] = OR gridEnds[1, 0] = OR gridEnds[1, 1] = OR gridEnds[2, 0] = OR gridEnds[2, 1] = 0 gridEnds[3, 0] = OR gridEnds[3, 1] = -OR gridEnds[4, 0] = 0 gridEnds[4, 1] = -OR gridEnds[5, 0] = -OR gridEnds[5, 1] = -OR gridEnds[6, 0] = -OR gridEnds[6, 1] = 0 gridEnds[7, 0] = -OR gridEnds[7, 1] = OR gridSpoke = visual.Line(winSub, start=(0, 0), end=(0, OR), lineColor=gridgray, lineColorSpace='rgb', autoLog=False) if direction == 1: scanNameText = 'contracting ring, %2.1f%% duty cycle' % dutyCycle else: scanNameText = 'expanding ring, %2.1f%% duty cycle' % dutyCycle #wait for subject msg1 = visual.TextStim(winSub, pos=[0, +2], text='%s \n\nSubject: press a button when ready.' % scanNameText) msg1.draw() winSub.flip() thisKey = None responseKeys = list(scanDict['subjectResponse']) responseKeys.extend('q') responseKeys.extend('escape') while thisKey == None: thisKey = event.waitKeys(keyList=responseKeys) if thisKey in quitKeys: core.quit() else: event.clearEvents() responseKeys = list(scanDict['subjectResponse']) #wait for trigger msg1.setText('Noise Coming....') msg1.draw() winSub.flip() trig = None triggerKeys = list(scanDict['trigger']) triggerKeys.extend('q') triggerKeys.extend('escape') while trig == None: trig = event.waitKeys(keyList=triggerKeys) if trig in quitKeys: core.quit() else: event.clearEvents() #start the timer scanTimer = core.Clock() startTime = scanTimer.getTime() #draw the stimulus # ring1.draw() # ring2.draw() # ring3.draw() # ring4.draw() # ring5.draw() # ring6.draw() # ring7.draw() # ring8.draw() # ringMask.draw() if thisPlatform < 3: gridCircle.draw() gridCircle.setRadius(gridRadii[0]) gridCircle.draw() gridCircle.setRadius(gridRadii[1]) gridCircle.draw() gridCircle.setRadius(gridRadii[2]) gridCircle.draw() gridCircle.setRadius(gridRadii[3]) gridCircle.draw() gridCircle.setRadius(gridRadii[4]) gridCircle.draw() gridCircle.setRadius(gridRadii[5]) gridCircle.draw() gridCircle.setRadius(gridRadii[6]) gridCircle.draw() gridCircle.setRadius(gridRadii[7]) gridCircle.draw() gridSpoke.setEnd(gridEnds[0, ]) gridSpoke.draw() gridSpoke.setEnd(gridEnds[1, ]) gridSpoke.draw() gridSpoke.setEnd(gridEnds[2, ]) gridSpoke.draw() gridSpoke.setEnd(gridEnds[3, ]) gridSpoke.draw() gridSpoke.setEnd(gridEnds[4, ]) gridSpoke.draw() gridSpoke.setEnd(gridEnds[5, ]) gridSpoke.draw() gridSpoke.setEnd(gridEnds[6, ]) gridSpoke.draw() gridSpoke.setEnd(gridEnds[7, ]) gridSpoke.draw() fix0.draw() fix1.draw() fix2.draw() winSub.flip() #draw the time timeNow = scanTimer.getTime() # timeMsg=visual.TextStim(winSub,pos=[-screenSize[0]/2+100,-screenSize[1]/2+15],units='pix',text= 't = %.3f' %timeNow) if screenCount == 2: timeMsg = visual.TextStim(winOp, pos=[0, -0.5], text='t = %.3f' % timeNow) timeMsg.draw() loopCounter = 0 fixTimer = core.Clock() respTimer = core.Clock() fixOri = 0 numCoins = 0 phaseSign = 1.0 phaseTimer = core.Clock() event.clearEvents() #drift it while timeNow < startTime + scanLength: timeBefore = timeNow #seems to be OK--testing shows it doesn't alias timeNow = scanTimer.getTime() deltaT = timeNow - startTime modDeltaT = (deltaT + scanDict['preScanRest']) % scanDict['period'] deltaTinc = timeNow - timeBefore thisWidth = width * math.log(ringOR) thisWidth = width #fix time to account for preScanRest. Add on the fractional period requested deltaTshift = deltaT + (scanDict['period'] - scanDict['preScanRest']) #new way to calculate the OR, based on the formula for a sawtooth #calculate the new OR for this timestep #from wikipedia #yWikiTrig=(-2*amplitude/pi)*atan(cot(pi*t/period)); #yT2=0.5*(yWikiTrig+amplitude); if direction < 0: #expanding ringIR = IR + 0.5 * ( ringAmp + (-2.0 * ringAmp / math.pi) * numpy.arctan(1.0 / numpy.tan( math.pi * deltaTshift / scanDict['period']))) else: #contracting ringIR = IR + 0.5 * ( ringAmp - (-2.0 * ringAmp / math.pi) * numpy.arctan(1.0 / numpy.tan( math.pi * deltaTshift / scanDict['period']))) ringOR = ringIR + thisWidth # debugVar[loopCounter,0]=deltaT # debugVar[loopCounter,1]=ringIR # debugVar[loopCounter,2]=ringOR #set the ORs ring1.setSize(ringOR * radialUnits) ring1.setRadialCycles(ringOR * radialUnits * numRadialCycles) ring2.setSize(ringOR * radialUnits) ring2.setRadialCycles(ringOR * radialUnits * numRadialCycles) ring3.setSize(ringOR * radialUnits) ring3.setRadialCycles(ringOR * radialUnits * numRadialCycles) ring4.setSize(ringOR * radialUnits) ring4.setRadialCycles(ringOR * radialUnits * numRadialCycles) ring5.setSize(ringOR * radialUnits) ring5.setRadialCycles(ringOR * radialUnits * numRadialCycles) ring6.setSize(ringOR * radialUnits) ring6.setRadialCycles(ringOR * radialUnits * numRadialCycles) ring7.setSize(ringOR * radialUnits) ring7.setRadialCycles(ringOR * radialUnits * numRadialCycles) ring8.setSize(ringOR * radialUnits) ring8.setRadialCycles(ringOR * radialUnits * numRadialCycles) ringMask.setRadius(ringIR) #experimental mask # mask[0:ringIR*100]=0.5 # mask[ringIR*100:ringOR*100]=1 # mask[ringOR*100:]=0 # ring1.setMask(mask) # ring2.setMask(mask) # ring3.setMask(mask) # ring4.setMask(mask) # ring5.setMask(mask) # ring6.setMask(mask) # ring7.setMask(mask) # ring8.setMask(mask) #new phase #ringRadPhi = driftFreq*deltaT # ringRadPhi = ringRadPhi + 2.0*math.pi*driftFreq*(timeNow-timeBefore) #new direction of phase drift--set randomly but not too often # phaseTimeCheck = phaseTimer.getTime() ## debugVar[loopCounter,3]=phaseTimeCheck # phaseCoin=numpy.random.ranf() # if phaseCoin<1.0 and phaseTimeCheck>3.0: # phaseTimer.reset() # phaseSign *= -1.0 #set the phase # ring1.setRadialPhase(ringRadPhi*phaseSign) # ring2.setRadialPhase(-1.0*ringRadPhi*phaseSign) # ring3.setRadialPhase(ringRadPhi*phaseSign) # ring4.setRadialPhase(-1.0*ringRadPhi*phaseSign) # ring5.setRadialPhase(ringRadPhi*phaseSign) # ring6.setRadialPhase(-1.0*ringRadPhi*phaseSign) # ring7.setRadialPhase(ringRadPhi*phaseSign) # ring8.setRadialPhase(-1.0*ringRadPhi*phaseSign) setSign = math.floor(driftReverseFreq * deltaT / 3.0) if setSign % 2 == 0: phaseSign = 1.0 else: phaseSign = -1.0 ringRadPhiDelta = driftFreq * deltaTinc ringRadPhi[0] += ringRadPhiDelta * phaseSign ringRadPhi[1] += ringRadPhiDelta * phaseSign * -1 ringRadPhi[2] += ringRadPhiDelta * phaseSign ringRadPhi[3] += ringRadPhiDelta * phaseSign * -1 ringRadPhi[4] += ringRadPhiDelta * phaseSign ringRadPhi[5] += ringRadPhiDelta * phaseSign * -1 ringRadPhi[6] += ringRadPhiDelta * phaseSign ringRadPhi[7] += ringRadPhiDelta * phaseSign * -1 ring1.setRadialPhase(ringRadPhiInit[0]) ring2.setRadialPhase(ringRadPhi[1]) ring3.setRadialPhase(ringRadPhi[2]) ring4.setRadialPhase(ringRadPhi[3]) ring5.setRadialPhase(ringRadPhi[4]) ring6.setRadialPhase(ringRadPhi[5]) ring7.setRadialPhase(ringRadPhi[6]) ring8.setRadialPhase(ringRadPhi[7]) #every 100 frames, decide if fixation should change or not if loopCounter % 100 == 0 and loopCounter > 10: #flip a coin to decide flipCoin = numpy.random.ranf() if flipCoin < fixPercentage: #reset timers/change ori fixOri = 45 fixTimer.reset() respTimer.reset() numCoins += 1 subjectResponse[numCoins] = 0 fixTimeCheck = fixTimer.getTime() respTimeCheck = respTimer.getTime() if fixTimeCheck > fixDuration: #timer expired--reset ori fixOri = 0 fix1.setOri(fixOri) fix2.setOri(fixOri) ring1.draw() ring2.draw() ring3.draw() ring4.draw() ring5.draw() ring6.draw() ring7.draw() ring8.draw() ringMask.draw() #draw grid only if NOT linux, where it looks bad.... if thisPlatform < 3: gridCircle.setRadius(gridRadii[0]) gridCircle.draw() gridCircle.setRadius(gridRadii[1]) gridCircle.draw() gridCircle.setRadius(gridRadii[2]) gridCircle.draw() gridCircle.setRadius(gridRadii[3]) gridCircle.draw() gridCircle.setRadius(gridRadii[4]) gridCircle.draw() gridCircle.setRadius(gridRadii[5]) gridCircle.draw() gridCircle.setRadius(gridRadii[6]) gridCircle.draw() gridCircle.setRadius(gridRadii[7]) gridCircle.draw() gridSpoke.draw() gridSpoke.setEnd(gridEnds[0, ]) gridSpoke.draw() gridSpoke.setEnd(gridEnds[1, ]) gridSpoke.draw() gridSpoke.setEnd(gridEnds[2, ]) gridSpoke.draw() gridSpoke.setEnd(gridEnds[3, ]) gridSpoke.draw() gridSpoke.setEnd(gridEnds[4, ]) gridSpoke.draw() gridSpoke.setEnd(gridEnds[5, ]) gridSpoke.draw() gridSpoke.setEnd(gridEnds[6, ]) gridSpoke.draw() gridSpoke.setEnd(gridEnds[7, ]) gridSpoke.draw() fix0.draw() fix1.draw() fix2.draw() winSub.flip() if screenCount == 2: timeMsg.setText('t = %.3f' % timeNow) timeMsg.draw() msgScanLength.draw() msgScanTr.draw() winOp.flip() #look for responses for key in event.getKeys(): if key in quitKeys: core.quit() elif key in responseKeys and respTimeCheck < respDuration: subjectResponse[numCoins] = 1 loopCounter += 1 #summarize responses findResp = subjectResponse[~numpy.isnan(subjectResponse)] calcResp = findResp[findResp == 1] numCorrect = float(calcResp.shape[0]) if numCoins > 0: percentCorrect = 100.0 * float(numCorrect) / (float(numCoins)) else: percentCorrect = 100.0 msgText = 'You got %.0f %% correct!' % (percentCorrect, ) msgPC = visual.TextStim(winSub, pos=[0, +3], text=msgText) msgPC.draw() winSub.flip() #numpy.savetxt('debug.txt',debugVar,fmt='%.3f') #create an output file in a subdirectory #check for the subdirectory if os.path.isdir('subjectResponseFiles') == False: #create directory os.makedirs('subjectResponseFiles') nowTime = datetime.datetime.now() outFile = 'ringResponse%04d%02d%02d_%02d%02d.txt' % ( nowTime.year, nowTime.month, nowTime.day, nowTime.hour, nowTime.minute) outFilePath = os.path.join('subjectResponseFiles', outFile) numpy.savetxt(outFilePath, findResp, fmt='%.0f') core.wait(2) if screenCount == 2: winOp.close() winSub.close()
# Draw bubbles of increasing radius at random positions for radius in range(n_bubbles): bubble.setRadius(radius / 2.) bubble.setPos(((rnd.random() - .5) * scrsize[0], (rnd.random() - .5) * scrsize[1])) bubble.draw() # Show the new screen we've drawn win.flip() # For the duration of 'changetime', # Listen for a spacebar or escape press change_clock.reset() while change_clock.getTime() <= changetime: keys = event.getKeys(keyList=['space', 'escape']) if len(keys) > 0: break # Analyze the keypress if keys: if 'escape' in keys: # Escape press = quit the experiment break else: # Spacebar press = correct change detection; register response time acc = 1 rt = rt_clock.getTime() else: # No press = failed change detection; maximal response time
win = visual.Window([1280,1024], fullscr=True, allowGUI=False, waitBlanking=True) progBar = visual.PatchStim(win, tex=None, mask=None, size=[0,0.05],color='red',pos=[0,-0.9], autoLog=False) myStim = visual.PatchStim(win, tex='sin', mask='gauss', size=300,sf=0.05, units='pix', autoLog=False) #logging.console.setLevel(logging.INFO)#uncomment if you want to print every frame time win.setRecordFrameIntervals() for frameN in range(nIntervals+1): progBar.setSize([2.0*frameN/nIntervals, 0.05]) progBar.draw() myStim.setPhase(0.1,'+') myStim.draw() if event.getKeys(): print 'stopped early' break win.logOnFlip(msg='frame=%i' %frameN, level=logging.EXP) win.flip() win.close() #calculate some values intervalsMS = pylab.array(win.frameIntervals[1:])*1000 m=pylab.mean(intervalsMS) sd=pylab.std(intervalsMS) # se=sd/pylab.sqrt(len(intervalsMS)) # for CI of the mean distString= "Mean=%.1fms, s.d.=%.1f, 99%%CI(frame)=%.2f-%.2f" %(m,sd,m-2.58*sd,m+2.58*sd) nTotal=len(intervalsMS) nDropped=sum(intervalsMS>(1.5*m)) droppedString = "Dropped/Frames = %i/%i = %.3f%%" %(nDropped,nTotal, 100*nDropped/float(nTotal))
def runLotsOfDots(self, win, fieldShape, starting=100, baseline=None): """DotStim stress test: draw increasingly many dots until drop lots of frames report best dots as the highest dot count at which drop no frames at all fieldShape = circle or square starting = initial dot count; increases until failure baseline = known frames per second; None means measure it here """ win.recordFrameIntervals = True secs = 1 # how long to draw them for, at least 1s # baseline frames per second: if not baseline: for i in xrange(5): win.flip() # wake things up win.fps() # reset for i in xrange(60): win.flip() baseline = round(win.fps()) maxFrame = round(baseline * secs) dotsInfo = [] win.flip() bestDots = starting # this might over-estimate the actual best dotCount = starting count = visual.TextStim(win, text=str(dotCount), autoLog=False) count.draw() win.flip() dots = visual.DotStim(win, color=(1.0, 1.0, 1.0), fieldShape=fieldShape, nDots=dotCount, autoLog=False) win.fps() # reset frameCount = 0 while True: dots.draw() win.flip() frameCount += 1 if frameCount > maxFrame: fps = win.fps() # get frames per sec if len(event.getKeys(['escape'])): sys.exit() if fps < baseline * 0.6: # only break when start dropping a LOT of frames (80% or more) dotsInfo.append( ('dots_' + fieldShape, str(bestDots), '', False)) break frames_dropped = round(baseline - fps) # can be negative if frames_dropped < 1: # can be negative # only set best if no dropped frames: bestDots = dotCount # but do allow to continue in case do better with more dots: dotCount += 100 if dotCount > 1200: dotCount += 100 if dotCount > 2400: dotCount += 100 # show the dot count: count.setText(str(dotCount), log=False) count.draw() win.flip() dots = visual.DotStim(win, color=(1.0, 1.0, 1.0), fieldShape=fieldShape, nDots=dotCount, autoLog=False) frameCount = 0 win.fps() # reset win.recordFrameIntervals = False win.flip() return tuple(dotsInfo)
main_label.size = 10 main_label.setText("+") main_label.draw() globalClock = core.Clock() win.flip() ## Launch MRI (operator selects Scan or Test [emulate]; see API docuwmentation) vol = launchScan(win, MR_settings, globalClock=globalClock, simResponses=None, mode=None, esc_key='escape', instr=file_contents) # wait for first MRI sync event while not event.getKeys(MR_settings['sync']): time.sleep(0.001) onset = globalClock.getTime() vol += 1 log_msg(u"%3d %7.3f sync\n" % (vol, onset)) ## Main loop while globalClock.getTime() < duration: # retrieve and log key presses all_keys = event.getKeys() ts = globalClock.getTime() for key in all_keys: if key == MR_settings['sync']: log_csv(ts, 'sync') log_msg(u"%3d %7.3f sync\n" % (vol, ts))
def do_run(run_number, trials): # 1. add ready screen and wait for trigger ready_screen.draw() win.flip() event.waitKeys(keyList='space') # reset globalClock globalClock.reset() # send START log event logging.log(level=logging.DATA, msg='******* START (trigger from scanner) - Run %i *******' % run_number) ################ # SHOW INSTRUCTIONS ################ #for frame in range(instruct_dur): instruction_image.draw() instruction_text.draw() win.flip() event.waitKeys(keyList=('space')) ####################### # MAIN LOOP for trials # loop over stimuli for tidx, trial in enumerate(trials): value = trial['value'] prime_label = 'Daily Activity' if value == 'control' else value.title() situation = trial['message'] valueStim.setText(prime_label) # test for REST trial if trial['value'] == 'REST': for frame in range(rest_dur): fixation.draw() win.flip() # fixation for frame in range(fixation_dur): fixation.draw() win.flip() continue # 1. show prime primeStim.setText(prime_label) if tidx % 2 == 0: primeStim.draw() win.flip() event.waitKeys(keyList=('space')) else: for frame in range(prime_dur): primeStim.draw() win.flip() # 2. show situation situationStim.setText(situation) if tidx % 2 == 0: situationStim.draw() thinkStim.draw() win.flip() event.waitKeys(keyList=('space')) else: for frame in range(situation_dur): situationStim.draw() thinkStim.draw() win.flip() event.clearEvents() # 3. show rating and get response timer = core.Clock() timer.reset() space_pressed = False while (tidx % 2 != 0 and timer.getTime() < rating_dur / frame_rate ) or (tidx % 2 == 0 and space_pressed == False): #for frame in range(rating_dur): situationStim.draw() valueStim.draw() anchor1.draw() anchor4.draw() # draw rating for resp in ratingStim: resp.draw() win.flip() # get key response resp = event.getKeys(keyList=buttons) if len(resp) > 0: if resp[0] == 'space': space_pressed = True continue resp_value = button_labels[resp[0]] ratingStim[resp_value].setColor('red') trials.addData('resp', resp_value + 1) # reset rating number color for rate in ratingStim: rate.setColor('white') # 4. fixation for frame in range(fixation_dur): fixation.draw() win.flip() ready_screen.draw() win.flip() event.waitKeys(keyList=['space']) # write logs # send END log event logging.log(level=logging.DATA, msg='******* END run %i *******' % run_number) # save the trial infomation from trial handler log_filename2 = "%s_%i.csv" % (log_filename[:-4], run_number) trials.saveAsText(log_filename2, delim=',', dataOut=('n', 'all_raw'))
if t >= 0.0 and instr1.status == NOT_STARTED: # keep track of start time/frame for later instr1.tStart = t instr1.frameNStart = frameN # exact frame index instr1.setAutoDraw(True) # *ready1* updates if t >= 0.0 and ready1.status == NOT_STARTED: # keep track of start time/frame for later ready1.tStart = t ready1.frameNStart = frameN # exact frame index ready1.status = STARTED # keyboard checking is just starting event.clearEvents(eventType='keyboard') if ready1.status == STARTED: theseKeys = event.getKeys() # check for quit: if "escape" in theseKeys: endExpNow = True if len(theseKeys) > 0: # at least one key was pressed # a response ends the routine continueRoutine = False # 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 instructPracticeComponents: if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
def collectStringResponse(numCharsWanted,respPromptStim,respStim,acceptTextStim,myWin,clickSound,badKeySound,requireAcceptance,autopilot,responseDebug=False): '''respPromptStim should be a stimulus with a draw() method ''' event.clearEvents() #clear the keyboard buffer drawBlanks = True expStop = False passThisTrial = False responses=[] numResponses = 0 accepted = True if requireAcceptance: #require user to hit ENTER to finalize response accepted = False while not expStop and (numResponses < numCharsWanted or not accepted): # (numResponses < numCharsWanted and not expStop) or not accepted: #while (numResponses < numCharsWanted and not expStop) or not accepted: print 'numResponses=', numResponses #debugOFF print 'expStop=',expStop print 'accepted=',accepted noResponseYet = True thisResponse='' while noResponseYet: #loop until a valid key is hit respPromptStim.draw() drawResponses(responses,respStim,numCharsWanted,drawBlanks) myWin.flip() click = False keysPressed = event.getKeys(); #print 'keysPressed = ', keysPressed if autopilot: noResponseYet = False if 'ESCAPE' in keysPressed: expStop = True elif len(keysPressed) > 0: key = keysPressed[-1] #process only the last key, it being the most recent. In theory person could type more than one key between window flips, #but that might be hard to handle. key = key.upper() thisResponse = key if key in ['ESCAPE']: expStop = True noResponseYet = False # if key in ['SPACE']: #observer opting out because think they moved their eyes # passThisTrial = True # noResponseYet = False elif key in string.ascii_letters: noResponseYet = False responses.append(thisResponse) numResponses += 1 #not just using len(responses) because want to work even when autopilot, where thisResponse is null click = True elif key in ['BACKSPACE','DELETE']: if len(responses) >0: responses.pop() numResponses -= 1 else: #invalid key pressed badKeySound.play() if click and (click is not None): clickSound.play() drawResponses(responses,respStim,numCharsWanted,drawBlanks) myWin.flip() #draw again, otherwise won't draw the last key if (numResponses == numCharsWanted) and requireAcceptance: #ask participant to HIT ENTER TO ACCEPT waitingForAccept = True while waitingForAccept and not expStop: acceptTextStim.draw() respStim.draw() for key in event.getKeys(): key = key.upper() if key in ['ESCAPE']: expStop = True #noResponseYet = False elif key in ['ENTER','RETURN']: waitingForAccept = False accepted = True elif key in ['BACKSPACE','DELETE']: waitingForAccept = False numResponses -= 1 responses.pop() drawResponses(responses,respStim,numCharsWanted,drawBlanks) myWin.flip() #draw again, otherwise won't draw the last key myWin.flip() #end of waitingForAccept loop #end of waiting until response is finished, all keys and acceptance if required responsesAutopilot = np.array( numCharsWanted*list([('A')]) ) responses=np.array( responses ) #print 'responses=', responses,' responsesAutopilot=', responsesAutopilot #debugOFF return expStop,passThisTrial,responses,responsesAutopilot
if t >= 0.0 and welcome_scr.status == NOT_STARTED: # keep track of start time/frame for later welcome_scr.tStart = t welcome_scr.frameNStart = frameN # exact frame index welcome_scr.setAutoDraw(True) # *exp_start* updates if t >= 0.0 and exp_start.status == NOT_STARTED: # keep track of start time/frame for later exp_start.tStart = t exp_start.frameNStart = frameN # exact frame index exp_start.status = STARTED # keyboard checking is just starting event.clearEvents(eventType='keyboard') if exp_start.status == STARTED: theseKeys = event.getKeys(keyList=['y']) # check for quit: if "escape" in theseKeys: endExpNow = True if len(theseKeys) > 0: # at least one key was pressed # a response ends the routine continueRoutine = False # 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
def get_events(self): """ Logs responses/triggers """ events = event.getKeys(timeStamped=self.session.clock) if events: if 'q' in [ev[0] for ev in events]: # specific key in settings? np.save( opj(self.session.output_dir, self.session.output_str + '_simple_response_data.npy'), { "Expected number of responses": len(self.session.dot_switch_color_times), "Total subject responses": self.session.total_responses, f"Correct responses (within {self.session.settings['Task settings']['response interval']}s of dot color change)": self.session.correct_responses }) if self.session.settings['PRF stimulus settings'][ 'Screenshot'] == True: self.session.win.saveMovieFrames( opj(self.session.screen_dir, self.session.output_str + '_Screenshot.png')) self.session.close() self.session.quit() for key, t in events: if key == self.session.mri_trigger: event_type = 'pulse' #marco edit. the second bit is a hack to avoid double-counting of the first t when simulating a scanner if self.session.settings['PRF stimulus settings'][ 'Scanner sync'] == True and t > 0.1: self.exit_phase = True #ideally, for speed, would want getMovieFrame to be called right after the first winflip. #but this would have to be dun from inside trial.run() if self.session.settings['PRF stimulus settings'][ 'Screenshot'] == True: self.session.win.getMovieFrame() else: event_type = 'response' self.session.total_responses += 1 #tracking percentage of correct responses per session if self.session.dot_count < len( self.session.dot_switch_color_times): if t > self.session.dot_switch_color_times[self.session.dot_count] and \ t < self.session.dot_switch_color_times[self.session.dot_count] + float(self.session.settings['Task settings']['response interval']): self.session.correct_responses += 1 # print(f'number correct responses: {self.session.correct_responses}') #testing idx = self.session.global_log.shape[0] self.session.global_log.loc[idx, 'trial_nr'] = self.trial_nr self.session.global_log.loc[idx, 'onset'] = t self.session.global_log.loc[idx, 'event_type'] = event_type self.session.global_log.loc[idx, 'phase'] = self.phase self.session.global_log.loc[idx, 'response'] = key for param, val in self.parameters.items(): self.session.global_log.loc[idx, param] = val #self.trial_log['response_key'][self.phase].append(key) #self.trial_log['response_onset'][self.phase].append(t) #self.trial_log['response_time'][self.phase].append(t - self.start_trial) if key != self.session.mri_trigger: self.last_resp = key self.last_resp_onset = t #update counter if self.session.dot_count < len(self.session.dot_switch_color_times): if self.session.clock.getTime() > self.session.dot_switch_color_times[self.session.dot_count] + \ float(self.session.settings['Task settings']['response interval'])+0.1: #to give time to respond self.session.dot_count += 1
def RunTrial(sequence): # check for going over session time if globalClock.getTime() - tStartSession > tSessionMax: CoolDown() #exit experiment gracefully # get deadline for response respDur = tRespPerItem * (len(sequence)) respDur = int( tRespRoundOff * np.ceil(float(respDur) / tRespRoundOff)) # round up to next tRespRoundOff multiple # print("length = %d, respDur = %1.1f"%(len(sequence), respDur)) logging.log(level=logging.EXP, msg='Start Sequence %d' % len(sequence)) # play sequence for iStim in sequence: DisplayButtons([iStim], stimDur) beeps[iStim].play() core.wait(stimDur, stimDur) # wait so sound plays properly DisplayButtons([], pauseDur) # core.wait(pauseDur,pauseDur) logging.log(level=logging.EXP, msg='End Sequence %d' % len(sequence)) #draw fixation dot and wait for response event.clearEvents() # ignore any keypresses before now # win.logOnFlip(level=logging.EXP, msg='Display Fixation') # fixation.draw() DisplayButtons([], 0, True) # tResp = trialClock.getTime() # IMPORTANT REFERENCE POINT tResp = tNextFlip[0] # IMPORTANT REFERENCE POINT iSeq = 0 # Response loop while globalClock.getTime() < (tResp + respDur) and iSeq < len(sequence): iStim = sequence[iSeq] thisKey = event.getKeys(timeStamped=globalClock) if len(thisKey) > 0 and thisKey[0][0] == respKeys[iStim]: #tResp = trialClock.getTime(); # reset the shot clock # fixation.draw() DisplayButtons([iStim], 0, True) # DON'T INCREMENT CLOCK beepsShort[iStim].play() core.wait( shortDur, shortDur) # USE CORE.WAIT HERE SO CLOCK DOESN'T INCREMENT # fixation.draw() DisplayButtons([], 0, True) iSeq += 1 elif len(thisKey) > 0 and thisKey[0][0] in ['q', 'escape']: core.quit() elif len(thisKey) > 0: print('this: %s' % str(thisKey[0][0])) print('correct: %s' % str(respKeys[iStim])) buzz.play() core.wait(buzzDur, buzzDur) # USE CORE.WAIT HERE SO CLOCK DOESN'T INCREMENT return (WRONG) #get response if iSeq == len(sequence): # finished sequence DisplayButtons([], respDur, False) # increment next-frame clock return (RIGHT) else: # ran out of time buzz.play() core.wait(buzzDur, buzzDur) # USE CORE.WAIT HERE SO CLOCK DOESN'T INCREMENT DisplayButtons([], respDur, False) # increment next-frame clock return (TOOSLOW)
simResponses = [(0.123, 'a'), (4.789, 'c'), (2.456, 'b')] # launch: operator selects Scan or Test (emulate); see API documentation vol = launchScan(win, MR_settings, globalClock=globalClock, simResponses=simResponses) infer_missed_sync = False # best if your script timing works without this, but this might be useful sometimes max_slippage = 0.02 # how long to allow before treating a "slow" sync as missed # any slippage is almost certainly due to timing issues with your script or PC, and not MR scanner duration = MR_settings['volumes'] * MR_settings['TR'] # note: globalClock has been reset to 0.0 by launchScan() while globalClock.getTime() < duration: allKeys = event.getKeys() for key in allKeys: if key != MR_settings['sync']: output += "%3d %7.3f %s\n" % (vol - 1, globalClock.getTime(), str(key)) if 'escape' in allKeys: output += 'user cancel, ' break # detect sync or infer it should have happened: if MR_settings['sync'] in allKeys: sync_now = key_code # flag onset = globalClock.getTime() if infer_missed_sync: expected_onset = vol * MR_settings['TR'] now = globalClock.getTime() if now > expected_onset + max_slippage:
for midx, ts in enumerate(tmel): trigger = str(block['type'][tidx]) + str(midx + 1) + str(ts) sounds[ts - 1].play() #setParallelData(int(trigger)) # for sending triggers print(trigger) #clear events and reset the clock for RT if midx == 0: event.clearEvents(eventType='keyboard') RT.reset() core.wait(0.5, hogCPUperiod=0.5) # if there is a response record keys and RT. Else record 0 and time limit: resp = None while resp == None: key = event.getKeys(timeStamped=RT) if len(key) > 0: resp = key[0][0] rt = key[0][1] elif RT.getTime() > 2.5: resp = 0 rt = RT.getTime() ## gather log info and add to logfile: lrow = '{},{},{},{},{},{};{};{},{};{};{},{},{},{}\n' lrow = lrow.format(sub_id[0], b, ttime, block['melID'][tidx], block['trialID'][tidx], pmel[0], pmel[1], pmel[2], tmel[0], tmel[1], tmel[2], block['type'][tidx], resp, rt * 1000) logfile.write(lrow) core.wait(0.3) # 300 ms after response, to start new trial
def get_events(self): events = event.getKeys(timeStamped=self.session.clock) if events: if 'q' in [ev[0] for ev in events]: # specific key in settings? self.session.close() self.session.quit() for key, t in events: if key == self.session.mri_trigger: event_type = 'pulse' else: event_type = 'response' idx = self.session.global_log.shape[0] self.session.global_log.loc[idx, 'trial_nr'] = self.trial_nr self.session.global_log.loc[idx, 'onset'] = t self.session.global_log.loc[idx, 'event_type'] = event_type self.session.global_log.loc[idx, 'phase'] = self.phase self.session.global_log.loc[idx, 'response'] = key for param, val in self.parameters.items(): self.session.global_log.loc[idx, param] = val if self.eyetracker_on: # send msg to eyetracker msg = f'start_type-{event_type}_trial-{self.trial_nr}_phase-{self.phase}_key-{key}_time-{t}' self.session.tracker.sendMessage(msg) #self.trial_log['response_key'][self.phase].append(key) #self.trial_log['response_onset'][self.phase].append(t) #self.trial_log['response_time'][self.phase].append(t - self.start_trial) if key != self.session.mri_trigger: self.last_resp = key self.last_resp_onset = t for e in events: if e[0] in self.keys: ix = self.keys.index(e[0]) if ix == 0: if self.current_topic == 'position_x': self.position[0] -= 0.1 elif self.current_topic == 'position_y': self.position[1] -= 0.1 elif self.current_topic == 'size': self.size -= 0.1 elif ix == 1: if self.current_topic == 'position_x': self.position[0] += 0.1 elif self.current_topic == 'position_y': self.position[1] += 0.1 elif self.current_topic == 'size': self.size += 0.1 elif ix == 2: if self.current_topic == 'position_x': self.current_topic = 'position_y' elif self.current_topic == 'position_y': self.current_topic = 'size' elif self.current_topic == 'size': self.current_topic = 'position_x' if self.current_topic == 'position_x': self.session.info.text = 'x: {:0.2f}'.format(self.position[0]) elif self.current_topic == 'position_y': self.session.info.text = 'y: {:0.2f}'.format(self.position[1]) elif self.current_topic == 'size': self.session.info.text = 'size: {:0.2f}'.format(self.size) if self.current_topic.startswith('position'): self.session.info.pos = self.position self.session.flicker_stimulus.pos = self.position self.session.fixation_stimulus.pos = self.position elif self.current_topic == 'size': self.session.flicker_stimulus.size = self.size self.session.fixation_stimulus.size = self.size * self.session.settings['flicker_experiment']['fixation_size_prop'] self.session.info.height = self.size / 15.
def get_ttl(): allKeys = event.getKeys([MR_settings["sync"]]) for key in allKeys: if key.lower() == MR_settings["sync"]: return True return False
flipHoriz=False, flipVert=False, interpolate=True, depth=-1.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 logging.setDefaultClock(globalClock) #------Prepare to start Routine "inst"------- trials = data.TrialHandler(nReps=1, method='sequential', extraInfo=expInfo, originPath=None, trialList=data.importConditions(CONFIGURATION_FILE % expInfo['participant']), name='trials') thisExp.addLoop(trials) # add the loop to the experiment # set up handler to look after randomisation of conditions etc text.setAutoDraw(True) win.flip() keys = event.getKeys(keyList=['T','t','escape']) event.waitKeys(['return']) globalClock.reset() routineTimer.reset() routineTimer.add(BEGIN_TRIAL_DELAY) text.setAutoDraw(False) win.flip() if('escape' in keys): core.quit() while routineTimer.getTime() > 0: continue for thisTrial in trials: trialComponents = [] trialComponents.append(image) trialComponents.append(image_2) trialComponents.append(image_3)
if t >= 0.0 and Instr.status == NOT_STARTED: # keep track of start time/frame for later Instr.tStart = t Instr.frameNStart = frameN # exact frame index Instr.setAutoDraw(True) # *key_resp_3* updates if t >= 0.0 and key_resp_3.status == NOT_STARTED: # keep track of start time/frame for later key_resp_3.tStart = t key_resp_3.frameNStart = frameN # exact frame index key_resp_3.status = STARTED # keyboard checking is just starting event.clearEvents(eventType='keyboard') if key_resp_3.status == STARTED: theseKeys = event.getKeys() # check for quit: if "escape" in theseKeys: endExpNow = True if len(theseKeys) > 0: # at least one key was pressed # a response ends the routine continueRoutine = False # 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 InstComponents: if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
def event(self): for ev in event.getKeys(): if len(ev) > 0: if ev in ['esc', 'escape', 'q']: self.events.append( [-99, self.session.clock.getTime() - self.start_time]) self.stopped = True self.session.stopped = True print 'run canceled by user' # it handles both numeric and lettering modes elif ev == ' ': self.events.append( [0, self.session.clock.getTime() - self.start_time]) if self.phase == 0: self.phase_forward() else: self.events.append([ -99, self.session.clock.getTime() - self.start_time ]) self.stopped = True print 'trial canceled by user' elif ev == 't': # TR pulse self.events.append( [99, self.session.clock.getTime() - self.start_time]) if (self.phase == 0) + (self.phase == 1): self.phase_forward() elif ev in self.session.response_button_signs.keys(): if self.last_sampled_staircase is not None: #hasattr(self,'last_sampled_staircase'): # what value were we presenting at? test_value = self.session.staircases[ self.last_sampled_staircase].quantile() response = self.session.response_button_signs[ ev] * self.present_fix_task_sign # update the staircase self.session.staircases[ self.last_sampled_staircase].update( test_value, (response + 1) / 2) # now block the possibility of further updates self.last_sampled_staircase = None log_msg = 'staircase updated from %f after response %s at %f' % ( test_value, str((response + 1) / 2), self.session.clock.getTime()) self.events.append(log_msg) print log_msg if self.session.tracker: self.session.tracker.log(log_msg) # add answers based on stimulus changes, and interact with the staircases at hand # elif ev == 'b' or ev == 'right': # answer pulse event_msg = 'trial ' + str( self.ID) + ' key: ' + str(ev) + ' at time: ' + str( self.session.clock.getTime()) self.events.append(event_msg) super(MapperTrial, self).key_event(ev)
nDots = 500 maxSpeed = 0.02 dotSize = .0075 dotsTheta = numpy.random.rand(nDots) * 360 dotsRadius = (numpy.random.rand(nDots)**0.5) * 2 speed = numpy.random.rand(nDots) * maxSpeed win = visual.Window([800, 600], color=[-1, -1, -1]) dots = visual.ElementArrayStim(win, elementTex=None, elementMask='circle', nElements=nDots, sizes=dotSize) while not event.getKeys(): # update radius dotsRadius = (dotsRadius + speed) # random radius where radius too large outFieldDots = (dotsRadius >= 2.0) dotsRadius[outFieldDots] = numpy.random.rand(sum(outFieldDots)) * 2.0 dotsX, dotsY = pol2cart(dotsTheta, dotsRadius) dotsX *= 0.75 # to account for wider aspect ratio dots.xys = numpy.array([dotsX, dotsY]).transpose() dots.draw() win.flip() win.close() core.quit()
if circle.radius < 10: circle.radius = (circle.radius + (9 / FRAMES)) circle.draw() win.flip() for f in range(HOLD_FRAMES): circle.radius = 10 circle.draw() win.flip() for f in range(ISI_FRAMES): win.flip() print(circle.radius) circle.radius = 1 EPOCH -= 1 # Get keys to quit. if len(event.getKeys()) > 0: event.clearEvents() win.close() ''' # For recording dropped frames win.recordFrameIntervals=True # By default, the threshold is set to 120% of the estimated refresh # duration, but arbitrary values can be set. # # I've got 85Hz monitor and want to allow 4 ms tolerance; any refresh that # takes longer than the specified period will be considered a "dropped" # frame and increase the count of win.nDroppedFrames. win.refreshThreshold = 1/85 + 0.004
def check_exit(): #abort if esc was pressed if event.getKeys('escape'): win.close() core.quit()
def Social(self, MotherPacket): ''' Pariticpant plays a trial of the social game in any of the four conditions. ''' event.Mouse(visible=False) # balloon instances b1 = balloon(self.window, 1, os.getcwd() + '/Resources', self.eventRecorder) b2 = balloon(self.window, 2, os.getcwd() + '/Resources', self.eventRecorder) self.eventRecorder.p1 = b1 self.eventRecorder.p2 = b2 # Use subject ID's to generate valid port numbers for subject TCP sockets Port = int(1100 + MotherPacket['SubjectID']) P2port = int(1100 + MotherPacket['P2_ID']) # Establish TCP connection with other player if Port > P2port: # If player's SubjectID is larger than P2, act as server. core.wait( np.random.uniform(1, 3) ) # pause for a moment to ensure P2 is ready to establish connection # Begin connnection protocol Server = socket(AF_INET, SOCK_STREAM) Server.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) Server.bind((gethostbyname(gethostname()), Port)) Server.settimeout(10) # Set timeout for 10 seconds Server.listen(1) try: GameSock, clientaddr = Server.accept() except timeout: # If no connection is established within 10sec. return restart = True self.restart = True return True elif Port < P2port: # If player's SubjectID is smaller than P2, act as client. start = time.time() end = start + 10 while 1: # For 10 seconds try to establish connection with server GameSock = socket(AF_INET, SOCK_STREAM) GameSock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) try: GameSock.connect((MotherPacket['P2_IP'], P2port)) break except error: # If no connection is established within 10sec. return restart = True if time.time() >= end: self.restart = True return True self.fixation.draw() self.window.flip() # Trial handshake ensures that both computers start trial at exact same time GameSock.setblocking(1) GameSock.settimeout(180) if Port > P2port: GameSock.send('n') GameSock.recv(1) else: GameSock.recv(1) GameSock.send('n') GameSock.setblocking(0) core.wait(1) # Get Trial ready BothFinished = False b1.reset() b2.reset() b1.update() b2.update() b1.Ex.setAutoDraw(True) b2.Ex.setAutoDraw(True) self.PreTrialSetup(MotherPacket) while not BothFinished: # Only update screen is something happens Action = False b2Action = False # Check if players have timed out Action = b1.timeOut(world=self.TrialTimer) b2Action = b2.timeOut(world=self.TrialTimer) # Check whether P2 sent a message # 1 = pump, 0 = popped, 2 = cashed Message = self.checkMessage(GameSock) if Message == '1': b2.pump() b2Action = True elif Message == '0': b2.pump() b2.pumps = 0 self.eventRecorder.RecordEvent('P2_Pop') b2.popped = True b2.earned.setText('0') b2.outcome.setText('Popped!') b2.outcome.setColor(u'red') b2.done = True b2Action = True elif Message == '2': b2Action = b2.cash() if self.Competitive == '0': b2.outcome.setColor(u'green') # Make Actions if b1.pumpAction(): # Pump and send message Action = True if b1.popped: if self.sendMessage(GameSock, '0'): self.rstart() break # if something went wrong, end trial else: if self.sendMessage(GameSock, '1'): print 'pump' self.rstart() break # if something went wrong, end trial # if np.random.randint(0,1000000) < 10: # FOR AUTO PUMP if event.getKeys(['return']): # cash in and send messaged if b1.cash(): Action = True if self.Competitive == '0': b1.outcome.setColor(u'green') if self.sendMessage(GameSock, '2'): self.rstart() break # if something went wrong, end trial # Determine winner of trial if b1.done and b2.done: if self.Competitive == '1': if b1.pumps > b2.pumps: b1.box.opacity = 1 b1.outcome.setColor(u'green') if b1.cashed and b2.cashed: b2.Ex.setText('X') elif b1.pumps < b2.pumps: b2.box.opacity = 1 b2.outcome.setColor(u'green') if b1.cashed and b2.cashed: b1.Ex.setText('X') elif b1.pumps == b2.pumps: if b1.cashed and b2.cashed: b1.Ex.setText('X') b2.Ex.setText('X') self.eventRecorder.RecordEvent('OutcomeScreen') Action = True BothFinished = True # Update the screen if Action or b2Action: b1.update() b2.update() self.window.flip() GameSock.close() # close game TCP socket core.wait(np.random.uniform(2, 3)) b1.Ex.setAutoDraw(False) b2.Ex.setAutoDraw(False) return self.restart
aperture = visual.Aperture(win, size=.5, pos=[0.16, 0.16], shape='square') select = "gabor1" while True: if select == "gabor1": aperture.enable() #actually is enabled by default when created gabor1.draw() select = "gabor2" elif select == "gabor2": aperture.disable() #drawing from here ignores aperture gabor2.draw() select = "gabor1" text.draw() win.flip() core.wait(0.1) if "q" in event.getKeys(): break # make the psychopy window empty and show mouse again mouse.setVisible(True) win.flip() win.flip() # on some graphics cards win.flip must be called twice to get an # empty screen ## Present html trials with psytml for trial_num, item in enumerate(items): data_trial = psytml.show_form(item, (900, 700), None) data_trial.update( { "id": id_, "condition": condition,
ori=45, autoLog=False) #this stim changes too much for autologging to be useful grating2 = visual.PatchStim( myWin, mask="gauss", color=[1.0, 1.0, 1.0], opacity=0.5, size=(1.0, 1.0), sf=(4, 0), ori=135, autoLog=False) #this stim changes too much for autologging to be useful trialClock = core.Clock() t = 0 while t < 20: #quits after 20 secs t = trialClock.getTime() grating1.setPhase(1 * t) #drift at 1Hz grating1.draw() #redraw it grating2.setPhase(2 * t) #drift at 2Hz grating2.draw() #redraw it myWin.flip() #update the screen #handle key presses each frame for keys in event.getKeys(): if keys in ['escape', 'q']: core.quit()
envsf=4, size=1, contrast=0.5, moddepth=1.0, envori=0, pos=[0.5, 0.5], beat=True, interpolate=0) while True: #contMod.phase += 0.01 env1.ori += 0.1 env2.envori += 0.1 env2.envphase += 0.01 env3.envori += 0.1 env3.ori -= 0.1 env4.envphase += 0.01 #env4.phase+=0.01 #env1.phase+=0.01 #env1.ori+=0.1 env1.draw() env2.draw() env3.draw() env4.draw() win.flip() if 'q' in event.getKeys(): core.quit()
# *Inst_text* updates if t >= 0.0 and Inst_text.status == NOT_STARTED: # keep track of start time/frame for later Inst_text.tStart = t Inst_text.frameNStart = frameN # exact frame index Inst_text.setAutoDraw(True) # *key_resp_1* updates if t >= 0.0 and key_resp_1.status == NOT_STARTED: # keep track of start time/frame for later key_resp_1.tStart = t key_resp_1.frameNStart = frameN # exact frame index key_resp_1.status = STARTED # keyboard checking is just starting if key_resp_1.status == STARTED: theseKeys = event.getKeys(keyList=['space']) # check for quit: if "escape" in theseKeys: endExpNow = True if len(theseKeys) > 0: # at least one key was pressed # a response ends the routine continueRoutine = False # 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:
def run_trial(pos_lists, speed_lists, trial_index): """ a function to run trials. :param pos_lists: 小方块的初始位置 :param speed_lists: 小方块的速度 :param trial_index: 试次数 :return: """ # get a reference to the currently active EyeLink connection el_tracker = pylink.getEYELINK() # put the tracker in the offline mode first el_tracker.setOfflineMode() # send a 'TRIALID' message to mark the start of a trial el_tracker.sendMessage('TRIALID %d' % trial_index) # record_status_message : show some info on the Host PC # here we show how many trial has been tested status_msg = 'TRIAL number %d ' % (trial_index) el_tracker.sendCommand("record_status_message '%s'" % status_msg) # draw a reference grid on the Host PC screen # For details, See section 25.6 'Drawing Commands' in the # EyeLink Programmers Guide manual # line_hor = (scnWidth / 2.0 - start_x, scnHeight / 2.0, # scnWidth / 2.0 + start_x, scnHeight / 2.0) # line_ver = (scnWidth / 2.0, scnHeight / 2.0 - start_y, # scnWidth / 2.0, scnHeight / 2.0 + start_y) # el_tracker.sendCommand('clear_screen 0') # clear the host Display # el_tracker.sendCommand('draw_line %d %d %d %d 15' % line_hor) # el_tracker.sendCommand('draw_line %d %d %d %d 15' % line_ver) red_box = (rv_red[0][0] + scn_width / 2, scn_height / 2 - rv_red[0][1], rv_red[2][0] + scn_width / 2, scn_height / 2 - rv_red[2][1]) blue_box = (rv_blue[0][0] + scn_width / 2, scn_height / 2 - rv_blue[0][1], rv_blue[2][0] + scn_width / 2, scn_height / 2 - rv_blue[2][1]) green_box = (rv_green[0][0] + scn_width / 2, scn_height / 2 - rv_green[0][1], rv_green[2][0] + scn_width / 2, scn_height / 2 - rv_green[2][1]) yellow_box = (rv_yellow[0][0] + scn_width / 2, scn_height / 2 - rv_yellow[0][1], rv_yellow[2][0] + scn_width / 2, scn_height / 2 - rv_yellow[2][1]) el_tracker.sendCommand('clear_screen 0') # clear the host Display el_tracker.sendCommand('draw_box %d %d %d %d 15' % red_box) el_tracker.sendCommand('draw_box %d %d %d %d 15' % blue_box) el_tracker.sendCommand('draw_box %d %d %d %d 15' % green_box) el_tracker.sendCommand('draw_box %d %d %d %d 15' % yellow_box) # put tracker in idle/offline mode before recording el_tracker.setOfflineMode() # Start recording # arguments: sample_to_file, events_to_file, sample_over_link, # event_over_link (1-yes, 0-no) try: el_tracker.startRecording(1, 1, 1, 1) except RuntimeError as error: print("ERROR:", error) abort_trial() return pylink.TRIAL_ERROR # Allocate some time for the tracker to cache some samples pylink.pumpDelay(100) # Send a message to clear the Data Viewer screen, get it ready for # drawing the pictures during visualization bgcolor_RGB = (116, 116, 116) el_tracker.sendMessage('!V CLEAR %d %d %d' % bgcolor_RGB) # open a INTEREAT AREA SET file to make a dynamic IA for the target ias = 'IA_%d.ias' % trial_index ias_file = open(os.path.join(aoi_folder, ias), 'w') frame_num = 0 # keep track of the frames displayed # 在每个试次开始时,更改小球位置属性 s_rect_red = visual.ShapeStim(win, vertices=pos_lists[0], fillColor='red', lineColor=None) s_rect_green = visual.ShapeStim(win, vertices=pos_lists[1], fillColor='green', lineColor=None) s_rect_blue = visual.ShapeStim(win, vertices=pos_lists[2], fillColor='blue', lineColor=None) s_rect_yellow = visual.ShapeStim(win, vertices=pos_lists[3], fillColor='yellow', lineColor=None) # 大方块是否选中 red_selected, green_selected, blue_selected, yellow_selected = False, False, False, False # 小方块是否选中 s_red_selected, s_green_selected = False, False s_blue_selected, s_yellow_selected = False, False # 小方块是否超出屏幕边缘 s_red_out, s_green_out, s_blue_out, s_yellow_out = False, False, False, False # 小方块是否选择错误 red_wrong, green_wrong, blue_wrong, yellow_wrong = False, False, False, False # set a timer t = core.getTime() # draw a cross FIXATION el_tracker.sendMessage('FIXATION_SCREEN') while core.getTime() - t <= 1: msg.setText('+') msg.height = 50 msg.draw() win.flip() # draw rect while True: # abort the current trial if the tracker is no longer recording error = el_tracker.isRecording() if error is not pylink.TRIAL_OK: el_tracker.sendMessage("tracker_disconnected") abort_trial() return error # check keyboard events for keycode, modifier in event.getKeys(modifiers=True): # abort a trial if 'ESCAPE' is pressed if keycode == 'escape': el_tracker.sendMessage('trial_skipped_by_user') # clear the screen clear_screen(win) # abort trial abort_trial() return pylink.SKIP_TRIAL # terminate the task if Ctrl-c if keycode == 'c' and (modifier['ctrl'] is True): el_tracker.sendMessage('terminated_by_user') terminate_task() return pylink.ABORT_EXPT # 获取鼠标或眼睛实时位置 get_mouse_eye_pos() # draw mouse zone mouse_zone.draw() # draw 大方块 rect_red.draw() rect_green.draw() rect_blue.draw() rect_yellow.draw() # draw 小方块 s_rect_red.draw() s_rect_green.draw() s_rect_blue.draw() s_rect_yellow.draw() frame_num += 1 if frame_num == 1: el_tracker.sendMessage('TARGET_ONSET') # record a message to let Data Viewer know where to find # the IA file for the current trial. ias_path = os.path.join('aoi', ias) el_tracker.sendMessage('!V IAREA FILE %s' % ias_path) else: # 对四个大方块设置兴趣区 # RECTANGLE id left top right bottom [label] # el_tracker.sendMessage('!V IAREA RECTANGLE %s %d %d %d %d %s' % # (1, rv_red[0][0], rv_red[0][1], # rv_red[2][0], rv_red[2][1], 'red')) # el_tracker.sendMessage('!V IAREA RECTANGLE %s %d %d %d %d %s' % # (2, rv_blue[0][0], rv_blue[0][1], # rv_blue[2][0], rv_blue[2][1], 'blue')) # el_tracker.sendMessage('!V IAREA RECTANGLE %s %d %d %d %d %s' % # (3, rv_green[0][0], rv_green[0][1], # rv_green[2][0], rv_green[2][1], 'red')) # el_tracker.sendMessage('!V IAREA RECTANGLE %s %d %d %d %d %s' % # (4, rv_yellow[0][0], rv_yellow[0][1], # rv_yellow[2][0], rv_yellow[2][1], 'red')) # el_tracker.sendMessage('!V IAREA RECTANGLE %s %d %d %d %d %s' % # (5, rv_red[1][0], rv_red[1][1], # rv_green[3][0], rv_green[3][1], 'center')) ias_file.write('RECTANGLE %s %d %d %d %d %s\n' % (1, rv_red[0][0] + scn_width / 2, scn_height / 2 - rv_red[0][1], rv_red[2][0] + scn_width / 2, scn_height / 2 - rv_red[2][1], 'red')) ias_file.write('RECTANGLE %s %d %d %d %d %s\n' % (2, rv_blue[0][0] + scn_width / 2, scn_height / 2 - rv_blue[0][1], rv_blue[2][0] + scn_width / 2, scn_height / 2 - rv_blue[2][1], 'blue')) ias_file.write('RECTANGLE %s %d %d %d %d %s\n' % (3, rv_green[0][0] + scn_width / 2, scn_height / 2 - rv_green[0][1], rv_green[2][0] + scn_width / 2, scn_height / 2 - rv_green[2][1], 'green')) ias_file.write( 'RECTANGLE %s %d %d %d %d %s\n' % (4, rv_yellow[0][0] + scn_width / 2, scn_height / 2 - rv_yellow[0][1], rv_yellow[2][0] + scn_width / 2, scn_height / 2 - rv_yellow[2][1], 'yellow')) ias_file.write('RECTANGLE %s %d %d %d %d %s\n' % (5, rv_red[1][0] + scn_width / 2, scn_height / 2 - rv_red[1][1], rv_green[3][0] + scn_width / 2, scn_height / 2 - rv_green[3][1], 'center')) # 定义小方块下落的速度 s_rect_red.pos -= (0, speed_lists[0]) s_rect_green.pos -= (0, speed_lists[1]) s_rect_blue.pos -= (0, speed_lists[2]) s_rect_yellow.pos -= (0, speed_lists[3]) win.flip() # 如果鼠标或眼睛移入大方块,则改变大方块颜色和透明度 # 如果移出,则恢复原来的属性 # 落在红色大方块区域 if rect_red.contains(mouse): rect_red.fillColor = 'black' red_time = core.getTime() - t while True: s_rect_red.pos -= (0, speed_lists[0]) s_rect_green.pos -= (0, speed_lists[1]) s_rect_blue.pos -= (0, speed_lists[2]) s_rect_yellow.pos -= (0, speed_lists[3]) # mouse_zone.pos = mouse.getPos() get_mouse_eye_pos() if rect_red.opacity >= 0.5: rect_red.opacity -= 0.02 mouse_zone.draw() rect_red.draw() rect_green.draw() rect_blue.draw() rect_yellow.draw() s_rect_red.draw() s_rect_green.draw() s_rect_blue.draw() s_rect_yellow.draw() win.flip() red_stay = core.getTime() - t if red_stay - red_time > stay_time: logging.info('red_stay: ' + str(red_stay - red_time)) logging.info('red_select') red_selected = True logging.info('red_break_1') break elif not rect_red.contains(mouse): logging.info('red_break_2') break else: rect_red.fillColor = 'grey' rect_red.opacity = 1 # 落在绿色大方块区域 if rect_green.contains(mouse): rect_green.fillColor = 'black' green_time = core.getTime() - t while True: s_rect_red.pos -= (0, speed_lists[0]) s_rect_green.pos -= (0, speed_lists[1]) s_rect_blue.pos -= (0, speed_lists[2]) s_rect_yellow.pos -= (0, speed_lists[3]) # mouse_zone.pos = mouse.getPos() get_mouse_eye_pos() if rect_green.opacity >= 0.5: rect_green.opacity -= 0.02 mouse_zone.draw() rect_red.draw() rect_green.draw() rect_blue.draw() rect_yellow.draw() s_rect_red.draw() s_rect_green.draw() s_rect_blue.draw() s_rect_yellow.draw() win.flip() green_stay = core.getTime() - t if green_stay - green_time > stay_time: logging.info('green_z: ' + str(green_stay - green_time)) logging.info('green_select') green_selected = True logging.info('green_break_1') break if not rect_green.contains(mouse): logging.info('green_break_2') break else: rect_green.fillColor = 'grey' rect_green.opacity = 1 # 落在蓝色大方块区域 if rect_blue.contains(mouse): rect_blue.fillColor = 'black' blue_time = core.getTime() - t while True: s_rect_red.pos -= (0, speed_lists[0]) s_rect_green.pos -= (0, speed_lists[1]) s_rect_blue.pos -= (0, speed_lists[2]) s_rect_yellow.pos -= (0, speed_lists[3]) # mouse_zone.pos = mouse.getPos() get_mouse_eye_pos() if rect_blue.opacity >= 0.5: rect_blue.opacity -= 0.02 mouse_zone.draw() rect_red.draw() rect_green.draw() rect_blue.draw() rect_yellow.draw() s_rect_red.draw() s_rect_green.draw() s_rect_blue.draw() s_rect_yellow.draw() win.flip() blue_stay = core.getTime() - t if blue_stay - blue_time > stay_time: logging.info('blue_z: ' + str(blue_stay - blue_time)) logging.info('blue_select') blue_selected = True logging.info('blue_break_1') break if not rect_blue.contains(mouse): logging.info('blue_break_2') break else: rect_blue.fillColor = 'grey' rect_blue.opacity = 1 # 落在黄色大方块区域 if rect_yellow.contains(mouse): rect_yellow.fillColor = 'black' yellow_time = core.getTime() - t while True: s_rect_red.pos -= (0, speed_lists[0]) s_rect_green.pos -= (0, speed_lists[1]) s_rect_blue.pos -= (0, speed_lists[2]) s_rect_yellow.pos -= (0, speed_lists[3]) # mouse_zone.pos = mouse.getPos() get_mouse_eye_pos() if rect_yellow.opacity >= 0.5: rect_yellow.opacity -= 0.02 mouse_zone.draw() rect_red.draw() rect_green.draw() rect_blue.draw() rect_yellow.draw() s_rect_red.draw() s_rect_green.draw() s_rect_blue.draw() s_rect_yellow.draw() win.flip() yellow_stay = core.getTime() - t if yellow_stay - yellow_time > stay_time: logging.info('yellow_z: ' + str(yellow_stay - yellow_time)) logging.info('yellow_select') yellow_selected = True logging.info('yellow_break_1') break if not rect_yellow.contains(mouse): logging.info('yellow_break_2') break else: rect_yellow.fillColor = 'grey' rect_yellow.opacity = 1 # 判断红色和绿色小方块的正确和错误选择 if not (s_red_selected and s_green_selected): # 正确选择 # 选中红色和绿色大方块,代表红色和绿色小方块被选中 # 通过大方块选中的先后顺序,判断哪个小方块被选中 if red_selected and green_selected: # 红色小方块被选中 if red_time - green_time < 0: s_rect_red.opacity = 0 s_red_selected = True # 反应时 RT_red = abs(red_time - green_time) logging.info('r: ' + str(RT_red)) else: # 绿色小方块被选中 s_rect_green.opacity = 0 s_green_selected = True RT_green = abs(red_time - green_time) logging.info('g: ' + str(RT_green)) green_selected = False red_selected = False # 由红色大方块而产生的错误选择 if red_selected: if blue_selected: # red --> blue --> green if not s_blue_selected: red_wrong = True logging.info('r1: ' + str(red_wrong)) blue_selected = False red_selected = False if yellow_selected: # red --> yellow --> green if not s_yellow_selected: red_wrong = True logging.info('r2: ' + str(red_wrong)) yellow_selected = False red_selected = False # 由绿色大方块而产生的错误选择 if green_selected: if blue_selected: # green --> blue --> red if not s_blue_selected: green_wrong = True logging.info('g1: ' + str(green_wrong)) blue_selected = False green_selected = False if yellow_selected: # green --> yellow --> red if not s_yellow_selected: green_wrong = True logging.info('g2: ' + str(green_wrong)) yellow_selected = False green_selected = False # 判断蓝色和黄色小方块的正确和错误选择 if not (s_blue_selected and s_yellow_selected): # 正确选择 if blue_selected and yellow_selected: # 蓝色小方块被选中 if blue_time - yellow_time < 0: s_rect_blue.opacity = 0 s_blue_selected = True RT_blue = abs(blue_time - yellow_time) logging.info('b: ' + str(RT_blue)) else: # 绿色小方块被选中 s_rect_yellow.opacity = 0 s_yellow_selected = True RT_yellow = abs(blue_time - yellow_time) logging.info('y: ' + str(RT_yellow)) yellow_selected = False blue_selected = False # 由蓝色大方块产生的错误选择 if blue_selected: if red_selected: # blue --> red --> yellow if not s_red_selected: blue_wrong = True logging.info('b1: ' + str(blue_wrong)) red_selected = False blue_selected = False if green_selected: # blue --> green --> yellow if not s_green_selected: blue_wrong = True logging.info('b2: ' + str(blue_wrong)) green_selected = False blue_selected = False # 由黄色大方块产生的错误选择 if yellow_selected: if red_selected: # yellow --> red --> blue if not s_red_selected: yellow_wrong = True logging.info('y1: ' + str(yellow_wrong)) red_selected = False yellow_selected = False if green_selected: # yellow --> green --> blue if not s_green_selected: yellow_wrong = True logging.info('y2: ' + str(yellow_wrong)) green_selected = False yellow_selected = False # 如果小方块没有被选择,判断其是否移动出屏幕之外 # 如果是,则标记True,并返回相应的反应时为None值 if s_rect_red.pos[1] < -1080 and not s_red_selected: s_red_out = True RT_red = 'NA' if s_rect_green.pos[1] < -1080 and not s_green_selected: s_green_out = True RT_green = 'NA' if s_rect_blue.pos[1] < -1080 and not s_blue_selected: s_blue_out = True RT_blue = 'NA' if s_rect_yellow.pos[1] < -1080 and not s_yellow_selected: s_yellow_out = True RT_yellow = 'NA' # 定义试次结束的条件 # 以选中和未选中(错过)小方块的数量,作“组合”计算 # 选中0,错过1,C(4, 0) = 1种可能 if s_red_out and s_green_out and s_blue_out and s_yellow_out: # 0 selected, miss 4 break # 选中4,错过0,C(4, 4) = 1种可能 elif s_red_selected and s_green_selected and s_blue_selected and s_yellow_selected: # 4 selected, miss 0 break # 选中1,错过3,C(4, 1) = 4种可能 elif s_red_selected and s_green_out and s_blue_out and s_yellow_out: # 1 red selected, miss 3 break elif s_green_selected and s_red_out and s_blue_out and s_yellow_out: # 1 green selected, miss 3 break elif s_blue_selected and s_red_out and s_green_out and s_yellow_out: # 1 blue selected, miss 3 break elif s_yellow_selected and s_red_out and s_green_out and s_blue_out: # 1 yellow selected, miss 3 break # 选中2,错过2,C(4, 2) = 6种可能 elif s_red_selected and s_green_selected and s_blue_out and s_yellow_out: # 2 red, green selected, miss 2 break elif s_red_selected and s_blue_selected and s_green_out and s_yellow_out: # 2 red, blue selected, miss 2 break elif s_red_selected and s_yellow_selected and s_green_out and s_blue_out: # 2 red, yellow selected, miss 2 break elif s_green_selected and s_blue_selected and s_red_out and s_yellow_out: # 2 green, blue selected, miss 2 break elif s_green_selected and s_yellow_selected and s_red_out and s_blue_out: # 2 green, yellow selected, miss 2 break elif s_blue_selected and s_yellow_selected and s_red_out and s_green_out: # 2 blue, yellow selected, miss 2 break # 选中3,错过1,C(4, 3) = 4种可能 elif s_red_selected and s_green_selected and s_blue_selected and s_yellow_out: # 3 r, g, b selected, miss 1 break elif s_red_selected and s_green_selected and s_yellow_selected and s_blue_out: # 3 r, g, y selected, miss 1 break elif s_red_selected and s_blue_selected and s_yellow_selected and s_green_out: # 3 r, b, y selected, miss 1 break elif s_green_selected and s_blue_selected and s_yellow_selected and s_red_out: # 3 g, b, y selected, miss 1 break # 结束While循环时,计算试次所需要的时间 trial_time = core.getTime() - t el_tracker.sendMessage('BLANK_SCREEN') clear_screen(win) core.wait(0.5) # send a message to clear the Data Viewer el_tracker.sendMessage('!V CLEAR 128 128 128') # close the IAS file ias_file.close() # record trial variables to the EDF data file el_tracker.sendMessage('!V TRIAL_VAR s_red_selected %s' % s_red_selected) el_tracker.sendMessage('!V TRIAL_VAR s_blue_selected %s' % s_blue_selected) el_tracker.sendMessage('!V TRIAL_VAR s_green_selected %s' % s_green_selected) el_tracker.sendMessage('!V TRIAL_VAR s_yellow_selected %s' % s_yellow_selected) pylink.msecDelay(4) # take a break of 4 millisecond el_tracker.sendMessage('!V TRIAL_VAR s_red_out %s' % s_red_out) el_tracker.sendMessage('!V TRIAL_VAR s_blue_out %s' % s_blue_out) el_tracker.sendMessage('!V TRIAL_VAR s_green_out %s' % s_green_out) el_tracker.sendMessage('!V TRIAL_VAR s_yellow_out %s' % s_yellow_out) pylink.msecDelay(4) # take a break of 4 millisecond el_tracker.sendMessage('!V TRIAL_VAR red_wrong %s' % red_wrong) el_tracker.sendMessage('!V TRIAL_VAR blue_wrong %s' % blue_wrong) el_tracker.sendMessage('!V TRIAL_VAR green_wrong %s' % green_wrong) el_tracker.sendMessage('!V TRIAL_VAR yellow_wrong %s' % yellow_wrong) pylink.msecDelay(4) # take a break of 4 millisecond # send a 'TRIAL_RESULT' message to mark the end of trial el_tracker.sendMessage('TRIAL_RESULT %d' % pylink.TRIAL_OK) # write trial info to CSV red_data = [ trial_index, 'red', s_red_selected, red_wrong, s_red_out, RT_red, trial_time ] sub_data.write(','.join(map(str, red_data)) + '\n') green_data = [ trial_index, 'green', s_green_selected, green_wrong, s_green_out, RT_green, trial_time ] sub_data.write(','.join(map(str, green_data)) + '\n') blue_data = [ trial_index, 'blue', s_blue_selected, blue_wrong, s_blue_out, RT_blue, trial_time ] sub_data.write(','.join(map(str, blue_data)) + '\n') yellow_data = [ trial_index, 'yellow', s_yellow_selected, yellow_wrong, s_yellow_out, RT_yellow, trial_time ] sub_data.write(','.join(map(str, yellow_data)) + '\n')
text.setText("Ready?");text.draw();win.flip() ISI.start(1);ISI.complete() text.setText("Go!");text.draw();win.flip() ISI.start(0.3);ISI.complete() for i in range(len(numlist)): ISI.start(0.3); #0.3 text.setText(str(numlist[i])); text.draw();win.flip() ISI.complete() ISI.start(0.9) #0.9 img.draw();win.flip()#ここの処理速度より早く押してしまうと空判定される rsp = event.getKeys(keyList=["space"]) ISI.complete() if cond !="Control" and i>=2: trial.append(tri); stm = numlist[i] if cond == "Moderate" else numlist[i-1] cnd.append(cond); if rsp == ["space"] and stm != 3: btn.append(1);stimli.append(0); elif rsp == ["space"] and stm == 3: btn.append(1);stimli.append(1); elif rsp == [] and stm != 3: btn.append(0);stimli.append(0);
return visual.ImageStim(win=mywin, image=filename) mywin = visual.Window([1920, 1080], monitor="testMonitor", units="deg", fullscr=True) targets = map(loadImage, glob('stim/target-*.jpg')) nontargets = map(loadImage, glob('stim/nontarget-*.jpg')) for ii, trial in trials.iterrows(): # inter trial interval core.wait(iti + np.random.rand() * jitter) # onset pos = trials['position'].iloc[ii] image = choice(targets if pos == 1 else nontargets) image.draw() timestamp = local_clock() outlet.push_sample([markernames[pos]], timestamp) mywin.flip() # offset core.wait(soa) mywin.flip() if len(event.getKeys()) > 0 or (time() - start) > record_duration: break event.clearEvents() # Cleanup mywin.close()