Timestamp discrepancy between stimulus update and variable change

Hello Christopher,
I have a weird issue that I don’t what could cause it. In the experiment, a stimulus appears after a randomized interval once the monkey fixates on the fixation point. The way it’s implemented is that a variable, let’s call it stim_wait, is set to this random value ( time_offset + disc_rand(250,1500) ) . Then a timer is used with this variable as the time. If the timer expires with the animal fixating, the target stimulus appears.
When we looked at the time stamps of the stim_wait variable changes, the values are indeed random with a uniform distribution. However, the time stamps of the target stimulus only correspond to the time_offset without hte randomized offset. Any idea what could cause this?

I have tried to build a test experiment with two stimuli appearing with a random interval between them and the time stamps for the stimulus display are correct in this case. I have implemented a similar deisgn to the original experiment with the timer and the randomization.
Thanks in advance
Beshoy Agayby

Hi Beshoy,

time_offset + disc_rand(250,1500)

This expression adds between 250 and 1500 microseconds to time_offset. Stimulus display updates can happen only during display refreshes, which, for a 60Hz display, occur every 16.67ms. So it makes sense that waiting <=1.5ms extra wouldn’t change when the stimulus appears on screen.

Was your intention to add 250-1500 milliseconds to time_offset? If so, you can do it like this:

time_offset + disc_rand(250ms,1500ms)

Cheers,
Chris

Hello Chris,
Thanks for the quick response. The units in the timer are set to ms and that should work. In any case, I attached the xml file. The CentreSurround paradigm is the one in question. Within this paradigm, the task system state " Stim on" is the one where the random timer is set.
Cheers,
Beshoy

Hi Beshoy,

Thank you for the clarification and for sending your experiment XML.

In the experiment, a stimulus appears after a randomized interval once the monkey fixates on the fixation point. The way it’s implemented is that a variable, let’s call it stim_wait, is set to this random value ( time_offset + disc_rand(250,1500) ) . Then a timer is used with this variable as the time. If the timer expires with the animal fixating, the target stimulus appears.

I’m confused, because the experiment you sent me doesn’t appear to work this way. Looking at lines 487-495, it looks like you display the stimuli, set the random interval, wait for the random interval to expire, then move on to the next state. Am I misunderstanding your description?

When we looked at the time stamps of the stim_wait variable changes, the values are indeed random with a uniform distribution. However, the time stamps of the target stimulus only correspond to the time_offset without hte randomized offset.

I take it that “stim_wait” is actually time_changeon. Where exactly are you getting the “time stamps of the target stimulus”? Are you looking at #stimDisplayUpdate or #announceStimulus events?

Chris

Hello Chris,
Sorry for using different variable names. You are correct though; time_changeon is the variable with the random value.

Indeed, in the state with the lines you mentioned, two disks are presented, the timer is used to make sure that the animal fixates until the target stimulus appears. Once the timer expires (animal didn’t break fixation), a luminance change is presented in one of the disks. This later presentation of the luminance change is in the next state after timer expiry.
I am using the time stamps from #stimDisplayUpdate. The time stamps from time_changeon, indeed, correspond to the random value used in ms.
Cheers,
Beshoy

Hi Beshoy,

The time stamps from time_changeon, indeed, correspond to the random value used in ms.

By “time stamps from time_changeon”, do you mean the value assigned to time_changeon (i.e. time_stimon plus a random value), or do you mean the time at which the assignment was made?

My current understanding of the problem is as follows:

  1. time_changeon is correctly assigned a value in the range [time_stimon+250, time_stimon+1500].

  2. When you subtract the time at which time_changeon is set (in state “Stim on”) from the time of the #stimDisplayUpdate event announcing the drawing of the “luminance change” stimulus (in state “Luminance change”), the difference is always approximately time_stimon milliseconds, as if the disc_rand(250,1500) term were missing from the assignment to time_changeon.

Is that correct?

Sorry for all the questions. This is indeed a weird issue, and I want to be sure I understand it completely.

Thanks,
Chris

Hello Chris,
Sorry for not getting back to you sooner. Indeed, you described the problem perfectly. Just in case, i will describe how the #stimDisplayUpdateEvents is used; I look for the event that has 6 data entries (background, fixation point, two targets, luminance change and fixation dot for the luminance change) and compare its time stamp with the previous one that has only 4 entries (before the luminance change and its fixation dot).

Cheers,
Beshoy

Hi Beshoy,

Thanks for the additional details.

I look for the event that has 6 data entries (background, fixation point, two targets, luminance change and fixation dot for the luminance change) and compare its time stamp with the previous one that has only 4 entries (before the luminance change and its fixation dot).

I’ve tried to reproduce this analysis using your experiment. Attached is a histogram of the time stamp differences between each pair of 4-entry and 6-entry #stimDisplayUpdate events for 103 trials, along with the Python script that generated it. I’ve subtracted the constant value of time_stimon and converted the differences to milliseconds. As you can see, the deltas are uniformly distributed between 250ms and 1500ms, exactly as you’d expect.

Can you run my script on one of your data files and share the histogram it produces?

Thanks,
Chris

Attachments:

Hello Chris,
I get this error:
Traceback (most recent call last):
File “plot_deltas.py”, line 8, in
from mworks.data import MWKFile
File “/Library/Application Support/MWorks/Scripting/Python/mworks/data.py”, line 4, in
from _mworks import ReservedEventCode, _MWKFile, _MWKStream
ModuleNotFoundError: No module named ‘_mworks’

Any idea what I need to do? I am sorry but I am not the most experienced in using python. Before, I have looked at the data using matlab.

Cheers,
Beshoy

It looks like you tried to use Python 3. You need to use Python 2. The system version of Python is fine:

/usr/bin/python plot_deltas.py events.mwk

Chris

Hello Chris,
I modified the experiment by removing the eye tracking and set the flag_trigger to 1 (basically always correct trials). I have found that the same experiment works fine (with correct time stamps) when used with Mworks version 0.7 (tested on a macbook and an iMac) while the problem that i described before occurs with the computer using version 0.6. Could the older version be causing this error? If so, any fixes without updating mworks?
The reason we are using the older version is that there were some issues with the bkohg_iodevice when using the latest Mworks.
I attached the modified xml used for testing and the resulting histograms generated by your code.

Attachments:

Hi Beshoy,

I have found that the same experiment works fine (with correct time stamps) when used with Mworks version 0.7 (tested on a macbook and an iMac) while the problem that i described before occurs with the computer using version 0.6.

Thanks, this was the clue I needed. I finally understand what’s going on.

Your experiment defines a number of variables with scope="local", including time_changeon. Prior to MWorks 0.7, assignments to local variables didn’t work. Therefore, regardless of what values you attempted to assign to time_changeon, it always retained its initial value (1000). Because time_stimon has the same initial value as time_changeon, it looked like the disc_rand(250,1500) term was somehow discarded. However, in reality the entire expression you assigned to time_changeon was discarded. In MWorks 0.7, assignment to local variables was fixed, which explains why your experiment works as expected under it.

The fix is to change scope="local" to scope="global". Generally, the only place you should use a variable with local scope is in a range replicator or list replicator. Looking at your experiment, the only variables used by replicators are LOCAL_califix_cross_x, LOCAL_califix_cross_y, and trial_index. Everything else should have global scope. Once that’s done, your experiment should work fine under 0.6 or 0.7.

Chris

Hello Chris,

Thanks a ton, the fix worked perfectly. I might need to update Mworks at some point, but at least it works for now.
Thanks again :slight_smile:

Cheers,
Beshoy