Skip to content

Commit f136410

Browse files
mavaylon1rly
andauthored
Update SpatialSeries to have bounds field (#1869)
Co-authored-by: Ryan Ly <[email protected]>
1 parent 78ebc86 commit f136410

File tree

5 files changed

+33
-6
lines changed

5 files changed

+33
-6
lines changed

CHANGELOG.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@
33
## PyNWB 2.7.0 (Upcoming)
44

55
### Enhancements and minor changes
6+
- 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)
67
- 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
7-
- Deprecated `ImagingRetinotopy` neurodata type. @rly [#1813](https://github.com/NeurodataWithoutBorders/pynwb/pull/1813)
8-
- Modified `OptogeneticSeries` to allow 2D data, primarily in extensions of `OptogeneticSeries`. @rly [#1812](https://github.com/NeurodataWithoutBorders/pynwb/pull/1812)
9-
- Support `stimulus_template` as optional predefined column in `IntracellularStimuliTable`. @stephprince [#1815](https://github.com/NeurodataWithoutBorders/pynwb/pull/1815)
10-
- Support `NWBDataInterface` and `DynamicTable` in `NWBFile.stimulus`. @rly [#1842](https://github.com/NeurodataWithoutBorders/pynwb/pull/1842)
8+
- Deprecated `ImagingRetinotopy` neurodata type. @rly [#1813](https://github.com/NeurodataWithoutBorders/pynwb/pull/1813)
9+
- Modified `OptogeneticSeries` to allow 2D data, primarily in extensions of `OptogeneticSeries`. @rly [#1812](https://github.com/NeurodataWithoutBorders/pynwb/pull/1812)
10+
- Support `stimulus_template` as optional predefined column in `IntracellularStimuliTable`. @stephprince [#1815](https://github.com/NeurodataWithoutBorders/pynwb/pull/1815)
11+
- Support `NWBDataInterface` and `DynamicTable` in `NWBFile.stimulus`. @rly [#1842](https://github.com/NeurodataWithoutBorders/pynwb/pull/1842)
1112
- 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)
1213
- Added `grid_spacing`, `grid_spacing_unit`, `origin_coords`, `origin_coords_unit` to `ImagingPlane` fields. @h-mayorquin [#1892](https://github.com/NeurodataWithoutBorders/pynwb/pull/1892)
1314
- Added `mock_Units` for generating Units tables. @h-mayorquin [#1875](https://github.com/NeurodataWithoutBorders/pynwb/pull/1875) and [#1883](https://github.com/NeurodataWithoutBorders/pynwb/pull/1883)

docs/gallery/domain/plot_behavior.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,13 +105,17 @@
105105
#
106106
# For position data ``reference_frame`` indicates the zero-position, e.g.
107107
# the 0,0 point might be the bottom-left corner of an enclosure, as viewed from the tracking camera.
108+
# In :py:class:`~pynwb.behavior.SpatialSeries`, the ``bounds`` field allows the user to set
109+
# the boundary range, i.e., (min, max), for each dimension of ``data``. The units are the same as in ``data``.
110+
# This field does not enforce a boundary on the dataset itself.
108111

109112
timestamps = np.linspace(0, 50) / 200
110113

111114
position_spatial_series = SpatialSeries(
112115
name="SpatialSeries",
113116
description="Position (x, y) in an open field.",
114117
data=position_data,
118+
bounds=[(0,50), (0,50)],
115119
timestamps=timestamps,
116120
reference_frame="(0,0) is bottom left corner",
117121
)

src/pynwb/behavior.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,11 @@ class SpatialSeries(TimeSeries):
2323
__nwbfields__ = ('reference_frame',)
2424

2525
@docval(*get_docval(TimeSeries.__init__, 'name'), # required
26-
{'name': 'data', 'type': ('array_data', 'data', TimeSeries), 'shape': ((None, ), (None, None)), # required
26+
{'name': 'data', 'type': ('array_data', 'data', TimeSeries), 'shape': ((None, ), (None, None)), # required
2727
'doc': ('The data values. Can be 1D or 2D. The first dimension must be time. If 2D, there can be 1, 2, '
2828
'or 3 columns, which represent x, y, and z.')},
29+
{'name': 'bounds', 'type': list, 'shape': ((1, 2), (2, 2), (3, 2)), 'default': None,
30+
'doc': 'The boundary range (min, max) for each dimension of data.'},
2931
{'name': 'reference_frame', 'type': str, # required
3032
'doc': 'description defining what the zero-position is'},
3133
{'name': 'unit', 'type': str, 'doc': 'The base unit of measurement (should be SI unit)',
@@ -36,7 +38,7 @@ def __init__(self, **kwargs):
3638
"""
3739
Create a SpatialSeries TimeSeries dataset
3840
"""
39-
name, data, reference_frame, unit = popargs('name', 'data', 'reference_frame', 'unit', kwargs)
41+
name, data, bounds, reference_frame, unit = popargs('name', 'data', 'bounds', 'reference_frame', 'unit', kwargs)
4042
super().__init__(name, data, unit, **kwargs)
4143

4244
# NWB 2.5 restricts length of second dimension to be <= 3
@@ -47,6 +49,7 @@ def __init__(self, **kwargs):
4749
"The second dimension should have length <= 3 to represent at most x, y, z." %
4850
(name, str(data_shape)))
4951

52+
self.bounds = bounds
5053
self.reference_frame = reference_frame
5154

5255
@staticmethod
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import numpy as np
2+
3+
from pynwb.behavior import SpatialSeries
4+
from pynwb.testing import AcquisitionH5IOMixin, TestCase
5+
6+
7+
class TestSpatialSeriesIO(AcquisitionH5IOMixin, TestCase):
8+
9+
def setUpContainer(self):
10+
""" Return the test TimeSeries to read/write """
11+
return SpatialSeries(
12+
name='test_sS',
13+
data=np.ones((3, 2)),
14+
bounds=[(-1,1),(-1,1),(-1,1)],
15+
reference_frame='reference_frame',
16+
timestamps=[1., 2., 3.]
17+
)

tests/unit/test_behavior.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@ def test_init(self):
1212
sS = SpatialSeries(
1313
name='test_sS',
1414
data=np.ones((3, 2)),
15+
bounds=[(-1,1),(-1,1),(-1,1)],
1516
reference_frame='reference_frame',
1617
timestamps=[1., 2., 3.]
1718
)
1819
self.assertEqual(sS.name, 'test_sS')
1920
self.assertEqual(sS.unit, 'meters')
21+
self.assertEqual(sS.bounds, [(-1,1),(-1,1),(-1,1)])
2022
self.assertEqual(sS.reference_frame, 'reference_frame')
2123

2224
def test_set_unit(self):

0 commit comments

Comments
 (0)