Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enh/getcachednamespaces #1432

Closed
wants to merge 12 commits into from
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
@weiglszonja (#1486)
- Improved warning text when dimensions are not matched in `TimeSeries`, `ElectricalSeries`, and `RoiResponseSeries`.
@rly (#1491)
- Added ``pywnb.validate.get_cached_namespaces_to_validate`` function to facilitate validation of files against cached
namespaces when using ``pynwb.validate`` from Python directly. @oruebel (#1432)

### Documentation and tutorial enhancements:
- Added tutorial on annotating data via ``TimeIntervals``. @oruebel (#1390)
Expand Down
58 changes: 46 additions & 12 deletions src/pynwb/validate.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,51 @@ def _validate_helper(**kwargs):
return (errors is not None and len(errors) > 0)


def get_cached_namespaces_to_validate(path):
"""
Determine the most specific namespace(s) (i.e., extensions) that are cached in the given
NWB file that should be used for validation.

Example
-------

The following example illustrates how we can use this function to validate against namespaces
cached in a file. This is useful, e.g., when a file was created using an extension

>>> from pynwb import validate
>>> from pynwb.validate import get_cached_namespaces_to_validate
>>> path = "my_nwb_file.nwb"
>>> validate_namespaces, manager, cached_namespaces = get_cached_namespaces_to_validate(path)
>>> with NWBHDF5IO(path, "r", manager=manager) as reader:
>>> errors = []
>>> for ns in validate_namespaces:
>>> errors += validate(io=reader, namespace=ns)

:param path: Path for the NWB file
:return: Tuple with:
- List of strings with the most specific namespace(s) to use for validation.
- BuildManager object for opening the file for validation
- Dict with the full result from NWBHDF5IO.load_namespaces
"""
catalog = NamespaceCatalog(NWBGroupSpec, NWBDatasetSpec, NWBNamespace)
ns_deps = NWBHDF5IO.load_namespaces(catalog, path)
# determine which namespaces are the most specific (i.e. extensions) and validate against those
s = set(ns_deps.keys())
for k in ns_deps:
s -= ns_deps[k].keys()
# TODO remove this workaround for issue https://github.com/NeurodataWithoutBorders/pynwb/issues/1357
s.discard('hdmf-experimental') # remove validation of hdmf-experimental for now
namespaces = sorted(s)

if len(namespaces) > 0:
tm = TypeMap(catalog)
manager = BuildManager(tm)
else:
manager = None

return namespaces, manager, ns_deps


def main(): # noqa: C901

ep = """
Expand Down Expand Up @@ -69,21 +114,10 @@ def main(): # noqa: C901
continue

if args.cached_namespace:
catalog = NamespaceCatalog(NWBGroupSpec, NWBDatasetSpec, NWBNamespace)
ns_deps = NWBHDF5IO.load_namespaces(catalog, path)
s = set(ns_deps.keys()) # determine which namespaces are the most
for k in ns_deps: # specific (i.e. extensions) and validate
s -= ns_deps[k].keys() # against those
# TODO remove this workaround for issue https://github.com/NeurodataWithoutBorders/pynwb/issues/1357
if 'hdmf-experimental' in s:
s.remove('hdmf-experimental') # remove validation of hdmf-experimental for now
namespaces = list(sorted(s))
namespaces, manager, ns_deps = get_cached_namespaces_to_validate(path)
if len(namespaces) > 0:
tm = TypeMap(catalog)
manager = BuildManager(tm)
specloc = "cached namespace information"
else:
manager = None
namespaces = [CORE_NAMESPACE]
specloc = "pynwb namespace information"
print("The file {} has no cached namespace information. "
Expand Down