Skip to content

Commit 7c899cc

Browse files
authored
Merge pull request #1753 from alejoe91/fix-onebox-adc
OpenEphysBinary: do not split ADC streams for OneBox
2 parents 5e3ccd9 + e8b130f commit 7c899cc

File tree

2 files changed

+46
-23
lines changed

2 files changed

+46
-23
lines changed

neo/rawio/openephysbinaryrawio.py

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -159,11 +159,14 @@ def _parse_header(self):
159159
# We then set the stream_id to the sync stream id
160160
channel_stream_id = sync_stream_id
161161

162-
if "ADC" in chan_id:
163-
# These are non-neural channels and their stream should be separated
164-
# We defined their stream_id as the stream_index of neural data plus the number of neural streams
165-
# This is to not break backwards compatbility with the stream_id numbering
166-
channel_stream_id = str(stream_index + len(sig_stream_names))
162+
if "OneBox" not in stream_name:
163+
# If recording system is not OneBox, which has already a separate stream for ADC channels,
164+
# we need to separate ADC channels from neural channels.
165+
if "ADC" in chan_id:
166+
# These are non-neural channels and their stream should be separated
167+
# We defined their stream_id as the stream_index of neural data plus the number of neural streams
168+
# This is to not break backwards compatbility with the stream_id numbering
169+
channel_stream_id = str(stream_index + len(sig_stream_names))
167170

168171
gain = float(chan_info["bit_volts"])
169172
sampling_rate = float(info["sample_rate"])
@@ -271,10 +274,22 @@ def _parse_header(self):
271274
"SYNC channel must be the last channel in the buffer. Open an issue in python-neo to request this feature."
272275
)
273276

274-
neural_channels = [ch for ch in info["channels"] if "ADC" not in ch["channel_name"]]
275-
adc_channels = [ch for ch in info["channels"] if "ADC" in ch["channel_name"]]
276-
num_neural_channels = len(neural_channels)
277-
num_adc_channels = len(adc_channels)
277+
if "OneBox" not in info["stream_name"]:
278+
# If recording system is not OneBox, which has already a separate stream for ADC channels,
279+
# we need to separate ADC channels from neural channels.
280+
# We do this by defining different stream_ids for ADC and non-ADC channels
281+
# (see above when creating signal_channels and signal_streams)
282+
283+
# Split neural and ADC channels
284+
# SYNC channel is handled separately below
285+
neural_channels = [ch for ch in info["channels"] if "ADC" not in ch["channel_name"]]
286+
adc_channels = [ch for ch in info["channels"] if "ADC" in ch["channel_name"]]
287+
num_neural_channels = len(neural_channels)
288+
num_adc_channels = len(adc_channels) if "OneBox" not in info["stream_name"] else 0
289+
else:
290+
# OneBox already has a separate stream for ADC channels, so no need to split them here
291+
num_neural_channels = num_channels - 1 if has_sync_trace else num_channels
292+
num_adc_channels = 0
278293

279294
if num_adc_channels == 0:
280295
if has_sync_trace and not self.load_sync_channel:
@@ -498,12 +513,17 @@ def _parse_header(self):
498513
if has_sync_trace:
499514
values = values[:-1]
500515

501-
neural_channels = [ch for ch in info["channels"] if "ADC" not in ch["channel_name"]]
502-
num_neural_channels = len(neural_channels)
503-
if is_neural_stream:
504-
values = values[:num_neural_channels]
505-
else:
506-
values = values[num_neural_channels:]
516+
if "SYNC" in stream_name and not self.load_sync_channel:
517+
# This is the sync stream, we only keep the last value
518+
values = values[-1:]
519+
520+
if "OneBox" not in info["stream_name"]:
521+
neural_channels = [ch for ch in info["channels"] if "ADC" not in ch["channel_name"]]
522+
num_neural_channels = len(neural_channels)
523+
if is_neural_stream:
524+
values = values[:num_neural_channels]
525+
else:
526+
values = values[num_neural_channels:]
507527

508528
sig_ann["__array_annotations__"][key] = values
509529

neo/test/rawiotest/test_openephysbinaryrawio.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,16 @@ class TestOpenEphysBinaryRawIO(BaseTestRawIO, unittest.TestCase):
1616
"openephysbinary/v0.6.x_neuropixels_multiexp_multistream",
1717
"openephysbinary/v0.6.x_neuropixels_with_sync",
1818
"openephysbinary/v0.6.x_neuropixels_missing_folders",
19+
"openephysbinary/v0.6.x_onebox_neuropixels",
1920
"openephysbinary/neural_and_non_neural_data_mixed",
2021
]
2122

2223
def test_sync(self):
23-
rawio_with_sync = OpenEphysBinaryRawIO(
24-
self.get_local_path("openephysbinary/v0.6.x_neuropixels_with_sync"), load_sync_channel=True
25-
)
26-
rawio_with_sync.parse_header()
24+
with self.assertWarns(DeprecationWarning):
25+
rawio_with_sync = OpenEphysBinaryRawIO(
26+
self.get_local_path("openephysbinary/v0.6.x_neuropixels_with_sync"), load_sync_channel=True
27+
)
28+
rawio_with_sync.parse_header()
2729
stream_name = [s_name for s_name in rawio_with_sync.header["signal_streams"]["name"] if "AP" in s_name][0]
2830
stream_index = list(rawio_with_sync.header["signal_streams"]["name"]).index(stream_name)
2931

@@ -69,10 +71,11 @@ def test_sync_channel_access(self):
6971
def test_no_sync(self):
7072
# requesting sync channel when there is none raises an error
7173
with self.assertRaises(ValueError):
72-
rawio_no_sync = OpenEphysBinaryRawIO(
73-
self.get_local_path("openephysbinary/v0.6.x_neuropixels_multiexp_multistream"), load_sync_channel=True
74-
)
75-
rawio_no_sync.parse_header()
74+
with self.assertWarns(DeprecationWarning):
75+
rawio_no_sync = OpenEphysBinaryRawIO(
76+
self.get_local_path("openephysbinary/v0.6.x_neuropixels_multiexp_multistream"), load_sync_channel=True
77+
)
78+
rawio_no_sync.parse_header()
7679

7780
def test_missing_folders(self):
7881
# missing folders should raise an error

0 commit comments

Comments
 (0)