Skip to content

Commit

Permalink
checkpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
mavaylon1 committed Jan 29, 2024
1 parent fd73ae0 commit 6a9c956
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 18 deletions.
79 changes: 70 additions & 9 deletions src/hdmf/container.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from uuid import uuid4
from warnings import warn
import yaml
import os

import h5py
import numpy as np
Expand Down Expand Up @@ -72,12 +73,12 @@ class AbstractContainer(metaclass=ExtenderMeta):
# Override the _setter factor function, so directives that apply to
# Container do not get used on Data
@classmethod
def _setter(cls, field):
def _setter(cls, field): # dada
"""
Make a setter function for creating a :py:func:`property`
"""
name = field['name']

# breakpoint()
if not field.get('settable', True):
return None

Expand All @@ -87,10 +88,66 @@ def setter(self, val):
if name in self.fields:
msg = "can't set attribute '%s' -- already set" % name
raise AttributeError(msg)
self.fields[name] = val
self.fields[name] = self._field_config(arg_name=name, val=val)
# self.fields[name] = val

return setter


def _field_config(self, arg_name, val):
"""
"""
# load termset configuartion file from global Config

Check failure on line 101 in src/hdmf/container.py

View workflow job for this annotation

GitHub Actions / Check for spelling errors

configuartion ==> configuration
# if arg_name == 'location':
# breakpoint()
configurator = self.type_map.ts_config
if len(configurator.path)>0:
CUR_DIR = os.path.dirname(os.path.realpath(configurator.path[0]))
termset_config = configurator.config


# check to see that the namespace for the container is in the config
if self.namespace not in self.type_map.container_types:
msg = "%s not found within loaded configuration." % self.namespace
warn(msg)
else:
# check to see that the container type is in the config under the namespace
config_namespace = termset_config['namespaces'][self.namespace]
object_name = self.__class__.__name__

if object_name not in config_namespace['data_types']:
msg = '%s not found within the configuration for %s' % (object_name, self.namespace)
else:
for attr in config_namespace['data_types'][object_name]:
# if the attr has been manually wrapped then skip checking the config for the attr
if type(attr) == TermSetWrapper:
continue

obj_mapper = self.type_map.get_map(self)
# get the spec according to attr name in schema
# Note: this is the name for the field in the config

spec = obj_mapper.get_attr_spec(attr)

# In the case of dealing with datasets directly or not defined in the spec.
# (Data/VectorData/DynamicTable/etc)
if spec is None:
msg = "Spec not found for %s" % attr
warn(msg)
# From the spec, get the corresponding constructor name
else:
constr_name = obj_mapper.get_const_arg(spec)
if constr_name == arg_name: # make sure any custom fields are not handled (i.e., make an extension)
termset_path = os.path.join(CUR_DIR, config_namespace['data_types'][object_name][attr])
termset = TermSet(term_schema_path=termset_path)
val = TermSetWrapper(value=val, termset=termset)
return val
return val
else:
return val


@classmethod
def _getter(cls, field):
"""
Expand Down Expand Up @@ -242,11 +299,12 @@ def init_validation(self, constructor_args):
"""
# load termset configuartion file from global Config

Check failure on line 300 in src/hdmf/container.py

View workflow job for this annotation

GitHub Actions / Check for spelling errors

configuartion ==> configuration
configurator = self.type_map.ts_config
CUR_DIR = os.path.dirname(os.path.realpath(configurator.path[0]))
termset_config = configurator.config

if termset_config is not None:
# check to see that the namespace for the container is in the config
if self.namespace not in self.type_map.container_types:
breakpoint()
msg = "%s not found within loaded configuration." % self.namespace
warn(msg)
else:
Expand All @@ -255,26 +313,29 @@ def init_validation(self, constructor_args):
object_name = self.__class__.__name__

if object_name not in config_namespace['data_types']:
breakpoint()
msg = '%s not found within the configuration for %s' % (object_name, self.namespace)
else:
for attr in config_namespace['data_types'][object_name]:
# if the attr has been manually wrapped then skip checking the config for the attr
if type(attr) == TermSetWrapper:
continue

obj_mapper = self.type_map.get_map(self)
# get the spec according to attr name in schema
# Note: this is the name for the field in the config

spec = obj_mapper.get_attr_spec(attr)

# In the case of dealing with datasets directly or not defined in the spec.
# (Data/VectorData/DynamicTable/etc)
breakpoint()
if spec is None:
msg = "Spec not found for %s" % attr
warn(msg)
# From the spec, get the corresponding constructor name
else:
constr_name = obj_mapper.get_const_arg(spec)
if constr_name in constructor_args: # make sure any custom fields are not handled (i.e., make an extension)
termset_path = config_namespace['data_types'][object_name][attr]
termset_path = os.path.join(CUR_DIR, config_namespace['data_types'][object_name][attr])
termset = TermSet(term_schema_path=termset_path)
constructor_args[attr] = TermSetWrapper(value=constructor_args[attr], termset=termset)

Expand Down Expand Up @@ -546,6 +607,7 @@ class Container(AbstractContainer):
def _setter(cls, field):
"""Returns a list of setter functions for the given field to be added to the class during class declaration."""
super_setter = AbstractContainer._setter(field)
# breakpoint()
ret = [super_setter]
# create setter with check for required name
# the AbstractContainer that is passed to the setter must have name = required_name
Expand All @@ -572,6 +634,7 @@ def container_setter(self, val):
idx2 = len(ret) - 1

def container_setter(self, val):
# breakpoint()
ret[idx2](self, val) # call the previous setter
if val is not None:
if isinstance(val, (tuple, list)):
Expand Down Expand Up @@ -830,8 +893,6 @@ class Data(AbstractContainer):
@docval({'name': 'name', 'type': str, 'doc': 'the name of this container'},
{'name': 'data', 'type': ('scalar_data', 'array_data', 'data'), 'doc': 'the source of the data'})
def __init__(self, **kwargs):
self.init_validation(constructor_args=kwargs)
# breakpoint()
data = popargs('data', kwargs)
super().__init__(**kwargs)

Expand Down
43 changes: 34 additions & 9 deletions src/hdmf/term_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -319,26 +319,51 @@ def __init__(self, **kwargs):
self.path = [kwargs['path']]
self.load_termset_config(config_path=self.path[0])

def get_config(self, object_name, namespace):
try:
namespace_config = self.config['namespaces'][namespace]
except KeyError:
msg = 'The namespace %s was not found within the configuration.' % namespace
raise ValueError(msg)

try:
type_config = namespace_config['data_types'][object_name]
return type_config
except KeyError:
msg = '%s was not found within the configuration for that namespace.' % object_name
raise ValueError(msg)

@docval({'name': 'config_path', 'type': str, 'doc': 'Path to the configuartion file.'})

Check failure on line 336 in src/hdmf/term_set.py

View workflow job for this annotation

GitHub Actions / Check for spelling errors

configuartion ==> configuration
def load_termset_config(self,config_path):
"""
Load the configuration file for validation on the fields defined for the objects within the file.
"""

with open(config_path, 'r') as config:
termset_config = yaml.safe_load(config)
if self.config is None: # set the initial config/load after config has been unloaded
self.config = termset_config
if len(self.path)==0: # for loading after an unloaded config
self.path.append(config_path)
else: # append to the existing config
for data_type in termset_config:
if data_type in self.config:
self.config[data_type] = termset_config[data_type]
termset_config.pop(data_type)
self.config.update(termset_config)

# append path to new config to self.path
self.path.append(config_path)
else: # append/replace to the existing config
if config_path in self.path:
msg = 'This configuration file path already exists within the configurator.'
raise ValueError(msg)
else:
for namespace in termset_config:
if namespace not in self.config: # append namespace config if not present within self.config
self.config['namespaces'][namespace] = termset_config['namespaces'][namespace]
else: # check for any needed overrides within existing namespace configs
for data_type in termset_config['namespaces'][namespace]['data_types']:
if data_type in self.config['namespaces'][namespace]['data_types']:
replace_config = termset_config['namespaces'][namespace]['data_types'][data_type]
self.config['namespaces'][namespace]['data_types'][data_type] = replace_config
else: # append to config
new_data_type_config = termset_config['namespaces'][namespace]['data_types'][data_type]
self.config['namespaces'][namespace]['data_types'] = new_data_type_config

# append path to self.path
self.path.append(config_path)

def unload_termset_config(self):
"""
Expand Down

0 comments on commit 6a9c956

Please sign in to comment.