From 889b33a05d28f59dbf5b907681ffa7bdfea9fcf5 Mon Sep 17 00:00:00 2001 From: alessandratrapani Date: Mon, 26 Aug 2024 16:57:28 +0200 Subject: [PATCH 1/5] add object from ndx-ophys-devices --- spec/ndx-microscopy.extensions.yaml | 126 +++++++++++---------------- spec/ndx-microscopy.namespace.yaml | 1 + src/pynwb/ndx_microscopy/__init__.py | 17 ++-- 3 files changed, 63 insertions(+), 81 deletions(-) diff --git a/spec/ndx-microscopy.extensions.yaml b/spec/ndx-microscopy.extensions.yaml index 118a9da..9312b3b 100644 --- a/spec/ndx-microscopy.extensions.yaml +++ b/spec/ndx-microscopy.extensions.yaml @@ -6,67 +6,45 @@ groups: attributes: - name: model dtype: text - doc: Model identifier of the light source device. + doc: Model identifier of the microscope. required: false - - neurodata_type_def: MicroscopyLightSource - neurodata_type_inc: Device - doc: Light source used to illuminate an imaging space. + - neurodata_type_def: ExcitationLightPath + neurodata_type_inc: NWBContainer + doc: Excitation light path that illuminates an imaging space. attributes: - - name: model - dtype: text - doc: Model identifier of the light source device. - required: false - - name: filter_description - dtype: text - doc: Filter used to obtain the excitation wavelength of light, e.g. 'Short pass at 1040 nm'. - required: false - name: excitation_wavelength_in_nm dtype: numeric doc: Excitation wavelength of light, in nanometers. + links: + - name: excitation_source + target_type: ExcitationSource + doc: Link to ExcitationSource object which contains metadata about the excitation source device. If it is a pulsed excitation source link a PulsedExcitationSource object. required: false - - name: peak_power_in_W - dtype: numeric - doc: Incident power of stimulation device (in Watts). - required: false - - name: peak_pulse_energy_in_J - dtype: numeric - doc: If device is pulsed light source, pulse energy (in Joules). - required: false - - name: intensity_in_W_per_m2 - dtype: numeric - doc: Intensity of the excitation in W/m^2, if known. + - name: excitation_filter + target_type: OpticalFilter + doc: Link to OpticalFilter object which contains metadata about the optical filter in this excitation light path. It can be either a BandOpticalFilter (e.g., 'Bandpass', 'Bandstop', 'Longpass', 'Shortpass') or a EdgeOpticalFilter (Longpass or Shortpass). required: false - - name: exposure_time_in_s + + - neurodata_type_def: EmissionLightPath + neurodata_type_inc: NWBContainer + doc: Emission light path from an imaging space. + attributes: + - name: emission_wavelength_in_nm dtype: numeric - doc: Exposure time of the sample (in sec). + doc: Emission wavelength of light, in nanometers. + links: + - name: photodetector + target_type: Photodetector + doc: Link to Photodetector object which contains metadata about the photodetector device. required: false - - name: pulse_rate_in_Hz - dtype: numeric - doc: If device is pulsed light source, pulse rate (in Hz) used for stimulation. + - name: emission_filter + target_type: OpticalFilter + doc: Link to OpticalFilter object which contains metadata about the optical filter in this emission light path. It can be either a BandOpticalFilter (e.g., 'Bandpass', 'Bandstop', 'Longpass', 'Shortpass') or a EdgeOpticalFilter (Longpass or Shortpass). required: false - - # Microscopy is added on to this only to differentiate from the OpticalChannel in the core namespace - # It would be removed when this structure is merged to core - - neurodata_type_def: MicroscopyOpticalChannel - neurodata_type_inc: LabMetaData # Would prefer basic NWBContainer - doc: An optical channel used to filter light emission from an imaging space. - datasets: - - name: description - doc: Description or other notes about the channel. - dtype: text - attributes: - - name: indicator - doc: Identifier for the indicator pertaining to this optical channel. - dtype: text - - name: filter_description - doc: Metadata information about the filter used by this optical channel. - dtype: text - required: false - - name: emission_wavelength_in_nm - doc: Emission wavelength for this optical channel, in nanometers. - dtype: numeric - required: false + - name: indicator + target_type: Indicator + doc: Link to Indicator object which contains metadata about the indicator used in this light path. - neurodata_type_def: ImagingSpace neurodata_type_inc: LabMetaData # Would prefer basic NWBContainer @@ -97,10 +75,6 @@ groups: Use standard atlas names for anatomical regions when possible. Specify 'whole brain' if the entire brain is strictly contained within the space. required: false - links: - - name: microscope - target_type: Microscope - doc: Link to Microscope object which contains metadata about the device which imaged this space. - neurodata_type_def: PlanarImagingSpace neurodata_type_inc: ImagingSpace @@ -273,13 +247,13 @@ groups: - name: microscope doc: Link to a Microscope object containing metadata about the device used to acquire this imaging data. target_type: Microscope - - name: light_source - doc: Link to a MicroscopyLightSource object containing metadata about the device used to illuminate the imaging space. - target_type: MicroscopyLightSource - - name: optical_channel - doc: Link to a MicroscopyOpticalChannel object containing metadata about the indicator and filters used to collect + - name: excitation_light_path + doc: Link to a ExcitationLightPath object containing metadata about the device used to illuminate the imaging space. + target_type: ExcitationLightPath + - name: emission_light_path + doc: Link to a EmissionLightPath object containing metadata about the indicator and filters used to collect this data. - target_type: MicroscopyOpticalChannel + target_type: EmissionLightPath - neurodata_type_def: PlanarMicroscopySeries neurodata_type_inc: MicroscopySeries @@ -392,24 +366,24 @@ groups: - null - null - null - - name: light_sources - doc: An ordered list of references to MicroscopyLightSource objects containing metadata about the excitation methods. + - name: excitation_light_paths + doc: An ordered list of references to ExcitationLightPath objects containing metadata about the excitation methods. neurodata_type_inc: VectorData dtype: reftype: object - target_type: MicroscopyLightSource + target_type: ExcitationLightPath dims: - - light_sources + - excitation_light_paths shape: - null - - name: optical_channels - doc: An ordered list of references to MicroscopyOpticalChannel objects containing metadata about the indicator and filters used to collect this data. This maps to the last dimension of `data`, i.e., the i-th MicroscopyOpticalChannel contains metadata about the indicator and filters used to collect the volume at `data[:,:,:,i]`. + - name: emission_light_paths + doc: An ordered list of references to EmissionLightPath objects containing metadata about the indicator and filters used to collect this data. This maps to the last dimension of `data`, i.e., the i-th MicroscopyOpticalChannel contains metadata about the indicator and filters used to collect the volume at `data[:,:,:,i]`. neurodata_type_inc: VectorData dtype: reftype: object - target_type: MicroscopyOpticalChannel + target_type: EmissionLightPath dims: - - optical_channels + - emission_light_paths shape: - null links: @@ -478,24 +452,24 @@ groups: - depths shape: - null - - name: light_sources - doc: An ordered list of references to MicroscopyLightSource objects containing metadata about the excitation methods. + - name: excitation_light_paths + doc: An ordered list of references to ExcitationLightPath objects containing metadata about the excitation methods. neurodata_type_inc: VectorData dtype: reftype: object - target_type: MicroscopyLightSource + target_type: ExcitationLightPath dims: - - light_sources + - excitation_light_paths shape: - null - - name: optical_channels - doc: An ordered list of references to MicroscopyOpticalChannel objects containing metadata about the indicator and filters used to collect this data. This maps to the last dimension of `data`, i.e., the i-th MicroscopyOpticalChannel contains metadata about the indicator and filters used to collect the volume at `data[:,:,:,i]`. + - name: emission_light_paths + doc: An ordered list of references to EmissionLightPath objects containing metadata about the indicator and filters used to collect this data. This maps to the last dimension of `data`, i.e., the i-th MicroscopyOpticalChannel contains metadata about the indicator and filters used to collect the volume at `data[:,:,:,i]`. neurodata_type_inc: VectorData dtype: reftype: object - target_type: MicroscopyOpticalChannel + target_type: EmissionLightPath dims: - - optical_channels + - emission_light_paths shape: - null links: diff --git a/spec/ndx-microscopy.namespace.yaml b/spec/ndx-microscopy.namespace.yaml index 8399608..75bf1c6 100644 --- a/spec/ndx-microscopy.namespace.yaml +++ b/spec/ndx-microscopy.namespace.yaml @@ -9,5 +9,6 @@ namespaces: - alessandra.trapani@catalystneuro.com schema: - namespace: core + - namespace: ndx-ophys-devices - source: ndx-microscopy.extensions.yaml version: 0.1.0 diff --git a/src/pynwb/ndx_microscopy/__init__.py b/src/pynwb/ndx_microscopy/__init__.py index 8dfeac9..1351b27 100644 --- a/src/pynwb/ndx_microscopy/__init__.py +++ b/src/pynwb/ndx_microscopy/__init__.py @@ -19,10 +19,15 @@ __spec_path = __location_of_this_file.parent.parent.parent / "spec" / f"{extension_name}.namespace.yaml" load_namespaces(str(__spec_path)) - +from ndx_ophys_devices import ( + OpticalFilter, + ExcitationSource, + Indicator, + Photodetector, +) Microscope = get_class("Microscope", extension_name) -MicroscopyLightSource = get_class("MicroscopyLightSource", extension_name) -MicroscopyOpticalChannel = get_class("MicroscopyOpticalChannel", extension_name) +ExcitationLightPath = get_class("ExcitationLightPath", extension_name) +EmissionLightPath = get_class("EmissionLightPath", extension_name) ImagingSpace = get_class("ImagingSpace", extension_name) PlanarImagingSpace = get_class("PlanarImagingSpace", extension_name) VolumetricImagingSpace = get_class("VolumetricImagingSpace", extension_name) @@ -36,9 +41,11 @@ VariableDepthMultiChannelMicroscopyVolume = get_class("VariableDepthMultiChannelMicroscopyVolume", extension_name) __all__ = [ + "OpticalFilter", + "ExcitationSource", + "Indicator", + "Photodetector", "Microscope", - "MicroscopyLightSource", - "MicroscopyOpticalChannel", "ImagingSpace", "PlanarImagingSpace", "VolumetricImagingSpace", From ceebfa6ff2b2423e9b7f171ee41ad221f25e1910 Mon Sep 17 00:00:00 2001 From: alessandratrapani Date: Mon, 26 Aug 2024 16:57:41 +0200 Subject: [PATCH 2/5] add tests --- src/pynwb/ndx_microscopy/testing/__init__.py | 8 +- src/pynwb/ndx_microscopy/testing/_mock.py | 114 +++++++++---------- src/pynwb/tests/test_constructors.py | 92 +++++++-------- src/pynwb/tests/test_roundtrip.py | 86 +++++++------- 4 files changed, 144 insertions(+), 156 deletions(-) diff --git a/src/pynwb/ndx_microscopy/testing/__init__.py b/src/pynwb/ndx_microscopy/testing/__init__.py index e27103f..9b7679e 100644 --- a/src/pynwb/ndx_microscopy/testing/__init__.py +++ b/src/pynwb/ndx_microscopy/testing/__init__.py @@ -1,7 +1,7 @@ from ._mock import ( mock_Microscope, - mock_MicroscopyLightSource, - mock_MicroscopyOpticalChannel, + mock_ExcitationLightPath, + mock_EmissionLightPath, mock_MicroscopyPlaneSegmentation, mock_MicroscopySegmentations, mock_MultiChannelMicroscopyVolume, @@ -15,8 +15,8 @@ __all__ = [ "mock_Microscope", - "mock_MicroscopyLightSource", - "mock_MicroscopyOpticalChannel", + "mock_ExcitationLightPath", + "mock_EmissionLightPath", "mock_PlanarImagingSpace", "mock_VolumetricImagingSpace", "mock_MicroscopySegmentations", diff --git a/src/pynwb/ndx_microscopy/testing/_mock.py b/src/pynwb/ndx_microscopy/testing/_mock.py index 862889d..47b4a64 100644 --- a/src/pynwb/ndx_microscopy/testing/_mock.py +++ b/src/pynwb/ndx_microscopy/testing/_mock.py @@ -7,6 +7,18 @@ import ndx_microscopy +from ndx_ophys_devices import ( + OpticalFilter, + ExcitationSource, + Indicator, + Photodetector, +) +from ndx_ophys_devices.testing import ( + mock_Indicator, + mock_Photodetector, + mock_OpticalFilter, + mock_ExcitationSource, +) def mock_Microscope( *, @@ -24,57 +36,46 @@ def mock_Microscope( return microscope -def mock_MicroscopyLightSource( +def mock_ExcitationLightPath( *, name: Optional[str] = None, - description: str = "This is a mock instance of a MicroscopyLightSource type to be used for rapid testing.", - manufacturer: str = "A fake manufacturer of the mock light source.", - model: str = "A fake model of the mock light source.", - filter_description: str = "A description about the fake filter used by the mock light source.", + description: str = "This is a mock instance of a ExcitationLightPath type to be used for rapid testing.", excitation_wavelength_in_nm: float = 500.0, - peak_power_in_W: float = 0.7, - peak_pulse_energy_in_J: float = 0.7, - intensity_in_W_per_m2: float = 0.005, - exposure_time_in_s: float = 2.51e-13, - pulse_rate_in_Hz: float = 2.0e6, -) -> ndx_microscopy.MicroscopyLightSource: - light_source = ndx_microscopy.MicroscopyLightSource( - name=name or name_generator("MicroscopyLightSource"), + excitation_source: ExcitationSource = None, + excitation_filter: OpticalFilter = None, +) -> ndx_microscopy.ExcitationLightPath: + excitation_light_path = ndx_microscopy.ExcitationLightPath( + name=name or name_generator("ExcitationLightPath"), description=description, - manufacturer=manufacturer, - model=model, - filter_description=filter_description, excitation_wavelength_in_nm=excitation_wavelength_in_nm, - peak_power_in_W=peak_power_in_W, - peak_pulse_energy_in_J=peak_pulse_energy_in_J, - intensity_in_W_per_m2=intensity_in_W_per_m2, - exposure_time_in_s=exposure_time_in_s, - pulse_rate_in_Hz=pulse_rate_in_Hz, + excitation_source=excitation_source or mock_ExcitationSource(), + excitation_filter=excitation_filter or mock_OpticalFilter(), ) - return light_source + return excitation_light_path -def mock_MicroscopyOpticalChannel( +def mock_EmissionLightPath( *, name: Optional[str] = None, - description: str = "This is a mock instance of a MicroscopyOpticalChannel type to be used for rapid testing.", - indicator: str = "The indicator targeted by the mock optical channel.", - filter_description: str = "A description about the fake filter used by the mock optical channel.", + description: str = "This is a mock instance of a EmissionLightPath type to be used for rapid testing.", + indicator: Indicator = None, + photodetector: Photodetector = None, + emission_filter: OpticalFilter = None, emission_wavelength_in_nm: float = 450.0, -) -> ndx_microscopy.MicroscopyOpticalChannel: - optical_channel = ndx_microscopy.MicroscopyOpticalChannel( - name=name or name_generator("MicroscopyOpticalChannel"), +) -> ndx_microscopy.EmissionLightPath: + emission_light_path = ndx_microscopy.EmissionLightPath( + name=name or name_generator("EmissionLightPath"), description=description, - indicator=indicator, - filter_description=filter_description, + indicator=indicator or mock_Indicator(), + photodetector=photodetector or mock_Photodetector(), + emission_filter=emission_filter or mock_OpticalFilter(), emission_wavelength_in_nm=emission_wavelength_in_nm, ) - return optical_channel + return emission_light_path def mock_PlanarImagingSpace( *, - microscope: ndx_microscopy.Microscope, name: Optional[str] = None, description: str = "This is a mock instance of a PlanarImagingSpace type to be used for rapid testing.", origin_coordinates: Tuple[float, float, float] = (-1.2, -0.6, -2), @@ -85,7 +86,6 @@ def mock_PlanarImagingSpace( planar_imaging_space = ndx_microscopy.PlanarImagingSpace( name=name or name_generator("PlanarImagingSpace"), description=description, - microscope=microscope, origin_coordinates=origin_coordinates, grid_spacing_in_um=grid_spacing_in_um, location=location, @@ -96,7 +96,6 @@ def mock_PlanarImagingSpace( def mock_VolumetricImagingSpace( *, - microscope: ndx_microscopy.Microscope, name: Optional[str] = None, description: str = "This is a mock instance of a VolumetricImagingSpace type to be used for rapid testing.", origin_coordinates: Tuple[float, float, float] = (-1.2, -0.6, -2), @@ -107,7 +106,6 @@ def mock_VolumetricImagingSpace( volumetric_imaging_space = ndx_microscopy.VolumetricImagingSpace( name=name or name_generator("VolumetricImagingSpace"), description=description, - microscope=microscope, origin_coordinates=origin_coordinates, grid_spacing_in_um=grid_spacing_in_um, location=location, @@ -122,9 +120,7 @@ def mock_MicroscopySegmentations( microscopy_plane_segmentations: Optional[Iterable[ndx_microscopy.MicroscopyPlaneSegmentation]] = None, ) -> ndx_microscopy.MicroscopySegmentations: name = name or name_generator("MicroscopySegmentations") - - microscope = mock_Microscope() - imaging_space = mock_PlanarImagingSpace(microscope=microscope) + imaging_space = mock_PlanarImagingSpace() microscopy_plane_segmentations = microscopy_plane_segmentations or [ mock_MicroscopyPlaneSegmentation(imaging_space=imaging_space) ] @@ -162,9 +158,9 @@ def mock_MicroscopyPlaneSegmentation( def mock_PlanarMicroscopySeries( *, microscope: ndx_microscopy.Microscope, - light_source: ndx_microscopy.MicroscopyLightSource, + excitation_light_path: ndx_microscopy.ExcitationLightPath, imaging_space: ndx_microscopy.PlanarImagingSpace, - optical_channel: ndx_microscopy.MicroscopyOpticalChannel, + emission_light_path: ndx_microscopy.EmissionLightPath, name: Optional[str] = None, description: str = "This is a mock instance of a PlanarMicroscopySeries type to be used for rapid testing.", data: Optional[np.ndarray] = None, @@ -200,9 +196,9 @@ def mock_PlanarMicroscopySeries( name=series_name, description=description, microscope=microscope, - light_source=light_source, + excitation_light_path=excitation_light_path, imaging_space=imaging_space, - optical_channel=optical_channel, + emission_light_path=emission_light_path, data=series_data, unit=unit, conversion=conversion, @@ -217,9 +213,9 @@ def mock_PlanarMicroscopySeries( def mock_VariableDepthMicroscopySeries( *, microscope: ndx_microscopy.Microscope, - light_source: ndx_microscopy.MicroscopyLightSource, + excitation_light_path: ndx_microscopy.ExcitationLightPath, imaging_space: ndx_microscopy.PlanarImagingSpace, - optical_channel: ndx_microscopy.MicroscopyOpticalChannel, + emission_light_path: ndx_microscopy.EmissionLightPath, name: Optional[str] = None, description: str = "This is a mock instance of a PlanarMicroscopySeries type to be used for rapid testing.", data: Optional[np.ndarray] = None, @@ -262,9 +258,9 @@ def mock_VariableDepthMicroscopySeries( name=series_name, description=description, microscope=microscope, - light_source=light_source, + excitation_light_path=excitation_light_path, imaging_space=imaging_space, - optical_channel=optical_channel, + emission_light_path=emission_light_path, data=series_data, depth_per_frame_in_um=depth_per_frame_in_um, unit=unit, @@ -280,9 +276,9 @@ def mock_VariableDepthMicroscopySeries( def mock_VolumetricMicroscopySeries( *, microscope: ndx_microscopy.Microscope, - light_source: ndx_microscopy.MicroscopyLightSource, + excitation_light_path: ndx_microscopy.ExcitationLightPath, imaging_space: ndx_microscopy.VolumetricImagingSpace, - optical_channel: ndx_microscopy.MicroscopyOpticalChannel, + emission_light_path: ndx_microscopy.EmissionLightPath, name: Optional[str] = None, description: str = "This is a mock instance of a VolumetricMicroscopySeries type to be used for rapid testing.", data: Optional[np.ndarray] = None, @@ -318,9 +314,9 @@ def mock_VolumetricMicroscopySeries( name=series_name, description=description, microscope=microscope, - light_source=light_source, + excitation_light_path=excitation_light_path, imaging_space=imaging_space, - optical_channel=optical_channel, + emission_light_path=emission_light_path, data=series_data, unit=unit, conversion=conversion, @@ -336,8 +332,8 @@ def mock_MultiChannelMicroscopyVolume( *, microscope: ndx_microscopy.Microscope, imaging_space: ndx_microscopy.VolumetricImagingSpace, - light_sources: pynwb.base.VectorData, - optical_channels: pynwb.base.VectorData, + excitation_light_paths: pynwb.base.VectorData, + emission_light_paths: pynwb.base.VectorData, name: Optional[str] = None, description: str = "This is a mock instance of a MultiChannelMicroscopyVolume type to be used for rapid testing.", data: Optional[np.ndarray] = None, @@ -353,8 +349,8 @@ def mock_MultiChannelMicroscopyVolume( description=description, microscope=microscope, imaging_space=imaging_space, - light_sources=light_sources, - optical_channels=optical_channels, + excitation_light_paths=excitation_light_paths, + emission_light_paths=emission_light_paths, data=imaging_data, unit=unit, conversion=conversion, @@ -367,8 +363,8 @@ def mock_VariableDepthMultiChannelMicroscopyVolume( *, microscope: ndx_microscopy.Microscope, imaging_space: ndx_microscopy.VolumetricImagingSpace, - light_sources: pynwb.base.VectorData, - optical_channels: pynwb.base.VectorData, + excitation_light_paths: pynwb.base.VectorData, + emission_light_paths: pynwb.base.VectorData, name: Optional[str] = None, description: str = "This is a mock instance of a MultiChannelMicroscopyVolume type to be used for rapid testing.", data: Optional[np.ndarray] = None, @@ -393,8 +389,8 @@ def mock_VariableDepthMultiChannelMicroscopyVolume( description=description, microscope=microscope, imaging_space=imaging_space, - light_sources=light_sources, - optical_channels=optical_channels, + excitation_light_paths=excitation_light_paths, + emission_light_paths=emission_light_paths, data=imaging_data, depth_per_frame_in_um=volume_depth_per_frame_in_um, unit=unit, diff --git a/src/pynwb/tests/test_constructors.py b/src/pynwb/tests/test_constructors.py index f5c29aa..3935c0d 100644 --- a/src/pynwb/tests/test_constructors.py +++ b/src/pynwb/tests/test_constructors.py @@ -5,8 +5,8 @@ import pynwb from ndx_microscopy.testing import ( mock_Microscope, - mock_MicroscopyLightSource, - mock_MicroscopyOpticalChannel, + mock_ExcitationLightPath, + mock_EmissionLightPath, mock_MicroscopyPlaneSegmentation, mock_MicroscopySegmentations, mock_MultiChannelMicroscopyVolume, @@ -23,24 +23,20 @@ def test_constructor_microscope(): mock_Microscope() -def test_constructor_light_source(): - mock_MicroscopyLightSource() +def test_constructor_excitation_light_path(): + mock_ExcitationLightPath() -def test_constructor_microscopy_optical_channel(): - mock_MicroscopyOpticalChannel() +def test_constructor_microscopy_emission_light_path(): + mock_EmissionLightPath() def test_constructor_planar_image_space(): - microscope = mock_Microscope() - - mock_PlanarImagingSpace(microscope=microscope) + mock_PlanarImagingSpace() def test_constructor_volumetric_image_space(): - microscope = mock_Microscope() - - mock_VolumetricImagingSpace(microscope=microscope) + mock_VolumetricImagingSpace() def test_constructor_microscopy_segmentations(): @@ -48,16 +44,12 @@ def test_constructor_microscopy_segmentations(): def test_constructor_microscopy_plane_segmentation(): - microscope = mock_Microscope() - imaging_space = mock_PlanarImagingSpace(microscope=microscope) - + imaging_space = mock_PlanarImagingSpace() mock_MicroscopyPlaneSegmentation(imaging_space=imaging_space) def test_constructor_microscopy_image_segmentation_with_plane_segmentation(): - microscope = mock_Microscope() - imaging_space = mock_PlanarImagingSpace(microscope=microscope) - + imaging_space = mock_PlanarImagingSpace() plane_segmentation_1 = mock_MicroscopyPlaneSegmentation( imaging_space=imaging_space, name="MicroscopyPlaneSegmentation1" ) @@ -71,84 +63,84 @@ def test_constructor_microscopy_image_segmentation_with_plane_segmentation(): def test_constructor_planar_microscopy_series(): microscope = mock_Microscope() - light_source = mock_MicroscopyLightSource() - imaging_space = mock_PlanarImagingSpace(microscope=microscope) - optical_channel = mock_MicroscopyOpticalChannel() + excitation_light_path = mock_ExcitationLightPath() + imaging_space = mock_PlanarImagingSpace() + emission_light_path = mock_EmissionLightPath() mock_PlanarMicroscopySeries( - microscope=microscope, light_source=light_source, imaging_space=imaging_space, optical_channel=optical_channel + microscope=microscope, excitation_light_path=excitation_light_path, imaging_space=imaging_space, emission_light_path=emission_light_path ) def test_constructor_variable_depth_microscopy_series(): microscope = mock_Microscope() - light_source = mock_MicroscopyLightSource() - imaging_space = mock_PlanarImagingSpace(microscope=microscope) - optical_channel = mock_MicroscopyOpticalChannel() + excitation_light_path = mock_ExcitationLightPath() + imaging_space = mock_PlanarImagingSpace() + emission_light_path = mock_EmissionLightPath() mock_VariableDepthMicroscopySeries( - microscope=microscope, light_source=light_source, imaging_space=imaging_space, optical_channel=optical_channel + microscope=microscope, excitation_light_path=excitation_light_path, imaging_space=imaging_space, emission_light_path=emission_light_path ) def test_constructor_volumetric_microscopy_series(): microscope = mock_Microscope() - light_source = mock_MicroscopyLightSource() - imaging_space = mock_VolumetricImagingSpace(microscope=microscope) - optical_channel = mock_MicroscopyOpticalChannel() + excitation_light_path = mock_ExcitationLightPath() + imaging_space = mock_VolumetricImagingSpace() + emission_light_path = mock_EmissionLightPath() mock_VolumetricMicroscopySeries( - microscope=microscope, light_source=light_source, imaging_space=imaging_space, optical_channel=optical_channel + microscope=microscope, excitation_light_path=excitation_light_path, imaging_space=imaging_space, emission_light_path=emission_light_path ) def test_constructor_multi_channel_microscopy_volume(): microscope = mock_Microscope() - imaging_space = mock_VolumetricImagingSpace(microscope=microscope) - light_sources = [mock_MicroscopyLightSource()] - optical_channels = [mock_MicroscopyOpticalChannel()] + imaging_space = mock_VolumetricImagingSpace() + excitation_light_paths = [mock_ExcitationLightPath()] + emission_light_paths = [mock_EmissionLightPath()] - light_sources_used_by_volume = pynwb.base.VectorData( - name="light_sources", description="Light sources used by this MultiChannelVolume.", data=light_sources + excitation_light_paths_used_by_volume = pynwb.base.VectorData( + name="excitation_light_paths", description="Light sources used by this MultiChannelVolume.", data=excitation_light_paths ) - optical_channels_used_by_volume = pynwb.base.VectorData( - name="optical_channels", + emission_light_paths_used_by_volume = pynwb.base.VectorData( + name="emission_light_paths", description=( "Optical channels ordered to correspond to the third axis (e.g., [0, 0, :, 0]) " "of the data for this MultiChannelVolume." ), - data=optical_channels, + data=emission_light_paths, ) mock_MultiChannelMicroscopyVolume( microscope=microscope, imaging_space=imaging_space, - light_sources=light_sources_used_by_volume, - optical_channels=optical_channels_used_by_volume, + excitation_light_paths=excitation_light_paths_used_by_volume, + emission_light_paths=emission_light_paths_used_by_volume, ) def test_constructor_variable_depth_multi_channel_microscopy_volume(): microscope = mock_Microscope() - imaging_space = mock_VolumetricImagingSpace(microscope=microscope) - light_sources = [mock_MicroscopyLightSource()] - optical_channels = [mock_MicroscopyOpticalChannel()] + imaging_space = mock_VolumetricImagingSpace() + excitation_light_paths = [mock_ExcitationLightPath()] + emission_light_paths = [mock_EmissionLightPath()] - light_sources_used_by_volume = pynwb.base.VectorData( - name="light_sources", description="Light sources used by this MultiChannelVolume.", data=light_sources + excitation_light_paths_used_by_volume = pynwb.base.VectorData( + name="excitation_light_paths", description="Light sources used by this MultiChannelVolume.", data=excitation_light_paths ) - optical_channels_used_by_volume = pynwb.base.VectorData( - name="optical_channels", + emission_light_paths_used_by_volume = pynwb.base.VectorData( + name="emission_light_paths", description=( "Optical channels ordered to correspond to the third axis (e.g., [0, 0, :, 0]) " "of the data for this MultiChannelVolume." ), - data=optical_channels, + data=emission_light_paths, ) mock_VariableDepthMultiChannelMicroscopyVolume( microscope=microscope, imaging_space=imaging_space, - light_sources=light_sources_used_by_volume, - optical_channels=optical_channels_used_by_volume, + excitation_light_paths=excitation_light_paths_used_by_volume, + emission_light_paths=emission_light_paths_used_by_volume, ) diff --git a/src/pynwb/tests/test_roundtrip.py b/src/pynwb/tests/test_roundtrip.py index 4d9f830..fe5d512 100644 --- a/src/pynwb/tests/test_roundtrip.py +++ b/src/pynwb/tests/test_roundtrip.py @@ -7,8 +7,8 @@ import pynwb from ndx_microscopy.testing import ( mock_Microscope, - mock_MicroscopyLightSource, - mock_MicroscopyOpticalChannel, + mock_ExcitationLightPath, + mock_EmissionLightPath, mock_MicroscopyPlaneSegmentation, mock_MicroscopySegmentations, mock_MultiChannelMicroscopyVolume, @@ -35,21 +35,21 @@ def test_roundtrip(self): microscope = mock_Microscope(name="Microscope") nwbfile.add_device(devices=microscope) - light_source = mock_MicroscopyLightSource(name="MicroscopyLightSource") - nwbfile.add_device(devices=light_source) + excitation_light_path = mock_ExcitationLightPath(name="ExcitationLightPath") + nwbfile.add_lab_meta_data(lab_meta_data=excitation_light_path) imaging_space = 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") - nwbfile.add_lab_meta_data(lab_meta_data=optical_channel) + emission_light_path = mock_EmissionLightPath(name="EmissionLightPath") + nwbfile.add_lab_meta_data(lab_meta_data=emission_light_path) planar_microscopy_series = mock_PlanarMicroscopySeries( name="PlanarMicroscopySeries", microscope=microscope, - light_source=light_source, + excitation_light_path=excitation_light_path, imaging_space=imaging_space, - optical_channel=optical_channel, + emission_light_path=emission_light_path, ) nwbfile.add_acquisition(nwbdata=planar_microscopy_series) @@ -60,10 +60,10 @@ def test_roundtrip(self): read_nwbfile = io.read() self.assertContainerEqual(microscope, read_nwbfile.devices["Microscope"]) - self.assertContainerEqual(light_source, read_nwbfile.devices["MicroscopyLightSource"]) + self.assertContainerEqual(excitation_light_path, read_nwbfile.lab_meta_data["ExcitationLightPath"]) self.assertContainerEqual(imaging_space, read_nwbfile.lab_meta_data["PlanarImagingSpace"]) - self.assertContainerEqual(optical_channel, read_nwbfile.lab_meta_data["MicroscopyOpticalChannel"]) + self.assertContainerEqual(emission_light_path, read_nwbfile.lab_meta_data["EmissionLightPath"]) self.assertContainerEqual(planar_microscopy_series, read_nwbfile.acquisition["PlanarMicroscopySeries"]) @@ -83,21 +83,21 @@ def test_roundtrip(self): microscope = mock_Microscope(name="Microscope") nwbfile.add_device(devices=microscope) - light_source = mock_MicroscopyLightSource(name="MicroscopyLightSource") - nwbfile.add_device(devices=light_source) + excitation_light_path = mock_ExcitationLightPath(name="ExcitationLightPath") + nwbfile.add_lab_meta_data(lab_meta_data=excitation_light_path) imaging_space = 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") - nwbfile.add_lab_meta_data(lab_meta_data=optical_channel) + emission_light_path = mock_EmissionLightPath(name="EmissionLightPath") + nwbfile.add_lab_meta_data(lab_meta_data=emission_light_path) volumetric_microscopy_series = mock_VolumetricMicroscopySeries( name="VolumetricMicroscopySeries", microscope=microscope, - light_source=light_source, + excitation_light_path=excitation_light_path, imaging_space=imaging_space, - optical_channel=optical_channel, + emission_light_path=emission_light_path, ) nwbfile.add_acquisition(nwbdata=volumetric_microscopy_series) @@ -108,10 +108,10 @@ def test_roundtrip(self): read_nwbfile = io.read() self.assertContainerEqual(microscope, read_nwbfile.devices["Microscope"]) - self.assertContainerEqual(light_source, read_nwbfile.devices["MicroscopyLightSource"]) + self.assertContainerEqual(excitation_light_path, read_nwbfile.lab_meta_data["ExcitationLightPath"]) self.assertContainerEqual(imaging_space, read_nwbfile.lab_meta_data["VolumetricImagingSpace"]) - self.assertContainerEqual(optical_channel, read_nwbfile.lab_meta_data["MicroscopyOpticalChannel"]) + self.assertContainerEqual(emission_light_path, read_nwbfile.lab_meta_data["EmissionLightPath"]) self.assertContainerEqual( volumetric_microscopy_series, read_nwbfile.acquisition["VolumetricMicroscopySeries"] @@ -133,21 +133,21 @@ def test_roundtrip(self): microscope = mock_Microscope(name="Microscope") nwbfile.add_device(devices=microscope) - light_source = mock_MicroscopyLightSource(name="MicroscopyLightSource") - nwbfile.add_device(devices=light_source) + excitation_light_path = mock_ExcitationLightPath(name="ExcitationLightPath") + nwbfile.add_lab_meta_data(lab_meta_data=excitation_light_path) imaging_space = 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") - nwbfile.add_lab_meta_data(lab_meta_data=optical_channel) + emission_light_path = mock_EmissionLightPath(name="EmissionLightPath") + nwbfile.add_lab_meta_data(lab_meta_data=emission_light_path) variable_depth_microscopy_series = mock_VariableDepthMicroscopySeries( name="VariableDepthMicroscopySeries", microscope=microscope, - light_source=light_source, + excitation_light_path=excitation_light_path, imaging_space=imaging_space, - optical_channel=optical_channel, + emission_light_path=emission_light_path, ) nwbfile.add_acquisition(nwbdata=variable_depth_microscopy_series) @@ -158,10 +158,10 @@ def test_roundtrip(self): read_nwbfile = io.read() self.assertContainerEqual(microscope, read_nwbfile.devices["Microscope"]) - self.assertContainerEqual(light_source, read_nwbfile.devices["MicroscopyLightSource"]) + self.assertContainerEqual(excitation_light_path, read_nwbfile.lab_meta_data["ExcitationLightPath"]) self.assertContainerEqual(imaging_space, read_nwbfile.lab_meta_data["PlanarImagingSpace"]) - self.assertContainerEqual(optical_channel, read_nwbfile.lab_meta_data["MicroscopyOpticalChannel"]) + self.assertContainerEqual(emission_light_path, read_nwbfile.lab_meta_data["EmissionLightPath"]) self.assertContainerEqual( variable_depth_microscopy_series, read_nwbfile.acquisition["VariableDepthMicroscopySeries"] @@ -186,35 +186,35 @@ def test_roundtrip(self): imaging_space = 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") - nwbfile.add_device(devices=light_source_0) - light_sources.append(light_source_0) + excitation_light_paths = list() + excitation_light_path_0 = mock_ExcitationLightPath(name="ExcitationLightPath") + nwbfile.add_lab_meta_data(lab_meta_data=excitation_light_path_0) + excitation_light_paths.append(excitation_light_path_0) - optical_channels = list() - optical_channel_0 = mock_MicroscopyOpticalChannel(name="MicroscopyOpticalChannel") - nwbfile.add_lab_meta_data(lab_meta_data=optical_channel_0) - optical_channels.append(optical_channel_0) + emission_light_paths = list() + emission_light_path_0 = mock_EmissionLightPath(name="EmissionLightPath") + nwbfile.add_lab_meta_data(lab_meta_data=emission_light_path_0) + emission_light_paths.append(emission_light_path_0) # TODO: It might be more convenient in Python to have a custom constructor that takes in a list of # light sources and optical channels and does the VectorData wrapping internally - light_sources_used_by_volume = pynwb.base.VectorData( - name="light_sources", description="Light sources used by this MultiChannelVolume.", data=light_sources + excitation_light_paths_used_by_volume = pynwb.base.VectorData( + name="excitation_light_paths", description="Light sources used by this MultiChannelVolume.", data=excitation_light_paths ) - optical_channels_used_by_volume = pynwb.base.VectorData( - name="optical_channels", + emission_light_paths_used_by_volume = pynwb.base.VectorData( + name="emission_light_paths", description=( "Optical channels ordered to correspond to the third axis (e.g., [0, 0, :, 0]) " "of the data for this MultiChannelVolume." ), - data=optical_channels, + data=emission_light_paths, ) multi_channel_microscopy_volume = mock_MultiChannelMicroscopyVolume( name="MultiChannelMicroscopyVolume", microscope=microscope, imaging_space=imaging_space, - light_sources=light_sources_used_by_volume, - optical_channels=optical_channels_used_by_volume, + excitation_light_paths=excitation_light_paths_used_by_volume, + emission_light_paths=emission_light_paths_used_by_volume, ) nwbfile.add_acquisition(nwbdata=multi_channel_microscopy_volume) @@ -225,10 +225,10 @@ def test_roundtrip(self): read_nwbfile = io.read() self.assertContainerEqual(microscope, read_nwbfile.devices["Microscope"]) - self.assertContainerEqual(light_source_0, read_nwbfile.devices["LightSource"]) + self.assertContainerEqual(excitation_light_path_0, read_nwbfile.lab_meta_data["ExcitationLightPath"]) self.assertContainerEqual(imaging_space, read_nwbfile.lab_meta_data["VolumetricImagingSpace"]) - self.assertContainerEqual(optical_channel_0, read_nwbfile.lab_meta_data["MicroscopyOpticalChannel"]) + self.assertContainerEqual(emission_light_path_0, read_nwbfile.lab_meta_data["EmissionLightPath"]) self.assertContainerEqual( multi_channel_microscopy_volume, read_nwbfile.acquisition["MultiChannelMicroscopyVolume"] From caa1802a8398f697848b26d9b3094ae995a64ce1 Mon Sep 17 00:00:00 2001 From: alessandratrapani Date: Mon, 26 Aug 2024 17:15:04 +0200 Subject: [PATCH 3/5] update requirements --- requirements-min.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements-min.txt b/requirements-min.txt index cd0c3e6..a2358dc 100644 --- a/requirements-min.txt +++ b/requirements-min.txt @@ -1 +1,2 @@ pynwb +ndx-ophys-devices git+https://github.com/catalystneuro/ndx-ophys-devices.git@create_specs \ No newline at end of file From 8356ca5414d033029663ac891edab97f0a3fdfe7 Mon Sep 17 00:00:00 2001 From: alessandratrapani Date: Mon, 26 Aug 2024 17:39:43 +0200 Subject: [PATCH 4/5] update README.md --- README.md | 64 ++++++++++++++++++++--------- spec/ndx-microscopy.extensions.yaml | 2 +- 2 files changed, 45 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 148426c..c1c5e80 100644 --- a/README.md +++ b/README.md @@ -36,8 +36,8 @@ classDiagram links -------------------------------------- microscope : Microscope - light_source : MicroscopyLightSource - optical_channel : MicroscopyOpticalChannel + excitation_light_path : ExcitationLightPath + emission_light_path : EmissionLightPath } class PlanarMicroscopySeries { @@ -86,6 +86,32 @@ classDiagram imaging_space : VolumetricImageSpace } + class MultiChannelMicroscopyVolume { + <> + + -------------------------------------- + attributes + -------------------------------------- + description : text, optional + unit : text, optional + conversion : numeric, optional + offset : numeric, optional + + -------------------------------------- + datasets + -------------------------------------- + data : numeric, frame x height x width x depth x emission_light_paths + --> unit : text + excitation_light_paths : ExcitationLightPath, excitation_light_paths + emission_light_paths : EmissionLightPath, emission_light_paths + + -------------------------------------- + links + -------------------------------------- + imaging_space : VolumetricImageSpace + microscope : Microscope + } + class ImagingSpace{ <> @@ -132,36 +158,34 @@ classDiagram reference_frame : text, optional } - class MicroscopyOpticalChannel{ + class ExcitationLightPath{ <> -------------------------------------- - datasets + links -------------------------------------- - description : text + excitation_source : ExcitationSource, optional + excitation_filter : OpticalFilter, optional -------------------------------------- attributes -------------------------------------- - indicator : text - filter_description : text, optional - emission_wavelength_in_nm : numeric, optional + excitation_wavelength_in_nm : numeric } - class MicroscopyLightSource{ - <> + class EmissionLightPath{ + <> + + -------------------------------------- + links + -------------------------------------- + photodetector : Photodetector, optional + emission_filter : OpticalFilter, optional -------------------------------------- attributes -------------------------------------- - model : text, optional - filter_description : text, optional - excitation_wavelength_in_nm : numeric, optional - peak_power_in_W : numeric, optional - peak_pulse_energy_in_J : numeric, optional - intensity_in_W_per_m2 : numeric, optional - exposure_time_in_s : numeric, optional - pulse_rate_in_Hz : numeric, optional + emission_wavelength_in_nm : numeric } class Microscope{ @@ -182,8 +206,8 @@ classDiagram PlanarImagingSpace *-- ImagingSpace : extends VolumetricImagingSpace *-- ImagingSpace : extends MicroscopySeries ..> Microscope : links - MicroscopySeries ..> MicroscopyLightSource : links - MicroscopySeries ..> MicroscopyOpticalChannel : links + MicroscopySeries ..> ExcitationLightPath : links + MicroscopySeries ..> EmissionLightPath : links ``` --- diff --git a/spec/ndx-microscopy.extensions.yaml b/spec/ndx-microscopy.extensions.yaml index 9312b3b..4a2e75a 100644 --- a/spec/ndx-microscopy.extensions.yaml +++ b/spec/ndx-microscopy.extensions.yaml @@ -360,7 +360,7 @@ groups: - height - width - depths - - optical_channels + - emission_light_paths shape: - null - null From 6f235426e3adc8c06404b93d74e63c13730b2e75 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 26 Aug 2024 15:45:10 +0000 Subject: [PATCH 5/5] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- README.md | 6 ++--- requirements-min.txt | 2 +- src/pynwb/ndx_microscopy/__init__.py | 8 ++---- src/pynwb/ndx_microscopy/testing/__init__.py | 4 +-- src/pynwb/ndx_microscopy/testing/_mock.py | 19 +++++--------- src/pynwb/tests/test_constructors.py | 27 +++++++++++++++----- src/pynwb/tests/test_roundtrip.py | 8 +++--- 7 files changed, 40 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index c1c5e80..bc78799 100644 --- a/README.md +++ b/README.md @@ -88,7 +88,7 @@ classDiagram class MultiChannelMicroscopyVolume { <> - + -------------------------------------- attributes -------------------------------------- @@ -104,14 +104,14 @@ classDiagram --> unit : text excitation_light_paths : ExcitationLightPath, excitation_light_paths emission_light_paths : EmissionLightPath, emission_light_paths - + -------------------------------------- links -------------------------------------- imaging_space : VolumetricImageSpace microscope : Microscope } - + class ImagingSpace{ <> diff --git a/requirements-min.txt b/requirements-min.txt index a2358dc..1299ede 100644 --- a/requirements-min.txt +++ b/requirements-min.txt @@ -1,2 +1,2 @@ pynwb -ndx-ophys-devices git+https://github.com/catalystneuro/ndx-ophys-devices.git@create_specs \ No newline at end of file +ndx-ophys-devices git+https://github.com/catalystneuro/ndx-ophys-devices.git@create_specs diff --git a/src/pynwb/ndx_microscopy/__init__.py b/src/pynwb/ndx_microscopy/__init__.py index 1351b27..467f201 100644 --- a/src/pynwb/ndx_microscopy/__init__.py +++ b/src/pynwb/ndx_microscopy/__init__.py @@ -19,12 +19,8 @@ __spec_path = __location_of_this_file.parent.parent.parent / "spec" / f"{extension_name}.namespace.yaml" load_namespaces(str(__spec_path)) -from ndx_ophys_devices import ( - OpticalFilter, - ExcitationSource, - Indicator, - Photodetector, -) +from ndx_ophys_devices import ExcitationSource, Indicator, OpticalFilter, Photodetector + Microscope = get_class("Microscope", extension_name) ExcitationLightPath = get_class("ExcitationLightPath", extension_name) EmissionLightPath = get_class("EmissionLightPath", extension_name) diff --git a/src/pynwb/ndx_microscopy/testing/__init__.py b/src/pynwb/ndx_microscopy/testing/__init__.py index 9b7679e..97ddbba 100644 --- a/src/pynwb/ndx_microscopy/testing/__init__.py +++ b/src/pynwb/ndx_microscopy/testing/__init__.py @@ -1,7 +1,7 @@ from ._mock import ( - mock_Microscope, - mock_ExcitationLightPath, mock_EmissionLightPath, + mock_ExcitationLightPath, + mock_Microscope, mock_MicroscopyPlaneSegmentation, mock_MicroscopySegmentations, mock_MultiChannelMicroscopyVolume, diff --git a/src/pynwb/ndx_microscopy/testing/_mock.py b/src/pynwb/ndx_microscopy/testing/_mock.py index 47b4a64..8b9f024 100644 --- a/src/pynwb/ndx_microscopy/testing/_mock.py +++ b/src/pynwb/ndx_microscopy/testing/_mock.py @@ -3,22 +3,17 @@ import numpy as np import pynwb.base -from pynwb.testing.mock.utils import name_generator - -import ndx_microscopy - -from ndx_ophys_devices import ( - OpticalFilter, - ExcitationSource, - Indicator, - Photodetector, -) +from ndx_ophys_devices import ExcitationSource, Indicator, OpticalFilter, Photodetector from ndx_ophys_devices.testing import ( + mock_ExcitationSource, mock_Indicator, - mock_Photodetector, mock_OpticalFilter, - mock_ExcitationSource, + mock_Photodetector, ) +from pynwb.testing.mock.utils import name_generator + +import ndx_microscopy + def mock_Microscope( *, diff --git a/src/pynwb/tests/test_constructors.py b/src/pynwb/tests/test_constructors.py index 3935c0d..0f5573e 100644 --- a/src/pynwb/tests/test_constructors.py +++ b/src/pynwb/tests/test_constructors.py @@ -4,9 +4,9 @@ import pynwb from ndx_microscopy.testing import ( - mock_Microscope, - mock_ExcitationLightPath, mock_EmissionLightPath, + mock_ExcitationLightPath, + mock_Microscope, mock_MicroscopyPlaneSegmentation, mock_MicroscopySegmentations, mock_MultiChannelMicroscopyVolume, @@ -68,7 +68,10 @@ def test_constructor_planar_microscopy_series(): emission_light_path = mock_EmissionLightPath() mock_PlanarMicroscopySeries( - microscope=microscope, excitation_light_path=excitation_light_path, imaging_space=imaging_space, emission_light_path=emission_light_path + microscope=microscope, + excitation_light_path=excitation_light_path, + imaging_space=imaging_space, + emission_light_path=emission_light_path, ) @@ -79,7 +82,10 @@ def test_constructor_variable_depth_microscopy_series(): emission_light_path = mock_EmissionLightPath() mock_VariableDepthMicroscopySeries( - microscope=microscope, excitation_light_path=excitation_light_path, imaging_space=imaging_space, emission_light_path=emission_light_path + microscope=microscope, + excitation_light_path=excitation_light_path, + imaging_space=imaging_space, + emission_light_path=emission_light_path, ) @@ -90,7 +96,10 @@ def test_constructor_volumetric_microscopy_series(): emission_light_path = mock_EmissionLightPath() mock_VolumetricMicroscopySeries( - microscope=microscope, excitation_light_path=excitation_light_path, imaging_space=imaging_space, emission_light_path=emission_light_path + microscope=microscope, + excitation_light_path=excitation_light_path, + imaging_space=imaging_space, + emission_light_path=emission_light_path, ) @@ -101,7 +110,9 @@ def test_constructor_multi_channel_microscopy_volume(): emission_light_paths = [mock_EmissionLightPath()] excitation_light_paths_used_by_volume = pynwb.base.VectorData( - name="excitation_light_paths", description="Light sources used by this MultiChannelVolume.", data=excitation_light_paths + name="excitation_light_paths", + description="Light sources used by this MultiChannelVolume.", + data=excitation_light_paths, ) emission_light_paths_used_by_volume = pynwb.base.VectorData( name="emission_light_paths", @@ -126,7 +137,9 @@ def test_constructor_variable_depth_multi_channel_microscopy_volume(): emission_light_paths = [mock_EmissionLightPath()] excitation_light_paths_used_by_volume = pynwb.base.VectorData( - name="excitation_light_paths", description="Light sources used by this MultiChannelVolume.", data=excitation_light_paths + name="excitation_light_paths", + description="Light sources used by this MultiChannelVolume.", + data=excitation_light_paths, ) emission_light_paths_used_by_volume = pynwb.base.VectorData( name="emission_light_paths", diff --git a/src/pynwb/tests/test_roundtrip.py b/src/pynwb/tests/test_roundtrip.py index fe5d512..99d2a16 100644 --- a/src/pynwb/tests/test_roundtrip.py +++ b/src/pynwb/tests/test_roundtrip.py @@ -6,9 +6,9 @@ import pynwb from ndx_microscopy.testing import ( - mock_Microscope, - mock_ExcitationLightPath, mock_EmissionLightPath, + mock_ExcitationLightPath, + mock_Microscope, mock_MicroscopyPlaneSegmentation, mock_MicroscopySegmentations, mock_MultiChannelMicroscopyVolume, @@ -199,7 +199,9 @@ def test_roundtrip(self): # TODO: It might be more convenient in Python to have a custom constructor that takes in a list of # light sources and optical channels and does the VectorData wrapping internally excitation_light_paths_used_by_volume = pynwb.base.VectorData( - name="excitation_light_paths", description="Light sources used by this MultiChannelVolume.", data=excitation_light_paths + name="excitation_light_paths", + description="Light sources used by this MultiChannelVolume.", + data=excitation_light_paths, ) emission_light_paths_used_by_volume = pynwb.base.VectorData( name="emission_light_paths",