Time stamping

Users must be familiar with how the time stamp associated with each event in a data file is determined. In this regard, MWorks has been designed with two overall goals:

  1. Make all time stamps relative to the same clock (the MWorks Global Clock).

    This means that all times can always be compared directly to one another (with the caveat of fully understanding goal 2).

  2. Each time stamp reflects, as best as possible, the time that something actually occurred (i.e. as if there were no lags in the system).

    We refer to this time as “neuroscientist time,” because it is the time one would naturally want to put on plots. However, because of goal 2, one must be especially cautious when trying to estimate the true (real-time) lags that are inherent in MWorks.

Variables are the currency of MWorks, and every event corresponds to a variable update. Therefore, one should understand how different ways of updating variables affect the time stamp associated with the update (i.e. the time value you will find in the final data file).

Explicit variable updates

When a variable is updated explicitly (i.e. by an assignment action, or by changing its value in the client’s variables window), the time stamp will indicate the time that the variable actually gets updated.

For example, suppose you create a variable X in your experiment. At time 20000us, a request is made to set X to value 3 via an assignment action. There may be some delay (depending on the system) between when the request is made and when the value is actually set. In this case, if the delay is 1000us, then the time stamp of X in the data file will be 21000us.

I/O channel data acquisition

Input I/O channels cause the updating of variables associated with those channels. The time stamp of each update is the best estimate of the time that the value was actually recorded at the I/O device.

For example, suppose you plug a BNC carrying your horizontal eye position signal into ITC-18 channel 0, and you design your MWorks experiment so that channel 0 streams data to an MWorks variable called eye_h. Regardless of how often you service the ITC-18 to get data, each input value will be stamped with the best estimate of the time that the signal is actually recorded.

Specifically, suppose channel 0 is being recorded every 1ms (data_interval="1ms"), the recorded data are transferred to MWorks every 3ms (update_interval="3ms"), and recording starts at time 0ms. If, at 4ms, the input value suddenly changes from 0V to 5V, here is how the eye_h values will be recorded, received, and time stamped:

Value Recorded by ITC at Received by MWorks at Time stamp in data file
0V 1ms 3ms 1ms
0V 2ms 3ms 2ms
0V 3ms 3ms 3ms
5V 4ms 6ms 4ms
5V 5ms 6ms 5ms
5V 6ms 6ms 6ms

Note that while the change from 0V to 5V occurs at 4ms, and the time stamp recorded in the data file for the first 5V value is also 4ms, MWorks doesn’t process the event until 6ms. Therefore, if the value change triggers any actions in the experiment (e.g. if eye_h jumping to 5V causes a state transition), the triggering won’t happen until 6ms.


Because event time stamps are intended to indicate the actual time the event took place, changes to variables attached to the output of filters have an adjusted time stamp to compensate for the delay of the filter. This means their time stamps will (in general) disagree with the actual time when they are logged into the data stream.

For example, suppose variable eye_h_raw goes through a boxcar filter of 5 samples (sampled at 1ms) to compute variable eye_h. Starting from time 0ms, eye_h_raw is updated every 1ms, meaning the time stamps for the next 5 data points are 1ms, 2ms, 3ms, 4ms, 5ms. At time 5ms, eye_h is updated for the first time, but to compensate for its delay, the update will be logged as occurring at 2.5ms, even though the update actually takes place at 5ms.

Components that currently behave this way are:

  • Filters
  • Calibrators
  • Basic eye monitor