Skip to content

Commit

Permalink
Round trip unit tests are working
Browse files Browse the repository at this point in the history
  • Loading branch information
VisLab committed Jan 18, 2024
1 parent 5aab6b6 commit 5fa6597
Show file tree
Hide file tree
Showing 10 changed files with 467 additions and 464 deletions.
8 changes: 4 additions & 4 deletions spec/ndx-hed.extensions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ datasets:
HED tags are used, the HED schema version must be specified in the NWB file using
the HedMetadata type.
groups:
- neurodata_type_def: HedVersion
- neurodata_type_def: HedVersionAttr
neurodata_type_inc: LabMetaData
name: hed_version
doc: An extension of LabMetaData to store the Hierarchical Event Descriptor (HED)
Expand All @@ -17,14 +17,14 @@ groups:
dtype: text
doc: The version of the HED schema used to validate the HED tags, e.g., '8.2.0'.
Required if HED tags are used in the NWB file.
- neurodata_type_def: HedVersion1
- neurodata_type_def: HedVersion
neurodata_type_inc: LabMetaData
name: hed_version1
name: hed_version
doc: An extension of LabMetaData to store the Hierarchical Event Descriptor (HED)
schema version. TODO When merged with core, this will no longer inherit from LabMetaData
but from NWBContainer and be placed optionally in /general.
datasets:
- name: version
dtype: text
doc: HED scheam version to use for this dataset
doc: HED schema version to use for this dataset
quantity: '?'
4 changes: 2 additions & 2 deletions src/pynwb/ndx_hed/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,6 @@
# # Remove these functions from the package
del load_namespaces, get_class

from .hed_version import HedVersion
from .hed_version_attr import HedVersionAttr
from .hed_tags import HedTags
from .hed_version1 import HedVersion1
from .hed_version import HedVersion
72 changes: 32 additions & 40 deletions src/pynwb/ndx_hed/hed_tags.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,32 @@
from collections.abc import Iterable
from hdmf.common import VectorData
from hdmf.utils import docval, getargs, get_docval, popargs
from hed.errors import HedFileError, get_printable_issue_string
from hed.schema import HedSchema, HedSchemaGroup, load_schema_version, from_string
from hed.models import HedString
from pynwb import register_class
from pynwb.file import LabMetaData, NWBFile
from ndx_hed import HedVersion
from ndx_hed import HedVersionAttr


@register_class('HedTags', 'ndx-hed')
class HedTags(VectorData):
"""
Column storing HED (Hierarchical Event Descriptors) annotations for a row. A HED string is a comma-separated,
and possibly parenthesized list of HED tags selected from a valid HED vocabulary as specified by the
NWBFile field HEDVersion.
NWBFile field HedVersion.
"""

__nwbfields__ = ('sub_name', '_hed_version')
__nwbfields__ = ('_hed_schema')

@docval(*get_docval(VectorData.__init__))
@docval({'name': 'name', 'type': 'str', 'doc': 'Must be HED', 'default': 'HED'},
{'name': 'description', 'type': 'str', 'doc': 'Description of the HED annotations',
'default': 'Hierarchical Event Descriptors (HED) annotations'},
*get_docval(VectorData.__init__, 'data'))
def __init__(self, **kwargs):
# kwargs['name'] = 'HED'
kwargs['name'] = 'HED'
super().__init__(**kwargs)
self._hed_version = None
self._init_internal()

def _init_internal(self):
Expand All @@ -32,54 +36,42 @@ def _init_internal(self):
TODO: How should errors be handled if this file doesn't have a HedVersion object in the LabMetaData?
"""
self.sub_name = "HED"
self._hed_schema = None

@docval({'name': 'val', 'type': str,
'doc': 'the value to add to this column. Should be a valid HED string.'})
'doc': 'the value to add to this column. Should be a valid HED string -- just forces string.'})
def add_row(self, **kwargs):
"""Append a data value to this column."""
val = getargs('val', kwargs)
# val.check_types()
# TODO how to validate
#
# if val is not None and self.validate(val):
# if self.term_set.validate(term=val):
# self.append(val)
# else:
# msg = ("%s is not in the term set." % val)
# raise ValueError(msg)
#
# else:
# self.append(val)
super().append(val)

@docval({'name': 'key', 'type': 'str', 'doc': 'the value to add to this column'})
def get(self, key):
"""
Retrieve elements from this object.
"""
# TODO: Can key be more than a single value? Do we need to check validity of anything?
vals = super().get(key)
return vals

@docval({'name': 'return', 'type': 'list', 'doc': 'list of issues or none'})
def validate(self):
"""Validate this VectorData. """
hed_schema = self.get_hed_version()
return True

def get_hed_version(self):
if not self._hed_version:
# @docval({'name': 'schema', 'type': (HedSchema, None), 'doc': 'HedSchema to use to validate.', 'default': None},
# {'name': 'return', 'type': 'list', 'doc': 'list of issues or none'})
def validate(self, schema):
"""Validate this VectorData. This is assuming a list --- where is the general iterator."""
if not schema:
raise HedFileError('HedSchemaMissing', "Must provide a valid HedSchema", "")
issues = []
for index in range(len(self.data)):
hed_obj = HedString(self.get(index), schema)
these_issues = hed_obj.validate()
if these_issues:
issues.append(f"line {str(index)}: {get_printable_issue_string(these_issues)}")
return "\n".join(issues)

def get_hed_schema(self):
if not self._hed_schema:
root = self._get_root()
if isinstance(root, NWBFile):
self._hed_version = root.get_lab_meta_data("HedVersion")
return self._hed_version
self._hed_schema = root.get_lab_meta_data("hed_version").get_schema()
return self._hed_schema

def _get_root(self):
root = self
while hasattr(root, 'parent') and root.parent:
root = root.parent
if root == self:
return None
return root


Expand Down
81 changes: 34 additions & 47 deletions src/pynwb/ndx_hed/hed_version.py
Original file line number Diff line number Diff line change
@@ -1,47 +1,34 @@
from hdmf.utils import docval, getargs, get_docval, popargs
from pynwb import register_class
from pynwb.file import LabMetaData
from hed.schema import HedSchema, HedSchemaGroup, load_schema_version, from_string


@register_class("HedVersion", "ndx-hed")
class HedVersion(LabMetaData):
"""
The class containing the HED versions and HED schema used in this data file.
"""

__nwbfields__ = ('version', 'schema_string')

# @docval({'name': 'version', 'type': str, 'doc': 'HED version of type str'},
# *get_docval(LabMetaData.__init__))
@docval({'name': 'version', 'type': str, 'doc': 'HED strings of type str'})
def __init__(self, **kwargs):
version = popargs('version', kwargs)
kwargs['name'] = 'hed_version'
super().__init__(**kwargs)
self.version = version
self._init_internal()

# @docval({'name': 'version', 'type': str, 'doc': 'HED version of type str'})
# def __init__(self, version):
# kwargs = {'name': 'hed_version'}
# super().__init__(**kwargs)
# self.name = 'hed_version'
# self.version = version
# self._init_internal()

def _init_internal(self):
"""
Create a HED schema string
"""
hed_schema = load_schema_version(self.version)
self.schema_string = hed_schema.get_as_xml_string()

@docval(returns='The HED schema version', rtype=str)
def get_version(self):
return self.version

@docval(returns='The HED schema or schema group object for this version', rtype=(HedSchema, HedSchemaGroup))
def get_schema(self):
return from_string(self.schema_string)
from hdmf.utils import docval, popargs
from pynwb import register_class
from pynwb.file import LabMetaData
from hed.schema import HedSchema, HedSchemaGroup, load_schema_version, from_string


@register_class("HedVersion", "ndx-hed")
class HedVersion(LabMetaData):
""" The class containing the HED versions and HED schema used in this data file. """

__nwbfields__ = ('name', 'version', 'schema_string')

@docval({'name': 'version', 'type': str, 'doc': 'HED strings of type str'})
def __init__(self, **kwargs):
version = popargs('version', kwargs)
kwargs['name'] = 'hed_version'
super().__init__(**kwargs)
self.version = version
self._init_internal()

def _init_internal(self):
""" Create a HED schema string """
hed_schema = load_schema_version(self.version)
self.schema_string = hed_schema.get_as_xml_string()

@docval(returns='The HED schema version', rtype=str)
def get_version(self):
""" Return the schema version. """
return self.version

@docval(returns='The HED schema or schema group object for this version', rtype=(HedSchema, HedSchemaGroup))
def get_schema(self):
""" Return the HEDSchema object for this version."""
return from_string(self.schema_string)
Original file line number Diff line number Diff line change
@@ -1,47 +1,37 @@
from hdmf.utils import docval, getargs, get_docval, popargs
from pynwb import register_class
from pynwb.file import LabMetaData
from hed.schema import HedSchema, HedSchemaGroup, load_schema_version, from_string


@register_class("HedVersion1", "ndx-hed")
class HedVersion1(LabMetaData):
"""
The class containing the HED versions and HED schema used in this data file.
"""

__nwbfields__ = ('name', 'version', 'schema_string')

# @docval({'name': 'version', 'type': str, 'doc': 'HED version of type str'},
# *get_docval(LabMetaData.__init__))
@docval({'name': 'version', 'type': str, 'doc': 'HED strings of type str'})
def __init__(self, **kwargs):
version = popargs('version', kwargs)
kwargs['name'] = 'hed_version1_ext'
super().__init__(**kwargs)
self.version = version
self._init_internal()

# @docval({'name': 'version', 'type': str, 'doc': 'HED version of type str'})
# def __init__(self, version):
# kwargs = {'name': 'hed_version1'}
# super().__init__(**kwargs)
# self.name = 'hed_version1'
# self.version = version
# self._init_internal()

def _init_internal(self):
"""
Create a HED schema string
"""
hed_schema = load_schema_version(self.version)
self.schema_string = hed_schema.get_as_xml_string()

@docval(returns='The HED schema version', rtype=str)
def get_version(self):
return self.version

@docval(returns='The HED schema or schema group object for this version', rtype=(HedSchema, HedSchemaGroup))
def get_schema(self):
return from_string(self.schema_string)
from hdmf.utils import docval, getargs, get_docval, popargs
from pynwb import register_class
from pynwb.file import LabMetaData
from hed.schema import HedSchema, HedSchemaGroup, load_schema_version, from_string


@register_class("HedVersionAttr", "ndx-hed")
class HedVersionAttr(LabMetaData):
"""
The class containing the HED versions and HED schema used in this data file.
"""

__nwbfields__ = ('name', 'version', 'schema_string')

@docval({'name': 'version', 'type': str, 'doc': 'HED strings of type str'})
def __init__(self, **kwargs):
version = popargs('version', kwargs)
kwargs['name'] = 'hed_version'
super().__init__(**kwargs)
self.version = version
self._init_internal()

def _init_internal(self):
"""
Create a HED schema string
"""
hed_schema = load_schema_version(self.version)
self.schema_string = hed_schema.get_as_xml_string()

@docval(returns='The HED schema version', rtype=str)
def get_version(self):
return self.version

@docval(returns='The HED schema or schema group object for this version', rtype=(HedSchema, HedSchemaGroup))
def get_schema(self):
return from_string(self.schema_string)
Loading

0 comments on commit 5fa6597

Please sign in to comment.