Confused about LFP & Spiking channel alignment


Currently, I am trying to sync up the LFP and unit spiking data from the EcephysProjectCache.
I am having trouble with the fact that for the LFP data, “NWB includes every 2nd sample
and every 4th channel” per the cheat sheet. What does this exactly mean?
For example, I tried to export all the LFP data from channels in VIS__ structures, and looked at the exported channel_ids list at the same time. I could see that the channel_ids, when ordered, increased by 2, except for one leap of 4.
I want to understand how exactly these channels work, because I want to compare them with the unit data in the same channels. My current understanding is that multiple channels of the unit data are all between one LFP contact and the next, but then I don’t understand why the channel_ids increase by 2 in the LFP data.

I guess the main question that would guide me best is, what exactly is the numbering scheme behind the channel_ids? Any suggestions on aligning unit data and spiking data by channel would help me greatly.

Thank you!

Hi Raphi, thanks for the question!

The original LFP data is sampled at 2500 Hz, and includes data for every channel on the probe (of which there are 384). To reduce the size of the NWB files (and because most analyses do not require such a high sample rate or channel density), we decimate the LFP by a factor of 2 (to 1250 Hz), and only include data for every 4th channel (e.g., 2, 6, 10, etc., for a 40 micron vertical site spacing).

In order to align spikes with LFP, you should use either each channel’s local_index or probe_vertical_position values, since the channel IDs are just arbitrary unique identifiers.

Once you’ve loaded the LFP data for one probe, (lfp = session.get_lfp(probe_id)) you can get the local index of each channel (channel index relative to the bottom of the probe, ranging from 0 to 384) using the following code:

lfp_channel_indices = session.channels.loc[].local_index.values

This will return an array of channel indices with intervals of 4, e.g.:

array([2, 6, 10, ..., 370, 374])

The local channel indices for the units can be obtained this way:

unit_channel_indices = units[units.probe_id ==  probe_id].channel_local_index.values

These can come from any of the available 384 channels.

Finally, you can extract the nearest LFP channel for each unit using np.searchsorted:

nearest_lfp_channel_index = np.searchsorted(lfp_channel_indices, unit_channel_indices)

This will return the index of the channel axis of the LFP DataArray that’s closest to each unit.

1 Like

This answer was extremely helpful. Thank you for the thorough and quick response! :smiley: