How to use ExperimentHandler/TrialHandler

Hello all,

My problem is: I cant generate a data file that I wish to achieve. It appears I have to learn how to use ‘experimentHandler’ and/or ‘trialHandler’ in my experiments. It would be amazing if some of you can show me how to use that in my own codes.

Below I have copied prototype platform that I wish to learn from. The color of the fixation changes (at stays at that color for 15ms) during randomly selected time point between 250-500ms. This whole block lasts 6 seconds and followed by 6 seconds ‘wait’ block, where the fixation color stays at baseline (black color). I want to record observers’ performance on judging the color of the fixation.

With my current knowledge and capabilities I can only produce an excel sheet that shows what happens at each frame (including the color of the fixation and pressed key). The data file that I wish to achieve would be something like this:

Is using ExperimentHandler/TrialHandler or other things useful for this kind of situation? Can I do this without them? Is there a way for writing data at different locations in the code (recording some at each frame, while recording other data at every trial, for example)?

Thank you very much for your time, hopefully I will return the goodness.

Side note: If you find the code poorly written and/or painfully to follow, I would also be happy if you can conceptually explain the ways in which I can approach the problem.

from __future__ import division  # so that 1/3=0.333 instead of 1/3=0
from psychopy import visual, core, data, event, logging, sound, gui
from psychopy.constants import *  # things like STARTED, FINISHED
import numpy  # whole numpy lib is available, prepend 'np.'
from numpy import sin, cos, tan, log, log10, pi, average, sqrt, std, deg2rad, rad2deg, linspace, asarray
from numpy.random import random, randint, normal, shuffle
import os  # handy system and path functions
from random import choice, randrange, shuffle
from psychopy.tools.coordinatetools import pol2cart, cart2pol
import time
from psychopy.tools.filetools import fromFile, toFile

#opening data file
fileName = 'fixationTask'
dataFile = open(fileName+'.csv', 'w')#a simple text file with 'comma-separated-values'
dataFile.write("{},{},{},{}\n".format("frameCount","magicFrame","doThreeTimes","response\n"))

win = visual.Window([1680, 1050], units = 'deg', monitor = 'Umram', color = 'gray',fullscr=False)


globalClock = core.Clock()

refRate = 60  # 1 second
nTrials = 4
stimDur = refRate * 6 # 6 seconds
t = 0

yellow = [1,1,-1]
black = [-1,-1,-1]
red = [1,-1,-1]


fixationColored = visual.GratingStim(win, size=0.1, pos=[0,0], sf=0,color = red, colorSpace = 'rgb')
fixationRegular = visual.GratingStim(win, size=0.1, pos=[0,0], sf=0,color = black,colorSpace = 'rgb')
fixationYellow = visual.GratingStim(win, size=0.1, pos=[0,0], sf=0,color = yellow,colorSpace = 'rgb')

waitText = visual.TextStim(win, text = 'wait', pos = [1,0])

for trial in range(nTrials):

    for times in range(2): # dynamic fixation period followed by 'wait' period for each trial
        ## some initial parameters before the frame loop ##
        frameCount = -1
        doThreeTimes = 0
        selected = False
        magicFrame = choice(range(15,30)) #initial random magic frame
        colorChoice = choice(['yellow', 'red'])
        fixationColored.color = colorChoice
        response = None
        
        ##### Frame Loop ######
        for frames in range(stimDur):
            keys = event.getKeys(keyList=["1", "4", "escape"],timeStamped = True)
            t = globalClock.getTime()
            if times % 2 == 0:
                ### dynamic fixation block ###
                if frameCount >= magicFrame and doThreeTimes < 3: # colored fixation lasts 3 frames (50ms)
                    fixa = fixationColored
                    doThreeTimes += 1
                else:
                    fixa = fixationRegular
            else:
                ### wait period ###
                waitText.draw()
            
            fixa.draw()
            win.flip()
            frameCount += 1
            
            for key in keys: #observer has to press 1 for red and 4 for yellow.
                if key[0] == '1':
                    if colorChoice == 'red':
                        response = 1
                    elif colorChoice =='yellow':
                        response = -1
                elif key == '4':
                    if colorChoice == 'yellow':
                        response = 1
                    elif colorChoice == 'red':
                        response = -1
            if frameCount >= 60: # One second/round has elapsed, time to reset some stuff
                frameCount = 0
                doThreeTimes = 0
                selected = False
                colorChoice = choice(['yellow','red'])
                fixationColored.color = colorChoice
                magicFrame = choice(range(15,30))
                
            dataFile.write("{},{},{},{}\n".format(frameCount, magicFrame,colorChoice, response))
        
dataFile.close()
win.close()
core.quit()

The TrialHandler class is really designed for working with data at the trial level, rather than every frame, so if you want to record information at that level, a custom solution is probably a good way to go.

So its not clear what your actual problem is then: you seem to be creating the file format you want? One suggestion would be not to actually write to the file on every frame: that might have performance implications. You’re probably better off to store the information in memory and only write it to disk once per trial, or at the end of block of trials.