diff --git a/CHANGELOG.md b/CHANGELOG.md index 374ad780c..c9c9afcde 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ ## Bug Fixes * datetime objects now can be validated as conversion options [#1139](https://github.com/catalystneuro/neuroconv/pull/1126) +* Make `NWBMetaDataEncoder` public again [PR #1142](https://github.com/catalystneuro/neuroconv/pull/1142) * Fix a bug where data in `DeepLabCutInterface` failed to write when `ndx-pose` was not imported. [#1144](https://github.com/catalystneuro/neuroconv/pull/1144) * `SpikeGLXConverterPipe` converter now accepts multi-probe structures with multi-trigger and does not assume a specific folder structure [#1150](https://github.com/catalystneuro/neuroconv/pull/1150) * `SpikeGLXNIDQInterface` is no longer written as an ElectricalSeries [#1152](https://github.com/catalystneuro/neuroconv/pull/1152) diff --git a/docs/api/utils.rst b/docs/api/utils.rst index 4f19f7cee..c9b85b14c 100644 --- a/docs/api/utils.rst +++ b/docs/api/utils.rst @@ -8,6 +8,8 @@ Dictionaries JSON Schema ----------- .. automodule:: neuroconv.utils.json_schema + :members: + :exclude-members: NWBMetaDataEncoder Common Reused Types ------------------- diff --git a/src/neuroconv/basedatainterface.py b/src/neuroconv/basedatainterface.py index 272abbd0c..530eec60c 100644 --- a/src/neuroconv/basedatainterface.py +++ b/src/neuroconv/basedatainterface.py @@ -19,12 +19,11 @@ ) from .tools.nwb_helpers._metadata_and_file_helpers import _resolve_backend from .utils import ( - _NWBMetaDataEncoder, get_json_schema_from_method_signature, load_dict_from_file, ) from .utils.dict import DeepDict -from .utils.json_schema import _NWBSourceDataEncoder +from .utils.json_schema import _NWBMetaDataEncoder, _NWBSourceDataEncoder class BaseDataInterface(ABC): diff --git a/src/neuroconv/datainterfaces/behavior/neuralynx/neuralynx_nvt_interface.py b/src/neuroconv/datainterfaces/behavior/neuralynx/neuralynx_nvt_interface.py index e161387f0..213adf731 100644 --- a/src/neuroconv/datainterfaces/behavior/neuralynx/neuralynx_nvt_interface.py +++ b/src/neuroconv/datainterfaces/behavior/neuralynx/neuralynx_nvt_interface.py @@ -8,7 +8,8 @@ from .nvt_utils import read_data, read_header from ....basetemporalalignmentinterface import BaseTemporalAlignmentInterface -from ....utils import DeepDict, _NWBMetaDataEncoder, get_base_schema +from ....utils import DeepDict, get_base_schema +from ....utils.json_schema import _NWBMetaDataEncoder from ....utils.path import infer_path diff --git a/src/neuroconv/tools/nwb_helpers/_metadata_and_file_helpers.py b/src/neuroconv/tools/nwb_helpers/_metadata_and_file_helpers.py index c3aaea48d..355c86510 100644 --- a/src/neuroconv/tools/nwb_helpers/_metadata_and_file_helpers.py +++ b/src/neuroconv/tools/nwb_helpers/_metadata_and_file_helpers.py @@ -8,7 +8,6 @@ from datetime import datetime from pathlib import Path from typing import Literal, Optional -from warnings import warn from hdmf_zarr import NWBZarrIO from pydantic import FilePath @@ -26,7 +25,7 @@ def get_module(nwbfile: NWBFile, name: str, description: str = None): """Check if processing module exists. If not, create it. Then return module.""" if name in nwbfile.processing: if description is not None and nwbfile.processing[name].description != description: - warn( + warnings.warn( "Custom description given to get_module does not match existing module description! " "Ignoring custom description." ) @@ -157,7 +156,7 @@ def _attempt_cleanup_of_existing_nwbfile(nwbfile_path: Path) -> None: # Windows in particular can encounter errors at this step except PermissionError: # pragma: no cover message = f"Unable to remove NWB file located at {nwbfile_path.absolute()}! Please remove it manually." - warn(message=message, stacklevel=2) + warnings.warn(message=message, stacklevel=2) @contextmanager diff --git a/src/neuroconv/tools/testing/data_interface_mixins.py b/src/neuroconv/tools/testing/data_interface_mixins.py index fab049165..dc45cec53 100644 --- a/src/neuroconv/tools/testing/data_interface_mixins.py +++ b/src/neuroconv/tools/testing/data_interface_mixins.py @@ -33,7 +33,7 @@ configure_backend, get_default_backend_configuration, ) -from neuroconv.utils import _NWBMetaDataEncoder +from neuroconv.utils.json_schema import _NWBMetaDataEncoder class DataInterfaceTestMixin: diff --git a/src/neuroconv/utils/__init__.py b/src/neuroconv/utils/__init__.py index c0061a983..f7163f3ff 100644 --- a/src/neuroconv/utils/__init__.py +++ b/src/neuroconv/utils/__init__.py @@ -7,7 +7,7 @@ load_dict_from_file, ) from .json_schema import ( - _NWBMetaDataEncoder, + NWBMetaDataEncoder, fill_defaults, get_base_schema, get_metadata_schema_for_icephys, diff --git a/src/neuroconv/utils/json_schema.py b/src/neuroconv/utils/json_schema.py index 07dc3321f..6aa7a75d0 100644 --- a/src/neuroconv/utils/json_schema.py +++ b/src/neuroconv/utils/json_schema.py @@ -16,13 +16,8 @@ from pynwb.icephys import IntracellularElectrode -class _NWBMetaDataEncoder(json.JSONEncoder): - """ - Custom JSON encoder for NWB metadata. - - This encoder extends the default JSONEncoder class and provides custom serialization - for certain data types commonly used in NWB metadata. - """ +class _GenericNeuroconvEncoder(json.JSONEncoder): + """Generic JSON encoder for NeuroConv data.""" def default(self, obj): """ @@ -36,45 +31,38 @@ def default(self, obj): if isinstance(obj, np.generic): return obj.item() + # Numpy arrays should be converted to lists if isinstance(obj, np.ndarray): return obj.tolist() + # Over-write behaviors for Paths + if isinstance(obj, Path): + return str(obj) + # The base-class handles it return super().default(obj) -class _NWBSourceDataEncoder(_NWBMetaDataEncoder): +class _NWBMetaDataEncoder(_GenericNeuroconvEncoder): """ - Custom JSON encoder for data interface source data (i.e. kwargs). - - This encoder extends the default JSONEncoder class and provides custom serialization - for certain data types commonly used in interface source data. + Custom JSON encoder for NWB metadata. """ - def default(self, obj): - # Over-write behaviors for Paths - if isinstance(obj, Path): - return str(obj) - - return super().default(obj) +class _NWBSourceDataEncoder(_GenericNeuroconvEncoder): + """ + Custom JSON encoder for data interface source data (i.e. kwargs). + """ -class _NWBConversionOptionsEncoder(_NWBMetaDataEncoder): +class _NWBConversionOptionsEncoder(_GenericNeuroconvEncoder): """ Custom JSON encoder for conversion options of the data interfaces and converters (i.e. kwargs). - - This encoder extends the default JSONEncoder class and provides custom serialization - for certain data types commonly used in interface source data. """ - def default(self, obj): - - # Over-write behaviors for Paths - if isinstance(obj, Path): - return str(obj) - return super().default(obj) +# This is used in the Guide so we will keep it public. +NWBMetaDataEncoder = _NWBMetaDataEncoder def get_base_schema( diff --git a/tests/test_minimal/test_tools/test_expand_paths.py b/tests/test_minimal/test_tools/test_expand_paths.py index 9e7f03631..59924f93a 100644 --- a/tests/test_minimal/test_tools/test_expand_paths.py +++ b/tests/test_minimal/test_tools/test_expand_paths.py @@ -9,7 +9,7 @@ from neuroconv.tools import LocalPathExpander from neuroconv.tools.path_expansion import construct_path_template from neuroconv.tools.testing import generate_path_expander_demo_ibl -from neuroconv.utils import _NWBMetaDataEncoder +from neuroconv.utils.json_schema import _NWBMetaDataEncoder def create_test_directories_and_files( diff --git a/tests/test_minimal/test_utils/test_json_schema_utils.py b/tests/test_minimal/test_utils/test_json_schema_utils.py index 4edf1e724..5ce63ee56 100644 --- a/tests/test_minimal/test_utils/test_json_schema_utils.py +++ b/tests/test_minimal/test_utils/test_json_schema_utils.py @@ -6,12 +6,12 @@ from pynwb.ophys import ImagingPlane, TwoPhotonSeries from neuroconv.utils import ( - _NWBMetaDataEncoder, dict_deep_update, fill_defaults, get_schema_from_hdmf_class, load_dict_from_file, ) +from neuroconv.utils.json_schema import _NWBMetaDataEncoder def compare_dicts(a: dict, b: dict):