Video Freezes During TMS Pulse Delivery in PsychoPy Using 'magpy' Package

Has anyone experienced video freezing when delivering a TMS pulse during a PsychoPy experiment? Does anyone have solutions to ensure the video runs smoothly during the TMS pulse?

PsychoPy Version: 2024.1.4
Operating System: Windows 11
TMS Setup: Triggering Magstim BiStim² stimulator from an external computer via USB to serial cable

I’m doing a very simple experiment on PsychoPy. In each trial, participants see a fixation point, then a short (<3 seconds) video is played and then there is a short bank screen for a few ms. See screenshot below:

This runs fine without issues. However, I’d like to deliver a TMS pulse at 1 sec after the start of each video. The TMS pulse is successfully triggered using the Magstim library, but I’ve run into a problem: the video freezes momentarily when the TMS pulse is delivered. The freeze only lasts for a fraction of a second, but it’s enough to disrupt the video.

I have the following code included during the ‘fixation’ routine:

# before experiment
from magpy import magstim
# Importing the core module from the psychopy library for timing functions
from psychopy import core

# Initialise variables
timer = core.Clock()
time_to_fire = 1.0  # Time in seconds for TMS to fire

And then this code during the ‘trial’ routine:

# Begin experiment
timer.reset()
#each frame
# Get the elapsed time since the routine started
elapsed_time = timer.getTime()

# Check if it's the desired time to trigger TMS
if elapsed_time >= time_to_fire and elapsed_time < time_to_fire + 0.5:
    myMagstim.fire()  # Trigger TMS
    myMagstim.arm(delay=True)

Any help would be much appreciated!

I took a quick glance at the magpy.magstim code. The problem is most likely this:

myMagstim.arm(delay=True)

If delay is True, it inserts a sleep() call, which is a built-in Python function that freezes all code execution, including window flips and movie playback. If you need the delay the best option would be to use another timer in your code component (the same way you control the fire command now) and make sure you use myMagStim.arm(delay=False)

Hi Jonathan, thanks for taking the time to look at this!

Unfortunately, changing

myMagstim.arm(delay=True)

to

myMagstim.arm(delay=False)

didn’t resolve the issue with the video freezing.

I also tried using ‘threading’ to trigger the TMS in a different thread than the videos being played. This fixed the video freezing, but then the TMS pulse is only delivered during the first trial. After the first pulse, the stimulator appears to be re-arming, but no additional pulses are triggered in subsequent trials.

Any further suggestions would be much appreciated!

Best,

Solya

Ah, I might be overthinking this. The way it’s set up now, it will try to fire and re-arm for 31 consecutive frames, which is probably gumming things up. Assuming you only want it to fire once per stimulus I think you might want something more like this (and note some of the code is in begin routine, not begin experiment)

# Begin routine
timer.reset()
fired = False
#each frame
# Get the elapsed time since the routine started
elapsed_time = timer.getTime()

# Check if it's the desired time to trigger TMS
if elapsed_time >= time_to_fire and elapsed_time < time_to_fire + 0.5 and not fired:
    myMagstim.fire()  # Trigger TMS
    fired = True
    myMagstim.arm(delay=False)

My other suggestion, if you’re only firing once per trial, is to move the myMagstim.arm() command to the “End routine” code rather than each frame. At the very least that will tell you if the issue is the fire() or the arm().

Awesome, thank you so much for this- much appreciated!