diff --git a/src/pynwb/ndx_microscopy/testing/_mock.py b/src/pynwb/ndx_microscopy/testing/_mock.py index cf1c020..168219b 100644 --- a/src/pynwb/ndx_microscopy/testing/_mock.py +++ b/src/pynwb/ndx_microscopy/testing/_mock.py @@ -382,17 +382,35 @@ def mock_MicroscopyResponseSeries( number_of_rois = len(table_region.data) series_data = data if data is not None else np.ones(shape=(number_of_frames, number_of_rois)) + if timestamps is None: + series_starting_time = starting_time or 0.0 + series_rate = rate or 10.0 + series_timestamps = None + else: + if starting_time is not None or rate is not None: + warnings.warn( + message=( + "Timestamps were provided in addition to either rate or starting_time! " + "Please specify only timestamps, or both starting_time and rate. Timestamps will take precedence." + ), + stacklevel=2, + ) + + series_starting_time = None + series_rate = None + series_timestamps = timestamps + microscopy_response_series = ndx_microscopy.MicroscopyResponseSeries( name=series_name, description=description, table_region=table_region, - data=data, + data=series_data, unit=unit, conversion=conversion, offset=offset, - starting_time=starting_time, - rate=rate, - timestamps=timestamps, + starting_time=series_starting_time, + rate=series_rate, + timestamps=series_timestamps, ) return microscopy_response_series diff --git a/src/pynwb/tests/test_constructors.py b/src/pynwb/tests/test_constructors.py index 419612a..bcbb3cf 100644 --- a/src/pynwb/tests/test_constructors.py +++ b/src/pynwb/tests/test_constructors.py @@ -117,9 +117,11 @@ def test_constructor_microscopy_response_series_container(): table=plane_segmentation, ) - microscopy_response_series = [ndx_microscopy.testing.mock_MicroscopyResponseSeries(table_region=table_region)] + microscopy_response_series = ndx_microscopy.testing.mock_MicroscopyResponseSeries(table_region=table_region) - ndx_microscopy.testing.mock_MicroscopyResponseSeriesContainer(microscopy_response_series=microscopy_response_series) + ndx_microscopy.testing.mock_MicroscopyResponseSeriesContainer( + microscopy_response_series=[microscopy_response_series] + ) def test_constructor_multi_channel_microscopy_volume(): diff --git a/src/pynwb/tests/test_roundtrip.py b/src/pynwb/tests/test_roundtrip.py index a7b1330..8742507 100644 --- a/src/pynwb/tests/test_roundtrip.py +++ b/src/pynwb/tests/test_roundtrip.py @@ -4,20 +4,8 @@ from pynwb.testing import TestCase as pynwb_TestCase from pynwb.testing.mock.file import mock_NWBFile +import ndx_microscopy.testing import pynwb -from ndx_microscopy.testing import ( - mock_Microscope, - mock_MicroscopyLightSource, - mock_MicroscopyOpticalChannel, - mock_MicroscopyPlaneSegmentation, - mock_MicroscopySegmentations, - mock_MultiChannelMicroscopyVolume, - mock_PlanarImagingSpace, - mock_PlanarMicroscopySeries, - mock_VariableDepthMicroscopySeries, - mock_VolumetricImagingSpace, - mock_VolumetricMicroscopySeries, -) class TestPlanarMicroscopySeriesSimpleRoundtrip(pynwb_TestCase): @@ -32,19 +20,19 @@ def tearDown(self): def test_roundtrip(self): nwbfile = mock_NWBFile() - microscope = mock_Microscope(name="Microscope") + microscope = ndx_microscopy.testing.mock_Microscope(name="Microscope") nwbfile.add_device(devices=microscope) - light_source = mock_MicroscopyLightSource(name="MicroscopyLightSource") + light_source = ndx_microscopy.testing.mock_MicroscopyLightSource(name="MicroscopyLightSource") nwbfile.add_device(devices=light_source) - imaging_space = mock_PlanarImagingSpace(name="PlanarImagingSpace", microscope=microscope) + imaging_space = ndx_microscopy.testing.mock_PlanarImagingSpace(name="PlanarImagingSpace", microscope=microscope) nwbfile.add_lab_meta_data(lab_meta_data=imaging_space) # Would prefer .add_imaging_spacec() - optical_channel = mock_MicroscopyOpticalChannel(name="MicroscopyOpticalChannel") + optical_channel = ndx_microscopy.testing.mock_MicroscopyOpticalChannel(name="MicroscopyOpticalChannel") nwbfile.add_lab_meta_data(lab_meta_data=optical_channel) - planar_microscopy_series = mock_PlanarMicroscopySeries( + planar_microscopy_series = ndx_microscopy.testing.mock_PlanarMicroscopySeries( name="PlanarMicroscopySeries", microscope=microscope, light_source=light_source, @@ -80,19 +68,21 @@ def tearDown(self): def test_roundtrip(self): nwbfile = mock_NWBFile() - microscope = mock_Microscope(name="Microscope") + microscope = ndx_microscopy.testing.mock_Microscope(name="Microscope") nwbfile.add_device(devices=microscope) - light_source = mock_MicroscopyLightSource(name="MicroscopyLightSource") + light_source = ndx_microscopy.testing.mock_MicroscopyLightSource(name="MicroscopyLightSource") nwbfile.add_device(devices=light_source) - imaging_space = mock_VolumetricImagingSpace(name="VolumetricImagingSpace", microscope=microscope) + imaging_space = ndx_microscopy.testing.mock_VolumetricImagingSpace( + name="VolumetricImagingSpace", microscope=microscope + ) nwbfile.add_lab_meta_data(lab_meta_data=imaging_space) # Would prefer .add_imaging_spacec() - optical_channel = mock_MicroscopyOpticalChannel(name="MicroscopyOpticalChannel") + optical_channel = ndx_microscopy.testing.mock_MicroscopyOpticalChannel(name="MicroscopyOpticalChannel") nwbfile.add_lab_meta_data(lab_meta_data=optical_channel) - volumetric_microscopy_series = mock_VolumetricMicroscopySeries( + volumetric_microscopy_series = ndx_microscopy.testing.mock_VolumetricMicroscopySeries( name="VolumetricMicroscopySeries", microscope=microscope, light_source=light_source, @@ -130,19 +120,19 @@ def tearDown(self): def test_roundtrip(self): nwbfile = mock_NWBFile() - microscope = mock_Microscope(name="Microscope") + microscope = ndx_microscopy.testing.mock_Microscope(name="Microscope") nwbfile.add_device(devices=microscope) - light_source = mock_MicroscopyLightSource(name="MicroscopyLightSource") + light_source = ndx_microscopy.testing.mock_MicroscopyLightSource(name="MicroscopyLightSource") nwbfile.add_device(devices=light_source) - imaging_space = mock_PlanarImagingSpace(name="PlanarImagingSpace", microscope=microscope) + imaging_space = ndx_microscopy.testing.mock_PlanarImagingSpace(name="PlanarImagingSpace", microscope=microscope) nwbfile.add_lab_meta_data(lab_meta_data=imaging_space) # Would prefer .add_imaging_space() - optical_channel = mock_MicroscopyOpticalChannel(name="MicroscopyOpticalChannel") + optical_channel = ndx_microscopy.testing.mock_MicroscopyOpticalChannel(name="MicroscopyOpticalChannel") nwbfile.add_lab_meta_data(lab_meta_data=optical_channel) - variable_depth_microscopy_series = mock_VariableDepthMicroscopySeries( + variable_depth_microscopy_series = ndx_microscopy.testing.mock_VariableDepthMicroscopySeries( name="VariableDepthMicroscopySeries", microscope=microscope, light_source=light_source, @@ -180,19 +170,21 @@ def tearDown(self): def test_roundtrip(self): nwbfile = mock_NWBFile() - microscope = mock_Microscope(name="Microscope") + microscope = ndx_microscopy.testing.mock_Microscope(name="Microscope") nwbfile.add_device(devices=microscope) - imaging_space = mock_VolumetricImagingSpace(name="VolumetricImagingSpace", microscope=microscope) + imaging_space = ndx_microscopy.testing.mock_VolumetricImagingSpace( + name="VolumetricImagingSpace", microscope=microscope + ) nwbfile.add_lab_meta_data(lab_meta_data=imaging_space) # Would prefer .add_imaging_space() light_sources = list() - light_source_0 = mock_MicroscopyLightSource(name="LightSource") + light_source_0 = ndx_microscopy.testing.mock_MicroscopyLightSource(name="LightSource") nwbfile.add_device(devices=light_source_0) light_sources.append(light_source_0) optical_channels = list() - optical_channel_0 = mock_MicroscopyOpticalChannel(name="MicroscopyOpticalChannel") + optical_channel_0 = ndx_microscopy.testing.mock_MicroscopyOpticalChannel(name="MicroscopyOpticalChannel") nwbfile.add_lab_meta_data(lab_meta_data=optical_channel_0) optical_channels.append(optical_channel_0) @@ -209,7 +201,7 @@ def test_roundtrip(self): ), data=optical_channels, ) - multi_channel_microscopy_volume = mock_MultiChannelMicroscopyVolume( + multi_channel_microscopy_volume = ndx_microscopy.testing.mock_MultiChannelMicroscopyVolume( name="MultiChannelMicroscopyVolume", microscope=microscope, imaging_space=imaging_space, @@ -247,21 +239,21 @@ def tearDown(self): def test_roundtrip(self): nwbfile = mock_NWBFile() - microscope = mock_Microscope(name="Microscope") + microscope = ndx_microscopy.testing.mock_Microscope(name="Microscope") nwbfile.add_device(devices=microscope) - imaging_space = mock_PlanarImagingSpace(name="PlanarImagingSpace", microscope=microscope) + imaging_space = ndx_microscopy.testing.mock_PlanarImagingSpace(name="PlanarImagingSpace", microscope=microscope) nwbfile.add_lab_meta_data(lab_meta_data=imaging_space) # Would prefer .add_imaging_space() - plane_segmentation_1 = mock_MicroscopyPlaneSegmentation( + plane_segmentation_1 = ndx_microscopy.testing.mock_MicroscopyPlaneSegmentation( imaging_space=imaging_space, name="MicroscopyPlaneSegmentation1" ) - plane_segmentation_2 = mock_MicroscopyPlaneSegmentation( + plane_segmentation_2 = ndx_microscopy.testing.mock_MicroscopyPlaneSegmentation( imaging_space=imaging_space, name="MicroscopyPlaneSegmentation2" ) microscopy_plane_segmentations = [plane_segmentation_1, plane_segmentation_2] - segmentations = mock_MicroscopySegmentations( + segmentations = ndx_microscopy.testing.mock_MicroscopySegmentations( name="MicroscopySegmentations", microscopy_plane_segmentations=microscopy_plane_segmentations ) processing_module = nwbfile.create_processing_module(name="ophys", description="") @@ -280,7 +272,60 @@ def test_roundtrip(self): self.assertContainerEqual(segmentations, read_nwbfile.processing["ophys"]["MicroscopySegmentations"]) -# TODO: add roundtrip test for MicroscopyResponseSeries +class TestMicroscopyResponseSeriesSimpleRoundtrip(pynwb_TestCase): + """Simple roundtrip test for MicroscopyResponseSeries.""" + + def setUp(self): + self.nwbfile_path = "test_microscopy_response_series_roundtrip.nwb" + + def tearDown(self): + pynwb.testing.remove_test_file(self.nwbfile_path) + + def test_roundtrip(self): + nwbfile = mock_NWBFile() + + ophys_module = nwbfile.create_processing_module(name="ophys", description="Optical neurophysiology data.") + + microscope = ndx_microscopy.testing.mock_Microscope(name="Microscope") + nwbfile.add_device(devices=microscope) + + imaging_space = ndx_microscopy.testing.mock_PlanarImagingSpace(device=device) + nwbfile.add_lab_meta_data(lab_meta_data=imaging_space) # Would prefer .add_imaging_space() + + plane_segmentation = ndx_microscopy.testing.mock_MicroscopyPlaneSegmentation( + name="MicroscopyPlaneSegmentation", imaging_space=imaging_space + ) + ophys_module.add(plane_segmentation) + + number_of_rois = 10 + plane_segmentation_region = pynwb.ophys.DynamicTableRegion( + name="table_region", # Name must be exactly this + description="", + data=[x for x in range(number_of_rois)], + table=plane_segmentation, + ) + microscopy_response_series = ndx_microscopy.testing.mock_MicroscopyResponseSeries( + name="MicroscopyResponseSeries", + table_region=plane_segmentation_region, + ) + + container = ndx_microscopy.MicroscopyResponseSeriesContainer( + name="MicroscopyResponseSeriesContainer", microscopy_response_series=[microscopy_response_series] + ) + + with pynwb.NWBHDF5IO(path=self.nwbfile_path, mode="w") as io: + io.write(nwbfile) + + with pynwb.NWBHDF5IO(path=self.nwbfile_path, mode="r", load_namespaces=True) as io: + read_nwbfile = io.read() + + self.assertContainerEqual(microscope, read_nwbfile.devices["Microscope"]) + + self.assertContainerEqual(imaging_space, read_nwbfile.lab_meta_data["PlanarImagingSpace"]) + + self.assertContainerEqual(segmentations, read_nwbfile.processing["ophys"]["MicroscopySegmentations"]) + + self.assertContainerEqual(container, read_nwbfile.processing["ophys"]["MicroscopyResponseSeriesContainer"]) if __name__ == "__main__":