spikeinterface
spikeinterface copied to clipboard
No way to access spikeGLX Digital Channels on the 'nidq' stream
Hi,
While read_spikeglx(spikeglx_folder, 'nidq') allows you to access the analog I/O channels, the signal on the digital i/O channels (TTL pulses) are missing - these often contain events related to experimental control and would be important to capture from a downstream analysis point of view.
Hi @manimoh
Is there any code to read them in Python? We should need to implement read_spikeglx_events! (We have one for Open Ephys)
Unfortunately all I could find is that the 'XD' (digital) is not really parsed in neo's spikeglxrawio, so I don't know where else to look at :/
There is no clear API on neo side to read digtal stream. This is on my todo list since very long time.
Okay I did some digging and here's what I found: The digital channels (if present and saved) are encoded as an 8 bit word, where the digital channel 0 refers to the least significant bit. And each sample essentially stores the state of the the 8 digital channels in this word.
I essentially confirmed this by inserting the following code after this line in the neo's spikeglxrawio.py
extracted_word = data[:,8] # Extract the 9th value 8 analog channels, and 1 'digital' word`
all_states = ['{0:08b}'.format(x) for x in extracted_word]
channel0_bits = [int(x[-1]) for x in all_states]
positive_edges0 = [i for i,x in enumerate(np.diff(channel0_bits)) if x == 1]
channel2_bits = [int(x[-3]) for x in all_states]
positive_edges2 = [i for i,x in enumerate(np.diff(channel2_bits)) if x == 1]
negative_edges2 = [i for i,x in enumerate(np.diff(channel2_bits)) if x == -1]
And then seeing if the transitions in the bits based on all_samples made sense.
I am attaching 2 test cases that can help you - 1 of them has only sync pulses on digital channel 0, and the other one has TTL pulses (high for ~1 sec) on channels 2 and 3, in addition to the sync pulses on digital channel 0. Sync0.zip Sync0TTL2and3.zip
P.S: The second zip file contains a .7z compression inside because i was not able to decrease the filesize to less than 25 MB, I apologize in advance for the inconvenience!
Hi! Is there a PR regarding this issue? I am unsure about whether this needs to be implemented on the NEO side and then accordingly in spikeinterface, or everything on the spikeinterface?
@samuelgarcia how could we may be help to get a fix for this going? may be point to few ideas on where to introduce what and then @TheChymera with @manimoh could take a stab at implementing it?
Hi @yarikoptic, @manimoh and @TheChymera
Yes this will need to be implemented in NEO, specifically in the SpikeGLXRawIO
Can you open an issue there?
Once that is implemented, on the SpikeItnerface side we just need a very thin layer on top of NEO events, similar to this OpenEphys implementation.
PRs merged so I'm closing this :)