Docs: the Barcoder
The Barcoder solves two commonly overlooked problems with recording devices: clock offsets and drift. Before we discuss how to fix these problems, let's define what we mean by clock offsets and drift.
Offsets
Say you are recording from two data acquisition devices: one for recording electrical activity from the brain, and another for keeping track of the experimental contingencies, perhaps tracking the frames of a movie on a monitor in front of the experimental subject.
Here's an ugly truth about the world. When two devices imply they start recording at the same time, you can't believe them. In a recent experiment, I was recording from two devices that claimed to start recording at 30,000 Hz at the same time. I measured the offset between a shared pulse from these devices at the beginning of the recording. Already, we had an offset of 152 samples, or 5 ms.
Drift
Let's imagine that both data acquisition devices are specified to sample at 30,000 Hz, with 0.1 Hz of imprecision. That imprecision may come from changes in temperature or manufacturing variation. Regardless, we must recognize that sampling rates for data acquisition devices have some unknown imprecision, and that their deviation from the specified sampling rate may not be fixed.
And many data acquisition systems have clocks that deviate from nominal by much more than 0.1 Hz.
Conservatively, let us assume that these two devices sample at rates that are off by 0.1 Hz. That means that if one device has recorded N samples at 20 minutes, the other device has recorded N + 120 samples at the same time. If you assume that the Nth sample from device 1 occurred at the same time as the Nth sample from device 2, you'd be off by 4 ms. After 3 hours of recording, this imprecision has grown to 36 ms.
Sure, 4 or 36 ms may be a short time for a human. However, it's not a small for a neuron, or for the speed of synaptic transmission.
Like I said, these are conservative numbers. The reality can be substantially worse. In a recent recording, the offset between two devices at the beginning of an experiment was 152 samples, or 5 milliseconds, as mentioned above. The recording was a little more than 9 minutes. At the end of the recording, the offset between shared events was half a second, or 540 ms to be precise. That's about 100 times worse drift than what we would expect with a sampling rate differential of only 0.1 Hz, so the differential is probably closer to 10 Hz!
Yikes!
Yikes indeed. Imagine how many papers you've read with this level of drift. Let's hope neuroscience as a field can course-correct. We have thrown our hat into the ring with the Barcoder. Here's how you can use it, and what we can expect in the world where neuroscience is millisecond-precise, the way it was meant to be.
The Barcoder works by generating “bar codes” of TTL (5 V) pulses that can be shared between any number of devices, creating a reliable means to relate the clock of one device to the clock of another.
In practical terms
Let's say you have an IMEC Neuropixels system that records extracellular spikes and a National Instruments DAQ that records additional event streams such as the timing of visual stimuli. To interpret a spike as a response to a stimulus, we need to know the relative timing between the two. However, they are recorded in different “time zones”: the spike in IMEC time, and the stimulus in NI time. We need to convert the NI timestamp of the stimulus to the corresponding IMEC timestamp to make it comparable to the IMEC timestamp of the spike.
How do you do that if the stated start times of the devices are not accurate and neither are their clock rates? If both devices have captured the Barcoder’s output, you can extract the sample numbers at which each device captured each bar code. You can then use these numbers to map an arbitrary intermediate sample number from one device to the corresponding sample number on the other device. Our “ephysio” Python library can do this for you. This works when the two devices have nominally identical sampling rates and also when they have very different rates.
Making it work
Here we describe a solution that applies to recording Neuropixels data with the OpenEphys GUI while using a National Instruments board to acquire auxiliary data. Other situations are similar.
Begin by connecting the output of the Barcoder to a digital input of the NIDAQ board and to the “Aux” input on the Neuropixels card.
Next, install our free and open source “ephysio” Python library:
pip install ephysio
Then, use ephysio to access your data set:
from ephysio import openephysio
expt = openephysio.Loader("/path/to/your/data")
spike_stream = expt.spikestream()
events = expt.nidaqevents(spike_stream)
Now events is a dictionary of all the event times captured by the NIDAQ card, in the time zone of your spikes.