Skip to content

Commit e05b553

Browse files
authored
Warn instead of raise error if SpatialSeries has more than 3 columns (#1480)
1 parent c9ea3f2 commit e05b553

File tree

3 files changed

+26
-12
lines changed

3 files changed

+26
-12
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
## PyNWB 2.1.0 (Upcoming)
44

55
### Breaking changes:
6-
- Restrict `SpatialSeries.data` to have no more than 3 columns (#1455)
6+
- Raise a warning if `SpatialSeries.data` has more than 3 columns (#1455, #1480)
77
- Updated ``TimeIntervals`` to use the new ``TimeSeriesReferenceVectorData`` type. This does not alter the overall
88
structure of ``TimeIntervals`` in a major way aside from changing the value of the ``neurodata_type`` attribute of the
99
``TimeIntervals.timeseries`` column from ``VectorData`` to ``TimeSeriesReferenceVectorData``. This change facilitates

src/pynwb/behavior.py

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
from hdmf.utils import docval, popargs, get_docval
1+
import warnings
2+
3+
from hdmf.utils import docval, popargs, get_docval, get_data_shape
24

35
from . import register_class, CORE_NAMESPACE
46
from .core import MultiContainerInterface
@@ -21,9 +23,7 @@ class SpatialSeries(TimeSeries):
2123
__nwbfields__ = ('reference_frame',)
2224

2325
@docval(*get_docval(TimeSeries.__init__, 'name'), # required
24-
{'name': 'data', 'type': ('array_data', 'data', TimeSeries), 'shape': (
25-
(None, ), (None, 1), (None, 2), (None, 3)
26-
), # 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.')},
2929
{'name': 'reference_frame', 'type': str, # required
@@ -38,8 +38,26 @@ def __init__(self, **kwargs):
3838
"""
3939
name, data, reference_frame, unit = popargs('name', 'data', 'reference_frame', 'unit', kwargs)
4040
super(SpatialSeries, self).__init__(name, data, unit, **kwargs)
41+
42+
# NWB 2.5 restricts length of second dimension to be <= 3
43+
allowed_data_shapes = ((None, ), (None, 1), (None, 2), (None, 3))
44+
data_shape = get_data_shape(data)
45+
if not any(self._validate_data_shape(data_shape, a) for a in allowed_data_shapes):
46+
warnings.warn("SpatialSeries '%s' has data shape %s which is not compliant with NWB 2.5 and greater. "
47+
"The second dimension should have length <= 3 to represent at most x, y, z." %
48+
(name, str(data_shape)))
49+
4150
self.reference_frame = reference_frame
4251

52+
@staticmethod
53+
def _validate_data_shape(valshape, argshape):
54+
if not len(valshape) == len(argshape):
55+
return False
56+
for a, b in zip(valshape, argshape):
57+
if b not in (a, None):
58+
return False
59+
return True
60+
4361

4462
@register_class('BehavioralEpochs', CORE_NAMESPACE)
4563
class BehavioralEpochs(MultiContainerInterface):

tests/unit/test_behavior.py

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,11 @@ def test_set_unit(self):
2020
self.assertEqual(sS.unit, 'degrees')
2121

2222
def test_gt_3_cols(self):
23-
with self.assertRaises(ValueError) as error:
23+
msg = ("SpatialSeries 'test_sS' has data shape (5, 4) which is not compliant with NWB 2.5 and greater. "
24+
"The second dimension should have length <= 3 to represent at most x, y, z.")
25+
with self.assertWarnsWith(UserWarning, msg):
2426
SpatialSeries("test_sS", np.ones((5, 4)), "reference_frame", "meters", rate=30.)
2527

26-
self.assertEqual(
27-
"SpatialSeries.__init__: incorrect shape for 'data' (got '(5, 4)', expected "
28-
"'((None,), (None, 1), (None, 2), (None, 3))')",
29-
str(error.exception)
30-
)
31-
3228

3329
class BehavioralEpochsConstructor(TestCase):
3430
def test_init(self):

0 commit comments

Comments
 (0)