Select Git revision
trial_runner.py
-
Josh Zosky authoredJosh Zosky authored
trial_runner.py 5.38 KiB
from os.path import basename, splitext
from random import randint
from psychopy import core, event
def start(win, fixation_screen, pause_screen, stim_list, stim_order, maker, data_file, hardware=None):
# Set trial constants
start_alpha = 1.0
change_time = 6000 # milliseconds # TODO:change happens in 2 sec blocks
change_rate = 1000 / 60.0
change_value = change_time / change_rate
constants = (start_alpha, change_time, change_rate, change_value)
'''
all_stim_list = []
for i in xrange(len(stim_order) / len(stim_list)):
shuffle(stim_list)
all_stim_list.extend(stim_list)
'''
trial_clock = core.Clock()
for trial_number, conditions in enumerate(stim_order):
block_number = ((trial_number + 1) / len(stim_order)) + 1
stim_pairs = stim_list[trial_number]
# print stim_pairs
stim_pair = select_stimuli(stim_pairs, conditions[0], conditions[1])
# print stim_pair
image_1 = basename(stim_pair[1])
image_2 = basename(stim_pair[0])
change_type = str(conditions[1])
stimuli_number = image_1.split('_')[0]
stimuli_orientation = image_1.split('_')[1]
trial_info = {'img1': image_1, 'img2': image_2, 'trl-': trial_number, 'bloc': block_number,
'img#': stimuli_number, 'orie': stimuli_orientation, 'CTyp': change_type}
stim_pair = (maker(win, stim_pair[0]), maker(win, stim_pair[1]))
if hardware:
hardware.sync()
display_fixation(win, fixation_screen, 1000, 1500)
if hardware:
hardware.send_event(key='imag', label='ImageAppears', description='Image appeared on-screen',
table=trial_info)
trial(win, trial_clock, stim_pair, constants)
# TODO:Move response to post-image so no motor artifact in trial. Include randomized response buttons for each
# TODO: trial to avoid preparatory activity, indicate onscreen what each button represents for that trial (e.g. 1=change detected, 4=change not detected)
pause, response, response_time = check_response(event.getKeys(timeStamped=trial_clock))
if pause:
escape = pause_screen.show()
if escape:
break
else:
win.flip(clearBuffer=True)
data_file.write_data([block_number,
trial_number,# 'Cumulative_trial_number' \
image_1,# 'Image_Start' \
image_2,# 'Image_Finish' \
stimuli_number,# 'Stimuli_Number' \
stimuli_orientation,# 'Stimuli_Orientation' \
change_type,# 'Change' \
str(conditions[1] is not None),# 'Correct_Response' \
str(response),# 'Response' \
str(response and conditions[1]),# 'Correct' \
str(response_time),# 'Response_Time' \
str(trial_clock.getTime())# 'Trial_time'
])
def trial(win, clock, stimuli, constants):
ch_value = constants[3]
win.callOnFlip(clock.reset)
for j in xrange(0, len(stimuli), 2):
stimuli[j].draw()
stimuli[j + 1].draw()
win.flip()
for i in xrange(int(ch_value) - 1):
stimuli[j].draw()
if stimuli[j+1].opacity > 0.0:
stimuli[j + 1].opacity -= 1 / ch_value
stimuli[j + 1].draw()
win.flip()
def select_stimuli(stim_list, orientation, abs_pres):
"""
:param stim_list: list of 4 potential stimuli variants
:param orientation: Which image orientation to use, left or right
:param abs_pres: Which presentation style to perform, disappear or appear
:return: list of stimuli in order of presentation style, 2nd image fades out while 1st image emerges.
"""
return_list = [None, None]
if abs_pres is 'present':
alt_abs_pres = 'in'
elif abs_pres is 'absent':
alt_abs_pres = 'neither'
else:
alt_abs_pres = None
for stim in stim_list:
stim_split = splitext(stim.lower())[0].split('_')
if orientation.lower() in stim_split:
if abs_pres:
if abs_pres in stim_split or alt_abs_pres in stim_split:
return_list[0] = stim
else:
return_list[1] = stim
elif 'present' in stim_split or 'in' in stim_split:
return_list = list((stim, stim))
return return_list
return return_list
def display_fixation(win, fixation_screen, ISI_min, ISI_max):
fixation_screen.draw()
win.flip()
ISI = randint(ISI_min, ISI_max) / 1000.0
core.wait(ISI)
return ISI
def check_response(keys_tuple):
# # Checking for and clearing out all uses of 'esc' from the keys_tuple list
#
pause = False
pop_list = []
for index, key_tuple in enumerate(keys_tuple):
if 'escape' in key_tuple:
pop_list.insert(0, index)
pause = True
for popper in pop_list:
keys_tuple.pop(popper)
# # Check if there's any responses left, and if so, return the first one.
#
response, response_time = (None, None)
if keys_tuple:
response_tuple = keys_tuple[0]
response, response_time = response_tuple
return pause, response, response_time