Skip to content

Commit afe5083

Browse files
Merge branch 'dev' into inspect_on_dandisets
2 parents 4137abe + 71818b1 commit afe5083

File tree

2 files changed

+76
-17
lines changed

2 files changed

+76
-17
lines changed

nwbinspector/checks/ophys.py

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
"""Check functions specific to optical electrophysiology neurodata types."""
2-
from pynwb.ophys import RoiResponseSeries, PlaneSegmentation
2+
from pynwb.ophys import RoiResponseSeries, PlaneSegmentation, OpticalChannel, ImagingPlane
33

44
from hdmf.utils import get_data_shape
55

66
from ..register_checks import register_check, Importance, InspectorMessage
77

8+
MIN_LAMBDA = 10.0 # trigger warnings for wavelength values less than this value
9+
810

911
@register_check(importance=Importance.CRITICAL, neurodata_type=RoiResponseSeries)
1012
def check_roi_response_series_dims(roi_response_series: RoiResponseSeries):
@@ -32,18 +34,15 @@ def check_roi_response_series_link_to_plane_segmentation(roi_response_series: Ro
3234
return InspectorMessage(message="rois field does not point to a PlaneSegmentation table.")
3335

3436

35-
# @nwbinspector_check(severity=2, neurodata_type=pynwb.TimeSeries)
36-
# def check_ophys(nwbfile):
37-
# opto_sites = list(all_of_type(nwbfile, pynwb.ogen.OptogeneticStimulusSite))
38-
# opto_series = list(all_of_type(nwbfile, pynwb.ogen.OptogeneticSeries))
39-
# for site in opto_sites:
40-
# if not site.description:
41-
# error_code = "A101"
42-
# print(
43-
# "%s: '%s' %s is missing text for attribute 'description'"
44-
# % (error_code, site.name, type(site).__name__)
45-
# )
46-
# if not site.location:
47-
# error_code = "A101"
48-
# print("%s: '%s' %s is missing text for attribute 'location'"
49-
# % (error_code, site.name, type(site).__name__))
37+
@register_check(importance=Importance.BEST_PRACTICE_VIOLATION, neurodata_type=OpticalChannel)
38+
def check_emission_lambda_in_nm(optical_channel: OpticalChannel):
39+
"""Check that emission lambda is in feasible range for unit nanometers."""
40+
if optical_channel.emission_lambda < MIN_LAMBDA:
41+
return InspectorMessage(f"emission lambda of {optical_channel.emission_lambda} should be in units of nm.")
42+
43+
44+
@register_check(importance=Importance.BEST_PRACTICE_VIOLATION, neurodata_type=ImagingPlane)
45+
def check_excitation_lambda_in_nm(imaging_plane: ImagingPlane):
46+
"""Check that emission lambda is in feasible range for unit nanometers."""
47+
if imaging_plane.excitation_lambda < MIN_LAMBDA:
48+
return InspectorMessage(f"excitation lambda of {imaging_plane.excitation_lambda} should be in units of nm.")

tests/unit_tests/test_ophys.py

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,15 @@
44

55
import numpy as np
66
from pynwb import NWBFile
7-
from pynwb.ophys import OpticalChannel, ImageSegmentation, RoiResponseSeries
7+
from pynwb.device import Device
8+
from pynwb.ophys import OpticalChannel, ImageSegmentation, RoiResponseSeries, ImagingPlane
89
from hdmf.common.table import DynamicTableRegion, DynamicTable
910

1011
from nwbinspector.checks.ophys import (
1112
check_roi_response_series_dims,
1213
check_roi_response_series_link_to_plane_segmentation,
14+
check_excitation_lambda_in_nm,
15+
check_emission_lambda_in_nm,
1316
)
1417
from nwbinspector.register_checks import InspectorMessage, Importance
1518

@@ -167,3 +170,60 @@ def test_pass_check_roi_response_series_link_to_plane_segmentation(self):
167170
)
168171

169172
assert check_roi_response_series_link_to_plane_segmentation(roi_resp_series) is None
173+
174+
175+
def test_check_excitation_lambda_in_nm():
176+
177+
device = Device(
178+
name="Microscope", description="My two-photon microscope", manufacturer="The best microscope manufacturer"
179+
)
180+
optical_channel = OpticalChannel(name="OpticalChannel", description="an optical channel", emission_lambda=500.0)
181+
imaging_plane = ImagingPlane(
182+
name="ImagingPlane",
183+
optical_channel=optical_channel,
184+
imaging_rate=30.0,
185+
description="a very interesting part of the brain",
186+
device=device,
187+
excitation_lambda=1.0,
188+
indicator="GFP",
189+
location="V1",
190+
grid_spacing=[0.01, 0.01],
191+
grid_spacing_unit="meters",
192+
origin_coords=[1.0, 2.0, 3.0],
193+
origin_coords_unit="meters",
194+
)
195+
196+
assert check_excitation_lambda_in_nm(imaging_plane).message == "excitation lambda of 1.0 should be in units of nm."
197+
198+
199+
def test_pass_check_excitation_lambda_in_nm():
200+
device = Device(
201+
name="Microscope", description="My two-photon microscope", manufacturer="The best microscope manufacturer"
202+
)
203+
optical_channel = OpticalChannel(name="OpticalChannel", description="an optical channel", emission_lambda=500.0)
204+
imaging_plane = ImagingPlane(
205+
name="ImagingPlane",
206+
optical_channel=optical_channel,
207+
imaging_rate=30.0,
208+
description="a very interesting part of the brain",
209+
device=device,
210+
excitation_lambda=300.0,
211+
indicator="GFP",
212+
location="V1",
213+
grid_spacing=[0.01, 0.01],
214+
grid_spacing_unit="meters",
215+
origin_coords=[1.0, 2.0, 3.0],
216+
origin_coords_unit="meters",
217+
)
218+
219+
assert check_excitation_lambda_in_nm(imaging_plane) is None
220+
221+
222+
def test_check_emission_lambda_in_nm():
223+
optical_channel = OpticalChannel(name="OpticalChannel", description="an optical channel", emission_lambda=5.0)
224+
assert check_emission_lambda_in_nm(optical_channel).message == "emission lambda of 5.0 should be in units of nm."
225+
226+
227+
def test_pass_check_emission_lambda_in_nm():
228+
optical_channel = OpticalChannel(name="OpticalChannel", description="an optical channel", emission_lambda=500.0)
229+
assert check_emission_lambda_in_nm(optical_channel) is None

0 commit comments

Comments
 (0)