Skip to content

Commit a3d49f5

Browse files
author
Cody Baker
committed
saving state
1 parent 04f44cd commit a3d49f5

File tree

2 files changed

+100
-6
lines changed

2 files changed

+100
-6
lines changed

nwbinspector/nwbinspector.py

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from types import FunctionType
1414
from warnings import filterwarnings, warn
1515
from distutils.util import strtobool
16-
from time import sleep
16+
from collections import defaultdict
1717

1818
import click
1919
import pynwb
@@ -154,10 +154,7 @@ def configure_checks(
154154
@click.argument("path")
155155
@click.option("--modules", help="Modules to import prior to reading the file(s).")
156156
@click.option(
157-
"--report-file-path",
158-
default=None,
159-
help="Save path for the report file.",
160-
type=click.Path(writable=True),
157+
"--report-file-path", default=None, help="Save path for the report file.", type=click.Path(writable=True),
161158
)
162159
@click.option("--overwrite", help="Overwrite an existing report file at the location.", is_flag=True)
163160
@click.option("--levels", help="Comma-separated names of InspectorMessage attributes to organize by.")
@@ -370,6 +367,30 @@ def inspect_all(
370367
# Filtering of checks should apply after external modules are imported, in case those modules have their own checks
371368
checks = configure_checks(config=config, ignore=ignore, select=select, importance_threshold=importance_threshold)
372369

370+
# Manual identifier check over all files in the folder path
371+
identifiers = defaultdict(list)
372+
for nwbfile_path in nwbfiles:
373+
with pynwb.NWBHDF5IO(path=nwbfile_path, mode="r", driver=driver) as io:
374+
nwbfile = robust_s3_read(io.read)
375+
identifiers[nwbfile.identifier].append(nwbfile_path)
376+
if len(identifiers) != len(nwbfiles):
377+
for identifier, nwbfiles_with_identifier in identifiers.items():
378+
if len(nwbfiles_with_identifier) > 1:
379+
yield InspectorMessage(
380+
message=(
381+
f"The identifier '{identifier}' is used across the .nwb files: "
382+
f"{[str(x) for x in nwbfiles_with_identifier]}\n"
383+
"The identifier of any NWBFile should be a completely unique value - "
384+
"we recommend using uuid4 to achieve this."
385+
),
386+
importance=Importance.CRITICAL,
387+
check_function_name="check_unique_identifiers",
388+
object_type="NWBFile",
389+
object_name="root",
390+
location="/",
391+
file_path=str(Path(nwbfiles_with_identifier[0]).parent),
392+
)
393+
373394
nwbfiles_iterable = nwbfiles
374395
if progress_bar:
375396
nwbfiles_iterable = tqdm(nwbfiles_iterable, **progress_bar_options)

tests/test_inspector.py

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from tempfile import mkdtemp
55
from pathlib import Path
66
from unittest import TestCase
7+
from datetime import datetime
78

89
import numpy as np
910
from pynwb import NWBFile, NWBHDF5IO, TimeSeries
@@ -144,7 +145,7 @@ def assertLogFileContentsEqual(
144145
if ".nwb" in test_line:
145146
# Transform temporary testing path and formatted to hardcoded fake path
146147
str_loc = test_line.find(".nwb")
147-
correction_str = test_line.replace(test_line[5 : str_loc - 8], "./")
148+
correction_str = test_line.replace(test_line[5 : str_loc - 8], "./") # noqa E203 (black)
148149
test_file_lines[line_number] = correction_str
149150
self.assertEqual(first=test_file_lines[skip_first_n_lines:-1], second=true_file_lines)
150151

@@ -561,3 +562,75 @@ def test_dandiset_streaming_cli_parallel(self):
561562
f"> {console_output_file}"
562563
)
563564
self.assertFileExists(path=self.tempdir / "test_nwbinspector_streaming_report_7.txt")
565+
566+
567+
class TestCheckUniqueIdentifiersPass(TestCase):
568+
maxDiff = None
569+
570+
@classmethod
571+
def setUpClass(cls):
572+
cls.tempdir = Path(mkdtemp())
573+
num_nwbfiles = 3
574+
unique_id_nwbfiles = list()
575+
for j in range(num_nwbfiles):
576+
unique_id_nwbfiles.append(make_minimal_nwbfile())
577+
578+
cls.unique_id_nwbfile_paths = [str(cls.tempdir / f"unique_id_testing{j}.nwb") for j in range(num_nwbfiles)]
579+
for nwbfile_path, nwbfile in zip(cls.unique_id_nwbfile_paths, unique_id_nwbfiles):
580+
with NWBHDF5IO(path=nwbfile_path, mode="w") as io:
581+
io.write(nwbfile)
582+
583+
@classmethod
584+
def tearDownClass(cls):
585+
rmtree(cls.tempdir)
586+
587+
def test_check_unique_identifiers_pass(self):
588+
assert list(inspect_all(path=self.tempdir, select=["check_data_orientation"])) == []
589+
590+
591+
class TestCheckUniqueIdentifiersFail(TestCase):
592+
maxDiff = None
593+
594+
@classmethod
595+
def setUpClass(cls):
596+
cls.tempdir = Path(mkdtemp())
597+
num_nwbfiles = 3
598+
non_unique_id_nwbfiles = list()
599+
for j in range(num_nwbfiles):
600+
non_unique_id_nwbfiles.append(
601+
NWBFile(
602+
session_description="",
603+
identifier="not a unique identifier!",
604+
session_start_time=datetime.now().astimezone(),
605+
)
606+
)
607+
608+
cls.non_unique_id_nwbfile_paths = [
609+
str(cls.tempdir / f"non_unique_id_testing{j}.nwb") for j in range(num_nwbfiles)
610+
]
611+
for nwbfile_path, nwbfile in zip(cls.non_unique_id_nwbfile_paths, non_unique_id_nwbfiles):
612+
with NWBHDF5IO(path=nwbfile_path, mode="w") as io:
613+
io.write(nwbfile)
614+
615+
@classmethod
616+
def tearDownClass(cls):
617+
rmtree(cls.tempdir)
618+
619+
def test_check_unique_identifiers_fail(self):
620+
print(list(inspect_all(path=self.tempdir, select=["check_data_orientation"])))
621+
assert list(inspect_all(path=self.tempdir, select=["check_data_orientation"])) == [
622+
InspectorMessage(
623+
message=(
624+
"The identifier 'not a unique identifier!' is used across the .nwb files: "
625+
f"{[str(x) for x in self.non_unique_id_nwbfile_paths]}\n"
626+
"The identifier of any NWBFile should be a completely unique value - "
627+
"we recommend using uuid4 to achieve this."
628+
),
629+
importance=Importance.CRITICAL,
630+
check_function_name="check_unique_identifiers",
631+
object_type="NWBFile",
632+
object_name="root",
633+
location="/",
634+
file_path=str(Path(self.non_unique_id_nwbfile_paths[0]).parent),
635+
)
636+
]

0 commit comments

Comments
 (0)