From 3dd00128706d47467225365041e24e5afed9daba Mon Sep 17 00:00:00 2001 From: mavaylon1 Date: Mon, 25 Mar 2024 11:51:52 -0700 Subject: [PATCH 01/10] Update SpatialSeries --- docs/gallery/domain/plot_behavior.py | 4 ++++ src/pynwb/_version.py | 16 ++++++++++++++++ src/pynwb/behavior.py | 7 +++++-- src/pynwb/nwb-schema | 2 +- tests/unit/test_behavior.py | 2 ++ 5 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 src/pynwb/_version.py diff --git a/docs/gallery/domain/plot_behavior.py b/docs/gallery/domain/plot_behavior.py index 8f341bea1..35fbae81f 100644 --- a/docs/gallery/domain/plot_behavior.py +++ b/docs/gallery/domain/plot_behavior.py @@ -105,6 +105,9 @@ # # For position data ``reference_frame`` indicates the zero-position, e.g. # the 0,0 point might be the bottom-left corner of an enclosure, as viewed from the tracking camera. +# In :py:class:`~pynwb.behavior.SpatialSeries`, the ``bounds`` field allows the user to set +# the boundary range, i.e., (min, max), for each dimension of ``data``. The units are the same as in ``data``. +# This field does not enforce a boundary on the dataset itself. timestamps = np.linspace(0, 50) / 200 @@ -112,6 +115,7 @@ name="SpatialSeries", description="Position (x, y) in an open field.", data=position_data, + bounds=[(0,50), (0,50)], timestamps=timestamps, reference_frame="(0,0) is bottom left corner", ) diff --git a/src/pynwb/_version.py b/src/pynwb/_version.py new file mode 100644 index 000000000..94fdb9d9f --- /dev/null +++ b/src/pynwb/_version.py @@ -0,0 +1,16 @@ +# file generated by setuptools_scm +# don't change, don't track in version control +TYPE_CHECKING = False +if TYPE_CHECKING: + from typing import Tuple, Union + VERSION_TUPLE = Tuple[Union[int, str], ...] +else: + VERSION_TUPLE = object + +version: str +__version__: str +__version_tuple__: VERSION_TUPLE +version_tuple: VERSION_TUPLE + +__version__ = version = '2.6.1.dev5+g8d9aaa34.d20240325' +__version_tuple__ = version_tuple = (2, 6, 1, 'dev5', 'g8d9aaa34.d20240325') diff --git a/src/pynwb/behavior.py b/src/pynwb/behavior.py index b9388e8df..93bb14a89 100644 --- a/src/pynwb/behavior.py +++ b/src/pynwb/behavior.py @@ -23,9 +23,11 @@ class SpatialSeries(TimeSeries): __nwbfields__ = ('reference_frame',) @docval(*get_docval(TimeSeries.__init__, 'name'), # required - {'name': 'data', 'type': ('array_data', 'data', TimeSeries), 'shape': ((None, ), (None, None)), # required + {'name': 'data', 'type': ('array_data', 'data', TimeSeries), 'shape': ((None, ), (None, None)), # required 'doc': ('The data values. Can be 1D or 2D. The first dimension must be time. If 2D, there can be 1, 2, ' 'or 3 columns, which represent x, y, and z.')}, + {'name': 'bounds', 'type': list, 'shape': ((None, ), (None, None), (None, None, None)), 'default': None, + 'doc': 'The boundary range (min, max) for each dimension of data.'}, {'name': 'reference_frame', 'type': str, # required 'doc': 'description defining what the zero-position is'}, {'name': 'unit', 'type': str, 'doc': 'The base unit of measurement (should be SI unit)', @@ -36,7 +38,7 @@ def __init__(self, **kwargs): """ Create a SpatialSeries TimeSeries dataset """ - name, data, reference_frame, unit = popargs('name', 'data', 'reference_frame', 'unit', kwargs) + name, data, bounds, reference_frame, unit = popargs('name', 'data', 'bounds', 'reference_frame', 'unit', kwargs) super().__init__(name, data, unit, **kwargs) # NWB 2.5 restricts length of second dimension to be <= 3 @@ -47,6 +49,7 @@ def __init__(self, **kwargs): "The second dimension should have length <= 3 to represent at most x, y, z." % (name, str(data_shape))) + self.bounds = bounds self.reference_frame = reference_frame @staticmethod diff --git a/src/pynwb/nwb-schema b/src/pynwb/nwb-schema index d65d42257..5f8fe9912 160000 --- a/src/pynwb/nwb-schema +++ b/src/pynwb/nwb-schema @@ -1 +1 @@ -Subproject commit d65d42257003543c569ea7ac0cd6d7aee01c88d6 +Subproject commit 5f8fe99123cd497fed90e9b433360852ab7b0339 diff --git a/tests/unit/test_behavior.py b/tests/unit/test_behavior.py index 0b7173da0..6bcf1a9eb 100644 --- a/tests/unit/test_behavior.py +++ b/tests/unit/test_behavior.py @@ -12,11 +12,13 @@ def test_init(self): sS = SpatialSeries( name='test_sS', data=np.ones((3, 2)), + bounds=[(-1,1),(-1,1),(-1,1)], reference_frame='reference_frame', timestamps=[1., 2., 3.] ) self.assertEqual(sS.name, 'test_sS') self.assertEqual(sS.unit, 'meters') + self.assertEqual(sS.bounds, [(-1,1),(-1,1),(-1,1)]) self.assertEqual(sS.reference_frame, 'reference_frame') def test_set_unit(self): From f86b4d730b92b08b76132136efcecdceffe6738c Mon Sep 17 00:00:00 2001 From: Matthew Avaylon Date: Mon, 25 Mar 2024 13:22:57 -0700 Subject: [PATCH 02/10] Delete src/pynwb/_version.py --- src/pynwb/_version.py | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 src/pynwb/_version.py diff --git a/src/pynwb/_version.py b/src/pynwb/_version.py deleted file mode 100644 index 94fdb9d9f..000000000 --- a/src/pynwb/_version.py +++ /dev/null @@ -1,16 +0,0 @@ -# file generated by setuptools_scm -# don't change, don't track in version control -TYPE_CHECKING = False -if TYPE_CHECKING: - from typing import Tuple, Union - VERSION_TUPLE = Tuple[Union[int, str], ...] -else: - VERSION_TUPLE = object - -version: str -__version__: str -__version_tuple__: VERSION_TUPLE -version_tuple: VERSION_TUPLE - -__version__ = version = '2.6.1.dev5+g8d9aaa34.d20240325' -__version_tuple__ = version_tuple = (2, 6, 1, 'dev5', 'g8d9aaa34.d20240325') From 549b2aa83d1647abf6cf6f03f78815de1f6c4e22 Mon Sep 17 00:00:00 2001 From: mavaylon1 Date: Sat, 30 Mar 2024 11:48:37 -0700 Subject: [PATCH 03/10] schema repo --- src/pynwb/nwb-schema | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pynwb/nwb-schema b/src/pynwb/nwb-schema index 5f8fe9912..d65d42257 160000 --- a/src/pynwb/nwb-schema +++ b/src/pynwb/nwb-schema @@ -1 +1 @@ -Subproject commit 5f8fe99123cd497fed90e9b433360852ab7b0339 +Subproject commit d65d42257003543c569ea7ac0cd6d7aee01c88d6 From 8e01fed9fb419fd95837e54f03c902384e4f97e3 Mon Sep 17 00:00:00 2001 From: Matthew Avaylon Date: Sat, 30 Mar 2024 12:24:14 -0700 Subject: [PATCH 04/10] Update CHANGELOG.md --- CHANGELOG.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a7515c3e..cdc930e15 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,11 +3,12 @@ ## PyNWB 2.7.0 (Upcoming) ### Enhancements and minor changes +- Added `bounds` field to `SpatialSeries` to set optional boundary range (min, max) for each dimension of data. @mavaylon1 [#1869](https://github.com/NeurodataWithoutBorders/pynwb/pull/1869/files) - Added support for NWB schema 2.7.0. See [2.7.0 release notes](https://nwb-schema.readthedocs.io/en/latest/format_release_notes.html) for details - - Deprecated `ImagingRetinotopy` neurodata type. @rly [#1813](https://github.com/NeurodataWithoutBorders/pynwb/pull/1813) - - Modified `OptogeneticSeries` to allow 2D data, primarily in extensions of `OptogeneticSeries`. @rly [#1812](https://github.com/NeurodataWithoutBorders/pynwb/pull/1812) - - Support `stimulus_template` as optional predefined column in `IntracellularStimuliTable`. @stephprince [#1815](https://github.com/NeurodataWithoutBorders/pynwb/pull/1815) - - Support `NWBDataInterface` and `DynamicTable` in `NWBFile.stimulus`. @rly [#1842](https://github.com/NeurodataWithoutBorders/pynwb/pull/1842) +- Deprecated `ImagingRetinotopy` neurodata type. @rly [#1813](https://github.com/NeurodataWithoutBorders/pynwb/pull/1813) +- Modified `OptogeneticSeries` to allow 2D data, primarily in extensions of `OptogeneticSeries`. @rly [#1812](https://github.com/NeurodataWithoutBorders/pynwb/pull/1812) +- Support `stimulus_template` as optional predefined column in `IntracellularStimuliTable`. @stephprince [#1815](https://github.com/NeurodataWithoutBorders/pynwb/pull/1815) +- Support `NWBDataInterface` and `DynamicTable` in `NWBFile.stimulus`. @rly [#1842](https://github.com/NeurodataWithoutBorders/pynwb/pull/1842) - Added support for python 3.12 and upgraded dependency versions. This also includes infrastructure updates for developers. @mavaylon1 [#1853](https://github.com/NeurodataWithoutBorders/pynwb/pull/1853) ### Bug fixes From 1568357cbeb680b680589c84f9d23ed691b767bd Mon Sep 17 00:00:00 2001 From: mavaylon1 Date: Wed, 1 May 2024 16:36:58 -0700 Subject: [PATCH 05/10] roundtrip --- src/pynwb/nwb-schema | 2 +- tests/integration/hdf5/test_behavior.py | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 tests/integration/hdf5/test_behavior.py diff --git a/src/pynwb/nwb-schema b/src/pynwb/nwb-schema index d65d42257..7393211bb 160000 --- a/src/pynwb/nwb-schema +++ b/src/pynwb/nwb-schema @@ -1 +1 @@ -Subproject commit d65d42257003543c569ea7ac0cd6d7aee01c88d6 +Subproject commit 7393211bb04a61c153239dc49691598b4a41fa39 diff --git a/tests/integration/hdf5/test_behavior.py b/tests/integration/hdf5/test_behavior.py new file mode 100644 index 000000000..b2407326e --- /dev/null +++ b/tests/integration/hdf5/test_behavior.py @@ -0,0 +1,16 @@ +import numpy as np + +from pynwb.behavior import SpatialSeries +from pynwb.testing import AcquisitionH5IOMixin, TestCase, remove_test_file + + +class TestTimeSeriesIO(AcquisitionH5IOMixin, TestCase): + + def setUpContainer(self): + """ Return the test TimeSeries to read/write """ + return SpatialSeries( + name='test_sS', + data=np.ones((3, 2)), + reference_frame='reference_frame', + timestamps=[1., 2., 3.] + ) From 5ac019127b5f1730cea9a96fcbff181b31497da9 Mon Sep 17 00:00:00 2001 From: mavaylon1 Date: Wed, 1 May 2024 16:37:26 -0700 Subject: [PATCH 06/10] roundtrip --- tests/integration/hdf5/test_behavior.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/hdf5/test_behavior.py b/tests/integration/hdf5/test_behavior.py index b2407326e..63ca660fb 100644 --- a/tests/integration/hdf5/test_behavior.py +++ b/tests/integration/hdf5/test_behavior.py @@ -1,7 +1,7 @@ import numpy as np from pynwb.behavior import SpatialSeries -from pynwb.testing import AcquisitionH5IOMixin, TestCase, remove_test_file +from pynwb.testing import AcquisitionH5IOMixin, TestCase class TestTimeSeriesIO(AcquisitionH5IOMixin, TestCase): From d289bd638f0e9d7be797ac2a75531aa580986d52 Mon Sep 17 00:00:00 2001 From: mavaylon1 Date: Wed, 1 May 2024 16:44:46 -0700 Subject: [PATCH 07/10] schema --- src/pynwb/nwb-schema | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pynwb/nwb-schema b/src/pynwb/nwb-schema index 7393211bb..d65d42257 160000 --- a/src/pynwb/nwb-schema +++ b/src/pynwb/nwb-schema @@ -1 +1 @@ -Subproject commit 7393211bb04a61c153239dc49691598b4a41fa39 +Subproject commit d65d42257003543c569ea7ac0cd6d7aee01c88d6 From 7c6c10d64b3090496ae719e776a8e3fb20232721 Mon Sep 17 00:00:00 2001 From: Matthew Avaylon Date: Wed, 1 May 2024 18:07:39 -0700 Subject: [PATCH 08/10] Update src/pynwb/behavior.py Co-authored-by: Ryan Ly --- src/pynwb/behavior.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pynwb/behavior.py b/src/pynwb/behavior.py index 93bb14a89..1b3078535 100644 --- a/src/pynwb/behavior.py +++ b/src/pynwb/behavior.py @@ -26,7 +26,7 @@ class SpatialSeries(TimeSeries): {'name': 'data', 'type': ('array_data', 'data', TimeSeries), 'shape': ((None, ), (None, None)), # required 'doc': ('The data values. Can be 1D or 2D. The first dimension must be time. If 2D, there can be 1, 2, ' 'or 3 columns, which represent x, y, and z.')}, - {'name': 'bounds', 'type': list, 'shape': ((None, ), (None, None), (None, None, None)), 'default': None, + {'name': 'bounds', 'type': list, 'shape': ((1, 2), (2, 2), (3, 2)), 'default': None, 'doc': 'The boundary range (min, max) for each dimension of data.'}, {'name': 'reference_frame', 'type': str, # required 'doc': 'description defining what the zero-position is'}, From 64e10b4015db353eb907c92adbd445d253b25eca Mon Sep 17 00:00:00 2001 From: Matthew Avaylon Date: Wed, 1 May 2024 18:07:46 -0700 Subject: [PATCH 09/10] Update tests/integration/hdf5/test_behavior.py Co-authored-by: Ryan Ly --- tests/integration/hdf5/test_behavior.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/hdf5/test_behavior.py b/tests/integration/hdf5/test_behavior.py index 63ca660fb..c55d4b7a2 100644 --- a/tests/integration/hdf5/test_behavior.py +++ b/tests/integration/hdf5/test_behavior.py @@ -4,7 +4,7 @@ from pynwb.testing import AcquisitionH5IOMixin, TestCase -class TestTimeSeriesIO(AcquisitionH5IOMixin, TestCase): +class TestSpatialSeriesIO(AcquisitionH5IOMixin, TestCase): def setUpContainer(self): """ Return the test TimeSeries to read/write """ From e0ad9d3c97e93dbc7fa63ec6edb331040ef82a7f Mon Sep 17 00:00:00 2001 From: Matthew Avaylon Date: Wed, 1 May 2024 18:07:54 -0700 Subject: [PATCH 10/10] Update tests/integration/hdf5/test_behavior.py Co-authored-by: Ryan Ly --- tests/integration/hdf5/test_behavior.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/integration/hdf5/test_behavior.py b/tests/integration/hdf5/test_behavior.py index c55d4b7a2..d4b230bcc 100644 --- a/tests/integration/hdf5/test_behavior.py +++ b/tests/integration/hdf5/test_behavior.py @@ -11,6 +11,7 @@ def setUpContainer(self): return SpatialSeries( name='test_sS', data=np.ones((3, 2)), + bounds=[(-1,1),(-1,1),(-1,1)], reference_frame='reference_frame', timestamps=[1., 2., 3.] )