Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Supported by

fMRI catch trial response messing up timing of presentation

edited June 2018 in OpenSesame

Hi all,

I'm working on an fMRI experiment with a 2000 ms TR in which the first 1000 ms is a scan, and next 1000 ms is a silent gap in which we present auditory stimuli.

At first, I tried using the "absolute timing" script that Sebastiaan provided to make the trials be presented every 2000 ms. This worked for the first block, but because we are using a multiband sequence that takes the scanner 40s to warm up, the "time_to_pad" variable would inevitably get messed up between blocks, and the second block's timing sequence would be off. Instead, it presented consistently presented stimuli every 1700 ms.

I abandoned the absolute timing in favor of having every trial triggered by the "5" keyboard response sent by our scanner to the testing computer. At the beginning of a TR, the scanner sends an emulated "5" keypress to the computer. As such, I put a keyboard response that required a "5" at the beginning of the block sequence to initiate the trial. It is then followed by a 1000 ms advanced delay, so that the audio doesn't start playing during the noisy scan sequence. Following the advanced delay is a sketchpad with a fixation cross that has a duration of 0, then the sampler that plays the auditory sequence, and then a keyboard response. On some trials, the stimulus is played more quietly and we use that as a catch trial to ensure participants are paying attention. Here is what this looks like

I currently have the timeout for the catch_response set at 1000 ms. However, when I look at the timing in my log file for the sampler called "stimulus", I see that trials are lasting 4000 ms instead of 2000 ms.

When I remove the "catch_response" item, the stimuli go back to being presented every 2000 ms and the timing is perfect. However, this breaks our ability to have catch trials.

I'm really struggling with this but I believe it has something to do with the timeout for catch_response. Any help would be much appreciated with this issue, as it will allow our lab to use OpenSesame for all of our future fMRI experiments.


  • I believe I have found a solution by using Sebastiaan's "absolute timing" script and modifying it so it resets the first trial timestamp for the first trial of each block, instead of trying to continue timing from the very beginning of the experiment.

  • Good to hear you figured it out!

    There's much bigger issues in the world, I know. But I first have to take care of the world I know.

  • edited July 2018

    Here is a more detailed explanation of what I changed, hopefully this will be useful to others in the future using OpenSesame for fMRI experiments that have breaks in between runs/blocks.

    In the code that Sebastiaan provides for absolute timing, it takes the timestamp of the very first trial and aligns timing to that for every stimulus thereafter. If you have a single, uninterrupted run with no breaks, this works fine. Given the particular scan parameters for my current experiment (multiband sequence), there is 40s of scanner "warmup" at the beginning of each block as it gets ready. This is not an issue for the first block, as the timing script does not mark the first trial timestamp until after the block has begun.

    However, for the remaining 9 blocks in the experiment, it attempts to pad 40s from the last trial of one block to the first trial of the following block. This leads to timing issues every time you transition from one block to another.

    The simple solution is to get the "live row" number of the loop (assuming each block/run of the experiment is its own loop) and have the timing of that block be relative to that, and not relative to the beginning of the experiment.

    Here is my code:

    # Specify how long you want the trial the last. Make sure that trials do not last
    # longer!
    trial_duration = xxxx
    # For the first trial, just note the time
    if var.live_row == 0:
            exp.set('first_trial_timestamp', self.time())
            time_to_pad = 0
    # For the other trials, wait until the the trial should start, based on the time
    # of the first trial and the trial duration
            time_to_pad = self.get('first_trial_timestamp') + var.live_row * trial_duration - self.time()
            if time_to_pad > 0:
    # Remember padding time
    exp.set('time_to_pad', time_to_pad)
Sign In or Register to comment.