Skip to content

Commit

Permalink
[Enhancement IV] Add roi response series (#19)
Browse files Browse the repository at this point in the history
* add multichannel volume

* swap to datainterface

* fix import

* fix test name

* fix intercompatability

* fix light sources

* fix

* add plane segmentation stuff

* fix autogenerated arg

* variable depth volume

* swap to um

* override for roi response to avoid construct error

* add container too

* ryans suggestion

* adjust to use full list

* adjust constructor test

* reorder kwargs in mock

* adjust kwargs order in mock

* Implement lists of object references with tests

* Adjust constructor test to match

* fix outer spec to match altered one

* Update spec/ndx-microscopy.extensions.yaml

* Update spec/ndx-microscopy.extensions.yaml

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* alessandras comments and tests

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* fix import

* fix import

* fix import

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* debug

* debugs

* debugs

* debugs

* debugs

* debugs

* debugs

* debugs

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* start adding tests

* start adding tests

* complete tests

* debug

* debug

---------

Co-authored-by: CodyCBakerPhD <[email protected]>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
3 people authored Aug 28, 2024
1 parent 512ff76 commit 6f5ceae
Show file tree
Hide file tree
Showing 6 changed files with 288 additions and 106 deletions.
28 changes: 28 additions & 0 deletions spec/ndx-microscopy.extensions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -506,3 +506,31 @@ groups:
doc: Link to VolumetricImagingSpace object containing metadata about the region of physical space this imaging data
was recorded from.
target_type: VolumetricImagingSpace


- neurodata_type_def: MicroscopyResponseSeries
neurodata_type_inc: TimeSeries
doc: ROI responses extracted from optical imaging.
datasets:
- name: data
dtype: numeric
dims:
- - number_of_frames
- number_of_rois
shape:
- - null
- null
doc: Signals from ROIs.
- name: table_region
neurodata_type_inc: DynamicTableRegion
doc: DynamicTableRegion referencing plane segmentation containing more information about the ROIs
stored in this series.

- neurodata_type_def: MicroscopyResponseSeriesContainer
neurodata_type_inc: NWBDataInterface
default_name: MicroscopyResponseSeriesContainer
doc: A container of many MicroscopyResponseSeries.
groups:
- neurodata_type_inc: MicroscopyResponseSeries
doc: MicroscopyResponseSeries object(s) containing fluorescence data for a ROI.
quantity: '+'
6 changes: 6 additions & 0 deletions src/pynwb/ndx_microscopy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@
MultiChannelMicroscopyVolume = get_class("MultiChannelMicroscopyVolume", extension_name)
VariableDepthMultiChannelMicroscopyVolume = get_class("VariableDepthMultiChannelMicroscopyVolume", extension_name)

MicroscopyResponseSeries = get_class("MicroscopyResponseSeries", extension_name)
MicroscopyResponseSeriesContainer = get_class("MicroscopyResponseSeriesContainer", extension_name)


__all__ = [
"Microscope",
"MicroscopyLightSource",
Expand All @@ -50,4 +54,6 @@
"VolumetricMicroscopySeries",
"MultiChannelMicroscopyVolume",
"VariableDepthMultiChannelMicroscopyVolume",
"MicroscopyResponseSeries",
"MicroscopyResponseSeriesContainer",
]
4 changes: 4 additions & 0 deletions src/pynwb/ndx_microscopy/testing/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
mock_MicroscopyLightSource,
mock_MicroscopyOpticalChannel,
mock_MicroscopyPlaneSegmentation,
mock_MicroscopyResponseSeries,
mock_MicroscopyResponseSeriesContainer,
mock_MicroscopySegmentations,
mock_MultiChannelMicroscopyVolume,
mock_PlanarImagingSpace,
Expand All @@ -25,5 +27,7 @@
"mock_VariableDepthMicroscopySeries",
"mock_VolumetricMicroscopySeries",
"mock_MultiChannelMicroscopyVolume",
"mock_MicroscopyResponseSeries",
"mock_MicroscopyResponseSeriesContainer",
"mock_VariableDepthMultiChannelMicroscopyVolume",
]
89 changes: 78 additions & 11 deletions src/pynwb/ndx_microscopy/testing/_mock.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
def mock_Microscope(
*,
name: Optional[str] = None,
description: str = "This is a mock instance of a Microscope type to be used for rapid testing.",
description: str = "A mock instance of a Microscope type to be used for rapid testing.",
manufacturer: str = "A fake manufacturer of the mock microscope.",
model: str = "A fake model of the mock microscope.",
) -> ndx_microscopy.Microscope:
Expand All @@ -27,7 +27,7 @@ def mock_Microscope(
def mock_MicroscopyLightSource(
*,
name: Optional[str] = None,
description: str = "This is a mock instance of a MicroscopyLightSource type to be used for rapid testing.",
description: str = "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.",
Expand Down Expand Up @@ -57,7 +57,7 @@ def mock_MicroscopyLightSource(
def mock_MicroscopyOpticalChannel(
*,
name: Optional[str] = None,
description: str = "This is a mock instance of a MicroscopyOpticalChannel type to be used for rapid testing.",
description: str = "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.",
emission_wavelength_in_nm: float = 450.0,
Expand All @@ -76,7 +76,7 @@ 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.",
description: str = "A mock instance of a PlanarImagingSpace type to be used for rapid testing.",
origin_coordinates: Tuple[float, float, float] = (-1.2, -0.6, -2),
grid_spacing_in_um: Tuple[float, float, float] = (20, 20),
location: str = "The location targeted by the mock imaging space.",
Expand All @@ -98,7 +98,7 @@ 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.",
description: str = "A mock instance of a VolumetricImagingSpace type to be used for rapid testing.",
origin_coordinates: Tuple[float, float, float] = (-1.2, -0.6, -2),
grid_spacing_in_um: Tuple[float, float, float] = (20, 20, 50),
location: str = "The location targeted by the mock imaging space.",
Expand Down Expand Up @@ -140,7 +140,7 @@ def mock_MicroscopyPlaneSegmentation(
*,
imaging_space: ndx_microscopy.ImagingSpace,
name: Optional[str] = None,
description: str = "This is a mock instance of a MicroscopyPlaneSegmentation type to be used for rapid testing.",
description: str = "A mock instance of a MicroscopyPlaneSegmentation type to be used for rapid testing.",
number_of_rois: int = 5,
image_shape: Tuple[int, int] = (10, 10),
) -> ndx_microscopy.MicroscopyPlaneSegmentation:
Expand All @@ -166,7 +166,7 @@ def mock_PlanarMicroscopySeries(
imaging_space: ndx_microscopy.PlanarImagingSpace,
optical_channel: ndx_microscopy.MicroscopyOpticalChannel,
name: Optional[str] = None,
description: str = "This is a mock instance of a PlanarMicroscopySeries type to be used for rapid testing.",
description: str = "A mock instance of a PlanarMicroscopySeries type to be used for rapid testing.",
data: Optional[np.ndarray] = None,
unit: str = "a.u.",
conversion: float = 1.0,
Expand Down Expand Up @@ -221,7 +221,7 @@ def mock_VariableDepthMicroscopySeries(
imaging_space: ndx_microscopy.PlanarImagingSpace,
optical_channel: ndx_microscopy.MicroscopyOpticalChannel,
name: Optional[str] = None,
description: str = "This is a mock instance of a PlanarMicroscopySeries type to be used for rapid testing.",
description: str = "A mock instance of a PlanarMicroscopySeries type to be used for rapid testing.",
data: Optional[np.ndarray] = None,
depth_per_frame_in_um: Optional[np.ndarray] = None,
unit: str = "a.u.",
Expand Down Expand Up @@ -284,7 +284,7 @@ def mock_VolumetricMicroscopySeries(
imaging_space: ndx_microscopy.VolumetricImagingSpace,
optical_channel: ndx_microscopy.MicroscopyOpticalChannel,
name: Optional[str] = None,
description: str = "This is a mock instance of a VolumetricMicroscopySeries type to be used for rapid testing.",
description: str = "A mock instance of a VolumetricMicroscopySeries type to be used for rapid testing.",
data: Optional[np.ndarray] = None,
unit: str = "a.u.",
conversion: float = 1.0,
Expand Down Expand Up @@ -339,7 +339,7 @@ def mock_MultiChannelMicroscopyVolume(
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.",
description: str = "A mock instance of a MultiChannelMicroscopyVolume type to be used for rapid testing.",
data: Optional[np.ndarray] = None,
unit: str = "n.a.",
conversion: float = 1.0,
Expand All @@ -363,14 +363,81 @@ def mock_MultiChannelMicroscopyVolume(
return volumetric_microscopy_series


def mock_MicroscopyResponseSeries(
*,
table_region: pynwb.core.DynamicTableRegion,
name: Optional[str] = None,
description: str = "A mock instance of a MicroscopyResponseSeries type to be used for rapid testing.",
data: Optional[np.ndarray] = None,
unit: str = "a.u.",
conversion: float = 1.0,
offset: float = 0.0,
starting_time: Optional[float] = None,
rate: Optional[float] = None,
timestamps: Optional[np.ndarray] = None,
) -> ndx_microscopy.MicroscopyResponseSeries:
series_name = name or name_generator("MicroscopyResponseSeries")

number_of_frames = 100
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=series_data,
unit=unit,
conversion=conversion,
offset=offset,
starting_time=series_starting_time,
rate=series_rate,
timestamps=series_timestamps,
)

return microscopy_response_series


def mock_MicroscopyResponseSeriesContainer(
*,
microscopy_response_series: List[ndx_microscopy.MicroscopyResponseSeries],
name: Optional[str] = None,
) -> ndx_microscopy.MicroscopyResponseSeriesContainer:
container_name = name or name_generator("MicroscopyResponseSeriesContainer")

microscopy_response_series_container = ndx_microscopy.MicroscopyResponseSeriesContainer(
name=container_name, microscopy_response_series=microscopy_response_series
)

return microscopy_response_series_container


def mock_VariableDepthMultiChannelMicroscopyVolume(
*,
microscope: ndx_microscopy.Microscope,
imaging_space: ndx_microscopy.VolumetricImagingSpace,
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.",
description: str = "A mock instance of a MultiChannelMicroscopyVolume type to be used for rapid testing.",
data: Optional[np.ndarray] = None,
depth_per_frame_in_um: Optional[np.ndarray] = None,
unit: str = "n.a.",
Expand Down
Loading

0 comments on commit 6f5ceae

Please sign in to comment.