Skip to content

Commit

Permalink
Merge branch 'dev' into expand
Browse files Browse the repository at this point in the history
  • Loading branch information
mavaylon1 authored Apr 6, 2024
2 parents b9771b5 + d85d0cb commit c0ce73b
Show file tree
Hide file tree
Showing 29 changed files with 776 additions and 137 deletions.
26 changes: 16 additions & 10 deletions .github/PULL_REQUEST_TEMPLATE/release.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
Prepare for release of HDMF [version]

### Before merging:
- [ ] Make sure all PRs to be included in this release have been merged to `dev`.
- [ ] Major and minor releases: Update package versions in `requirements.txt`, `requirements-dev.txt`,
`requirements-doc.txt`, `requirements-opt.txt`, and `environment-ros3.yml` to the latest versions,
and update dependency ranges in `pyproject.toml` and minimums in `requirements-min.txt` as needed.
Expand All @@ -10,23 +11,28 @@ Prepare for release of HDMF [version]
and any other locations as needed
- [ ] Update `pyproject.toml` as needed
- [ ] Update `README.rst` as needed
- [ ] Update `src/hdmf/common/hdmf-common-schema` submodule as needed. Check the version number and commit SHA manually
- [ ] Update `src/hdmf/common/hdmf-common-schema` submodule as needed. Check the version number and commit SHA
manually. Make sure we are using the latest release and not the latest commit on the `main` branch.
- [ ] Update changelog (set release date) in `CHANGELOG.md` and any other docs as needed
- [ ] Run tests locally including gallery tests, and inspect all warnings and outputs
(`pytest && python test_gallery.py`)
(`pytest && python test_gallery.py`). Try to remove all warnings.
- [ ] Run PyNWB tests locally including gallery and validation tests, and inspect all warnings and outputs
(`cd pynwb; python test.py -v > out.txt 2>&1`)
(`cd pynwb; git checkout dev; git pull; python test.py -v > out.txt 2>&1`)
- [ ] Run HDMF-Zarr tests locally including gallery and validation tests, and inspect all warnings and outputs
(`cd hdmf-zarr; pytest && python test_gallery.py`)
(`cd hdmf-zarr; git checkout dev; git pull; pytest && python test_gallery.py`)
- [ ] Test docs locally and inspect all warnings and outputs `cd docs; make clean && make html`
- [ ] Push changes to this PR and make sure all PRs to be included in this release have been merged
- [ ] Check that the readthedocs build for this PR succeeds (build latest to pull the new branch, then activate and
build docs for new branch): https://readthedocs.org/projects/hdmf/builds/
- [ ] After pushing this branch to GitHub, manually trigger the "Run all tests" GitHub Actions workflow on this
branch by going to https://github.com/hdmf-dev/hdmf/actions/workflows/run_all_tests.yml, selecting
"Run workflow" on the right, selecting this branch, and clicking "Run workflow". Make sure all tests pass.
- [ ] Check that the readthedocs build for this PR succeeds (see the PR check)

### After merging:
1. Create release by following steps in `docs/source/make_a_release.rst` or use alias `git pypi-release [tag]` if set up
2. After the CI bot creates the new release (wait ~10 min), update the release notes on the
[GitHub releases page](https://github.com/hdmf-dev/hdmf/releases) with the changelog
3. Check that the readthedocs "latest" and "stable" builds run and succeed
4. Update [conda-forge/hdmf-feedstock](https://github.com/conda-forge/hdmf-feedstock) with the latest version number
and SHA256 retrieved from PyPI > HDMF > Download Files > View hashes for the `.tar.gz` file. Re-render as needed
3. Check that the readthedocs "stable" build runs and succeeds
4. Either monitor [conda-forge/hdmf-feedstock](https://github.com/conda-forge/hdmf-feedstock) for the
regro-cf-autotick-bot bot to create a PR updating the version of HDMF to the latest PyPI release, usually within
24 hours of release, or manually create a PR updating `recipe/meta.yaml` with the latest version number
and SHA256 retrieved from PyPI > HDMF > Download Files > View hashes for the `.tar.gz` file. Re-render and update
dependencies as needed.
4 changes: 2 additions & 2 deletions .github/workflows/project_action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ jobs:
- name: Add to Developer Board
env:
TOKEN: ${{ steps.generate_token.outputs.token }}
uses: actions/add-to-project@v0.5.0
uses: actions/add-to-project@v0.6.1
with:
project-url: https://github.com/orgs/hdmf-dev/projects/7
github-token: ${{ env.TOKEN }}

- name: Add to Community Board
env:
TOKEN: ${{ steps.generate_token.outputs.token }}
uses: actions/add-to-project@v0.5.0
uses: actions/add-to-project@v0.6.1
with:
project-url: https://github.com/orgs/hdmf-dev/projects/8
github-token: ${{ env.TOKEN }}
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ repos:
# hooks:
# - id: black
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.2.0
rev: v0.3.3
hooks:
- id: ruff
# - repo: https://github.com/econchick/interrogate
Expand Down
39 changes: 26 additions & 13 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
# HDMF Changelog

## HDMF 3.14.0 (Upcoming)

### Enhancements
- Added `TermSetConfigurator` to automatically wrap fields with `TermSetWrapper` according to a configuration file. @mavaylon1 [#1016](https://github.com/hdmf-dev/hdmf/pull/1016)
- Updated `TermSetWrapper` to support validating a single field within a compound array. @mavaylon1 [#1061](https://github.com/hdmf-dev/hdmf/pull/1061)

## HDMF 3.13.0 (March 20, 2024)

### Enhancements
- Unwrap `TermSetWrapper` within the builder to support different backends more efficiently. @mavaylon1 [#1070](https://github.com/hdmf-dev/hdmf/pull/1070)
- Added docs page that lists limitations of support for the HDMF specification language. @rly [#1069](https://github.com/hdmf-dev/hdmf/pull/1069)
- Added warning when using `add_row` or `add_column` to add a ragged array to `DynamicTable` without an index parameter. @stephprince [#1066](https://github.com/hdmf-dev/hdmf/pull/1066)

## HDMF 3.12.2 (February 9, 2024)

### Bug fixes
Expand Down Expand Up @@ -126,8 +139,8 @@ will increase the minor version number to 3.10.0. See the 3.9.1 release notes be
## HDMF 3.6.0 (May 12, 2023)

### New features and minor improvements
- Updated `ExternalResources` to have `FileTable` and new methods to query data. the `ResourceTable` has been removed along with methods relating to `Resource`. @mavaylon [#850](https://github.com/hdmf-dev/hdmf/pull/850)
- Updated hdmf-common-schema version to 1.6.0. @mavaylon [#850](https://github.com/hdmf-dev/hdmf/pull/850)
- Updated `ExternalResources` to have `FileTable` and new methods to query data. the `ResourceTable` has been removed along with methods relating to `Resource`. @mavaylon1 [#850](https://github.com/hdmf-dev/hdmf/pull/850)
- Updated hdmf-common-schema version to 1.6.0. @mavaylon1 [#850](https://github.com/hdmf-dev/hdmf/pull/850)
- Added testing of HDMF-Zarr on PR and nightly. @rly [#859](https://github.com/hdmf-dev/hdmf/pull/859)
- Replaced `setup.py` with `pyproject.toml`. @rly [#844](https://github.com/hdmf-dev/hdmf/pull/844)
- Use `ruff` instead of `flake8`. @rly [#844](https://github.com/hdmf-dev/hdmf/pull/844)
Expand All @@ -141,7 +154,7 @@ will increase the minor version number to 3.10.0. See the 3.9.1 release notes be
[#853](https://github.com/hdmf-dev/hdmf/pull/853)

### Documentation and tutorial enhancements:
- Updated `ExternalResources` how to tutorial to include the new features. @mavaylon [#850](https://github.com/hdmf-dev/hdmf/pull/850)
- Updated `ExternalResources` how to tutorial to include the new features. @mavaylon1 [#850](https://github.com/hdmf-dev/hdmf/pull/850)

## HDMF 3.5.6 (April 28, 2023)

Expand Down Expand Up @@ -181,13 +194,13 @@ will increase the minor version number to 3.10.0. See the 3.9.1 release notes be

### Bug fixes
- Fixed issue with conda CI. @rly [#823](https://github.com/hdmf-dev/hdmf/pull/823)
- Fixed issue with deprecated `pkg_resources`. @mavaylon [#822](https://github.com/hdmf-dev/hdmf/pull/822)
- Fixed `hdmf.common` deprecation warning. @mavaylon [#826]((https://github.com/hdmf-dev/hdmf/pull/826)
- Fixed issue with deprecated `pkg_resources`. @mavaylon1 [#822](https://github.com/hdmf-dev/hdmf/pull/822)
- Fixed `hdmf.common` deprecation warning. @mavaylon1 [#826]((https://github.com/hdmf-dev/hdmf/pull/826)

### Internal improvements
- A number of typos fixed and Github action running codespell to ensure that no typo sneaks in [#825](https://github.com/hdmf-dev/hdmf/pull/825) was added.
- Added additional documentation for `__fields__` in `AbstactContainer`. @mavaylon [#827](https://github.com/hdmf-dev/hdmf/pull/827)
- Updated warning message for broken links. @mavaylon [#829](https://github.com/hdmf-dev/hdmf/pull/829)
- Added additional documentation for `__fields__` in `AbstactContainer`. @mavaylon1 [#827](https://github.com/hdmf-dev/hdmf/pull/827)
- Updated warning message for broken links. @mavaylon1 [#829](https://github.com/hdmf-dev/hdmf/pull/829)

## HDMF 3.5.1 (January 26, 2023)

Expand All @@ -206,9 +219,9 @@ will increase the minor version number to 3.10.0. See the 3.9.1 release notes be
- Added ``HDMFIO.__del__`` to ensure that I/O objects are being closed on delete. @oruebel[#811](https://github.com/hdmf-dev/hdmf/pull/811)

### Minor improvements
- Added support for reading and writing `ExternalResources` to and from denormalized TSV files. @mavaylon [#799](https://github.com/hdmf-dev/hdmf/pull/799)
- Changed the name of `ExternalResources.export_to_sqlite` to `ExternalResources.to_sqlite`. @mavaylon [#799](https://github.com/hdmf-dev/hdmf/pull/799)
- Updated the tutorial for `ExternalResources`. @mavaylon [#799](https://github.com/hdmf-dev/hdmf/pull/799)
- Added support for reading and writing `ExternalResources` to and from denormalized TSV files. @mavaylon1 [#799](https://github.com/hdmf-dev/hdmf/pull/799)
- Changed the name of `ExternalResources.export_to_sqlite` to `ExternalResources.to_sqlite`. @mavaylon1 [#799](https://github.com/hdmf-dev/hdmf/pull/799)
- Updated the tutorial for `ExternalResources`. @mavaylon1 [#799](https://github.com/hdmf-dev/hdmf/pull/799)
- Added `message` argument for assert methods defined by `hdmf.testing.TestCase` to allow developers to include custom error messages with asserts. @oruebel [#812](https://github.com/hdmf-dev/hdmf/pull/812)
- Clarify the expected chunk shape behavior for `DataChunkIterator`. @oruebel [#813](https://github.com/hdmf-dev/hdmf/pull/813)

Expand Down Expand Up @@ -349,7 +362,7 @@ the fields (i.e., when the constructor sets some fields to fixed values). @rly
- Plotted results in external resources tutorial. @oruebel (#667)
- Added support for Python 3.10. @rly (#679)
- Updated requirements. @rly @TheChymera (#681)
- Improved testing for `ExternalResources`. @mavaylon (#673)
- Improved testing for `ExternalResources`. @mavaylon1 (#673)
- Improved docs for export. @rly (#674)
- Enhanced data chunk iteration speeds through new ``GenericDataChunkIterator`` class. @CodyCBakerPhD (#672)
- Enhanced issue template forms on GitHub. @CodyCBakerPHD (#700)
Expand Down Expand Up @@ -425,7 +438,7 @@ the fields (i.e., when the constructor sets some fields to fixed values). @rly
- Allow passing ``index=True`` to ``DynamicTable.to_dataframe()`` to support returning `DynamicTableRegion` columns
as indices or Pandas DataFrame. @rly (#579)
- Improve ``DynamicTable`` documentation. @rly (#639)
- Updated external resources tutorial. @mavaylon (#611)
- Updated external resources tutorial. @mavaylon1 (#611)

### Breaking changes and deprecations
- Previously, when using ``DynamicTable.__getitem__`` or ``DynamicTable.get`` to access a selection of a
Expand Down Expand Up @@ -510,7 +523,7 @@ the fields (i.e., when the constructor sets some fields to fixed values). @rly
- Add experimental namespace to HDMF common schema. New data types should go in the experimental namespace
(hdmf-experimental) prior to being added to the core (hdmf-common) namespace. The purpose of this is to provide
a place to test new data types that may break backward compatibility as they are refined. @ajtritt (#545)
- `ExternalResources` was changed to support storing both names and URIs for resources. @mavaylon (#517, #548)
- `ExternalResources` was changed to support storing both names and URIs for resources. @mavaylon1 (#517, #548)
- The `VocabData` data type was replaced by `EnumData` to provide more flexible support for data from a set of
fixed values.
- Added `AlignedDynamicTable`, which defines a `DynamicTable` that supports storing a collection of sub-tables.
Expand Down
14 changes: 14 additions & 0 deletions docs/gallery/plot_term_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
"""
from hdmf.common import DynamicTable, VectorData
import os
import numpy as np

try:
import linkml_runtime # noqa: F401
Expand Down Expand Up @@ -129,6 +130,19 @@
data=TermSetWrapper(value=['Homo sapiens'], termset=terms)
)

######################################################
# Validate Compound Data with TermSetWrapper
# ----------------------------------------------------
# :py:class:`~hdmf.term_set.TermSetWrapper` can be wrapped around compound data.
# The user will set the field within the compound data type that is to be validated
# with the termset.
c_data = np.array([('Homo sapiens', 24)], dtype=[('species', 'U50'), ('age', 'i4')])
data = VectorData(
name='species',
description='...',
data=TermSetWrapper(value=c_data, termset=terms, field='species')
)

######################################################
# Validate Attributes with TermSetWrapper
# ----------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ If you use HDMF in your research, please use the following citation:
building_api
export
validation
spec_language_support

.. toctree::
:hidden:
Expand Down
21 changes: 21 additions & 0 deletions docs/source/spec_language_support.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@

.. _spec_language_support:

===========================================
Support for the HDMF Specification Language
===========================================

The HDMF API provides nearly full support for all features of the `HDMF Specification Language`_
version 3.0.0, except for the following:

1. Attributes containing multiple references (see `#833`_)
2. Certain text and integer values for quantity (see `#423`_, `#531`_)
3. Datasets that do not have a data_type_inc/data_type_def and contain either a reference dtype or a compound dtype (see `#737`_)
4. Passing dataset dtype and shape from parent data type to child data type (see `#320`_)

.. _HDMF Specification Language: https://hdmf-schema-language.readthedocs.io
.. _#833: https://github.com/hdmf-dev/hdmf/issues/833
.. _#423: https://github.com/hdmf-dev/hdmf/issues/423
.. _#531: https://github.com/hdmf-dev/hdmf/issues/531
.. _#737: https://github.com/hdmf-dev/hdmf/issues/737
.. _#320: https://github.com/hdmf-dev/hdmf/issues/320
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ classifiers = [
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"License :: OSI Approved :: BSD License",
"Development Status :: 5 - Production/Stable",
"Operating System :: OS Independent",
Expand Down
2 changes: 1 addition & 1 deletion requirements-dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# compute coverage, and create test environments. note that depending on the version of python installed, different
# versions of requirements may be installed due to package incompatibilities.
#
black==23.10.1
black==24.3.0
codespell==2.2.6
coverage==7.3.2
pre-commit==3.5.0
Expand Down
12 changes: 5 additions & 7 deletions requirements-opt.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
# pinned dependencies that are optional. used to reproduce an entire development environment to use HDMF
tqdm==4.66.1
zarr==2.16.1
linkml-runtime==1.6.0; python_version >= "3.9"
schemasheets==0.1.24; python_version >= "3.9"
oaklib==0.5.20; python_version >= "3.9"
pydantic==1.10.13 # linkml-runtime 1.6.0 and related packages require pydantic<2
pyyaml==6.0.1; python_version >= "3.9"
tqdm==4.66.2
zarr==2.17.1
linkml-runtime==1.7.4; python_version >= "3.9"
schemasheets==0.2.1; python_version >= "3.9"
oaklib==0.5.32; python_version >= "3.9"
2 changes: 1 addition & 1 deletion src/hdmf/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from .container import Container, Data, DataRegion, HERDManager
from .region import ListSlicer
from .utils import docval, getargs
from .term_set import TermSet, TermSetWrapper
from .term_set import TermSet, TermSetWrapper, TypeConfigurator


@docval(
Expand Down
5 changes: 0 additions & 5 deletions src/hdmf/backends/hdf5/h5tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
from ...build import (Builder, GroupBuilder, DatasetBuilder, LinkBuilder, BuildManager, RegionBuilder,
ReferenceBuilder, TypeMap, ObjectMapper)
from ...container import Container
from ...term_set import TermSetWrapper
from ...data_utils import AbstractDataChunkIterator
from ...spec import RefSpec, DtypeSpec, NamespaceCatalog
from ...utils import docval, getargs, popargs, get_data_shape, get_docval, StrDataset
Expand Down Expand Up @@ -1103,10 +1102,6 @@ def write_dataset(self, **kwargs): # noqa: C901
data = data.data
else:
options['io_settings'] = {}
if isinstance(data, TermSetWrapper):
# This is for when the wrapped item is a dataset
# (refer to objectmapper.py for wrapped attributes)
data = data.value
attributes = builder.attributes
options['dtype'] = builder.dtype
dset = None
Expand Down
18 changes: 13 additions & 5 deletions src/hdmf/build/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from .builders import DatasetBuilder, GroupBuilder, LinkBuilder, Builder, BaseBuilder
from .classgenerator import ClassGenerator, CustomClassGenerator, MCIClassGenerator
from ..container import AbstractContainer, Container, Data
from ..term_set import TypeConfigurator
from ..spec import DatasetSpec, GroupSpec, NamespaceCatalog
from ..spec.spec import BaseStorageSpec
from ..utils import docval, getargs, ExtenderMeta, get_docval
Expand Down Expand Up @@ -391,25 +392,32 @@ def data_type(self):


class TypeMap:
''' A class to maintain the map between ObjectMappers and AbstractContainer classes
'''
"""
A class to maintain the map between ObjectMappers and AbstractContainer classes
"""

@docval({'name': 'namespaces', 'type': NamespaceCatalog, 'doc': 'the NamespaceCatalog to use', 'default': None},
{'name': 'mapper_cls', 'type': type, 'doc': 'the ObjectMapper class to use', 'default': None})
{'name': 'mapper_cls', 'type': type, 'doc': 'the ObjectMapper class to use', 'default': None},
{'name': 'type_config', 'type': TypeConfigurator, 'doc': 'The TypeConfigurator to use.',
'default': None})
def __init__(self, **kwargs):
namespaces, mapper_cls = getargs('namespaces', 'mapper_cls', kwargs)
namespaces, mapper_cls, type_config = getargs('namespaces', 'mapper_cls', 'type_config', kwargs)
if namespaces is None:
namespaces = NamespaceCatalog()
if mapper_cls is None:
from .objectmapper import ObjectMapper # avoid circular import
mapper_cls = ObjectMapper
if type_config is None:
type_config = TypeConfigurator()
self.__ns_catalog = namespaces
self.__mappers = dict() # already constructed ObjectMapper classes
self.__mapper_cls = dict() # the ObjectMapper class to use for each container type
self.__container_types = OrderedDict()
self.__data_types = dict()
self.__default_mapper_cls = mapper_cls
self.__class_generator = ClassGenerator()
self.type_config = type_config

self.register_generator(CustomClassGenerator)
self.register_generator(MCIClassGenerator)

Expand All @@ -422,7 +430,7 @@ def container_types(self):
return self.__container_types

def __copy__(self):
ret = TypeMap(copy(self.__ns_catalog), self.__default_mapper_cls)
ret = TypeMap(copy(self.__ns_catalog), self.__default_mapper_cls, self.type_config)
ret.merge(self)
return ret

Expand Down
6 changes: 5 additions & 1 deletion src/hdmf/build/objectmapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -752,7 +752,11 @@ def build(self, **kwargs):
% (container.__class__.__name__, container.name, repr(source)))
try:
# use spec_dtype from self.spec when spec_ext does not specify dtype
bldr_data, dtype = self.convert_dtype(spec, container.data, spec_dtype=spec_dtype)
if isinstance(container.data, TermSetWrapper):
data = container.data.value
else:
data = container.data
bldr_data, dtype = self.convert_dtype(spec, data, spec_dtype=spec_dtype)
except Exception as ex:
msg = 'could not resolve dtype for %s \'%s\'' % (type(container).__name__, container.name)
raise Exception(msg) from ex
Expand Down
Loading

0 comments on commit c0ce73b

Please sign in to comment.