diff --git a/src/nwbinspector/nwbinspector.py b/src/nwbinspector/nwbinspector.py index 748f6fe7a..6940e72b0 100644 --- a/src/nwbinspector/nwbinspector.py +++ b/src/nwbinspector/nwbinspector.py @@ -604,6 +604,32 @@ def inspect_nwbfile( ) +def _intercept_in_vitro(nwbfile_object: pynwb.NWBFile, checks: Optional[list] = None) -> List[callable]: + """If the special 'in_vitro' subject_id is specified, return a truncated list of checks to run.""" + subject_related_check_names = [ + "check_subject_exists", + "check_subject_id_exists", + "check_subject_sex", + "check_subject_species_exists", + "check_subject_species_form", + "check_subject_age", + "check_subject_proper_age_range", + ] + subject_related_dandi_requirements = [ + check.importance == Importance.CRITICAL for check in checks if check.__name__ in subject_related_check_names + ] + + subject = getattr(nwbfile_object, "subject", None) + if ( + any(subject_related_dandi_requirements) + and subject is not None + and getattr(subject, "subject_id", "") == "in_vitro" + ): + non_subject_checks = [check for check in checks if check.__name__ not in subject_related_check_names] + return non_subject_checks + return checks + + def inspect_nwbfile_object( nwbfile_object: pynwb.NWBFile, checks: Optional[list] = None, @@ -651,7 +677,9 @@ def inspect_nwbfile_object( checks=checks, config=config, ignore=ignore, select=select, importance_threshold=importance_threshold ) - for inspector_message in run_checks(nwbfile=nwbfile_object, checks=checks): + subject_dependent_checks = _intercept_in_vitro(nwbfile_object=nwbfile_object, checks=checks) + + for inspector_message in run_checks(nwbfile=nwbfile_object, checks=subject_dependent_checks): yield inspector_message diff --git a/tests/test_inspector.py b/tests/test_inspector.py index 5d540453a..385f77413 100644 --- a/tests/test_inspector.py +++ b/tests/test_inspector.py @@ -1,5 +1,4 @@ import os -import pytest from shutil import rmtree from tempfile import mkdtemp from pathlib import Path @@ -7,6 +6,7 @@ from datetime import datetime import numpy as np +import pynwb from pynwb import NWBFile, NWBHDF5IO, TimeSeries from pynwb.file import TimeIntervals from pynwb.behavior import SpatialSeries, Position @@ -22,7 +22,7 @@ check_subject_exists, load_config, ) -from nwbinspector import inspect_all, inspect_nwbfile, available_checks +from nwbinspector import inspect_all, inspect_nwbfile, inspect_nwbfile_object, available_checks from nwbinspector.register_checks import Severity, InspectorMessage, register_check from nwbinspector.tools import make_minimal_nwbfile from nwbinspector.utils import FilePathType @@ -727,3 +727,18 @@ def test_check_unique_identifiers_fail(self): file_path=str(self.tempdir), ) ] + + +def test_dandi_config_in_vitro_injection(): + """Test that a special subject_id of 'in_vitro' properly excludes meaningless CRITICAL-elevated subject checks.""" + nwbfile = pynwb.testing.mock.file.mock_NWBFile( + subject=pynwb.file.Subject( + subject_id="in_vitro", description="A detailed description about the in vitro setup." + ) + ) + config = load_config(filepath_or_keyword="dandi") + importance_threshold = "CRITICAL" + messages = list( + inspect_nwbfile_object(nwbfile_object=nwbfile, config=config, importance_threshold=importance_threshold) + ) + assert messages == []