def image(self, filename): """Filename, including relative or absolute path. The image can be any format that the Python Imaging Library can import (almost any). Can also be an image already loaded by PIL. """ filename = pathToString(filename) self.__dict__['image'] = filename if isinstance(filename, basestring): # is a string - see if it points to a file if os.path.isfile(filename): self.filename = filename im = Image.open(self.filename) im = im.transpose(Image.FLIP_TOP_BOTTOM) else: logging.error("couldn't find image...%s" % filename) core.quit() else: # not a string - have we been passed an image? try: im = filename.copy().transpose(Image.FLIP_TOP_BOTTOM) except AttributeError: # apparently not an image logging.error("couldn't find image...%s" % filename) core.quit() self.filename = repr(filename) # '<Image.Image image ...>' self.size = im.size # set correct formats for bytes/floats if im.mode == 'RGBA': self.imArray = numpy.array(im).astype(numpy.ubyte) self.internalFormat = GL.GL_RGBA else: self.imArray = numpy.array(im.convert("RGB")).astype(numpy.ubyte) self.internalFormat = GL.GL_RGB self.dataType = GL.GL_UNSIGNED_BYTE self._needStrUpdate = True
def startExperiment(): startEEGBox = gui.Dlg(title='waiting for Actiview') startEEGBox.addText('click OK when you are sure ActiView is ready') startEEGBox.show() if startEEGBox.OK == False: core.quit() #now that we made sure that actiview works and receives our triggers, display another dialog box #that will allow us to review and/or set the experimental settings for the run configBox = gui.Dlg(title='Choose settings for this run') configBox.addField('# of repeats', EXPERIMENTAL_SETTINGS['nb_of_repeats'], tip="how many trials per type of trials. remember there are 4 types of trials") configBox.addField(label='Language', initial = EXPERIMENTAL_SETTINGS['language'], color='', choices= ['english', 'french']) configBox.addField(label='Get distances from file name?', initial=True, color='', choices=[True, False], tip='set to true if the names of the stimuli contain a hint to the vectorial distance of the pair. We will recover it with using curly brace parameters on the searchstring setting below') configBox.addField(label="Search String", initial=EXPERIMENTAL_SETTINGS['search_path'], color='', tip="read the READMD.txt or try me: [email protected] if you are not sure :)") configBox.addField(label="Code for 1st category", initial=EXPERIMENTAL_SETTINGS['1st_category_label']) handle = configBox.addField(label="Code for 2nd category", initial=EXPERIMENTAL_SETTINGS['2nd_category_label']) configBox.show() #DEBUG STATEMENT print configBox.data print handle #this represent the window in which the experiment will be displayed display = visual.Window(size=(1024, 760), fullscr=True, monitor = 'testMonitor', color='white') #this is a useful object to manage the order of trials and most of all save data! check the PsychoPy documentation to learn #how to use it! mainHandler = data.ExperimentHandler(version='1.0')
def enterSubjInfo(expName,optionList): """ Brings up a GUI in which to enter all the subject info.""" def inputsOK(optionList,expInfo): for curOption in sorted(optionList.items()): if curOption[1]['options'] != 'any' and expInfo[curOption[1]['name']] not in curOption[1]['options']: return [False,"The option you entered for " + curOption[1]['name'] + " is not in the allowable list of options: " + str(curOption[1]['options'])] print "inputsOK passed" return [True,''] try: expInfo = misc.fromFile(expName+'_lastParams.pickle') except: expInfo={} #make the kind of dictionary that this gui can understand for curOption in sorted(optionList.items()): expInfo[curOption[1]['name']]=curOption[1]['default'] #load the tips tips={} for curOption in sorted(optionList.items()): tips[curOption[1]['name']]=curOption[1]['prompt'] expInfo['dateStr']= data.getDateStr() expInfo['expName']= expName dlg = gui.DlgFromDict(expInfo, title=expName, fixed=['dateStr','expName'],order=[optionName[1]['name'] for optionName in sorted(optionList.items())],tip=tips) if dlg.OK: misc.toFile(expName+'_lastParams.pickle', expInfo) [success,error] = inputsOK(optionList,expInfo) if success: return [True,expInfo] else: return [False,error] else: core.quit()
def setScale(self, units, font='dummyFont', prevScale=[1.0,1.0]): """This method is called from within the draw routine and sets the scale of the OpenGL context to map between units. Could potentially be called by the user in order to draw OpenGl objects manually in each frame. The **units** can be 'norm'(normalised),'pix'(pixels),'cm' or 'stroke_font'. The **font** argument is only used if units='stroke_font' """ if units is "norm": thisScale = scipy.array([1.0,1.0]) elif units in ["pix", "pixels"]: thisScale = 2.0/scipy.array(self.size) elif units is "cm": #windowPerCM = windowPerPIX / CMperPIX # = (window /winPIX) / (scrCm /scrPIX) if (self.scrWidthCM in [0,None]) or (self.scrWidthPIX in [0, None]): print 'you didnt give me the width of the screen (pixels and cm)' core.wait(1.0); core.quit() thisScale = (scipy.array([2.0,2.0])/self.size)/(float(self.scrWidthCM)/float(self.scrWidthPIX)) elif units in ["deg", "degs"]: #windowPerDeg = winPerCM*CMperDEG # = winPerCM * tan(scipy.pi/180) * distance if (self.scrWidthCM in [0,None]) or (self.scrWidthPIX in [0, None]): print 'you didnt give me the width of the screen (pixels and cm)' core.wait(1.0); core.quit() cmScale = (scipy.array([2.0,2.0])/self.size)/(float(self.scrWidthCM)/float(self.scrWidthPIX)) thisScale = cmScale * 0.017455 * self.scrDistCM elif units is "stroke_font": thisScale = scipy.array([2*font.letterWidth,2*font.letterWidth]/self.size/38.0) #actually set the scale as appropriate thisScale = thisScale/scipy.asarray(prevScale)#allows undoing of a previous scaling procedure print 'scale %f %f' %(thisScale[0], thisScale[1]) GL.glScalef(float(thisScale[0]), float(thisScale[1]), 1.0) return thisScale #just in case the user wants to know?!
def __init__(self, settings=None): super(Pursuit, self).__init__() self.global_clock = mono_clock # set up input if settings['mouse']: self.device = Mouse(clock=self.global_clock.getTime) else: core.quit() #self.device = ForceHandle(clock=self.global_clock.getTime) try: #self.trial_table = pd.read_csv(settings['trial_table']) pass except FileNotFoundError: core.quit() # set up display self.win = visual.Window(size=(800, 800), pos=(0, 0), fullscr=settings['fullscreen'], screen=1, units='height', allowGUI=False, colorSpace='rgb', color=(-1, -1, -1), waitBlanking=False) self.win.recordFrameIntervals = True self.setup_visuals() # extras self.data = None self.total_frames = 0 self.frames_on_target = 0
def waitForKeypress(): allKeys = event.getKeys() while len(allKeys)==0: allKeys = event.getKeys() if 'escape' in allKeys[0]: mywin.close() # quit core.quit()
def start_datafile(sn): """creates datafile (after checking for old one)""" # determines file name if sn < 10: snstr = '0' + str(sn) else: snstr = str(sn) datafileName = "experiment_" + snstr + ".csv" currentDirectory = os.listdir("." + os.sep + "Data") for file in currentDirectory: if file == datafileName: warningDialog = gui.Dlg(title="Warning!") warningDialog.addText("A data file with this number already exists.") warningDialog.addField("Overwrite?", choices=["No", "Yes"]) warningDialog.addField("If not, enter new subject number:", initial="0") warningDialog.show() if gui.OK: if warningDialog.data[0] == "No": subjectNumber = int(warningDialog.data[1]) if subjectNumber < 10: snstr = '0' + str(subjectNumber) else: sntstr = str(subjectNumber) datafileName = "experiment_" + snstr + ".csv" else: core.quit() datafile = open("." + os.sep + "Data" + os.sep + datafileName, "ab") datafile.write("subjectnum,runnum,trialnum,trialbegintime,trialduration,trialjitterduration,\ response,responsetime,person,personnum, prefitem, prefnum\n") return(datafile, sn)
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 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 runTrial(self,*args): self.babyStatus=0 # -1 no signal, 0 saccade, 1 fixation, self.sacPerPursuit=0 self.pursuedAgents=False self.rewardIter=0 self.nrRewards=0 self.blinkCount=0 self.tFix=0 self.isFixLast=False self.babySawReward=False ende=False if core.getTime()> BabyExperiment.expDur*60+self.tStart: ende=True if ende: print core.getTime()-self.tStart self.etController.sendMessage('Finished') self.etController.closeConnection() self.wind.close(); core.quit() self.timeNotLooking=0 self.etController.preTrial(driftCorrection=self.showAttentionCatcher>0) self.etController.sendMessage('Trial\t%d'%self.t) self.etController.sendMessage('Phase\t%d'%self.phases[self.pi]) if self.eeg!=None: self.eeg.setData(int(self.t+1)) Experiment.runTrial(self,*args,fixCross=False) self.etController.postTrial()
def get_subject_info(experiment_name, conditions, data_location): ss_info = [] pc = socket.gethostname() my_Dlg = gui.Dlg(title=experiment_name) my_Dlg.addText('Subject Info') my_Dlg.addField('ID:', tip='or subject code') my_Dlg.addField('Condition:', rnd.choice(conditions), choices = conditions) my_Dlg.show() if not my_Dlg.OK: print 'User Terminated' core.quit() subject_info = [str(i) for i in my_Dlg.data] if subject_info[0]=='': core.quit() else: id = subject_info[0] condition = subject_info[1] subject_file = (data_location + pc + '-' + experiment_name + '-' + condition + '-' + id + '.csv') while os.path.exists(subject_file) == True: subject_file = (data_location + pc + '-' + experiment_name + '-' + condition + '-' + id + '.csv' + '_dupe') return [int(id),int(condition),subject_file]
def _show_screen(self, text): visual.TextStim(text=text, **self.screen_text_kwargs).draw() self.win.flip() response = event.waitKeys(keyList=['space', 'q'])[0] if response == 'q': core.quit()
def cleanup(): ''' cleanup function to be called if a KeyboardInterrupt is raised ''' print "control C was pressed. aborting script and cleaning up monitors." core.quit() sys.exit(10)
def on_key_release(k,m): if k == key.SPACE: print 'space up' global writeData global space_down global space_time global famStim global data global click_stim global look_onset global mode global counting global look_away_time if mode == "test" and counting == 0: counting = 1 look_away_time = clock.getTime() elif mode == "get": pass else: space_time = (clock.getTime() - space_down) * 1000 #return time in milliseconds print click_stim, famStim data.append( ( click_stim+"~~"+famStim, str(space_time), "lookingFam" ) ) #data to be written to the output file is added to the data array above on each key release, and some globals are updated, i.e. 'stimuli' are updated as the experiment executes if k == key.ESCAPE: if mode == 'test': escStim = stimuli elif mode == 'famil': escStim = famStim data.append( ( escStim, str( (clock.getTime() - famStart) * 1000), "totalPlaying-Escape" ) ) writeData() win.close() 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 _present_choices(self, oleft, oright, trial): """Present the left and the right outcomes, first at the left and second at the right of fixation. After choice_screen_dur fixation cross is colored red for choice_screen_dur2, user has to respond while the cross is red. If user respond before or after then show the slow-down or too-slow message, otherwise color the outcome pressed yellow for remaining duration. Store all the events in dictionary trial, which is an argument to the method. Return value is the key pressed.""" trial['success'] = False # set to True if user responded on time. start_time = time.time() dist = NUMBER_FIXATION_DIST left_outcome = visual.TextStim(self.win, text=u"\u20AC" + str(oleft) , pos=(-dist, 0)) right_outcome = visual.TextStim(self.win, text=u"\u20AC" + str(oright), pos=(dist, 0)) self._render(left_outcome, right_outcome, self.fixation) # wait for choice_screen_dur and check if user presses left or right key try: key = event.waitKeys(maxWait=CHOICE_SCREEN_DUR, keyList=[LEFT_KEY, RIGHT_KEY, ESC_KEY])[0] except: key = "none" #usr responded too early show her slow down message and return if key in [LEFT_KEY, RIGHT_KEY]: trial['slow_down_msg_event'] = time.time() trial['too_fast'] = True self._render(slow_down_msg, duration=SLOW_DOWN_MSG_DUR) return key if key == ESC_KEY: self.win.close() core.quit() # turn the fixation cross red and wait for 1 sec for a user to respond trial['fixation_color_red_event'] = time.time() self.fixation.color = "red" self._render(left_outcome, right_outcome, self.fixation) try: key = event.waitKeys(maxWait=CHOICE_SCREEN_DUR2, keyList=[LEFT_KEY, RIGHT_KEY])[0] trial['key_pressed_event'] = time.time() except: key = "none" self.fixation.color = "black" # user did not responded, show too slow msg and return. if key == "none": trial['too_slow'] = True trial['too_slow_msg_event'] = time.time() self._render(too_slow_msg, duration=TOO_SLOW_MSG_DUR) return key #show the pressed key in yellow for the remaining time. if key == LEFT_KEY: left_outcome.color = "yellow" elif key == RIGHT_KEY: right_outcome.color = "yellow" self._render(left_outcome, right_outcome, self.fixation) time_elasped = time.time() - start_time core.wait(CHOICE_SCREEN_DUR + CHOICE_SCREEN_DUR2 - time_elasped) return key
def run_calibration(): # display instructions set_msg('SET SOUND LEVEL','TITLE') set_msg('press up and down to increase/decrease sound level and press enter when level is confortable','MAIN') set_msg('Press return to continue','KEY') win.flip() # prepare calibration sound s = sound_build.make_lp_noise(100000,3000,Exp.rate) vol = 0.5 playsound(s,vol,200) pressEnter = False while pressEnter==False: allKeys=event.waitKeys() for thisKey in allKeys: if thisKey=='up': pygame.mixer.music.set_volume(pygame.mixer.music.get_volume()+0.03) print(pygame.mixer.music.get_volume()) elif thisKey=='down': pygame.mixer.music.set_volume(pygame.mixer.music.get_volume()-0.03) print(pygame.mixer.music.get_volume()) elif thisKey in ['return']: pressEnter = True elif thisKey in ['q', 'escape']: core.quit() #abort experiment event.clearEvents() #must clear other (eg mouse) events - they clog the buffer vol = pygame.mixer.music.get_volume() pygame.mixer.music.stop() return vol
def present(self, start=None, stop=None): if not isinstance(start, int): start = self.this_page if not isinstance(stop, int): stop = len(self.pages) # show pages: self.this_page = start while self.this_page < stop: # create page elements self.create_page() self.show_page() # wait for response if not self.auto: k = event.waitKeys(keyList=self.navigation.keys() + ['q'])[0] if 'q' in k: core.quit() action = self.navigation[k] else: core.wait(0.15) action = 'next' # go next/prev according to the response if action == 'next': self.this_page += 1 else: self.this_page = max(0, self.this_page - 1)
def runVerbalFluency(win, ask, test, language): try: output = { "A" : { "English" : FormAEng, "French" : FormAFr }, "B" : { "English" : FormBEng, "French" : FormBFr }, "C" : { "English" : FormCEng, "French" :FormCFr } } instructions = output[test][language] stopSign = visual.SimpleImageStim(win, image = stopSignPath, units='norm', pos=(0.0, 0.0)) #Stop Sign ding = sound.Sound(audioPath) ding.setVolume(1.0) ask(instructions) timer = core.CountdownTimer(60) while timer.getTime() > 0: # after 60s will become negative win.flip() ding.play() #instructionText.draw(win) responses = event.waitKeys(timeStamped=False) if 'q' in responses: print 'Program aborted...' core.quit() elif 's' in responses: print "Skipped experiment" return else: win.flip() ding.play() stopSign.draw(win) ask() except KeyboardInterrupt: raise core.quit()
def GetResponse(): global currentRule, currentTgt, ruleCount, rightAnswers, gameScore event.clearEvents() retVal = 0 #if not modified, breaks the task answerPressed = -1 # which card was selected? keylist = { 'down': ['down', '2'], 'left': ['left', '4'], 'up': ['up', '8'], 'right': ['right', '6']} keys = event.waitKeys(keyList=['f10', 'escape', 'up', 'right', 'down', 'left', '2', '4', '6', '8']) if keys[0] == 'f10': triggerAndLog(portCodes['stop'], "STP", 0, 0, "STOP: aborted by F10") win.close() core.quit() if keys[0] == 'escape': retVal = 0 #elif keys[0] == 'up': elif keys[0] in keylist['up']: if CheckCard( 0, currentRule, currentTgt ): rightAnswers += 1 retVal = 1 else: retVal = -1 #elif keys[0] == 'right': elif keys[0] in keylist['right']: if CheckCard( 1, currentRule, currentTgt ): rightAnswers += 1 retVal = 2 else: retVal = -2 #elif keys[0] == 'down': elif keys[0] in keylist['down']: if CheckCard( 2, currentRule, currentTgt ): rightAnswers += 1 retVal = 3 else: retVal = -3 #elif keys[0] == 'left': elif keys[0] in keylist['left']: if CheckCard( 3, currentRule, currentTgt ): rightAnswers += 1 retVal = 4 else: retVal = -4 idx=str(rules.index(currentRule)+1) if retVal > 0: gameScore += 1 triggerAndLog( portCodes['respRight'] + portCodes['rule'+idx],\ "RSP", currentBlock, currentTrial, 'RESPONSE 1 ' + currentRule + ' ANSWER ' + str(retVal) ) elif retVal < 0: gameScore -= 1 triggerAndLog( portCodes['respWrong'] + portCodes['rule'+idx],\ "RSP", currentBlock, currentTrial, 'RESPONSE 0 ' + currentRule + ' ANSWER ' + str(retVal) ) return retVal
def showText(myWin, textToShow, fontFace): """Display text on screen (e.g., instructions for participants).""" try: textClock except NameError: textClock = core.Clock() else: textClock.reset() textStim = visual.TextStim(myWin, text=textToShow, color='black', font=fontFace, height=1) continueInstruct = True while continueInstruct: # Get current time t = textClock.getTime() # Update/draw components on each frame if (0 <= t): textStim.draw() if (0 <= t): keypresses = event.getKeys() if len(keypresses) > 0: # At least one key was pressed. # Abort routine on response continueInstruct = False # Check for quit (the [Esc] key). if keypresses[0] == "escape": core.quit() # Refresh the screen myWin.flip()
def close(self): if not TESTING and self.mark_mode == "Plexon": self.plexon.CloseClient() if self.input_mode == "RTBox": self.RTBox.close() self.mark_task("end") core.quit()
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 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 cleanup(self): """ Destructor """ #STOP CLOCKS self.window.setRecordFrameIntervals(False) #stop recording frame intervals self.stoptime = time.clock() #TIME SENSITIVE STUFF ENDS HERE #FLIP FOR SYNC SQUARE CLEAR for i in range(30): self.window.flip() timestr = str(datetime.timedelta(seconds = (self.stoptime-self.starttime))) print "Actual experiment duration:", timestr self.stopdatetime = datetime.datetime.now() #DISPLAY SOME STUFF print "Actual sweeps completed:", str(self.sweepsdisplayed) self.printFrameInfo() #LOG INFORMATION (If not in replay mode) if not self.replay: self.logMeta() #CLOSE EVERYTHING if self.ni: self.dOut.WriteBit(self.sweepBit, 0) #ensure sweep bit is low self.dOut.WriteBit(self.frameBit, 0) #ensure frame bit is low self.dOut.ClearTask() #clear NIDAQ self.window.close() core.quit()
def trial(city_left, city_right): """ City-size paired comparison task """ leftTS.text = city_left rightTS.text = city_right questionTS.draw() fixpoint.draw() leftTS.draw() rightTS.draw() win.flip() timer.reset() response = None while response not in [city_left, city_right]: pressed_key = event.waitKeys(timeStamped=timer) if pressed_key[0][0] in ['q', 'escape']: core.quit() if pressed_key[0][0] == 'less': response = city_left if pressed_key[0][0] == 'minus': response = city_right questionTS.draw() fixpoint.draw() win.flip() core.wait(0.4) ## Save data datfile.write('%s;%s;%s;%1.4f\n' % (city_left, city_right, response, pressed_key[0][1]))
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 text_and_stim_keypress(self, text, stim=None): if stim is not None: if type(stim) == list: map(lambda x: x.draw(), stim) else: stim.draw() display_text = visual.TextStim(self.win, text=text, font='Helvetica', alignHoriz='center', alignVert='center', units='norm', pos=(0, 0), height=0.1, color=[255, 255, 255], colorSpace='rgb255', wrapWidth=2) display_text.draw() self.win.flip() key = event.waitKeys() if key[0] == 'escape': self.trigger.flicker_block(0) # Save end data t = datetime.now() day_time = '%d:%d:%d:%d' % (t.hour, t.minute, t.second, t.microsecond) end_time = globalTimer.getTime() save_data(day_time, end_time, self.subjnum) core.quit() self.win.flip() self.win.flip()
def setCup(pp): global button global cupBuffer sN = pp rtClock = core.Clock() while True: key = event.getKeys(keyList = ['q','escape']) if len(key) > 0: core.quit() mX, mY = mouse.getPos() if mX > buttonX[0] and mX < buttonX[1] and mY > buttonY[0] and mY < buttonY[1]: #Checks to see if "Next" button was pressed set_mouse_position(win,0,0) break if mY < (slotY-(slotHeight/2)) and mY > -(screenY*.2): sN1 = getSlot(mX,mY,slotSpread) if sN1 !=None: sN = sN1 if sN == 0: sN = 1 elif sN == 40: sN = 39 plinkoTable.draw() button.draw() buttonText.draw() ball.draw() drawCup(slotPos[sN][0]) drawPbar(totalPoints,maxScore) win.flip() rt = rtClock.getTime() plinkoTable.draw() drawCup(slotPos[sN][0]) drawPbar(totalPoints,maxScore) cupBuffer = visual.BufferImageStim(win) return sN,rt
def CoolDown(): # display cool-down message message1.setText("That's the end! ") message2.setText("Press 'q' or 'escape' to end the session.") win.logOnFlip(level=logging.EXP, msg='Display TheEnd') win.callOnFlip(SendMessage,'DisplayTheEnd') message1.draw() message2.draw() win.flip() thisKey = event.waitKeys(keyList=['q','escape']) """ # stop recording SMI via serial port myTracker.stop_recording() # save result myTracker.save_data(path=(filename+'.idf')) # close serial port myTracker.cleanup() """ #""" # End EyeLink recording: add 100 msec of data to catch final events pylink.endRealTimeMode() pumpDelay(100) getEYELINK().stopRecording() while getEYELINK().getkey(): # not sure what this is for pass # File transfer and cleanup! getEYELINK().setOfflineMode() msecDelay(500) message1.setText("Sending EyeLink File...") message2.setText("Please Wait.") win.logOnFlip(level=logging.EXP, msg='Display SendingFile') message1.draw() message2.draw() win.flip() #Close the file and transfer it to Display PC getEYELINK().closeDataFile() getEYELINK().receiveDataFile(edfHostFileName, edfFileName) getEYELINK().close(); #Close the experiment graphicss pylink.closeGraphics() #""" # stop sound # fullSound.stop() whiteNoiseSound.stop() pageSound.stop() # save experimental info (if we reached here, we didn't have an error) expInfo['tSound'] = tSound toFile(expInfoFilename, expInfo) # save params to file for next time # exit core.quit()
def get_specs(subj_name='mmddyyn_wmLoadMem02'): """Opens a GUI to set up the experiment """ dictDlg = gui.DlgFromDict( { 'Participant number': '05dd181_sustAttnWM03', #subject name: month, day, year, number, and project name 'Environment': [ 'imac', 'booth', 'edslab' ], #which environment (aka monitor name in Tools > Monitor Center) 'Restarting experiment?': False, #whether restarting an experiment that was aborted in the middle 'Debug': False, #whether instructions are in english 'Picture game': True, 'Block game': True }, title='Welcome to the experiment', #title for GUI fixed=[' '], order=[ 'Participant number', 'Environment', 'Restarting experiment?', 'Debug' ]) #choose order of elements if dictDlg.OK == True: gui_specs = {} gui_specs['subj_name'] = str(dictDlg.data[0]) gui_specs['env'] = dictDlg.data[1] gui_specs['restarting'] = dictDlg.data[2] gui_specs['expt_date'] = datetime.now().strftime("%m/%d/%Y %H:%M") gui_specs['debug'] = dictDlg.data[3] gui_specs['seed'] = int(time.time()) gui_specs['sustattn'] = dictDlg.data[4] gui_specs['changedetect'] = dictDlg.data[5] else: core.quit() #check the specs assert isinstance( gui_specs['subj_name'], basestring), "subj_name is not an string: %r" % specs['subj_name'] assert isinstance(gui_specs['env'], basestring), "env is not a string: %r" % specs['env'] assert isinstance( gui_specs['expt_date'], basestring), "expt_date is not a string: %r" % specs['expt_date'] assert isinstance(gui_specs['seed'], int), "seed is not a int: %r" % specs['seed'] #which environment is being used to run the experiment if gui_specs['env'] == 'imac': gui_specs[ 'project_dir'] = '/Users/megan/Documents/projects/sustAttnWM03/' elif gui_specs['env'] == 'booth': gui_specs[ 'project_dir'] = 'C:/Users/AwhVogelLab/Desktop/Megan/sustAttnWM03/' elif gui_specs['env'] == 'edslab': gui_specs[ 'project_dir'] = '/Users/edslab/Documents/projects/sustAttnWM03/' else: print 'ERROR: unknown environment selected in the GUI' #which directory to use to save the data gui_specs['save_dir'] = gui_specs['project_dir'] + 'subjects/' + gui_specs[ 'subj_name'] + '/data/beh/' #if the directory where data will be saved does not exist yet if not os.path.isdir(gui_specs['save_dir']): print "saving files to: ", gui_specs['save_dir'] os.makedirs( gui_specs['save_dir']) #this command can make multiple subfolders return gui_specs
import sys reload(sys) sys.setdefaultencoding('utf8') import pandas as pd import feedback_ansl as feedback import screening_ansl as screening # Ensure that relative paths start from the same directory as this script _thisDir = os.path.dirname(os.path.abspath(__file__)).decode(sys.getfilesystemencoding()) os.chdir(_thisDir) expInfo = {'participant':'', 'directory':'/home/michael/ANSL/questionnaires/data'} dlg = gui.DlgFromDict(dictionary=expInfo, title='questionaire') if dlg.OK == False: core.quit() # user pressed cancel expInfo['date'] = data.getDateStr() # add a simple timestamp save_path = expInfo['directory'] print(save_path) # defines layout of hui gui and updates status of questionnaires after each run def update(field1, field2): # creates starting gui myDlg = gui.Dlg(title=u'questionaires') myDlg.addText(u'status: o = noch ausstehend x = erledigt\n') # prompts static text field showing the status of each questionaire myDlg.addText(field1 + ' demographisch') myDlg.addText(field2 + ' feedback') # create empty list to append to
def sprTrial(sentence): """ Experiment trial. """ # Clear any key log. deadlineClock = core.Clock() # Decode sentence before presentation if using Unicode. #sentence = map(decode_unicode, sentence) # Display fixation point. fixation = visual.TextStim(stim_window, text='+', pos=(0.0, 0.0), bold=True, height=0.15) fixation.draw() stim_window.flip() core.wait(fix_time) stim_window.flip() # Display sentence word-by-word, but allow the final word to be distinct font or color. event.clearEvents() deadlineClock.reset() response = [] current_word_position = 1 for word in sentence: current_word_response = [] while len(current_word_response ) == 0 and deadlineClock.getTime() < deadline: stim = visual.TextStim(stim_window, text=word, pos=(0.0, 0.0), bold=True, height=0.15) stim.draw() stim_window.flip() current_word_response = event.getKeys(keyList=["space", "escape"]) current_rt = deadlineClock.getTime() if deadlineClock.getTime() > deadline: timeout_feedback.draw() stim_window.flip() core.wait(1) stim_window.flip() response.append([word, current_word_position, 'NA', 'NA']) break elif "escape" in current_word_response: core.quit() else: response.append( [word, current_word_position, round(1000 * current_rt), 'NA']) current_word_position += 1 core.wait(between_words_time) deadlineClock.reset() event.clearEvents() return response
answer1.draw() answer2.draw() stim_window.flip() answer = event.getKeys(keyList=["f", "j", "escape"]) answer_rt = deadlineClock.getTime() if deadlineClock.getTime() > qDeadline: timeout_feedback.draw() stim_window.flip() core.wait(1) stim_window.flip() response = ['QUESTION', 'NA', 'NA', 'NA'] if "escape" in answer: core.quit() else: response = [ 'NA', 'NA', round(1000 * answer_rt), int(correct_response in answer) ] return response ##### RUNTIME ################################################################# practice() main() stim_window.close() core.quit()
def check_input(self): keys = event.getKeys() if 'space' in keys: self._manager.set_audio_scene() elif 'escape' in keys: core.quit()
def check_exit(): #abort if esc was pressed if event.getKeys('escape'): win.close() core.quit()
def quit(self): self.myoHub.close() core.quit()
def launchScan(win, settings, globalClock=None, simResponses=None, mode=None, esc_key='escape', instr='select Scan or Test, press enter', wait_msg="waiting for scanner...", wait_timeout=300, log=True): """ Accepts up to four fMRI scan parameters (TR, volumes, sync-key, skip), and launches an experiment in one of two modes: Scan, or Test. :Usage: See Coder Demo -> experiment control -> fMRI_launchScan.py. In brief: 1) from psychopy.hardware.emulator import launchScan; 2) Define your args; and 3) add 'vol = launchScan(args)' at the top of your experiment script. launchScan() waits for the first sync pulse and then returns, allowing your experiment script to proceed. The key feature is that, in test mode, it first starts an autonomous thread that emulates sync pulses (i.e., emulated by your CPU rather than generated by an MRI machine). The thread places a character in the key buffer, exactly like a keyboard event does. launchScan will wait for the first such sync pulse (i.e., character in the key buffer). launchScan returns the number of sync pulses detected so far (i.e., 1), so that a script can account for them explicitly. If a globalClock is given (highly recommended), it is reset to 0.0 when the first sync pulse is detected. If a mode was not specified when calling launchScan, the operator is prompted to select Scan or Test. If **scan mode** is selected, the script will wait until the first scan pulse is detected. Typically this would be coming from the scanner, but note that it could also be a person manually pressing that key. If **test mode** is selected, launchScan() starts a separate thread to emit sync pulses / key presses. Note that this thread is effectively nothing more than a key-pressing metronome, emitting a key at the start of every TR, doing so with high temporal precision. If your MR hardware interface does not deliver a key character as a sync flag, you can still use launchScan() to test script timing. You have to code your experiment to trigger on either a sync character (to test timing) or your usual sync flag (for actual scanning). :Parameters: win: a :class:`~psychopy.visual.Window` object (required) settings : a dict containing up to 5 parameters (2 required: TR, volumes) TR : seconds per whole-brain volume (minimum value = 0.1s) volumes : number of whole-brain (3D) volumes to obtain in a given scanning run. sync : (optional) key for sync timing, default = '5'. skip : (optional) how many volumes to silently omit initially (during T1 stabilization, no sync pulse). default = 0. sound : (optional) whether to play a sound when simulating scanner sync pulses globalClock : optional but highly recommended :class:`~psychopy.core.Clock` to be used during the scan; if one is given, it is reset to 0.000 when the first sync pulse is received. simResponses : optional list of tuples [(time, key), (time, key), ...]. time values are seconds after the first scan pulse is received. esc_key : key to be used for user-interrupt during launch. default = 'escape' mode : if mode is 'Test' or 'Scan', launchScan() will start in that mode. instr : instructions to be displayed to the scan operator during mode selection. wait_msg : message to be displayed to the subject while waiting for the scan to start (i.e., after operator indicates start but before the first scan pulse is received). wait_timeout : time in seconds that launchScan will wait before assuming something went wrong and exiting. Defaults to 300sec (5 minutes). Raises a TimeoutError if no sync pulse is received in the allowable time. """ if not 'sync' in settings: settings.update({'sync': '5'}) if not 'skip' in settings: settings.update({'skip': 0}) try: wait_timeout = max(0.01, float(wait_timeout)) except ValueError: raise ValueError("wait_timeout must be number-like, but instead it was %s." % str(wait_timeout)) settings['sync'] = unicode(settings['sync']) settings['TR'] = float(settings['TR']) settings['volumes'] = int(settings['volumes']) settings['skip'] = int(settings['skip']) runInfo = "vol: %(volumes)d TR: %(TR).3fs skip: %(skip)d sync: '%(sync)s'" % (settings) if log: # pragma: no cover logging.exp('launchScan: ' + runInfo) instructions = visual.TextStim(win, text=instr, height=.05, pos=(0,0), color=.4, autoLog=False) parameters = visual.TextStim(win, text=runInfo, height=.05, pos=(0,-0.5), color=.4, autoLog=False) # if a valid mode was specified, use it; otherwise query via RatingScale: mode = str(mode).capitalize() if mode not in ['Scan', 'Test']: run_type = visual.RatingScale(win, choices=['Scan', 'Test'], marker='circle', markerColor='DarkBlue', size=.8, stretch=.3, pos=(0.8,-0.9), markerStart='Test', lineColor='DarkGray', autoLog=False) while run_type.noResponse: instructions.draw() parameters.draw() run_type.draw() win.flip() if event.getKeys([esc_key]): break mode = run_type.getRating() doSimulation = bool(mode == 'Test') win.mouseVisible = False if doSimulation: wait_msg += ' (simulation)' msg = visual.TextStim(win, color='DarkGray', text=wait_msg, autoLog=False) msg.draw() win.flip() event.clearEvents() # do before starting the threads if doSimulation: syncPulse = SyncGenerator(**settings) syncPulse.start() # start emitting sync pulses core.runningThreads.append(syncPulse) if simResponses: roboResponses = ResponseEmulator(simResponses) roboResponses.start() # start emitting simulated user responses core.runningThreads.append(roboResponses) # wait for first sync pulse: timeoutClock = core.Clock() # zeroed now allKeys = [] while not settings['sync'] in allKeys: allKeys = event.getKeys() if esc_key and esc_key in allKeys: # pragma: no cover core.quit() if timeoutClock.getTime() > wait_timeout: raise TimeoutError('Waiting for scanner has timed out in %.3f seconds.' % wait_timeout) if globalClock: globalClock.reset() if log: # pragma: no cover logging.exp('launchScan: start of scan') win.flip() # blank the screen on first sync pulse received elapsed = 1 # one sync pulse has been caught so far return elapsed
def main(): # open up data file + gui expInfo = {'Participant': 0, 'Gender': ['Male', 'Female'], 'Age': 0} expInfo['dateStr'] = data.getDateStr() dlg = gui.DlgFromDict(expInfo, title="Participant Info", fixed=['dateStr'], order=['Participant', 'Age', 'Gender']) if dlg.OK: LogFile = "SP_participantInfo" infoFile = open('data/' + LogFile + '.csv', 'a') infoFile.write('%s,%s,%s,%s\n' % (expInfo['Participant'], expInfo['Gender'], expInfo['Age'], expInfo['dateStr'])) infoFile.close() else: core.quit() fileName = 'Participant' + str( expInfo['Participant']) + '_SP' # + expInfo['dateStr'] global dataFile, win, patchCols, maskTex, fix, instrText, instrImage dataFile = open('data/' + fileName + '.csv', 'w') dataFile.write( 'Trial, SetSize, Cond, testChange, respChange, RT, study, test\n') win = visual.Window([1024, 768], fullscr=True, allowGUI=False, units='deg', monitor='testMonitor') patchCols = [ colours[col] for col in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 4, 6, 7, 2, 5, 1] ] # random.sample([colours[col] for col in range(Nstim)*2], 16) maskTex = numpy.array(patchCols).reshape((4, 4, 3)) fix = visual.TextStim(win, text='+', color="black", height=1, pos=[0, 0]) instrText = visual.TextStim(win, color="black", height=1, pos=[0, 0], wrapWidth=30) # before each trial instrImage = visual.ImageStim(win, contrast=1, pos=[0, 5]) # before each block # determine block order - following Donkin et al (2013) blockList = [] for i in range(3): for j in random.sample([.3, .5, .7], 3): blockList.append(j) # main experimental trials for block in range(len(blockList)): pc = blockList[block] trials = genBlock(Ns, blockList[block], trialsPerBlock) # instruction screen + image (pie chart) instrImage.setImage('images/pie' + str(int(pc * 100)) + '.png') instrImage.draw() instr( "In this block there is a %s%% chance that one square has changed colour between study and test.\n\n\nPress %s for SAME or %s for CHANGE\n\n\nPress any key to start." % (int(pc * 100), SameKey, ChangeKey)) win.flip() core.wait(.5) trialSeq(trials) if block < len(blockList) - 1: instr('End of block\n\n\nPress any key to begin next block') else: instr('End of Experiment\n\n\nThank you for taking part!')
from psychopy.constants import * # things like STARTED, FINISHED import numpy as np # whole numpy lib is available, prepend 'np.' from numpy import sin, cos, tan, log, log10, pi, average, sqrt, std, deg2rad, rad2deg, linspace, asarray from numpy.random import random, randint, normal, shuffle import os # handy system and path functions from psychopy.hardware.emulator import launchScan import time # Ensure that relative paths start from the same directory as this script _thisDir = os.path.dirname(os.path.abspath(__file__)) os.chdir(_thisDir) # Store info about the experiment session expName = u'test2' # from the Builder filename that created this script expInfo = {u'session': u'001', u'participant': u''} dlg = gui.DlgFromDict(dictionary=expInfo, title=expName) if dlg.OK == False: core.quit() # user pressed cancel expInfo['date'] = data.getDateStr() # add a simple timestamp expInfo['expName'] = expName # MRI INFORMATION FOR SYNCHRONIZATION MR_settings = { 'TR': 2.000, # duration (sec) per volume 'volumes': 5, # number of whole-brain 3D volumes / frames 'sync': 'equal', # character to use as the sync timing event; assumed to come at start of a volume 'skip': 0, # number of volumes lacking a sync pulse at start of scan (for T1 stabilization) 'sound': False # in test mode only, play a tone as a reminder of scanner noise } # DISPLAY PARAMETERS FOR THE USER TO CONFIRM
#------------------------------ #get values from dialog expName = 'Rest' myDlg = gui.Dlg(title=expName, pos=(860, 340)) myDlg.addField(label='Participant', initial=0, tip='Participant name or code'), myDlg.addField(label='Duration', choices=(3, 5, 10), tip='Minutes'), myDlg.addField(label='Show', choices=('nothing', 'photo', 'beach', 'earth', 'forest')), myDlg.addField(label='Hz', choices=(144, 60), tip='Refresh Rate') myDlg.addField(label='Triggers', initial='Yes', choices=['Yes', 'No'], tip='Send Parallel Port Triggers') dlg_data = myDlg.show() if myDlg.OK == False: core.quit() #user pressed cancel #store values from dialog expInfo = { 'Participant': dlg_data[0], 'Duration': dlg_data[1], 'Show': dlg_data[2], 'Hz': dlg_data[3], 'Triggers': dlg_data[4] } expInfo['date'] = data.getDateStr() #add a simple timestamp expInfo['expName'] = expName #----------------------- #setup files for saving #-----------------------
def trialSeq(block): nDone = 0 for thisTrial in block: # # # SET-UP TRIAL (done before time critical stuff) # extract relevant information for trial N = thisTrial['SetSize'] ttype = thisTrial['SoC'] pChange = thisTrial['pChange'] # create trial stimuli and masks trialMasks = [] trialStim = [] for s in range(N): trialStim.append(visual.Rect(win, width=stimSize, height=stimSize)) trialMasks.append( visual.GratingStim(win, tex=maskTex, mask=None, size=stimSize, sf=1.0 / stimSize, texRes=256)) # select trial locations trialLocs = [] for i in range(N): works = 0 while works < 1: # while we havent got a location that works (i.e. is not more than 2 deg from others...) candidate = [ random.uniform(widthLim[0], widthLim[1]), random.uniform(heightLim[0], heightLim[1]) ] # generate random candidate close = 0 # test is this close if numpy.sqrt((candidate[0])**2 + (candidate[1])**2 ) > locSep: # if candidate is far from centre for loc in trialLocs: dist = numpy.sqrt((loc[0] - candidate[0])**2 + (loc[1] - candidate[1])**2) if dist < locSep: # if the candidate location is near an already sampled one... close += 1 else: close += 1 if close == 0: # if the candidate is not close to any trialLocs.append(candidate) # add to trial list works += 1 # this one works... # place trial stimuli in location for s in range(N): trialStim[s].setPos(trialLocs[s]) trialMasks[s].setPos(trialLocs[s]) # select study stimuli (indices to store later) study = random.sample(range(Nstim), N) # randomly choose an item to change (for use if trial == 'change') testItem = random.choice(range(N)) # select a colour to change to (for use if trial == 'change') newItem = random.choice([x for x in range(Nstim) if x not in study]) test = study[testItem] if ttype == 'c': # if trial == 'change' test = newItem # new colour in place of the old # # # MAIN TRIAL SEQUENCE instrText.setText('Ready - %s%% chance of a change' % (int(pChange * 100))) # 1000 ms warning (with reminder of change probability) for fr in range(frameRate): instrText.draw() win.flip() # 1000 ms fixation for fr in range(frameRate): fix.draw() win.flip() # set study colours for s in range(N): trialStim[s].setLineColor(colours[study[s]]) trialStim[s].setFillColor(colours[study[s]]) # present study array for 500 ms for fr in range(frameRate / 2): [trialStim[i].draw() for i in range(N)] win.flip() # 500 ms blank screen for fr in range(frameRate / 2): win.flip() # present masks for 500 ms for fr in range(frameRate / 2): [trialMasks[i].draw() for i in range(N)] win.flip() # # set test colours + draw # for s in range(N): # trialStim[s].setLineColor(colours[test[s]]) # trialStim[s].setFillColor(colours[test[s]]) # [trialStim[i].draw() for i in range(N)] # present single central probe testStim = visual.Rect(win, width=stimSize, height=stimSize, pos=testLoc, lineColor=colours[test], fillColor=colours[test]) testStim.draw() RT.reset() # start RT counter and present test win.flip() # # # COLLECT RESPONSE event.clearEvents(eventType='keyboard') keyP = 0 while keyP == 0: for key in event.getKeys(): if key in [SameKey]: ans = 0 keyP += 1 elif key in [ChangeKey]: ans = 1 keyP += 1 elif key in [quitKey]: core.quit() # to test - comment above lines and uncomment below # core.wait(.5); ans = random.choice([1, 0]) reactionTime = RT.getTime() nDone += 1 # # # WRITE TO CSV dataFile.write('%i,%i,%.4f,%i,%i,%.4f,%s,%s\n' % (nDone, N, pChange, int(ttype == 'c'), ans, reactionTime, ''.join(str(x) for x in study), str(test)))
def __init__(self, params=None, reportobj=None, subroutines=[]): logging.LogFile(params['cwd'] + os.sep + params['logfile'], level=logging.INFO, filemode='w') logging.LogFile(level=logging.ERROR) logging.info('Using Python ' + sys.version) self.args = sys.argv self.params = self.update_params(self.args, params) self.win = None self.model = None self.routines = subroutines self.thisExp = None self.name = params['name'] self.cwd = params['cwd'] self.reportobj = reportobj if params['monitor'] not in monitors.getAllMonitors(): logging.error('monitor not found: ' + params.monitor) logging.info('available monitors: ' + ' '.join(monitors.getAllMonitors())) logging.info('Define monitor in monitor center.') logging.info('To launch monitor center, type:\n' 'python -m psychopy.monitors.MonitorCenter') core.quit() else: self.monitor = monitors.Monitor( '', width=None, distance=self.params['viewing_distance'], gamma=None, notes=None, useBits=None, verbose=True, currentCalib=None, autoLog=True) self.monitor.setSizePix((1920, 1280)) self.monitor.setWidth(54.15) logging.exp('using monitor: ' + self.params['monitor'] + ' with viewing_distance=' + str(self.params['viewing_distance']) + ' cm\n' + ' resolution (pixel/deg): ' + str(deg2pix(1, self.monitor))) # TODO: change screen_pixel_size back to calculation from monitor # TODO: change the monitor definition width so that screen_pixel_size=0.282 if 'screen_pixel_size' not in self.params['model']: self.params['model']['screen_pixel_size'] = pix2cm( 1, self.monitor) * 10.0 #self.params['model']['screen_pixel_size'] = 0.282 self.params['model'][ 'viewing_distance'] = self.params['viewing_distance'] / 2.54 self.expInfo = params['exp_info'] self.expInfo['date'] = data.getDateStr() # Ensure that relative paths start from the same directory as this script _thisDir = os.path.dirname(os.path.abspath(__file__)) os.chdir(_thisDir) # Data file name stem = absolute path + name; later add .psyexp, .csv, .log, etc runsubject = self.params['runsubject'] if runsubject: self.filename = self.cwd + os.sep + u'data' + os.sep + '%s_%s_%s' % ( self.expInfo['participant'], params['name'], self.expInfo['date']) else: self.filename = self.cwd + os.sep + u'data' + os.sep + 'model-' + params[ 'expName']
'ID number': '1', 'frameRate': 120, 'w1': 0.2, 'ISI1': 0.3, 'w2': 0.2, 'blank': 0.3, 'fp': 0.3, 'task': 'wordPrimingTask', 'computer': 'raylan' } dlg = gui.DlgFromDict(params, title='SameDiffTask', fixed=['dateStr']) if dlg.OK: toFile('lastParams.pickle', params) #save params to file for next time else: core.quit() #the user hit cancel so exit fileName = params['ID number'] + '_SDTArb2' dataFile = open('/home/zahrahussain/Documents/psychopy/data/wordSDT/' + fileName + '.txt', 'a') #a simple text file with 'comma-separated-values' #dataFile = open(fileName+'.txt', 'a') dataFile.write( 'word, cue, condition, distractorType, corresp, subjectResp, accuracy, RT\n' ) # Create a visual window: #win = visual.Window(fullscr=True, allowGUI = True, monitor = 'testmonitor', units = 'deg') win = visual.Window(fullscr=True, allowGUI=True, monitor='2wordTasks',
# stimulus # for frameN in range(int(round(params['duration']*params['frameRate']))): clockRT.reset() target.draw() arrow2.draw() arrow3.draw() arrow4.draw() arrow5.draw() win.update() # start collecting response allKeys = event.waitKeys(timeStamped=clockRT) for keyTuple in allKeys: [thisKey, thisRT] = keyTuple for thisKey in allKeys: if thisKey in ['escape']: core.quit() elif int(thisKey[0]) == int(trials.thisTrial['dir']): thisResponse = 1 accuracy = 1 corSnd.play() else: thisResponse = 1 accuracy = 0 incorSnd.play() trials.data.add('accuracy', accuracy) event.clearEvents() win.close() core.quit()
def run(self, runsubject=False, monitor=None, distance=None, store_runtime_info=False, display_report=True): try: # TODO: do this only if this a model run print('Removing old model data files.') logging.info('Removing old model data files from data directory.') filelist = glob.glob( os.path.join(self.cwd, 'data', 'model-' + self.params['expName'] + '.csv')) for f in filelist: print('Removing: ' + str(f)) os.remove(f) runtime_info = None runsubject = self.params['runsubject'] if runsubject or self.params['genstim']: self.win = visual.Window( size=self.monitor.getSizePix(), fullscr=False, screen=0, winType='pyglet', allowGUI=True, allowStencil=False, #monitor=self.monitor, color='black', colorSpace='rgb', # TODO: add color parameter for newlibrary: mainwindow monitor=self.monitor, color=self.params['window_color'], colorSpace='rgb', blendMode='avg', useFBO=True, autoLog=False) if store_runtime_info: from psychopy import info # this library is slow to load, so we load here only since it is now needed runtime_info = info.RunTimeInfo(author=None, version=None, win=self.win, refreshTest='grating', userProcsDetailed=False, verbose=True) else: self.model = Model(name=self.params['expName'], cwd=self.params['cwd'], saveimages=self.params['saveimages'], params=self.params, **self.params['model']) self.params['model'][ 'decision_sigma'] = self.model.decision_sigma self.params['model']['decision_K'] = self.model.decision_K #logging.exp('Params:\n'+str(params)) if not self.params['genstim']: # An ExperimentHandler isn't essential but helps with data saving self.thisExp = data.ExperimentHandler( name=self.params['name'], version='', extraInfo=self.expInfo, runtimeInfo=runtime_info, savePickle=False, saveWideText=True, dataFileName=self.filename, autoLog=True) for routine in self.routines: routine.create(self.win, exp_handler=self.thisExp) for routine in self.routines: routine.run(runmodel=self.model, genstim=self.params['genstim'], params=self.params, loopstate=Params()) if self.thisExp: self.thisExp.close() logging.exp('Experiment Finished.') logging.exp('Params used in experiment:\n' + str(self.params)) logging.exp('Done.--------------------------------') if display_report: self.displayreport() #core.quit() except Exception as e: logging.error(traceback.format_exc()) self.end() core.quit()
def itemrecog_pattsep(subject_stim, context_bind_items, count): # Item recognition and pattern separation instructions for n in range(17, 20): temp_instr = visual.TextStim(win, instr[n], color='black', pos=[0, 0]) temp_instr.draw() win.update() event.waitKeys(keyList=['space']) win.flip() encoding_pres_items = subject_stim[subject_stim['Part'] == 'encoding'] feedback_correct = 'That’s right.' feedback_incorrect = 'Actually, you saw that friend with this object circled in black.' random.shuffle(character_list) for character in character_list: if event.getKeys(['escape']): win.close() core.quit() subject_stim['Scene'].iloc[n].split('_')[0] items_already_pres = subject_stim['Item'].tolist( ) + subject_stim['Lure_1'].tolist() + subject_stim['Lure_2'].tolist() # Get two random category lures lures_ir = random.sample([ x for x in stimulus_key[stimulus_key['Character'] == character] ['Item'].unique() if x not in items_already_pres ], 2) # Get lure items that were not presented during encoding and set random color lure1_ir = lures_ir[0] lure2_ir = lures_ir[1] target_ir = [ x for x in encoding_pres_items[encoding_pres_items['Character'] == character]['Item'].tolist() if x not in context_bind_items ][0] subject_stim.loc[count, 'Part'] = 'item_recognition' subject_stim.loc[count, 'Character'] = character subject_stim.loc[count, 'Item'] = target_ir subject_stim.loc[count, 'Lure_1'] = lure1_ir subject_stim.loc[count, 'Lure_2'] = lure2_ir # Present stimuli char_stim = Image.open(char_dir + [ i for i in os.listdir(char_dir) if i.endswith(character + '.png') ][0]) lure1_stim = Image.open(item_dir + character + '/' + [ i for i in os.listdir(item_dir + character + '/') if i.startswith(lure1_ir + '_white.png') ][0]) lure2_stim = Image.open(item_dir + character + '/' + [ i for i in os.listdir(item_dir + character + '/') if i.startswith(lure2_ir + '_white.png') ][0]) target_stim = Image.open(item_dir + character + '/' + [ i for i in os.listdir(item_dir + character + '/') if i.startswith(target_ir + '_white.png') ][0]) char_stim.thumbnail(item_size, Image.ANTIALIAS) lure1_stim.thumbnail(item_size, Image.ANTIALIAS) lure2_stim.thumbnail(item_size, Image.ANTIALIAS) target_stim.thumbnail(item_size, Image.ANTIALIAS) stim_pos = [[-0.5, -0.6], [0, -0.6], [0.5, -0.6]] random.shuffle(stim_pos) char_pres = visual.ImageStim(win, char_stim, pos=[0, 0.5]) lure1_pres = visual.ImageStim(win, lure1_stim, pos=stim_pos[0]) lure2_pres = visual.ImageStim(win, lure2_stim, pos=stim_pos[1]) target_pres = visual.ImageStim(win, target_stim, pos=stim_pos[2]) char_pres.draw() lure1_pres.draw() lure2_pres.draw() target_pres.draw() win.update() timer.reset() # Record response and give feedback while True: if mouse.isPressedIn(target_pres): subject_stim.loc[count, 'Reaction_Time'] = timer.getTime() subject_stim.loc[count, 'Answer'] = target_ir temp_instr = visual.TextStim(win, feedback_correct, color='black', pos=[0, 0]) feedback_circle = visual.Polygon(win, edges=100, radius=0.3, pos=target_pres.pos) feedback_circle.lineColor = 'black' feedback_circle.lineWidth = 7 char_pres.draw() lure1_pres.draw() lure2_pres.draw() target_pres.draw() temp_instr.draw() feedback_circle.draw() win.flip() core.wait(time_bind) break elif mouse.isPressedIn(lure1_pres): subject_stim.loc[count, 'Reaction_Time'] = timer.getTime() subject_stim.loc[count, 'Answer'] = lure1_ir temp_instr = visual.TextStim(win, feedback_incorrect, color='black', pos=[0, 0]) feedback_circle = visual.Polygon(win, edges=100, radius=0.3, pos=target_pres.pos) feedback_circle.lineColor = 'black' feedback_circle.lineWidth = 7 char_pres.draw() lure1_pres.draw() lure2_pres.draw() target_pres.draw() temp_instr.draw() feedback_circle.draw() win.flip() core.wait(time_bind) break elif mouse.isPressedIn(lure2_pres): subject_stim.loc[count, 'Reaction_Time'] = timer.getTime() subject_stim.loc[count, 'Answer'] = lure2_ir temp_instr = visual.TextStim(win, feedback_incorrect, color='black', pos=[0, 0]) feedback_circle = visual.Polygon(win, edges=100, radius=0.3, pos=target_pres.pos) feedback_circle.lineColor = 'black' feedback_circle.lineWidth = 7 char_pres.draw() lure1_pres.draw() lure2_pres.draw() target_pres.draw() temp_instr.draw() feedback_circle.draw() win.flip() core.wait(time_bind) break win.update() win.flip() fix_pres = scene_pres = visual.ImageStim(win, fixation, pos=[0, 0]) fix_pres.draw() win.update() core.wait(time_fixcr) win.flip() subject_stim.to_csv(save_subj_file_name) count = count + 1 # Pattern Separation target_ps = encoding_pres_items[encoding_pres_items['Item'] == target_ir][['Item', 'Color' ]].iloc[0].str.cat(sep='_') lures_ps = random.sample([ x for x in stimulus_key[stimulus_key['Item'] == target_ir]['Stim'] if x not in target_ps ], 2) lure1_ps = lures_ps[0] lure2_ps = lures_ps[1] subject_stim.loc[count, 'Part'] = 'pattern_separation' subject_stim.loc[count, 'Character'] = character subject_stim.loc[count, 'Item'] = target_ps.rsplit('_', 1)[0] subject_stim.loc[count, 'Color'] = target_ps.rsplit('_', 1)[1] subject_stim.loc[count, 'Lure_1'] = lure1_ps subject_stim.loc[count, 'Lure_2'] = lure2_ps lure1_ps_stim = Image.open(item_dir + character + '/' + [ i for i in os.listdir(item_dir + character + '/') if i.startswith(lure1_ps + '.png') ][0]) lure2_ps_stim = Image.open(item_dir + character + '/' + [ i for i in os.listdir(item_dir + character + '/') if i.startswith(lure2_ps + '.png') ][0]) target_ps_stim = Image.open(item_dir + character + '/' + [ i for i in os.listdir(item_dir + character + '/') if i.startswith(target_ps + '.png') ][0]) lure1_ps_stim.thumbnail(item_size, Image.ANTIALIAS) lure2_ps_stim.thumbnail(item_size, Image.ANTIALIAS) target_ps_stim.thumbnail(item_size, Image.ANTIALIAS) stim_pos = [[-0.5, -0.6], [0, -0.6], [0.5, -0.6]] random.shuffle(stim_pos) char_pres = visual.ImageStim(win, char_stim, pos=[0, 0.5]) lure1_ps_pres = visual.ImageStim(win, lure1_ps_stim, pos=stim_pos[0]) lure2_ps_pres = visual.ImageStim(win, lure2_ps_stim, pos=stim_pos[1]) target_ps_pres = visual.ImageStim(win, target_ps_stim, pos=stim_pos[2]) char_pres.draw() lure1_ps_pres.draw() lure2_ps_pres.draw() target_ps_pres.draw() win.update() timer.reset() while True: if mouse.isPressedIn(target_ps_pres): subject_stim.loc[count, 'Reaction_Time'] = timer.getTime() subject_stim.loc[count, 'Answer'] = target_ps break elif mouse.isPressedIn(lure1_ps_pres): subject_stim.loc[count, 'Reaction_Time'] = timer.getTime() subject_stim.loc[count, 'Answer'] = lure1_ps break elif mouse.isPressedIn(lure2_ps_pres): subject_stim.loc[count, 'Reaction_Time'] = timer.getTime() subject_stim.loc[count, 'Answer'] = lure2_ps break win.update() win.flip() count = count + 1 fix_pres = scene_pres = visual.ImageStim(win, fixation, pos=[0, 0]) fix_pres.draw() win.update() core.wait(time_fixcr) win.flip() subject_stim.to_csv(save_subj_file_name) return subject_stim, count
def run(self, runmodel=None, genstim=False, trialparams={}, params={}, loopstate={}): self.update_params(trialparams, loopstate) resp = Response() filename = '' # If we have a window then either we are generating stimuli or # running a human subject experiment if self.win is not None: for component in self.components: if genstim: filename = self.get_filename(trialparams, loopstate) component.start(trialparams, loopstate) else: component.run(trialparams, loopstate) left, top = params['model']['view_pos'] width, height = params['model']['view_size'] ################### #diff_x,diff_y = params['diff_size'] diff_x, diff_y = 1.0, 1.0 # TODO: remove all this diff_size code width_window, height_window = self.win.size center_left = int(deg2pix(left, self.win.monitor)) center_top = int(deg2pix(top, self.win.monitor)) upper_left = center_left - int(0.5 * width) upper_top = center_top + int(0.5 * height) if width % 2 == 0: # width is even number of pixels lower_right = upper_left + width lower_bottom = upper_top - height else: lower_right = upper_left + (width + 1) lower_bottom = upper_top - (height + 1) # convert to normalized coords upper_left_norm = upper_left / (0.5 * width_window) upper_top_norm = upper_top / (0.5 * height_window) lower_right_norm = lower_right / (0.5 * width_window) lower_bottom_norm = lower_bottom / (0.5 * height_window) rect = [ upper_left_norm, upper_top_norm, lower_right_norm * diff_x, lower_bottom_norm * diff_y ] extra = 2 # extra space to draw lines around rect if not self.viewport: self.viewport = visual.Rect(win=self.win, width=width + extra, height=height + extra, autoLog=None, units='pixels', lineWidth=1, lineColor='yellow', lineColorSpace='rgb', fillColor=None, fillColorSpace='rgb', pos=(center_left, center_top), ori=0.0, opacity=0.5, contrast=0.8, depth=1000, interpolate=False, name=None, autoDraw=True) else: self.viewport.setPos((center_left, center_top)) self.win.flip() if genstim: model_stimulus = self.win._getFrame(rect=None, buffer='front') model_stimulus = np.array(model_stimulus) center_height = int(height_window / 2) + center_top center_width = int(width_window / 2) + center_left top_height = int(center_height - height / 2) bottom_height = int(center_height + height / 2) top_width = int(center_width - width / 2) bottom_width = int(center_width + width / 2) model_stimulus = model_stimulus[top_height:bottom_height, top_width:bottom_width, :] model_stimulus = Image.fromarray(model_stimulus) if np.shape(model_stimulus)[1] != width or np.shape( model_stimulus)[0] != height: print(np.shape(model_stimulus)) import pdb pdb.set_trace() # TODO: Make it so this exception gets caught logging.error('problem with model window') raise Exception( 'Error in calculating shape of model window.') if 'model' in os.path.join(params['cwd'], 'stimuli' + os.sep + filename): import pdb pdb.set_trace() logging.info('saving: ' + filename) model_stimulus.save( os.path.join(params['cwd'], 'stimuli' + os.sep + filename), "PNG") keys = [] else: keys = event.waitKeys(maxWait=self.timeout, keyList=None) resp = Response(key=keys[0]) for component in self.components: component.end() else: filename = self.get_filename(trialparams, loopstate) # if we don't have a target_contrast in the parameters # then we need to load an image and get its target_contrast if 'target_contrast' not in params['model']: target_key, target_val = params['target_identifier'] target_condition = Params(trialparams) target_condition.update({target_key: target_val}) target_filename = self.get_filename(target_condition, loopstate) # load stim from filename im = Image.open( os.path.join(params['cwd'], 'stimuli' + os.sep + target_filename)).convert('L') im_array = np.frombuffer(im.tobytes(), dtype=np.uint8) width, height = im.size im_array = im_array.reshape((height, width)) contrast = runmodel.process(data=im_array) runmodel.target_contrast = contrast logging.exp('Generating target_contrast from ' + target_filename) logging.exp('Using target_contrast = ' + str(contrast)) params['model']['target_contrast'] = contrast runmodel.update_decision_params() params['model']['decision_K'] = runmodel.decision_K params['model']['decision_sigma'] = runmodel.decision_sigma logging.exp('***Using decision_K = ' + str(runmodel.decision_K)) logging.exp('***Using decision_sigma = ' + str(runmodel.decision_sigma)) # load stim from filename define StimulusNotFound and raise it im = Image.open( os.path.join(params['cwd'], 'stimuli' + os.sep + filename)).convert('L') im_array = np.frombuffer(im.tobytes(), dtype=np.uint8) width, height = im.size im_array = im_array.reshape((height, width)) print('processing:', filename) save_conv_filename = None if params['saveimages']: #save_conv_filename = 'images/'+filename[:-4]+'-convolved.png' save_conv_filename = filename[:-4] correct_answer, incorrect_answer = self.get_answer( trialparams, loopstate) # if we are saving additional plots we also want to pass the # corresponding target data to the runmodel.runsponse im_array_target = None if save_conv_filename: target_key, target_val = params['target_identifier'] target_condition = Params(trialparams) target_condition.update({target_key: target_val}) target_filename = self.get_filename(target_condition, loopstate) # load stim from filename im_target = Image.open( os.path.join(params['cwd'], 'stimuli' + os.sep + target_filename)).convert('L') im_array_target = np.frombuffer(im_target.tobytes(), dtype=np.uint8) width_target, height_target = im_target.size im_array_target = im_array_target.reshape( (height_target, width_target)) # TODO: if we are generating all the plots then read the target data # from the file using the 'target_identifier' from params # then pass into runmodel.response key, prob, contrast = runmodel.response( data=im_array, correct_answer=correct_answer, incorrect_answer=incorrect_answer, save_conv_filename=save_conv_filename, target_data=im_array_target) correct = False if key == correct_answer: correct = True resp = Response(key=key, rt=0, correct=correct, prob=prob, contrast=contrast) #keys = ['left'] if resp.key == 'escape': core.quit() return resp
def isolumCheckerScan(scanDict, screenSize=[1024, 768]): #do full field flickering checkerboard #length of scan in s scanLength = float(scanDict['numCycles'] * scanDict['period'] + scanDict['preScanRest']) #parse out vars from scanDict IR = scanDict['innerRadius'] OR = scanDict['outerRadius'] # colorA=scanDict['colorA'] # colorB=scanDict['colorB'] # colorBG=scanDict['colorBackground'] colorA = numpy.zeros((3, 1)) colorB = numpy.zeros((3, 1)) colorBG = numpy.zeros((3, 1)) foo = scanDict['colorA'] bar = foo.split(",") colorA[0] = float(bar[0]) colorA[1] = float(bar[1]) colorA[2] = float(bar[2]) foo = scanDict['colorB'] bar = foo.split(",") colorB[0] = float(bar[0]) colorB[1] = float(bar[1]) colorB[2] = float(bar[2]) foo = scanDict['colorBackground'] bar = foo.split(",") colorBG[0] = float(bar[0]) colorBG[1] = float(bar[1]) colorBG[2] = float(bar[2]) flickFreq = scanDict['animFreq'] timeBase = scanDict['timeBase'] #open subject window mySubScreen = numpy.int(scanDict['subjectScreen']) myOpScreen = numpy.int(scanDict['operatorScreen']) # print mySubScreen # print myOpScreen winSub = visual.Window(screenSize, monitor=scanDict['monCalFile'], units="deg", screen=mySubScreen, color=[-1.0, -1.0, -1.0], colorSpace='rgb', fullscr=False, allowGUI=False) #needs to be flexible--how do I extract the dims from screen? # screenSize=numpy.array([1600,1200]) #screenSize=numpy.array([1024,768]) fixPercentage = scanDict['fixFraction'] fixDuration = 0.25 respDuration = 1.0 subjectResponse = numpy.zeros((numpy.ceil(scanLength * 60 / 100), 1)) subRespArray = numpy.zeros((numpy.ceil(scanLength * 60 / 100), 3)) subjectResponse[:] = numpy.nan #plotResp=numpy.zeros((2,2)) # plotRespWrong=numpy.zeros((2,2)) plotMax = numpy.ceil(scanLength * (60.0 / 100.0)) plotResp = numpy.zeros((plotMax, 2)) plotColors = numpy.zeros((plotMax, 3)) #axesX=numpy.arange(0,scanLength*60/100) white = [1.0, 1.0, 1.0] gray = [0.0, 0.0, 0.0] black = [-1.0, -1.0, -1.0] # plt.ion() # plt.plot(plotResp[0:2],'ro') # plt.ylabel('subject responses') # plt.show() # plt.axis([0,scanLength*0.6,-0.1,1.1]) operatorWindow = visual.Window([1024, 768], monitor='testMonitor', units='deg', screen=myOpScreen, color=[0, 0, 0], colorSpace='rgb') #create a shapeStim to show the operator how the subject is doing on the task # opPlotRight=visual.ShapeStim(operatorWindow,units='pix',vertices=plotResp,closeShape=False,pos=(-448,-448),lineWidth=1,lineColor=[-1,1,-1],lineColorSpace='rgb' ) # opPlotWrong=visual.ShapeStim(operatorWindow,units='pix',vertices=plotResp,closeShape=False,pos=(-448,-448),lineWidth=1,lineColor=[1,-1,-1],lineColorSpace='rgb' ) #try another kind of plot opPlot = visual.ElementArrayStim(operatorWindow, units='pix', xys=plotResp, sizes=7, nElements=plotMax, fieldPos=(-500, -384), colors=plotColors, colorSpace='rgb', sfs=0, fieldShape='square', elementMask='circle') opPlot = visual.ElementArrayStim(operatorWindow, units='pix', xys=plotResp, sizes=7, nElements=plotMax, fieldPos=(-500, -384), colors=plotColors, colorSpace='rgb', sfs=0, fieldShape='square', elementMask='circle') gridLinesVertices = numpy.zeros((46, 2)) gridLinesVertices[:, 0] = [ 0, 998, 0, 0, 998, 0, 0, 998, 0, 0, 998, 0, 0, 998, 0, 0, 998, 100, 100, 100, 200, 200, 200, 300, 300, 300, 400, 400, 400, 500, 500, 500, 600, 600, 600, 700, 700, 700, 800, 800, 800, 900, 900, 900, 998, 998 ] gridLinesVertices[:, 1] = [ 0, 0, 0, 100, 100, 100, 200, 200, 200, 300, 300, 300, 400, 400, 400, 500, 500, 500, 0, 500, 500, 0, 500, 500, 0, 500, 500, 0, 500, 500, 0, 500, 500, 0, 500, 500, 0, 500, 500, 0, 500, 500, 0, 500, 500, 0 ] opPlotGrid = visual.ShapeStim(operatorWindow, units='pix', vertices=gridLinesVertices, closeShape=False, pos=(-512, -334)) # gridLinesStart=numpy.zeros((17,2)) # gridLinesEnd=numpy.zeros((17,2)) # for i in range(11): # gridLinesStart[i,0]=i*100 # gridLinesEnd[i,0]=i*100 # gridLinesStart[i,1]=0 # gridLinesEnd[i,1]=500 # for i in range(11,17): # gridLinesStart[i,0]=0 # gridLinesEnd[i,0]=1000 # gridLinesStart[i,1]=(i-12)*100 # gridLinesEnd[i,1]=(i-12)*100 # opPlotGrid00=visual.Line(operatorWindow,units='pix',start=gridLinesStart[:,0],end=gridLinesEnd[:,0],pos=(-448,-448)) # opPlotGrid01=visual.Line(operatorWindow,units='pix',start=gridLinesStart[:,1],end=gridLinesEnd[:,1],pos=(-448,-448)) # opPlotGrid02=visual.Line(operatorWindow,units='pix',start=gridLinesStart[:,2],end=gridLinesEnd[:,2],pos=(-448,-448)) #labels for the plot regions plotLabel1 = visual.TextStim( operatorWindow, units='pix', pos=(-450, 150), alignHoriz='left', text='Correct (active--displayed \'X\' and got a button press)', color=(-1, 1, -1), colorSpace='rgb', height=15) plotLabel2 = visual.TextStim( operatorWindow, units='pix', pos=(-450, -250), alignHoriz='left', text='Wrong (\'X\' displayed, NO button press)', color=(1, -1, -1), colorSpace='rgb', height=15) plotLabel3 = visual.TextStim( operatorWindow, units='pix', pos=(-450, -150), alignHoriz='left', text='Wrong-ish (No \'X\', but got a button press!?)', color=(1, -1, -1), colorSpace='rgb', height=15) plotLabel4 = visual.TextStim( operatorWindow, units='pix', pos=(-450, 25), alignHoriz='left', text='Correct (passive--no \'X\', no button press)', color=(-1, -1, 1), colorSpace='rgb', height=15) #create a designmatrix for trigger-based counting #first create an array--length = total number of Trs numTr = scanLength / scanDict['Tr'] designMatrix = numpy.zeros((numTr, 1)) #first N Trs are already zero--rest #figure out when the stim should be on for iStim in range(scanDict['numCycles']): restAmt = scanDict['preScanRest'] / scanDict['Tr'] stimDur = scanDict['period'] / scanDict['Tr'] #CHECK THIS firstVal = restAmt + iStim * stimDur lastVal = firstVal + scanDict['period'] / (2 * scanDict['Tr']) designMatrix[firstVal:lastVal] = 1 numpy.savetxt('debug.txt', designMatrix, fmt='%.3i') #convert colors to psychopy's scheme colorAf = numpy.asarray(colorA, dtype=float) colorBf = numpy.asarray(colorB, dtype=float) colorBGf = numpy.asarray(colorBG, dtype=float) colorAp = 2 * colorAf - 1 colorBp = 2 * colorBf - 1 colorBGp = 2 * colorBGf - 1 # image1=visual.SimpleImageStim(winSub,image='redblack1.jpg') # image2=visual.SimpleImageStim(winSub,image='redblack2.jpg') # image1=visual.PatchStim(winSub,tex='redblack1a.jpg',mask=None,size=[OR,OR]) # image2=visual.PatchStim(winSub,tex='redblack2a.jpg',mask=None,size=[OR,OR]) #let's try making some numpy arrays of the checkerboards! translated from matlab arrays #size of image--hardcode for now, but needs to be 2^n that fits inside smaller screen dimension # twoN=numpy.ones((13)) # for n in range(13): # twoN[n]=pow(2.0,n) # twoNsize=numpy.nonzero(twoN>screenSize[1]) # #hmm, this somehow made a nested tuple, whatever that is # keep_n=twoNsize[0][0]-1 # imageSize=pow(2,keep_n) # halfSize=numpy.int(imageSize/2) debugVar = numpy.zeros((scanLength * 60, 2)) #imageSize=1024 if screenSize[0] < 257: imageSize = 256 elif screenSize[0] < 513: imageSize = 512 elif screenSize[0] < 1025: imageSize = 1024 elif screenSize[0] < 2057: imageSize = 2048 halfSize = numpy.int(imageSize / 2) # print screenSize # print imageSize # print halfSize #create arrays of x,y, and r,theta xIn = numpy.arange(-halfSize, halfSize, 1) yIn = numpy.arange(-halfSize, halfSize, 1) xIn.astype(float) yIn.astype(float) x, y = numpy.meshgrid(xIn, yIn) r = numpy.sqrt(x**2 + y**2) #avoid divide by zero issues y[y == 0] = numpy.finfo(numpy.float).eps xOverY = x / y theta = numpy.arctan(xOverY) theta[halfSize + 1, halfSize + 1] = 0 #number of wedges (pairs!!)--eventually to be a var passed in nWedges = 8.0 #number of ring pairs nRings = 15.0 #width of wedges in radians wedgeWidth = 2.0 * math.pi / nWedges ringWidth = 2.0 / nRings #ring function--describes how the ring width increases with eccentricity ringFunction = numpy.power( r / halfSize, 0.3) + 0.2 #um, is there an int float problem here? wedgeMask = 0.5 - (numpy.mod(theta, wedgeWidth) > (wedgeWidth / 2.0)) #does this work rmA = numpy.mod(ringFunction, ringWidth) > (ringWidth / 2.0) ringMask = 1 - 2.0 * (rmA) checkerBoardLogic = wedgeMask * ringMask + 0.5 #checkerBoardBG=r> #initialize an array of 1024x1024x3 for RGB channels checkerBoardA = numpy.ones((imageSize, imageSize, 3)) checkerBoardAR = numpy.ones((imageSize, imageSize)) checkerBoardAB = numpy.ones((imageSize, imageSize)) checkerBoardAG = numpy.ones((imageSize, imageSize)) #set the RGB values based on the colors passed in during launch #CBA, logic=1-->colorB, logic=0-->colorA #CBB, logic=1-->colorA, logic=0-->colorB #color A, column 1 checkerBoardAR[checkerBoardLogic == 1] = colorAp[0] checkerBoardAG[checkerBoardLogic == 1] = colorAp[1] checkerBoardAB[checkerBoardLogic == 1] = colorAp[2] checkerBoardAR[checkerBoardLogic == 0] = colorBp[0] checkerBoardAG[checkerBoardLogic == 0] = colorBp[1] checkerBoardAB[checkerBoardLogic == 0] = colorBp[2] #now add in the background color around the widest ring # imageMask=numpy.ones((imageSize,imageSize)) # imageMask[r>halfSize]=-1 print(colorBG) print(colorBGf) print(colorBGp) checkerBoardAR[r > halfSize] = colorBGp[0] checkerBoardAG[r > halfSize] = colorBGp[1] checkerBoardAB[r > halfSize] = colorBGp[2] #smoosh the arrays together checkerBoardA[:, :, 0] = checkerBoardAR checkerBoardA[:, :, 1] = checkerBoardAG checkerBoardA[:, :, 2] = checkerBoardAB checkerBoardB = numpy.ones((imageSize, imageSize, 3)) checkerBoardBR = numpy.ones((imageSize, imageSize)) checkerBoardBB = numpy.ones((imageSize, imageSize)) checkerBoardBG = numpy.ones((imageSize, imageSize)) checkerBoardBR[checkerBoardLogic == 1] = colorBp[0] checkerBoardBG[checkerBoardLogic == 1] = colorBp[1] checkerBoardBB[checkerBoardLogic == 1] = colorBp[2] checkerBoardBR[checkerBoardLogic == 0] = colorAp[0] checkerBoardBG[checkerBoardLogic == 0] = colorAp[1] checkerBoardBB[checkerBoardLogic == 0] = colorAp[2] checkerBoardBR[r > halfSize] = colorBGp[0] checkerBoardBG[r > halfSize] = colorBGp[1] checkerBoardBB[r > halfSize] = colorBGp[2] checkerBoardB[:, :, 0] = checkerBoardBR checkerBoardB[:, :, 1] = checkerBoardBG checkerBoardB[:, :, 2] = checkerBoardBB # numpy.savetxt('chAr.txt',checkerBoardA[:,:,0],fmt='%f') # numpy.savetxt('chAg.txt',checkerBoardA[:,:,1],fmt='%f') # numpy.savetxt('chAb.txt',checkerBoardA[:,:,2],fmt='%f') # numpy.savetxt('chBr.txt',checkerBoardB[:,:,0],fmt='%f') # numpy.savetxt('chBg.txt',checkerBoardB[:,:,1],fmt='%f') # numpy.savetxt('chBb.txt',checkerBoardB[:,:,2],fmt='%f') #finally, create the image textures!! #oooh, these are fun--tiles the checkerboards! #stimA=visual.GratingStim(winSub,tex=checkerBoardA,size=imageSize) #stimB=visual.GratingStim(winSub,tex=checkerBoardB,size=imageSize) stimA = visual.GratingStim(winSub, tex=checkerBoardA, size=imageSize, sf=1 / imageSize, units='pix', texRes=imageSize) stimB = visual.GratingStim(winSub, tex=checkerBoardB, size=imageSize, sf=1 / imageSize, units='pix') ReverseFreq = flickFreq #drift in Hz. #make a fixation cross which will rotate 45 deg on occasion fix0 = visual.Circle(winSub, radius=IR / 2.0, edges=32, lineColor=gray, lineColorSpace='rgb', fillColor=gray, fillColorSpace='rgb', autoLog=False) fix1 = visual.ShapeStim(winSub, pos=[0.0, 0.0], vertices=((0.0, -0.2), (0.0, 0.2)), lineWidth=3.0, lineColor=black, lineColorSpace='rgb', fillColor=black, fillColorSpace='rgb', autoLog=False) fix2 = visual.ShapeStim(winSub, pos=[0.0, 0.0], vertices=((-0.2, 0.0), (0.2, 0.0)), lineWidth=3.0, lineColor=black, lineColorSpace='rgb', fillColor=black, fillColorSpace='rgb', autoLog=False) #stim.setOri(t*rotationRate*360.0) #stim.setRadialPhase(driftRate,'+') #stim.setPos()#something here msg1x = visual.TextStim(winSub, pos=[0, +8], text='flickering checkerboard') msg1a = visual.TextStim( winSub, pos=[0, +5], text='During the scan, please keep your eyes on the + in the center.', height=1) msg1b = visual.TextStim(winSub, pos=[0, +2], text='Hit any button any time the + becomes an X.', height=1) msg1 = visual.TextStim(winSub, pos=[0, -3], text='Subject: Hit a button when ready.', color=[1, -1, -1], colorSpace='rgb') msg1.draw() msg1a.draw() msg1b.draw() msg1X.draw() fix0.draw() fix1.draw() fix2.draw() winSub.flip() #wait for subject thisKey = None while thisKey == None: thisKey = event.waitKeys( keyList=['r', 'g', 'b', 'y', '1', '2', '3', '4', 'q', 'escape']) if thisKey in ['q', 'escape']: core.quit() #abort else: event.clearEvents() # while len(event.getKeys())==0: # core.wait(0.05) # event.clearEvents() # msg1=visual.TextStim(winSub,pos=[0,+0.1],text='Waiting for magnet....',color=[-1,1,-1],colorSpace='rgb',height=0.1,units='norm') # msg1=visual.TextStim(winSub,text='Waiting for magnet....',height=10) # msg1=visual.TextStim(operatorWindow,pos=[0,-3],text='Subject: wait.',color=[1,-1,-1],colorSpace='rgb') # fix0.draw() # fix1.draw() # fix2.draw() # msg1.draw() # winSub.flip() msg1a = visual.TextStim(winSub, pos=[0, +5], text=' ', height=1) msg1b = visual.TextStim(winSub, pos=[0, +2], text='Waiting for magnet', height=1) #msg1c=visual.TextStim(winSub,pos=[0,-3],text='Subject: Hit a key when ready.',color=[1,-1,-1],colorSpace='rgb') msg1c.draw() msg1a.draw() msg1b.draw() fix0.draw() fix1.draw() fix2.draw() winSub.flip() #wait for trigger trig = None while trig == None: #wait for trigger "keypress" trig = event.waitKeys(keyList=['t', '5', 'q', 'escape']) if trig in ['q', 'escape']: core.quit() else: #stray key event.clearEvents() #start the timer scanTimer = core.Clock() startTime = scanTimer.getTime() #draw the fixation point # wedge1.draw() fix0.draw() fix1.draw() fix2.draw() winSub.flip() # and drift it timeNow = scanTimer.getTime() #row=1 msg = visual.TextStim(operatorWindow, units='pix', text='t = %.3f' % timeNow, pos=(0.0, 325.0), height=30) msg.draw() loopCounter = 0 restLoopCounter = 0 TrCounter = 0 if timeBase == 0: ttp = TrCounter + 1 msgTr = visual.TextStim(operatorWindow, units='pix', pos=(0.0, 275.0), text='Tr = %i' % ttp, height=30) msgTr.draw() # msgPC = visual.TextStim(operatorWindow,units='pix',text = 'percent correct',pos=(0.0,0.0),height=30) # msgPC.draw() # msgTC = visual.TextStim(operatorWindow,units='pix',text = 'time since correct',pos=(0.0,-75.0),height=30) # msgTC.draw() plotLabel1.draw() plotLabel2.draw() plotLabel3.draw() plotLabel4.draw() fixTimer = core.Clock() respTimer = core.Clock() flickerTimer = core.Clock() fixOri = 0 numCoins = 0 event.clearEvents() for key in event.getKeys(): if key in ['q', 'escape']: core.quit() elif key in ['r', 'g', 'b', 'y', '1', '2', '3', '4' ] and respTimeCheck < respDuration: subjectResponse[numCoins] = 1 if timeBase == 1: #time based loop advancement respCounter = 0 #display rest for pre-scan duration while timeNow < scanDict['preScanRest']: timeNow = scanTimer.getTime() #draw fixation #every 100 frames, decide if the fixation point should change or not if restLoopCounter % 100 == 0 and restLoopCounter > 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 #store info--expected response or not? respCounter += 1 subRespArray[respCounter, 0] = timeNow subRespArray[respCounter, 1] = flipCoin < fixPercentage fixTimeCheck = fixTimer.getTime() respTimeCheck = respTimer.getTime() if fixTimeCheck > fixDuration: #timer expired--reset ori fixOri = 0 fix1.setOri(fixOri) fix2.setOri(fixOri) fix0.draw() fix1.draw() fix2.draw() msg.setText('t = %.3f' % timeNow) msg.draw() winSub.flip() operatorWindow.flip() for key in event.getKeys(): if key in ['q', 'escape']: core.quit() elif key in ['r', 'g', 'b', 'y', '1', '2', '3', '4' ] and respTimeCheck < respDuration: subjectResponse[numCoins] = 1 plotResp[numCoins] = 1 subRespArray[respCounter, 2] = 1 # elif key in ['t']: #increment loop count for each trigger #update the operator graph #determine response correctness and append to plot vertices variable plotResp[respCounter, 0] = respCounter if subRespArray[respCounter, 1] == 1 and subRespArray[respCounter, 2] == 1: #exp resp and got resp--correct and awake plotResp[respCounter, 1] = 500 plotColors[respCounter, 0] = -1 plotColors[respCounter, 1] = 1 plotColors[respCounter, 2] = -1 # plotResp=numpy.append(plotResp,[[respCounter,500]],0) #opPlotRight.setLineColor([-1,1,-1]) elif subRespArray[respCounter, 1] == 1 and subRespArray[respCounter, 2] == 0: #exp response, got NONE--wrong! plotResp[respCounter, 1] = 100 plotColors[respCounter, 0] = 1 plotColors[respCounter, 1] = -1 plotColors[respCounter, 2] = -1 # plotRespWrong=numpy.append(plotRespWrong,[[respCounter,200]],0) #opPlotRight.setLineColor([1,-1,-1]) elif subRespArray[respCounter, 1] == 0 and subRespArray[respCounter, 2] == 1: #exp NONE, got response--wrong, but awake at least plotResp[respCounter, 1] = 150 plotColors[respCounter, 0] = 1 plotColors[respCounter, 1] = -1 plotColors[respCounter, 2] = -1 # plotRespWrong=numpy.append(plotRespWrong,[[respCounter,250]],0) #opPlotRight.setLineColor([1,-1,-1]) elif subRespArray[respCounter, 1] == 0 and subRespArray[respCounter, 2] == 0: #exp none, got NONE--correct, but uninformative plotResp[respCounter, 1] = 400 plotColors[respCounter, 0] = -1 plotColors[respCounter, 1] = -1 plotColors[respCounter, 2] = 1 # plotResp=numpy.append(plotResp,[[respCounter,450]],0) #opPlotRight.setLineColor([-1,1,-1]) #update the vertices plotLabel1.draw() plotLabel2.draw() plotLabel3.draw() plotLabel4.draw() opPlotGrid.draw() #plot only the last 10==do hijinks for n<10 plotStart = respCounter - 10 if plotStart < 0: plotStart == 0 opPlot.setXYs(plotResp[plotStart:respCounter]) opPlot.setColors(plotColors) opPlot.draw() restLoopCounter += 1 # if restLoopCounter%300 and restLoopCounter>5: # plt.plot(plotResp[0:numCoins+1],'ro') # plt.draw #pre-scan rest is done. #prepare for looping through the cycles epochTimer = core.Clock() #time based looping through stimulus while timeNow < startTime + scanLength: #loop for scan duration timeBefore = timeNow timeNow = scanTimer.getTime() deltaT = timeNow - startTime deltaTinc = timeNow - timeBefore #every 100 frames, decide if the fixation point 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 plotResp[numCoins] = 1 #store info--expected response or not? respCounter += 1 subRespArray[respCounter, 0] = timeNow subRespArray[respCounter, 1] = flipCoin < fixPercentage fixTimeCheck = fixTimer.getTime() respTimeCheck = respTimer.getTime() if fixTimeCheck > fixDuration: #timer expired--reset ori fixOri = 0 fix1.setOri(fixOri) fix2.setOri(fixOri) # alternate between stimulus and rest, starting with pre-scan duration of rest epochTime = epochTimer.getTime() #half-period epoch of stimulus radialPhase = nowTime oriAngle = nowTime / 360.0 if epochTime < scanDict['period'] / 2.0: #alternate wedge 1&2 at flicker rate flickerTimeCheck = flickerTimer.getTime() if flickerTimeCheck < 1 / (2.0 * ReverseFreq): #first half of a period, show wedge 1 #image1.draw() stimA.setPhase(radialPhase) stimA.draw() elif flickerTimeCheck < 1 / ReverseFreq: #second half of period, show wedge 2 # image2.draw() stimB.setPhase(radialPhase) stimB.draw() else: #clocked over, reset timer #could also do some modulus of timing flickerTimer.reset() fix0.draw() fix1.draw() fix2.draw() elif epochTime < scanDict['period']: #half-period epoch of rest fix0.draw() fix1.draw() fix2.draw() else: epochTimer.reset() msg.setText('t = %.3f' % timeNow) msg.draw() operatorWindow.flip() winSub.flip() #row+=1 #core.wait(3.0/60.0) #count number of keypresses since previous frame, break if non-zero for key in event.getKeys(): if key in ['q', 'escape']: core.quit() elif key in ['r', 'g', 'b', 'y', '1', '2', '3', '4' ] and respTimeCheck < respDuration: subjectResponse[numCoins] = 1 subRespArray[respCounter, 2] = 1 # if loopCounter%300 and loopCounter>5: # plt.plot(plotResp[0:numCoins+1],'ro') # plt.draw #update the operator graph #determine response correctness and append to plot vertices variable plotResp[respCounter, 0] = respCounter #print subRespArray[respCounter,1:2] if subRespArray[respCounter, 1] == 1 and subRespArray[respCounter, 2] == 1: #exp resp and got resp--correct and awake plotResp[respCounter, 1] = 500 #print('exp resp, got resp') #print plotResp[respCounter,1] plotColors[respCounter, 0] = -1 plotColors[respCounter, 1] = 1 plotColors[respCounter, 2] = -1 # plotResp=numpy.append(plotResp,[[respCounter,500]],0) #opPlotRight.setLineColor([-1,1,-1]) elif subRespArray[respCounter, 1] == 1 and subRespArray[respCounter, 2] == 0: #exp response, got NONE--wrong! plotResp[respCounter, 1] = 100 #print('exp resp, got none') #print plotResp[respCounter,1] plotColors[respCounter, 0] = 1 plotColors[respCounter, 1] = -1 plotColors[respCounter, 2] = -1 # plotRespWrong=numpy.append(plotRespWrong,[[respCounter,200]],0) #opPlotRight.setLineColor([1,-1,-1]) elif subRespArray[respCounter, 1] == 0 and subRespArray[respCounter, 2] == 1: #exp NONE, got response--wrong, but awake at least plotResp[respCounter, 1] = 150 #print('exp none, got one') #print plotResp[respCounter,1] plotColors[respCounter, 0] = 1 plotColors[respCounter, 1] = -1 plotColors[respCounter, 2] = -1 # plotRespWrong=numpy.append(plotRespWrong,[[respCounter,250]],0) #opPlotRight.setLineColor([1,-1,-1]) elif subRespArray[respCounter, 1] == 0 and subRespArray[respCounter, 2] == 0: #exp none, got NONE--correct, but uninformative plotResp[respCounter, 1] = 400 #print('exp none, got none') #print plotResp[respCounter,1] plotColors[respCounter, 0] = -1 plotColors[respCounter, 1] = -1 plotColors[respCounter, 2] = 1 # plotResp=numpy.append(plotResp,[[respCounter,450]],0) #opPlotRight.setLineColor([-1,1,-1]) #update the vertices plotLabel1.draw() plotLabel2.draw() plotLabel3.draw() plotLabel4.draw() opPlotGrid.draw() opPlot.setXYs(plotResp) opPlot.setColors(plotColors) opPlot.draw() loopCounter += 1 else: #trigger based #loop through, presenting stim or rest according to designMatrix TrCounter = 0 loopCounter = 0 respCounter = 0 numFlips = 0 #WORKING HERE #trigger based loop advancement #wait for trigger until N triggers found while TrCounter < numTr: #update times timeNow = scanTimer.getTime() timeBefore = timeNow timeNow = scanTimer.getTime() deltaT = timeNow - startTime deltaTinc = timeNow - timeBefore #organize fixation point orientation #every 100 frames, decide if the fixation point should change or not debugVar[loopCounter, 0] = loopCounter if loopCounter % 50 == 0 and loopCounter > 10: #flip a coin to decide flipCoin = numpy.random.ranf() numFlips += 1 if flipCoin < fixPercentage: #reset timers/change ori fixOri = 45 fixTimer.reset() respTimer.reset() numCoins += 1 subjectResponse[numCoins] = 0 #store info--expected response or not? respCounter += 1 subRespArray[respCounter, 0] = timeNow subRespArray[respCounter, 1] = flipCoin < fixPercentage fixTimeCheck = fixTimer.getTime() respTimeCheck = respTimer.getTime() if fixTimeCheck > fixDuration: #timer expired--reset ori fixOri = 0 debugVar[loopCounter, 1] = fixOri fix1.setOri(fixOri) fix2.setOri(fixOri) #draw stim or rest, based on designMatrix # alternate between stimulus and rest, starting with pre-scan duration of rest if designMatrix[TrCounter] == 1: #alternate wedge 1&2 at flicker rate flickerTimeCheck = flickerTimer.getTime() if flickerTimeCheck < 1 / (2.0 * ReverseFreq): #first half of a period, show wedge 1 #image1.draw() stimA.draw() elif flickerTimeCheck < 1 / ReverseFreq: #second half of period, show wedge 2 # image2.draw() stimB.draw() else: #clocked over, reset timer #could also do some modulus of timing flickerTimer.reset() fix0.draw() fix1.draw() fix2.draw() else: #rest fix0.draw() fix1.draw() fix2.draw() #count number of keypresses since previous frame, TrDone = 0 for key in event.getKeys(): if key in ['q', 'escape']: core.quit() elif key in ['r', 'g', 'b', 'y', '1', '2', '3', '4' ] and respTimeCheck < respDuration: subjectResponse[numCoins] = 1 subRespArray[respCounter, 2] = 1 elif key in ['t'] and TrDone == 0: #increment loop count for each trigger TrCounter += 1 TrDone = 1 #update the operator graph #determine response correctness and append to plot vertices variable plotResp[respCounter, 0] = respCounter if subRespArray[respCounter, 1] == 1 and subRespArray[respCounter, 2] == 1: #exp resp and got resp--correct and awake plotResp[respCounter, 1] = 500 plotColors[respCounter, 0] = -1 plotColors[respCounter, 1] = 1 plotColors[respCounter, 2] = -1 # plotResp=numpy.append(plotResp,[[respCounter,500]],0) #opPlotRight.setLineColor([-1,1,-1]) elif subRespArray[respCounter, 1] == 1 and subRespArray[respCounter, 2] == 0: #exp response, got NONE--wrong! plotResp[respCounter, 1] = 100 plotColors[respCounter, 0] = 1 plotColors[respCounter, 1] = -1 plotColors[respCounter, 2] = -1 # plotRespWrong=numpy.append(plotRespWrong,[[respCounter,200]],0) #opPlotRight.setLineColor([1,-1,-1]) elif subRespArray[respCounter, 1] == 0 and subRespArray[respCounter, 2] == 1: #exp NONE, got response--wrong, but awake at least plotResp[respCounter, 1] = 150 plotColors[respCounter, 0] = 1 plotColors[respCounter, 1] = -1 plotColors[respCounter, 2] = -1 # plotRespWrong=numpy.append(plotRespWrong,[[respCounter,250]],0) #opPlotRight.setLineColor([1,-1,-1]) elif subRespArray[respCounter, 1] == 0 and subRespArray[respCounter, 2] == 0: #exp none, got NONE--correct, but uninformative plotResp[respCounter, 1] = 400 plotColors[respCounter, 0] = -1 plotColors[respCounter, 1] = -1 plotColors[respCounter, 2] = 1 # plotResp=numpy.append(plotResp,[[respCounter,450]],0) #opPlotRight.setLineColor([-1,1,-1]) #update the vertices plotLabel1.draw() plotLabel2.draw() plotLabel3.draw() plotLabel4.draw() opPlotGrid.draw() opPlot.setXYs(plotResp) opPlot.setColors(plotColors) opPlot.draw() # opPlotWrong.setVertices(plotRespWrong) # opPlotWrong.draw() #update the operator on the last 10 responses # if numCoins>9: # findResp = subjectResponse[~numpy.isnan(subjectResponse)] # calcResp=findResp[findResp==1] # numCorrect=float(calcResp.shape[0]) # percentCorrect=float(numCorrect)/(float(findResp.shape[0])) # timeLastCor=subRespArray[-1,0] # timeSinceCor=timeNow-timeLastCor # msgTextPC='Last 10 fixation tasks, percent correct: %.1f' %(percentCorrect) ## msgTextTC='time since last correct response: %f' %(timeSinceCor) # msgPC.setText(msgTextPC) ## msgTC.setText(msgTextTC) # msgPC.draw() ## msgTC.draw() msg.setText('t = %.3f' % timeNow) ttp = TrCounter + 1 msgTr.setText('Tr = %i' % ttp) msg.draw() msgTr.draw() operatorWindow.flip() winSub.flip() #row+=1 #core.wait(3.0/60.0) #update plot once per 3Tr # if TrCounter%3==0 and TrCounter>1: # plt.plot(plotResp[0:numFlips+1],'ro') # plt.draw #plt.draw() # if numCoins>2: # #calculate correct percentage # findResp=subjectResponse[~numpy.isnan(subjectResponse)] # calcResp=findResp[findResp==1] # numCorrect=float(calcResp.shape[0]) # percentCorrect=float(numCorrect)/(float(numCoins)) # timeLastCor=subRespArray[len(calcResp),0] # timeSinceCor=timeNow-timeLastCor # msgText='Subject responses: %f correct' %(percentCorrect,) # msgText2='Time since last correct response: %f s' %(timeSinceCor,) # msg4.setText(msgText) # msg4.draw() # msg5.setText(msgText2) # msg5.draw() # msg.draw() # msgTr.draw() # operatorWindow.flip() # print msgText # print msgText2 loopCounter += 1 #core.wait(5.0) #outFile = open("debug.txt","w") #outFile.write(str(debugVar)) #outFile.close() #numpy.savetxt('debug.txt',debugVar,fmt='%.3f') #numpy.savetxt('debug.txt',designMatrix,fmt='%.3i') #numpy.savetxt('debugchop.txt',debugVar[:row,],fmt='%.3f') #calculate %age of responses that were correct #find non-nan #np.isnan(a) gives boolean array of true/a=false #np.isnan(a).any(1) gives a col vector of the rows with nans #~np.isnan(a).any(1) inverts the logic #myarray[~np.isnan(a).any(1)] gives the subset that I want 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, ) msg1 = visual.TextStim(winSub, pos=[0, +3], text=msgText) msg1.draw() winSub.flip() #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 = 'isolumResponse%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) winSub.close() operatorWindow.close()
# Experiment session GUI dialog #------------------------------ #get values from dialog my_dlg = gui.Dlg(title=exp_name, pos=(860, 340)) my_dlg.addField(label='id', initial=0, tip='Participant name or code'), my_dlg.addField(label='age', initial=0, tip='Participant age'), my_dlg.addField(label='gender', choices=('female', 'male', 'Other/Prefer no to say')) my_dlg.addField(label='screen', choices=(60, 144), tip='Refresh Rate') my_dlg.addField(label='triggers', initial='No', choices=['Yes', 'No'], tip='Send EEG Triggers') dlg_data = my_dlg.show() if my_dlg.OK == False: core.quit() #user pressed cancel #store values from dialog exp_info = { 'id': dlg_data[0], 'age': dlg_data[1], 'gender': dlg_data[2], 'screen': dlg_data[3], 'triggers': dlg_data[4] } exp_info['date'] = data.getDateStr() #get a simple timestamp for filename exp_info['exp_name'] = exp_name #----------------------- #setup files for saving
def displayCircularStimuli(directions, colors, colors_wheel, thicknesses, speeds, duration): global mywin, plate, white mywin = visual.Window([1280, 1024], monitor="Dell Inc. 17", units="pix", fullscr=False, screen=1, color='white') plate = visual.Rect(win=mywin, size=(width_plate, height_plate), lineColor=[0, 0, 0], lineColorSpace="rgb255", lineWidth=4) white = visual.ImageStim(win=mywin, image="Solid_white.png", size=(1280, 1024), pos=[0, 0]) ops = [] for d in directions: if d == 'Clockwise': ops.append('+') else: ops.append('-') shape1 = visual.ShapeStim(mywin, units='', lineWidth=thicknesses[0], lineColor=colors_wheel[0], lineColorSpace='rgb', fillColor='red', fillColorSpace='rgb', vertices=np.multiply(wheel, scalingFactor), windingRule=None, closeShape=True, pos=(-width_plate / 6.4, height_plate / 8.2), size=1, ori=0.0, opacity=1.0, contrast=1.0, depth=0, interpolate=True, name=None, autoLog=None, autoDraw=False) shape1b = visual.Circle(mywin, radius=scalingFactor, fillColor=colors[0], pos=(-width_plate / 6.4, height_plate / 8.2)) shape2 = visual.ShapeStim(mywin, units='', lineWidth=thicknesses[1], lineColor=colors_wheel[1], lineColorSpace='rgb', fillColor='red', fillColorSpace='rgb', vertices=np.multiply(wheel, scalingFactor), windingRule=None, closeShape=True, pos=(0, height_plate / 8.2), size=1, ori=0.0, opacity=1.0, contrast=1.0, depth=0, interpolate=True, name=None, autoLog=None, autoDraw=False) shape2b = visual.Circle(mywin, radius=scalingFactor, fillColor=colors[1], pos=(0, height_plate / 8.2)) shape3 = visual.ShapeStim(mywin, units='', lineWidth=thicknesses[2], lineColor=colors_wheel[2], lineColorSpace='rgb', fillColor='red', fillColorSpace='rgb', vertices=np.multiply(wheel, scalingFactor), windingRule=None, closeShape=True, pos=(width_plate / 6.4, height_plate / 8.2), size=1, ori=0.0, opacity=1.0, contrast=1.0, depth=0, interpolate=True, name=None, autoLog=None, autoDraw=False) shape3b = visual.Circle(mywin, radius=scalingFactor, fillColor=colors[2], pos=(width_plate / 6.4, height_plate / 8.2)) shape4 = visual.ShapeStim(mywin, units='', lineWidth=thicknesses[3], lineColor=colors_wheel[3], lineColorSpace='rgb', fillColor='red', fillColorSpace='rgb', vertices=np.multiply(wheel, scalingFactor), windingRule=None, closeShape=True, pos=(-width_plate / 6.4, -height_plate / 8.2), size=1, ori=0.0, opacity=1.0, contrast=1.0, depth=0, interpolate=True, name=None, autoLog=None, autoDraw=False) shape4b = visual.Circle(mywin, radius=scalingFactor, fillColor=colors[3], pos=(-width_plate / 6.4, -height_plate / 8.2)) shape5 = visual.ShapeStim(mywin, units='', lineWidth=thicknesses[4], lineColor=colors_wheel[4], lineColorSpace='rgb', fillColor='red', fillColorSpace='rgb', vertices=np.multiply(wheel, scalingFactor), windingRule=None, closeShape=True, pos=(0, -height_plate / 8.2), size=1, ori=0.0, opacity=1.0, contrast=1.0, depth=0, interpolate=True, name=None, autoLog=None, autoDraw=False) shape5b = visual.Circle(mywin, radius=scalingFactor, fillColor=colors[4], pos=(0, -height_plate / 8.2)) shape6 = visual.ShapeStim(mywin, units='', lineWidth=thicknesses[5], lineColor=colors_wheel[5], lineColorSpace='rgb', fillColor='red', fillColorSpace='rgb', vertices=np.multiply(wheel, scalingFactor), windingRule=None, closeShape=True, pos=(width_plate / 6.4, -height_plate / 8.2), size=1, ori=0.0, opacity=1.0, contrast=1.0, depth=0, interpolate=True, name=None, autoLog=None, autoDraw=False) shape6b = visual.Circle(mywin, radius=scalingFactor, fillColor=colors[5], pos=(width_plate / 6.4, -height_plate / 8.2)) mywin.winHandle.maximize() mywin.winHandle.set_fullscreen(True) mywin.winHandle.activate() # display white while True: white.draw() plate.draw() mywin.flip() if event.waitKeys(0.5) == ["escape"]: break event.clearEvents() startCamera(duration) clock = core.Clock() for frameN in range(duration): white.draw() plate.draw() shape1.setOri(speeds[0], operation=ops[0]) shape1b.draw() shape1.draw() shape2.setOri(speeds[1], operation=ops[1]) shape2b.draw() shape2.draw() shape3.setOri(speeds[2], operation=ops[2]) shape3b.draw() shape3.draw() shape4.setOri(speeds[3], operation=ops[3]) shape4b.draw() shape4.draw() shape5.setOri(speeds[4], operation=ops[4]) shape5b.draw() shape5.draw() shape6.setOri(speeds[5], operation=ops[5]) shape6b.draw() shape6.draw() mywin.logOnFlip(level=logging.CRITICAL, msg='sent on actual flip') mywin.flip() for frameN in range(300): white.draw() plate.draw() mywin.flip() mywin.close() core.quit()
def context_binding(subject_stim, context_bind_items, count): encoding_pres_items = subject_stim[subject_stim['Part'] == 'encoding'] temp_instr = visual.TextStim(win, instr[16], color='black', pos=[0, 0]) temp_instr.draw() win.update() event.waitKeys(keyList=['space']) win.flip() random.shuffle(character_list) for character in character_list: if event.getKeys(['escape']): win.close() core.quit() subject_stim['Scene'].iloc[n].split('_')[0] items_already_pres = subject_stim['Item'].tolist( ) + subject_stim['Lure_1'].tolist() + subject_stim['Lure_2'].tolist() # Get two random category lures cb_items = random.sample( encoding_pres_items[encoding_pres_items['Character'] == character] ['Item'].tolist(), 3) # Get lure items that were not presented during encoding and set random color scene_cb = encoding_pres_items[encoding_pres_items['Item'] == cb_items[0]]['Scene'].iloc[0] target_cb = encoding_pres_items[encoding_pres_items['Item'] == cb_items[0]][[ 'Item', 'Color' ]].iloc[0].str.cat(sep='_') lure1_cb = encoding_pres_items[encoding_pres_items['Item'] == cb_items[1]][[ 'Item', 'Color' ]].iloc[0].str.cat(sep='_') lure2_cb = encoding_pres_items[encoding_pres_items['Item'] == cb_items[2]][[ 'Item', 'Color' ]].iloc[0].str.cat(sep='_') context_bind_items = context_bind_items + [ target_cb.rsplit('_', 1)[0], lure1_cb.rsplit('_', 1)[0], lure2_cb.rsplit('_', 1)[0] ] subject_stim.loc[count, 'Part'] = 'context_binding' subject_stim.loc[count, 'Character'] = character subject_stim.loc[count, 'Scene'] = scene_cb subject_stim.loc[count, 'Item'] = target_cb.rsplit('_', 1)[0] subject_stim.loc[count, 'Color'] = target_cb.rsplit('_', 1)[1] subject_stim.loc[count, 'Lure_1'] = lure1_cb subject_stim.loc[count, 'Lure_2'] = lure2_cb # Present stimuli scene_stim = Image.open(scene_dir + scene_cb + '.png') lure1_stim = Image.open(item_dir + character + '/' + [ i for i in os.listdir(item_dir + character + '/') if i.startswith(lure1_cb + '.png') ][0]) lure2_stim = Image.open(item_dir + character + '/' + [ i for i in os.listdir(item_dir + character + '/') if i.startswith(lure2_cb + '.png') ][0]) target_stim = Image.open(item_dir + character + '/' + [ i for i in os.listdir(item_dir + character + '/') if i.startswith(target_cb + '.png') ][0]) char_stim.thumbnail(item_size, Image.ANTIALIAS) lure1_stim.thumbnail(item_size, Image.ANTIALIAS) lure2_stim.thumbnail(item_size, Image.ANTIALIAS) target_stim.thumbnail(item_size, Image.ANTIALIAS) stim_pos = [[-0.5, -0.6], [0, -0.6], [0.5, -0.6]] random.shuffle(stim_pos) scene_pres = visual.ImageStim(win, scene_stim, pos=[0, 0.35]) lure1_pres = visual.ImageStim(win, lure1_stim, pos=stim_pos[0]) lure2_pres = visual.ImageStim(win, lure2_stim, pos=stim_pos[1]) target_pres = visual.ImageStim(win, target_stim, pos=stim_pos[2]) scene_pres.draw() lure1_pres.draw() lure2_pres.draw() target_pres.draw() win.update() timer.reset() # Record response and give feedback while True: if mouse.isPressedIn(target_pres): subject_stim.loc[count, 'Reaction_Time'] = timer.getTime() subject_stim.loc[count, 'Answer'] = target_cb break elif mouse.isPressedIn(lure1_pres): subject_stim.loc[count, 'Reaction_Time'] = timer.getTime() subject_stim.loc[count, 'Answer'] = lure1_cb break elif mouse.isPressedIn(lure2_pres): subject_stim.loc[count, 'Reaction_Time'] = timer.getTime() subject_stim.loc[count, 'Answer'] = lure2_cb break win.update() win.flip() fix_pres = scene_pres = visual.ImageStim(win, fixation, pos=[0, 0]) fix_pres.draw() win.update() core.wait(time_fixcr) win.flip() subject_stim.to_csv(save_subj_file_name) count = count + 1 return subject_stim, context_bind_items, count
pauseClock = core.Clock() ###################################################################################################### ##################### Routine "iViewX_Connect" # routine_helper comps = [] iview_connect_clock = core.Clock() routine_helper = RoutineHelper(win, comps) routine_helper.reset_components() while routine_helper.get_status(): if not routine_helper.get_status(): break routine_helper.set_status(False) if event.getKeys(keyList=conf_escape_keys): core.quit() if routine_helper.get_status(): win.flip() routine_helper.end_components() # end components routineTimer.reset() # reset the non-slip timer ###################################################################################################### ##################### Trials loop setup # set up handler to look after randomisation of conditions etc trials = data.TrialHandler(nReps=conf_total_trials, method='random', extraInfo=expInfo, originPath=-1, trialList=[None],
def do_run(run, trials): resp = [] fileName = log_file.format(subj_id, run) #wait for trigger ready_screen.draw() win.flip() event.waitKeys(keyList=('equal')) globalClock.reset() studyStart = globalClock.getTime() #Initial Fixation screen fixation.draw() win.flip() core.wait(initial_fixation_dur) for trial in trials: condition_label = stim_map[trial['Partner']] imagepath = os.path.join(expdir, 'Images') image = os.path.join(imagepath, "%s.png") % condition_label pictureStim.setImage(image) #decision phase timer.reset() event.clearEvents() decision_onset = globalClock.getTime() trials.addData('decision_onset', decision_onset) #while timer.getTime() < decision_dur: while timer.getTime() < 1: partner_offer = trial['Offer'] partnerOffer = 'Proposal: $%s.00 out of $20.00' % partner_offer offer_text.setText(partnerOffer) offer_text.draw() offer_text.draw() pictureStim.draw() win.flip() resp_val = None resp_onset = None while timer.getTime() < (decision_dur): resp_text_accept.draw() resp_text_reject.draw() pictureStim.draw() offer_text.setText(partnerOffer) offer_text.draw() win.flip() resp = event.getKeys(keyList=responseKeys) if len(resp) > 0: if resp[0] == 'z': #trials.saveAsText(fileName=log_file.format(subj_id),delim=',',dataOut='all_raw') os.chdir(subjdir) trials.saveAsWideText(fileName) os.chdir(expdir) win.close() core.quit() resp_val = int(resp[0]) resp_onset = globalClock.getTime() rt = resp_onset - decision_onset if resp_val == 2: resp_text_reject.setColor('darkorange') if resp_val == 3: resp_text_accept.setColor('darkorange') resp_text_accept.draw() resp_text_reject.draw() pictureStim.draw() offer_text.setText(partnerOffer) offer_text.draw() win.flip() core.wait((decision_dur - rt) + .5) decision_offset = globalClock.getTime() break else: resp_val = 999 rt = 999 resp_onset = 999 outcome_txt = outcome_map[resp_val] decision_offset = globalClock.getTime() trials.addData('resp', resp_val) trials.addData('rt', rt) trials.addData('resp_onset', resp_onset) trials.addData('decision_offset', decision_offset) #win.flip() timer.reset() if resp_val == 999: outcome_stim.setText(outcome_txt) outcome_stim.draw() win.flip() missFB_onset = globalClock.getTime() core.wait(.5) missFB_offset = globalClock.getTime() #reset rating number color resp_text_accept.setColor('#FFFFFF') resp_text_reject.setColor('#FFFFFF') trial_offset = globalClock.getTime() duration = trial_offset - decision_onset trials.addData('trialDuration', duration) event.clearEvents() print "got to check 3" #ITI logging.log(level=logging.DATA, msg='ITI') #send fixation log event timer.reset() ITI_onset = globalClock.getTime() iti_for_trial = float(trial['ITI']) fixation.draw() win.flip() core.wait(iti_for_trial) ITI_offset = globalClock.getTime() trials.addData('ITIonset', ITI_onset) trials.addData('ITIoffset', ITI_offset) # Final Fixation screen after trials completed #fixation.draw() #win.flip() #core.wait(final_fixation_dur) #trials.saveAsText(fileName=log_file.format(subj_id),delim=',',dataOut='all_raw') os.chdir(subjdir) trials.saveAsWideText(fileName) os.chdir(expdir) if globalClock.getTime() < 408: #10 seconds above what task is clocking in at endTime = (408 - globalClock.getTime()) else: endTime = 10 core.wait(endTime) print globalClock.getTime()
def setupExperiment(): from psychopy import gui """ Setup the experimental variables with a dialog box """ dlgMonitor, monitorInfo = setup_monitor() expInfo = { 'Partecipant': 'Subj', 'Subject code': '00', 'SquareEdge': 6, 'BallRadius': 0.5, 'BlinkTime': 3, 'TrainingTrials': 0, 'SaveVideo': False } dlg = gui.DlgFromDict(dictionary=expInfo, title='Flicker Experiment', order=[ 'Partecipant', 'Subject code', 'SquareEdge', 'BallRadius', 'BlinkTime', 'TrainingTrials', ], tip={ 'Partecipant Name': 'Name of the participant', 'Subject code': 'Code of the subject', 'SquareEdge': 'Length of the virtual square edge', 'BallRadius': 'Radius of the balls in cm', 'BlinkTime': 'Time of white/black ball blinking in seconds', 'TrainingTrials': 'Number of preparation training trials', }) if not dlg.OK: core.quit() # user pressed cancel # nUp is the number of incorrect (or 0) responses before the staircase level increases. # nDown is the number of correct (or 1) responses before the staircase # level decreases. staircaseInfo = { 'StepType': ['lin', 'db', 'log'], 'Selection': ['random', 'sequential'], 'MinReversals': 6, 'MinTrials': 10, 'FlickerFreqLeft': 10.0, 'FlickerFreqRight': 10.0, 'StepSizes': '[0.5,0.25]', 'nUpLeft': 1, 'nUpRight': 1, 'nDownLeft': 1, 'nDownRight': 1, 'AverageReversals': 3 } dlgStaircase = gui.DlgFromDict(dictionary=staircaseInfo, title='Staircase procedure') if not dlgStaircase.OK: core.quit() outputfile = set_output_file(expInfo, 'flicker_') save_experimental_settings(outputfile + '_info.pickle', expInfo, staircaseInfo, monitorInfo) return expInfo, staircaseInfo, outputfile, monitorInfo
def do_run(stimset): #instructions if version == 'A' or 'B': instruct_screen.draw() else: instruct_screen_practice.draw() win.flip() event.waitKeys(keyList=('space','2')) if stimset == 'face': instruct_screen1_face.draw() win.flip() else: instruct_screen1_image.draw() win.flip() event.waitKeys(keyList=('space','2')) instruct_screen2.draw() win.flip() event.waitKeys(keyList=('space','2')) if stimset == 'face': if version == 'A' or 'B': instruct_screen3_face.draw() else: instruct_screen3_face_practice.draw() else: if version == 'A' or 'B': instruct_screen3_image.draw() else: instruct_screen3_image_practice.draw() win.flip() event.waitKeys(keyList=('space','2')) #wait for scan trigger if version == 'A' or 'B': ready_screen.draw() else: ready_screen_practice.draw() win.flip() event.waitKeys(keyList=('equal')) run_start = time.time() #set Version ITI, Image orders, feedback order pic_path = os.path.join(os.getcwd(), 'pictureFolder', f'{version}_{stimset}') #lists to store logging clock = core.Clock() clock.reset() onset = [] duration = [] condition = [] resp_val = [] responsetime = [] b_1 = [] b_2 = [] b_3 = [] for trial in reference.iterrows(): trial_start = clock.getTime() row_counter = trial[0] pic_L = visual.ImageStim(win,os.path.join(pic_path, reference.loc[reference.index[row_counter], f'{version}_{stimset}_L']), pos =(-7,0),size=(11.2,17.14)) pic_R = visual.ImageStim(win,os.path.join(pic_path, reference.loc[reference.index[row_counter], f'{version}_{stimset}_R']), pos =(7,0),size=(11.2,17.14)) border = visual.ShapeStim(win, vertices=pic_L.verticesPix, units='pix', fillColor = 'grey', lineColor = 'grey') border2 = visual.ShapeStim(win, vertices=pic_R.verticesPix, units='pix', fillColor = 'grey', lineColor = 'grey') trial_timer = core.CountdownTimer(5.2) while trial_timer.getTime() > 0: #1st fixation if stimset == 'image': timer = core.CountdownTimer(fixation_time + 0.034) else: timer = core.CountdownTimer(fixation_time) while timer.getTime() > 0: fixation.draw() win.flip() fixationPre_dur = clock.getTime() - trial_start #decision_phase timer = core.CountdownTimer(decision_time) resp = event.getKeys(keyList = responseKeys) decision_onset = clock.getTime() while timer.getTime() > 0: pic_L.draw() pic_R.draw() win.flip() resp = event.getKeys(keyList = responseKeys) if len(resp)>0: if 'z' in resp: log.to_csv(os.path.join("data",subj_id, f"{subj_id}_{stimset}-{version}.tsv"), sep='\t', index = False) core.quit() if selected == 2 or 3: selected = int(resp[0]) resp_onset = clock.getTime() rt = resp_onset - decision_onset border.autoDraw=True border2.autoDraw=True pic_L.draw() pic_R.draw() win.flip() core.wait(decision_time - rt) break else: selected = '999' rt = '999' core.wait(.25) decision_dur = clock.getTime() - decision_onset border.autoDraw=False border2.autoDraw=False #2nd fixation timer = core.CountdownTimer(fixation_time) fixationPost_onset = clock.getTime() while timer.getTime() > 0: fixation.draw() win.flip() fixationPost_dur = clock.getTime() - fixationPost_onset #feedback timer = core.CountdownTimer(fb_dur) feedback_onset = clock.getTime() fb_type = reference.loc[reference.index[row_counter], f'{version}_feedback'] if fb_type == 'loss': while timer.getTime() > 0: down_arrow.draw() win.flip() elif fb_type == 'win': while timer.getTime() > 0: up_arrow.draw() win.flip() else: print('Feedback Error') feedback_dur = clock.getTime() - feedback_onset #ITI ITI_onset = clock.getTime() ITI = reference.loc[reference.index[row_counter], f'{version}_ITI'] timer = core.CountdownTimer(ITI) while timer.getTime() > 0: fixation.draw() win.flip() core.wait(ITI) ITI_dur = clock.getTime() - ITI_onset #logging condition.append('fixation_1') onset.append(trial_start) duration.append(fixationPre_dur) resp_val.append('999') responsetime.append('999') condition.append('face') onset.append(decision_onset) duration.append(decision_dur) resp_val.append(selected) responsetime.append(rt) condition.append('fixation_2') onset.append(fixationPost_onset) duration.append(fixationPre_dur) resp_val.append('999') responsetime.append('999') condition.append('feedback ' + fb_type) onset.append(feedback_onset) duration.append(feedback_dur) resp_val.append('999') responsetime.append('999') condition.append('ITI') onset.append(ITI_onset) duration.append(ITI_dur) resp_val.append('999') responsetime.append('999') #BIDS Log b_1.append(decision_onset) b_2.append(decision_dur) b_3.append(fb_type) #data to frame log = pd.DataFrame( {'onset':onset, 'duration':duration, 'trial_type':condition, 'rt':responsetime, 'resp':resp_val}) bidsEvents = pd.DataFrame( {'onset':b_1, 'duration':b_2, 'trial_type':b_3}) log.to_csv(os.path.join("data",subj_id, f"sub-{subj_id}_{stimset}-{version}.tsv"), sep='\t', index = False) bidsEvents.to_csv(os.path.join("data",subj_id, f"sub-{subj_id}_task-socialReward-{stimset}-{version}.tsv"), sep='\t', index = False) run_end = time.time() run_length = run_end -run_start print(run_length) event.clearEvents() return;
from numpy.random import random, randint, normal, shuffle import random import os # Handy system and path functions import sys # to get file system encoding # Ensure that relative paths start from the same directory as this script _thisDir = (os.path.dirname(os.path.abspath(__file__)).decode( sys.getfilesystemencoding())) os.chdir(_thisDir) # Store info about the experiment session expName = 'PDR_script' # From the Builder filename that created this script expInfo = {'participant': '', 'session': ''} dlg = gui.DlgFromDict(dictionary=expInfo, title=expName) if dlg.OK == False: core.quit() # User pressed cancel during popout expInfo['date'] = data.getDateStr() # Add a simple timestamp expInfo['expName'] = expName # Setup the Window win = visual.Window(size=(1280, 800), fullscr=True, allowGUI=False, monitor='testMonitor', color=[1, 1, 1], useFBO=True) # store frame rate of monitor if we can measure it expInfo['frameRate'] = win.getActualFrameRate() # cueversions = np.repeat([0,1,2,3,4,5],4) # Randomizes assignment of cues for participants, counterbalanced, counterbalanced
def flickerTrial(win, experimentalInfo, flickerFreq, side, useOddBall): from psychopy import visual, event """ Start the tracking trial """ # Generate the 4 balls as list balls = [] edge = experimentalInfo['SquareEdge'] # First two balls are left, second two balls are right positions = [ np.array([-edge / 2, -edge / 2]), np.array([-edge / 2, edge / 2]), np.array([edge / 2, -edge / 2]), np.array([edge / 2, edge / 2]) ] for i in range(0, 4): balls.append( Ball(win, position=positions[i], direction=np.array([0, 0]), speed=0, radius=experimentalInfo['BallRadius'], color='Black')) fixationBall = Ball(win, position=np.array([0.0, 0.0]), direction=np.array([0.0, 0.0]), speed=0.0, radius=0.15, color='White') oddBallIndex = randrange(0, 4) oddBalls = [balls[oddBallIndex]] noiseMaskStimuli = [] for i in range(0, 4): noiseMaskStimuli.append( visual.GratingStim(win, pos=positions[i], units='cm', tex=np.random.rand(256, 256) * 2.0 - 1.0, mask='circle', size=[ experimentalInfo['BallRadius'] * 2, experimentalInfo['BallRadius'] * 2 ])) arrows = [ visual.TextStim(win, "-->", pos=[0, 0]), visual.TextStim(win, "<--", pos=[0, 0]) ] # Initialize a color for the balls for ball in balls: ball.setColor('Black') if useOddBall: for oddBall in oddBalls: oddBall.setColor('White') # Draw the arrow cue trialClock = core.Clock() trialClock.reset() sideIndex = (side == 'Left') while (trialClock.getTime() < 2.0): arrows[sideIndex].draw() if (experimentalInfo['SaveVideo']): win.getMovieFrame() win.flip() totalMaskTime = 0.350 # seconds totalMaskTimeInFrames = int(round(totalMaskTime * win.measuredFPS)) for t in range(0, totalMaskTimeInFrames): for i in range(0, 4): noiseMaskStimuli[i].draw() if (experimentalInfo['SaveVideo']): win.getMovieFrame() win.flip() # Here instead of using timers we precompute the number of frames to display for the stimuli, so # that the calls to timers are avoided and the program is faster between # two flips totStimFrames = int(round(experimentalInfo['BlinkTime'] * win.measuredFPS)) totBlinkFrames = int(round(1.0 / flickerFreq * win.measuredFPS)) blinkFrame, totBlinks = 0, 0 times = [None] * totStimFrames switchIndices = [] for t in range(0, totStimFrames): fixationBall.draw() blinkFrame = blinkFrame + 1 oldTotBlinks = totBlinks if (blinkFrame >= totBlinkFrames): blinkFrame = 0 totBlinks = totBlinks + 1 if (oldTotBlinks < totBlinks): switchIndices.append(t) if (totBlinks % 2): for ball in balls: ball.setColor('White') if useOddBall: for oddBall in oddBalls: oddBall.setColor('Black') else: for ball in balls: ball.setColor('Black') if useOddBall: for oddBall in oddBalls: oddBall.setColor('White') for ball in balls: ball.draw() if (experimentalInfo['SaveVideo']): win.getMovieFrame() times[t] = win.flip() totalMaskTimeInFrames = int(round(totalMaskTime * win.measuredFPS)) for t in range(0, totalMaskTimeInFrames): for i in range(0, 4): noiseMaskStimuli[i].draw() if (experimentalInfo['SaveVideo']): win.getMovieFrame() win.flip() times = np.array(times) # switchIndices=np.array(switchIndices) # switchTimes=np.diff(times[switchIndices]) # print "Average switch times",np.average(switchTimes),"corresponding to ",1.0/np.average(switchTimes)," [Hz]" # print "Average inversion times # error=",np.average(switchTimes-1.0/flickerFreq)*1000,"[ms]" # Get the subject response event.getKeys() trialClock = core.Clock() trialClock.reset() response = None while True: keys = event.getKeys() fixationBall.draw() if 's' in keys: response = (sideIndex == (oddBallIndex >= 2)) trialClock.reset() break if 'd' in keys: response = (sideIndex == (oddBallIndex < 2)) trialClock.reset() break if 'escape' in keys: win.close() core.quit() if (experimentalInfo['SaveVideo']): win.getMovieFrame() win.flip() print sideIndex, side, oddBallIndex, response if (experimentalInfo['SaveVideo']): import os currentpath = os.getcwd() savedatapath = currentpath + os.path.sep + 'data' outputVideo = savedatapath + os.path.sep + \ "frames" + os.path.sep + 'Flicker.png' print "Saving video to " + outputVideo win.saveMovieFrames(outputVideo) return response
def end(): ### end of this exp, disp thank you instr end = images['end'][0].draw() win.flip() event.waitKeys(keyList=['space']) core.quit()
from numpy.random import random, randint, normal, shuffle import os # handy system and path functions import sys # to get file system encoding import csv # Ensure that relative paths start from the same directory as this script _thisDir = os.path.dirname(os.path.abspath(__file__)) os.chdir(_thisDir) # Store info about the experiment session expName = 'SelfCont' # from the Builder filename that created this script expInfo = {'participant':'', 'session':'01'} dlg = gui.DlgFromDict(dictionary=expInfo, title=expName) if dlg.OK == False: core.quit() # user pressed cancel expInfo['date'] = data.getDateStr() # add a simple timestamp expInfo['expName'] = expName endExpNow = False # flag for 'escape' or other condition => quit the exp # Data file name stem = absolute path + name; later add .psyexp, .csv, .log, etc filename= _thisDir + os.sep + u'SelfCont' + os.sep + '%s_%s' % (expInfo['participant'], expName + ".csv") #################################################################################################### # Program Constants # #################################################################################################### # Set psychopy required names for things EXP_NAME = "self_control_questionnaire" # The name of the experiment for save files MONITOR_NAME = "testMonitor" # The name of the monitor set in PsychoPy.