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 writeScript(self, expPath=None): """Write a PsychoPy script for the experiment """ self.expPath = expPath script = IndentingBuffer(u"") # a string buffer object script.write( "#!/usr/bin/env python\n" + "# -*- coding: utf-8 -*-\n" + '"""\nThis experiment was created using PsychoPy2 Experiment Builder (v%s), %s\n' % (self.psychopyVersion, data.getDateStr(format="%B %d, %Y, at %H:%M")) + "If you publish work using this script please cite the relevant PsychoPy publications\n" + " Peirce, JW (2007) PsychoPy - Psychophysics software in Python. Journal of Neuroscience Methods, 162(1-2), 8-13.\n" + ' Peirce, JW (2009) Generating stimuli for neuroscience using PsychoPy. Frontiers in Neuroinformatics, 2:10. doi: 10.3389/neuro.11.010.2008\n"""\n' ) script.write( "from numpy import * #many different maths functions\n" + "from numpy.random import * #maths randomisation functions\n" + "import os #handy system and path functions\n" + "from psychopy import %s\n" % ", ".join(self.psychopyLibs) + "import psychopy.log #import like this so it doesn't interfere with numpy.log\n\n" ) self.namespace.user.sort() script.write( "#User-defined variables = %s\n" % str(self.namespace.user) + "known_name_collisions = %s #(collisions are bad)\n\n" % str(self.namespace.get_collisions()) ) self.settings.writeStartCode(script) # present info dlg, make logfile, Window # delegate rest of the code-writing to Flow self.flow.writeCode(script) self.settings.writeEndCode(script) # close log file return script
def _setExperimentInfo(self, author, version, verbose): # try to auto-detect __author__ and __version__ in sys.argv[0] (= the users's script) if not author or not version: if os.path.isfile(sys.argv[0]): f = open(sys.argv[0], 'r') lines = f.read() f.close() if not author and '__author__' in lines: linespl = lines.splitlines() while linespl[0].find('__author__') == -1: linespl.pop(0) auth = linespl[0] if len(auth) and '=' in auth: try: author = str(eval(auth[auth.find('=')+1 :])) except: pass if not version and '__version__' in lines: linespl = lines.splitlines() while linespl[0].find('__version__') == -1: linespl.pop(0) ver = linespl[0] if len(ver) and ver.find('=') > 0: try: version = str(eval(ver[ver.find('=')+1 :])) except: pass if author or verbose: self['experimentAuthor'] = author if version or verbose: self['experimentAuthVersion'] = version # script identity & integrity information: self['experimentScript'] = os.path.basename(sys.argv[0]) # file name scriptDir = os.path.dirname(os.path.abspath(sys.argv[0])) self['experimentScript.directory'] = scriptDir # sha1 digest, text-format compatibility self['experimentScript.digestSHA1'] = _getSha1hexDigest(os.path.abspath(sys.argv[0]), isfile=True) # subversion revision? try: svnrev, last, url = _getSvnVersion(os.path.abspath(sys.argv[0])) # svn revision if svnrev: # or verbose: self['experimentScript.svnRevision'] = svnrev self['experimentScript.svnRevLast'] = last self['experimentScript.svnRevURL'] = url except: pass # mercurical revision? try: hgChangeSet = _getHgVersion(os.path.abspath(sys.argv[0])) if hgChangeSet: # or verbose: self['experimentScript.hgChangeSet'] = hgChangeSet except: pass # when was this run? self['experimentRunTime.epoch'] = core.getAbsTime() self['experimentRunTime'] = data.getDateStr(format="%Y_%m_%d %H:%M (Year_Month_Day Hour:Min)")
def get_subject_info(): try: expInfo = fromFile('../data/lastParams.pickle') # check existence of previous parameter file except: expInfo = {'pseudo':'pseudo'} expInfo['date']= data.getDateStr() #add current time #present a dialog box to get user info dlg = gui.DlgFromDict(expInfo, title='Experiment', fixed=['date']) if dlg.OK: toFile('../data/lastParams.pickle', expInfo)#save params to file for next time else: core.quit()#cancel -> exit return expInfo
def experimentInfo(self, expName = "SET EXPERIMENT NAME"): self.expName = expName self.expInfo = {'Subject Id':'', 'Age':'', 'Experiment Version': 0.1, 'Sex': ['Male', 'Female', 'Other']} self.expInfo[u'date'] = data.getDateStr(format="%Y-%m-%d_%H:%M") self.infoDlg = gui.DlgFromDict(dictionary=self.expInfo, title=self.expName, fixed=['Experiment Version']) self.expInfo[u'DataFile'] = u'Data' + os.path.sep + u'DATA_Local-Global_Task.csv' if self.infoDlg.OK: return self.expInfo else: return 'Cancelled'
def callDialog(self): """Fire up the dialog instance and return the data""" # Set up dialog data for item in self.dialog_data: self.info[item] = "" dlg = gui.DlgFromDict(dictionary=self.info, title=self.expName) if not dlg.OK: core.quit() # Tack on date self.info["dateStr"] = data.getDateStr() # will create str of current date/time return self.info
def info_gui(expName, expInfo): infoDlg = gui.DlgFromDict(expInfo, title = '%s Subject details:'%(expName)) #set the name of the pop up window expInfo['date'] = data.getDateStr() # add a simple timestamp to the experiment expInfo['expName'] = expName datalog_fn = 'data_' + expName + os.sep + '%s_%s_%s_%s' %(expInfo['subject'], expInfo['session'], expName, expInfo['date']) def make_sure_path_exists(path): try: os.makedirs(path) except OSError as exception: if exception.errno != errno.EEXIST: raise make_sure_path_exists('data_' + expName) timelog(datalog_fn) if infoDlg.OK == False: #stop experiment if press cancel print 'User Cancelled' core.quit() # user pressed cancel return expInfo, datalog_fn
tasktype = sessioninfo[4] actual = [] #the correct response response = [] # given response by the user digitcolor = [] # color of the digit numValue = [] # value of the number taskstore = [] #the task being performed at a given instant rTime = [] #reaction times for each experiment lettPress = [] #the letter the subject pressed #filename filename = '' filename = 'Switchcost' filename += idn filename += '_' + str(sessnumber) filename += '_' + data.getDateStr() print(filename) datetime = data.getDateStr() #window #*******************************Question Default Screen Color mywin = visual.Window([800, 600], monitor="testMonitor", units="pix") #rgb=[-1,-1,-1] makes screen black random.seed() #initializes by reading the time global digitVal global digitColor global endAnswer endAnswer = 0 numbers = [1, 2, 3, 4, 6, 7, 8, 9] colors = [
#ntrials3 = 100 #nblocks3 = 2 #blockSize3 = 100 # uncomment for debug run #ntrials = 4 #nblocks = 4 #blockSize = 4 #create a window to draw in myWin =visual.Window((1280,1024), allowGUI=True, bitsMode=None, units='norm', winType='pyglet', color=(-1,-1,-1)) # Admin expInfo = {'subject':'test','date':data.getDateStr(),'practice':True,'speed time':speedTime,'trial time':1500} #expInfo['dateStr']= data.getDateStr() #add the current time #expInfo['practice'] = True #present a dialogue to change params ok = False while(not ok): dlg = gui.DlgFromDict(expInfo, title='Moving Dots', fixed=['dateStr'],order=['date','subject','practice','speed time','trial time']) if dlg.OK: misc.toFile('lastParams.pickle', expInfo)#save params to file for next time ok = True else: core.quit()#the user hit cancel so exit # setup data file
'display': ['oculus', 'laptop'], 'Moog': ['yes', 'no'], 'n_adjust': 1} dlg = gui.DlgFromDict(dictionary=V, title=exp_name, order=['participant_number', 'participant_name', 'age', 'hand', 'gender', 'xpos', 'session', 'adaptation', 'belief_side', 'tilt_position', 'belief', 'task', 'reps', 'Moog', 'display', 'n_adjust', 'estimation_method']) if not dlg.OK: core.quit() V['date'] = data.getDateStr() V['exp_name'] = exp_name """ workaround for dropdown selection error: https://groups.google.com/forum/#!topic/psychopy-users/jV8JBSwIUWk """ from psychopy import visual # experiment parameters valid_responses = ['f', 'j', 'escape'] audio_dir = 'audio' RANGE = 3 # test orientations lie in the range [svv-RANGE, svv+RANGE] # number of test orientations around estimate
) if dialogue_box.OK: print(dialogue_content) else: print('User Cancelled') core.quit() # Ensure that relative paths start from the same directory as this script # current_dir = os.path.dirname(os.path.abspath(__file__)) # os.chdir(current_dir) # Store info about the experiment session experiment_name = 'CFS popping time' # from the Builder filename that created this script experiment_info = {u'session': u'001', u'participant': u''} experiment_info['date'] = data.getDateStr() # add a simple timestamp experiment_info['experiment_name'] = experiment_name # Data file name stem = absolute path + name; later add .psyexp, .csv, .log, etc filename = 'data/'+ str(dialogue_box.data[0]) # An ExperimentHandler isn't essential but helps with data saving current_experiment = data.ExperimentHandler( name=experiment_name, extraInfo=experiment_info, runtimeInfo=None, #originPath=u'/Users/alex/Documents/Popping Time/', savePickle=True, saveWideText=False, dataFileName=filename)
parser.add_argument('-s','--subj',default='s666',type=str,help='subject #') parser.add_argument('-c','--scrn',default='lewpea',type=str,choices=list(SCREENS.keys()),help='screen used for display') parser.add_argument('-o','--order',default=None,type=str,choices=['A','T'],help='which category is paired with forget cues') parser.add_argument('-p','--phase',default=None,type=str,help='start from this phase, indented for dev only') args = parser.parse_args() #================================================= # Set some stimulus parameters and other constants #================================================= PROJ_NAME = 'imdifrep' SUBJ = args.subj SCRN = args.scrn ORDER = args.order DEV = SUBJ in ['s666','sim','s777'] DATE = data.getDateStr() home = os.getcwd() #i/o data_dir = os.getcwd() assert os.path.split(data_dir)[-1] == PROJ_NAME #make sure we are in an imdifrep directory #read in the design file with everything on it design = pd.read_csv('imdifrep_design.csv') #initialize the parallel port if in the testing room if BIO: port = parallel.ParallelPort(address=0xDFF8) port.setData(0)
# real session - 24. divided to 18 (go or nogo) and 6 (the opposite). stimulus display for 1,2 or 3s. intertrial was 1.5s # attched is a .odt document with the conditions (as suggested by Prof. Andrea Berger). from psychopy import core, visual, gui, data, misc, event, sound import time, os, random, numpy # now turn to right folder directory=os.getcwd() # get folder os.chdir(directory) # use it #folder='/home/ord/Experiments_BP_Clinic/PCT/' #specify the folder of result files to be saved in # savine last experiment data try:#try to get a previous parameters file expInfo = misc.fromFile('gonogo.pickle') except:#if not there then use a default set expInfo = {'subject no':''} expInfo['dateStr']= data.getDateStr() #add the current time # dialouge box for name of subject and file dlg = gui.DlgFromDict(expInfo, title='Go/NoGo Task', fixed=['dateStr']) if dlg.OK: misc.toFile('gonogo.pickle', expInfo)#save params to file for next time else: core.quit()#the user hit cancel so exit # check if folder exist and if not, create it if not os.path.exists('results'): os.makedirs('results') fileName = expInfo['subject no'] + expInfo['dateStr'] dataFile = open(directory+'/results/'+fileName+'.csv', 'w')#a simple text file with 'comma-separated-values' dataFile.write('trialNo,trial,RT,press,answer\n')
file_name.write( str(sides) + ',' + str((fillcolor == None)) + ',' + str(signal_radius) + ',' + str(test_radius) + ',' + str(thisResp) + '\n') core.wait(1.0) mywin.flip() staircase.saveAsPickle('poly-' + str(sides) + '_' + str(fillcolor == None) + '_' + str(radius)) print('reversals:') print(staircase.reversalIntensities) approxThreshold = numpy.average(staircase.reversalIntensities[-6:]) print('mean of final 6 reversals = %.3f' % (approxThreshold)) subject_name = {'Name': 'please enter your name'} subject_name['time_and_date'] = data.getDateStr() dlg = gui.DlgFromDict(subject_name, title='Weber\'s Law Experiment', fixed=['time_and_date']) if dlg.OK: toFile('parameters.pickle', subject_name) else: core.quit() file_name = subject_name['Name'] + subject_name['time_and_date'] text_file = open(file_name + '.csv', 'w') text_file.write('polygon,outline_or_filled, signal_size, test_size, correct\n') mywin = visual.Window([1920, 1080], allowGUI=True, monitor='testMonitor',
def _setExperimentInfo(self, author, version, verbose, randomSeedFlag=None): # try to auto-detect __author__ and __version__ in sys.argv[0] (= the users's script) if not author or not version: f = open(sys.argv[0],'r') lines = f.read() f.close() if not author and lines.find('__author__')>-1: linespl = lines.splitlines() while linespl[0].find('__author__') == -1: linespl.pop(0) auth = linespl[0] if len(auth) and auth.find('=') > 0: try: author = str(eval(auth[auth.find('=')+1 :])) except: pass if not version and lines.find('__version__')>-1: linespl = lines.splitlines() while linespl[0].find('__version__') == -1: linespl.pop(0) ver = linespl[0] if len(ver) and ver.find('=') > 0: try: version = str(eval(ver[ver.find('=')+1 :])) except: pass if author or verbose: self['experimentAuthor'] = author if version or verbose: self['experimentAuthVersion'] = version # script identity & integrity information: self['experimentScript'] = os.path.basename(sys.argv[0]) # file name scriptDir = os.path.dirname(os.path.abspath(sys.argv[0])) self['experimentScript.directory'] = scriptDir # sha1 digest, text-format compatibility self['experimentScript.digestSHA1'] = _getSha1hexDigest(os.path.abspath(sys.argv[0]), file=True) # subversion revision? try: svnrev, last, url = _getSvnVersion(os.path.abspath(sys.argv[0])) # svn revision if svnrev: # or verbose: self['experimentScript.svnRevision'] = svnrev self['experimentScript.svnRevLast'] = last self['experimentScript.svnRevURL'] = url except: pass # mercurical revision? try: hgChangeSet = _getHgVersion(os.path.abspath(sys.argv[0])) if hgChangeSet: # or verbose: self['experimentScript.hgChangeSet'] = hgChangeSet except: pass # when was this run? self['experimentRunTime.epoch'] = core.getAbsTime() # basis for default random.seed() self['experimentRunTime'] = data.getDateStr(format="%Y_%m_%d %H:%M (Year_Month_Day Hour:Min)") # random.seed -- record the value, and initialize random.seed() if 'set:' if randomSeedFlag: randomSeedFlag = str(randomSeedFlag) while randomSeedFlag.find('set: ') == 0: randomSeedFlag = randomSeedFlag.replace('set: ','set:',1) # spaces between set: and value could be confusing after deleting 'set:' randomSeed = randomSeedFlag.replace('set:','',1).strip() if randomSeed in ['time']: randomSeed = self['experimentRunTime.epoch'] self['experimentRandomSeed.string'] = randomSeed if randomSeedFlag.find('set:') == 0: random.seed(self['experimentRandomSeed.string']) # seed it self['experimentRandomSeed.isSet'] = True else: self['experimentRandomSeed.isSet'] = False else: self['experimentRandomSeed.string'] = None self['experimentRandomSeed.isSet'] = False
# -- GET INPUT FROM THE EXPERIMENTER -- exptInfo = { '01. Participant Code': '00', '02. Experiment name': 'test', '03. Number of repeats': 3, '04. Speeds (cm/sec)': '1,3,30', '05. Stimuli': 'soft brush', '06. Stimulation site': 'dorsal left hand', '08. Participant language': ('en'), ## ('en','sv') '09. Folder for saving data': 'data' } dlg = gui.DlgFromDict(exptInfo, title='Experiment details') if dlg.OK: exptInfo['10. Date and time'] = data.getDateStr( format='%Y-%m-%d_%H-%M-%S') ##add the current time and continue else: core.quit() ## the user hit cancel so exit # -- # -- DISPLAY TEXT -- displayTextDictionary = { 'en': { 'waitMessage': 'Please wait.', 'interStimMessage': '...', 'finishedMessage': 'Session finished.', 'strokeQuestion': 'How pleasant was the last stimulus on your skin?', 'strokeMin': 'very unpleasant', 'strokeMax': 'very pleasant'
def writeScript(self, expPath=None, target="PsychoPy", modular=True): """Write a PsychoPy script for the experiment """ # set this so that params write for approp target utils.scriptTarget = target self.flow._prescreenValues() self.expPath = expPath script = IndentingBuffer(u'') # a string buffer object # get date info, in format preferred by current locale as set by app: if hasattr(locale, 'nl_langinfo'): fmt = locale.nl_langinfo(locale.D_T_FMT) localDateTime = data.getDateStr(format=fmt) else: localDateTime = data.getDateStr(format="%B %d, %Y, at %H:%M") if target == "PsychoPy": self.settings.writeInitCode(script, self.psychopyVersion, localDateTime) self.settings.writeStartCode(script) # present info, make logfile # writes any components with a writeStartCode() self.flow.writeStartCode(script) self.settings.writeWindowCode(script) # create our visual.Window() # for JS the routine begin/frame/end code are funcs so write here # write the rest of the code for the components self.flow.writeBody(script) self.settings.writeEndCode(script) # close log file script = script.getvalue() elif target == "PsychoJS": script.oneIndent = " " # use 2 spaces rather than python 4 self.settings.writeInitCodeJS(script, self.psychopyVersion, localDateTime, modular) self.flow.writeFlowSchedulerJS(script) self.settings.writeExpSetupCodeJS(script) # initialise the components for all Routines in a single function script.writeIndentedLines("\nfunction experimentInit() {") script.setIndentLevel(1, relative=True) # routine init sections for entry in self.flow: # NB each entry is a routine or LoopInitiator/Terminator self._currentRoutine = entry if hasattr(entry, 'writeInitCodeJS'): entry.writeInitCodeJS(script) # create globalClock etc code = ("// Create some handy timers\n" "globalClock = new util.Clock();" " // to track the time since experiment started\n" "routineTimer = new util.CountdownTimer();" " // to track time remaining of each (non-slip) routine\n" "\nreturn Scheduler.Event.NEXT;") script.writeIndentedLines(code) script.setIndentLevel(-1, relative=True) script.writeIndentedLines("}\n") # This differs to the Python script. We can loop through all # Routines once (whether or not they get used) because we're using # functions that may or may not get called later. # Do the Routines of the experiment first routinesToWrite = list(self.routines) for thisItem in self.flow: if thisItem.getType() in ['LoopInitiator', 'LoopTerminator']: self.flow.writeLoopHandlerJS(script) elif thisItem.name in routinesToWrite: self._currentRoutine = self.routines[thisItem.name] self._currentRoutine.writeRoutineBeginCodeJS(script) self._currentRoutine.writeEachFrameCodeJS(script) self._currentRoutine.writeRoutineEndCodeJS(script) routinesToWrite.remove(thisItem.name) self.settings.writeEndCodeJS(script) try: script = py2js.addVariableDeclarations(script.getvalue()) except esprima.error_handler.Error: script = script.getvalue() print("Failed to parse as JS by esprima") self.flow._resetLoopController() # Reset loop controller ready for next call to writeScript return script
labelButtonCancel=' No ', screen=-1) ok_data = datadlg.show() glasses = datadlg.OK if recordData: #OUTPUT FILE PATH PATH = 'C:\\Users\\chand\\OneDrive\\Desktop\\Visual-Acuity\\Crowded Center' OUTPATH = '{0:s}\\Data\\'.format(PATH) #CD TO SCRIPT DIRECTORY _thisDir = os.path.dirname(os.path.abspath(__file__)) os.chdir(_thisDir) #STORE INFO ABOUT EXPERIMENT SESSION expName = 'Crowded Center Circle' date = data.getDateStr(format='%m-%d') expInfo = {'Participant': ''} #DIALOGUE WINDOW FOR PARTICIPANT NAME dlg = gui.DlgFromDict(dictionary=expInfo, sortKeys=False, title=expName) if dlg.OK == False: core.quit() #CREATE FILE NAME, PRINT HEADER IF FILE DOESN'T EXIST filename = OUTPATH + u'%s_%s_%s' % (expInfo['Participant'], date, expName) + '.csv' if not os.path.isfile(filename): csvOutput( ["Direction", "Letter Height (degrees)", "Eccentricity (degrees)"]) #WINDOW CREATION
'age': EXP_info[1], 'gender': EXP_info[2], 'scanner': EXP_info[3], 'scan_day': EXP_info[4], 'onset': time_flip - exp_start, 'offset': offset - exp_start, 'duration_measured': offset - time_flip, 'response': 'NA', 'key_t': 'NA', 'rt': offset - time_flip, 'con': 'inani' + str(i) }, ignore_index=True) ############# Saves data ################################ date = data.getDateStr() OUTPUT_folder = 'animate_inanimate_exp_data' #saves to this folder OUTPUT_filename = OUTPUT_folder + '/log_' + str( EXP_info[0]) + '_' + date + '.csv' DATA.to_csv(OUTPUT_filename) ############# Outro text ################################ outroText = ''' This is the end of the experiment. Thank you for your participation! '''
experiment_trial(is_reward, is_even, position_arms, window, right_highlight, left_highlight, grating_h, grating_v, plus_one, zero_pound, minus_one) cpt_iteration += 1 print("%d experiment trials has been performed." % cpt_iteration) # Store info about the experiment session expName = 'bandit_cont' expInfo = { 'gui': { 'participant_number': participant_number, 'cond_num': cond_num, 'age': age, 'gender': gender }, 'date': data.getDateStr(), 'expName': expName, 'frameRate': window.getActualFrameRate() } # store frame rate of monitor if we can measure it if expInfo['frameRate'] != None: frameDur = 1.0 / round(expInfo['frameRate']) else: frameDur = 1.0 / 60.0 # could not measure, so guess print("expInfo", expInfo) # Data file name stem = absolute path + name; later add .psyexp, .csv, .log, etc _thisDir = os.curdir psychopy.logging.debug(expInfo)
def htmlReport(self, items=None, fatal=False): """Return an html report given a list of (key, val, msg, warn) items. format triggers: 'Critical issue' in fatal gets highlighted warn == True -> highlight key and val val == msg == '' -> use key as section heading """ imgfile = os.path.join(self.prefs.paths['resources'], 'psychopySplash.png') _head = (u'<html><head><meta http-equiv="Content-Type" ' 'content="text/html; charset=utf-8"></head><body>' + '<a href="http://www.psychopy.org"><img src="%s" ' 'width=396 height=156></a>') self.header = _head % imgfile # self.iconhtml = '<a href="http://www.psychopy.org"><img src="%s" # width=48 height=48></a>' % self.iconfile _foot = _translate('This page was auto-generated by the ' 'PsychoPy configuration wizard on %s') self.footer = ('<center><font size=-1>' + _foot % data.getDateStr(format="%Y-%m-%d, %H:%M") + '</font></center>') htmlDoc = self.header if fatal: # fatal is a list of strings: htmlDoc += ('<h2><font color="red">' + _translate('Configuration problem') + '</font></h2><hr>') for item in fatal: item = item.replace('Critical issue', '<p><strong>') item += _translate('Critical issue') + '</strong>' htmlDoc += item + "<hr>" else: # items is a list of tuples: htmlDoc += ('<h2><font color="green">' + _translate('Configuration report') + '</font></h2>\n') numWarn = len(self.warnings) if numWarn == 0: htmlDoc += _translate('<p>All values seem reasonable (no ' 'warnings, but there might still be ' 'room for improvement).</p>\n') elif numWarn == 1: _warn = _translate('1 suboptimal value was detected</font>, ' 'see details below (%s).</p>\n') htmlDoc += ('<p><font color="red">' + _warn % (self.warnings[0])) elif numWarn > 1: _warn = _translate('%(num)i suboptimal values were detected' '</font>, see details below (%(warn)s).' '</p>\n') htmlDoc += ('<p><font color="red">' + _warn % {'num': numWarn, 'warn': ', '.join(self.warnings)}) htmlDoc += '''<script type="text/javascript"> // Loops through all rows in document and changes display // property of rows with a specific ID // toggle('ok', '') will display all rows // toggle('ok', 'none') hides ok rows, leaving Warning // rows shown function toggle(ID, display_value) { var tr=document.getElementsByTagName('tr'), i; for (i=0;i<tr.length;i++) { if (tr[i].id == ID) tr[i].style.display = display_value; } } </script> <p> <button onClick="toggle('ok', 'none');">''' htmlDoc += _translate('Only show suboptimal values') + \ '</button>' + \ '''<button onClick="toggle('ok', '');">''' + \ _translate('Show all information') + '</button></p>' htmlDoc += _translate('''<p>Resources: | <a href="http://www.psychopy.org/documentation.html">On-line documentation</a> | Download <a href="http://www.psychopy.org/PsychoPyManual.pdf">PDF manual</a> | <a href="http://groups.google.com/group/psychopy-users">Search the user-group archives</a> </p>''') htmlDoc += '<hr><p></p> <table cellspacing=8 border=0>\n' htmlDoc += ' <tr><td><font size=+1><strong>' + \ _translate('Configuration test</strong> or setting') +\ '</font></td><td><font size=+1><strong>' + _translate('Version or value') +\ '</strong></font></td><td><font size=+1><em>' + \ _translate('Notes') + '</em></font></td>' for (key, val, msg, warn) in items: if val == msg == '': key = '<font color="darkblue" size="+1"><strong>' + \ _translate(key) + '</strong></font>' else: key = ' ' + _translate(key) if warn: key = '<font style=color:red><strong>' + \ _translate(key) + '</strong></font>' val = '<font style=color:red><strong>' + val + '</strong></font>' id = 'Warning' else: id = 'ok' htmlDoc += ' <tr id="%s"><td>' % id htmlDoc += key + '</td><td>' + val + '</td><td><em>' + msg + '</em></td></tr>\n' htmlDoc += ' </table><hr>' htmlDoc += self.footer if not fatal and numWarn: htmlDoc += """<script type="text/javascript">toggle('ok', 'none'); </script>""" htmlDoc += '</body></html>' self.reportText = htmlDoc
def main(): save_path = "cued-recall-data/" if not os.path.exists(save_path): os.makedirs(save_path) #win.winHandle.minimize() #win.flip() expInfo = {'Participant': 1, 'Gender': ['M', 'F', "O"], 'Age': 18} expInfo['dateStr'] = data.getDateStr() dlg = gui.DlgFromDict(expInfo, title="Basic Information", fixed=['dateStr'], order=['Participant', 'Age', 'Gender']) if not dlg.OK: core.quit() #win.winHandle.maximize() #win.winHandle.activate() #win.fullscr=True #win.winHandle.set_fullscreen(True) #win.flip() pNo = expInfo["Participant"] gen = expInfo["Gender"] age = expInfo["Age"] date = expInfo['dateStr'] press_key("Press SPACE to start.") # study for pair in range(NLEARN): study_pair(image=block_list[pair]["image"], word=block_list[pair]["word"]) instr.text = "RECALL" instr.draw() win.flip() core.wait(1) recall_order = list( range(NLEARN) ) # range has changed in python 3, now must be converted to a list to shuffle random.shuffle(recall_order) # recall for pair in recall_order: recalled, acc, rt = recall_pair(cue_image=block_list[pair]["image"], correct_word=block_list[pair]["word"]) # add to dictionary block_list[pair]["recall_order"] = recall_order.index(pair) + 1 block_list[pair]["recalled"] = recalled block_list[pair]["recall_acc"] = acc block_list[pair]["recall_rt"] = rt #print(block_list) block_list_pd = pd.DataFrame(block_list) block_list_pd["pid"] = pNo block_list_pd["date"] = date block_list_pd["age"] = age file_name = save_path + "p" + str(pNo) + "_" + date block_list_pd.to_csv(file_name + ".csv") block_list_pd.to_pickle(file_name + ".pkl")
info = {'Session': 1, 'Subject':'', 'gender':['male','female']} dialog = gui.DlgFromDict(dictionary= info, title='MPRR with Joystick') if dialog.OK: infoUser = dialog.data #Subject's data is saved in infoUser and are ready to print them on each file else: print('user cancelled') core.quit() #Date is saved on each trial info['dateStr'] = data.getDateStr() #We create a screen on which our program will run #We also set up the internal clock meanwhile the remaining functions are ready to use mywin = visual.Window([1366,768], fullscr = False, monitor='testMonitor', color='black',units='deg', allowGUI = False) respClock = core.Clock() joystick.backend='pyglet' nJoysticks=joystick.getNumJoysticks() if nJoysticks>0: joy = joystick.Joystick(0)
from psychopy.sound import Sound from numpy.random import random #========= # Settings #========= datapath = 'data' exp_info = {'participant': 'x', 'pair': 1} scrsize = (1024, 768) changetime = 2.5 timelimit = 2.5 n_trials = 5 ind_threshold = 0.3 # between 0 and 1 # Get date and time exp_info['date'] = data.getDateStr() exp_info['exp_name'] = 'ddm' # Create a unique filename for the experiment data if not os.path.isdir(datapath): os.makedirs(datapath) data_fname = exp_info['participant'] + '_' + exp_info['date'] data_fname = os.path.join(datapath, data_fname) #========================== # Create window and stimuli #========================== # Open a window # (Change to fullscreen) win = visual.Window(size=scrsize, units='pix', fullscr=False)
# E.g.: When ImageServerWindow is initialized. # [Log] Record experiment events to file import time from lumos.net import EventLogger logEvents = True if logEvents: eventTag = "TRIAL" eventFilename = "logs/trial-events_{}_{}_{}.log".format(target, num_stimuli, time.strftime(EventLogger.timestamp_format, time.localtime(time.time()))) eventLogger = EventLogger(eventFilename, rpc_export=False, start_server=False) # no need to expose event logger, this is for local logging only (TODO: design a logger proxy and then enable this to provide a common logging target) # Store info about the experiment session expName = u'zelinsky' # from the Builder filename that created this script expInfo = {u'session': u'000', u'participant': u'0'} expInfo['expName'] = expName expInfo['date'] = data.getDateStr('%Y-%m-%d_%H-%M-%S') # add a simple timestamp expInfo['target'] = target expInfo['num_stimuli'] = num_stimuli # Setup files for saving if not os.path.isdir('data'): os.makedirs('data') # if this fails (e.g. permissions) we will get error filename = 'data' + os.path.sep + '%s_%s' %(expInfo['participant'], expInfo['date']) logging.console.setLevel(logging.WARNING) # this outputs to the screen, not a file # An ExperimentHandler isn't essential but helps with data saving thisExp = data.ExperimentHandler(name=expName, version='', extraInfo=expInfo, runtimeInfo=None, originPath=None, savePickle=True, saveWideText=True, dataFileName=filename)
def setup(self): """ Setup experiment info, log file and window """ self._thisDir = os.path.dirname(os.path.abspath(__file__)) os.chdir(self._thisDir) expName = 'SemanticIntegration' # from the Builder filename that created this script expInfo = { 'mode': 'experiment', 'participant': '', 'session': '001', 'run': '1', 'list': 'generate', 'screen': '0', 'Send triggers': 'yes' } dlg = gui.DlgFromDict(dictionary=expInfo, sortKeys=False, title=expName) if dlg.OK == False: core.quit() # user pressed cancel expInfo['date'] = data.getDateStr() # add a simple timestamp expInfo['expName'] = expName expInfo['psychopyVersion'] = self.psychopyVersion filename = self._thisDir + os.sep + u'data/%s_%s_%s_%s' % ( expInfo['participant'], expName, expInfo['run'], expInfo['date']) self.thisExp = data.ExperimentHandler( name=expName, version='', extraInfo=expInfo, runtimeInfo=None, originPath=self._thisDir + os.sep + 'SemanticIntegration.py', savePickle=True, saveWideText=True, dataFileName=filename) self.logFile = logging.LogFile(filename + '.log', level=logging.EXP) logging.console.setLevel(logging.WARNING) #self.serial = serial.Serial(self.serialPort, 19200, timeout=1) self.win = visual.Window(size=(1024, 768), fullscr=True, screen=int(expInfo['screen']), winType='pyglet', allowGUI=False, allowStencil=False, monitor='testMonitor', color='black', colorSpace='rgb', blendMode='avg', useFBO=True, units='height') # fixation cross self.fixation = visual.TextStim(win=self.win, name='fixation', text='+', font='Arial', pos=(0, 0), height=0.1, wrapWidth=None, ori=0, color='white', colorSpace='rgb', opacity=1, languageStyle='LTR', depth=0.0) self.fixation.autoDraw = False self.message = visual.TextStim(win=self.win, name='message', text='Press key to start', font='Arial', pos=(0, 0), height=0.1, wrapWidth=None, ori=0, color='white', colorSpace='rgb', opacity=1, languageStyle='LTR', depth=0.0) self.expInfo = expInfo self.expName = expName if expInfo['Send triggers'] == "yes": setupTriggers(self, MODE_EXP) else: setupTriggers(self, MODE_DEV)
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']
print("Visual Angle: {}, degree: {} pix, ".format(VA, an2px)) # Change working directory if not os.path.isfile(os.path.basename(__file__)): os.chdir("./experiments") # Try to get a previous parameters file try: exp_info = fromFile("lastParams.pickle") # If not there then use a default set except: exp_info = {"Observer": "unknown", "Session": "1", "Type[1: RDK; 2: Grating]": "1"} # Add the current time exp_info["dateStr"] = data.getDateStr() # Present a dialogue to change params dlg = gui.DlgFromDict( exp_info, title="Peripheral Vision Search Experiment", fixed=["dateStr"] ) # Save params to file for next time if dlg.OK: toFile("lastParams.pickle", exp_info) # The user hit cancel so exit else: core.quit() # Make a text file to save data file_name = exp_info["Observer"] + "_" + exp_info["Session"] + "_" + exp_info["dateStr"]
from infant_eeg.facial_movement_exp import FacialMovementExperiment from infant_eeg.gaze_following_exp import GazeFollowingExperiment import os from psychopy import data, gui from infant_eeg.config import CONF_DIR from infant_eeg.nine_month_facial_movement_exp import NineMonthFacialMovementExperiment if __name__ == '__main__': # experiment parameters expInfo = { 'child_id': '', 'date': data.getDateStr(), 'session': '', 'diagnosis': '', 'age': '', 'gender': '', 'experimenter_id': '', 'monitor': ['viewsonic','tobii'], 'monitor distance': '65', 'experiment': ['FacialMovement','GazeFollowing','9mo FacialMovement'], 'congruent actor': ['CG', 'FO'], 'incongruent actor': ['CG', 'FO'], 'preferential gaze': False, 'eeg': True, 'eyetracking source': ['tobii', 'mouse', 'none'], 'debug mode': False } #present a dialogue to change params dlg = gui.DlgFromDict( expInfo,
press_time = 8 # time spent waiting for input # reading datafile which will be used when creating iterable object # Ensure that relative paths start from the same directory as this script _thisDir = os.path.dirname(os.path.abspath(__file__)) os.chdir(_thisDir) # Store info about the experiment session psychopyVersion = '3.2.3' expName = 'Zimmerertest' # from the Builder filename that created this script expInfo = { 'participant': '', 'session': '001', 'date': data.getDateStr(), 'list_name': '1', 'random_seed': int(data.getDateStr()[-4:]) } dlg = gui.DlgFromDict(dictionary=expInfo, sortKeys=False, title=expName) if dlg.OK is False: core.quit() # user pressed cancel expInfo['date'] = data.getDateStr() # add a simple timestamp expInfo['expName'] = expName expInfo['psychopyVersion'] = psychopyVersion print(f'list is {expInfo["list_name"]}') rand_seed = expInfo['random_seed'] print(f'random seed is {rand_seed}') np.random.seed(expInfo['random_seed'])
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 #----------------------- # 1.3 File saving """Create functions to handle trial logging""" dir = 'data' filename = dir + os.path.sep + exp_name + '_' + '%s_%s' % ( exp_info['id'], exp_info['date']) + '.csv' #generate file name with name of the experiment logfile = logging.LogFile(filename[:-3] + 'log', level=logging.EXP)
using CODER, please see the gc_window example in this directory. """ from psychopy.iohub import EventConstants,ioHubConnection,load,Loader from psychopy.data import getDateStr # Load the specified iohub configuration file # converting it to a python dict. # io_config=load(file('./SMI_iview_std.yaml','r'), Loader=Loader) # Add / Update the session code to be unique. Here we use the psychopy # getDateStr() function for session code generation # session_info=io_config.get('data_store').get('session_info') session_info.update(code="S_%s"%(getDateStr())) # Create an ioHubConnection instance, which starts the ioHubProcess, and # informs it of the requested devices and their configurations. # io=ioHubConnection(io_config) keyboard=io.devices.keyboard eyetracker=io.devices.tracker # Start by running the eye tracker default setup procedure. # The details of the setup procedure (calibration, validation, etc) # are unique to each implementation of the Common Eye Tracker Interface. # All have the common end goal of calibrating the eye tracking system # prior to data collection. #
from os.path import expanduser import sys sys.dont_write_bytecode = True import cPickle as pickle # import relevant classes and dicts for condition names + targets/distractors per condition from vwmClasses import VWMObj, VWMTrial, conds, nTotalObjsPerCond, nDistractorsInCond, nTargetsInCond ### Assign Random Seed ### assert len(sys.argv) == 3, "Too many inputs" assert sys.argv[1].isdigit() and sys.argv[2].isdigit(), "Integers necessary" subjHash = (int(sys.argv[1]), int(sys.argv[2])) np.random.seed(seed=subjHash) ### Path and Filename Information based on terminal input### behavRun = 'behav5' date = data.getDateStr() homeDirectory = expanduser("~") saveDirectory = homeDirectory + os.sep + 'Google Drive/tACS_VWM_ALPHA/data' filename = saveDirectory + os.sep + behavRun + os.sep + 's' + sys.argv[1] + os.sep + 'setupData/setup-run' + sys.argv[2] + "_" + date pickleFilename = saveDirectory + os.sep + behavRun + os.sep + 's' + sys.argv[1] + os.sep + 'setupData/subj' + sys.argv[1] + 'run' + sys.argv[2] + '.p' # ExperimentHandler conducts data saving thisExp = data.ExperimentHandler(name='setup', version='', runtimeInfo=None, originPath=None, savePickle=False, saveWideText=True, dataFileName=filename) ############# Object Location Rules ######################## # maxNumObjsPerQuadrant = 2 # maxNumTargersPerQuadrant = 1 # maxNumObjsPerRadix = 4
def htmlReport(self, items=None, fatal=False): """Return an html report given a list of (key, val, msg, warn) items. format triggers: 'Critical issue' in fatal gets highlighted warn == True -> highlight key and val val == msg == '' -> use key as section heading """ imgfile = os.path.join(self.prefs.paths['resources'], 'psychopySplash.png') _head = (u'<html><head><meta http-equiv="Content-Type" ' 'content="text/html; charset=utf-8"></head><body>' + '<a href="http://www.psychopy.org"><img src="%s" ' 'width=396 height=156></a>') self.header = _head % imgfile # self.iconhtml = '<a href="http://www.psychopy.org"><img src="%s" # width=48 height=48></a>' % self.iconfile _foot = _translate('This page was auto-generated by the ' 'PsychoPy configuration wizard on %s') self.footer = ('<center><font size=-1>' + _foot % data.getDateStr(format="%Y-%m-%d, %H:%M") + '</font></center>') htmlDoc = self.header if fatal: # fatal is a list of strings: htmlDoc += ('<h2><font color="red">' + _translate('Configuration problem') + '</font></h2><hr>') for item in fatal: item = item.replace('Critical issue', '<p><strong>') item += _translate('Critical issue') + '</strong>' htmlDoc += item + "<hr>" else: # items is a list of tuples: htmlDoc += ('<h2><font color="green">' + _translate('Configuration report') + '</font></h2>\n') numWarn = len(self.warnings) if numWarn == 0: htmlDoc += _translate('<p>All values seem reasonable (no ' 'warnings, but there might still be ' 'room for improvement).</p>\n') elif numWarn == 1: _warn = _translate('1 suboptimal value was detected</font>, ' 'see details below (%s).</p>\n') htmlDoc += ('<p><font color="red">' + _warn % (self.warnings[0])) elif numWarn > 1: _warn = _translate('%(num)i suboptimal values were detected' '</font>, see details below (%(warn)s).' '</p>\n') htmlDoc += ('<p><font color="red">' + _warn % { 'num': numWarn, 'warn': ', '.join(self.warnings) }) htmlDoc += '''<script type="text/javascript"> // Loops through all rows in document and changes display // property of rows with a specific ID // toggle('ok', '') will display all rows // toggle('ok', 'none') hides ok rows, leaving Warning // rows shown function toggle(ID, display_value) { var tr=document.getElementsByTagName('tr'), i; for (i=0;i<tr.length;i++) { if (tr[i].id == ID) tr[i].style.display = display_value; } } </script> <p> <button onClick="toggle('ok', 'none');">''' htmlDoc += _translate('Only show suboptimal values') + \ '</button>' + \ '''<button onClick="toggle('ok', '');">''' + \ _translate('Show all information') + '</button></p>' htmlDoc += _translate('''<p>Resources: Contributed <a href="http://upload.psychopy.org/benchmark/report.html">benchmarks</a> | <a href="http://www.psychopy.org/documentation.html">On-line documentation</a> | Download <a href="http://www.psychopy.org/PsychoPyManual.pdf">PDF manual</a> | <a href="http://groups.google.com/group/psychopy-users">Search the user-group archives</a> </p>''') htmlDoc += '<hr><p></p> <table cellspacing=8 border=0>\n' htmlDoc += ' <tr><td><font size=+1><strong>' + \ _translate('Configuration test</strong> or setting') +\ '</font></td><td><font size=+1><strong>' + _translate('Version or value') +\ '</strong></font></td><td><font size=+1><em>' + \ _translate('Notes') + '</em></font></td>' for (key, val, msg, warn) in items: if val == msg == '': key = '<font color="darkblue" size="+1"><strong>' + \ _translate(key) + '</strong></font>' else: key = ' ' + _translate(key) if warn: key = '<font style=color:red><strong>' + \ _translate(key) + '</strong></font>' val = '<font style=color:red><strong>' + val + '</strong></font>' id = 'Warning' else: id = 'ok' htmlDoc += ' <tr id="%s"><td>' % id htmlDoc += key + '</td><td>' + val + '</td><td><em>' + msg + '</em></td></tr>\n' htmlDoc += ' </table><hr>' htmlDoc += self.footer if not fatal and numWarn: htmlDoc += """<script type="text/javascript">toggle('ok', 'none'); </script>""" htmlDoc += '</body></html>' self.reportText = htmlDoc
'05. Conditioning time (sec)':5, '06. Top-up time (sec)':5, '07. Number of trials':10, '08. Conditioning motors (1-6)':'1,2,3,4,5,6', '09. Conditioning lights (1-6)':'1,2,3,4,5,6', '10. Conditioning reversed motors (1-6)':'3,4', '11. Test motors (1-6)':'3,4', '12. Test lights (1-6)':'', '13. ISOI (ms)':100, '14. Duration (ms)':100, '15. Use GO button':True, '16. Folder for saving data':'Conditioning-Data', '17. Device orientation (0 or 1)':0, '18. Arduino serial port':'/dev/cu.usbmodem1421', '19. Print arduino messages':False} exptInfo['20. Date and time']= data.getDateStr(format='%Y-%m-%d_%H-%M-%S') #add the current time dlg = gui.DlgFromDict(exptInfo, title='Experiment details', fixed=['20. Date and time']) if dlg.OK: conditioningType = exptInfo['04. Conditioning'] exptInfo['04. Conditioning'] = ['incongruent','congruent','off'] toFile(parameterFile, exptInfo) # save params to file for next time else: core.quit() # the user hit cancel so exit ## ---- ## -- convert number lists to arrays -- try: condTactToUse = [int(i) for i in exptInfo['08. Conditioning motors (1-6)'].split(',')] except: condTactToUse = [] try: condVisToUse = [int(i) for i in exptInfo['09. Conditioning lights (1-6)'].split(',')] except: condVisToUse = [] try: condTactRev = [int(i) for i in exptInfo['10. Conditioning reversed motors (1-6)'].split(',')]
#Import necessary libraries from psychopy import visual, event, core, data, gui #set experiment parameters info = {} #a dictionary #present dialog to collect info info['Participant'] = '' dlg = gui.DlgFromDict(info) if not dlg.OK: core.quit() info['fixTime'] = 1.0 # seconds info['cueTime'] = 0.2 info['probeTime'] = 0.2 info['dateStr'] = data.getDateStr() #will create str of current date/time filename = "data/" + info['Participant'] + "_" + info['dateStr'] #Create window win = visual.Window([1024, 768], fullscr=False, units='pix', rgb='DodgerBlue') core.wait(1) #create a fixation point fixation = visual.Circle(win, size=25, lineColor='DarkOrchid', fillColor='Fuchsia', lineWidth=3.0) #fixation.setAutoDraw(True) #create a probe probe = visual.ImageStim(win, image=None,
def htmlReport(self, items=None, fatal=False): """Return an html report given a list of (key, val, msg, warn) items. format triggers: 'Critical issue' in fatal gets highlighted warn==True -> highlight key and val val == msg == '' -> use key as section heading """ imgfile = os.path.join(self.prefs.paths["resources"], "psychopySplash.png") self.header = ( u'<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>' + '<a href="http://www.psychopy.org"><image src="%s" width=396 height=156></a>' % imgfile ) # self.iconhtml = '<a href="http://www.psychopy.org"><image src="%s" width=48 height=48></a>' % self.iconfile self.footer = ( "<font size=-1><center>" + _translate("This page auto-generated by the PsychoPy configuration wizard on %s") % data.getDateStr(format="%Y-%m-%d, %H:%M") + "</center></font>" ) htmlDoc = self.header if fatal: # fatal is a list of strings: htmlDoc += '<h2><font color="red">' + _translate("Configuration problem") + "</font></h2><hr>" for item in fatal: item = item.replace("Critical issue", "<p><strong>" + _translate("Critical issue") + "</strong>") htmlDoc += item + "<hr>" else: # items is a list of tuples: htmlDoc += '<h2><font color="green">' + _translate("Configuration report") + "</font></h2>\n" numWarn = len(self.warnings) if numWarn == 0: htmlDoc += _translate( "<p>All values seem reasonable (no warnings, but there might still be room for improvement).</p>\n" ) elif numWarn == 1: htmlDoc += '<p><font color="red">' + _translate( "1 suboptimal value was detected</font>, see details below (%s).</p>\n" ) % (self.warnings[0]) elif numWarn > 1: htmlDoc += '<p><font color="red">' + _translate( "%(num)i suboptimal values were detected</font>, see details below (%(warn)s).</p>\n" ) % {"num": numWarn, "warn": ", ".join(self.warnings)} htmlDoc += ( """<script type="text/javascript"> // Loops through all rows in document and changes display property of rows with a specific ID // toggle('ok', '') will display all rows // toggle('ok', 'none') hides ok rows, leaving Warning rows shown function toggle(ID, display_value) { tr=document.getElementsByTagName('tr'); for (i=0;i<tr.length;i++) { if (tr[i].id == ID) tr[i].style.display = display_value; } } </script> <p> <button onClick="toggle('ok', 'none');">""" + _translate("Only show suboptimal values") + "</button>" + """<button onClick="toggle('ok', '');">""" + _translate("Show all information") + "</button></p>" ) htmlDoc += _translate( """<p>Resources: Contributed <a href="http://upload.psychopy.org/benchmark/report.html">benchmarks</a> | <a href="http://www.psychopy.org/documentation.html">On-line documentation</a> | Download <a href="http://www.psychopy.org/PsychoPyManual.pdf">PDF manual</a> | <a href="http://groups.google.com/group/psychopy-users">Search the user-group archives</a> </p>""" ) htmlDoc += "<hr><p></p> <table cellspacing=8 border=0>\n" htmlDoc += ( " <tr><td><font size=+1><strong>" + _translate("Configuration test</strong> or setting") + "</font></td><td><font size=+1><strong>" + _translate("Version or value") + "</strong></font></td><td><font size=+1><em>" + _translate("Notes") + "</em></font></td>" ) for (key, val, msg, warn) in items: if val == msg == "": key = '<font color="darkblue" size="+1"><strong>' + _translate(key) + "</strong></font>" else: key = " " + _translate(key) if warn: key = "<font style=color:red><strong>" + _translate(key) + "</strong></font>" val = "<font style=color:red><strong>" + val + "</strong></font>" id = "Warning" else: id = "ok" htmlDoc += ' <tr id="%s"><td>' % id htmlDoc += key + "</td><td>" + val + "</td><td><em>" + msg + "</em></td></tr>\n" htmlDoc += " </table><hr>" htmlDoc += self.footer if not fatal and numWarn: htmlDoc += """<script type="text/javascript">toggle('ok', 'none'); </script>""" htmlDoc += "</html>" self.reportText = htmlDoc
ordered_names = [field['name'] for field in ordered_fields] field_tips = {field['name']: field['prompt'] for field in ordered_fields} # Load the last participant's options or use the defaults last_subj_info = gui_yaml + '.pickle' try: gui_data = misc.fromFile(last_subj_info) for yaml_name in ordered_names: if yaml_name not in gui_data: # Invalid pickle raise AssertionError except IOError, AssertionError: gui_data = {field['name']: field['default'] for field in ordered_fields} # Set fixed fields gui_data['date'] = data.getDateStr() gui_data['computer'] = socket.gethostname() fixed_fields = ['date', 'computer'] while True: # Bring up the dialogue dlg = gui.DlgFromDict(gui_data, order=ordered_names, fixed=fixed_fields, tip=field_tips) if not dlg.OK: core.quit() subj_info = dict(gui_data) if check_exists(subj_info): popup_error('That subj_id already exists.')
def writeScript(self, expPath=None, target="PsychoPy"): """Write a PsychoPy script for the experiment """ self.flow._prescreenValues() self.expPath = expPath script = IndentingBuffer(u'') # a string buffer object # get date info, in format preferred by current locale as set by app: if hasattr(locale, 'nl_langinfo'): fmt = locale.nl_langinfo(locale.D_T_FMT) localDateTime = data.getDateStr(format=fmt) else: localDateTime = data.getDateStr(format="%B %d, %Y, at %H:%M") if target == "PsychoPy": self.settings.writeInitCode(script, self.psychopyVersion, localDateTime) self.settings.writeStartCode(script) # present info, make logfile # writes any components with a writeStartCode() self.flow.writeStartCode(script) self.settings.writeWindowCode(script) # create our visual.Window() # for JS the routine begin/frame/end code are funcs so write here # write the rest of the code for the components self.flow.writeBody(script) self.settings.writeEndCode(script) # close log file elif target == "PsychoJS": script.oneIndent = " " # use 2 spaces rather than python 4 self.settings.writeInitCodeJS(script, self.psychopyVersion, localDateTime) self.settings.writeWindowCodeJS(script) # initialise the components for all Routines in a single function script.writeIndentedLines("\nfunction experimentInit() {") script.setIndentLevel(1, relative=True) # routine init sections for entry in self.flow: # NB each entry is a routine or LoopInitiator/Terminator self._currentRoutine = entry if hasattr(entry, 'writeInitCodeJS'): entry.writeInitCodeJS(script) # create globalClock etc code = ("\n// Create some handy timers\n" "globalClock = new psychoJS.core.Clock();" " // to track the time since experiment started\n" "routineTimer = new psychoJS.core.CountdownTimer();" " // to track time remaining of each (non-slip) routine\n" "\nreturn psychoJS.NEXT;") script.writeIndentedLines(code) script.setIndentLevel(-1, relative=True) script.writeIndentedLines("}") # This differs to the Python script. We can loop through all # Routines once (whether or not they get used) because we're using # functions that may or may not get called later. # Do the Routines of the experiment first for thisRoutine in list(self.routines.values()): self._currentRoutine = thisRoutine thisRoutine.writeRoutineBeginCodeJS(script) thisRoutine.writeEachFrameCodeJS(script) thisRoutine.writeRoutineEndCodeJS(script) # loao resources files (images, csv files etc self.flow.writeResourcesCodeJS(script) # create the run() function and schedulers self.flow.writeBodyJS(script) # functions for loops and for scheduler self.settings.writeEndCodeJS(script) return script
from numpy import * # many different maths functions from numpy.random import * # maths randomisation functions import os # handy system and path functions from psychopy import core, data, event, visual, gui import psychopy.log # import like this so it doesn't interfere with numpy.log # User-defined variables = [u'Gabor', 'Instructions', 'Intro', 'key_resp', 'key_resp_2', 'trial', u'trials'] known_name_collisions = None # (collisions are bad) # store info about the experiment expName = "StairTest" # from the Builder filename that created this script expInfo = {"participant": "", "session": "001"} 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 # setup files for saving if not os.path.isdir("data"): os.makedirs("data") # if this fails (e.g. permissions) we will get error filename = "data" + os.path.sep + "%s_%s" % (expInfo["participant"], expInfo["date"]) psychopy.log.console.setLevel(psychopy.log.warning) # this outputs to the screen, not a file logFile = psychopy.log.LogFile(filename + ".log", level=psychopy.log.EXP) # setup the Window win = visual.Window( size=[1024, 768], fullscr=True, screen=0, allowGUI=False, allowStencil=False,
globalClock = core.Clock() respClock = core.Clock() #initialise experiment information info = {} #a dictionary #present dialog to collect info info['participant'] = '' dlg = gui.DlgFromDict(info) if not dlg.OK: core.quit() #add additional info after the dialog has gone info['fixFrames'] = 30 #0.5s at 60Hz info['cueFrames'] = 12 #200ms at 60Hz info['probeFrames'] = 12 info['dateStr'] = data.getDateStr() #will create str of current date/time #set up logging #create a clock to synchronise with our experiment globalClock = core.Clock() logging.setDefaultClock(globalClock) logging.console.setLevel(logging.WARNING)#set the console to receive warnings and errors #create the base filename for our data files filename = "data/{participant}_{dateStr}".format(**info) DEBUG = False # set debug if DEBUG: fullscr = False logging.console.setLevel(logging.INFO) else:
import matplotlib.pyplot as plt from psychopy import visual, core, event, gui, data from sklearn import linear_model nSessions = 5 # Grab user info and set up output files for analysis _thisDir = os.path.dirname(os.path.abspath(__file__)) print _thisDir os.chdir(_thisDir) expName = 'standardFlashlag' expInfo = {u'User': u''} dlg = gui.DlgFromDict(dictionary=expInfo, title=expName) if dlg.OK == False: core.quit() expInfo['date'] = data.getDateStr() expInfo['expName'] = expName dataOut = pd.DataFrame(columns = ('response','correct','rotation')) grabMeans = pd.DataFrame() deg_sign= u'\N{DEGREE SIGN}' ''' Initalize stimuli parameters all units are in pixels to show correctly on any sized screen user may wish to modify for optimality on small or larger screens tested on 1920x1080 (widescreen) display ''' dotRad = (55,55) flashRad = (55,55) circleRadius = 125
EXP_NAME = "AMP China Dorm" # name of experiment ### store info about experiment session --------------------------------------- # set up info we need to get exp_info = {"Participant ID": ""} # create a dialog box to get info dialog = gui.DlgFromDict(dictionary=exp_info, title=EXP_NAME) if dialog.OK == False: # quit dialog box if "canceled" is pressed core.quit() # add experiment title and date exp_info["Experiment Name"] = EXP_NAME exp_info["Date"] = data.getDateStr() ### set up stimuli ------------------------------------------------------------ ## create a window win = visual.Window(size=SCREENSIZE, color="black", units="pix", fullscr=False) ## display instructions at the beginning of trial instruction_1 = "What you are about to see will involve two kinds of images: pictures of people, and of geometric shapes.\n\n\nPress SPACE to continue" instruction_2 = "The pictures of people will be either pictures of Han people doing daily activities, or pictures of minority people such as Tibetan or Uyghur doing similar activities.\n\nYou do not need to do anything with these pictures.\n\n\nPress SPACE to continue" instruction_3 = "Your job is to judge the visual pleasantness of the geometric shape.\n\nIf the geometric shape is less visually pleasing than average, press the (E) key.\n\nIf the geometric shape is more visually pleasing than average, press the (I) key.\n\n\nPress SPACE to BEGIN" instruction_text = visual.TextStim(win, text=instruction_1, color="red", height=20) ## display "Pleasant" and "Unpleasant" commands throughout trials pleasant_text = visual.TextStim(win, text="Pleasant", color="green", height=0.07, pos=(-0.8, 0.85), units="norm")
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!')
"""measure your JND in orientation using a staircase method""" from psychopy import core, visual, gui, data, event from psychopy.tools.filetools import fromFile, toFile import time, numpy, random try: #try to get a previous parameters file expInfo = fromFile('lastParams.pickle') except: #if not there then use a default set expInfo = {'observer': 'jwp', 'refOrientation': 0} expInfo['dateStr'] = data.getDateStr() #add the current time #present a dialogue to change params dlg = gui.DlgFromDict(expInfo, title='simple JND Exp', fixed=['dateStr']) if dlg.OK: toFile('lastParams.pickle', expInfo) #save params to file for next time else: core.quit() #the user hit cancel so exit #make a text file to save data fileName = expInfo['observer'] + expInfo['dateStr'] dataFile = open(fileName + '.csv', 'w') #a simple text file with 'comma-separated-values' dataFile.write('targetSide,oriIncrement,correct\n') #create the staircase handler staircase = data.StairHandler( startVal=20.0, stepType='db', stepSizes=[8, 4, 4, 2, 2, 1, 1], nUp=1, nDown=3, #will home in on the 80% threshold
ID = thisInfo[1] session = thisInfo[2] barContrast = thisInfo[3] apertWidth = thisInfo[4] if apertWidth > 0.7: apertWidth = 0.7 if apertWidth < 0.2: apertWIDTH = 0.2 trials = thisInfo[5] file = '' file += name # file+='_Bar'+str(barContrast) # file+='_AperWidth'+str(apertWidth) file += '_' + ID file += '_Session' + str(session) file += '_' + data.getDateStr() print(file) keyState = key.KeyStateHandler() win = visual.Window(monitor="testMonitor", units="pix", allowGUI=True, fullscr=False) win.winHandle.push_handlers(keyState) show_instruction() # instruction between trials showbox1 = visual.TextStim( win, font='Arial', height=0.09, # font_color=[0,0,0], # dpi=72,
# Show a dialog box to enter session information exp_name = 'CB_study1' exp_info = { 'participant': '', 'cueCond': 1 } dlg = gui.DlgFromDict(dictionary=exp_info, title=exp_name) # If 'Cancel' is pressed, quit if dlg.OK == False: core.quit() # Add the date and the experiment name exp_info['date'] = data.getDateStr() exp_info['exp_name'] = exp_name # Set up filename for saving data if not os.path.isdir(datapath): os.makedirs(datapath) data_fname = exp_info['participant'] + '_' + exp_info['date'] data_fname = os.path.join(datapath, data_fname) # read in pre made treat list for this participant number treatfile = treatpath+exp_info['participant']+'_treatout.csv' treatlist = pandas.DataFrame.from_csv(treatfile) imlist = map(str, treatlist['imglist']) n_imgs = len(imlist) # total number of images
from psychopy import visual, core, event, data, gui from pathlib import Path # aktualny sposób radzenia sobie ze ścieżkami # Wyświetlamy okienko do wpisywania danych badanego expName = 'Eksperyment testowy' expInfo = {'uczestnik': '', 'sesja': '001', 'płeć (M/F)': ''} dlg = gui.DlgFromDict(dictionary=expInfo, title=expName) if dlg.OK == False: core.quit() # jeżeli klikniemy na anuluj, to PsychoPy zakończy działanie # Dodajemy do danych eksperymentu nazwę eksperymentu oraz datę expInfo['date'] = data.getDateStr() expInfo['expName'] = expName # Konstruujemy ściężkę, w której będą się zapisywać rezultaty badania filename = Path().absolute() / 'data/{p}_{e}_{d}'.format(p = expInfo['uczestnik'], e = expName, d = expInfo['date']) filename = str(filename) # Obiekt, który będzie pomagał nam w zapisywaniu danych z eksperymentu exp = data.ExperimentHandler(name = 'Eksperyment testowy', extraInfo = expInfo, dataFileName = filename) # Warunki eksperymentalne można importować z plików Excela lub zwykłych CSV conditions = data.importConditions('conditions.xlsx') # Tworzymy obiekt, który będzie przechowywał nasze próby trials = data.TrialHandler(conditions, # lista ze słownikami dla każdego warunku
depth=-4.0) def handleKeys(key): '''Function for handling keys from the handles and using with ratingScale...''' if key != 191: key = str(key) event._onPygletKey(symbol=key, modifiers=None, emulated=True)#Buffers the input last_state = True # Return true if down port.setData(0) core.wait(.15) # Store info about the experiment session expName = u'Cross-Modality Matching' # expInfo = {'Subject_Id':'', 'Age':'', 'ExpVersion': 2.0,'Sex': ['Male', 'Female']} expInfo[u'date'] = data.getDateStr(format="%Y-%m-%d_%H:%M") # add a simple timestamp infoDlg = gui.DlgFromDict(dictionary=expInfo, title=expName, fixed=['ExpVersion']) if infoDlg.OK: print expInfo else: print 'User Cancelled' #Soundlevels to choose from... sndlvls = numpy.linspace(0.1, 1.0, 21)#This can be removed later!!!!!!!!!!!!!!! #List of sound levels to start from sint = [0.1, 1.0] #List of vibration intensities vlvl = [5,5,5,5,10,10,10,10,15,15,15,15] #List of the tasks task = ['Attention', 'Attention', 'Attention', 'Intensity', 'Intensity', 'Intensity'] #Sounds
def _setExperimentInfo(self, author, version, verbose): # try to auto-detect __author__ and __version__ in sys.argv[0] (= the users's script) if not author or not version: if os.path.isfile(sys.argv[0]): f = open(sys.argv[0], 'r') lines = f.read() f.close() if not author and '__author__' in lines: linespl = lines.splitlines() while linespl[0].find('__author__') == -1: linespl.pop(0) auth = linespl[0] if len(auth) and '=' in auth: try: author = str(eval(auth[auth.find('=') + 1:])) except: pass if not version and '__version__' in lines: linespl = lines.splitlines() while linespl[0].find('__version__') == -1: linespl.pop(0) ver = linespl[0] if len(ver) and ver.find('=') > 0: try: version = str(eval(ver[ver.find('=') + 1:])) except: pass if author or verbose: self['experimentAuthor'] = author if version or verbose: self['experimentAuthVersion'] = version # script identity & integrity information: self['experimentScript'] = os.path.basename(sys.argv[0]) # file name scriptDir = os.path.dirname(os.path.abspath(sys.argv[0])) self['experimentScript.directory'] = scriptDir # sha1 digest, text-format compatibility self['experimentScript.digestSHA1'] = _getSha1hexDigest( os.path.abspath(sys.argv[0]), isfile=True) # subversion revision? try: svnrev, last, url = _getSvnVersion(os.path.abspath( sys.argv[0])) # svn revision if svnrev: # or verbose: self['experimentScript.svnRevision'] = svnrev self['experimentScript.svnRevLast'] = last self['experimentScript.svnRevURL'] = url except: pass # mercurical revision? try: hgChangeSet = _getHgVersion(os.path.abspath(sys.argv[0])) if hgChangeSet: # or verbose: self['experimentScript.hgChangeSet'] = hgChangeSet except: pass # when was this run? self['experimentRunTime.epoch'] = core.getAbsTime() self['experimentRunTime'] = data.getDateStr( format="%Y_%m_%d %H:%M (Year_Month_Day Hour:Min)")
def runBlocks(win, filename, startBlock, blockDur, clock, answerKey, EDFfilename, expInfo, thoughtProbeStim, stickyStim, temporalStim, valenceStim, instructionStim5, breakStim): ## Runs 'blockDur' number of trials of each block, including thought probes, ## starting at 'startBlock'. Breaks are presented every other block. trialNo = 0 for i in range (startBlock, 9): expFile = pd.read_csv('Block_' + str(i) + '_Ned.csv', delimiter = ';') stimuli = expFile['stimuli'] trialType = expFile['trialType'] # 0 = Practice, 1 = Go, 2 = NoGo, 3 = OwnConcern, blockNum = expFile['blockNum'] # 4 = OtherConcern, 5 = ThoughtProbe outputFile = open(filename + '_' + str(i) + 'out' + '.csv', 'w') outputFile.write("expName, 'EDFfile', date, subjID, subjNum, blockNum, trialNo, trialType, goResp, RT, tpResp, tpRT, stickyResp, stickyRT, temporalResp, temporalRT, valenceResp, valenceRT") outputFile.write("\n") # Suggest a break after 2, 4 and 6 blocks: if blockNum[i] in [3, 5, 7]: presentBreak(win, EDFfilename, breakStim, instructionStim5) # Run trials for m in range (blockDur): trialNo = trialNo + 1 # Send trial info to tracker #getEYELINK().sendCommand("record_status_message 'Trial %d %s'"%(trialNo, trialType[m])) #getEYELINK().sendMessage("TRIAL_ID %d %s"%(trialNo, trialType[m])) # Normal trial if trialType[m]!= 5: presentBlank(win) trialResp = presentStimuli(win, stimuli[m], clock, answerKey, EDFfilename) # Write results to data file outputFile.write("{},{},{},{},{},{},{},{},{},{},{},{},{},{}, {}, {}, {}, {}\n".format( expInfo['Experiment'], EDFfilename, data.getDateStr(), expInfo['Participant ID'], expInfo['Participant number'], blockNum[m], trialNo, trialType[m], trialResp[0], trialResp[1], "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA")) # Thought probe else: presTime = time.time() probeResp = presentProbe(win, thoughtProbeStim, EDFfilename) respTime = time.time() probeRT = float(respTime - presTime) stickyResp = presentStickyProbe(win, stickyStim, EDFfilename) respTimeSticky = time.time() stickyRT = float(respTimeSticky - presTime) temporalResp = presentTemporalProbe(win, temporalStim, EDFfilename) respTimeTemporal = time.time() temporalRT = float(respTimeTemporal - presTime) valenceResp = presentValenceProbe(win, valenceStim, EDFfilename) respTimeValence = time.time() valenceRT = float(respTimeValence - presTime) # Write results to data file outputFile.write("{},{},{},{},{},{},{},{},{},{},{},{},{},{}, {}, {}, {}, {}\n".format( expInfo['Experiment'], EDFfilename, data.getDateStr(), expInfo['Participant ID'], expInfo['Participant number'], blockNum[m], trialNo, trialType[m], "NA", "NA", probeResp, probeRT, stickyResp, stickyRT, temporalResp, temporalRT, valenceResp, valenceRT)) # After a thought probe, press any key to continue. #win.callOnFlip(getEYELINK().sendMessage, "INSTRUCTION5_ON") instructionStim5.draw() win.flip() c = event.waitKeys() #getEYELINK().sendMessage("INSTRUCTION5_RESPONSE") # Mark end of trial #getEYELINK().sendMessage("TRIAL_OK") outputFile.close()
def vaff(participant_id: str, session: str, run_number: str, is_first: bool): """ Run the value affirmation task for the smoking study. :param participant_id: Participant identifier such as ASH999 :param session: Session number (should be 1 or 2) :param run_number: Run number (should be 1, 2, 3, 4) :param is_first: True if the first run in a block, False if not :return: None """ # Ensure that relative paths start from the same directory as this script _thisDir = os.path.dirname(os.path.abspath(__file__)) os.chdir(_thisDir) # Store info about the experiment session psychopyVersion = '2021.1.2' expName = 'value_affirmation' # from the Builder filename that created this script expInfo = {'participant': participant_id, 'session': session, 'run_number': run_number} expInfo['date'] = data.getDateStr() # add a simple timestamp expInfo['expName'] = expName expInfo['psychopyVersion'] = psychopyVersion # Data file name stem = absolute path + name; later add .psyexp, .csv, .log, etc filename = _thisDir + os.sep + u'data/%s_%s_%s' % (expInfo['participant'], expName, expInfo['date']) # An ExperimentHandler isn't essential but helps with data saving thisExp = data.ExperimentHandler(name=expName, version='', extraInfo=expInfo, runtimeInfo=None, originPath='/Users/pnovak2/src/smoking/value_affirmation/value_affirmation_lastrun.py', savePickle=True, saveWideText=True, dataFileName=filename) # save a log file for detail verbose info logFile = logging.LogFile(filename + '.log', level=logging.DEBUG) logging.console.setLevel(logging.WARNING) # this outputs to the screen, not a file endExpNow = False # flag for 'escape' or other condition => quit the exp frameTolerance = 0.001 # how close to onset before 'same' frame # Start Code - component code to be run after the window creation # Setup the Window win = visual.Window( size=[2560, 1440], fullscr=True, screen=0, winType='pyglet', allowGUI=False, allowStencil=False, monitor='testMonitor', color=[-1, -1, -1], colorSpace='rgb', blendMode='avg', useFBO=True, units='height') # store frame rate of monitor if we can measure it expInfo['frameRate'] = win.getActualFrameRate() if expInfo['frameRate'] != None: frameDur = 1.0 / round(expInfo['frameRate']) else: frameDur = 1.0 / 60.0 # could not measure, so guess # create a default keyboard (e.g. to check for escape) defaultKeyboard = keyboard.Keyboard() # Initialize components for Routine "setup" setupClock = core.Clock() if is_first: start_text_str = 'Calibrating scanner' start_text_duration = 120 end_text_str = 'The task has ended. The next task will start in a few seconds.' end_text_duration = 10 else: start_text_str = '' start_text_duration = 0.1 end_text_str = 'The task has ended. Waiting for researcher to start next task.' end_text_duration = 3600 conditions_file = os.path.join('conditions', f'VAFF_{expInfo["participant"]}_Session{expInfo["session"]}_Run{expInfo["run_number"]}.csv') # session 0 is a practice session if expInfo['session'] == '0': conditions_file = os.path.join('conditions', 'conditions_practice.csv') start_text_str = 'Practice for message task' start_text_duration = 20 # Initialize components for Routine "instructions" instructionsClock = core.Clock() title_text = visual.TextStim(win=win, name='title_text', text='The Message Task', font='Open Sans', pos=(0, 0), height=0.1, wrapWidth=None, ori=0.0, color='white', colorSpace='rgb', opacity=None, languageStyle='LTR', depth=0.0); start_text = visual.TextStim(win=win, name='start_text', text=start_text_str, font='Helvetica', pos=(0, 0), height=0.05, wrapWidth=None, ori=0, color='white', colorSpace='rgb', opacity=1, languageStyle='LTR', depth=-1.0); start_trigger = keyboard.Keyboard() # Initialize components for Routine "trial" trialClock = core.Clock() value_message_text = visual.TextStim(win=win, name='value_message_text', text='', font='Helvetica', pos=(0, 0), height=0.05, wrapWidth=None, ori=0, color='white', colorSpace='rgb', opacity=1, languageStyle='LTR', depth=-1.0); rating_text = visual.TextStim(win=win, name='rating_text', text='How helpful is this message to help you quit smoking?', font='Helvetica', pos=(0, 0.2), height=0.05, wrapWidth=None, ori=0, color='white', colorSpace='rgb', opacity=1, languageStyle='LTR', depth=-2.0); value_rating = visual.Slider(win=win, name='value_rating', size=(1.0, 0.025), pos=(0, -0.3), units=None, labels=['not at all', 'extremely'], ticks=(1, 2, 3, 4, 5), granularity=0, style='rating', styleTweaks=('triangleMarker',), opacity=1, color='LightGray', fillColor='Red', borderColor='White', colorSpace='rgb', font='Helvetica', labelHeight=0.05, flip=False, depth=-3, readOnly=False) value_keyboard = keyboard.Keyboard() # Initialize components for Routine "iti" itiClock = core.Clock() intertrial_interval = visual.ImageStim( win=win, name='intertrial_interval', image=None, mask=None, ori=0, pos=(0, 0), size=(0.5, 0.5), color=[1, 1, 1], colorSpace='rgb', opacity=1, flipHoriz=False, flipVert=False, texRes=128, interpolate=True, depth=0.0) # Initialize components for Routine "end" endClock = core.Clock() end_text = visual.TextStim(win=win, name='end_text', text=end_text_str, font='Helvetica', pos=(0, 0), height=0.05, wrapWidth=None, ori=0, color='white', colorSpace='rgb', opacity=1, languageStyle='LTR', depth=0.0); end_key_resp = keyboard.Keyboard() # Create some handy timers globalClock = core.Clock() # to track the time since experiment started routineTimer = core.CountdownTimer() # to track time remaining of each (non-slip) routine # ------Prepare to start Routine "setup"------- continueRoutine = True # update component parameters for each repeat # keep track of which components have finished setupComponents = [] for thisComponent in setupComponents: thisComponent.tStart = None thisComponent.tStop = None thisComponent.tStartRefresh = None thisComponent.tStopRefresh = None if hasattr(thisComponent, 'status'): thisComponent.status = NOT_STARTED # reset timers t = 0 _timeToFirstFrame = win.getFutureFlipTime(clock="now") setupClock.reset(-_timeToFirstFrame) # t0 is time of first possible flip frameN = -1 # -------Run Routine "setup"------- while continueRoutine: # get current time t = setupClock.getTime() tThisFlip = win.getFutureFlipTime(clock=setupClock) tThisFlipGlobal = win.getFutureFlipTime(clock=None) frameN = frameN + 1 # number of completed frames (so 0 is the first frame) # update/draw components on each frame # check for quit (typically the Esc key) if endExpNow or defaultKeyboard.getKeys(keyList=["escape"]): core.quit() # check if all components have finished if not continueRoutine: # a component has requested a forced-end of Routine break continueRoutine = False # will revert to True if at least one component still running for thisComponent in setupComponents: if hasattr(thisComponent, "status") and thisComponent.status != FINISHED: continueRoutine = True break # at least one component has not yet finished # refresh the screen if continueRoutine: # don't flip if this routine is over or we'll get a blank screen win.flip() # -------Ending Routine "setup"------- for thisComponent in setupComponents: if hasattr(thisComponent, "setAutoDraw"): thisComponent.setAutoDraw(False) # the Routine "setup" was not non-slip safe, so reset the non-slip timer routineTimer.reset() # ------Prepare to start Routine "instructions"------- continueRoutine = True # update component parameters for each repeat start_trigger.keys = [] start_trigger.rt = [] _start_trigger_allKeys = [] # keep track of which components have finished instructionsComponents = [title_text, start_text, start_trigger] for thisComponent in instructionsComponents: thisComponent.tStart = None thisComponent.tStop = None thisComponent.tStartRefresh = None thisComponent.tStopRefresh = None if hasattr(thisComponent, 'status'): thisComponent.status = NOT_STARTED # reset timers t = 0 _timeToFirstFrame = win.getFutureFlipTime(clock="now") instructionsClock.reset(-_timeToFirstFrame) # t0 is time of first possible flip frameN = -1 # -------Run Routine "instructions"------- while continueRoutine: # get current time t = instructionsClock.getTime() tThisFlip = win.getFutureFlipTime(clock=instructionsClock) tThisFlipGlobal = win.getFutureFlipTime(clock=None) frameN = frameN + 1 # number of completed frames (so 0 is the first frame) # update/draw components on each frame # *title_text* updates if title_text.status == NOT_STARTED and tThisFlip >= 0.0 - frameTolerance: # keep track of start time/frame for later title_text.frameNStart = frameN # exact frame index title_text.tStart = t # local t and not account for scr refresh title_text.tStartRefresh = tThisFlipGlobal # on global time win.timeOnFlip(title_text, 'tStartRefresh') # time at next scr refresh title_text.setAutoDraw(True) if title_text.status == STARTED: # is it time to stop? (based on global clock, using actual start) if tThisFlipGlobal > title_text.tStartRefresh + 2.0 - frameTolerance: # keep track of stop time/frame for later title_text.tStop = t # not accounting for scr refresh title_text.frameNStop = frameN # exact frame index win.timeOnFlip(title_text, 'tStopRefresh') # time at next scr refresh title_text.setAutoDraw(False) # *start_text* updates if start_text.status == NOT_STARTED and tThisFlip >= 2 - frameTolerance: # keep track of start time/frame for later start_text.frameNStart = frameN # exact frame index start_text.tStart = t # local t and not account for scr refresh start_text.tStartRefresh = tThisFlipGlobal # on global time win.timeOnFlip(start_text, 'tStartRefresh') # time at next scr refresh start_text.setAutoDraw(True) if start_text.status == STARTED: # is it time to stop? (based on global clock, using actual start) if tThisFlipGlobal > start_text.tStartRefresh + start_text_duration - frameTolerance: # keep track of stop time/frame for later start_text.tStop = t # not accounting for scr refresh start_text.frameNStop = frameN # exact frame index win.timeOnFlip(start_text, 'tStopRefresh') # time at next scr refresh start_text.setAutoDraw(False) # *start_trigger* updates waitOnFlip = False if start_trigger.status == NOT_STARTED and tThisFlip >= 2 - frameTolerance: # keep track of start time/frame for later start_trigger.frameNStart = frameN # exact frame index start_trigger.tStart = t # local t and not account for scr refresh start_trigger.tStartRefresh = tThisFlipGlobal # on global time win.timeOnFlip(start_trigger, 'tStartRefresh') # time at next scr refresh start_trigger.status = STARTED # keyboard checking is just starting waitOnFlip = True win.callOnFlip(start_trigger.clock.reset) # t=0 on next screen flip win.callOnFlip(start_trigger.clearEvents, eventType='keyboard') # clear events on next screen flip if start_trigger.status == STARTED: # is it time to stop? (based on global clock, using actual start) if tThisFlipGlobal > start_trigger.tStartRefresh + start_text_duration - frameTolerance: # keep track of stop time/frame for later start_trigger.tStop = t # not accounting for scr refresh start_trigger.frameNStop = frameN # exact frame index win.timeOnFlip(start_trigger, 'tStopRefresh') # time at next scr refresh start_trigger.status = FINISHED if start_trigger.status == STARTED and not waitOnFlip: theseKeys = start_trigger.getKeys(keyList=['apostrophe'], waitRelease=False) _start_trigger_allKeys.extend(theseKeys) if len(_start_trigger_allKeys): start_trigger.keys = _start_trigger_allKeys[-1].name # just the last key pressed start_trigger.rt = _start_trigger_allKeys[-1].rt # a response ends the routine continueRoutine = False # check for quit (typically the Esc key) if endExpNow or defaultKeyboard.getKeys(keyList=["escape"]): core.quit() # check if all components have finished if not continueRoutine: # a component has requested a forced-end of Routine break continueRoutine = False # will revert to True if at least one component still running for thisComponent in instructionsComponents: if hasattr(thisComponent, "status") and thisComponent.status != FINISHED: continueRoutine = True break # at least one component has not yet finished # refresh the screen if continueRoutine: # don't flip if this routine is over or we'll get a blank screen win.flip() # -------Ending Routine "instructions"------- for thisComponent in instructionsComponents: if hasattr(thisComponent, "setAutoDraw"): thisComponent.setAutoDraw(False) thisExp.addData('title_text.started', title_text.tStartRefresh) thisExp.addData('title_text.stopped', title_text.tStopRefresh) # the Routine "instructions" was not non-slip safe, so reset the non-slip timer routineTimer.reset() # set up handler to look after randomisation of conditions etc trials = data.TrialHandler(nReps=1, method='sequential', extraInfo=expInfo, originPath=-1, trialList=data.importConditions(conditions_file), seed=None, name='trials') thisExp.addLoop(trials) # add the loop to the experiment for thisTrial in trials: currentLoop = trials # ------Prepare to start Routine "trial"------- continueRoutine = True routineTimer.add(10.000000) # update component parameters for each repeat value_message_text.setText(thisTrial['message']) value_rating.reset() value_keyboard.keys = [] value_keyboard.rt = [] _value_keyboard_allKeys = [] # keep track of which components have finished trialComponents = [value_message_text, rating_text, value_rating, value_keyboard] for thisComponent in trialComponents: thisComponent.tStart = None thisComponent.tStop = None thisComponent.tStartRefresh = None thisComponent.tStopRefresh = None if hasattr(thisComponent, 'status'): thisComponent.status = NOT_STARTED # reset timers t = 0 _timeToFirstFrame = win.getFutureFlipTime(clock="now") trialClock.reset(-_timeToFirstFrame) # t0 is time of first possible flip frameN = -1 # -------Run Routine "trial"------- while continueRoutine and routineTimer.getTime() > 0: # get current time t = trialClock.getTime() tThisFlip = win.getFutureFlipTime(clock=trialClock) tThisFlipGlobal = win.getFutureFlipTime(clock=None) frameN = frameN + 1 # number of completed frames (so 0 is the first frame) # update/draw components on each frame # Update marker position and slider rating # when there are keypresses of the rating buttons r = convert_key_to_rating(value_keyboard.keys) value_rating.markerPos = r # confirm rating by setting to current markerPos value_rating.rating = r # *value_message_text* updates if value_message_text.status == NOT_STARTED and tThisFlip >= 0.0 - frameTolerance: # keep track of start time/frame for later value_message_text.frameNStart = frameN # exact frame index value_message_text.tStart = t # local t and not account for scr refresh value_message_text.tStartRefresh = tThisFlipGlobal # on global time win.timeOnFlip(value_message_text, 'tStartRefresh') # time at next scr refresh value_message_text.setAutoDraw(True) if value_message_text.status == STARTED: # is it time to stop? (based on global clock, using actual start) if tThisFlipGlobal > value_message_text.tStartRefresh + 6 - frameTolerance: # keep track of stop time/frame for later value_message_text.tStop = t # not accounting for scr refresh value_message_text.frameNStop = frameN # exact frame index win.timeOnFlip(value_message_text, 'tStopRefresh') # time at next scr refresh value_message_text.setAutoDraw(False) # *rating_text* updates if rating_text.status == NOT_STARTED and tThisFlip >= 6 - frameTolerance: # keep track of start time/frame for later rating_text.frameNStart = frameN # exact frame index rating_text.tStart = t # local t and not account for scr refresh rating_text.tStartRefresh = tThisFlipGlobal # on global time win.timeOnFlip(rating_text, 'tStartRefresh') # time at next scr refresh rating_text.setAutoDraw(True) if rating_text.status == STARTED: # is it time to stop? (based on global clock, using actual start) if tThisFlipGlobal > rating_text.tStartRefresh + 4 - frameTolerance: # keep track of stop time/frame for later rating_text.tStop = t # not accounting for scr refresh rating_text.frameNStop = frameN # exact frame index win.timeOnFlip(rating_text, 'tStopRefresh') # time at next scr refresh rating_text.setAutoDraw(False) # *value_rating* updates if value_rating.status == NOT_STARTED and tThisFlip >= 6 - frameTolerance: # keep track of start time/frame for later value_rating.frameNStart = frameN # exact frame index value_rating.tStart = t # local t and not account for scr refresh value_rating.tStartRefresh = tThisFlipGlobal # on global time win.timeOnFlip(value_rating, 'tStartRefresh') # time at next scr refresh value_rating.setAutoDraw(True) if value_rating.status == STARTED: # is it time to stop? (based on global clock, using actual start) if tThisFlipGlobal > value_rating.tStartRefresh + 4 - frameTolerance: # keep track of stop time/frame for later value_rating.tStop = t # not accounting for scr refresh value_rating.frameNStop = frameN # exact frame index win.timeOnFlip(value_rating, 'tStopRefresh') # time at next scr refresh value_rating.setAutoDraw(False) # *value_keyboard* updates waitOnFlip = False if value_keyboard.status == NOT_STARTED and tThisFlip >= 6 - frameTolerance: # keep track of start time/frame for later value_keyboard.frameNStart = frameN # exact frame index value_keyboard.tStart = t # local t and not account for scr refresh value_keyboard.tStartRefresh = tThisFlipGlobal # on global time win.timeOnFlip(value_keyboard, 'tStartRefresh') # time at next scr refresh value_keyboard.status = STARTED # keyboard checking is just starting waitOnFlip = True win.callOnFlip(value_keyboard.clock.reset) # t=0 on next screen flip win.callOnFlip(value_keyboard.clearEvents, eventType='keyboard') # clear events on next screen flip if value_keyboard.status == STARTED: # is it time to stop? (based on global clock, using actual start) if tThisFlipGlobal > value_keyboard.tStartRefresh + 4 - frameTolerance: # keep track of stop time/frame for later value_keyboard.tStop = t # not accounting for scr refresh value_keyboard.frameNStop = frameN # exact frame index win.timeOnFlip(value_keyboard, 'tStopRefresh') # time at next scr refresh value_keyboard.status = FINISHED if value_keyboard.status == STARTED and not waitOnFlip: theseKeys = value_keyboard.getKeys(keyList=['5', '6', '7', '8', '9'], waitRelease=False) _value_keyboard_allKeys.extend(theseKeys) if len(_value_keyboard_allKeys): value_keyboard.keys = _value_keyboard_allKeys[-1].name # just the last key pressed value_keyboard.rt = _value_keyboard_allKeys[-1].rt # check for quit (typically the Esc key) if endExpNow or defaultKeyboard.getKeys(keyList=["escape"]): core.quit() # check if all components have finished if not continueRoutine: # a component has requested a forced-end of Routine break continueRoutine = False # will revert to True if at least one component still running for thisComponent in trialComponents: if hasattr(thisComponent, "status") and thisComponent.status != FINISHED: continueRoutine = True break # at least one component has not yet finished # refresh the screen if continueRoutine: # don't flip if this routine is over or we'll get a blank screen win.flip() # -------Ending Routine "trial"------- for thisComponent in trialComponents: if hasattr(thisComponent, "setAutoDraw"): thisComponent.setAutoDraw(False) rating_text.tStopRefresh = tThisFlipGlobal value_rating.tStopRefresh = tThisFlipGlobal value_keyboard.tStopRefresh = tThisFlipGlobal trials.addData('value_message_text.started', value_message_text.tStartRefresh) trials.addData('value_message_text.stopped', value_message_text.tStopRefresh) trials.addData('rating_text.started', rating_text.tStartRefresh) trials.addData('rating_text.stopped', rating_text.tStopRefresh) trials.addData('value_rating.response', value_rating.getRating()) trials.addData('value_rating.started', value_rating.tStartRefresh) trials.addData('value_rating.stopped', value_rating.tStopRefresh) # check responses if value_keyboard.keys in ['', [], None]: # No response was made value_keyboard.keys = None trials.addData('value_keyboard.keys', value_keyboard.keys) if value_keyboard.keys != None: # we had a response trials.addData('value_keyboard.rt', value_keyboard.rt) trials.addData('value_keyboard.started', value_keyboard.tStartRefresh) trials.addData('value_keyboard.stopped', value_keyboard.tStopRefresh) # ------Prepare to start Routine "iti"------- continueRoutine = True # update component parameters for each repeat # keep track of which components have finished itiComponents = [intertrial_interval] for thisComponent in itiComponents: thisComponent.tStart = None thisComponent.tStop = None thisComponent.tStartRefresh = None thisComponent.tStopRefresh = None if hasattr(thisComponent, 'status'): thisComponent.status = NOT_STARTED # reset timers t = 0 _timeToFirstFrame = win.getFutureFlipTime(clock="now") itiClock.reset(-_timeToFirstFrame) # t0 is time of first possible flip frameN = -1 # -------Run Routine "iti"------- while continueRoutine: # get current time t = itiClock.getTime() tThisFlip = win.getFutureFlipTime(clock=itiClock) tThisFlipGlobal = win.getFutureFlipTime(clock=None) frameN = frameN + 1 # number of completed frames (so 0 is the first frame) # update/draw components on each frame # *intertrial_interval* updates if intertrial_interval.status == NOT_STARTED and tThisFlip >= 0.0 - frameTolerance: # keep track of start time/frame for later intertrial_interval.frameNStart = frameN # exact frame index intertrial_interval.tStart = t # local t and not account for scr refresh intertrial_interval.tStartRefresh = tThisFlipGlobal # on global time win.timeOnFlip(intertrial_interval, 'tStartRefresh') # time at next scr refresh intertrial_interval.setAutoDraw(True) if intertrial_interval.status == STARTED: # is it time to stop? (based on global clock, using actual start) if tThisFlipGlobal > intertrial_interval.tStartRefresh + thisTrial['iti'] - frameTolerance: # keep track of stop time/frame for later intertrial_interval.tStop = t # not accounting for scr refresh intertrial_interval.frameNStop = frameN # exact frame index win.timeOnFlip(intertrial_interval, 'tStopRefresh') # time at next scr refresh intertrial_interval.setAutoDraw(False) # check for quit (typically the Esc key) if endExpNow or defaultKeyboard.getKeys(keyList=["escape"]): core.quit() # check if all components have finished if not continueRoutine: # a component has requested a forced-end of Routine break continueRoutine = False # will revert to True if at least one component still running for thisComponent in itiComponents: if hasattr(thisComponent, "status") and thisComponent.status != FINISHED: continueRoutine = True break # at least one component has not yet finished # refresh the screen if continueRoutine: # don't flip if this routine is over or we'll get a blank screen win.flip() # -------Ending Routine "iti"------- for thisComponent in itiComponents: if hasattr(thisComponent, "setAutoDraw"): thisComponent.setAutoDraw(False) trials.addData('intertrial_interval.started', intertrial_interval.tStartRefresh) trials.addData('intertrial_interval.stopped', intertrial_interval.tStopRefresh) # the Routine "iti" was not non-slip safe, so reset the non-slip timer routineTimer.reset() thisExp.nextEntry() # completed 1 repeats of 'trials' # ------Prepare to start Routine "end"------- continueRoutine = True # update component parameters for each repeat end_key_resp.keys = [] end_key_resp.rt = [] _end_key_resp_allKeys = [] # keep track of which components have finished endComponents = [end_text, end_key_resp] for thisComponent in endComponents: thisComponent.tStart = None thisComponent.tStop = None thisComponent.tStartRefresh = None thisComponent.tStopRefresh = None if hasattr(thisComponent, 'status'): thisComponent.status = NOT_STARTED # reset timers t = 0 _timeToFirstFrame = win.getFutureFlipTime(clock="now") endClock.reset(-_timeToFirstFrame) # t0 is time of first possible flip frameN = -1 # -------Run Routine "end"------- while continueRoutine: # get current time t = endClock.getTime() tThisFlip = win.getFutureFlipTime(clock=endClock) tThisFlipGlobal = win.getFutureFlipTime(clock=None) frameN = frameN + 1 # number of completed frames (so 0 is the first frame) # update/draw components on each frame # *end_text* updates if end_text.status == NOT_STARTED and tThisFlip >= 0.0 - frameTolerance: # keep track of start time/frame for later end_text.frameNStart = frameN # exact frame index end_text.tStart = t # local t and not account for scr refresh end_text.tStartRefresh = tThisFlipGlobal # on global time win.timeOnFlip(end_text, 'tStartRefresh') # time at next scr refresh end_text.setAutoDraw(True) if end_text.status == STARTED: # is it time to stop? (based on global clock, using actual start) if tThisFlipGlobal > end_text.tStartRefresh + end_text_duration - frameTolerance: # keep track of stop time/frame for later end_text.tStop = t # not accounting for scr refresh end_text.frameNStop = frameN # exact frame index win.timeOnFlip(end_text, 'tStopRefresh') # time at next scr refresh end_text.setAutoDraw(False) # *end_key_resp* updates waitOnFlip = False if end_key_resp.status == NOT_STARTED and tThisFlip >= 0.0 - frameTolerance: # keep track of start time/frame for later end_key_resp.frameNStart = frameN # exact frame index end_key_resp.tStart = t # local t and not account for scr refresh end_key_resp.tStartRefresh = tThisFlipGlobal # on global time win.timeOnFlip(end_key_resp, 'tStartRefresh') # time at next scr refresh end_key_resp.status = STARTED # keyboard checking is just starting waitOnFlip = True win.callOnFlip(end_key_resp.clock.reset) # t=0 on next screen flip win.callOnFlip(end_key_resp.clearEvents, eventType='keyboard') # clear events on next screen flip if end_key_resp.status == STARTED: # is it time to stop? (based on global clock, using actual start) if tThisFlipGlobal > end_key_resp.tStartRefresh + asarray(end_text_duration) - frameTolerance: # keep track of stop time/frame for later end_key_resp.tStop = t # not accounting for scr refresh end_key_resp.frameNStop = frameN # exact frame index win.timeOnFlip(end_key_resp, 'tStopRefresh') # time at next scr refresh end_key_resp.status = FINISHED if end_key_resp.status == STARTED and not waitOnFlip: theseKeys = end_key_resp.getKeys(keyList=['space'], waitRelease=False) _end_key_resp_allKeys.extend(theseKeys) if len(_end_key_resp_allKeys): end_key_resp.keys = _end_key_resp_allKeys[-1].name # just the last key pressed end_key_resp.rt = _end_key_resp_allKeys[-1].rt # a response ends the routine continueRoutine = False # check for quit (typically the Esc key) if endExpNow or defaultKeyboard.getKeys(keyList=["escape"]): core.quit() # check if all components have finished if not continueRoutine: # a component has requested a forced-end of Routine break continueRoutine = False # will revert to True if at least one component still running for thisComponent in endComponents: if hasattr(thisComponent, "status") and thisComponent.status != FINISHED: continueRoutine = True break # at least one component has not yet finished # refresh the screen if continueRoutine: # don't flip if this routine is over or we'll get a blank screen win.flip() # -------Ending Routine "end"------- for thisComponent in endComponents: if hasattr(thisComponent, "setAutoDraw"): thisComponent.setAutoDraw(False) thisExp.addData('end_text.started', end_text.tStartRefresh) thisExp.addData('end_text.stopped', end_text.tStopRefresh) # check responses if end_key_resp.keys in ['', [], None]: # No response was made end_key_resp.keys = None thisExp.addData('end_key_resp.keys', end_key_resp.keys) if end_key_resp.keys != None: # we had a response thisExp.addData('end_key_resp.rt', end_key_resp.rt) thisExp.addData('end_key_resp.started', end_key_resp.tStartRefresh) thisExp.addData('end_key_resp.stopped', end_key_resp.tStopRefresh) thisExp.nextEntry() # the Routine "end" was not non-slip safe, so reset the non-slip timer routineTimer.reset() # Flip one final time so any remaining win.callOnFlip() # and win.timeOnFlip() tasks get executed before quitting win.flip() # these shouldn't be strictly necessary (should auto-save) thisExp.saveAsWideText(filename + '.csv', delim='auto') thisExp.saveAsPickle(filename) logging.flush() # make sure everything is closed down thisExp.abort() # or data files will save again on exit win.close() core.quit()
# 'estimation_method': ['adjustment', 'staircase'], 'display': ['oculus', 'laptop'], 'Moog': ['yes', 'no'], 'n_adjust': 1} dlg = gui.DlgFromDict(dictionary=V, title=exp_name, order=['participant_number', 'participant_name', 'age', 'hand', 'gender', 'xpos', 'session', 'side', 'tilt_position', 'adaptation', 'task', 'reps', 'Moog', 'display', 'n_adjust']) if not dlg.OK: core.quit() V['date'] = data.getDateStr() V['exp_name'] = exp_name """ workaround for dropdown selection error: https://groups.google.com/forum/#!topic/psychopy-users/jV8JBSwIUWk """ from psychopy import visual # experiment parameters valid_responses = ['f', 'j', 'escape'] audio_dir = 'audio' RANGE = 3 # test orientations lie in the range [svv-RANGE, svv+RANGE] # number of test orientations around estimate
def _setExperimentInfo(self, author, version, verbose, randomSeedFlag=None): # try to auto-detect __author__ and __version__ in sys.argv[0] (= the users's script) if not author or not version: f = open(sys.argv[0], 'r') lines = f.read() f.close() if not author and lines.find('__author__') > -1: linespl = lines.splitlines() while linespl[0].find('__author__') == -1: linespl.pop(0) auth = linespl[0] if len(auth) and auth.find('=') > 0: try: author = str(eval(auth[auth.find('=') + 1:])) except: pass if not version and lines.find('__version__') > -1: linespl = lines.splitlines() while linespl[0].find('__version__') == -1: linespl.pop(0) ver = linespl[0] if len(ver) and ver.find('=') > 0: try: version = str(eval(ver[ver.find('=') + 1:])) except: pass if author or verbose: self['experimentAuthor'] = author if version or verbose: self['experimentAuthVersion'] = version # script identity & integrity information: self['experimentScript'] = os.path.basename(sys.argv[0]) # file name scriptDir = os.path.dirname(os.path.abspath(sys.argv[0])) self['experimentScript.directory'] = scriptDir # sha1 digest, text-format compatibility self['experimentScript.digestSHA1'] = _getSha1hexDigest( os.path.abspath(sys.argv[0]), file=True) # subversion revision? try: svnrev, last, url = _getSvnVersion(os.path.abspath( sys.argv[0])) # svn revision if svnrev: # or verbose: self['experimentScript.svnRevision'] = svnrev self['experimentScript.svnRevLast'] = last self['experimentScript.svnRevURL'] = url except: pass # mercurical revision? try: hgChangeSet = _getHgVersion(os.path.abspath(sys.argv[0])) if hgChangeSet: # or verbose: self['experimentScript.hgChangeSet'] = hgChangeSet except: pass # when was this run? self['experimentRunTime.epoch'] = core.getTime( ) # basis for default random.seed() self['experimentRunTime'] = data.getDateStr( format="%Y_%m_%d %H:%M (Year_Month_Day Hour:Min)") # random.seed -- record the value, and initialize random.seed() if 'set:' if randomSeedFlag: randomSeedFlag = str(randomSeedFlag) while randomSeedFlag.find('set: ') == 0: randomSeedFlag = randomSeedFlag.replace( 'set: ', 'set:', 1 ) # spaces between set: and value could be confusing after deleting 'set:' randomSeed = randomSeedFlag.replace('set:', '', 1).strip() if randomSeed in ['time']: randomSeed = self['experimentRunTime.epoch'] self['experimentRandomSeed.string'] = randomSeed if randomSeedFlag.find('set:') == 0: random.seed(self['experimentRandomSeed.string']) # seed it self['experimentRandomSeed.isSet'] = True else: self['experimentRandomSeed.isSet'] = False else: self['experimentRandomSeed.string'] = None self['experimentRandomSeed.isSet'] = False
def htmlReport(self, items=None, fatal=False): """Return an html report given a list of (key, val, msg) items. format triggers: 'Critical issue' in fatal gets highlighted 'Warning:' in msg -> highlight key and val val == msg == '' -> use key as section heading """ imgfile = os.path.join(self.prefs.paths['resources'], 'psychopySplash.png') self.header = '<html><head></head><a href="http://www.psychopy.org"><image src="%s" width=396 height=156></a>' % imgfile #self.iconhtml = '<a href="http://www.psychopy.org"><image src="%s" width=48 height=48></a>' % self.iconfile self.footer = '<font size=-1><center>This page auto-generated by the PsychoPy configuration wizard on %s</center></font>' % data.getDateStr(format="%Y-%m-%d, %H:%M") htmlDoc = self.header if fatal: # fatal is a list of strings: htmlDoc += '<h2><font color="red">Configuration problem</font></h2><hr>' for item in fatal: item = item.replace('Critical issue', '<p><strong>Critical issue</strong>') htmlDoc += item + "<hr>" else: # items is a list of tuples: htmlDoc += '<h2><font color="green">Configuration report</font></h2>\n' numWarn = len(self.warnings) if numWarn == 0: htmlDoc += '<p>All values seem reasonable (no warnings, but there might still be room for improvement).</p>\n' elif numWarn == 1: htmlDoc += '<p><font color="red">1 suboptimal value was detected</font>, see details below (%s).</p>\n' % (self.warnings[0]) elif numWarn > 1: htmlDoc += '<p><font color="red">%i suboptimal values were detected</font>, see details below (%s).</p>\n' % (numWarn, ', '.join(self.warnings)) htmlDoc += '''<script type="text/javascript"> // Loops through all rows in document and changes display property of rows with a specific ID // toggle('ok', '') will display all rows // toggle('ok', 'none') hides ok rows, leaving Warning rows shown function toggle(ID, display_value) { tr=document.getElementsByTagName('tr'); for (i=0;i<tr.length;i++) { if (tr[i].id == ID) tr[i].style.display = display_value; } } </script> <p> <button onClick="toggle('ok', 'none');">Only show suboptimal values</button> <button onClick="toggle('ok', '');">Show all information</button></p> ''' htmlDoc += '''<p>Resources: Contributed <a href="http://upload.psychopy.org/benchmark/report.html">benchmarks</a> | <a href="http://www.psychopy.org/documentation.html">On-line documentation</a> | Download <a href="http://www.psychopy.org/PsychoPyManual.pdf">PDF manual</a> | <a href="http://groups.google.com/group/psychopy-users">Search the user-group archives</a> </p>''' htmlDoc += '<hr><p></p> <table cellspacing=8 border=0>\n' htmlDoc += ' <tr><td><font size=+1><strong>Configuration test</strong> or setting</font></td><td><font size=+1><strong>Version or value</strong></font></td><td><font size=+1><em>Notes</em></font></td>' for (key, val, msg) in items: if val == msg == '': key = '<font color="darkblue" size="+1"><strong>' + key + '</strong></font>' else: key = ' ' + key if msg.startswith('Warning'): key = '<font style=color:red><strong>' + key + '</strong></font>' val = '<font style=color:red><strong>' + val + '</strong></font>' id = 'Warning' else: id = 'ok' htmlDoc += ' <tr id="%s"><td>' % id htmlDoc += key + '</td><td>' + val + '</td><td><em>' + msg + '</em></td></tr>\n' htmlDoc += ' </table><hr>' htmlDoc += self.footer if not fatal and numWarn: htmlDoc += """<script type="text/javascript">toggle('ok', 'none'); </script>""" htmlDoc += '</html>' self.reportText = htmlDoc
return returned_string '''A function to create a graph depicting the participants progress untill the last session''' #def progress_graph() #obtaining participant info my_dlg = gui.Dlg(title='N-back training') my_dlg.addText('Please enter your assigned code') my_dlg.addField('Participant:') my_dlg.show() if my_dlg.OK == False: core.quit() id_participant = str(my_dlg.data[0]) date = data.getDateStr() date_reg = data.getDateStr()[:11] file_name = id_participant+'_n-back_'+date data_headings = 'trial;n-level;Details' win = visual.Window( fullscr = False, color=(0,0,0), units = 'pix' ) win.mouseVisible=False txt_menu = visual.TextStim(win = win, color=(-1,-1,-1), height=24) txt_session_t = visual.TextStim(win = win, pos=(0,-250),color = (-1,-1,-1))
def writeScript(self, expPath=None, target="PsychoPy", modular=True): """Write a PsychoPy script for the experiment """ self.psychopyVersion = psychopy.__version__ # make sure is current # set this so that params write for approp target utils.scriptTarget = target self.flow._prescreenValues() self.expPath = expPath script = IndentingBuffer(u'') # a string buffer object # get date info, in format preferred by current locale as set by app: if hasattr(locale, 'nl_langinfo'): fmt = locale.nl_langinfo(locale.D_T_FMT) localDateTime = data.getDateStr(format=fmt) else: localDateTime = data.getDateStr(format="%B %d, %Y, at %H:%M") if target == "PsychoPy": self.settings.writeInitCode(script, self.psychopyVersion, localDateTime) self.settings.writeStartCode(script, self.psychopyVersion) # present info, make logfile # writes any components with a writeStartCode() self.flow.writeStartCode(script) self.settings.writeWindowCode(script) # create our visual.Window() # for JS the routine begin/frame/end code are funcs so write here # write the rest of the code for the components self.flow.writeBody(script) self.settings.writeEndCode(script) # close log file script = script.getvalue() elif target == "PsychoJS": script.oneIndent = " " # use 2 spaces rather than python 4 self.settings.writeInitCodeJS(script, self.psychopyVersion, localDateTime, modular) self.flow.writeFlowSchedulerJS(script) self.settings.writeExpSetupCodeJS(script, self.psychopyVersion) # initialise the components for all Routines in a single function script.writeIndentedLines("\nfunction experimentInit() {") script.setIndentLevel(1, relative=True) # routine init sections for entry in self.flow: # NB each entry is a routine or LoopInitiator/Terminator self._currentRoutine = entry if hasattr(entry, 'writeInitCodeJS'): entry.writeInitCodeJS(script) # create globalClock etc code = ("// Create some handy timers\n" "globalClock = new util.Clock();" " // to track the time since experiment started\n" "routineTimer = new util.CountdownTimer();" " // to track time remaining of each (non-slip) routine\n" "\nreturn Scheduler.Event.NEXT;") script.writeIndentedLines(code) script.setIndentLevel(-1, relative=True) script.writeIndentedLines("}\n") # This differs to the Python script. We can loop through all # Routines once (whether or not they get used) because we're using # functions that may or may not get called later. # Do the Routines of the experiment first routinesToWrite = list(self.routines) for thisItem in self.flow: if thisItem.getType() in ['LoopInitiator', 'LoopTerminator']: self.flow.writeLoopHandlerJS(script) elif thisItem.name in routinesToWrite: self._currentRoutine = self.routines[thisItem.name] self._currentRoutine.writeRoutineBeginCodeJS(script) self._currentRoutine.writeEachFrameCodeJS(script) self._currentRoutine.writeRoutineEndCodeJS(script) routinesToWrite.remove(thisItem.name) self.settings.writeEndCodeJS(script) try: script = py2js.addVariableDeclarations(script.getvalue()) except py2js.esprima.error_handler.Error: script = script.getvalue() print("Failed to parse as JS by esprima") self.flow._resetLoopController() # Reset loop controller ready for next call to writeScript return script
from psychopy.hardware import keyboard from sequence_generation import generate_pattern_mismatch # Ensure that relative paths start from the same directory as this script _thisDir = os.path.dirname(os.path.abspath(__file__)) os.chdir(_thisDir) # Store info about the experiment session psychopyVersion = '2021.1.4' expName = 'pattern_mismatch' # from the Builder filename that created this script expInfo = {'participant': '', 'session': '001'} dlg = gui.DlgFromDict(dictionary=expInfo, sortKeys=False, title=expName) if dlg.OK == False: core.quit() # user pressed cancel expInfo['date'] = data.getDateStr() # add a simple timestamp expInfo['expName'] = expName expInfo['psychopyVersion'] = psychopyVersion # Data file name stem = absolute path + name; later add .psyexp, .csv, .log, etc filename = _thisDir + os.sep + u'data/%s_%s_%s' % (expInfo['participant'], expName, expInfo['date']) # An ExperimentHandler isn't essential but helps with data saving thisExp = data.ExperimentHandler(name=expName, version='', extraInfo=expInfo, runtimeInfo=None, originPath='D:\\Code\\mismatch_negativity\\pattern_mismatch.py', savePickle=True, saveWideText=True, dataFileName=filename) # save a log file for detail verbose info logFile = logging.LogFile(filename+'.log', level=logging.EXP) logging.console.setLevel(logging.WARNING) # this outputs to the screen, not a file
import numpy as np # whole numpy lib is available, prepend 'np.' from numpy import sin, cos, tan, log, log10, pi, average, sqrt, std, deg2rad, rad2deg, linspace, asarray from numpy.random import random, randint, normal, shuffle import os # handy system and path functions import random as rand import pandas as pd # Store info about the experiment session expName = u'dotSeq_trial' # from the Builder filename that created this script expInfo = {u'session': u'001', u'participant': u'Optimal Learner', 'sequenceLength':25} 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 sequenceLength = expInfo['sequenceLength'] # Setup files for saving if not os.path.isdir('Data'): os.makedirs('Data') # if this fails (e.g. permissions) we will get error filename = 'Data' + os.path.sep + '%s_%s' %(expInfo['participant'], expInfo['date']) logFile = logging.LogFile(filename+'.log', level=logging.EXP) logging.console.setLevel(logging.WARNING) # this outputs to the screen, not a file # An ExperimentHandler isn't essential but helps with data saving thisExp = data.ExperimentHandler(name=expName, version='', extraInfo=expInfo, runtimeInfo=None, originPath=None,
def run_try(): schedules = [f for f in os.listdir(os.path.dirname(__file__)) if f.endswith('.schedule')] if not g.session_params['auto_advance']: myDlg = gui.Dlg(title="CR") myDlg.addField('Run Number', choices=schedules, initial=g.run_params['run']) myDlg.show() # show dialog and wait for OK or Cancel if myDlg.OK: # then the user pressed OK thisInfo = myDlg.data else: print 'QUIT!' return -1#the user hit cancel so exit g.run_params['run'] = thisInfo[0] param_file = g.run_params['run'][0:-9] + '.params' #every .schedule file can (probably should) have a .params file associated with it to specify running parameters (including part of the output filename) StimToolLib.get_var_dict_from_file(os.path.join(os.path.dirname(__file__), param_file), g.run_params) g.prefix = StimToolLib.generate_prefix(g) schedule_file = os.path.join(os.path.dirname(__file__), g.run_params['run']) StimToolLib.general_setup(g) trial_types,images,durations,junk = StimToolLib.read_trial_structure(schedule_file, g.win, g.msg) durations = durations[0] #durations of the images/itis images = images[0] for i in images: i.size = (g.session_params['screen_x'], g.session_params['screen_y']) #set stimulus images to be fullscreen #for i in range(len(trial_types)): #convert to int for easier decoding # trial_types[i] = int(trial_types[i]) #g.rating_marker = visual.ImageStim(g.win, image=os.path.join(os.path.dirname(__file__), 'media/rating_mark_down.png'), pos=[285,-450], units='pix') #g.rating_marker_selected = visual.ImageStim(g.win, image=os.path.join(os.path.dirname(__file__), 'media/rating_mark_down_selected.png'), pos=[285,-450], units='pix') g.box = visual.ImageStim(g.win, image=os.path.join(os.path.dirname(__file__), 'media','YellowFrame.gif'), units='pix', mask=os.path.join(os.path.dirname(__file__), 'media/frame_mask.gif')) g.box.size = (g.session_params['screen_x'], g.session_params['screen_y']) #set stimulus images to be fullscreen #initialize question/response images g.question_image = visual.ImageStim(g.win, image=os.path.join(os.path.dirname(__file__), g.run_params['question_image'])) g.response_image_1 = visual.ImageStim(g.win, image=os.path.join(os.path.dirname(__file__), g.run_params['response_image_1'])) g.response_image_2 = visual.ImageStim(g.win, image=os.path.join(os.path.dirname(__file__), g.run_params['response_image_2'])) g.response_image_3 = visual.ImageStim(g.win, image=os.path.join(os.path.dirname(__file__), g.run_params['response_image_3'])) g.response_image_4 = visual.ImageStim(g.win, image=os.path.join(os.path.dirname(__file__), g.run_params['response_image_4'])) g.frame_reminder = visual.ImageStim(g.win, image=os.path.join(os.path.dirname(__file__), 'media', 'frame_reminder.PNG')) start_time = data.getDateStr() fileName = os.path.join(g.prefix + '.csv') g.output = open(fileName, 'w') sorted_events = sorted(event_types.iteritems(), key=operator.itemgetter(1)) g.output.write('Administrator:,' + g.session_params['admin_id'] + ',Original File Name:,' + fileName + ',Time:,' + start_time + ',Parameter File:,' + param_file + ',Event Codes:,' + str(sorted_events) + '\n') g.output.write('trial_number,trial_type,event_code,absolute_time,response_time,response,result\n') StimToolLib.task_start(StimToolLib.CUE_REACTIVITY_CODE, g) instruct_start_time = g.clock.getTime() StimToolLib.mark_event(g.output, 'NA', 'NA', event_types['INSTRUCT_ONSET'], instruct_start_time, 'NA', 'NA', 'NA', g.session_params['signal_parallel'], g.session_params['parallel_port_address']) StimToolLib.run_instructions_keyselect(os.path.join(os.path.dirname(__file__), 'media', 'instructions', g.run_params['instruction_schedule']), g) g.trial = 0 if g.session_params['scan']: StimToolLib.wait_scan_start(g.win) else: StimToolLib.wait_start(g.win) instruct_end_time = g.clock.getTime() StimToolLib.mark_event(g.output, 'NA', 'NA', event_types['TASK_ONSET'], instruct_end_time, instruct_end_time - instruct_start_time, 'NA', 'NA', g.session_params['signal_parallel'], g.session_params['parallel_port_address']) g.ideal_trial_start = instruct_end_time g.win.flip() for t, i, d in zip(trial_types, images, durations): g.trial_type = t do_one_trial(t, i, d) g.trial = g.trial + 1