Skip to content

Commit 90589d4

Browse files
h-mayorquinzm711
andauthored
IntanRawIO: Improve intan logic for "one-file-per-channel" in the rhs format (#1676)
* add stim demultiplex rhs intan * fix tests * docstring and demultiplex to decode name change * Update neo/rawio/intanrawio.py Co-authored-by: Zach McKenzie <[email protected]> * Update neo/rawio/intanrawio.py Co-authored-by: Zach McKenzie <[email protected]> * Update neo/rawio/intanrawio.py Co-authored-by: Zach McKenzie <[email protected]> * fix * refactor and comments * add test * add comments to test * add gin comment * update header parsing for stim + update docstring * add stim to channel check * wip * oops * fix for header attached * fix for one-file-per-signal * add one new test file * clean up logic * add more info to comments --------- Co-authored-by: Zach McKenzie <[email protected]>
1 parent 02da7aa commit 90589d4

File tree

1 file changed

+40
-32
lines changed

1 file changed

+40
-32
lines changed

neo/rawio/intanrawio.py

Lines changed: 40 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -899,19 +899,19 @@ def read_rhs(filename, file_format: str):
899899
names_to_count = [name for name in stream_names if name not in special_cases_for_counting]
900900
channel_number_dict = {name: len(stream_name_to_channel_info_list[name]) for name in names_to_count}
901901

902-
# Both DC Amplifier and Stim streams have the same number of channels as the amplifier stream
903-
# if using the `header-attached` or `one-file-per-signal` formats
904-
# the amplifier data is stored in the same place in the header so no matter what the DC amp
905-
# uses the same info as the RHS amp.
902+
# Each DC amplifier channel has a corresponding RHS2000 amplifier channel
906903
channel_number_dict["DC Amplifier channel"] = channel_number_dict["RHS2000 amplifier channel"]
907-
if file_format != "one-file-per-channel":
908-
channel_number_dict["Stim channel"] = channel_number_dict["RHS2000 amplifier channel"]
909-
raw_file_paths_dict = create_one_file_per_signal_dict_rhs(dirname=filename.parent)
910-
else:
904+
905+
if file_format == "one-file-per-channel":
906+
# There is a way to shut off saving amplifier data and only keeping the DC amplifier or shutting off all amplifier file saving,
907+
# so we need to count the number of files we find instead of relying on the header.
911908
raw_file_paths_dict = create_one_file_per_channel_dict_rhs(dirname=filename.parent)
912909
channel_number_dict["Stim channel"] = len(raw_file_paths_dict["Stim channel"])
913-
# but the user can shut off the normal amplifier and only save dc amplifier
910+
# Moreover, even if the amplifier channels are in the header their files are dropped
914911
channel_number_dict["RHS2000 amplifier channel"] = len(raw_file_paths_dict["RHS2000 amplifier channel"])
912+
else:
913+
channel_number_dict["Stim channel"] = channel_number_dict["RHS2000 amplifier channel"]
914+
915915

916916
header_size = f.tell()
917917

@@ -925,7 +925,7 @@ def read_rhs(filename, file_format: str):
925925
memmap_data_dtype["timestamp"] = "int32"
926926
channel_number_dict["timestamp"] = 1
927927

928-
if file_format != "one-file-per-channel" or channel_number_dict["RHS2000 amplifier channel"] > 0:
928+
if channel_number_dict["RHS2000 amplifier channel"] > 0:
929929
for chan_info in stream_name_to_channel_info_list["RHS2000 amplifier channel"]:
930930
chan_info["sampling_rate"] = sr
931931
chan_info["units"] = "uV"
@@ -967,29 +967,37 @@ def read_rhs(filename, file_format: str):
967967
# I can't seem to get stim files to generate for one-file-per-channel
968968
# so ideally at some point we need test data to confirm this is true
969969
# based on what Heberto and I read in the docs
970+
971+
# Add stim channels
970972
for chan_info in stream_name_to_channel_info_list["RHS2000 amplifier channel"]:
971-
# we see which stim were activated
972-
if file_format != "one-file-per-channel" or any(
973-
[chan_info["native_channel_name"] in stim_file.stem for stim_file in raw_file_paths_dict["Stim channel"]]
974-
):
975-
chan_info_stim = dict(chan_info)
976-
name = chan_info["native_channel_name"]
977-
chan_info_stim["native_channel_name"] = name + "_STIM"
978-
chan_info_stim["sampling_rate"] = sr
979-
# stim channel are complicated because they are coded
980-
# with bits, they do not fit the gain/offset rawio strategy
981-
chan_info_stim["units"] = "A" # Amps
982-
chan_info_stim["gain"] = global_info["stim_step_size"]
983-
chan_info_stim["offset"] = 0.0
984-
chan_info_stim["signal_type"] = 11 # put it in another group
985-
chan_info_stim["dtype"] = "int16" # this change is due to bit decoding see note below
986-
ordered_channel_info.append(chan_info_stim)
987-
# Note that the data on disk is uint16 but the data is
988-
# then decoded as int16 so the chan_info is int16
989-
if file_format == "header-attached":
990-
memmap_data_dtype += [(name + "_STIM", "uint16", BLOCK_SIZE)]
991-
else:
992-
memmap_data_dtype["Stim channel"] = "uint16"
973+
# stim channel presence is not indicated in the header so for some formats each amplifier channel has a stim channel, but for other formats this isn't the case.
974+
975+
if file_format == "one-file-per-channel":
976+
# Some amplifier channels don't have a corresponding stim channel,
977+
# so we need to make sure we don't add channel info for stim channels that don't exist.
978+
# In this case, if the stim channel has no data, there won't be a file for it.
979+
stim_file_paths = raw_file_paths_dict["Stim channel"]
980+
amplifier_native_name = chan_info["native_channel_name"]
981+
stim_file_exists = any([amplifier_native_name in stim_file.stem for stim_file in stim_file_paths])
982+
if not stim_file_exists:
983+
continue
984+
985+
chan_info_stim = dict(chan_info)
986+
name = chan_info["native_channel_name"]
987+
chan_info_stim["native_channel_name"] = name + "_STIM"
988+
chan_info_stim["sampling_rate"] = sr
989+
chan_info_stim["units"] = "A" # Amps
990+
chan_info_stim["gain"] = global_info["stim_step_size"]
991+
chan_info_stim["offset"] = 0.0
992+
chan_info_stim["signal_type"] = 11 # put it in another group
993+
chan_info_stim["dtype"] = "int16" # this change is due to bit decoding see note below
994+
ordered_channel_info.append(chan_info_stim)
995+
# Note that the data on disk is uint16 but the data is
996+
# then decoded as int16 so the chan_info is int16
997+
if file_format == "header-attached":
998+
memmap_data_dtype += [(name + "_STIM", "uint16", BLOCK_SIZE)]
999+
else:
1000+
memmap_data_dtype["Stim channel"] = "uint16"
9931001

9941002
# No supply or aux for rhs files (ie no stream_id 1 and 2)
9951003
# We have an error above that requests test files to help if the spec is changed

0 commit comments

Comments
 (0)