psychopy.org | Reference | Downloads | Github

Delay between visual stimuli and (parallel port) triggers


#1

Hi,

I’ve been trying to use PsychoPy for an experiment where subjects are required to focus on phase-changing checkerboards, while EEG is being recorded. While all experimental procedures are working just fine, I’m having some trouble with getting the delay between certain frames (the first frames when a phase change occurs) and parallel output trigger constant (mean=~30ms, std=~6.5ms). I measure delays using the BlackBox toolkit (using the opto-detector). First, I thought it was because of the graphics card or monitor I use, but when I implement the exact same experiment in E-Prime, the delay-variability looks really good (mean=~26ms, std=0.1 ms).

A figure showing the delays using PsychoPy (note the strange pattern… sync issue?):

A figure showing the delays using E-Prime:
delayEprime

A simplified version of the code I use:

Ntrials = 100
Nframe_image = 30 #0.5 seconds, assuming a refresh rate at 60Hz

fname = resource_path("stimuli\\Checkerboard_check_" + checksize + "_phase2.png")
checkerboard_phase1 = visual.ImageStim(
		win=win_sub,
		image=fname,
		units="pix"
	)

fname = resource_path("stimuli\\Checkerboard_check_" + checksize + "_phase1.png")
checkerboard_phase2 = visual.ImageStim(
		win=win_sub,
		image=fname,
		units="pix"
	)

win_sub = visual.Window(
	size=(1280,1024), fullscr=True, screen=1,
	allowGUI=False, allowStencil=False,
	monitor='testMonitor', color=[-1,-1,-1], colorSpace='rgb',
	blendMode='avg', useFBO=False, waitBlanking = True)

for iTrial in range(Ntrials): 
	checkerboard_phase1.draw()
	win_sub.flip()
	port.setPin(PinCheckPhase1Trigger, 1)
	for iframe in range(Nframe_image - 1):
		checkerboard_phase1.draw()
		if iframe==9:
			port.setPin(PinCheckPhase1Trigger, 0)
		win_sub.flip()
		
	checkerboard_phase2.draw()
	win_sub.flip()
	port.setPin(PinCheckPhase2Trigger, 1) 
	for iframe in range(Nframe_image - 1):
		checkerboard_phase2.draw()
		if iframe==9:
			port.setPin(PinCheckPhase2Trigger, 0) 
		win_sub.flip()

Does anyone know how I can solve this? I guess I’m just missing an option somewhere…

Kind regards,
Robert


#2

I would approach this by logging times at various points in your code to look for issues there, and compare to your hardware validation.

It won’t be related to your detection of trigger onset events, but the trigger offset should occur after the win_sub.flip() line, to reduce variability in the pulse width.


#3

(part 1 / 2) Thanks for your suggestion. I played around with some settings (mostly graphic card settings) but I still get some strange results.

Some information:

  • There are two stimuli (checkerboards): stimulus A, and stimulus B.
  • A marker is sent after each transition.
  • A transition occurs every 0.5 seconds (30 frames).
  • I placed an opto-detector on the screen to detect changes in the intensity on the screen (only occur during a transition between stimuli).

When I look at the time difference between two consecutive As, I find perfectly stable values (except for a few outliers; likely missed frames). Similarly for the time difference between markers.
deltaT_01

When I look at the time difference between A and Bs, I again get perfectly stable values. Similarly for the opto-detector (mismatch between values in the figure below are because of the threshold of the detector).
deltaT_02


#4

(part2/2)
When I look at the time difference between the stimulus transition and marker, I still get this strange pattern. The (mean) differences between the red and blue values can be explained by the detection-threshold of the opto-detector.
deltaT_03

I find this pattern strange. If we look at the difference of the values, it seems as if the drawing/flip is out of sync with the actual drawing and flip…
deltaT_04

Any suggestions on how I can fix this strange behavior…?


#5

Again, I did some additional testing and I think I know what the problem is. If I make a simple experiment where the screen flips from black to white and vice versa every second (so two phase shifts per second); the actual time two phases are presented on the screen is about 998 - 999 ms. This suggests I “lose” several ms per second, which is in line with one of the previous figures I posted…