|
73 | 73 | _signal_channel_dtype, |
74 | 74 | _signal_stream_dtype, |
75 | 75 | _signal_buffer_dtype, |
76 | | - _spike_channel_dtype, |
77 | 76 | _event_channel_dtype, |
78 | 77 | ) |
79 | 78 |
|
@@ -133,6 +132,19 @@ class BlackrockRawIO(BaseRawIO): |
133 | 132 | # We need to document the origin of this value |
134 | 133 | main_sampling_rate = 30000.0 |
135 | 134 |
|
| 135 | + # Override spike channel dtype to include unit_class field specific to Blackrock |
| 136 | + _spike_channel_dtype = [ |
| 137 | + ("name", "U64"), |
| 138 | + ("id", "U64"), |
| 139 | + # for waveform |
| 140 | + ("wf_units", "U64"), |
| 141 | + ("wf_gain", "float64"), |
| 142 | + ("wf_offset", "float64"), |
| 143 | + ("wf_left_sweep", "int64"), |
| 144 | + ("wf_sampling_rate", "float64"), |
| 145 | + ("unit_class", "U64"), |
| 146 | + ] |
| 147 | + |
136 | 148 | def __init__( |
137 | 149 | self, filename=None, nsx_override=None, nev_override=None, nsx_to_load=None, load_nev=True, verbose=False |
138 | 150 | ): |
@@ -300,7 +312,21 @@ def _parse_header(self): |
300 | 312 | # default value: threshold crossing after 10 samples of waveform |
301 | 313 | wf_left_sweep = 10 |
302 | 314 | wf_sampling_rate = self.main_sampling_rate |
303 | | - spike_channels.append((name, _id, wf_units, wf_gain, wf_offset, wf_left_sweep, wf_sampling_rate)) |
| 315 | + |
| 316 | + # Map unit_class_nb to unit classification string |
| 317 | + if unit_id == 0: |
| 318 | + unit_class = "unclassified" |
| 319 | + warnings.warn(f"Unit {unit_id} for channel {channel_id} is unclassified events!") |
| 320 | + elif 1 <= unit_id <= 16: |
| 321 | + unit_class = "sorted" |
| 322 | + elif unit_id == 255: |
| 323 | + unit_class = "noise" |
| 324 | + warnings.warn(f"Unit {unit_id} for channel {channel_id} is noisy events!") |
| 325 | + else: # 17-254 are reserved but treated as "non-spike-events" |
| 326 | + unit_class = "non-spike-events" |
| 327 | + warnings.warn(f"Unit {unit_id} for channel {channel_id} is non-spike events!") |
| 328 | + |
| 329 | + spike_channels.append((name, _id, wf_units, wf_gain, wf_offset, wf_left_sweep, wf_sampling_rate, unit_class)) |
304 | 330 |
|
305 | 331 | # scan events |
306 | 332 | # NonNeural: serial and digital input |
@@ -520,7 +546,7 @@ def _parse_header(self): |
520 | 546 | self._sigs_t_starts = [None] * self._nb_segment |
521 | 547 |
|
522 | 548 | # finalize header |
523 | | - spike_channels = np.array(spike_channels, dtype=_spike_channel_dtype) |
| 549 | + spike_channels = np.array(spike_channels, dtype=self._spike_channel_dtype) |
524 | 550 | event_channels = np.array(event_channels, dtype=_event_channel_dtype) |
525 | 551 | signal_channels = np.array(signal_channels, dtype=_signal_channel_dtype) |
526 | 552 | signal_streams = np.array(signal_streams, dtype=_signal_stream_dtype) |
|
0 commit comments