Skip to content

Commit

Permalink
Remove try/except around NWBZarrIO (#242)
Browse files Browse the repository at this point in the history
  • Loading branch information
rly authored Nov 22, 2024
1 parent 8376fe4 commit 6fd9d53
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 79 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

### Bug Fixes
* Fix reading of cached specs and caching of specs during export. @rly [#232](https://github.com/hdmf-dev/hdmf-zarr/pull/232)
* Fix hiding of pynwb compatibility errors. @rly [242](https://github.com/hdmf-dev/hdmf-zarr/pull/242)

## 0.9.0 (September 16, 2024)
### Enhancements
Expand Down
6 changes: 3 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ classifiers = [
"Topic :: Scientific/Engineering :: Medical Science Apps."
]
dependencies = [
'hdmf>=3.14.3',
'hdmf>=3.14.5',
'zarr>=2.11.0, <3.0', # pin below 3.0 until HDMF-zarr supports zarr 3.0
'numpy>=1.24',
'numcodecs>=0.9.1',
'pynwb>=2.5.0',
'pynwb>=2.8.3',
'threadpoolctl>=3.1.0',
]
dynamic = ["version"]
Expand Down Expand Up @@ -123,7 +123,7 @@ exclude = [
]
line-length = 120

[tool.ruff.per-file-ignores]
[tool.ruff.lint.per-file-ignores]
"docs/gallery/*" = ["E402", "T201"]
"src/*/__init__.py" = ["F401"]
"test_gallery.py" = ["T201"]
Expand Down
5 changes: 3 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
hdmf==3.14.5
zarr==2.18.3; python_version >= "3.10" # zarr 2.18.3 dropped support for python 3.9
zarr==2.18.2; python_version < "3.10"
pynwb==2.8.2
numpy==2.1.3
pynwb==2.8.3
numpy==2.1.3; python_version >= "3.10" # numpy 2.1.0 dropped support for python 3.9
numpy==2.0.2; python_version < "3.10"
numcodecs==0.13.1
threadpoolctl==3.5.0
144 changes: 70 additions & 74 deletions src/hdmf_zarr/nwb.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
"""Module with Zarr backend for NWB for integration with PyNWB"""
from warnings import warn
from pathlib import Path
from .backend import ZarrIO, SUPPORTED_ZARR_STORES

Expand All @@ -9,85 +8,82 @@
from hdmf.backends.io import HDMFIO
from hdmf.build import (BuildManager,
TypeMap)
try:
from pynwb import get_manager, get_type_map
from pynwb import get_manager, get_type_map

class NWBZarrIO(ZarrIO):
"""
IO backend for PyNWB for writing NWB files

This class is similar to the :py:class:`~pynwb.NWBHDF5IO` class in PyNWB. The main purpose of this class
is to perform default setup for BuildManager, loading or namespaces etc., in the context
of the NWB format.
"""
@docval(*get_docval(ZarrIO.__init__),
{'name': 'load_namespaces', 'type': bool,
'doc': 'whether or not to load cached namespaces from given path - not applicable in write mode',
'default': True},
{'name': 'extensions', 'type': (str, TypeMap, list),
'doc': 'a path to a namespace, a TypeMap, or a list consisting paths to namespaces and TypeMaps',
'default': None})
def __init__(self, **kwargs):
path, mode, manager, extensions, load_namespaces, synchronizer, storage_options = \
popargs('path', 'mode', 'manager', 'extensions',
'load_namespaces', 'synchronizer', 'storage_options', kwargs)
class NWBZarrIO(ZarrIO):
"""
IO backend for PyNWB for writing NWB files
io_modes_that_create_file = ['w', 'w-', 'x']
if mode in io_modes_that_create_file or manager is not None or extensions is not None:
load_namespaces = False
This class is similar to the :py:class:`~pynwb.NWBHDF5IO` class in PyNWB. The main purpose of this class
is to perform default setup for BuildManager, loading or namespaces etc., in the context
of the NWB format.
"""
@docval(*get_docval(ZarrIO.__init__),
{'name': 'load_namespaces', 'type': bool,
'doc': 'whether or not to load cached namespaces from given path - not applicable in write mode',
'default': True},
{'name': 'extensions', 'type': (str, TypeMap, list),
'doc': 'a path to a namespace, a TypeMap, or a list consisting paths to namespaces and TypeMaps',
'default': None})
def __init__(self, **kwargs):
path, mode, manager, extensions, load_namespaces, synchronizer, storage_options = \
popargs('path', 'mode', 'manager', 'extensions',
'load_namespaces', 'synchronizer', 'storage_options', kwargs)

if load_namespaces:
tm = get_type_map()
super(NWBZarrIO, self).load_namespaces(tm, path, storage_options)
manager = BuildManager(tm)
else:
if manager is not None and extensions is not None:
raise ValueError("'manager' and 'extensions' cannot be specified together")
elif extensions is not None:
manager = get_manager(extensions=extensions)
elif manager is None:
manager = get_manager()
super(NWBZarrIO, self).__init__(path,
manager=manager,
mode=mode,
synchronizer=synchronizer,
storage_options=storage_options)
io_modes_that_create_file = ['w', 'w-', 'x']
if mode in io_modes_that_create_file or manager is not None or extensions is not None:
load_namespaces = False

@docval({'name': 'src_io', 'type': HDMFIO, 'doc': 'the HDMFIO object for reading the data to export'},
{'name': 'nwbfile', 'type': 'NWBFile',
'doc': 'the NWBFile object to export. If None, then the entire contents of src_io will be exported',
'default': None},
{'name': 'write_args', 'type': dict, 'doc': 'arguments to pass to :py:meth:`write_builder`',
'default': dict()})
def export(self, **kwargs):
nwbfile = popargs('nwbfile', kwargs)
kwargs['container'] = nwbfile
super().export(**kwargs)
if load_namespaces:
tm = get_type_map()
super(NWBZarrIO, self).load_namespaces(tm, path, storage_options)
manager = BuildManager(tm)
else:
if manager is not None and extensions is not None:
raise ValueError("'manager' and 'extensions' cannot be specified together")
elif extensions is not None:
manager = get_manager(extensions=extensions)
elif manager is None:
manager = get_manager()
super(NWBZarrIO, self).__init__(path,
manager=manager,
mode=mode,
synchronizer=synchronizer,
storage_options=storage_options)

@staticmethod
@docval({'name': 'path',
'type': (str, Path, *SUPPORTED_ZARR_STORES),
'doc': 'the path to the Zarr file or a supported Zarr store'},
is_method=False)
def read_nwb(**kwargs):
"""
Helper factory method for reading an NWB file and return the NWBFile object
"""
# Retrieve the filepath
path = popargs('path', kwargs)
if isinstance(path, Path):
path = str(path)
# determine default storage options to use when opening a file from S3
storage_options = {}
if isinstance(path, str) and path.startswith(("s3://")):
storage_options = dict(anon=True)
@docval({'name': 'src_io', 'type': HDMFIO, 'doc': 'the HDMFIO object for reading the data to export'},
{'name': 'nwbfile', 'type': 'NWBFile',
'doc': 'the NWBFile object to export. If None, then the entire contents of src_io will be exported',
'default': None},
{'name': 'write_args', 'type': dict, 'doc': 'arguments to pass to :py:meth:`write_builder`',
'default': dict()})
def export(self, **kwargs):
nwbfile = popargs('nwbfile', kwargs)
kwargs['container'] = nwbfile
super().export(**kwargs)

# open the file with NWBZarrIO and rad the file
io = NWBZarrIO(path=path, mode="r", load_namespaces=True, storage_options=storage_options)
nwbfile = io.read()
@staticmethod
@docval({'name': 'path',
'type': (str, Path, *SUPPORTED_ZARR_STORES),
'doc': 'the path to the Zarr file or a supported Zarr store'},
is_method=False)
def read_nwb(**kwargs):
"""
Helper factory method for reading an NWB file and return the NWBFile object
"""
# Retrieve the filepath
path = popargs('path', kwargs)
if isinstance(path, Path):
path = str(path)
# determine default storage options to use when opening a file from S3
storage_options = {}
if isinstance(path, str) and path.startswith(("s3://")):
storage_options = dict(anon=True)

# return the NWBFile object
return nwbfile
# open the file with NWBZarrIO and rad the file
io = NWBZarrIO(path=path, mode="r", load_namespaces=True, storage_options=storage_options)
nwbfile = io.read()

except ImportError:
warn("PyNWB is not installed. Support for NWBZarrIO is disabled.")
# return the NWBFile object
return nwbfile

0 comments on commit 6fd9d53

Please sign in to comment.