psychopy.org | Reference | Downloads | Github

Collecting data and writing to csv

Hello. I have written a completed script of an experiment, but am missing the data collection part. For example, I am trying to collect data that is mostly in the for loops, such as trial number, image presented, reaction time, and other variables. I have tried several different techniques to collect and write the data to a csv, but nothing seems to working. I would greatly appreciate any guidance on how to incorporate this into my current script. Below is my entire script:

import os, sys, glob, csv, random, datetime
from psychopy import gui, core, data, event, sound, visual, logging
from psychopy.hardware import keyboard

# obtain working directory path
directory = os.getcwd()

# initialize timer
timer = core.Clock()

# initialize keyboard 
kb = keyboard.Keyboard()

# initialize screen durations
iti_duration_list = [5, 7, 9, 11, 13] # create list so we jitter iti's throughout the task
trial_duration = 3
missed_trial_duration = 1.5
post_trial_duration = 1
thank_subject_duration = 3

# initialize trial data
prac_num_trials = 2
num_trials = 6

### launch task ###
# obtain subject id and confirm it has been entered
subj_dialogue = gui.Dlg(title="Pattern Detection Task")
subj_dialogue.addField('Enter Subject ID: ')
subj_dialogue.show()
subj_id=subj_dialogue.data[0]

if len(subj_id) < 1:
    core.quit()

# initialize window
win = visual.Window(fullscr=False, units='pix', monitor='testMonitor', color = [-.9,-.9,-.9])

# initialize task stimuli
diaganol_left_stimulus = visual.ImageStim(win=win,
                        image='/Users/amy/Desktop/psychophysics/stimuli/diaganol_left.png',
                        size = [300,300])
                        
diaganol_right_stimulus = visual.ImageStim(win=win,
                        image='/Users/amy/Desktop/psychophysics/stimuli/diaganol_right.png',
                        size = [300,300])
                        
few_checkers_stimulus = visual.ImageStim(win=win,
                        image='/Users/amy/Desktop/psychophysics/stimuli/few_checkers.png',
                        size = [300,300])

grey_square_stimulus = visual.ImageStim(win=win,
                        image='/Users/amy/Desktop/psychophysics/stimuli/grey_square.png',
                        size = [300,300])

hard_zig_zag_down_stimulus = visual.ImageStim(win=win,
                        image='/Users/amy/Desktop/psychophysics/stimuli/hard_zig_zag_down.png',
                        size = [300,300])

hard_zig_zag_left_stimulus = visual.ImageStim(win=win,
                        image='/Users/amy/Desktop/psychophysics/stimuli/hard_zig_zag_left.png',
                        size = [300,300])

hard_zig_zag_right_stimulus = visual.ImageStim(win=win,
                        image='/Users/amy/Desktop/psychophysics/stimuli/hard_zig_zag_right.png',
                        size = [300,300])

hard_zig_zag_up_stimulus = visual.ImageStim(win=win,
                        image='/Users/amy/Desktop/psychophysics/stimuli/hard_zig_zag_up.png',
                        size = [300,300])

horizontal_stripes_stimulus = visual.ImageStim(win=win,
                        image='/Users/amy/Desktop/psychophysics/stimuli/horizontal_stripes.png',
                        size = [300,300])

horizontal_stripes_extra_lines_stimulus = visual.ImageStim(win=win,
                        image='/Users/amy/Desktop/psychophysics/stimuli/horizontal_stripes_extra_lines.png',
                        size = [300,300])

many_checkers_stimulus = visual.ImageStim(win=win,
                        image='/Users/amy/Desktop/psychophysics/stimuli/many_checkers.png',
                        size = [300,300])

pentagon_down_empty_stimulus = visual.ImageStim(win=win,
                        image='/Users/amy/Desktop/psychophysics/stimuli/pentagon_down_empty.png',
                        size = [300,300])

pentagon_down_fill_stimulus = visual.ImageStim(win=win,
                        image='/Users/amy/Desktop/psychophysics/stimuli/pentagon_down_fill.png',
                        size = [300,300])

pentagon_up_empty_stimulus = visual.ImageStim(win=win,
                        image='/Users/amy/Desktop/psychophysics/stimuli/pentagon_up_empty.png',
                        size = [300,300])

pentagon_up_fill_stimulus = visual.ImageStim(win=win,
                        image='/Users/amy/Desktop/psychophysics/stimuli/pentagon_up_fill.png',
                        size = [300,300])

pentagon_up_left_empty_stimulus = visual.ImageStim(win=win,
                        image='/Users/amy/Desktop/psychophysics/stimuli/pentagon_up_left_empty.png',
                        size = [300,300])

pentagon_up_left_fill_stimulus = visual.ImageStim(win=win,
                        image='/Users/amy/Desktop/psychophysics/stimuli/pentagon_up_left_fill.png',
                        size = [300,300])

pentagon_up_right_empty_stimulus = visual.ImageStim(win=win,
                        image='/Users/amy/Desktop/psychophysics/stimuli/pentagon_up_right_empty.png',
                        size = [300,300])

pentagon_up_right_fill_stimulus = visual.ImageStim(win=win,
                        image='/Users/amy/Desktop/psychophysics/stimuli/pentagon_up_right_fill.png',
                        size = [300,300])

soft_zig_zag_down_stimulus = visual.ImageStim(win=win,
                        image='/Users/amy/Desktop/psychophysics/stimuli/soft_zig_zag_down.png',
                        size = [300,300])

soft_zig_zag_left_stimulus = visual.ImageStim(win=win,
                        image='/Users/amy/Desktop/psychophysics/stimuli/soft_zig_zag_left.png',
                        size = [300,300])

soft_zig_zag_right_stimulus = visual.ImageStim(win=win,
                        image='/Users/amy/Desktop/psychophysics/stimuli/soft_zig_zag_right.png',
                        size = [300,300])

soft_zig_zag_up_stimulus = visual.ImageStim(win=win,
                        image='/Users/amy/Desktop/psychophysics/stimuli/soft_zig_zag_up.png',
                        size = [300,300])

vertical_stripes_less_lines_stimulus = visual.ImageStim(win=win,
                        image='/Users/amy/Desktop/psychophysics/stimuli/vertical_stripes_less_lines.png',
                        size = [300,300])

vertical_stripes_stimulus = visual.ImageStim(win=win,
                        image='/Users/amy/Desktop/psychophysics/stimuli/vertical_stripes.png',
                        size = [300,300])

# initialize 10 seperate dictionaries
# each dict contains the true image shown, 2 similar images, and 4 dissimilar images
# for each alpha_update_time_list, we will show the true image 4 times, each similar image twice, and each dissimilar image once

vertical_stripes_stimulus_dict = {'true_image_list': [vertical_stripes_stimulus], 
                                'similar_image_list': [vertical_stripes_less_lines_stimulus, many_checkers_stimulus],
                                'dissimilar_image_list': [pentagon_up_right_fill_stimulus, horizontal_stripes_stimulus,
                                pentagon_up_fill_stimulus, horizontal_stripes_extra_lines_stimulus]}
                                                                
horizontal_stripes_stimulus_dict = {'true_image_list': [horizontal_stripes_stimulus],
                                    'similar_image_list': [horizontal_stripes_extra_lines_stimulus, few_checkers_stimulus],
                                    'dissimilar_image_list': [soft_zig_zag_left_stimulus, pentagon_up_left_fill_stimulus,
                                    vertical_stripes_stimulus, vertical_stripes_less_lines_stimulus]}

pentagon_up_left_empty_stimulus_dict = {'true_image_list': [pentagon_up_left_empty_stimulus],
                                   'similar_image_list': [pentagon_up_left_fill_stimulus, pentagon_down_empty_stimulus],
                                   'dissimilar_image_list': [horizontal_stripes_stimulus, soft_zig_zag_down_stimulus,
                                   many_checkers_stimulus, few_checkers_stimulus]}

soft_zig_zag_down_stimulus_dict = {'true_image_list': [soft_zig_zag_down_stimulus],
                                'similar_image_list': [hard_zig_zag_down_stimulus, horizontal_stripes_stimulus],
                                'dissimilar_image_list': [diaganol_left_stimulus, pentagon_up_left_fill_stimulus,
                                diaganol_right_stimulus, vertical_stripes_less_lines_stimulus]}

pentagon_down_empty_stimulus_dict = {'true_image_list': [pentagon_down_empty_stimulus],
                                    'similar_image_list': [pentagon_up_left_empty_stimulus, pentagon_up_left_fill_stimulus],
                                    'dissimilar_image_list': [vertical_stripes_stimulus, vertical_stripes_less_lines_stimulus,
                                    soft_zig_zag_down_stimulus, hard_zig_zag_down_stimulus]}

soft_zig_zag_right_stimulus_dict = {'true_image_list': [soft_zig_zag_right_stimulus],
                                    'similar_image_list': [hard_zig_zag_right_stimulus, vertical_stripes_less_lines_stimulus],
                                    'dissimilar_image_list': [pentagon_up_fill_stimulus, hard_zig_zag_down_stimulus,
                                    diaganol_left_stimulus, pentagon_up_left_fill_stimulus]}

hard_zig_zag_up_stimulus_dict = {'true_image_list': [hard_zig_zag_up_stimulus],
                                'similar_image_list': [soft_zig_zag_up_stimulus, vertical_stripes_less_lines_stimulus],
                                'dissimilar_image_list': [diaganol_left_stimulus, pentagon_down_empty_stimulus,
                                pentagon_up_left_fill_stimulus, diaganol_right_stimulus]}

hard_zig_zag_left_stimulus_dict = {'true_image_list': [hard_zig_zag_left_stimulus],
                                'similar_image_list': [soft_zig_zag_right_stimulus, vertical_stripes_stimulus],
                                'dissimilar_image_list': [horizontal_stripes_stimulus, diaganol_left_stimulus,
                                pentagon_up_left_fill_stimulus, horizontal_stripes_extra_lines_stimulus]}
                                
diaganol_right_stimulus_dict = {'true_image_list': [diaganol_right_stimulus],
                                'similar_image_list': [diaganol_left_stimulus, vertical_stripes_less_lines_stimulus],
                                'dissimilar_image_list': [pentagon_down_fill_stimulus, many_checkers_stimulus,
                                horizontal_stripes_extra_lines_stimulus, pentagon_up_left_empty_stimulus]}
                                
few_checkers_stimulus_dict = {'true_image_list': [few_checkers_stimulus],
                            'similar_image_list': [many_checkers_stimulus, vertical_stripes_less_lines_stimulus],
                            'dissimilar_image_list': [soft_zig_zag_down_stimulus, diaganol_right_stimulus,
                            pentagon_up_left_fill_stimulus, pentagon_down_empty_stimulus]}

# create a list of list of the above dictionaries so we can randomly choose a dict during the task
display_stimuli_list = [vertical_stripes_stimulus_dict, horizontal_stripes_stimulus_dict,
                       pentagon_up_left_empty_stimulus_dict, soft_zig_zag_down_stimulus_dict,
                       pentagon_down_empty_stimulus_dict, soft_zig_zag_right_stimulus_dict,
                       hard_zig_zag_up_stimulus_dict, hard_zig_zag_left_stimulus_dict,
                       diaganol_right_stimulus_dict, few_checkers_stimulus_dict]
                       
# initialze alpha times, these are the rates at which opacity is updated
alpha_time_update_1_cond = 2.5/12 
alpha_time_update_2_cond = 5/12
alpha_time_update_3_cond = 10/12

# intialize empty lists so we can append each permutation of stimuli we want 
condition_one_list = []
condition_two_list = []
condition_three_list = []
condition_four_list = []

for each_dict in display_stimuli_list:
    condition_one = [each_dict['true_image_list'][0], each_dict['similar_image_list'][0], each_dict['dissimilar_image_list'][0]]
    condition_two = [each_dict['true_image_list'][0], each_dict['similar_image_list'][0], each_dict['dissimilar_image_list'][1]]
    condition_three = [each_dict['true_image_list'][0], each_dict['similar_image_list'][1], each_dict['dissimilar_image_list'][2]]
    condition_four = [each_dict['true_image_list'][0], each_dict['similar_image_list'][1], each_dict['dissimilar_image_list'][3]]
    
    condition_one_list.append(condition_one)
    condition_two_list.append(condition_two)
    condition_three_list.append(condition_three)
    condition_four_list.append(condition_four)

# add all conditions together
# now we have 40 lists in all_conditions, but we still need to add opacity rate of change as a paraemter
# initialize 3 seperate lists to append different opacity to each list
all_conditions = condition_one_list + condition_two_list + condition_three_list + condition_four_list
all_conditions_one_opacity = all_conditions
all_conditions_two_opacity = all_conditions
all_conditions_three_opacity = all_conditions

# append different opacity to each list
for each_list in all_conditions_one_opacity:
    each_list.append(alpha_time_update_1_cond)
for each_list in all_conditions_two_opacity:
    each_list.append(alpha_time_update_2_cond)
for each_list in all_conditions_three_opacity:
    each_list.append(alpha_time_update_3_cond)

# add all conditions together, now we have 120 total lists in this list_of_all_trials
# each true image is displayed 4 x 3 each opacity
# 12 x 10 stim = 120 total trials
list_of_all_trials = all_conditions_one_opacity + all_conditions_two_opacity + all_conditions_three_opacity # combine each list for a total of 120 trials

# initiation the fixation cross for the iti
fixation_cross = visual.ShapeStim(win, vertices=((0, -0.03), (0, 0.03), (0,0), (-0.03,0), (0.03, 0)), lineWidth=15, closeShape=False, lineColor="white", size = [400,400])

# initialize instructions screens
instructions_1_screen = visual.ImageStim(win=win,
                                        image='/Users/amy/Desktop/psychophysics/instructions/instructions_1_screen.png',
                                        size = [1200,800])
                                        
instructions_2_screen = visual.ImageStim(win=win,
                                        image='/Users/amy/Desktop/psychophysics/instructions/instructions_2_screen.png',
                                        size = [1200,650])
                                        
instructions_3_screen = visual.ImageStim(win=win,
                                        image='/Users/amy/Desktop/psychophysics/instructions/instructions_3_screen.png',
                                        size = [1200,800])
                                        
instructions_4_screen = visual.ImageStim(win=win,
                                        image='/Users/amy/Desktop/psychophysics/instructions/instructions_4_screen.png',
                                        size = [1200,800])
                                        
instructions_5_screen = visual.ImageStim(win=win,
                                        image='/Users/amy/Desktop/psychophysics/instructions/instructions_5_screen.png',
                                        size = [1200,800])

# initialize text screens
thank_you_screen = visual.TextStim(win,
                                text='Thank you for your participation')
                                
missed_trial_screen = visual.TextStim(win,
                                    text='No response recorded')
begin_real_task_screen = visual.TextStim(win,
                                    text='You have completed the practice round. Please press any button to advance to the main game.')

# initialize post trial stimulus position list so we can present the stimuli in random positions each trial
post_trial_stimulus_position_list = [(-200, 200), (200, 200), (0, 200)]

# initialize post trial stimuli
pattern_question_text = visual.TextStim(win, text='Which pattern did you see?', pos=(0, 320)) # pattern question text
min_confidence = 0
max_confidence = 100
confidence_range = range(min_confidence, max_confidence+1)
labelpoints = [0, 0.25, 0.5, 0.75, 1.0]  # the fractions of the range we want the labels at
labels = [str(int(max_confidence * point)) for point in labelpoints]  # the actual text for each label
ticks = [len(confidence_range) * point for point in labelpoints] 
ratingScale = visual.RatingScale(win=win, choices=confidence_range,labels=labels, tickMarks=ticks)
confidence_text = visual.TextStim(win, "How confident are you that this is pattern you saw? \n (0 = no confidence, 100 = full confidence)")

# display instructions
event.clearEvents()
instructions_1_screen.draw()
win.flip()
event.waitKeys()
instructions_2_screen.draw()
win.flip()
event.waitKeys()
instructions_3_screen.draw()
win.flip()
event.waitKeys()
instructions_4_screen.draw()
win.flip()
event.waitKeys()
instructions_5_screen.draw()
win.flip()

# practice loop
for i in range(0, prac_num_trials):

    fixation_cross.draw()
    win.flip()
    core.wait(random.choice(iti_duration_list))
    select_trial_list = random.choice(list_of_all_trials)
    present_true_stimulus = select_trial_list[0]
    present_similar_stimulus = select_trial_list[1]
    present_dissimilar_stimulus = select_trial_list[2]
    unveil_rate = select_trial_list[3]
    mask_stimulus = grey_square_stimulus
    
    kb.clearEvents()
    timer.reset()
    while timer.getTime() < unveil_rate * 25:
        
        current_time = timer.getTime()
        key = kb.getKeys()
        
        if 'space' in key:
            break
        if current_time < unveil_rate:
            mask_stimulus.opacity = 1
        elif current_time  >= unveil_rate and current_time < unveil_rate * 2:
            mask_stimulus.opacity = .985
        elif  current_time >= unveil_rate * 2 and current_time < unveil_rate * 3:
            mask_stimulus.opacity = .970
        elif  current_time >= unveil_rate * 3 and current_time < unveil_rate * 4:
            mask_stimulus.opacity = .955
        elif  current_time >= unveil_rate * 4 and current_time < unveil_rate * 5:
            mask_stimulus.opacity = .940        
        elif  current_time > unveil_rate * 5 and current_time < unveil_rate * 6:
            mask_stimulus.opacity = .925                
        elif  current_time > unveil_rate * 6 and current_time < unveil_rate * 7:
            mask_stimulus.opacity = .910
        elif  current_time > unveil_rate * 7 and current_time < unveil_rate * 8:
            mask_stimulus.opacity = .895
        elif  current_time > unveil_rate * 8 and current_time < unveil_rate * 9:
            mask_stimulus.opacity = .880
        elif  current_time > unveil_rate * 9 and current_time < unveil_rate * 10:
            mask_stimulus.opacity = .865
        elif  current_time > unveil_rate * 10 and current_time < unveil_rate * 11:
            mask_stimulus.opacity = .850
        elif  current_time > unveil_rate * 11 and current_time < unveil_rate * 12:
            mask_stimulus.opacity = .835
        elif  current_time > unveil_rate * 12 and current_time < unveil_rate * 13:
            mask_stimulus.opacity = .820
        else:
            missed_trial_screen.draw()
            win.flip()
            core.wait(missed_trial_duration)
            break
                

        # now just have this once:
        
        present_true_stimulus.size = [300,300]
        present_true_stimulus.pos = (0,0)
        present_true_stimulus.draw()
        mask_stimulus.draw()         
        win.flip()
    
    shuffled_post_trial_stimulus_position_list = random.sample(post_trial_stimulus_position_list, len(post_trial_stimulus_position_list))
    present_true_stimulus.size = [150,150]
    present_similar_stimulus.size = [150,150]
    present_dissimilar_stimulus.size = [150,150]
    present_true_stimulus.pos = shuffled_post_trial_stimulus_position_list[0]
    present_similar_stimulus.pos = shuffled_post_trial_stimulus_position_list[1]
    present_dissimilar_stimulus.pos = shuffled_post_trial_stimulus_position_list[2]
    mouse = event.Mouse(win)
    Pressed = False

    while not Pressed:
        pattern_question_text.draw()
        present_true_stimulus.draw()
        present_similar_stimulus.draw()
        present_dissimilar_stimulus.draw()
        win.flip()

        # choose which stimulus to draw:
        for stimulus in [present_true_stimulus, present_similar_stimulus, present_dissimilar_stimulus]:
            if mouse.isPressedIn(stimulus):
                stim_to_draw = stimulus

                while ratingScale.noResponse:
                    stim_to_draw.draw()
                    confidence_text.draw()
                    ratingScale.draw()
                    win.flip()
                rating = ratingScale.getRating()
                Pressed = True
                ratingScale.reset()
                break

# end of practice session
begin_real_task_screen.draw() # ask subject to make button press to advance to real part of the session
win.flip()
event.waitKeys()

# main loop
for i in range(0, num_trials):

    fixation_cross.draw()
    win.flip()
    core.wait(random.choice(iti_duration_list))
    select_trial_list = random.choice(list_of_all_trials)
    present_true_stimulus = select_trial_list[0]
    present_similar_stimulus = select_trial_list[1]
    present_dissimilar_stimulus = select_trial_list[2]
    unveil_rate = select_trial_list[3]
    mask_stimulus = grey_square_stimulus
    
    
    list_of_all_trials.remove(select_trial_list) # every trial, we remove the list that was selected so we do not repeat
    
    
    kb.clearEvents()
    timer.reset()
    while timer.getTime() > 0:
        current_time = timer.getTime()
        key = kb.getKeys()
        if 'space' in key:
            break
        if current_time < unveil_rate:
            mask_stimulus.opacity = 1
        elif current_time  >= unveil_rate and current_time < unveil_rate * 2:
            mask_stimulus.opacity = .985
        elif  current_time >= unveil_rate * 2 and current_time < unveil_rate * 3:
            mask_stimulus.opacity = .970
        elif  current_time >= unveil_rate * 3 and current_time < unveil_rate * 4:
            mask_stimulus.opacity = .955
        elif  current_time >= unveil_rate * 4 and current_time < unveil_rate * 5:
            mask_stimulus.opacity = .940        
        elif  current_time > unveil_rate * 5 and current_time < unveil_rate * 6:
            mask_stimulus.opacity = .925                
        elif  current_time > unveil_rate * 6 and current_time < unveil_rate * 7:
            mask_stimulus.opacity = .910
        elif  current_time > unveil_rate * 7 and current_time < unveil_rate * 8:
            mask_stimulus.opacity = .895
        elif  current_time > unveil_rate * 8 and current_time < unveil_rate * 9:
            mask_stimulus.opacity = .880
        elif  current_time > unveil_rate * 9 and current_time < unveil_rate * 10:
            mask_stimulus.opacity = .865
        elif  current_time > unveil_rate * 10 and current_time < unveil_rate * 11:
            mask_stimulus.opacity = .850
        elif  current_time > unveil_rate * 11 and current_time < unveil_rate * 12:
            mask_stimulus.opacity = .835
        elif  current_time > unveil_rate * 12 and current_time < unveil_rate * 13:
            mask_stimulus.opacity = .820
        else:
            missed_trial_screen.draw()
            win.flip()
            core.wait(missed_trial_duration)
            break    
        
        
        # now just have this once:
        present_true_stimulus.size = [300,300]
        present_true_stimulus.pos = (0,0)
        present_true_stimulus.draw()
        mask_stimulus.draw()         
        win.flip()
    
    shuffled_post_trial_stimulus_position_list = random.sample(post_trial_stimulus_position_list, len(post_trial_stimulus_position_list))
    present_true_stimulus.size = [150,150]
    present_similar_stimulus.size = [150,150]
    present_dissimilar_stimulus.size = [150,150]
    present_true_stimulus.pos = shuffled_post_trial_stimulus_position_list[0]
    present_similar_stimulus.pos = shuffled_post_trial_stimulus_position_list[1]
    present_dissimilar_stimulus.pos = shuffled_post_trial_stimulus_position_list[2]
    mouse = event.Mouse(win)
    Pressed = False

    while not Pressed:
        pattern_question_text.draw()
        present_true_stimulus.draw()
        present_similar_stimulus.draw()
        present_dissimilar_stimulus.draw()
        win.flip()

        # choose which stimulus to draw:
        for stimulus in [present_true_stimulus, present_similar_stimulus, present_dissimilar_stimulus]:
            if mouse.isPressedIn(stimulus):
                stim_to_draw = stimulus

                while ratingScale.noResponse:
                    stim_to_draw.draw()
                    confidence_text.draw()
                    ratingScale.draw()
                    win.flip()
                rating = ratingScale.getRating()
                Pressed = True
                ratingScale.reset()
                break
                
# thank subject for participation
thank_you_screen.draw()
win.flip()
core.wait(thank_subject_duration)```