Skip to content

[WIP] Extract sync event timestamps from SpikeGLX streams #1657

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

guptadivyansh
Copy link
Contributor

Slowly working towards SpikeInterface/spikeinterface#2234

Trying to reuse the nidq digital channel event processing for handling sync edges. Will then align edges and change sampling rate/time vector as necessary

Also, I'm not sure if any of the current test files have simultaneously recorded sync signals in both imec and nidq streams.

@manimoh
Copy link
Contributor

manimoh commented Mar 17, 2025

Hi @guptadivyansh
Thank you so much for working on this issue!
This is a real-world (although really big) dataset that has simultaneously recorded sync signals from 2 imec device and 1 nidq device. If you think it is too cumbersome to handle, I can try clipping it and trying to submit a pull-request for much more sensibly sized dataset on here

@guptadivyansh
Copy link
Contributor Author

guptadivyansh commented Mar 17, 2025 via email

@zm711
Copy link
Contributor

zm711 commented Mar 18, 2025

Thanks so much for working on this. Please ping Alessio and Sam to review when you're ready!

@guptadivyansh guptadivyansh changed the title WIP, imec sync channel processing [WIP] Extract sync event timestamps from SpikeGLX streams Mar 19, 2025
@guptadivyansh guptadivyansh marked this pull request as ready for review March 19, 2025 10:16
@guptadivyansh
Copy link
Contributor Author

I think this should expose all that we need from neo to solve SpikeInterface/spikeinterface#2234 that is, the timestamps of sync edges of the correct channels in any given streams. Actually aligning the edges across streams can/should(?) be done in spikeinterface, likely here.

I also noticed that the nidq digital channel processing introduced in #1383 is hardcoded for the first segment. I can fix it in a separate PR. Once that is done, we should be able to get sync events from all segments too.

@@ -292,33 +293,113 @@ def _event_count(self, event_channel_idx, block_index=None, seg_index=None):
return timestamps.size

def _get_event_timestamps(self, block_index, seg_index, event_channel_index, t_start=None, t_stop=None):
#TODO: fix seg_index usage, currently hardcoded for first segment
timestamps, durations, labels = [], None, []
info = self.signals_info_dict[0, "nidq"] # There are no events that are not in the nidq stream
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

currently the event detector for nidq digital channels ignores the seg_index. This needs fixing for detecting sync events across segments.

Should still work for multi-segment imec streams though

sync_line = self.get_analogsignal_chunk(channel_names = [f'XA{niChan}'],
stream_index = stream_index,
seg_index = seg_index)
#Does this need to be scaled by channel gain before threshold?
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Help!

@@ -204,6 +204,7 @@ def _parse_header(self):
# This is true only in case of 'nidq' stream
for stream_name in stream_names:
if "nidq" in stream_name:
#TODO: loop over all segments to add nidq events to _events_memmap
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the np.unpackbits below would load the nidq digital data into memory?

@guptadivyansh
Copy link
Contributor Author

@alejoe91 , @samuelgarcia , would be grateful if you could have a look!

@guptadivyansh
Copy link
Contributor Author

There's a messy testing notebook here that uses some of my data but I still need to look into which (if any) of the current testing datasets have simultaneously recorded sync lines for more than a couple of seconds.

Ideally, we want a good mix of multiple probes, and sync signal in nidq digital and analog channels. Most of the neural channels in the test imec streams can be dropped to keep a managable filesize. (otherwise we'll need a ~23 MB test file per second per probe)

timestamps, durations, labels = [], None, []
info = self.signals_info_dict[0, "nidq"] # There are no events that are not in the nidq stream
dig_ch = info["digital_channels"]
if len(dig_ch) > 0:
event_data = self._events_memmap
channel = dig_ch[event_channel_index]
channel = dig_ch[event_channel_index] # 'XD0', 'XD1', etc.
ch_idx = 7 - int(channel[2:]) # They are in the reverse order
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This calculation of channel index is also something that I had hard-coded and will work only when there are exactly 8 digital channels saved (which was the cases for our setup, but isn't generally true); but not when you save fewer channels or have I/O devices that have more than 8 digital channels.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for pointing this out, this is something to fix.

@h-mayorquin
Copy link
Contributor

I can take a look at this but first we should determine if there is available data on the testing set that contains the cases that you want to cover in your scope:

https://gin.g-node.org/NeuralEnsemble/ephy_testing_data/src/master/spikeglx

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants