diff --git a/docs/gallery/domain/images.py b/docs/gallery/domain/images.py index 294566680..4fe7a8d49 100644 --- a/docs/gallery/domain/images.py +++ b/docs/gallery/domain/images.py @@ -310,7 +310,6 @@ name="stimuli", data=[0, 1, 0, 1], indexed_images=images, - unit="N/A", timestamps=[0.1, 0.2, 0.3, 0.4], ) diff --git a/src/pynwb/image.py b/src/pynwb/image.py index ac2d49b86..ded593146 100644 --- a/src/pynwb/image.py +++ b/src/pynwb/image.py @@ -13,7 +13,7 @@ - :class:`~pynwb.base.Images`: Container for storing a collection of images (imported from :mod:`pynwb.base`) - :class:`~pynwb.base.Image`: Base class for image data (imported from :mod:`pynwb.base`) -Note: While the :class:`~pynwb.base.Image` and :class:`~pynwb.base.Images` classes are defined in :mod:`pynwb.base`, +Note: While the :class:`~pynwb.base.Image` and :class:`~pynwb.base.Images` classes are defined in :mod:`pynwb.base`, they can be imported directly from this module: .. code-block:: python @@ -243,6 +243,11 @@ class IndexSeries(TimeSeries): # # value used when an ImageSeries is read and missing data # DEFAULT_UNIT = 'N/A' + DEFAULT_RESOLUTION = -1.0 + DEFAULT_CONVERSION = 1.0 + DEFAULT_OFFSET = 0.0 + + @docval( *get_docval(TimeSeries.__init__, 'name'), # required { @@ -251,7 +256,15 @@ class IndexSeries(TimeSeries): 'shape': (None,), # required 'doc': 'The data values. Must be 1D, where the first dimension must be time (frame)', }, - *get_docval(TimeSeries.__init__, 'unit'), # required + { + 'name': 'unit', + 'type': str, + 'doc': ( + 'The base unit of measurement (should be SI unit). Setting this to a value other than "N/A" is deprecated as of ' + 'NWB 2.5.0.' + ), + 'default': "N/A", + }, { 'name': 'indexed_timeseries', 'type': TimeSeries, # required 'doc': 'Link to TimeSeries containing images that are indexed.', @@ -266,8 +279,6 @@ class IndexSeries(TimeSeries): }, *get_docval( TimeSeries.__init__, - 'resolution', - 'conversion', 'timestamps', 'starting_time', 'rate', @@ -275,7 +286,6 @@ class IndexSeries(TimeSeries): 'description', 'control', 'control_description', - 'offset', ), allow_positional=AllowPositional.WARNING, ) @@ -291,21 +301,20 @@ def __init__(self, **kwargs): self._error_on_new_pass_on_construct("The indexed_timeseries field of IndexSeries is deprecated. " "Use the indexed_images field instead.") kwargs['unit'] = 'N/A' # fixed value starting in NWB 2.5 + # NOTE: attributes "resolution", "conversion", and "offset" from TimeSeries are unused by IndexSeries + # and should not be set, so IndexSeries does not allow the user to set them + kwargs['resolution'] = None + kwargs['conversion'] = None + kwargs['offset'] = None super().__init__(**kwargs) self.indexed_timeseries = indexed_timeseries self.indexed_images = indexed_images - if kwargs['conversion'] and kwargs['conversion'] != self.DEFAULT_CONVERSION: - warnings.warn("The conversion attribute is not used by IndexSeries.") - if kwargs['resolution'] and kwargs['resolution'] != self.DEFAULT_RESOLUTION: - warnings.warn("The resolution attribute is not used by IndexSeries.") - if kwargs['offset'] and kwargs['offset'] != self.DEFAULT_OFFSET: - warnings.warn("The offset attribute is not used by IndexSeries.") @register_class('ImageMaskSeries', CORE_NAMESPACE) class ImageMaskSeries(ImageSeries): ''' - DEPRECATED as of NWB 2.8.0 and PyNWB 3.0.0. + DEPRECATED as of NWB 2.8.0 and PyNWB 3.0.0. An alpha mask that is applied to a presented visual stimulus. The data[] array contains an array of mask values that are applied to the displayed image. Mask values are stored as RGBA. Mask can vary with time. The timestamps array indicates the starting time of a mask, and that mask diff --git a/src/pynwb/nwb-schema b/src/pynwb/nwb-schema index 764aa3725..a2ff463e6 160000 --- a/src/pynwb/nwb-schema +++ b/src/pynwb/nwb-schema @@ -1 +1 @@ -Subproject commit 764aa372536db61339ec4ae578e0b375b4b54829 +Subproject commit a2ff463e62ae788295606f0149245a2422dd5366 diff --git a/tests/integration/hdf5/test_image.py b/tests/integration/hdf5/test_image.py index 198ccc2d1..c64108862 100644 --- a/tests/integration/hdf5/test_image.py +++ b/tests/integration/hdf5/test_image.py @@ -40,7 +40,6 @@ def setUpContainer(self): iS = IndexSeries( name='test_iS', data=np.uint([1, 2, 3]), - unit='N/A', indexed_images=self.images, timestamps=[0.1, 0.2, 0.3] ) diff --git a/tests/unit/test_image.py b/tests/unit/test_image.py index 52c59f19f..6c1bdf22f 100644 --- a/tests/unit/test_image.py +++ b/tests/unit/test_image.py @@ -255,7 +255,7 @@ def test_external_file_default_format(self): unit="n.a.", starting_frame=[0, 10], rate=0.2,) - + iS = ImageSeries(**kwargs) self.assertEqual(iS.format, "external") @@ -343,15 +343,17 @@ def test_init(self): iS = IndexSeries( name='test_iS', data=[1, 2, 3], - unit='N/A', indexed_images=images, timestamps=[0.1, 0.2, 0.3] ) self.assertEqual(iS.name, 'test_iS') self.assertEqual(iS.unit, 'N/A') + self.assertIsNone(iS.resolution) + self.assertIsNone(iS.conversion) + self.assertIsNone(iS.offset) self.assertIs(iS.indexed_images, images) - def test_init_bad_unit(self): + def test_init_bad_unit(self): ts = TimeSeries( name='test_ts', data=[1, 2, 3], @@ -390,7 +392,7 @@ def test_init_indexed_ts(self): unit='N/A', indexed_timeseries=ts, timestamps=[0.1, 0.2, 0.3]) - + # create object with deprecated argument with self.assertRaisesWith(ValueError, msg): IndexSeries(**kwargs) @@ -407,63 +409,11 @@ def test_init_no_indexed_ts_or_timeseries(self): msg = ("Either indexed_timeseries or indexed_images " "must be provided when creating an IndexSeries.") with self.assertRaisesWith(ValueError, msg): - IndexSeries(name='test_iS', - data=[1, 2, 3], - unit='N/A', + IndexSeries(name='test_iS', + data=[1, 2, 3], + unit='N/A', timestamps=[0.1, 0.2, 0.3]) - def test_init_conversion_warning(self): - """Test that a warning is raised when conversion is provided""" - image1 = Image(name='test_image', data=np.ones((10, 10))) - image2 = Image(name='test_image2', data=np.ones((10, 10))) - image_references = ImageReferences(name='order_of_images', data=[image2, image1]) - images = Images(name='images_name', images=[image1, image2], order_of_images=image_references) - - with self.assertWarnsWith(UserWarning, "The conversion attribute is not used by IndexSeries."): - IndexSeries( - name='test_iS', - data=[1, 2, 3], - unit='N/A', - indexed_images=images, - timestamps=[0.1, 0.2, 0.3], - conversion=5.0 - ) - - def test_init_resolution_warning(self): - """Test that a warning is raised when resolution is provided""" - image1 = Image(name='test_image', data=np.ones((10, 10))) - image2 = Image(name='test_image2', data=np.ones((10, 10))) - image_references = ImageReferences(name='order_of_images', data=[image2, image1]) - images = Images(name='images_name', images=[image1, image2], order_of_images=image_references) - - with self.assertWarnsWith(UserWarning, "The resolution attribute is not used by IndexSeries."): - IndexSeries( - name='test_iS', - data=[1, 2, 3], - unit='N/A', - indexed_images=images, - timestamps=[0.1, 0.2, 0.3], - resolution=1.0 - ) - - def test_init_offset_warning(self): - """Test that a warning is raised when offset is provided""" - image1 = Image(name='test_image', data=np.ones((10, 10))) - image2 = Image(name='test_image2', data=np.ones((10, 10))) - image_references = ImageReferences(name='order_of_images', data=[image2, image1]) - images = Images(name='images_name', images=[image1, image2], order_of_images=image_references) - - with self.assertWarnsWith(UserWarning, "The offset attribute is not used by IndexSeries."): - IndexSeries( - name='test_iS', - data=[1, 2, 3], - unit='N/A', - indexed_images=images, - timestamps=[0.1, 0.2, 0.3], - offset=1.0 - ) - - class ImageMaskSeriesConstructor(TestCase):