diff --git a/CHANGELOG.md b/CHANGELOG.md index b6d676a1..4241e2f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,9 @@ ### New Checks * Added `check_rate_is_not_zero` for ensuring non-zero rate value of `TimeSeries` that has more than one frame. [#389](https://github.com/NeurodataWithoutBorders/nwbinspector/issues/389) +* Added `check_electrical_series_conversion_factors` for ensuring non-default conversion/offset factors of any `ElectricalSeries` that has an integer data type. [#395](https://github.com/NeurodataWithoutBorders/nwbinspector/issues/395) + + # v0.4.30 diff --git a/src/nwbinspector/checks/ecephys.py b/src/nwbinspector/checks/ecephys.py index 5044bd8d..d853993d 100644 --- a/src/nwbinspector/checks/ecephys.py +++ b/src/nwbinspector/checks/ecephys.py @@ -79,3 +79,16 @@ def check_spike_times_not_in_unobserved_interval(units_table: Units, nunits: int "observed intervals." ) ) + + +@register_check(importance=Importance.CRITICAL, neurodata_type=ElectricalSeries) +def check_electrical_series_conversion_factors(electrical_series: ElectricalSeries): + data = electrical_series.data + if ( + np.issubdtype(data.dtype, np.integer) + and electrical_series.conversion == electrical_series.DEFAULT_CONVERSION + and electrical_series.offset == electrical_series.DEFAULT_OFFSET + ): + return InspectorMessage( + message="ElectricalSeries data type is integer and conversion factor and offset are both default, the value may not be in the correct unit" + ) diff --git a/tests/unit_tests/test_ecephys.py b/tests/unit_tests/test_ecephys.py index ccd3ab63..3cd47f71 100644 --- a/tests/unit_tests/test_ecephys.py +++ b/tests/unit_tests/test_ecephys.py @@ -15,6 +15,7 @@ check_electrical_series_dims, check_electrical_series_reference_electrodes_table, check_spike_times_not_in_unobserved_interval, + check_electrical_series_conversion_factors, ) @@ -155,6 +156,76 @@ def test_trigger_check_electrical_series_reference_electrodes_table(self): == "electrodes does not reference an electrodes table." ) + def test_check_electrical_series_dtype_pass(self): + electrodes = self.nwbfile.create_electrode_table_region(region=[0, 1, 2, 3, 4], description="all") + + electrical_series = ElectricalSeries( + name="elec_series", + description="desc", + data=np.ones((100, 5), dtype=np.dtype("float64")), + electrodes=electrodes, + rate=30.0, + ) + + self.nwbfile.add_acquisition(electrical_series) + + assert check_electrical_series_conversion_factors(electrical_series) is None + + def test_check_electrical_series_dtype_fail(self): + electrodes = self.nwbfile.create_electrode_table_region(region=[0, 1, 2, 3, 4], description="all") + + electrical_series = ElectricalSeries( + name="elec_series", + description="desc", + data=np.ones((100, 5), dtype=np.dtype("int16")), + electrodes=electrodes, + rate=30.0, + ) + + self.nwbfile.add_acquisition(electrical_series) + + assert check_electrical_series_conversion_factors(electrical_series) == InspectorMessage( + message=( + "ElectricalSeries data type is integer and conversion factor and offset are both default, the value may not be in the correct unit" + ), + importance=Importance.CRITICAL, + check_function_name="check_electrical_series_dtype", + object_type="ElectricalSeries", + object_name="elec_series", + ) + + def test_check_electrical_series_dtype_non_default_conversion_skip(self): + electrodes = self.nwbfile.create_electrode_table_region(region=[0, 1, 2, 3, 4], description="all") + + electrical_series = ElectricalSeries( + name="elec_series", + description="desc", + data=np.ones((100, 5), dtype=np.dtype("int16")), + electrodes=electrodes, + rate=30.0, + conversion=0.1, + ) + + self.nwbfile.add_acquisition(electrical_series) + + assert check_electrical_series_conversion_factors(electrical_series) is None + + def test_check_electrical_series_dtype_non_default_offet_skip(self): + electrodes = self.nwbfile.create_electrode_table_region(region=[0, 1, 2, 3, 4], description="all") + + electrical_series = ElectricalSeries( + name="elec_series", + description="desc", + data=np.ones((100, 5), dtype=np.dtype("int16")), + electrodes=electrodes, + rate=30.0, + offset=0.1, + ) + + self.nwbfile.add_acquisition(electrical_series) + + assert check_electrical_series_conversion_factors(electrical_series) is None + def test_check_spike_times_not_in_unobserved_interval_pass(): units_table = Units(name="TestUnits")