Skip to content

Commit

Permalink
Merge pull request #1496 from khl02007/sgrawio_chan_fix
Browse files Browse the repository at this point in the history
Minimal fix of `SpikeGadgetsRawIO` channel ID issue
  • Loading branch information
zm711 authored Jul 24, 2024
2 parents cda3281 + 69b5403 commit 44f0b2b
Showing 1 changed file with 40 additions and 6 deletions.
46 changes: 40 additions & 6 deletions neo/rawio/spikegadgetsrawio.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,18 @@
Author: Samuel Garcia
"""

import numpy as np

from xml.etree import ElementTree

from .baserawio import (
BaseRawIO,
_signal_channel_dtype,
_signal_stream_dtype,
_spike_channel_dtype,
_event_channel_dtype,
)

import numpy as np

from xml.etree import ElementTree
from neo.core import NeoReadWriteError


class SpikeGadgetsRawIO(BaseRawIO):
Expand Down Expand Up @@ -79,6 +80,24 @@ def __init__(self, filename="", selected_streams=None):
def _source_name(self):
return self.filename

def _produce_ephys_channel_ids(self, n_total_channels, n_channels_per_chip):
"""Compute the channel ID labels
The ephys channels in the .rec file are stored in the following order:
hwChan ID of channel 0 of first chip, hwChan ID of channel 0 of second chip, ..., hwChan ID of channel 0 of Nth chip,
hwChan ID of channel 1 of first chip, hwChan ID of channel 1 of second chip, ..., hwChan ID of channel 1 of Nth chip,
...
So if there are 32 channels per chip and 128 channels (4 chips), then the channel IDs are:
0, 32, 64, 96, 1, 33, 65, 97, ..., 128
See also: https://github.com/NeuralEnsemble/python-neo/issues/1215
"""
ephys_channel_ids_list = []
for hw_channel in range(n_channels_per_chip):
hw_channel_list = [
hw_channel + chip * n_channels_per_chip for chip in range(int(n_total_channels / n_channels_per_chip))
]
ephys_channel_ids_list.append(hw_channel_list)
return [channel for channel_list in ephys_channel_ids_list for channel in channel_list]

def _parse_header(self):
# parse file until "</Configuration>"
header_size = None
Expand All @@ -104,6 +123,20 @@ def _parse_header(self):
self._sampling_rate = float(hconf.attrib["samplingRate"])
num_ephy_channels = int(hconf.attrib["numChannels"])

# check for agreement with number of channels in xml
sconf_channels = np.sum([len(x) for x in sconf])
if sconf_channels < num_ephy_channels:
num_ephy_channels = sconf_channels
if sconf_channels > num_ephy_channels:
raise NeoReadWriteError(
"SpikeGadgets: the number of channels in the spike configuration is larger than the number of channels in the hardware configuration"
)

try:
num_chan_per_chip = int(sconf.attrib["chanPerChip"])
except KeyError:
num_chan_per_chip = 32 # default value for Intan chips

# explore sub stream and count packet size
# first bytes is 0x55
packet_size = 1
Expand Down Expand Up @@ -174,6 +207,7 @@ def _parse_header(self):
signal_streams.append((stream_name, stream_id))
self._mask_channels_bytes[stream_id] = []

channel_ids = self._produce_ephys_channel_ids(num_ephy_channels, num_chan_per_chip)
chan_ind = 0
self.is_scaleable = "spikeScalingToUv" in sconf[0].attrib
if not self.is_scaleable:
Expand All @@ -190,8 +224,8 @@ def _parse_header(self):
units = ""

for schan in trode:
name = "trode" + trode.attrib["id"] + "chan" + schan.attrib["hwChan"]
chan_id = schan.attrib["hwChan"]
chan_id = str(channel_ids[chan_ind])
name = "hwChan" + chan_id

offset = 0.0
signal_channels.append(
Expand Down

0 comments on commit 44f0b2b

Please sign in to comment.