forked from psychopy/posner
/
posner.py
150 lines (128 loc) · 5.13 KB
/
posner.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# Import psychopy modules
from psychopy import visual, core, event, data, gui, logging
instructionPractice = 'Practice starts now. Use arrow keys to identify where the green target is'
instructionExp = 'Good. Now continue until the experiment stops automatically.'
instructionThanks = 'Thank you!'
# Toggle debugging/production
DEBUG = True
if DEBUG:
fullscr = False
logging.console.setLevel(logging.DEBUG)
else:
fullscr = True
logging.console.setLevel(logging.WARNING)
# Collect general parameters in the "info" dictionary
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
# initialise stimuli
win = visual.Window([1024,768], fullscr=fullscr, monitor='testMonitor', units='deg')
fixation = visual.Circle(win, size = 0.5,
lineColor = 'white', fillColor = 'lightGrey')
probe = visual.ImageStim(win, size = 2, # 'size' is 3xSD for gauss,
pos = [5, 0], #we'll change this later
image = None, mask = 'gauss',
color = 'green')
cue = visual.ShapeStim(win,
vertices = [[-3,-2], [-3,2], [3,0]],
lineColor = 'red', fillColor = 'salmon')
instruction = visual.TextStim(win)
respClock = core.Clock()
# Shows instructions
def showInstruction(text, keyList=None): # obs, default argument for keyList
# Show text
instruction.setText(text) # use the question passed as argument
instruction.draw()
win.flip()
# Wait for response
response = event.waitKeys(keyList=keyList) # use the keyList passed as argument
if response[0] == 'escape':
core.quit()
return response[0] # return first response
# Run a block of trials. nReps is a positive integer and saveTrial is True/False.
def runBlock(nReps, saveTrials=True):
#set up the trials/experiment
conditions = data.importConditions('conditions.csv') #import conditions from file
trials = data.TrialHandler(trialList=conditions, nReps=nReps) #create trial handler (loop)
#(optional) set up logging if events should be saved
if saveTrials:
#create the base filename for our data files
filename = "data/{participant}_{dateStr}".format(**info)
logfile = logging.LogFile(filename+".log",
filemode='w',#if you set this to 'a' it will append instead of overwriting
level=logging.EXP)
#add trials to the experiment handler to store data
thisExp = data.ExperimentHandler(
name='Posner', version='1.0', #not needed, just handy
extraInfo = info, #the info we created earlier
dataFileName = filename, # using our string with data/name_date
)
thisExp.addLoop(trials) #there could be other loops (like practice loop)
# Actually present stimuli: loop through trials
for thisTrial in trials:
# set up this trial
resp = None
rt = None
probe.setPos( [thisTrial['probeX'], 0] )
cue.setOri( thisTrial['cueOri'] )
#fixation period
fixation.setAutoDraw(True)
for frameN in range(info['fixFrames']):
win.flip()
#present cue
cue.setAutoDraw(True)
for frameN in range(info['cueFrames']):
win.flip()
cue.setAutoDraw(False)
#present probe and collect responses during presentation
probe.setAutoDraw(True)
win.callOnFlip(respClock.reset) #NB: reset not reset()
event.clearEvents()
for frameN in range(info['probeFrames']):
keys = event.getKeys(keyList = ['left','right','escape'])
if len(keys)>0:
resp = keys[0] #take the first keypress as the response
rt = respClock.getTime()
break #out of the probe-drawing loop
win.flip()
probe.setAutoDraw(False)
fixation.setAutoDraw(False)
#clear screen
win.flip()
#wait for response if we didn't already have one
if resp is None:
keys = event.waitKeys(keyList = ['left','right','escape'])
resp = keys[0] #take first response
rt = respClock.getTime()
#check if the response was correct
if thisTrial['probeX']>0 and resp=='right':
corr = 1
elif thisTrial['probeX']<0 and resp=='left':
corr = 1
elif resp=='escape':
corr = None
trials.finished = True
else:
corr = 0
#store the response and RT
trials.addData('resp', resp)
trials.addData('rt', rt)
trials.addData('corr', corr)
# Register end of trial in the log file
if saveTrials:
thisExp.nextEntry()
# Run practice session
showInstruction(instructionPractice, ['space'])
runBlock(1, saveTrials=False)
# Real experiment
showInstruction(instructionExp, ['space'])
runBlock(5)
showInstruction(instructionThanks)