Skip to content

Commit 14a96b1

Browse files
Merge branch 'dev' into better_fix_curl
2 parents 78b9d71 + 04f44cd commit 14a96b1

File tree

4 files changed

+81
-12
lines changed

4 files changed

+81
-12
lines changed

docs/best_practices/nwbfile_metadata.rst

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,13 +202,19 @@ Species
202202
~~~~~~~
203203

204204
The ``species`` of a :nwb-schema:ref:`sec-Subject` should be set to the proper
205-
:wikipedia:`Latin binomial <Binomial_nomenclature>`. *E.g.*, a rat would be "Rattus norvegicus". Specific subspecies
206-
may be further specified by a dash, *e.g.*, "Rattus norvegicus - Long Evans".
205+
:wikipedia:`Latin binomial <Binomial_nomenclature>`. *E.g.*, a rat would be "Rattus norvegicus".
207206

208207
Check function: :py:meth:`~nwbinspector.checks.nwbfile_metadata.check_subject_species`
209208

210209

211210

211+
Strain
212+
~~~~~~~
213+
214+
The ``strain`` of a :nwb-schema:ref:`sec-Subject` should be set to further indicate the subspecies or breed or common genetic modification. *E.g.*, common strains for species "Rattus norvegicus" might include "Long Evans", "Sprague-Dawley", "Wistar", or "C57BL/6". If no specific strain is used, then simply indicate "Wild Type".
215+
216+
217+
212218
.. _best_practice_subject_age:
213219

214220
Age

nwbinspector/checks/nwbfile_metadata.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from pynwb.file import Subject
77

88
from ..register_checks import register_check, InspectorMessage, Importance
9+
from ..utils import is_module_installed
910

1011
duration_regex = (
1112
r"^P(?!$)(\d+(?:\.\d+)?Y)?(\d+(?:\.\d+)?M)?(\d+(?:\.\d+)?W)?(\d+(?:\.\d+)?D)?(T(?=\d)(\d+(?:\.\d+)?H)?(\d+(?:\.\d+)"
@@ -38,12 +39,31 @@ def check_session_start_time_future_date(nwbfile: NWBFile):
3839

3940

4041
@register_check(importance=Importance.BEST_PRACTICE_SUGGESTION, neurodata_type=NWBFile)
41-
def check_experimenter(nwbfile: NWBFile):
42+
def check_experimenter_exists(nwbfile: NWBFile):
4243
"""Check if an experimenter has been added for the session."""
4344
if not nwbfile.experimenter:
4445
return InspectorMessage(message="Experimenter is missing.")
4546

4647

48+
@register_check(importance=Importance.BEST_PRACTICE_SUGGESTION, neurodata_type=NWBFile)
49+
def check_experimenter_form(nwbfile: NWBFile):
50+
"""Check the text form of each experimenter to see if it matches the DANDI regex pattern."""
51+
if is_module_installed(module_name="dandi"):
52+
from dandischema.models import NAME_PATTERN # for most up to date version of the regex
53+
else:
54+
NAME_PATTERN = r"^([\w\s\-\.']+),\s+([\w\s\-\.']+)$" # copied on 7/12/22
55+
56+
for experimenter in nwbfile.experimenter:
57+
experimenter = experimenter.decode() if isinstance(experimenter, bytes) else experimenter
58+
if re.match(string=experimenter, pattern=NAME_PATTERN) is None:
59+
yield InspectorMessage(
60+
message=(
61+
f"The name of experimenter '{experimenter}' does not match the DANDI form "
62+
"(Last, First Middle or Last, First M.)."
63+
)
64+
)
65+
66+
4767
@register_check(importance=Importance.BEST_PRACTICE_SUGGESTION, neurodata_type=NWBFile)
4868
def check_experiment_description(nwbfile: NWBFile):
4969
"""Check if a description has been added for the session."""

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
long_description = f.read()
66
setup(
77
name="nwbinspector",
8-
version="0.4.8",
8+
version="0.4.9",
99
description="Tool to inspect NWB files for best practices compliance.",
1010
long_description=long_description,
1111
long_description_content_type="text/markdown",

tests/unit_tests/test_nwbfile_metadata.py

Lines changed: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
from nwbinspector import (
88
InspectorMessage,
99
Importance,
10-
check_experimenter,
10+
check_experimenter_exists,
11+
check_experimenter_form,
1112
check_experiment_description,
1213
check_institution,
1314
check_keywords,
@@ -70,37 +71,79 @@ def test_check_session_start_time_future_date_fail():
7071
)
7172

7273

73-
def test_check_experimenter_pass():
74+
def test_check_experimenter_exists_pass():
7475
nwbfile = NWBFile(
7576
session_description="",
7677
identifier=str(uuid4()),
7778
session_start_time=datetime.now().astimezone(),
7879
experimenter=["Last, First"],
7980
)
80-
assert check_experimenter(nwbfile) is None
81+
assert check_experimenter_exists(nwbfile) is None
8182

8283

83-
def test_check_experimenter_bytestring_pass():
84+
def test_check_experimenter_exists_bytestring_pass():
8485
nwbfile = NWBFile(
8586
session_description="",
8687
identifier=str(uuid4()),
8788
session_start_time=datetime.now().astimezone(),
8889
experimenter=[b"Last, First"],
8990
)
90-
assert check_experimenter(nwbfile) is None
91+
assert check_experimenter_exists(nwbfile) is None
9192

9293

93-
def test_check_experimenter_fail():
94-
assert check_experimenter(minimal_nwbfile) == InspectorMessage(
94+
def test_check_experimenter_exists_fail():
95+
assert check_experimenter_exists(minimal_nwbfile) == InspectorMessage(
9596
message="Experimenter is missing.",
9697
importance=Importance.BEST_PRACTICE_SUGGESTION,
97-
check_function_name="check_experimenter",
98+
check_function_name="check_experimenter_exists",
9899
object_type="NWBFile",
99100
object_name="root",
100101
location="/",
101102
)
102103

103104

105+
def test_check_experimenter_form_pass():
106+
nwbfile = NWBFile(
107+
session_description="",
108+
identifier=str(uuid4()),
109+
session_start_time=datetime.now().astimezone(),
110+
experimenter=["Last, First"],
111+
)
112+
assert check_experimenter_form(nwbfile=nwbfile) is None
113+
114+
115+
def test_check_experimenter_form_bytestring_pass():
116+
nwbfile = NWBFile(
117+
session_description="",
118+
identifier=str(uuid4()),
119+
session_start_time=datetime.now().astimezone(),
120+
experimenter=[b"Last, First"],
121+
)
122+
assert check_experimenter_form(nwbfile=nwbfile) is None
123+
124+
125+
def test_check_experimenter_form_fail():
126+
nwbfile = NWBFile(
127+
session_description="",
128+
identifier=str(uuid4()),
129+
session_start_time=datetime.now().astimezone(),
130+
experimenter=["First Middle Last"],
131+
)
132+
assert check_experimenter_form(nwbfile=nwbfile) == [
133+
InspectorMessage(
134+
message=(
135+
"The name of experimenter 'First Middle Last' does not match the DANDI form "
136+
"(Last, First Middle or Last, First M.)."
137+
),
138+
importance=Importance.BEST_PRACTICE_SUGGESTION,
139+
check_function_name="check_experimenter_form",
140+
object_type="NWBFile",
141+
object_name="root",
142+
location="/",
143+
)
144+
]
145+
146+
104147
def test_check_experiment_description():
105148
assert check_experiment_description(minimal_nwbfile) == InspectorMessage(
106149
message="Experiment description is missing.",

0 commit comments

Comments
 (0)