Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[New Check]: TimeSeries rate is zero #404

4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Upcoming

### 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)

# v0.4.30

### Fixes
Expand Down
11 changes: 11 additions & 0 deletions docs/best_practices/time_series.rst
Original file line number Diff line number Diff line change
Expand Up @@ -157,3 +157,14 @@ Unknown Resolution
If the ``resolution`` of a :ref:`nwb-schema:sec-TimeSeries` is unknown, use ``-1.0`` or ``NaN`` to indicate this.

Check function: :py::meth:`~nwbinspector.checks.time_series.check_resolution`



.. _best_practice_non_zero_rate:

Zero Rate
~~~~~~~~~

If the ``data`` field of :ref:`nwb-schema:sec-TimeSeries` has more than one frame, and according to :ref:`best_practice_data_orientation` this axis ought to be time, then the ``rate`` field should not be ``0.0``.

Check function: :py::meth:`~nwbinspector.checks.time_series.check_rate_is_not_zero`
11 changes: 11 additions & 0 deletions src/nwbinspector/checks/time_series.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,3 +129,14 @@ def check_resolution(time_series: TimeSeries):
return InspectorMessage(
message=f"'resolution' should use -1.0 or NaN for unknown instead of {time_series.resolution}."
)


@register_check(importance=Importance.CRITICAL, neurodata_type=TimeSeries)
def check_rate_is_not_zero(time_series: TimeSeries):
if time_series.data is None:
return
data_shape = get_data_shape(time_series.data)
if time_series.rate == 0.0 and data_shape[0] > 1:
return InspectorMessage(
f"{time_series.name} has a sampling rate value of 0.0Hz but the series has more than one frame."
)
23 changes: 23 additions & 0 deletions tests/unit_tests/test_time_series.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
check_missing_unit,
check_resolution,
check_timestamp_of_the_first_sample_is_not_negative,
check_rate_is_not_zero,
)
from nwbinspector.tools import make_minimal_nwbfile
from nwbinspector.testing import check_streaming_tests_enabled
Expand Down Expand Up @@ -199,6 +200,28 @@ def test_check_timestamps_empty_timestamps():
)


def test_check_rate_is_not_zero_pass():
time_series = pynwb.TimeSeries(name="test", unit="test_units", data=[1, 2, 3], rate=4.0)
assert check_rate_is_not_zero(time_series) is None


def test_check_rate_is_not_zero_single_frame_pass():
time_series = pynwb.TimeSeries(name="test", unit="test_units", data=[1], rate=0.0)
assert check_rate_is_not_zero(time_series) is None


def test_check_rate_is_not_zero_fail():
time_series = pynwb.TimeSeries(name="TimeSeriesTest", unit="n.a.", data=[1, 2, 3], rate=0.0)
assert check_rate_is_not_zero(time_series) == InspectorMessage(
message="TimeSeriesTest has a sampling rate value of 0.0Hz but the series has more than one frame.",
importance=Importance.CRITICAL,
check_function_name="check_rate_is_not_zero",
object_type="TimeSeries",
object_name="TimeSeriesTest",
location="/",
)


def test_pass_check_timestamps_ascending_pass():
time_series = pynwb.TimeSeries(name="test_time_series", unit="test_units", data=[1, 2, 3], timestamps=[1, 2, 3])
assert check_timestamps_ascending(time_series) is None
Expand Down
Loading