Skip to content

Commit

Permalink
Merge branch 'add_multichannel_volume' into all_previous_prs_and_vari…
Browse files Browse the repository at this point in the history
…able_depth_static
  • Loading branch information
CodyCBakerPhD authored Jul 12, 2024
2 parents a00fa42 + 4912507 commit 523d972
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 30 deletions.
21 changes: 12 additions & 9 deletions spec/ndx-microscopy.extensions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -393,19 +393,22 @@ groups:
- null
- null
- null
- name: light_sources
doc: Reference to a list of MicroscopyLightSource objects containing metadata about the excitation methods.
neurodata_type_inc: VectorData
dtype:
reftype: object
target_type: MicroscopyLightSource
- name: optical_channels
doc: Reference to an ordered list of MicroscopyOpticalChannel objects containing metadata about the indicator and filters used to collect this data.
neurodata_type_inc: VectorData
dtype:
reftype: object
target_type: MicroscopyOpticalChannel
links:
- name: microscope
doc: Link to a Microscope object containing metadata about the device used to acquire this imaging data.
target_type: Microscope
# TODO: figure out best way to link to list of light sources
- name: light_sources
doc: Link to an ordered list of MicroscopyLightSource objects containing metadata about the excitation method.
target_type: MicroscopyLightSource
# TODO: figure out best way to link to list of optical channels
- name: optical_channels
doc: Link to an ordered list of MicroscopyOpticalChannel objects containing metadata about the indicator and
filters used to collect this data.
target_type: MicroscopyOpticalChannel
- name: imaging_space
doc: Link to VolumetricImagingSpace object containing metadata about the region of physical space this imaging data
was recorded from.
Expand Down
9 changes: 5 additions & 4 deletions src/pynwb/ndx_microscopy/testing/_mock.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from typing import Iterable, List, Optional, Tuple

import numpy as np
import pynwb.base
from pynwb.testing.mock.utils import name_generator

import ndx_microscopy
Expand Down Expand Up @@ -322,9 +323,9 @@ def mock_VolumetricMicroscopySeries(
def mock_MultiChannelMicroscopyVolume(
*,
microscope: ndx_microscopy.Microscope,
light_sources: List[ndx_microscopy.MicroscopyLightSource],
imaging_space: ndx_microscopy.VolumetricImagingSpace,
optical_channels: List[ndx_microscopy.MicroscopyOpticalChannel],
light_sources: pynwb.base.VectorData,
optical_channels: 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,
Expand All @@ -339,9 +340,9 @@ def mock_MultiChannelMicroscopyVolume(
name=series_name,
description=description,
microscope=microscope,
light_sources=light_sources[0], # TODO: figure out how to specify list
imaging_space=imaging_space,
optical_channels=optical_channels[0], # TODO: figure out how to specify list
light_sources=light_sources,
optical_channels=optical_channels,
data=imaging_data,
unit=unit,
conversion=conversion,
Expand Down
20 changes: 16 additions & 4 deletions src/pynwb/tests/test_constructors.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import pytest

import pynwb
from ndx_microscopy.testing import (
mock_Microscope,
mock_MicroscopyImageSegmentation,
Expand Down Expand Up @@ -103,15 +104,26 @@ def test_constructor_volumetric_microscopy_series():

def test_constructor_multi_channel_microscopy_volume():
microscope = mock_Microscope()
light_source = mock_LightSource()
imaging_space = mock_VolumetricImagingSpace(microscope=microscope)
optical_channel = mock_MicroscopyOpticalChannel()
light_sources = [mock_MicroscopyLightSource()]
optical_channels = [mock_MicroscopyOpticalChannel()]

light_sources_used_by_volume = pynwb.base.VectorData(
name="light_sources", description="Light sources used by this MultiChannelVolume.", data=light_sources
)
optical_channels_used_by_volume = pynwb.base.VectorData(
name="optical_channels",
description=(
"Optical channels ordered to correspond to the third axis (e.g., [0, 0, :, 0]) "
"of the data for this MultiChannelVolume."
),
data=optical_channels,
)
mock_MultiChannelMicroscopyVolume(
microscope=microscope,
light_source=light_source,
imaging_space=imaging_space,
optical_channels=[optical_channel],
light_sources=light_sources_used_by_volume,
optical_channels=optical_channels_used_by_volume,
)


Expand Down
46 changes: 33 additions & 13 deletions src/pynwb/tests/test_roundtrip.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class TestPlanarMicroscopySeriesSimpleRoundtrip(pynwb_TestCase):
"""Simple roundtrip test for PlanarMicroscopySeries."""

def setUp(self):
self.nwbfile_path = "test.nwb"
self.nwbfile_path = "test_planar_microscopy_series_roundtrip.nwb"

def tearDown(self):
pynwb.testing.remove_test_file(self.nwbfile_path)
Expand Down Expand Up @@ -69,7 +69,7 @@ class TestVolumetricMicroscopySeriesSimpleRoundtrip(pynwb_TestCase):
"""Simple roundtrip test for VolumetricMicroscopySeries."""

def setUp(self):
self.nwbfile_path = "test.nwb"
self.nwbfile_path = "test_volumetric_microscopy_series_roundtrip.nwb"

def tearDown(self):
pynwb.testing.remove_test_file(self.nwbfile_path)
Expand Down Expand Up @@ -119,7 +119,7 @@ class TestVariableDepthMicroscopySeriesSimpleRoundtrip(pynwb_TestCase):
"""Simple roundtrip test for VariableDepthMicroscopySeries."""

def setUp(self):
self.nwbfile_path = "test.nwb"
self.nwbfile_path = "test_variable_depth_microscopy_series_roundtrip.nwb"

def tearDown(self):
pynwb.testing.remove_test_file(self.nwbfile_path)
Expand Down Expand Up @@ -169,7 +169,7 @@ class TestMultiChannelMicroscopyVolumeSimpleRoundtrip(pynwb_TestCase):
"""Simple roundtrip test for MultiChannelMicroscopyVolume."""

def setUp(self):
self.nwbfile_path = "test.nwb"
self.nwbfile_path = "test_multi_channel_microscopy_volume_roundtrip.nwb"

def tearDown(self):
pynwb.testing.remove_test_file(self.nwbfile_path)
Expand All @@ -180,21 +180,38 @@ def test_roundtrip(self):
microscope = mock_Microscope(name="Microscope")
nwbfile.add_device(devices=microscope)

light_source = mock_LightSource(name="LightSource")
nwbfile.add_device(devices=light_source)

imaging_space = mock_VolumetricImagingSpace(name="VolumetricImagingSpace", 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)
light_sources = list()
light_source_0 = 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")
nwbfile.add_lab_meta_data(lab_meta_data=optical_channel_0)
optical_channels.append(optical_channel_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
)
optical_channels_used_by_volume = pynwb.base.VectorData(
name="optical_channels",
description=(
"Optical channels ordered to correspond to the third axis (e.g., [0, 0, :, 0]) "
"of the data for this MultiChannelVolume."
),
data=optical_channels,
)
multi_channel_microscopy_volume = mock_MultiChannelMicroscopyVolume(
name="MultiChannelMicroscopyVolume",
microscope=microscope,
light_source=light_source,
imaging_space=imaging_space,
optical_channels=[optical_channel],
light_sources=light_sources_used_by_volume,
optical_channels=optical_channels_used_by_volume,
)
nwbfile.add_acquisition(nwbdata=multi_channel_microscopy_volume)

Expand All @@ -205,14 +222,17 @@ def test_roundtrip(self):
read_nwbfile = io.read()

self.assertContainerEqual(microscope, read_nwbfile.devices["Microscope"])
self.assertContainerEqual(light_source, read_nwbfile.devices["LightSource"])
self.assertContainerEqual(light_source_0, read_nwbfile.devices["LightSource"])

self.assertContainerEqual(imaging_space, read_nwbfile.lab_meta_data["VolumetricImagingSpace"])
self.assertContainerEqual(optical_channel, read_nwbfile.lab_meta_data["MicroscopyOpticalChannel"])
self.assertContainerEqual(optical_channel_0, read_nwbfile.lab_meta_data["MicroscopyOpticalChannel"])

self.assertContainerEqual(
multi_channel_microscopy_volume, read_nwbfile.acquisition["MultiChannelMicroscopyVolume"]
)


# TODO: add roundtrip for planesegmentation, imagesegmentation, etc.

if __name__ == "__main__":
pytest.main() # Required since not a typical package structure

0 comments on commit 523d972

Please sign in to comment.