Skip to content

Commit

Permalink
Merge branch 'main' into add_annotation_to_vebose_on_sorting
Browse files Browse the repository at this point in the history
  • Loading branch information
h-mayorquin authored Jan 16, 2025
2 parents b7d97c9 + 32f6834 commit f3dd4ed
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 33 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@ Small fixes should be here.
* Temporary set a ceiling for hdmf to avoid a chunking bug [PR #1175](https://github.com/catalystneuro/neuroconv/pull/1175)

## Features
* Add description to inter-sample-shift for `SpikeGLXRecordingInterface` [PR #1177](https://github.com/catalystneuro/neuroconv/pull/1177)

## Improvements
* `get_json_schema_from_method_signature` now throws a more informative error when an untyped parameter is passed [#1157](https://github.com/catalystneuro/neuroconv/pull/1157)
* Improve the naming of ElectrodeGroups in the `SpikeGLXRecordingInterface` when multi probes are present [PR #1177](https://github.com/catalystneuro/neuroconv/pull/1177)
* Detect mismatch errors between group and group names when writing ElectrodeGroups [PR #1165](https://github.com/catalystneuro/neuroconv/pull/1165)
* Fix metadata bug in `IntanRecordingInterface` where extra devices were added incorrectly if the recording contained multiple electrode groups or names [#1166](https://github.com/catalystneuro/neuroconv/pull/1166)
* Source validation is no longer performed when initializing interfaces or converters [PR #1168](https://github.com/catalystneuro/neuroconv/pull/1168)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ def add_recording_extractor_properties(recording_extractor) -> None:
if probe.get_shank_count() > 1:
shank_ids = probe.shank_ids
recording_extractor.set_property(key="shank_ids", values=shank_ids)
group_name = [f"{probe_name}{shank_id}" for shank_id in shank_ids]
group_name = [f"Neuropixels{probe_name}Shank{shank_id}" for shank_id in shank_ids]
else:
group_name = [f"{probe_name}"] * len(channel_ids)
group_name = [f"Neuropixels{probe_name}"] * len(channel_ids)

recording_extractor.set_property(key="group_name", ids=channel_ids, values=group_name)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,6 @@ class SpikeGLXRecordingInterface(BaseRecordingExtractorInterface):
associated_suffixes = (".imec{probe_index}", ".ap", ".lf", ".meta", ".bin")
info = "Interface for SpikeGLX recording data."

# TODO: Add probe_index to probeinterface and propagate it from there
# Note to developer.
# In a conversion with Jennifer Colonell she refers to the number after imec as the probe index
# Quoting here:
# imec0 is the probe in the lowest slot and port number, imec1 in the next highest, and so on.
# If you have probes in {slot 2, port 3}, {slot 3, port1} and {slot3, port2},
# the probe indices in the SGLX output will be 0, 1, and 2, respectively.

ExtractorName = "SpikeGLXRecordingExtractor"

@classmethod
Expand Down Expand Up @@ -135,7 +127,7 @@ def get_metadata(self) -> dict:

# Should follow pattern 'Imec0', 'Imec1', etc.
probe_name = self._signals_info_dict["device"].capitalize()
device["name"] = f"Neuropixel{probe_name}"
device["name"] = f"Neuropixels{probe_name}"

# Add groups metadata
metadata["Ecephys"]["Device"] = [device]
Expand All @@ -155,6 +147,13 @@ def get_metadata(self) -> dict:
dict(name="group_name", description="Name of the ElectrodeGroup this electrode is a part of."),
dict(name="contact_shapes", description="The shape of the electrode"),
dict(name="contact_ids", description="The id of the contact on the electrode"),
dict(
name="inter_sample_shift",
description=(
"Array of relative phase shifts for each channel, with values ranging from 0 to 1, "
"representing the fractional delay within the sampling period due to sequential ADC."
),
),
]

if self.recording_extractor.get_probe().get_shank_count() > 1:
Expand Down
20 changes: 12 additions & 8 deletions tests/test_on_data/ecephys/spikeglx_multi_probe_metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,28 @@
"Ecephys": {
"Device": [
{
"name": "NeuropixelImec0",
"name": "NeuropixelsImec0",
"description": "{\"probe_type\": \"0\", \"probe_type_description\": \"NP1.0\", \"flex_part_number\": \"NP2_FLEX_0\", \"connected_base_station_part_number\": \"NP2_QBSC_00\"}",
"manufacturer": "Imec"
},
{
"name": "NeuropixelImec1",
"name": "NeuropixelsImec1",
"description": "{\"probe_type\": \"0\", \"probe_type_description\": \"NP1.0\", \"flex_part_number\": \"NP2_FLEX_0\", \"connected_base_station_part_number\": \"NP2_QBSC_00\"}",
"manufacturer": "Imec"
}
],
"ElectrodeGroup": [
{
"name": "Imec0",
"description": "A group representing probe/shank 'Imec0'.",
"name": "NeuropixelsImec0",
"description": "A group representing probe/shank 'NeuropixelsImec0'.",
"location": "unknown",
"device": "NeuropixelImec0"
"device": "NeuropixelsImec0"
},
{
"name": "Imec1",
"description": "A group representing probe/shank 'Imec1'.",
"name": "NeuropixelsImec1",
"description": "A group representing probe/shank 'NeuropixelsImec1'.",
"location": "unknown",
"device": "NeuropixelImec1"
"device": "NeuropixelsImec1"
}
],
"ElectricalSeriesAPImec0": {
Expand All @@ -45,6 +45,10 @@
{
"name": "contact_ids",
"description": "The id of the contact on the electrode"
},
{
"name": "inter_sample_shift",
"description": "Array of relative phase shifts for each channel, with values ranging from 0 to 1, representing the fractional delay within the sampling period due to sequential ADC."
}
],
"ElectricalSeriesAPImec1": {
Expand Down
12 changes: 8 additions & 4 deletions tests/test_on_data/ecephys/spikeglx_single_probe_metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@
"Ecephys": {
"Device": [
{
"name": "NeuropixelImec0",
"name": "NeuropixelsImec0",
"description": "{\"probe_type\": \"0\", \"probe_type_description\": \"NP1.0\", \"flex_part_number\": \"NP2_FLEX_0\", \"connected_base_station_part_number\": \"NP2_QBSC_00\"}",
"manufacturer": "Imec"
}
],
"ElectrodeGroup": [
{
"name": "Imec0",
"description": "A group representing probe/shank 'Imec0'.",
"name": "NeuropixelsImec0",
"description": "A group representing probe/shank 'NeuropixelsImec0'.",
"location": "unknown",
"device": "NeuropixelImec0"
"device": "NeuropixelsImec0"
}

],
Expand All @@ -35,6 +35,10 @@
{
"name": "contact_ids",
"description": "The id of the contact on the electrode"
},
{
"name": "inter_sample_shift",
"description": "Array of relative phase shifts for each channel, with values ranging from 0 to 1, representing the fractional delay within the sampling period due to sequential ADC."
}
],
"ElectricalSeriesLF": {
Expand Down
4 changes: 2 additions & 2 deletions tests/test_on_data/ecephys/test_recording_interfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -670,7 +670,7 @@ class TestSpikeGLXRecordingInterface(RecordingExtractorInterfaceTestMixin):
def check_extracted_metadata(self, metadata: dict):
assert metadata["NWBFile"]["session_start_time"] == datetime(2020, 11, 3, 10, 35, 10)
assert metadata["Ecephys"]["Device"][-1] == dict(
name="NeuropixelImec0",
name="NeuropixelsImec0",
description="{"
'"probe_type": "0", '
'"probe_type_description": "NP1.0", '
Expand Down Expand Up @@ -698,7 +698,7 @@ class TestSpikeGLXRecordingInterfaceLongNHP(RecordingExtractorInterfaceTestMixin
def check_extracted_metadata(self, metadata: dict):
assert metadata["NWBFile"]["session_start_time"] == datetime(2024, 1, 3, 11, 51, 51)
assert metadata["Ecephys"]["Device"][-1] == dict(
name="NeuropixelImec0",
name="NeuropixelsImec0",
description="{"
'"probe_type": "1030", '
'"probe_type_description": "NP1.0 NHP", '
Expand Down
22 changes: 15 additions & 7 deletions tests/test_on_data/ecephys/test_spikeglx_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,11 @@ def assertNWBFileStructure(self, nwbfile_path: FilePath, expected_session_start_

assert len(nwbfile.acquisition) == 3

assert "NeuropixelImec0" in nwbfile.devices
assert "NeuropixelsImec0" in nwbfile.devices
assert "NIDQBoard" in nwbfile.devices
assert len(nwbfile.devices) == 2

assert "Imec0" in nwbfile.electrode_groups
assert "NeuropixelsImec0" in nwbfile.electrode_groups
assert len(nwbfile.electrode_groups) == 1

def test_single_probe_spikeglx_converter(self):
Expand Down Expand Up @@ -132,12 +132,12 @@ def assertNWBFileStructure(self, nwbfile_path: FilePath, expected_session_start_
assert "ElectricalSeriesLFImec11" in nwbfile.acquisition
assert len(nwbfile.acquisition) == 16

assert "NeuropixelImec0" in nwbfile.devices
assert "NeuropixelImec1" in nwbfile.devices
assert "NeuropixelsImec0" in nwbfile.devices
assert "NeuropixelsImec1" in nwbfile.devices
assert len(nwbfile.devices) == 2

assert "Imec0" in nwbfile.electrode_groups
assert "Imec1" in nwbfile.electrode_groups
assert "NeuropixelsImec0" in nwbfile.electrode_groups
assert "NeuropixelsImec1" in nwbfile.electrode_groups
assert len(nwbfile.electrode_groups) == 2

def test_multi_probe_spikeglx_converter(self):
Expand All @@ -160,8 +160,16 @@ def test_multi_probe_spikeglx_converter(self):

device_metadata = test_ecephys_metadata.pop("Device")
expected_device_metadata = expected_ecephys_metadata.pop("Device")

assert device_metadata == expected_device_metadata

assert test_ecephys_metadata["ElectrodeGroup"] == expected_ecephys_metadata["ElectrodeGroup"]
assert test_ecephys_metadata["Electrodes"] == expected_ecephys_metadata["Electrodes"]
assert test_ecephys_metadata["ElectricalSeriesAPImec0"] == expected_ecephys_metadata["ElectricalSeriesAPImec0"]
assert test_ecephys_metadata["ElectricalSeriesAPImec1"] == expected_ecephys_metadata["ElectricalSeriesAPImec1"]
assert test_ecephys_metadata["ElectricalSeriesLFImec0"] == expected_ecephys_metadata["ElectricalSeriesLFImec0"]
assert test_ecephys_metadata["ElectricalSeriesLFImec1"] == expected_ecephys_metadata["ElectricalSeriesLFImec1"]

# Test all the dictionary
assert test_ecephys_metadata == expected_ecephys_metadata

nwbfile_path = self.tmpdir / "test_multi_probe_spikeglx_converter.nwb"
Expand Down
3 changes: 2 additions & 1 deletion tests/test_on_data/ecephys/test_spikeglx_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ def test_spikelgx_recording_property_addition():
probe_name = "Imec0"

expected_shank_ids = probe.shank_ids
expected_group_name = [f"{probe_name}{shank_id}" for shank_id in expected_shank_ids]
expected_group_name = [f"Neuropixels{probe_name}Shank{shank_id}" for shank_id in expected_shank_ids]

expected_contact_shapes = ["square"] * n_channels
expected_contact_ids = probe.contact_ids

Expand Down

0 comments on commit f3dd4ed

Please sign in to comment.