From 078d0ce9ccb15926dbc1564c784c9dd2602a67a4 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Tue, 29 Apr 2025 21:23:54 +0200 Subject: [PATCH 01/65] Create HasGroups.m --- +matnwb/+mixin/HasGroups.m | 161 +++++++++++++++++++++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 +matnwb/+mixin/HasGroups.m diff --git a/+matnwb/+mixin/HasGroups.m b/+matnwb/+mixin/HasGroups.m new file mode 100644 index 000000000..c332926a8 --- /dev/null +++ b/+matnwb/+mixin/HasGroups.m @@ -0,0 +1,161 @@ +classdef HasGroups < matlab.mixin.CustomDisplay & matlab.mixin.indexing.RedefinesDot & handle +% HasGroups - Provides methods for retrieving group elements by their key names +% +% This mixin class allows accessing elements in Set properties using dot notation. +% For example, instead of using obj.setProperty.get('keyName'), you can use obj.keyName. +% +% Classes that inherit from this mixin must implement the GroupPropertyNames property +% to specify which properties contain Sets. + + properties (Abstract, Access = protected, Transient) + GroupPropertyNames % Cell array of property names that contain Sets + end + + methods (Access = protected) + function varargout = dotReference(obj, indexOp) + % Handle dot indexing references + propName = char(indexOp(1).Name); + + % First check if it's a method + methodList = methods(obj); + if any(strcmp(methodList, propName)) + % It's a method, use built-in behavior + %[varargout{1:nargout}] = builtin('subsref', obj, substruct('.', propName)); + [varargout{1:nargout}] = obj.(indexOp); + + return; + end + + % Then check if it's a property + if isprop(obj, propName) + % Use built-in behavior for direct properties + %[varargout{1:nargout}] = builtin('subsref', obj, substruct('.', propName)); + [varargout{1:nargout}] = obj.(indexOp); + return; + end + + % Check if the property name matches a key in any of the Set properties + for i = 1:length(obj.GroupPropertyNames) + groupPropName = obj.GroupPropertyNames{i}; + if isprop(obj, groupPropName) && ~isempty(obj.(groupPropName)) + % Check if this Set has the key + if obj.(groupPropName).isKey(propName) + % Get the value from the Set + [varargout{1:nargout}] = obj.(groupPropName).get(propName); + return; + end + end + end + + % If we get here, the property/method wasn't found + error(['Reference to non-existent field or method ''' propName '''.']); + end + + function obj = dotAssign(obj, indexOp, varargin) + % Handle dot indexing assignments + propName = char(indexOp(1).Name); + + % Check if the property exists directly in the object + if isprop(obj, propName) + % Use built-in behavior for direct properties + subs = indexOp2subs(indexOp); + obj = builtin('subsasgn', obj, substruct('.', propName), varargin{:}); + + %obj = builtin('dotAssign', indexOp, varargin{:}); + %[obj.(propName)(indexOp(2:end))] = varargin{:}; + return; + end + + % For now, we don't allow assigning to keys in the Sets + % This could be extended if needed + error(['Cannot assign to key ''' propName ''' in Set properties.']); + end + + function n = dotListLength(obj, indexOp, indexContext) + % Determine number of values to return + propName = char(indexOp); + + % Check if it's a method + methodList = methods(obj); + if any(strcmp(methodList, propName)) + % It's a method, use built-in behavior + value = builtin('subsref', obj, substruct('.', propName)); + if isnumeric(value) || islogical(value) + n = length(value); + elseif iscell(value) + n = length(value); + else + n = 1; + end + return; + end + + % Check if it's a property + if isprop(obj, propName) + % Use built-in behavior for direct properties + value = builtin('subsref', obj, substruct('.', propName)); + if isnumeric(value) || islogical(value) + n = length(value); + elseif iscell(value) + n = length(value); + else + n = 1; + end + return; + end + + % Check if the property name matches a key in any of the Set properties + for i = 1:length(obj.GroupPropertyNames) + groupPropName = obj.GroupPropertyNames{i}; + if isprop(obj, groupPropName) && ~isempty(obj.(groupPropName)) + % Check if this Set has the key + if obj.(groupPropName).isKey(propName) + % Get the value from the Set + value = obj.(groupPropName).get(propName); + if isnumeric(value) || islogical(value) + n = length(value); + elseif iscell(value) + n = length(value); + else + n = 1; + end + return; + end + end + end + + % If we get here, the property/method wasn't found + error(['Reference to non-existent field or method ''' propName '''.']); + end + + function groups = getPropertyGroups(obj) + % Create property groups for display + % Standard properties + standardProps = properties(obj); + + % Remove the Set properties that we'll display separately + for i = 1:length(obj.GroupPropertyNames) + idx = strcmp(standardProps, obj.GroupPropertyNames{i}); + standardProps(idx) = []; + end + + % Create a property group for standard properties + groups = matlab.mixin.util.PropertyGroup(standardProps); + + % Create property groups for each Set property + for i = 1:length(obj.GroupPropertyNames) + groupPropName = obj.GroupPropertyNames{i}; + if isprop(obj, groupPropName) && ~isempty(obj.(groupPropName)) + % Get all keys from the Set + keys = obj.(groupPropName).keys(); + + % Create a title for this group + title = [groupPropName ' elements:']; + + % Add this group to the property groups + groups(end+1) = matlab.mixin.util.PropertyGroup(keys, title); + end + end + end + end +end From f924435b0e49f845edbee51147df6bf3666868d2 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Tue, 29 Apr 2025 23:01:43 +0200 Subject: [PATCH 02/65] Update HasGroups.m Try using redefinesParen --- +matnwb/+mixin/HasGroups.m | 208 ++++++++++++++++++------------------- 1 file changed, 104 insertions(+), 104 deletions(-) diff --git a/+matnwb/+mixin/HasGroups.m b/+matnwb/+mixin/HasGroups.m index c332926a8..e42bb0f8a 100644 --- a/+matnwb/+mixin/HasGroups.m +++ b/+matnwb/+mixin/HasGroups.m @@ -1,8 +1,8 @@ -classdef HasGroups < matlab.mixin.CustomDisplay & matlab.mixin.indexing.RedefinesDot & handle +classdef HasGroups < matlab.mixin.CustomDisplay & matlab.mixin.indexing.RedefinesParen & handle % HasGroups - Provides methods for retrieving group elements by their key names % -% This mixin class allows accessing elements in Set properties using dot notation. -% For example, instead of using obj.setProperty.get('keyName'), you can use obj.keyName. +% This mixin class allows accessing elements in Set properties using parentheses notation. +% For example, instead of using obj.setProperty.get('keyName'), you can use obj('keyName'). % % Classes that inherit from this mixin must implement the GroupPropertyNames property % to specify which properties contain Sets. @@ -12,88 +12,86 @@ end methods (Access = protected) - function varargout = dotReference(obj, indexOp) - % Handle dot indexing references - propName = char(indexOp(1).Name); + function varargout = parenReference(obj, indexOp) + % Handle parentheses indexing references + % Check if the index is a string (key name) - % First check if it's a method - methodList = methods(obj); - if any(strcmp(methodList, propName)) - % It's a method, use built-in behavior - %[varargout{1:nargout}] = builtin('subsref', obj, substruct('.', propName)); - [varargout{1:nargout}] = obj.(indexOp); + key = indexOp(1).Indices{1}; - return; - end - - % Then check if it's a property - if isprop(obj, propName) - % Use built-in behavior for direct properties - %[varargout{1:nargout}] = builtin('subsref', obj, substruct('.', propName)); - [varargout{1:nargout}] = obj.(indexOp); - return; - end - - % Check if the property name matches a key in any of the Set properties - for i = 1:length(obj.GroupPropertyNames) - groupPropName = obj.GroupPropertyNames{i}; - if isprop(obj, groupPropName) && ~isempty(obj.(groupPropName)) - % Check if this Set has the key - if obj.(groupPropName).isKey(propName) - % Get the value from the Set - [varargout{1:nargout}] = obj.(groupPropName).get(propName); - return; + if length(indexOp) == 1 && ischar(key) + keyName = indexOp(1).Indices{1}; + + % Check if the key name matches a key in any of the Set properties + for i = 1:length(obj.GroupPropertyNames) + groupPropName = obj.GroupPropertyNames{i}; + if isprop(obj, groupPropName) + % Get the Set property + setObj = obj.(groupPropName); + + % Check if the Set is not empty and has the key + if ~isempty(setObj) && ismethod(setObj, 'isKey') && setObj.isKey(keyName) + % Get the value from the Set + [varargout{1:nargout}] = setObj.get(keyName); + return; + end end end + + % If we get here, the key wasn't found + error(['Key ''' keyName ''' not found in any Set property.']); + else + % Use default behavior for non-string indices + [varargout{1:nargout}] = builtin('subsref', obj, substruct('()', indexOp)); end - - % If we get here, the property/method wasn't found - error(['Reference to non-existent field or method ''' propName '''.']); end - function obj = dotAssign(obj, indexOp, varargin) - % Handle dot indexing assignments - propName = char(indexOp(1).Name); - - % Check if the property exists directly in the object - if isprop(obj, propName) - % Use built-in behavior for direct properties - subs = indexOp2subs(indexOp); - obj = builtin('subsasgn', obj, substruct('.', propName), varargin{:}); - - %obj = builtin('dotAssign', indexOp, varargin{:}); - %[obj.(propName)(indexOp(2:end))] = varargin{:}; - return; - end - + function obj = parenAssign(obj, indexOp, varargin) + % Handle parentheses indexing assignments % For now, we don't allow assigning to keys in the Sets % This could be extended if needed - error(['Cannot assign to key ''' propName ''' in Set properties.']); + if length(indexOp) == 1 && ischar(indexOp{1}) + keyName = indexOp{1}; + error(['Cannot assign to key ''' keyName ''' in Set properties.']); + else + % Use default behavior for non-string indices + obj = builtin('subsasgn', obj, substruct('()', indexOp), varargin{:}); + end end - function n = dotListLength(obj, indexOp, indexContext) + function n = parenListLength(obj, indexOp, indexContext) % Determine number of values to return - propName = char(indexOp); - - % Check if it's a method - methodList = methods(obj); - if any(strcmp(methodList, propName)) - % It's a method, use built-in behavior - value = builtin('subsref', obj, substruct('.', propName)); - if isnumeric(value) || islogical(value) - n = length(value); - elseif iscell(value) - n = length(value); - else - n = 1; + % Check if the index is a string (key name) + if length(indexOp) == 1 && ischar(indexOp{1}) + keyName = indexOp{1}; + + % Check if the key name matches a key in any of the Set properties + for i = 1:length(obj.GroupPropertyNames) + groupPropName = obj.GroupPropertyNames{i}; + if isprop(obj, groupPropName) + % Get the Set property + setObj = obj.(groupPropName); + + % Check if the Set is not empty and has the key + if ~isempty(setObj) && ismethod(setObj, 'isKey') && setObj.isKey(keyName) + % Get the value from the Set + value = setObj.get(keyName); + if isnumeric(value) || islogical(value) + n = length(value); + elseif iscell(value) + n = length(value); + else + n = 1; + end + return; + end + end end - return; - end - - % Check if it's a property - if isprop(obj, propName) - % Use built-in behavior for direct properties - value = builtin('subsref', obj, substruct('.', propName)); + + % If we get here, the key wasn't found + error(['Key ''' keyName ''' not found in any Set property.']); + else + % Use default behavior for non-string indices + value = builtin('subsref', obj, substruct('()', indexOp)); if isnumeric(value) || islogical(value) n = length(value); elseif iscell(value) @@ -101,33 +99,13 @@ else n = 1; end - return; - end - - % Check if the property name matches a key in any of the Set properties - for i = 1:length(obj.GroupPropertyNames) - groupPropName = obj.GroupPropertyNames{i}; - if isprop(obj, groupPropName) && ~isempty(obj.(groupPropName)) - % Check if this Set has the key - if obj.(groupPropName).isKey(propName) - % Get the value from the Set - value = obj.(groupPropName).get(propName); - if isnumeric(value) || islogical(value) - n = length(value); - elseif iscell(value) - n = length(value); - else - n = 1; - end - return; - end - end end - - % If we get here, the property/method wasn't found - error(['Reference to non-existent field or method ''' propName '''.']); end + function parenDelete(obj, indexop) + error('not implemented') + end + function groups = getPropertyGroups(obj) % Create property groups for display % Standard properties @@ -145,17 +123,39 @@ % Create property groups for each Set property for i = 1:length(obj.GroupPropertyNames) groupPropName = obj.GroupPropertyNames{i}; - if isprop(obj, groupPropName) && ~isempty(obj.(groupPropName)) - % Get all keys from the Set - keys = obj.(groupPropName).keys(); - - % Create a title for this group - title = [groupPropName ' elements:']; + if isprop(obj, groupPropName) + % Get the Set property + setObj = obj.(groupPropName); - % Add this group to the property groups - groups(end+1) = matlab.mixin.util.PropertyGroup(keys, title); + % Check if the Set is not empty + if ~isempty(setObj) && ismethod(setObj, 'keys') + % Get all keys from the Set + keys = setObj.keys(); + + if ~isempty(keys) + propList = cell2struct(setObj.values(), keys, 2); + else + propList = struct; + end + + % Create a title for this group + title = [groupPropName ' elements:']; + + % Add this group to the property groups + groups(end+1) = matlab.mixin.util.PropertyGroup(propList, title); + end end end end end + + methods + function value = size(obj, dim) + value = [1,1]; + end + function value = cat(obj, dim) + error('not implemented') + end + + end end From 05b4f678c34075839b28663dda72494b45b3b128 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Wed, 30 Apr 2025 16:20:28 +0200 Subject: [PATCH 03/65] Update fillClass.m Add HasGroup mixin class to classes with anonymous subgroups --- +file/fillClass.m | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/+file/fillClass.m b/+file/fillClass.m index 4d017202f..d88282dff 100644 --- a/+file/fillClass.m +++ b/+file/fillClass.m @@ -92,6 +92,12 @@ classTag = 'types.untyped.DatasetClass'; end + if isa(class, 'file.Group') + if class.hasAnonGroups + classTag = sprintf('%s & matnwb.mixin.HasGroups', classTag); + end + end + %% return classfile string classDefinitionHeader = [... 'classdef ' name ' < ' depnm ' & ' classTag newline... %header, dependencies @@ -128,6 +134,7 @@ , '% OPTIONAL PROPERTIES' ... } ... ); + fullPropertyDefinition = ''; for iGroup = 1:length(PropertyGroups) Group = PropertyGroups(iGroup); @@ -141,6 +148,17 @@ , propertyDefinitionBody ... }, newline); end + if isa(class, 'file.Group') + if class.hasAnonGroups + isAnonGroup = arrayfun(@(x) isempty(x.name), class.subgroups, 'uni', true); + anonNames = arrayfun(@(x) lower(x.type), class.subgroups(isAnonGroup), 'uni', false); + fullPropertyDefinition = strjoin({... + fullPropertyDefinition, ... + ' properties (Access = protected)', ... + sprintf(' GroupPropertyNames = {%s}', strjoin(strcat('''', anonNames, ''''), ', ') ), ... + ' end'}, newline); + end + end constructorBody = file.fillConstructor(... name,... From e1ee36ed6adf0fda45d8e6ea9aa7c7355e0fec6d Mon Sep 17 00:00:00 2001 From: ehennestad Date: Wed, 30 Apr 2025 21:30:35 +0200 Subject: [PATCH 04/65] Update HasGroups.m Fix HasGroups with redefinesDot. This is one option, but only supported from R2021b and later --- +matnwb/+mixin/HasGroups.m | 99 ++++++++++++-------------------------- 1 file changed, 30 insertions(+), 69 deletions(-) diff --git a/+matnwb/+mixin/HasGroups.m b/+matnwb/+mixin/HasGroups.m index e42bb0f8a..5d9606d01 100644 --- a/+matnwb/+mixin/HasGroups.m +++ b/+matnwb/+mixin/HasGroups.m @@ -1,4 +1,4 @@ -classdef HasGroups < matlab.mixin.CustomDisplay & matlab.mixin.indexing.RedefinesParen & handle +classdef HasGroups < matlab.mixin.CustomDisplay & matlab.mixin.indexing.RedefinesDot & handle % HasGroups - Provides methods for retrieving group elements by their key names % % This mixin class allows accessing elements in Set properties using parentheses notation. @@ -12,14 +12,14 @@ end methods (Access = protected) - function varargout = parenReference(obj, indexOp) + function varargout = dotReference(obj, indexOp) % Handle parentheses indexing references % Check if the index is a string (key name) - key = indexOp(1).Indices{1}; + key = indexOp(1).Name; - if length(indexOp) == 1 && ischar(key) - keyName = indexOp(1).Indices{1}; + if ischar(key) || isstring(key) + keyName = indexOp(1).Name; % Check if the key name matches a key in any of the Set properties for i = 1:length(obj.GroupPropertyNames) @@ -27,85 +27,56 @@ if isprop(obj, groupPropName) % Get the Set property setObj = obj.(groupPropName); + assert(isa(setObj, 'types.untyped.Set')) - % Check if the Set is not empty and has the key - if ~isempty(setObj) && ismethod(setObj, 'isKey') && setObj.isKey(keyName) + % Check if the Set has the key + if setObj.isKey(keyName) % Get the value from the Set - [varargout{1:nargout}] = setObj.get(keyName); + if isscalar(indexOp) + [varargout{1:nargout}] = setObj.get(keyName); + else + intermediateObj = setObj.get(keyName); + [varargout{1:nargout}] = intermediateObj.(indexOp(2:end)); + end return; end end end - + % If we get here, the key wasn't found error(['Key ''' keyName ''' not found in any Set property.']); else - % Use default behavior for non-string indices - [varargout{1:nargout}] = builtin('subsref', obj, substruct('()', indexOp)); + error('Unsupported indexing operation') end end - function obj = parenAssign(obj, indexOp, varargin) + function obj = dotAssign(obj, indexOp, varargin) % Handle parentheses indexing assignments % For now, we don't allow assigning to keys in the Sets % This could be extended if needed - if length(indexOp) == 1 && ischar(indexOp{1}) + + key = indexOp(1).Name; + + if isscalar(indexOp) + obj.(indexOp(1).Name) + else + obj.(indexOp(1).Name).(indexOp(2:end)) = varargin{:}; keyName = indexOp{1}; error(['Cannot assign to key ''' keyName ''' in Set properties.']); - else - % Use default behavior for non-string indices - obj = builtin('subsasgn', obj, substruct('()', indexOp), varargin{:}); end end - - function n = parenListLength(obj, indexOp, indexContext) + + function n = dotListLength(obj, indexOp, indexContext) % Determine number of values to return % Check if the index is a string (key name) - if length(indexOp) == 1 && ischar(indexOp{1}) - keyName = indexOp{1}; - - % Check if the key name matches a key in any of the Set properties - for i = 1:length(obj.GroupPropertyNames) - groupPropName = obj.GroupPropertyNames{i}; - if isprop(obj, groupPropName) - % Get the Set property - setObj = obj.(groupPropName); - - % Check if the Set is not empty and has the key - if ~isempty(setObj) && ismethod(setObj, 'isKey') && setObj.isKey(keyName) - % Get the value from the Set - value = setObj.get(keyName); - if isnumeric(value) || islogical(value) - n = length(value); - elseif iscell(value) - n = length(value); - else - n = 1; - end - return; - end - end - end - - % If we get here, the key wasn't found - error(['Key ''' keyName ''' not found in any Set property.']); + if length(indexOp) > 1 && (ischar(indexOp(1).Name) || isstring(indexOp(1).Name)) + intermediateObj = obj.dotReference(indexOp(1)); + n = listLength(intermediateObj, indexOp(2:end), indexContext); else - % Use default behavior for non-string indices - value = builtin('subsref', obj, substruct('()', indexOp)); - if isnumeric(value) || islogical(value) - n = length(value); - elseif iscell(value) - n = length(value); - else - n = 1; - end + n = 1; end end - function parenDelete(obj, indexop) - error('not implemented') - end - function groups = getPropertyGroups(obj) % Create property groups for display % Standard properties @@ -148,14 +119,4 @@ function parenDelete(obj, indexop) end end end - - methods - function value = size(obj, dim) - value = [1,1]; - end - function value = cat(obj, dim) - error('not implemented') - end - - end end From 53ac3919769022a8e7851e15cf74692c73a9c586 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Thu, 1 May 2025 13:14:00 +0200 Subject: [PATCH 05/65] Create listGeneratedTypes.m Utility method for listing names of generated classes for neurodata types --- +schemes/+utility/listGeneratedTypes.m | 43 ++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 +schemes/+utility/listGeneratedTypes.m diff --git a/+schemes/+utility/listGeneratedTypes.m b/+schemes/+utility/listGeneratedTypes.m new file mode 100644 index 000000000..fe9576597 --- /dev/null +++ b/+schemes/+utility/listGeneratedTypes.m @@ -0,0 +1,43 @@ +function typeClassNames = listGeneratedTypes(options) +% listGeneratedTypes - List class names for generated types +% +% Syntax: +% typeClassNames = schemes.utility.listGeneratedTypes(options) +% +% Input Arguments: +% - options (name-value pairs) - +% Optional name-value pairs. Available options: +% +% - OutputType (string) - +% Specifies the type of output; can be either "class name" or +% "short name" (default is "class name"). +% +% Output Arguments: +% - typeClassNames (string array) - An array of class names of the generated +% types based on the specified output type. + + arguments + options.OutputType (1,1) string ... + {mustBeMember(options.OutputType, ["class name", "short name"])} = "class name" + end + + typesDir = schemes.utility.findRootDirectoryForGeneratedTypes(); + + listing = dir(fullfile(typesDir, '+types', '**', '*.m')); + + absoluteFilePaths = fullfile({listing.folder}, {listing.name}); + ignore = contains(absoluteFilePaths, {'+untyped', '+util'}); + absoluteFilePaths(ignore)=[]; + + relativeFilePaths = strrep(absoluteFilePaths, typesDir, ''); + typeClassNames = strrep(relativeFilePaths, '.m', ''); + typeClassNames = strrep(typeClassNames, filesep, '.'); % NB: needs to happen before next replacement + typeClassNames = strrep(typeClassNames, '+', ''); + + typeClassNames = string(typeClassNames); + + if strcmp(options.OutputType, 'short name') + typeClassNamesSplit = split(typeClassNames, '.'); + typeClassNames = typeClassNamesSplit(1,:,end); + end +end From 95387a6aa7298cb426afdad773b6e241c7fa0ecb Mon Sep 17 00:00:00 2001 From: ehennestad Date: Thu, 1 May 2025 13:20:05 +0200 Subject: [PATCH 06/65] Update MetaClass.m Add TypeName property as a convenience for getting the short name of a data type --- +types/+untyped/MetaClass.m | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/+types/+untyped/MetaClass.m b/+types/+untyped/MetaClass.m index 21ce7f53c..3b84b5598 100644 --- a/+types/+untyped/MetaClass.m +++ b/+types/+untyped/MetaClass.m @@ -7,6 +7,10 @@ REQUIRED containers.Map = containers.Map end + properties (Hidden, Dependent, Transient) + TypeName % Short name for data type class, i.e NWBFile + end + methods function obj = MetaClass(varargin) end @@ -141,6 +145,13 @@ function warnIfPropertyAttributeNotExported(obj, propName, depPropName, fullpath end end + methods % Set/get + function result = get.TypeName(obj) + classNameParts = strsplit( class(obj), '.'); + result = classNameParts{end}; + end + end + methods (Hidden) % Set of methods that should be publicly available, for example for % testing purposes, or other use cases where type inspection might From 6e7380801c83f45fa607735487150ca7fdb525a9 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Thu, 1 May 2025 15:03:54 +0200 Subject: [PATCH 07/65] Update HasGroup mixin - Renamed to HasUnnamedGroups - Use dynamic props instead of overriding indexing - add "add" method --- +matnwb/+mixin/HasGroups.m | 122 -------------- +matnwb/+mixin/HasUnnamedGroups.m | 266 ++++++++++++++++++++++++++++++ 2 files changed, 266 insertions(+), 122 deletions(-) delete mode 100644 +matnwb/+mixin/HasGroups.m create mode 100644 +matnwb/+mixin/HasUnnamedGroups.m diff --git a/+matnwb/+mixin/HasGroups.m b/+matnwb/+mixin/HasGroups.m deleted file mode 100644 index 5d9606d01..000000000 --- a/+matnwb/+mixin/HasGroups.m +++ /dev/null @@ -1,122 +0,0 @@ -classdef HasGroups < matlab.mixin.CustomDisplay & matlab.mixin.indexing.RedefinesDot & handle -% HasGroups - Provides methods for retrieving group elements by their key names -% -% This mixin class allows accessing elements in Set properties using parentheses notation. -% For example, instead of using obj.setProperty.get('keyName'), you can use obj('keyName'). -% -% Classes that inherit from this mixin must implement the GroupPropertyNames property -% to specify which properties contain Sets. - - properties (Abstract, Access = protected, Transient) - GroupPropertyNames % Cell array of property names that contain Sets - end - - methods (Access = protected) - function varargout = dotReference(obj, indexOp) - % Handle parentheses indexing references - % Check if the index is a string (key name) - - key = indexOp(1).Name; - - if ischar(key) || isstring(key) - keyName = indexOp(1).Name; - - % Check if the key name matches a key in any of the Set properties - for i = 1:length(obj.GroupPropertyNames) - groupPropName = obj.GroupPropertyNames{i}; - if isprop(obj, groupPropName) - % Get the Set property - setObj = obj.(groupPropName); - assert(isa(setObj, 'types.untyped.Set')) - - % Check if the Set has the key - if setObj.isKey(keyName) - % Get the value from the Set - if isscalar(indexOp) - [varargout{1:nargout}] = setObj.get(keyName); - else - intermediateObj = setObj.get(keyName); - [varargout{1:nargout}] = intermediateObj.(indexOp(2:end)); - end - return; - end - end - end - - % If we get here, the key wasn't found - error(['Key ''' keyName ''' not found in any Set property.']); - else - error('Unsupported indexing operation') - end - end - - function obj = dotAssign(obj, indexOp, varargin) - % Handle parentheses indexing assignments - % For now, we don't allow assigning to keys in the Sets - % This could be extended if needed - - key = indexOp(1).Name; - - if isscalar(indexOp) - obj.(indexOp(1).Name) - else - obj.(indexOp(1).Name).(indexOp(2:end)) = varargin{:}; - keyName = indexOp{1}; - error(['Cannot assign to key ''' keyName ''' in Set properties.']); - end - end - - function n = dotListLength(obj, indexOp, indexContext) - % Determine number of values to return - % Check if the index is a string (key name) - if length(indexOp) > 1 && (ischar(indexOp(1).Name) || isstring(indexOp(1).Name)) - intermediateObj = obj.dotReference(indexOp(1)); - n = listLength(intermediateObj, indexOp(2:end), indexContext); - else - n = 1; - end - end - - function groups = getPropertyGroups(obj) - % Create property groups for display - % Standard properties - standardProps = properties(obj); - - % Remove the Set properties that we'll display separately - for i = 1:length(obj.GroupPropertyNames) - idx = strcmp(standardProps, obj.GroupPropertyNames{i}); - standardProps(idx) = []; - end - - % Create a property group for standard properties - groups = matlab.mixin.util.PropertyGroup(standardProps); - - % Create property groups for each Set property - for i = 1:length(obj.GroupPropertyNames) - groupPropName = obj.GroupPropertyNames{i}; - if isprop(obj, groupPropName) - % Get the Set property - setObj = obj.(groupPropName); - - % Check if the Set is not empty - if ~isempty(setObj) && ismethod(setObj, 'keys') - % Get all keys from the Set - keys = setObj.keys(); - - if ~isempty(keys) - propList = cell2struct(setObj.values(), keys, 2); - else - propList = struct; - end - - % Create a title for this group - title = [groupPropName ' elements:']; - - % Add this group to the property groups - groups(end+1) = matlab.mixin.util.PropertyGroup(propList, title); - end - end - end - end - end -end diff --git a/+matnwb/+mixin/HasUnnamedGroups.m b/+matnwb/+mixin/HasUnnamedGroups.m new file mode 100644 index 000000000..dfe136e29 --- /dev/null +++ b/+matnwb/+mixin/HasUnnamedGroups.m @@ -0,0 +1,266 @@ +classdef HasUnnamedGroups < matlab.mixin.CustomDisplay & dynamicprops & handle +% HasUnnamedGroups - Mixin to simplify access to unnamed subgroup Sets +% +% Overview: +% Some NWB container types (e.g. ProcessingModule) include unnamed +% subgroups which can only contain specific types (e.g. +% NWBDataInterface or DynamicTable). By default you must say +% module.nwbdatainterface.get('MyData') +% This mixin lets you write +% module.MyData +% +% To also simplify the adding of new data, this class provides an `add` +% method. By default you must use: +% module.nwbdatainterface.set('MyData', dataObject) +% This mixin lets you write +% module.add('MyData', dataObject) +% +% Implementation details: +% - Data elements are added to objects of this class as dynamic properties. +% - Event listeners make sure objects of this class are always up-to-date +% with the included types.untyped.Set objects. +% +% Usage: +% - Subclasses must implement a static property `GroupPropertyNames` +% listing the names of the internal Set properties (e.g. +% {'nwbdatainterface','dynamictable'}). +% Note: This is added in the matnwb generator pipeline +% +% - Once applied, any element added to one of those sets is +% also available directly as a property. +% +% Example: +% % Before: +% module = ProcessingModule('mod'); +% module.nwbdatainterface.set('timeseries', types.core.TimeSeries); +% ts = module.nwbdatainterface.get('timeseries'); +% +% % After using HasUnnamedGroups: +% module.add('timeseries', types.core.TimeSeries); +% ts = module.timeseries; + + properties (Abstract, Access = protected, Transient) + GroupPropertyNames % Cell array of property names that contain Sets + end + + properties (Access = private, Transient) + % DynamicPropertyMap - A containers.Map (name) -> (meta.DynamicProperty) + % storing the dynamic property objects for each added dynamic + % property, accessible by the dynamic property name + DynamicPropertyMap + + % SetItemAddedListener - Listener for ItemAdded events on the Set + % objects that are stored on the "unnamed group" properties + SetItemAddedListener event.listener + + % SetItemRemovedListener - Listener for ItemRemoved events on the Set + % objects that are stored on the "unnamed group" properties + SetItemRemovedListener event.listener + end + + methods + function obj = HasUnnamedGroups() + obj.DynamicPropertyMap = containers.Map(); + end + end + + methods + function add(obj, name, value) + wasSuccess = false; + + for i = 1:numel(obj.GroupPropertyNames) + thisGroupName = obj.GroupPropertyNames{i}; + thisSet = obj.(thisGroupName); + try + thisSet.set(name, value, ... + 'FailOnInvalidType', true, ... + 'FailIfKeyExists', true) + wasSuccess = true; + break + catch ME + if strcmp(ME.identifier, 'NWB:Set:KeyExists') + ME = MException('NWB:Set:KeyExists', 'A neurodata object with name `%s` already exists in this `%s`', name, obj.TypeName); + throwAsCaller(ME); + elseif strcmp(ME.identifier, 'NWB:Set:FailedValidation') + continue + else + rethrow(ME) + end + end + end + if ~wasSuccess + % If we end up here, the type is invalid. + identifier = 'NWB:HasGroupsMixin:AddInvalidType'; + message = 'Object with name `%s` was a "%s", but must be one of the following type(s):\n%s\n'; + allowedTypes = obj.getClassNamesForAllowedGroupTypes(); + allowedTypes = strjoin(" - " + allowedTypes, newline); + error(identifier, message, name, class(value), allowedTypes) + end + end + + function remove(obj, name) + for i = 1:numel(obj.GroupPropertyNames) + thisGroupName = obj.GroupPropertyNames{i}; + thisSet = obj.(thisGroupName); + + if thisSet.isKey(name) + try + thisSet.remove(name) + break + catch ME + rethrow(ME) + end + end + end + end + end + + methods (Access = protected) + + function createListeners(obj) + for i = 1:length(obj.GroupPropertyNames) + groupPropName = obj.GroupPropertyNames{i}; + + setObj = obj.(groupPropName); + + obj.SetItemAddedListener(i) = addlistener(setObj, ... + 'ItemAdded', @obj.onSetItemAdded); + obj.SetItemRemovedListener(i) = addlistener(setObj, ... + 'ItemRemoved', @obj.onSetItemRemoved); + end + end + + function addDynamicProperties(obj) + % TODO: What if multiple groups have the same subkeys? + for i = 1:length(obj.GroupPropertyNames) + groupPropName = obj.GroupPropertyNames{i}; + + setObj = obj.(groupPropName); + keys = setObj.keys; + + for j = 1:numel(keys) + obj.addSingleDynamicProperty(keys{j}, setObj.get(keys{j})) + end + end + end + + function groups = getPropertyGroups(obj) + % getPropertyGroups - Create property groups for display + + standardProps = properties(obj); + + % Remove the Set properties that we'll display separately + toSkip = false(1, length(obj.GroupPropertyNames)); + for i = 1:length(obj.GroupPropertyNames) + idx = strcmp(standardProps, obj.GroupPropertyNames{i}); + toSkip(idx) = true; + end + + % Todo: Use a nwbPreferences object + displayPref = getpref('matnwb', 'displaymode', 'groups'); % groups | flat + + if strcmp(displayPref, 'groups') % Remove dynamic props + dynamicPropNames = obj.DynamicPropertyMap.keys(); + for i = 1:length(dynamicPropNames) + idx = strcmp(standardProps, dynamicPropNames{i}); + toSkip(idx) = true; + end + end + standardProps(toSkip) = []; + + % Create a property group for standard properties + groups = matlab.mixin.util.PropertyGroup(standardProps); + + if strcmp(displayPref, 'groups') + + % Create property groups for each Set property + for i = 1:length(obj.GroupPropertyNames) + groupPropName = obj.GroupPropertyNames{i}; + assert(isprop(obj, groupPropName), ... + 'Expected "%s" to be a property of class', groupPropName) + + % Get the Set property + setObj = obj.(groupPropName); + assert(~isempty(setObj) && isa(setObj, 'types.untyped.Set'), ... + 'Expected property "%s" to contain a Set', groupPropName) + + % Get all keys from the Set + keys = setObj.keys(); + + if ~isempty(keys) + propList = cell2struct(setObj.values(), keys, 2); + else + propList = string(missing); + end + + % Create a title for this group + title = ['' groupPropName ' elements:']; + + % Add this group to the property groups + groups(end+1) = matlab.mixin.util.PropertyGroup(propList, title); %#ok + end + end + end + end + + methods (Access = private) + function onSetItemAdded(obj, ~, ~) + % Todo: can be more specific by receiving event data with names + % of removed properties + obj.addDynamicProperties() + end + + function onSetItemRemoved(obj, ~, ~) + % Todo: can be more specific by receiving event data with names + % of removed properties + obj.pruneDynamicProperties() + end + + function pruneDynamicProperties(obj) + dynamicPropertyNames = obj.DynamicPropertyMap.keys(); + + subgroupElementNames = string.empty; + + for i = 1:numel(obj.GroupPropertyNames) + thisGroupName = obj.GroupPropertyNames{i}; + thisSet = obj.(thisGroupName); + + subgroupElementNames = [subgroupElementNames, thisSet.keys]; %#ok + end + + removedPropNames = setdiff(dynamicPropertyNames, subgroupElementNames); + + for i = 1:numel(removedPropNames) + dynamicPropertyMeta = obj.DynamicPropertyMap(removedPropNames{i}); + delete(dynamicPropertyMeta) + obj.DynamicPropertyMap.remove(removedPropNames{i}) + end + end + + function addSingleDynamicProperty(obj, name, value) + if ~isprop(obj, name) + p = obj.addprop(name); + obj.DynamicPropertyMap(name) = p; + else + p = obj.DynamicPropertyMap(name); + if iscell(p); p = p{1}; end + end + p.SetAccess = 'public'; + obj.(name) = value; + % Dynamic props can only be set from within the class + p.SetAccess = 'protected'; + end + + function result = getClassNamesForAllowedGroupTypes(obj) + % getAllowedGroupTypes - Resolve full class names for the allowed group types. + groupPropertyNames = obj.GroupPropertyNames; + typeClassNames = schemes.utility.listGeneratedTypes(); + + typeClassNamesSplit = split(typeClassNames, '.'); + typeClassNamesShort = typeClassNamesSplit(1,:,end); + + isMatch = ismember(lower(typeClassNamesShort), groupPropertyNames); + result = typeClassNames(isMatch); + end + end +end From abc0363835d7d1840c074d1a2082adad4a033199 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Thu, 1 May 2025 15:18:13 +0200 Subject: [PATCH 08/65] Update HasUnnamedGroups.m Use callback functions instead of event listeners. The dependency of container groups and their sets are very specific, and an event/listener system would be too general for this case. I.e a Set does not generally have to notify about Items added/removed. --- +matnwb/+mixin/HasUnnamedGroups.m | 34 +++++++++++++------------------ 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/+matnwb/+mixin/HasUnnamedGroups.m b/+matnwb/+mixin/HasUnnamedGroups.m index dfe136e29..13374aff1 100644 --- a/+matnwb/+mixin/HasUnnamedGroups.m +++ b/+matnwb/+mixin/HasUnnamedGroups.m @@ -17,8 +17,8 @@ % % Implementation details: % - Data elements are added to objects of this class as dynamic properties. -% - Event listeners make sure objects of this class are always up-to-date -% with the included types.untyped.Set objects. +% - Assign callback functions on Set object to make sure objects of this +% class are always up-to-date with the included types.untyped.Set objects. % % Usage: % - Subclasses must implement a static property `GroupPropertyNames` @@ -48,14 +48,6 @@ % storing the dynamic property objects for each added dynamic % property, accessible by the dynamic property name DynamicPropertyMap - - % SetItemAddedListener - Listener for ItemAdded events on the Set - % objects that are stored on the "unnamed group" properties - SetItemAddedListener event.listener - - % SetItemRemovedListener - Listener for ItemRemoved events on the Set - % objects that are stored on the "unnamed group" properties - SetItemRemovedListener event.listener end methods @@ -123,10 +115,10 @@ function createListeners(obj) setObj = obj.(groupPropName); - obj.SetItemAddedListener(i) = addlistener(setObj, ... - 'ItemAdded', @obj.onSetItemAdded); - obj.SetItemRemovedListener(i) = addlistener(setObj, ... - 'ItemRemoved', @obj.onSetItemRemoved); + setObj.ItemAddedFunction = ... + @(itemName) obj.onSetItemAdded(itemName); + setObj.ItemRemovedFunction = ... + @(itemName) obj.onSetItemRemoved(itemName); end end @@ -204,15 +196,17 @@ function addDynamicProperties(obj) end methods (Access = private) - function onSetItemAdded(obj, ~, ~) - % Todo: can be more specific by receiving event data with names - % of removed properties + function onSetItemAdded(obj, name) + % onSetItemAdded - Handle items being added to a contained types.untyped.Set + + % Todo: pass name to addDynamicProperties obj.addDynamicProperties() end - function onSetItemRemoved(obj, ~, ~) - % Todo: can be more specific by receiving event data with names - % of removed properties + function onSetItemRemoved(obj, name) + % onSetItemRemoved - Handle items being removed from a contained types.untyped.Set + + % Todo: pass name to pruneDynamicProperties obj.pruneDynamicProperties() end From 0b3363dc6a87a2f51bad554805c525469c15bcc4 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Thu, 1 May 2025 15:28:51 +0200 Subject: [PATCH 09/65] Update Set.m - Add callback function properties accessible by matnwb.mixin.HasUnnamedGroups - Add add method - Add optional inputs for controlling behavior of set method --- +types/+untyped/Set.m | 48 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/+types/+untyped/Set.m b/+types/+untyped/Set.m index a7116e117..abfede7fe 100644 --- a/+types/+untyped/Set.m +++ b/+types/+untyped/Set.m @@ -3,6 +3,13 @@ Map; % containers.Map ValidationFcn = @(key, value)[]; end + + properties (SetAccess = ?matnwb.mixin.HasUnnamedGroups) + % These properties enables the HasUnnamedGroups mixin to react when + % items are added or removed from the Set. + ItemAddedFunction function_handle + ItemRemovedFunction function_handle + end methods function obj = Set(varargin) @@ -123,8 +130,14 @@ function validateAll(obj) end remove(obj.Map, mapkeys(keyFailed)); end + + function add(obj, name, val) + % add - Add an element to the set + obj.set(name, val, 'FailIfKeyExists', true); + end - function obj = set(obj, name, val) + function obj = set(obj, name, val, varargin) + if ischar(name) name = {name}; end @@ -132,29 +145,54 @@ function validateAll(obj) if ischar(val) val = {val}; end + + parser = inputParser(); + addParameter(parser, 'FailOnInvalidType', false); + addParameter(parser, 'FailIfKeyExists', false); + parser.parse(varargin{:}); + cellExtract = iscell(val); assert(length(name) == length(val),... 'number of property names should match number of vals on set.'); - for i=1:length(name) + for i = 1:length(name) if cellExtract elem = val{i}; else elem = val(i); end + + if parser.Results.FailIfKeyExists + if obj.isKey(name{i}) + error('NWB:Set:KeyExists', ... + 'Key `%s` already exists in Set', name{i}) + end + end + try obj.ValidationFcn(name{i}, elem); obj.Map(name{i}) = elem; + if ~isempty(obj.ItemAddedFunction) + obj.ItemAddedFunction(name{i}) + end catch ME - warning('NWB:Set:FailedValidation' ... - , 'Failed to add key `%s` to Constrained Set with message:\n %s' ... - , name{i}, ME.message); + identifier = 'NWB:Set:FailedValidation'; + message = 'Failed to add key `%s` to Constrained Set with message:\n %s'; + + if parser.Results.FailOnInvalidType + error(identifier, message, name{i}, ME.message) + else + warning(identifier, message, name{i}, ME.message); + end end end end function obj = remove(obj, name) remove(obj.Map, name); + if ~isempty(obj.ItemRemovedFunction) + obj.ItemRemovedFunction(name) + end end function obj = clear(obj) From 3fb29650b1655f1ad2fd48079b90fac469df67d2 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Thu, 1 May 2025 15:44:53 +0200 Subject: [PATCH 10/65] Update HasUnnamedGroups.m Rename and reorder methods for better logical composition --- +matnwb/+mixin/HasUnnamedGroups.m | 88 +++++++++++++++++-------------- 1 file changed, 49 insertions(+), 39 deletions(-) diff --git a/+matnwb/+mixin/HasUnnamedGroups.m b/+matnwb/+mixin/HasUnnamedGroups.m index 13374aff1..cf4fefa9a 100644 --- a/+matnwb/+mixin/HasUnnamedGroups.m +++ b/+matnwb/+mixin/HasUnnamedGroups.m @@ -17,16 +17,18 @@ % % Implementation details: % - Data elements are added to objects of this class as dynamic properties. -% - Assign callback functions on Set object to make sure objects of this +% - Assign callback functions on Set object to make sure objects of this % class are always up-to-date with the included types.untyped.Set objects. +% - `add` method lets users assign data elements directly without +% going via the contained Set object % % Usage: -% - Subclasses must implement a static property `GroupPropertyNames` -% listing the names of the internal Set properties (e.g. -% {'nwbdatainterface','dynamictable'}). +% - Subclasses must implement a static property `GroupPropertyNames` +% listing the names of the internal Set properties (e.g. +% {'nwbdatainterface','dynamictable'}). % Note: This is added in the matnwb generator pipeline % -% - Once applied, any element added to one of those sets is +% - Once applied, any element added to one of those sets is % also available directly as a property. % % Example: @@ -108,34 +110,13 @@ function remove(obj, name) end methods (Access = protected) - - function createListeners(obj) - for i = 1:length(obj.GroupPropertyNames) - groupPropName = obj.GroupPropertyNames{i}; - - setObj = obj.(groupPropName); - - setObj.ItemAddedFunction = ... - @(itemName) obj.onSetItemAdded(itemName); - setObj.ItemRemovedFunction = ... - @(itemName) obj.onSetItemRemoved(itemName); - end - end - - function addDynamicProperties(obj) - % TODO: What if multiple groups have the same subkeys? - for i = 1:length(obj.GroupPropertyNames) - groupPropName = obj.GroupPropertyNames{i}; - - setObj = obj.(groupPropName); - keys = setObj.keys; - - for j = 1:numel(keys) - obj.addSingleDynamicProperty(keys{j}, setObj.get(keys{j})) - end - end + function setupHasUnnamedGroupsMixin(obj) + obj.addDynamicProperties() + obj.assignContainedSetCallbackFunctions() end + end + methods (Access = protected) % matlab.mixin.CustomDisplay override function groups = getPropertyGroups(obj) % getPropertyGroups - Create property groups for display @@ -196,18 +177,31 @@ function addDynamicProperties(obj) end methods (Access = private) - function onSetItemAdded(obj, name) - % onSetItemAdded - Handle items being added to a contained types.untyped.Set + function assignContainedSetCallbackFunctions(obj) + for i = 1:length(obj.GroupPropertyNames) + groupPropName = obj.GroupPropertyNames{i}; - % Todo: pass name to addDynamicProperties - obj.addDynamicProperties() + setObject = obj.(groupPropName); + + setObject.ItemAddedFunction = ... + @(itemName) obj.onSetItemAdded(itemName); + setObject.ItemRemovedFunction = ... + @(itemName) obj.onSetItemRemoved(itemName); + end end - function onSetItemRemoved(obj, name) - % onSetItemRemoved - Handle items being removed from a contained types.untyped.Set + function addDynamicProperties(obj) + % TODO: What if multiple groups have the same subkeys? + for i = 1:length(obj.GroupPropertyNames) + groupPropName = obj.GroupPropertyNames{i}; + + setObj = obj.(groupPropName); + keys = setObj.keys; - % Todo: pass name to pruneDynamicProperties - obj.pruneDynamicProperties() + for j = 1:numel(keys) + obj.addSingleDynamicProperty(keys{j}, setObj.get(keys{j})) + end + end end function pruneDynamicProperties(obj) @@ -257,4 +251,20 @@ function addSingleDynamicProperty(obj, name, value) result = typeClassNames(isMatch); end end + + methods (Access = private) % types.untyped.Set callback functions + function onSetItemAdded(obj, name) + % onSetItemAdded - Handle items being added to a contained types.untyped.Set + + % Todo: pass name to addDynamicProperties + obj.addDynamicProperties() + end + + function onSetItemRemoved(obj, name) + % onSetItemRemoved - Handle items being removed from a contained types.untyped.Set + + % Todo: pass name to pruneDynamicProperties + obj.pruneDynamicProperties() + end + end end From 410429b5fc70eef38dc6147840c3c518d765133e Mon Sep 17 00:00:00 2001 From: ehennestad Date: Thu, 1 May 2025 15:51:11 +0200 Subject: [PATCH 11/65] Update matnwb generator - Add the HasUnnamedGroups mixin to the relevant data type classes --- +file/fillClass.m | 30 ++++++++++++++++++------------ +file/fillConstructor.m | 11 ++++++++--- 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/+file/fillClass.m b/+file/fillClass.m index d88282dff..596586464 100644 --- a/+file/fillClass.m +++ b/+file/fillClass.m @@ -94,7 +94,7 @@ if isa(class, 'file.Group') if class.hasAnonGroups - classTag = sprintf('%s & matnwb.mixin.HasGroups', classTag); + classTag = sprintf('%s & matnwb.mixin.HasUnnamedGroups', classTag); end end @@ -148,16 +148,11 @@ , propertyDefinitionBody ... }, newline); end - if isa(class, 'file.Group') - if class.hasAnonGroups - isAnonGroup = arrayfun(@(x) isempty(x.name), class.subgroups, 'uni', true); - anonNames = arrayfun(@(x) lower(x.type), class.subgroups(isAnonGroup), 'uni', false); - fullPropertyDefinition = strjoin({... - fullPropertyDefinition, ... - ' properties (Access = protected)', ... - sprintf(' GroupPropertyNames = {%s}', strjoin(strcat('''', anonNames, ''''), ', ') ), ... - ' end'}, newline); - end + if isa(class, 'file.Group') && class.hasAnonGroups + mixinPropertyBlock = createPropertyBlockForHasUnnamedGroupMixin(class); + + fullPropertyDefinition = strjoin(... + {fullPropertyDefinition, mixinPropertyBlock}, newline); end constructorBody = file.fillConstructor(... @@ -166,7 +161,8 @@ defaults,... %all defaults, regardless of inheritance classprops,... namespace, ... - superClassProps); + superClassProps, ... + class); setterFcns = file.fillSetters(setdiff(nonInherited, union(readonly, hiddenAndReadonly)), classprops); validatorFcns = file.fillValidators(allProperties, classprops, namespace, namespace.getFullClassName(name), inherited); exporterFcns = file.fillExport(nonInherited, class, depnm, required); @@ -202,3 +198,13 @@ tf = parentInfo.required; end end + +function propertyBlockStr = createPropertyBlockForHasUnnamedGroupMixin(classInfo) + isAnonGroup = arrayfun(@(x) isempty(x.name), classInfo.subgroups, 'uni', true); + anonNames = arrayfun(@(x) lower(x.type), classInfo.subgroups(isAnonGroup), 'uni', false); + + propertyBlockStr = strjoin({... + 'properties (Access = protected)', ... + sprintf(' GroupPropertyNames = {%s}', strjoin(strcat('''', anonNames, ''''), ', ') ), ... + 'end'}, newline); +end diff --git a/+file/fillConstructor.m b/+file/fillConstructor.m index 8f34875be..2d88af169 100644 --- a/+file/fillConstructor.m +++ b/+file/fillConstructor.m @@ -1,4 +1,4 @@ -function functionString = fillConstructor(name, parentname, defaults, props, namespace, superClassProps) +function functionString = fillConstructor(name, parentname, defaults, props, namespace, superClassProps, class) caps = upper(name); functionBody = ['% ' caps ' - Constructor for ' name]; @@ -7,7 +7,7 @@ functionBody = [functionBody newline() docString]; end - bodyString = fillBody(parentname, defaults, props, namespace); + bodyString = fillBody(parentname, defaults, props, namespace, class); if ~isempty(bodyString) functionBody = [functionBody newline() bodyString]; end @@ -30,7 +30,7 @@ 'end'}, newline()); end -function bodystr = fillBody(parentName, defaults, props, namespace) +function bodystr = fillBody(parentName, defaults, props, namespace, class) if isempty(defaults) bodystr = ''; else @@ -146,6 +146,11 @@ fullBody = strjoin(fullBody, newline); bodystr(end+1:end+length(fullBody)+1) = [newline fullBody]; + if isa(class, 'file.Group') && class.hasAnonGroups + % Include the setup function for the HasUnnamedGroups mixin + bodystr = [bodystr, newline, 'obj.setupHasUnnamedGroupsMixin()', newline]; + end + parser = {... 'p = inputParser;',... 'p.KeepUnmatched = true;',... From 95e6cf7a6e15779d8a98b391db58ac17aeb6d69c Mon Sep 17 00:00:00 2001 From: ehennestad Date: Thu, 1 May 2025 15:51:30 +0200 Subject: [PATCH 12/65] Update generated classes --- +types/+core/BehavioralEpochs.m | 7 ++++++- +types/+core/BehavioralEvents.m | 7 ++++++- +types/+core/BehavioralTimeSeries.m | 7 ++++++- +types/+core/CompassDirection.m | 7 ++++++- +types/+core/DfOverF.m | 7 ++++++- +types/+core/EventWaveform.m | 7 ++++++- +types/+core/EyeTracking.m | 7 ++++++- +types/+core/FilteredEphys.m | 7 ++++++- +types/+core/Fluorescence.m | 7 ++++++- +types/+core/ImageSegmentation.m | 7 ++++++- +types/+core/ImagingPlane.m | 7 ++++++- +types/+core/LFP.m | 7 ++++++- +types/+core/MotionCorrection.m | 7 ++++++- +types/+core/Position.m | 7 ++++++- +types/+core/ProcessingModule.m | 7 ++++++- +types/+core/PupilTracking.m | 7 ++++++- +types/+hdmf_common/AlignedDynamicTable.m | 7 ++++++- +types/+hdmf_common/SimpleMultiContainer.m | 7 ++++++- 18 files changed, 108 insertions(+), 18 deletions(-) diff --git a/+types/+core/BehavioralEpochs.m b/+types/+core/BehavioralEpochs.m index 93239c916..a608daf44 100644 --- a/+types/+core/BehavioralEpochs.m +++ b/+types/+core/BehavioralEpochs.m @@ -1,4 +1,4 @@ -classdef BehavioralEpochs < types.core.NWBDataInterface & types.untyped.GroupClass +classdef BehavioralEpochs < types.core.NWBDataInterface & types.untyped.GroupClass & matnwb.mixin.HasUnnamedGroups % BEHAVIORALEPOCHS - TimeSeries for storing behavioral epochs. The objective of this and the other two Behavioral interfaces (e.g. BehavioralEvents and BehavioralTimeSeries) is to provide generic hooks for software tools/scripts. This allows a tool/script to take the output one specific interface (e.g., UnitTimes) and plot that data relative to another data modality (e.g., behavioral events) without having to define all possible modalities in advance. Declaring one of these interfaces means that one or more TimeSeries of the specified type is published. These TimeSeries should reside in a group having the same name as the interface. For example, if a BehavioralTimeSeries interface is declared, the module will have one or more TimeSeries defined in the module sub-group 'BehavioralTimeSeries'. BehavioralEpochs should use IntervalSeries. BehavioralEvents is used for irregular events. BehavioralTimeSeries is for continuous data. % % Required Properties: @@ -9,6 +9,9 @@ properties intervalseries; % (IntervalSeries) IntervalSeries object containing start and stop times of epochs. end +properties (Access = protected) + GroupPropertyNames = {'intervalseries'} +end methods function obj = BehavioralEpochs(varargin) @@ -29,6 +32,8 @@ [obj.intervalseries, ivarargin] = types.util.parseConstrained(obj,'intervalseries', 'types.core.IntervalSeries', varargin{:}); varargin(ivarargin) = []; + obj.setupHasUnnamedGroupsMixin() + p = inputParser; p.KeepUnmatched = true; p.PartialMatching = false; diff --git a/+types/+core/BehavioralEvents.m b/+types/+core/BehavioralEvents.m index 1536944c6..93c72df1d 100644 --- a/+types/+core/BehavioralEvents.m +++ b/+types/+core/BehavioralEvents.m @@ -1,4 +1,4 @@ -classdef BehavioralEvents < types.core.NWBDataInterface & types.untyped.GroupClass +classdef BehavioralEvents < types.core.NWBDataInterface & types.untyped.GroupClass & matnwb.mixin.HasUnnamedGroups % BEHAVIORALEVENTS - TimeSeries for storing behavioral events. See description of BehavioralEpochs for more details. % % Required Properties: @@ -9,6 +9,9 @@ properties timeseries; % (TimeSeries) TimeSeries object containing behavioral events. end +properties (Access = protected) + GroupPropertyNames = {'timeseries'} +end methods function obj = BehavioralEvents(varargin) @@ -29,6 +32,8 @@ [obj.timeseries, ivarargin] = types.util.parseConstrained(obj,'timeseries', 'types.core.TimeSeries', varargin{:}); varargin(ivarargin) = []; + obj.setupHasUnnamedGroupsMixin() + p = inputParser; p.KeepUnmatched = true; p.PartialMatching = false; diff --git a/+types/+core/BehavioralTimeSeries.m b/+types/+core/BehavioralTimeSeries.m index c5689f52c..63f73046a 100644 --- a/+types/+core/BehavioralTimeSeries.m +++ b/+types/+core/BehavioralTimeSeries.m @@ -1,4 +1,4 @@ -classdef BehavioralTimeSeries < types.core.NWBDataInterface & types.untyped.GroupClass +classdef BehavioralTimeSeries < types.core.NWBDataInterface & types.untyped.GroupClass & matnwb.mixin.HasUnnamedGroups % BEHAVIORALTIMESERIES - TimeSeries for storing Behavoioral time series data. See description of BehavioralEpochs for more details. % % Required Properties: @@ -9,6 +9,9 @@ properties timeseries; % (TimeSeries) TimeSeries object containing continuous behavioral data. end +properties (Access = protected) + GroupPropertyNames = {'timeseries'} +end methods function obj = BehavioralTimeSeries(varargin) @@ -29,6 +32,8 @@ [obj.timeseries, ivarargin] = types.util.parseConstrained(obj,'timeseries', 'types.core.TimeSeries', varargin{:}); varargin(ivarargin) = []; + obj.setupHasUnnamedGroupsMixin() + p = inputParser; p.KeepUnmatched = true; p.PartialMatching = false; diff --git a/+types/+core/CompassDirection.m b/+types/+core/CompassDirection.m index 9df7227bd..b60b3a8c2 100644 --- a/+types/+core/CompassDirection.m +++ b/+types/+core/CompassDirection.m @@ -1,4 +1,4 @@ -classdef CompassDirection < types.core.NWBDataInterface & types.untyped.GroupClass +classdef CompassDirection < types.core.NWBDataInterface & types.untyped.GroupClass & matnwb.mixin.HasUnnamedGroups % COMPASSDIRECTION - With a CompassDirection interface, a module publishes a SpatialSeries object representing a floating point value for theta. The SpatialSeries::reference_frame field should indicate what direction corresponds to 0 and which is the direction of rotation (this should be clockwise). The si_unit for the SpatialSeries should be radians or degrees. % % Required Properties: @@ -9,6 +9,9 @@ properties spatialseries; % (SpatialSeries) SpatialSeries object containing direction of gaze travel. end +properties (Access = protected) + GroupPropertyNames = {'spatialseries'} +end methods function obj = CompassDirection(varargin) @@ -29,6 +32,8 @@ [obj.spatialseries, ivarargin] = types.util.parseConstrained(obj,'spatialseries', 'types.core.SpatialSeries', varargin{:}); varargin(ivarargin) = []; + obj.setupHasUnnamedGroupsMixin() + p = inputParser; p.KeepUnmatched = true; p.PartialMatching = false; diff --git a/+types/+core/DfOverF.m b/+types/+core/DfOverF.m index 0aa247148..2e9aad419 100644 --- a/+types/+core/DfOverF.m +++ b/+types/+core/DfOverF.m @@ -1,4 +1,4 @@ -classdef DfOverF < types.core.NWBDataInterface & types.untyped.GroupClass +classdef DfOverF < types.core.NWBDataInterface & types.untyped.GroupClass & matnwb.mixin.HasUnnamedGroups % DFOVERF - dF/F information about a region of interest (ROI). Storage hierarchy of dF/F should be the same as for segmentation (i.e., same names for ROIs and for image planes). % % Required Properties: @@ -9,6 +9,9 @@ properties roiresponseseries; % REQUIRED (RoiResponseSeries) RoiResponseSeries object(s) containing dF/F for a ROI. end +properties (Access = protected) + GroupPropertyNames = {'roiresponseseries'} +end methods function obj = DfOverF(varargin) @@ -29,6 +32,8 @@ [obj.roiresponseseries, ivarargin] = types.util.parseConstrained(obj,'roiresponseseries', 'types.core.RoiResponseSeries', varargin{:}); varargin(ivarargin) = []; + obj.setupHasUnnamedGroupsMixin() + p = inputParser; p.KeepUnmatched = true; p.PartialMatching = false; diff --git a/+types/+core/EventWaveform.m b/+types/+core/EventWaveform.m index 3847832f3..a248deedf 100644 --- a/+types/+core/EventWaveform.m +++ b/+types/+core/EventWaveform.m @@ -1,4 +1,4 @@ -classdef EventWaveform < types.core.NWBDataInterface & types.untyped.GroupClass +classdef EventWaveform < types.core.NWBDataInterface & types.untyped.GroupClass & matnwb.mixin.HasUnnamedGroups % EVENTWAVEFORM - DEPRECATED. Represents either the waveforms of detected events, as extracted from a raw data trace in /acquisition, or the event waveforms that were stored during experiment acquisition. % % Required Properties: @@ -9,6 +9,9 @@ properties spikeeventseries; % (SpikeEventSeries) SpikeEventSeries object(s) containing detected spike event waveforms. end +properties (Access = protected) + GroupPropertyNames = {'spikeeventseries'} +end methods function obj = EventWaveform(varargin) @@ -29,6 +32,8 @@ [obj.spikeeventseries, ivarargin] = types.util.parseConstrained(obj,'spikeeventseries', 'types.core.SpikeEventSeries', varargin{:}); varargin(ivarargin) = []; + obj.setupHasUnnamedGroupsMixin() + p = inputParser; p.KeepUnmatched = true; p.PartialMatching = false; diff --git a/+types/+core/EyeTracking.m b/+types/+core/EyeTracking.m index 5fb4cb3fd..a56043629 100644 --- a/+types/+core/EyeTracking.m +++ b/+types/+core/EyeTracking.m @@ -1,4 +1,4 @@ -classdef EyeTracking < types.core.NWBDataInterface & types.untyped.GroupClass +classdef EyeTracking < types.core.NWBDataInterface & types.untyped.GroupClass & matnwb.mixin.HasUnnamedGroups % EYETRACKING - Eye-tracking data, representing direction of gaze. % % Required Properties: @@ -9,6 +9,9 @@ properties spatialseries; % (SpatialSeries) SpatialSeries object containing data measuring direction of gaze. end +properties (Access = protected) + GroupPropertyNames = {'spatialseries'} +end methods function obj = EyeTracking(varargin) @@ -29,6 +32,8 @@ [obj.spatialseries, ivarargin] = types.util.parseConstrained(obj,'spatialseries', 'types.core.SpatialSeries', varargin{:}); varargin(ivarargin) = []; + obj.setupHasUnnamedGroupsMixin() + p = inputParser; p.KeepUnmatched = true; p.PartialMatching = false; diff --git a/+types/+core/FilteredEphys.m b/+types/+core/FilteredEphys.m index 02cd1e5e2..c5038249c 100644 --- a/+types/+core/FilteredEphys.m +++ b/+types/+core/FilteredEphys.m @@ -1,4 +1,4 @@ -classdef FilteredEphys < types.core.NWBDataInterface & types.untyped.GroupClass +classdef FilteredEphys < types.core.NWBDataInterface & types.untyped.GroupClass & matnwb.mixin.HasUnnamedGroups % FILTEREDEPHYS - Electrophysiology data from one or more channels that has been subjected to filtering. Examples of filtered data include Theta and Gamma (LFP has its own interface). FilteredEphys modules publish an ElectricalSeries for each filtered channel or set of channels. The name of each ElectricalSeries is arbitrary but should be informative. The source of the filtered data, whether this is from analysis of another time series or as acquired by hardware, should be noted in each's TimeSeries::description field. There is no assumed 1::1 correspondence between filtered ephys signals and electrodes, as a single signal can apply to many nearby electrodes, and one electrode may have different filtered (e.g., theta and/or gamma) signals represented. Filter properties should be noted in the ElectricalSeries 'filtering' attribute. % % Required Properties: @@ -9,6 +9,9 @@ properties electricalseries; % REQUIRED (ElectricalSeries) ElectricalSeries object(s) containing filtered electrophysiology data. end +properties (Access = protected) + GroupPropertyNames = {'electricalseries'} +end methods function obj = FilteredEphys(varargin) @@ -29,6 +32,8 @@ [obj.electricalseries, ivarargin] = types.util.parseConstrained(obj,'electricalseries', 'types.core.ElectricalSeries', varargin{:}); varargin(ivarargin) = []; + obj.setupHasUnnamedGroupsMixin() + p = inputParser; p.KeepUnmatched = true; p.PartialMatching = false; diff --git a/+types/+core/Fluorescence.m b/+types/+core/Fluorescence.m index 2c6f372fa..ac09297b4 100644 --- a/+types/+core/Fluorescence.m +++ b/+types/+core/Fluorescence.m @@ -1,4 +1,4 @@ -classdef Fluorescence < types.core.NWBDataInterface & types.untyped.GroupClass +classdef Fluorescence < types.core.NWBDataInterface & types.untyped.GroupClass & matnwb.mixin.HasUnnamedGroups % FLUORESCENCE - Fluorescence information about a region of interest (ROI). Storage hierarchy of fluorescence should be the same as for segmentation (ie, same names for ROIs and for image planes). % % Required Properties: @@ -9,6 +9,9 @@ properties roiresponseseries; % REQUIRED (RoiResponseSeries) RoiResponseSeries object(s) containing fluorescence data for a ROI. end +properties (Access = protected) + GroupPropertyNames = {'roiresponseseries'} +end methods function obj = Fluorescence(varargin) @@ -29,6 +32,8 @@ [obj.roiresponseseries, ivarargin] = types.util.parseConstrained(obj,'roiresponseseries', 'types.core.RoiResponseSeries', varargin{:}); varargin(ivarargin) = []; + obj.setupHasUnnamedGroupsMixin() + p = inputParser; p.KeepUnmatched = true; p.PartialMatching = false; diff --git a/+types/+core/ImageSegmentation.m b/+types/+core/ImageSegmentation.m index e48733106..11801451a 100644 --- a/+types/+core/ImageSegmentation.m +++ b/+types/+core/ImageSegmentation.m @@ -1,4 +1,4 @@ -classdef ImageSegmentation < types.core.NWBDataInterface & types.untyped.GroupClass +classdef ImageSegmentation < types.core.NWBDataInterface & types.untyped.GroupClass & matnwb.mixin.HasUnnamedGroups % IMAGESEGMENTATION - Stores pixels in an image that represent different regions of interest (ROIs) or masks. All segmentation for a given imaging plane is stored together, with storage for multiple imaging planes (masks) supported. Each ROI is stored in its own subgroup, with the ROI group containing both a 2D mask and a list of pixels that make up this mask. Segments can also be used for masking neuropil. If segmentation is allowed to change with time, a new imaging plane (or module) is required and ROI names should remain consistent between them. % % Required Properties: @@ -9,6 +9,9 @@ properties planesegmentation; % REQUIRED (PlaneSegmentation) Results from image segmentation of a specific imaging plane. end +properties (Access = protected) + GroupPropertyNames = {'planesegmentation'} +end methods function obj = ImageSegmentation(varargin) @@ -29,6 +32,8 @@ [obj.planesegmentation, ivarargin] = types.util.parseConstrained(obj,'planesegmentation', 'types.core.PlaneSegmentation', varargin{:}); varargin(ivarargin) = []; + obj.setupHasUnnamedGroupsMixin() + p = inputParser; p.KeepUnmatched = true; p.PartialMatching = false; diff --git a/+types/+core/ImagingPlane.m b/+types/+core/ImagingPlane.m index d207064e4..bfda5d224 100644 --- a/+types/+core/ImagingPlane.m +++ b/+types/+core/ImagingPlane.m @@ -1,4 +1,4 @@ -classdef ImagingPlane < types.core.NWBContainer & types.untyped.GroupClass +classdef ImagingPlane < types.core.NWBContainer & types.untyped.GroupClass & matnwb.mixin.HasUnnamedGroups % IMAGINGPLANE - An imaging plane and its metadata. % % Required Properties: @@ -26,6 +26,9 @@ origin_coords_unit = "meters"; % (char) Measurement units for origin_coords. The default value is 'meters'. reference_frame; % (char) Describes reference frame of origin_coords and grid_spacing. For example, this can be a text description of the anatomical location and orientation of the grid defined by origin_coords and grid_spacing or the vectors needed to transform or rotate the grid to a common anatomical axis (e.g., AP/DV/ML). This field is necessary to interpret origin_coords and grid_spacing. If origin_coords and grid_spacing are not present, then this field is not required. For example, if the microscope takes 10 x 10 x 2 images, where the first value of the data matrix (index (0, 0, 0)) corresponds to (-1.2, -0.6, -2) mm relative to bregma, the spacing between pixels is 0.2 mm in x, 0.2 mm in y and 0.5 mm in z, and larger numbers in x means more anterior, larger numbers in y means more rightward, and larger numbers in z means more ventral, then enter the following -- origin_coords = (-1.2, -0.6, -2) grid_spacing = (0.2, 0.2, 0.5) reference_frame = "Origin coordinates are relative to bregma. First dimension corresponds to anterior-posterior axis (larger index = more anterior). Second dimension corresponds to medial-lateral axis (larger index = more rightward). Third dimension corresponds to dorsal-ventral axis (larger index = more ventral)." end +properties (Access = protected) + GroupPropertyNames = {'opticalchannel'} +end methods function obj = ImagingPlane(varargin) @@ -75,6 +78,8 @@ [obj.opticalchannel, ivarargin] = types.util.parseConstrained(obj,'opticalchannel', 'types.core.OpticalChannel', varargin{:}); varargin(ivarargin) = []; + obj.setupHasUnnamedGroupsMixin() + p = inputParser; p.KeepUnmatched = true; p.PartialMatching = false; diff --git a/+types/+core/LFP.m b/+types/+core/LFP.m index e0e3c19bb..921dedc4b 100644 --- a/+types/+core/LFP.m +++ b/+types/+core/LFP.m @@ -1,4 +1,4 @@ -classdef LFP < types.core.NWBDataInterface & types.untyped.GroupClass +classdef LFP < types.core.NWBDataInterface & types.untyped.GroupClass & matnwb.mixin.HasUnnamedGroups % LFP - LFP data from one or more channels. The electrode map in each published ElectricalSeries will identify which channels are providing LFP data. Filter properties should be noted in the ElectricalSeries 'filtering' attribute. % % Required Properties: @@ -9,6 +9,9 @@ properties electricalseries; % REQUIRED (ElectricalSeries) ElectricalSeries object(s) containing LFP data for one or more channels. end +properties (Access = protected) + GroupPropertyNames = {'electricalseries'} +end methods function obj = LFP(varargin) @@ -29,6 +32,8 @@ [obj.electricalseries, ivarargin] = types.util.parseConstrained(obj,'electricalseries', 'types.core.ElectricalSeries', varargin{:}); varargin(ivarargin) = []; + obj.setupHasUnnamedGroupsMixin() + p = inputParser; p.KeepUnmatched = true; p.PartialMatching = false; diff --git a/+types/+core/MotionCorrection.m b/+types/+core/MotionCorrection.m index 9a67b4b70..e3ed97e81 100644 --- a/+types/+core/MotionCorrection.m +++ b/+types/+core/MotionCorrection.m @@ -1,4 +1,4 @@ -classdef MotionCorrection < types.core.NWBDataInterface & types.untyped.GroupClass +classdef MotionCorrection < types.core.NWBDataInterface & types.untyped.GroupClass & matnwb.mixin.HasUnnamedGroups % MOTIONCORRECTION - An image stack where all frames are shifted (registered) to a common coordinate system, to account for movement and drift between frames. Note: each frame at each point in time is assumed to be 2-D (has only x & y dimensions). % % Required Properties: @@ -9,6 +9,9 @@ properties correctedimagestack; % REQUIRED (CorrectedImageStack) Results from motion correction of an image stack. end +properties (Access = protected) + GroupPropertyNames = {'correctedimagestack'} +end methods function obj = MotionCorrection(varargin) @@ -29,6 +32,8 @@ [obj.correctedimagestack, ivarargin] = types.util.parseConstrained(obj,'correctedimagestack', 'types.core.CorrectedImageStack', varargin{:}); varargin(ivarargin) = []; + obj.setupHasUnnamedGroupsMixin() + p = inputParser; p.KeepUnmatched = true; p.PartialMatching = false; diff --git a/+types/+core/Position.m b/+types/+core/Position.m index 389ca1ef7..fe546460d 100644 --- a/+types/+core/Position.m +++ b/+types/+core/Position.m @@ -1,4 +1,4 @@ -classdef Position < types.core.NWBDataInterface & types.untyped.GroupClass +classdef Position < types.core.NWBDataInterface & types.untyped.GroupClass & matnwb.mixin.HasUnnamedGroups % POSITION - Position data, whether along the x, x/y or x/y/z axis. % % Required Properties: @@ -9,6 +9,9 @@ properties spatialseries; % REQUIRED (SpatialSeries) SpatialSeries object containing position data. end +properties (Access = protected) + GroupPropertyNames = {'spatialseries'} +end methods function obj = Position(varargin) @@ -29,6 +32,8 @@ [obj.spatialseries, ivarargin] = types.util.parseConstrained(obj,'spatialseries', 'types.core.SpatialSeries', varargin{:}); varargin(ivarargin) = []; + obj.setupHasUnnamedGroupsMixin() + p = inputParser; p.KeepUnmatched = true; p.PartialMatching = false; diff --git a/+types/+core/ProcessingModule.m b/+types/+core/ProcessingModule.m index c5b4c2d4f..adc3e6108 100644 --- a/+types/+core/ProcessingModule.m +++ b/+types/+core/ProcessingModule.m @@ -1,4 +1,4 @@ -classdef ProcessingModule < types.core.NWBContainer & types.untyped.GroupClass +classdef ProcessingModule < types.core.NWBContainer & types.untyped.GroupClass & matnwb.mixin.HasUnnamedGroups % PROCESSINGMODULE - A collection of processed data. % % Required Properties: @@ -14,6 +14,9 @@ dynamictable; % (DynamicTable) Tables stored in this collection. nwbdatainterface; % (NWBDataInterface) Data objects stored in this collection. end +properties (Access = protected) + GroupPropertyNames = {'nwbdatainterface', 'dynamictable'} +end methods function obj = ProcessingModule(varargin) @@ -40,6 +43,8 @@ [obj.nwbdatainterface, ivarargin] = types.util.parseConstrained(obj,'nwbdatainterface', 'types.core.NWBDataInterface', varargin{:}); varargin(ivarargin) = []; + obj.setupHasUnnamedGroupsMixin() + p = inputParser; p.KeepUnmatched = true; p.PartialMatching = false; diff --git a/+types/+core/PupilTracking.m b/+types/+core/PupilTracking.m index 0a4f149a0..4e066bf56 100644 --- a/+types/+core/PupilTracking.m +++ b/+types/+core/PupilTracking.m @@ -1,4 +1,4 @@ -classdef PupilTracking < types.core.NWBDataInterface & types.untyped.GroupClass +classdef PupilTracking < types.core.NWBDataInterface & types.untyped.GroupClass & matnwb.mixin.HasUnnamedGroups % PUPILTRACKING - Eye-tracking data, representing pupil size. % % Required Properties: @@ -9,6 +9,9 @@ properties timeseries; % REQUIRED (TimeSeries) TimeSeries object containing time series data on pupil size. end +properties (Access = protected) + GroupPropertyNames = {'timeseries'} +end methods function obj = PupilTracking(varargin) @@ -29,6 +32,8 @@ [obj.timeseries, ivarargin] = types.util.parseConstrained(obj,'timeseries', 'types.core.TimeSeries', varargin{:}); varargin(ivarargin) = []; + obj.setupHasUnnamedGroupsMixin() + p = inputParser; p.KeepUnmatched = true; p.PartialMatching = false; diff --git a/+types/+hdmf_common/AlignedDynamicTable.m b/+types/+hdmf_common/AlignedDynamicTable.m index 197a0d79c..4c43b9532 100644 --- a/+types/+hdmf_common/AlignedDynamicTable.m +++ b/+types/+hdmf_common/AlignedDynamicTable.m @@ -1,4 +1,4 @@ -classdef AlignedDynamicTable < types.hdmf_common.DynamicTable & types.untyped.GroupClass +classdef AlignedDynamicTable < types.hdmf_common.DynamicTable & types.untyped.GroupClass & matnwb.mixin.HasUnnamedGroups % ALIGNEDDYNAMICTABLE - DynamicTable container that supports storing a collection of sub-tables. Each sub-table is a DynamicTable itself that is aligned with the main table by row index. I.e., all DynamicTables stored in this group MUST have the same number of rows. This type effectively defines a 2-level table in which the main data is stored in the main table implemented by this type and additional columns of the table are grouped into categories, with each category being represented by a separate DynamicTable stored within the group. % % Required Properties: @@ -13,6 +13,9 @@ properties dynamictable; % (DynamicTable) A DynamicTable representing a particular category for columns in the AlignedDynamicTable parent container. The table MUST be aligned with (i.e., have the same number of rows) as all other DynamicTables stored in the AlignedDynamicTable parent container. The name of the category is given by the name of the DynamicTable and its description by the description attribute of the DynamicTable. end +properties (Access = protected) + GroupPropertyNames = {'dynamictable'} +end methods function obj = AlignedDynamicTable(varargin) @@ -43,6 +46,8 @@ [obj.dynamictable, ivarargin] = types.util.parseConstrained(obj,'dynamictable', 'types.hdmf_common.DynamicTable', varargin{:}); varargin(ivarargin) = []; + obj.setupHasUnnamedGroupsMixin() + p = inputParser; p.KeepUnmatched = true; p.PartialMatching = false; diff --git a/+types/+hdmf_common/SimpleMultiContainer.m b/+types/+hdmf_common/SimpleMultiContainer.m index 499450240..baa722efb 100644 --- a/+types/+hdmf_common/SimpleMultiContainer.m +++ b/+types/+hdmf_common/SimpleMultiContainer.m @@ -1,4 +1,4 @@ -classdef SimpleMultiContainer < types.hdmf_common.Container & types.untyped.GroupClass +classdef SimpleMultiContainer < types.hdmf_common.Container & types.untyped.GroupClass & matnwb.mixin.HasUnnamedGroups % SIMPLEMULTICONTAINER - A simple Container for holding onto multiple containers. % % Required Properties: @@ -10,6 +10,9 @@ container; % (Container) Container objects held within this SimpleMultiContainer. data; % (Data) Data objects held within this SimpleMultiContainer. end +properties (Access = protected) + GroupPropertyNames = {'container'} +end methods function obj = SimpleMultiContainer(varargin) @@ -34,6 +37,8 @@ [obj.data, ivarargin] = types.util.parseConstrained(obj,'data', 'types.hdmf_common.Data', varargin{:}); varargin(ivarargin) = []; + obj.setupHasUnnamedGroupsMixin() + p = inputParser; p.KeepUnmatched = true; p.PartialMatching = false; From 4a8b47a00ffdc228b8c0b9806fbd12e66a125cfe Mon Sep 17 00:00:00 2001 From: ehennestad Date: Thu, 1 May 2025 20:48:20 +0200 Subject: [PATCH 13/65] Update HasUnnamedGroups.m Add minimal support for contained "types.untyped.Anon" objects add and NotImplemented warnings/errors in cases where these are not supported --- +matnwb/+mixin/HasUnnamedGroups.m | 52 ++++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 12 deletions(-) diff --git a/+matnwb/+mixin/HasUnnamedGroups.m b/+matnwb/+mixin/HasUnnamedGroups.m index cf4fefa9a..d7e944c24 100644 --- a/+matnwb/+mixin/HasUnnamedGroups.m +++ b/+matnwb/+mixin/HasUnnamedGroups.m @@ -41,6 +41,10 @@ % module.add('timeseries', types.core.TimeSeries); % ts = module.timeseries; +% Note: Subclasses for this mixin might include Anon sets. Currently there +% are no schemas in NWB where Anon sets are used, and this class does not +% currently support contained Anon sets. + properties (Abstract, Access = protected, Transient) GroupPropertyNames % Cell array of property names that contain Sets end @@ -65,6 +69,11 @@ function add(obj, name, value) for i = 1:numel(obj.GroupPropertyNames) thisGroupName = obj.GroupPropertyNames{i}; thisSet = obj.(thisGroupName); + + if isa(thisSet, 'types.untyped.Anon') + error('Not implemented yet') + end + try thisSet.set(name, value, ... 'FailOnInvalidType', true, ... @@ -73,7 +82,9 @@ function add(obj, name, value) break catch ME if strcmp(ME.identifier, 'NWB:Set:KeyExists') - ME = MException('NWB:Set:KeyExists', 'A neurodata object with name `%s` already exists in this `%s`', name, obj.TypeName); + ME = MException('NWB:HasUnnamedGroupsMixin:KeyExists', ... + 'A neurodata object with name `%s` already exists in this `%s`', ... + name, obj.TypeName); throwAsCaller(ME); elseif strcmp(ME.identifier, 'NWB:Set:FailedValidation') continue @@ -84,8 +95,9 @@ function add(obj, name, value) end if ~wasSuccess % If we end up here, the type is invalid. - identifier = 'NWB:HasGroupsMixin:AddInvalidType'; - message = 'Object with name `%s` was a "%s", but must be one of the following type(s):\n%s\n'; + identifier = 'NWB:HasUnnamedGroupsMixin:AddInvalidType'; + message = ['Object with name `%s` was a "%s", but must be ', ... + 'one of the following type(s):\n%s\n']; allowedTypes = obj.getClassNamesForAllowedGroupTypes(); allowedTypes = strjoin(" - " + allowedTypes, newline); error(identifier, message, name, class(value), allowedTypes) @@ -96,6 +108,10 @@ function remove(obj, name) for i = 1:numel(obj.GroupPropertyNames) thisGroupName = obj.GroupPropertyNames{i}; thisSet = obj.(thisGroupName); + + if isa(thisSet, 'types.untyped.Anon') + error('Not implemented yet') + end if thisSet.isKey(name) try @@ -182,11 +198,15 @@ function assignContainedSetCallbackFunctions(obj) groupPropName = obj.GroupPropertyNames{i}; setObject = obj.(groupPropName); - - setObject.ItemAddedFunction = ... - @(itemName) obj.onSetItemAdded(itemName); - setObject.ItemRemovedFunction = ... - @(itemName) obj.onSetItemRemoved(itemName); + if isa(setObject, 'types.untyped.Set') + setObject.ItemAddedFunction = ... + @(itemName) obj.onSetItemAdded(itemName); + setObject.ItemRemovedFunction = ... + @(itemName) obj.onSetItemRemoved(itemName); + else + warning('NWB:HasUnnamedGroupsMixin:NotImplemented', ... + 'Callback functions are not implemented for Anon sets.') + end end end @@ -196,10 +216,18 @@ function addDynamicProperties(obj) groupPropName = obj.GroupPropertyNames{i}; setObj = obj.(groupPropName); - keys = setObj.keys; - - for j = 1:numel(keys) - obj.addSingleDynamicProperty(keys{j}, setObj.get(keys{j})) + if isa(setObj, 'types.untyped.Set') + keys = setObj.keys; + + for j = 1:numel(keys) + obj.addSingleDynamicProperty(keys{j}, setObj.get(keys{j})) + end + elseif isa(setObj, 'types.untyped.Anon') + name = setObj.name; + value = setObj.value; + if ~isempty(name) + obj.addSingleDynamicProperty(name, value) + end end end end From 31bc60b4ca33a3f9b05ca05ba07bd84a2aec477e Mon Sep 17 00:00:00 2001 From: ehennestad Date: Thu, 1 May 2025 20:48:39 +0200 Subject: [PATCH 14/65] Update AnonTest.m Suppress warning --- +tests/+unit/+schema/AnonTest.m | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/+tests/+unit/+schema/AnonTest.m b/+tests/+unit/+schema/AnonTest.m index 2eac2b126..38ed1b10b 100644 --- a/+tests/+unit/+schema/AnonTest.m +++ b/+tests/+unit/+schema/AnonTest.m @@ -7,6 +7,10 @@ methods (Test) function testAnonDataset(testCase) + import matlab.unittest.fixtures.SuppressedWarningsFixture + warningIdentifier = 'NWB:HasUnnamedGroupsMixin:NotImplemented'; + testCase.applyFixture(SuppressedWarningsFixture(warningIdentifier)) + ag = types.anon.AnonGroup('ad', types.anon.AnonData('data', 0)); nwbExpected = NwbFile(... 'identifier', 'ANON',... From f83048556f1916458cd47095a4d96e123678c781 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Thu, 1 May 2025 20:55:31 +0200 Subject: [PATCH 15/65] Refactor fillClass Rename variable depnm to superclassNames --- +file/fillClass.m | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/+file/fillClass.m b/+file/fillClass.m index 596586464..6609342e4 100644 --- a/+file/fillClass.m +++ b/+file/fillClass.m @@ -79,28 +79,27 @@ optional = setdiff(intersect(optional, nonInherited), exclusivePropertyGroups); %% CLASSDEF + superclassNames = {}; if length(processed) <= 1 - depnm = 'types.untyped.MetaClass'; %WRITE + superclassNames{1} = 'types.untyped.MetaClass'; %WRITE else parentName = processed(2).type; %WRITE - depnm = namespace.getFullClassName(parentName); + superclassNames{1} = namespace.getFullClassName(parentName); end if isa(processed, 'file.Group') - classTag = 'types.untyped.GroupClass'; + superclassNames{end+1} = 'types.untyped.GroupClass'; else - classTag = 'types.untyped.DatasetClass'; + superclassNames{end+1} = 'types.untyped.DatasetClass'; end - if isa(class, 'file.Group') - if class.hasAnonGroups - classTag = sprintf('%s & matnwb.mixin.HasUnnamedGroups', classTag); - end + if isa(class, 'file.Group') && class.hasAnonGroups + superclassNames{end+1} = 'matnwb.mixin.HasUnnamedGroups'; end %% return classfile string classDefinitionHeader = [... - 'classdef ' name ' < ' depnm ' & ' classTag newline... %header, dependencies + 'classdef ' name ' < ' strjoin(superclassNames, ' & ') newline... %header, dependencies '% ' upper(name) ' - ' class.doc]; %name, docstr fullClassName = strjoin({'types', misc.str2validName(namespace.name), name}, '.'); @@ -157,7 +156,7 @@ constructorBody = file.fillConstructor(... name,... - depnm,... + superclassNames{1},... defaults,... %all defaults, regardless of inheritance classprops,... namespace, ... @@ -165,7 +164,7 @@ class); setterFcns = file.fillSetters(setdiff(nonInherited, union(readonly, hiddenAndReadonly)), classprops); validatorFcns = file.fillValidators(allProperties, classprops, namespace, namespace.getFullClassName(name), inherited); - exporterFcns = file.fillExport(nonInherited, class, depnm, required); + exporterFcns = file.fillExport(nonInherited, class, superclassNames{1}, required); methodBody = strjoin({constructorBody... '%% SETTERS' setterFcns... '%% VALIDATORS' validatorFcns... From fd16470c2c34edde9721783bbe0e8645558db504 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Fri, 2 May 2025 10:19:18 +0200 Subject: [PATCH 16/65] Start adding name remapping to valid matlab names --- +matnwb/+mixin/HasUnnamedGroups.m | 78 +++++++++++++++++++++++++------ 1 file changed, 64 insertions(+), 14 deletions(-) diff --git a/+matnwb/+mixin/HasUnnamedGroups.m b/+matnwb/+mixin/HasUnnamedGroups.m index d7e944c24..99eab992e 100644 --- a/+matnwb/+mixin/HasUnnamedGroups.m +++ b/+matnwb/+mixin/HasUnnamedGroups.m @@ -45,6 +45,8 @@ % are no schemas in NWB where Anon sets are used, and this class does not % currently support contained Anon sets. +% Todo: Add custom footer if any names are aliased to valid matlab names. + properties (Abstract, Access = protected, Transient) GroupPropertyNames % Cell array of property names that contain Sets end @@ -54,11 +56,13 @@ % storing the dynamic property objects for each added dynamic % property, accessible by the dynamic property name DynamicPropertyMap + ValidNameMap end methods function obj = HasUnnamedGroups() obj.DynamicPropertyMap = containers.Map(); + obj.ValidNameMap = containers.Map(); end end @@ -77,7 +81,7 @@ function add(obj, name, value) try thisSet.set(name, value, ... 'FailOnInvalidType', true, ... - 'FailIfKeyExists', true) + 'FailIfKeyExists', true); wasSuccess = true; break catch ME @@ -112,10 +116,10 @@ function remove(obj, name) if isa(thisSet, 'types.untyped.Anon') error('Not implemented yet') end - - if thisSet.isKey(name) + actualName = obj.ValidNameMap(name); + if thisSet.isKey(actualName) try - thisSet.remove(name) + thisSet.remove(actualName) break catch ME rethrow(ME) @@ -175,9 +179,10 @@ function setupHasUnnamedGroupsMixin(obj) % Get all keys from the Set keys = setObj.keys(); + validNames = obj.getValidNames(keys); if ~isempty(keys) - propList = cell2struct(setObj.values(), keys, 2); + propList = cell2struct(setObj.values(), validNames, 2); else propList = string(missing); end @@ -189,6 +194,29 @@ function setupHasUnnamedGroupsMixin(obj) groups(end+1) = matlab.mixin.util.PropertyGroup(propList, title); %#ok end end + obj.aliasWarning() + end + + function aliasWarning(obj) + allValidNames = string(obj.ValidNameMap.keys()); + allActualNames = string(obj.ValidNameMap.values()); + + if ~isequal(allValidNames, allActualNames) + hasAlias = ~strcmp(allValidNames, allActualNames); + str = sprintf([... + 'The following names are remapped to valid MATLAB ', ... + 'names:\n%s\nbut will be written to file as originally ', ... + 'named:\n%s\n'], ... + strjoin(" - " + allValidNames(hasAlias), newline), ... + strjoin(" - " + allActualNames(hasAlias), newline)); + else + str = ''; + end + if ~isempty(str) + warnState = warning('backtrace', 'off'); + resetWarningObj = onCleanup(@() warning(warnState)); + warning(str) + end end end @@ -220,7 +248,7 @@ function addDynamicProperties(obj) keys = setObj.keys; for j = 1:numel(keys) - obj.addSingleDynamicProperty(keys{j}, setObj.get(keys{j})) + obj.addSingleDynamicProperty(keys{j}, setObj.get(keys{j}), groupPropName) end elseif isa(setObj, 'types.untyped.Anon') name = setObj.name; @@ -243,26 +271,37 @@ function pruneDynamicProperties(obj) subgroupElementNames = [subgroupElementNames, thisSet.keys]; %#ok end - - removedPropNames = setdiff(dynamicPropertyNames, subgroupElementNames); + validMatlabNames = obj.getValidNames(subgroupElementNames); + removedPropNames = setdiff(dynamicPropertyNames, validMatlabNames); for i = 1:numel(removedPropNames) dynamicPropertyMeta = obj.DynamicPropertyMap(removedPropNames{i}); delete(dynamicPropertyMeta) obj.DynamicPropertyMap.remove(removedPropNames{i}) + obj.ValidNameMap.remove(removedPropNames{i}) end end - function addSingleDynamicProperty(obj, name, value) - if ~isprop(obj, name) - p = obj.addprop(name); - obj.DynamicPropertyMap(name) = p; + function addSingleDynamicProperty(obj, name, value, groupName) + + % Todo: + % - Need to consider where name is used in another group, + % and prepend the group name if yes + % - Need to consider that makeValidName can map different names + % to the same name, i.e "my_data" and "my-data" -> my_data + % Todo: make separate function + matlabValidName = matlab.lang.makeValidName(name); + + if ~isprop(obj, matlabValidName) + p = obj.addprop(matlabValidName); + obj.DynamicPropertyMap(matlabValidName) = p; + obj.ValidNameMap(matlabValidName) = name; else - p = obj.DynamicPropertyMap(name); + p = obj.DynamicPropertyMap(matlabValidName); if iscell(p); p = p{1}; end end p.SetAccess = 'public'; - obj.(name) = value; + obj.(matlabValidName) = value; % Dynamic props can only be set from within the class p.SetAccess = 'protected'; end @@ -278,6 +317,17 @@ function addSingleDynamicProperty(obj, name, value) isMatch = ismember(lower(typeClassNamesShort), groupPropertyNames); result = typeClassNames(isMatch); end + + function validNames = getValidNames(obj, actualNames) + allValidNames = obj.ValidNameMap.keys(); + allActualNames = obj.ValidNameMap.values(); + + validNames = actualNames; + for i = 1:numel(actualNames) + isMatch = strcmp(allActualNames, actualNames{i}); + validNames(i) = allValidNames(isMatch); + end + end end methods (Access = private) % types.untyped.Set callback functions From 1f75bf1077ef6f5ad7bdfd0fee695857a9af7a57 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Fri, 2 May 2025 19:08:12 +0200 Subject: [PATCH 17/65] Add name-mapping strategy for invalid or duplicate names --- +matnwb/+mixin/HasUnnamedGroups.m | 153 ++++++++++++++++++++---------- 1 file changed, 103 insertions(+), 50 deletions(-) diff --git a/+matnwb/+mixin/HasUnnamedGroups.m b/+matnwb/+mixin/HasUnnamedGroups.m index 99eab992e..d4b6c80c1 100644 --- a/+matnwb/+mixin/HasUnnamedGroups.m +++ b/+matnwb/+mixin/HasUnnamedGroups.m @@ -47,6 +47,10 @@ % Todo: Add custom footer if any names are aliased to valid matlab names. +% Todo: consider reverse name map, because mapping from actual to valid +% names is ambiguous if the same name is used across groups. +% Or consider one map per contained group + properties (Abstract, Access = protected, Transient) GroupPropertyNames % Cell array of property names that contain Sets end @@ -59,6 +63,10 @@ ValidNameMap end + properties (Access = private, Dependent, Transient) + NumGroups + end + methods function obj = HasUnnamedGroups() obj.DynamicPropertyMap = containers.Map(); @@ -128,6 +136,12 @@ function remove(obj, name) end end end + + methods % Get + function numGroups = get.NumGroups(obj) + numGroups = numel(obj.GroupPropertyNames); + end + end methods (Access = protected) function setupHasUnnamedGroupsMixin(obj) @@ -194,21 +208,24 @@ function setupHasUnnamedGroupsMixin(obj) groups(end+1) = matlab.mixin.util.PropertyGroup(propList, title); %#ok end end - obj.aliasWarning() + obj.displayAliasWarning() end - function aliasWarning(obj) + function displayAliasWarning(obj) allValidNames = string(obj.ValidNameMap.keys()); allActualNames = string(obj.ValidNameMap.values()); if ~isequal(allValidNames, allActualNames) hasAlias = ~strcmp(allValidNames, allActualNames); + + T = table(allValidNames(hasAlias)', allActualNames(hasAlias)', ... + 'VariableNames', {'ValidName', 'ActualName'} ); %#ok + nameMap = evalc('disp(T)'); + str = sprintf([... - 'The following names are remapped to valid MATLAB ', ... - 'names:\n%s\nbut will be written to file as originally ', ... - 'named:\n%s\n'], ... - strjoin(" - " + allValidNames(hasAlias), newline), ... - strjoin(" - " + allActualNames(hasAlias), newline)); + 'The following named elements of "%s" are remapped to have valid MATLAB ', ... + 'names, but will be written to file with their actual names:', ... + '\n%s\n'], obj.TypeName, strip(nameMap, 'right')); else str = ''; end @@ -221,40 +238,45 @@ function aliasWarning(obj) end methods (Access = private) + function containerObj = getGroupContainer(obj, groupNumber) + propertyNameForGroup = obj.GroupPropertyNames{groupNumber}; + containerObj = obj.(propertyNameForGroup); + end + function assignContainedSetCallbackFunctions(obj) - for i = 1:length(obj.GroupPropertyNames) - groupPropName = obj.GroupPropertyNames{i}; - - setObject = obj.(groupPropName); - if isa(setObject, 'types.untyped.Set') - setObject.ItemAddedFunction = ... - @(itemName) obj.onSetItemAdded(itemName); - setObject.ItemRemovedFunction = ... - @(itemName) obj.onSetItemRemoved(itemName); + for i = 1:obj.NumGroups + propertyNameForGroup = obj.GroupPropertyNames{i}; + containerObj = obj.getGroupContainer(i); + + if isa(containerObj, 'types.untyped.Set') + containerObj.ItemAddedFunction = ... + @(itemName, groupName) obj.onSetItemAdded(itemName, propertyNameForGroup); + containerObj.ItemRemovedFunction = ... + @(itemName, groupName) obj.onSetItemRemoved(itemName, propertyNameForGroup); else warning('NWB:HasUnnamedGroupsMixin:NotImplemented', ... - 'Callback functions are not implemented for Anon sets.') + 'Callback functions are not implemented for Anon types.') end end end function addDynamicProperties(obj) - % TODO: What if multiple groups have the same subkeys? - for i = 1:length(obj.GroupPropertyNames) - groupPropName = obj.GroupPropertyNames{i}; - - setObj = obj.(groupPropName); - if isa(setObj, 'types.untyped.Set') - keys = setObj.keys; + % addDynamicProperties - Add dynamic properties for set values + + for i = 1:obj.NumGroups + groupPropertyName = obj.GroupPropertyNames{i}; + containerObj = obj.getGroupContainer(i); + + if isa(containerObj, 'types.untyped.Set') + keys = containerObj.keys(); for j = 1:numel(keys) - obj.addSingleDynamicProperty(keys{j}, setObj.get(keys{j}), groupPropName) + obj.addSingleDynamicProperty(keys{j}, groupPropertyName) end - elseif isa(setObj, 'types.untyped.Anon') - name = setObj.name; - value = setObj.value; + elseif isa(containerObj, 'types.untyped.Anon') + name = containerObj.name; if ~isempty(name) - obj.addSingleDynamicProperty(name, value) + obj.addSingleDynamicProperty(name, groupPropertyName) end end end @@ -282,28 +304,20 @@ function pruneDynamicProperties(obj) end end - function addSingleDynamicProperty(obj, name, value, groupName) - - % Todo: - % - Need to consider where name is used in another group, - % and prepend the group name if yes - % - Need to consider that makeValidName can map different names - % to the same name, i.e "my_data" and "my-data" -> my_data - % Todo: make separate function - matlabValidName = matlab.lang.makeValidName(name); + function addSingleDynamicProperty(obj, name, groupName) + % addSingleDynamicProperty - Add a single dynamic property to the class + matlabValidName = obj.createValidName(name, groupName); if ~isprop(obj, matlabValidName) p = obj.addprop(matlabValidName); + p.Dependent = true; + p.GetMethod = @(nm, gnm) obj.getDynamicPropertyValueFromSet(matlabValidName, groupName); obj.DynamicPropertyMap(matlabValidName) = p; obj.ValidNameMap(matlabValidName) = name; else - p = obj.DynamicPropertyMap(matlabValidName); - if iscell(p); p = p{1}; end + error('NWB:HasUnnamedGroupsMixin:DynamicPropertyExists', ... + 'Dynamic property with name "%s" already exists', matlabValidName) end - p.SetAccess = 'public'; - obj.(matlabValidName) = value; - % Dynamic props can only be set from within the class - p.SetAccess = 'protected'; end function result = getClassNamesForAllowedGroupTypes(obj) @@ -317,7 +331,37 @@ function addSingleDynamicProperty(obj, name, value, groupName) isMatch = ismember(lower(typeClassNamesShort), groupPropertyNames); result = typeClassNames(isMatch); end - + + function validName = createValidName(obj, name, groupName) + % createValidName - Create a valid MATLAB name to using for dynamic + % property. + + % Make sure the valid name is unique across groups + if obj.NumGroups > 1 + existingNames = obj.ValidNameMap.values(); + % If the name already exists, prepend the group name to the + % name + if any(strcmp(name, existingNames)) + name = [groupName, '_', name]; + end + end + + % Make sure the valid name is unique across all other valid names + isFinished = false; + suggestedName = name; + counter = 0; + while ~isFinished + suggestedName = matlab.lang.makeValidName(suggestedName); + if ~any( strcmp(obj.ValidNameMap.keys(), suggestedName)) + isFinished = true; + else + counter = counter+1; + suggestedName = sprintf('%s_%d', name, counter); + end + end + validName = suggestedName; + end + function validNames = getValidNames(obj, actualNames) allValidNames = obj.ValidNameMap.keys(); allActualNames = obj.ValidNameMap.values(); @@ -330,15 +374,24 @@ function addSingleDynamicProperty(obj, name, value, groupName) end end + methods % Dynamic property get method + function value = getDynamicPropertyValueFromSet(obj, name, groupName, varargin) + actualName = obj.ValidNameMap(name); + value = obj.(groupName).get(actualName); + end + + function value = getDynamicPropertyValueFromAnon(obj, groupName) + value = obj.(groupName).value; + end + end + methods (Access = private) % types.untyped.Set callback functions - function onSetItemAdded(obj, name) + function onSetItemAdded(obj, name, groupName) % onSetItemAdded - Handle items being added to a contained types.untyped.Set - - % Todo: pass name to addDynamicProperties - obj.addDynamicProperties() + obj.addSingleDynamicProperty(name, groupName) end - function onSetItemRemoved(obj, name) + function onSetItemRemoved(obj, name, groupName) % onSetItemRemoved - Handle items being removed from a contained types.untyped.Set % Todo: pass name to pruneDynamicProperties From cb79ebd1a47f5160e600c05cc2b1b1bc568af4f7 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Fri, 2 May 2025 20:50:59 +0200 Subject: [PATCH 18/65] Fix bugs related to name remapping and custom display property names --- +matnwb/+mixin/HasUnnamedGroups.m | 175 ++++++++++++++++++++++++------ 1 file changed, 140 insertions(+), 35 deletions(-) diff --git a/+matnwb/+mixin/HasUnnamedGroups.m b/+matnwb/+mixin/HasUnnamedGroups.m index d4b6c80c1..4776f712c 100644 --- a/+matnwb/+mixin/HasUnnamedGroups.m +++ b/+matnwb/+mixin/HasUnnamedGroups.m @@ -45,12 +45,6 @@ % are no schemas in NWB where Anon sets are used, and this class does not % currently support contained Anon sets. -% Todo: Add custom footer if any names are aliased to valid matlab names. - -% Todo: consider reverse name map, because mapping from actual to valid -% names is ambiguous if the same name is used across groups. -% Or consider one map per contained group - properties (Abstract, Access = protected, Transient) GroupPropertyNames % Cell array of property names that contain Sets end @@ -60,7 +54,10 @@ % storing the dynamic property objects for each added dynamic % property, accessible by the dynamic property name DynamicPropertyMap - ValidNameMap + % ValidNameMaps - A containers.Map (groupName) -> (containers.Map) + % Each group has its own ValidNameMap that maps valid MATLAB names to + % actual NWB names + ValidNameMaps end properties (Access = private, Dependent, Transient) @@ -70,7 +67,7 @@ methods function obj = HasUnnamedGroups() obj.DynamicPropertyMap = containers.Map(); - obj.ValidNameMap = containers.Map(); + obj.ValidNameMaps = containers.Map(); end end @@ -124,7 +121,8 @@ function remove(obj, name) if isa(thisSet, 'types.untyped.Anon') error('Not implemented yet') end - actualName = obj.ValidNameMap(name); + % Find which group contains this name + actualName = obj.getActualNameFromValidName(name); if thisSet.isKey(actualName) try thisSet.remove(actualName) @@ -181,7 +179,7 @@ function setupHasUnnamedGroupsMixin(obj) if strcmp(displayPref, 'groups') % Create property groups for each Set property - for i = 1:length(obj.GroupPropertyNames) + for i = 1:obj.NumGroups groupPropName = obj.GroupPropertyNames{i}; assert(isprop(obj, groupPropName), ... 'Expected "%s" to be a property of class', groupPropName) @@ -193,7 +191,7 @@ function setupHasUnnamedGroupsMixin(obj) % Get all keys from the Set keys = setObj.keys(); - validNames = obj.getValidNames(keys); + validNames = obj.getValidNames(keys, groupPropName); if ~isempty(keys) propList = cell2struct(setObj.values(), validNames, 2); @@ -212,8 +210,20 @@ function setupHasUnnamedGroupsMixin(obj) end function displayAliasWarning(obj) - allValidNames = string(obj.ValidNameMap.keys()); - allActualNames = string(obj.ValidNameMap.values()); + allValidNames = string.empty; + allActualNames = string.empty; + + % Collect all valid and actual names from all groups + groupNames = obj.ValidNameMaps.keys(); + for i = 1:numel(groupNames) + groupName = groupNames{i}; + validNameMap = obj.ValidNameMaps(groupName); + + if ~isempty(validNameMap) + allValidNames = [allValidNames, string(validNameMap.keys())]; %#ok + allActualNames = [allActualNames, string(validNameMap.values())]; %#ok + end + end if ~isequal(allValidNames, allActualNames) hasAlias = ~strcmp(allValidNames, allActualNames); @@ -286,21 +296,45 @@ function pruneDynamicProperties(obj) dynamicPropertyNames = obj.DynamicPropertyMap.keys(); subgroupElementNames = string.empty; + groupNames = string.empty; for i = 1:numel(obj.GroupPropertyNames) thisGroupName = obj.GroupPropertyNames{i}; thisSet = obj.(thisGroupName); + + keys = thisSet.keys(); + subgroupElementNames = [subgroupElementNames, keys]; %#ok + groupNames = [groupNames, repmat(string(thisGroupName), 1, numel(keys))]; %#ok + end - subgroupElementNames = [subgroupElementNames, thisSet.keys]; %#ok + validMatlabNames = string.empty; + for i = 1:numel(subgroupElementNames) + if ~isempty(obj.ValidNameMaps(char(groupNames(i)))) + validMap = obj.ValidNameMaps(char(groupNames(i))); + validKeys = validMap.keys(); + validValues = validMap.values(); + + idx = find(strcmp(validValues, subgroupElementNames{i}), 1); + if ~isempty(idx) + validMatlabNames = [validMatlabNames, string(validKeys{idx})]; %#ok + end + end end - validMatlabNames = obj.getValidNames(subgroupElementNames); + removedPropNames = setdiff(dynamicPropertyNames, validMatlabNames); for i = 1:numel(removedPropNames) dynamicPropertyMeta = obj.DynamicPropertyMap(removedPropNames{i}); delete(dynamicPropertyMeta) obj.DynamicPropertyMap.remove(removedPropNames{i}) - obj.ValidNameMap.remove(removedPropNames{i}) + + % Remove from the appropriate ValidNameMap + for j = 1:numel(obj.GroupPropertyNames) + thisGroupName = obj.GroupPropertyNames{j}; + if obj.ValidNameMaps.isKey(thisGroupName) && obj.ValidNameMaps(thisGroupName).isKey(removedPropNames{i}) + obj.ValidNameMaps(thisGroupName).remove(removedPropNames{i}); + end + end end end @@ -313,13 +347,31 @@ function addSingleDynamicProperty(obj, name, groupName) p.Dependent = true; p.GetMethod = @(nm, gnm) obj.getDynamicPropertyValueFromSet(matlabValidName, groupName); obj.DynamicPropertyMap(matlabValidName) = p; - obj.ValidNameMap(matlabValidName) = name; + + % Create ValidNameMap for this group if it doesn't exist + if ~obj.ValidNameMaps.isKey(groupName) + obj.ValidNameMaps(groupName) = containers.Map(); + end + + % Add mapping to the group's ValidNameMap + nameMapForGoup = obj.ValidNameMaps(groupName); + nameMapForGoup(matlabValidName) = name; %#ok else error('NWB:HasUnnamedGroupsMixin:DynamicPropertyExists', ... 'Dynamic property with name "%s" already exists', matlabValidName) end end + function deleteDynamicProperty(obj, name, groupName) + dynamicPropertyMeta = obj.DynamicPropertyMap(name); + delete(dynamicPropertyMeta) + obj.DynamicPropertyMap.remove(name) + + if obj.ValidNameMaps.isKey(groupName) && obj.ValidNameMaps(groupName).isKey(name) + obj.ValidNameMaps(groupName).remove(name); + end + end + function result = getClassNamesForAllowedGroupTypes(obj) % getAllowedGroupTypes - Resolve full class names for the allowed group types. groupPropertyNames = obj.GroupPropertyNames; @@ -333,26 +385,36 @@ function addSingleDynamicProperty(obj, name, groupName) end function validName = createValidName(obj, name, groupName) - % createValidName - Create a valid MATLAB name to using for dynamic - % property. + % createValidName - Create a valid MATLAB name to use for dynamic property. % Make sure the valid name is unique across groups if obj.NumGroups > 1 - existingNames = obj.ValidNameMap.values(); - % If the name already exists, prepend the group name to the - % name + % Check if the name already exists in any other group + existingNames = []; + otherGroupNames = obj.ValidNameMaps.keys(); + for i = 1:numel(otherGroupNames) + otherGroupName = otherGroupNames{i}; + if ~strcmp(otherGroupName, groupName) && obj.ValidNameMaps.isKey(otherGroupName) + otherGroupMap = obj.ValidNameMaps(otherGroupName); + if ~isempty(otherGroupMap) + existingNames = [existingNames, otherGroupMap.values()]; %#ok + end + end + end + + % If the name already exists in another group, prepend the group name if any(strcmp(name, existingNames)) name = [groupName, '_', name]; end end - % Make sure the valid name is unique across all other valid names + % Make sure the valid name is unique across all dynamic properties isFinished = false; suggestedName = name; counter = 0; while ~isFinished suggestedName = matlab.lang.makeValidName(suggestedName); - if ~any( strcmp(obj.ValidNameMap.keys(), suggestedName)) + if ~isprop(obj, suggestedName) isFinished = true; else counter = counter+1; @@ -362,21 +424,66 @@ function addSingleDynamicProperty(obj, name, groupName) validName = suggestedName; end - function validNames = getValidNames(obj, actualNames) - allValidNames = obj.ValidNameMap.keys(); - allActualNames = obj.ValidNameMap.values(); + function validNames = getValidNames(obj, actualNames, groupName) + if nargin < 3 + groupNames = obj.ValidNameMaps.keys(); + else + groupNames = {groupName}; + end - validNames = actualNames; + validNames = cell(size(actualNames)); + + % Check each group's ValidNameMap for i = 1:numel(actualNames) - isMatch = strcmp(allActualNames, actualNames{i}); - validNames(i) = allValidNames(isMatch); + + for j = 1:numel(groupNames) + groupName = groupNames{j}; + validNameMap = obj.ValidNameMaps(groupName); + + % Get all valid names and actual names for this group + allValidNames = validNameMap.keys(); + allActualNames = validNameMap.values(); + + % Find the matching valid name + isMatch = strcmp(allActualNames, actualNames{i}); + if any(isMatch) + validNames{i} = allValidNames{isMatch}; + break; + end + end end end + + function actualName = getActualNameFromValidName(obj, validName) + % getActualNameFromValidName - Reverse-map actual name from valid name + + % Check name maps for each contained group + groupNames = obj.ValidNameMaps.keys(); + + for i = 1:numel(groupNames) + groupName = groupNames{i}; + validNameMap = obj.ValidNameMaps(groupName); + + if validNameMap.isKey(validName) + actualName = validNameMap(validName); + return; + end + end + + % If not found, assume the valid name is the actual name + actualName = validName; + end end methods % Dynamic property get method - function value = getDynamicPropertyValueFromSet(obj, name, groupName, varargin) - actualName = obj.ValidNameMap(name); + function value = getDynamicPropertyValueFromSet(obj, name, groupName) + % Get the actual name from the group's ValidNameMap + if obj.ValidNameMaps.isKey(groupName) && obj.ValidNameMaps(groupName).isKey(name) + nameMapForGroup = obj.ValidNameMaps(groupName); + actualName = nameMapForGroup(name); + else + actualName = name; + end value = obj.(groupName).get(actualName); end @@ -393,9 +500,7 @@ function onSetItemAdded(obj, name, groupName) function onSetItemRemoved(obj, name, groupName) % onSetItemRemoved - Handle items being removed from a contained types.untyped.Set - - % Todo: pass name to pruneDynamicProperties - obj.pruneDynamicProperties() + obj.deleteDynamicProperty(name, groupName) end end end From ebef8ab61a6e4334c735cd8e4724e0d07cf02175 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Fri, 2 May 2025 20:51:35 +0200 Subject: [PATCH 19/65] Update Set.m Only invoke callback if the set operation adds a new element, but not for overrides --- +types/+untyped/Set.m | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/+types/+untyped/Set.m b/+types/+untyped/Set.m index abfede7fe..302a4a37e 100644 --- a/+types/+untyped/Set.m +++ b/+types/+untyped/Set.m @@ -4,7 +4,7 @@ ValidationFcn = @(key, value)[]; end - properties (SetAccess = ?matnwb.mixin.HasUnnamedGroups) + properties (Access = ?matnwb.mixin.HasUnnamedGroups) % These properties enables the HasUnnamedGroups mixin to react when % items are added or removed from the Set. ItemAddedFunction function_handle @@ -162,6 +162,8 @@ function add(obj, name, val) elem = val(i); end + isOverride = obj.isKey(name{i}); + if parser.Results.FailIfKeyExists if obj.isKey(name{i}) error('NWB:Set:KeyExists', ... @@ -172,7 +174,7 @@ function add(obj, name, val) try obj.ValidationFcn(name{i}, elem); obj.Map(name{i}) = elem; - if ~isempty(obj.ItemAddedFunction) + if ~isOverride && ~isempty(obj.ItemAddedFunction) obj.ItemAddedFunction(name{i}) end catch ME From 8263dd1cad9e42e74c46b212c680476adfc52e81 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Fri, 2 May 2025 21:21:44 +0200 Subject: [PATCH 20/65] Add unit test for HasUnnamedGroupsMixin --- +matnwb/+mixin/HasUnnamedGroups.m | 4 +- +tests/+unit/HasUnnamedGroupsTest.m | 144 ++++++++++++++++++++++++++++ 2 files changed, 146 insertions(+), 2 deletions(-) create mode 100644 +tests/+unit/HasUnnamedGroupsTest.m diff --git a/+matnwb/+mixin/HasUnnamedGroups.m b/+matnwb/+mixin/HasUnnamedGroups.m index 4776f712c..c26aef346 100644 --- a/+matnwb/+mixin/HasUnnamedGroups.m +++ b/+matnwb/+mixin/HasUnnamedGroups.m @@ -125,7 +125,7 @@ function remove(obj, name) actualName = obj.getActualNameFromValidName(name); if thisSet.isKey(actualName) try - thisSet.remove(actualName) + thisSet.remove(actualName); break catch ME rethrow(ME) @@ -365,7 +365,7 @@ function addSingleDynamicProperty(obj, name, groupName) function deleteDynamicProperty(obj, name, groupName) dynamicPropertyMeta = obj.DynamicPropertyMap(name); delete(dynamicPropertyMeta) - obj.DynamicPropertyMap.remove(name) + obj.DynamicPropertyMap.remove(name); if obj.ValidNameMaps.isKey(groupName) && obj.ValidNameMaps(groupName).isKey(name) obj.ValidNameMaps(groupName).remove(name); diff --git a/+tests/+unit/HasUnnamedGroupsTest.m b/+tests/+unit/HasUnnamedGroupsTest.m new file mode 100644 index 000000000..c44ec1bbc --- /dev/null +++ b/+tests/+unit/HasUnnamedGroupsTest.m @@ -0,0 +1,144 @@ +classdef (SharedTestFixtures = {tests.fixtures.GenerateCoreFixture}) ... + HasUnnamedGroupsTest < matlab.unittest.TestCase + % HASUNNAMEDGROUPSTEST Tests for the HasUnnamedGroups mixin + % + % This test suite verifies the functionality of the HasUnnamedGroups mixin, + % which is used to simplify access to unnamed subgroup Sets. + % It uses types.core.ProcessingModule as a test type because it's the only + % NWB type that has two groups. + + methods (Test) + function testAddRemove(testCase) + % Test add and remove methods of HasUnnamedGroups mixin + + % Create a ProcessingModule + module = types.core.ProcessingModule(); + + % Add a new type using the Set interface + module.add('TimeSeries', types.core.TimeSeries()); + + % Verify that the dynamic property was created + testCase.verifyTrue(isprop(module, 'TimeSeries'), ... + 'Dynamic property was not created'); + + % Verify that the dynamic property returns the correct value + testCase.verifyClass(module.TimeSeries, ... + 'types.core.TimeSeries', ... + 'Dynamic property returned incorrect value'); + + % Remove the item and verify it's gone + module.remove('TimeSeries'); + testCase.verifyFalse(isprop(module, 'TimeSeries'), ... + 'Dynamic property was not removed'); + end + + function testLegacySyntax(testCase) + % Create a ProcessingModule + module = types.core.ProcessingModule(); + + % Add a new type using the Set interface + module.nwbdatainterface.set('TimeSeries', types.core.TimeSeries()); + + % Verify that the dynamic property was created + testCase.verifyTrue(isprop(module, 'TimeSeries'), ... + 'Dynamic property was not created'); + + % Verify that the dynamic property returns the correct value + testCase.verifyClass(module.TimeSeries, ... + 'types.core.TimeSeries', ... + 'Dynamic property returned incorrect value'); + + % Remove the item and verify it's gone + module.nwbdatainterface.remove('TimeSeries'); + testCase.verifyFalse(isprop(module, 'TimeSeries'), ... + 'Dynamic property was not removed'); + end + + function testInvalidMatlabName(testCase) + % Create a ProcessingModule + module = types.core.ProcessingModule(); + + % Add items with similar names to nwbdatainterface + module.add('Time-Series', types.core.TimeSeries()) + + % Verify that the dynamic property was created + testCase.verifyTrue(isprop(module, 'Time_Series'), ... + 'Dynamic property was not created'); + + testCase.verifyClass(module.Time_Series, ... + 'types.core.TimeSeries', ... + 'Dynamic property returned incorrect value'); + end + + function testSimilarNames(testCase) + % Test handling of similar names that result in the same valid name + + % Create a ProcessingModule + module = types.core.ProcessingModule(); + + % Add items with similar names to nwbdatainterface + module.add('Time_Series', types.core.TimeSeries()) + + module.add('Time-Series', types.core.TimeSeries()) + + % Verify that the dynamic property was created + testCase.verifyTrue(isprop(module, 'Time_Series'), ... + 'Dynamic property was not created'); + + % Verify that similarly named property was created + testCase.verifyTrue(isprop(module, 'Time_Series_1'), ... + 'Dynamic property was not created'); + end + + function testCrossGroupNameConflicts(testCase) + % Test handling of name conflicts across different groups + + % Create a ProcessingModule + module = types.core.ProcessingModule(); + + % Add items with the same name to different groups + module.nwbdatainterface.set('Test', types.core.TimeSeries()); + module.dynamictable.set('Test', types.hdmf_common.DynamicTable()); + + % Verify both properties exist with appropriate names + % One should be Test and the other should have the group name prepended + testCase.verifyTrue(isprop(module, 'Test'), ... + 'Dynamic property Test was not created'); + testCase.verifyTrue(isprop(module, 'dynamictable_Test'), ... + 'Dynamic property dynamictable_Test was not created'); + + % Verify the properties return the correct values + if isa(module.Test, 'types.core.TimeSeries') + testCase.verifyClass(module.Test, 'types.core.TimeSeries', ... + 'Dynamic property Test returned incorrect value'); + testCase.verifyClass(module.dynamictable_Test, 'types.hdmf_common.DynamicTable', ... + 'Dynamic property dynamictable_Test returned incorrect value'); + else + testCase.verifyClass(module.Test, 'types.hdmf_common.DynamicTable', ... + 'Dynamic property Test returned incorrect value'); + testCase.verifyClass(module.nwbdatainterface_Test, 'types.core.TimeSeries', ... + 'Dynamic property nwbdatainterface_Test returned incorrect value'); + end + end + + function testOverriding(testCase) + % Test overriding an existing item + + % Create a ProcessingModule + module = types.core.ProcessingModule(); + + % Add an item + module.nwbdatainterface.set('Test', types.core.TimeSeries()); + testCase.verifyTrue(isprop(module, 'Test'), 'Dynamic property Test was not created'); + testCase.verifyClass(module.Test, 'types.core.TimeSeries', ... + 'Dynamic property Test did not return expected value'); + + % Override it with a different type + module.nwbdatainterface.set('Test', types.core.Fluorescence()); + + % Verify the property has the new type + testCase.verifyClass(module.Test, 'types.core.Fluorescence', ... + 'Dynamic property Test did not return the overridden value'); + end + end +end From 9d4577923a8cf36deb153d6e5caef388c01fd51e Mon Sep 17 00:00:00 2001 From: ehennestad Date: Fri, 2 May 2025 21:31:36 +0200 Subject: [PATCH 21/65] Add extra tests --- +tests/+unit/FunctionTests.m | 5 +++++ +tests/+unit/HasUnnamedGroupsTest.m | 20 ++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/+tests/+unit/FunctionTests.m b/+tests/+unit/FunctionTests.m index 15574d579..8acd7e853 100644 --- a/+tests/+unit/FunctionTests.m +++ b/+tests/+unit/FunctionTests.m @@ -26,5 +26,10 @@ function testIsNeurodatatype(testCase) dataPipe = types.untyped.DataPipe('data', rand(10,10)); testCase.verifyFalse(matnwb.utility.isNeurodataType(dataPipe)) end + + function testListGeneratedTypesWithShortNames(testCase) + typeNames = schemes.utility.listGeneratedTypes("OutputType", "short name"); + testCase.verifyTrue(contains('NWBFile', typeNames)) + end end end diff --git a/+tests/+unit/HasUnnamedGroupsTest.m b/+tests/+unit/HasUnnamedGroupsTest.m index c44ec1bbc..120c429fc 100644 --- a/+tests/+unit/HasUnnamedGroupsTest.m +++ b/+tests/+unit/HasUnnamedGroupsTest.m @@ -120,6 +120,18 @@ function testCrossGroupNameConflicts(testCase) 'Dynamic property nwbdatainterface_Test returned incorrect value'); end end + + function testAddingWithExistingName(testCase) + % Create a ProcessingModule + module = types.core.ProcessingModule(); + + % Add items with similar names to nwbdatainterface + module.add('TimeSeries', types.core.TimeSeries()) + + testCase.verifyError(... + @() module.add('TimeSeries', types.core.TimeSeries()), ... + 'NWB:HasUnnamedGroupsMixin:KeyExists') + end function testOverriding(testCase) % Test overriding an existing item @@ -140,5 +152,13 @@ function testOverriding(testCase) testCase.verifyClass(module.Test, 'types.core.Fluorescence', ... 'Dynamic property Test did not return the overridden value'); end + + function testInvalidType(testCase) + module = types.core.ProcessingModule(); + + testCase.verifyError(... + @() module.add('Device', types.core.Device()), ... + 'NWB:HasUnnamedGroupsMixin:AddInvalidType') + end end end From addb0fc76e1d386f63e2c87148747e678ca7f450 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Fri, 2 May 2025 21:50:49 +0200 Subject: [PATCH 22/65] Update tests, remove unused/redundant method --- +matnwb/+mixin/HasUnnamedGroups.m | 48 +---------------------------- +tests/+unit/HasUnnamedGroupsTest.m | 36 ++++++++++++++++++++++ 2 files changed, 37 insertions(+), 47 deletions(-) diff --git a/+matnwb/+mixin/HasUnnamedGroups.m b/+matnwb/+mixin/HasUnnamedGroups.m index c26aef346..96fcad83d 100644 --- a/+matnwb/+mixin/HasUnnamedGroups.m +++ b/+matnwb/+mixin/HasUnnamedGroups.m @@ -291,53 +291,7 @@ function addDynamicProperties(obj) end end end - - function pruneDynamicProperties(obj) - dynamicPropertyNames = obj.DynamicPropertyMap.keys(); - - subgroupElementNames = string.empty; - groupNames = string.empty; - - for i = 1:numel(obj.GroupPropertyNames) - thisGroupName = obj.GroupPropertyNames{i}; - thisSet = obj.(thisGroupName); - - keys = thisSet.keys(); - subgroupElementNames = [subgroupElementNames, keys]; %#ok - groupNames = [groupNames, repmat(string(thisGroupName), 1, numel(keys))]; %#ok - end - - validMatlabNames = string.empty; - for i = 1:numel(subgroupElementNames) - if ~isempty(obj.ValidNameMaps(char(groupNames(i)))) - validMap = obj.ValidNameMaps(char(groupNames(i))); - validKeys = validMap.keys(); - validValues = validMap.values(); - - idx = find(strcmp(validValues, subgroupElementNames{i}), 1); - if ~isempty(idx) - validMatlabNames = [validMatlabNames, string(validKeys{idx})]; %#ok - end - end - end - - removedPropNames = setdiff(dynamicPropertyNames, validMatlabNames); - - for i = 1:numel(removedPropNames) - dynamicPropertyMeta = obj.DynamicPropertyMap(removedPropNames{i}); - delete(dynamicPropertyMeta) - obj.DynamicPropertyMap.remove(removedPropNames{i}) - - % Remove from the appropriate ValidNameMap - for j = 1:numel(obj.GroupPropertyNames) - thisGroupName = obj.GroupPropertyNames{j}; - if obj.ValidNameMaps.isKey(thisGroupName) && obj.ValidNameMaps(thisGroupName).isKey(removedPropNames{i}) - obj.ValidNameMaps(thisGroupName).remove(removedPropNames{i}); - end - end - end - end - + function addSingleDynamicProperty(obj, name, groupName) % addSingleDynamicProperty - Add a single dynamic property to the class matlabValidName = obj.createValidName(name, groupName); diff --git a/+tests/+unit/HasUnnamedGroupsTest.m b/+tests/+unit/HasUnnamedGroupsTest.m index 120c429fc..25c7c9935 100644 --- a/+tests/+unit/HasUnnamedGroupsTest.m +++ b/+tests/+unit/HasUnnamedGroupsTest.m @@ -160,5 +160,41 @@ function testInvalidType(testCase) @() module.add('Device', types.core.Device()), ... 'NWB:HasUnnamedGroupsMixin:AddInvalidType') end + + function testObjectDisplay(testCase) + % Create a ProcessingModule + module = types.core.ProcessingModule(); + + % Add items with the same name to different groups + module.add('TimeSeries', types.core.TimeSeries()); + module.add('DynamicTable', types.hdmf_common.DynamicTable()); + + origPrefValue = getpref('matnwb', 'displaymode', 'flat'); + testCase.addTeardown(@() setpref('matnwb', 'displaymode', origPrefValue)) + + setpref('matnwb', 'displaymode', 'flat') + C = evalc('disp(module)'); + testCase.verifyTrue(contains(C, 'TimeSeries:')) + testCase.verifyTrue(contains(C, 'DynamicTable:')) + + setpref('matnwb', 'displaymode', 'groups') + C = evalc('disp(module)'); + testCase.verifyTrue(contains(C, 'nwbdatainterface elements:')) + testCase.verifyTrue(contains(C, 'dynamictable elements:')) + end + + function testObjectWithAliasedNames(testCase) + % Create a ProcessingModule + module = types.core.ProcessingModule(); + + % Add items with the same name to different groups + module.add('Time_Series', types.core.TimeSeries()); + module.add('Time-Series', types.core.TimeSeries()); + + C = evalc('disp(module)'); + + expectedMessage = 'Warning: The following named elements of "ProcessingModule"'; + testCase.verifyTrue( contains(C, expectedMessage)) + end end end From 2d69d9aa3d250f8bdeaebb7c96e90bd2cf6fb84d Mon Sep 17 00:00:00 2001 From: ehennestad Date: Fri, 2 May 2025 22:12:16 +0200 Subject: [PATCH 23/65] Minor fixes in comments --- +matnwb/+mixin/HasUnnamedGroups.m | 5 +---- +schemes/+utility/listGeneratedTypes.m | 2 +- +tests/+unit/HasUnnamedGroupsTest.m | 22 ++++++++++++++-------- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/+matnwb/+mixin/HasUnnamedGroups.m b/+matnwb/+mixin/HasUnnamedGroups.m index 96fcad83d..e4c99b623 100644 --- a/+matnwb/+mixin/HasUnnamedGroups.m +++ b/+matnwb/+mixin/HasUnnamedGroups.m @@ -291,7 +291,7 @@ function addDynamicProperties(obj) end end end - + function addSingleDynamicProperty(obj, name, groupName) % addSingleDynamicProperty - Add a single dynamic property to the class matlabValidName = obj.createValidName(name, groupName); @@ -423,9 +423,6 @@ function deleteDynamicProperty(obj, name, groupName) return; end end - - % If not found, assume the valid name is the actual name - actualName = validName; end end diff --git a/+schemes/+utility/listGeneratedTypes.m b/+schemes/+utility/listGeneratedTypes.m index fe9576597..7732ecddf 100644 --- a/+schemes/+utility/listGeneratedTypes.m +++ b/+schemes/+utility/listGeneratedTypes.m @@ -31,7 +31,7 @@ relativeFilePaths = strrep(absoluteFilePaths, typesDir, ''); typeClassNames = strrep(relativeFilePaths, '.m', ''); - typeClassNames = strrep(typeClassNames, filesep, '.'); % NB: needs to happen before next replacement + typeClassNames = strrep(typeClassNames, filesep, '.'); typeClassNames = strrep(typeClassNames, '+', ''); typeClassNames = string(typeClassNames); diff --git a/+tests/+unit/HasUnnamedGroupsTest.m b/+tests/+unit/HasUnnamedGroupsTest.m index 25c7c9935..4f56665fa 100644 --- a/+tests/+unit/HasUnnamedGroupsTest.m +++ b/+tests/+unit/HasUnnamedGroupsTest.m @@ -14,7 +14,7 @@ function testAddRemove(testCase) % Create a ProcessingModule module = types.core.ProcessingModule(); - % Add a new type using the Set interface + % Add a new type using the mixin's add method module.add('TimeSeries', types.core.TimeSeries()); % Verify that the dynamic property was created @@ -61,7 +61,8 @@ function testInvalidMatlabName(testCase) % Add items with similar names to nwbdatainterface module.add('Time-Series', types.core.TimeSeries()) - % Verify that the dynamic property was created + % Verify that the dynamic property was created and accessible + % with a valid MATLAB name testCase.verifyTrue(isprop(module, 'Time_Series'), ... 'Dynamic property was not created'); @@ -121,13 +122,13 @@ function testCrossGroupNameConflicts(testCase) end end - function testAddingWithExistingName(testCase) + function testAddWithExistingName(testCase) % Create a ProcessingModule module = types.core.ProcessingModule(); - % Add items with similar names to nwbdatainterface module.add('TimeSeries', types.core.TimeSeries()) + % Adding a new object with the same name should fail testCase.verifyError(... @() module.add('TimeSeries', types.core.TimeSeries()), ... 'NWB:HasUnnamedGroupsMixin:KeyExists') @@ -165,7 +166,7 @@ function testObjectDisplay(testCase) % Create a ProcessingModule module = types.core.ProcessingModule(); - % Add items with the same name to different groups + % Add one object to each of the subgroups module.add('TimeSeries', types.core.TimeSeries()); module.add('DynamicTable', types.hdmf_common.DynamicTable()); @@ -187,14 +188,19 @@ function testObjectWithAliasedNames(testCase) % Create a ProcessingModule module = types.core.ProcessingModule(); - % Add items with the same name to different groups + % Add items with similar names that will evaluate to the same + % valid name module.add('Time_Series', types.core.TimeSeries()); module.add('Time-Series', types.core.TimeSeries()); C = evalc('disp(module)'); - expectedMessage = 'Warning: The following named elements of "ProcessingModule"'; - testCase.verifyTrue( contains(C, expectedMessage)) + % Verify that the displayed object will contain a warning + % message informing about "alias" names + expectedMessage = 'Warning: The following named elements of "ProcessingModule"'; % ... + testCase.verifyTrue( contains(C, expectedMessage)) + % Would use startsWith instead of contains, but C contains some + % hidden "display" characters in the beginning end end end From 5d8a8ba578947c1307663c85d5830df460ced7ee Mon Sep 17 00:00:00 2001 From: ehennestad Date: Sat, 3 May 2025 22:11:13 +0200 Subject: [PATCH 24/65] Refactor HasUnnamedGroups Improve variable naming Remove unused code --- +matnwb/+mixin/HasUnnamedGroups.m | 184 +++++++++++++----------------- +tests/+unit/untypedSetTest.m | 15 +++ 2 files changed, 93 insertions(+), 106 deletions(-) diff --git a/+matnwb/+mixin/HasUnnamedGroups.m b/+matnwb/+mixin/HasUnnamedGroups.m index e4c99b623..a1f38dd16 100644 --- a/+matnwb/+mixin/HasUnnamedGroups.m +++ b/+matnwb/+mixin/HasUnnamedGroups.m @@ -46,7 +46,8 @@ % currently support contained Anon sets. properties (Abstract, Access = protected, Transient) - GroupPropertyNames % Cell array of property names that contain Sets + GroupPropertyNames (1,:) string % String array of property names that contain Sets + % todo: string end properties (Access = private, Transient) @@ -60,10 +61,6 @@ ValidNameMaps end - properties (Access = private, Dependent, Transient) - NumGroups - end - methods function obj = HasUnnamedGroups() obj.DynamicPropertyMap = containers.Map(); @@ -75,16 +72,15 @@ function add(obj, name, value) wasSuccess = false; - for i = 1:numel(obj.GroupPropertyNames) - thisGroupName = obj.GroupPropertyNames{i}; - thisSet = obj.(thisGroupName); + for groupName = obj.GroupPropertyNames + currentSet = obj.(groupName); - if isa(thisSet, 'types.untyped.Anon') + if isa(currentSet, 'types.untyped.Anon') error('Not implemented yet') end try - thisSet.set(name, value, ... + currentSet.set(name, value, ... 'FailOnInvalidType', true, ... 'FailIfKeyExists', true); wasSuccess = true; @@ -114,32 +110,25 @@ function add(obj, name, value) end function remove(obj, name) - for i = 1:numel(obj.GroupPropertyNames) - thisGroupName = obj.GroupPropertyNames{i}; - thisSet = obj.(thisGroupName); - - if isa(thisSet, 'types.untyped.Anon') + % remove - remove object given it's (matlab-valid) name + for groupName = obj.GroupPropertyNames + currentSet = obj.(groupName); + + if isa(currentSet, 'types.untyped.Anon') error('Not implemented yet') end - % Find which group contains this name - actualName = obj.getActualNameFromValidName(name); - if thisSet.isKey(actualName) - try - thisSet.remove(actualName); + + if obj.ValidNameMaps(groupName).isKey(name) + actualName = obj.getActualNameFromValidName(name, groupName); + + if currentSet.isKey(actualName) + currentSet.remove(actualName); break - catch ME - rethrow(ME) end end end end end - - methods % Get - function numGroups = get.NumGroups(obj) - numGroups = numel(obj.GroupPropertyNames); - end - end methods (Access = protected) function setupHasUnnamedGroupsMixin(obj) @@ -156,8 +145,9 @@ function setupHasUnnamedGroupsMixin(obj) % Remove the Set properties that we'll display separately toSkip = false(1, length(obj.GroupPropertyNames)); - for i = 1:length(obj.GroupPropertyNames) - idx = strcmp(standardProps, obj.GroupPropertyNames{i}); + + for groupName = obj.GroupPropertyNames + idx = strcmp(standardProps, groupName); toSkip(idx) = true; end @@ -179,28 +169,28 @@ function setupHasUnnamedGroupsMixin(obj) if strcmp(displayPref, 'groups') % Create property groups for each Set property - for i = 1:obj.NumGroups - groupPropName = obj.GroupPropertyNames{i}; - assert(isprop(obj, groupPropName), ... - 'Expected "%s" to be a property of class', groupPropName) + for groupName = obj.GroupPropertyNames + assert(isprop(obj, groupName), ... + 'Expected "%s" to be a property of class', groupName) % Get the Set property - setObj = obj.(groupPropName); + setObj = obj.(groupName); assert(~isempty(setObj) && isa(setObj, 'types.untyped.Set'), ... - 'Expected property "%s" to contain a Set', groupPropName) + 'Expected property "%s" to contain a Set', groupName) % Get all keys from the Set keys = setObj.keys(); - validNames = obj.getValidNames(keys, groupPropName); + validNames = obj.getValidNamesFromActualNames(keys, groupName); + + % Initialize property list + propList = string(missing); if ~isempty(keys) propList = cell2struct(setObj.values(), validNames, 2); - else - propList = string(missing); end % Create a title for this group - title = ['' groupPropName ' elements:']; + title = "" + groupName + " elements:"; % Add this group to the property groups groups(end+1) = matlab.mixin.util.PropertyGroup(propList, title); %#ok @@ -217,6 +207,7 @@ function displayAliasWarning(obj) groupNames = obj.ValidNameMaps.keys(); for i = 1:numel(groupNames) groupName = groupNames{i}; + validNameMap = obj.ValidNameMaps(groupName); if ~isempty(validNameMap) @@ -248,21 +239,15 @@ function displayAliasWarning(obj) end methods (Access = private) - function containerObj = getGroupContainer(obj, groupNumber) - propertyNameForGroup = obj.GroupPropertyNames{groupNumber}; - containerObj = obj.(propertyNameForGroup); - end - function assignContainedSetCallbackFunctions(obj) - for i = 1:obj.NumGroups - propertyNameForGroup = obj.GroupPropertyNames{i}; - containerObj = obj.getGroupContainer(i); + for groupName = obj.GroupPropertyNames + containerObj = obj.(groupName); if isa(containerObj, 'types.untyped.Set') containerObj.ItemAddedFunction = ... - @(itemName, groupName) obj.onSetItemAdded(itemName, propertyNameForGroup); + @(itemName) obj.onSetItemAdded(itemName, groupName); containerObj.ItemRemovedFunction = ... - @(itemName, groupName) obj.onSetItemRemoved(itemName, propertyNameForGroup); + @(itemName) obj.onSetItemRemoved(itemName, groupName); else warning('NWB:HasUnnamedGroupsMixin:NotImplemented', ... 'Callback functions are not implemented for Anon types.') @@ -273,27 +258,25 @@ function assignContainedSetCallbackFunctions(obj) function addDynamicProperties(obj) % addDynamicProperties - Add dynamic properties for set values - for i = 1:obj.NumGroups - groupPropertyName = obj.GroupPropertyNames{i}; - containerObj = obj.getGroupContainer(i); + for groupName = obj.GroupPropertyNames + containerObj = obj.(groupName); if isa(containerObj, 'types.untyped.Set') keys = containerObj.keys(); - for j = 1:numel(keys) - obj.addSingleDynamicProperty(keys{j}, groupPropertyName) + obj.createDynamicProperty(keys{j}, groupName) end elseif isa(containerObj, 'types.untyped.Anon') name = containerObj.name; if ~isempty(name) - obj.addSingleDynamicProperty(name, groupPropertyName) + obj.createDynamicProperty(name, groupName) end end end end - function addSingleDynamicProperty(obj, name, groupName) - % addSingleDynamicProperty - Add a single dynamic property to the class + function createDynamicProperty(obj, name, groupName) + % createDynamicProperty - Add a single dynamic property to the class matlabValidName = obj.createValidName(name, groupName); if ~isprop(obj, matlabValidName) @@ -342,23 +325,23 @@ function deleteDynamicProperty(obj, name, groupName) % createValidName - Create a valid MATLAB name to use for dynamic property. % Make sure the valid name is unique across groups - if obj.NumGroups > 1 + if numel(obj.GroupPropertyNames) > 1 % Check if the name already exists in any other group existingNames = []; - otherGroupNames = obj.ValidNameMaps.keys(); - for i = 1:numel(otherGroupNames) - otherGroupName = otherGroupNames{i}; - if ~strcmp(otherGroupName, groupName) && obj.ValidNameMaps.isKey(otherGroupName) - otherGroupMap = obj.ValidNameMaps(otherGroupName); - if ~isempty(otherGroupMap) - existingNames = [existingNames, otherGroupMap.values()]; %#ok + allGroupNames = obj.ValidNameMaps.keys(); + for i = 1:numel(allGroupNames) + currentGroupName = allGroupNames{i}; + if ~strcmp(currentGroupName, groupName) && obj.ValidNameMaps.isKey(currentGroupName) + currentGroupMap = obj.ValidNameMaps(currentGroupName); + if ~isempty(currentGroupMap) + existingNames = [existingNames, currentGroupMap.values()]; %#ok end end end % If the name already exists in another group, prepend the group name if any(strcmp(name, existingNames)) - name = [groupName, '_', name]; + name = sprintf('%s_%s', groupName, name); end end @@ -378,62 +361,51 @@ function deleteDynamicProperty(obj, name, groupName) validName = suggestedName; end - function validNames = getValidNames(obj, actualNames, groupName) - if nargin < 3 - groupNames = obj.ValidNameMaps.keys(); - else - groupNames = {groupName}; - end - + function validNames = getValidNamesFromActualNames(obj, actualNames, groupName) + validNames = cell(size(actualNames)); + if isempty(actualNames); return; end + + validNameMap = obj.ValidNameMaps(groupName); + % Get all valid names and actual names for this group + allValidNames = validNameMap.keys(); + allActualNames = validNameMap.values(); + % Check each group's ValidNameMap for i = 1:numel(actualNames) - - for j = 1:numel(groupNames) - groupName = groupNames{j}; - validNameMap = obj.ValidNameMaps(groupName); - - % Get all valid names and actual names for this group - allValidNames = validNameMap.keys(); - allActualNames = validNameMap.values(); - - % Find the matching valid name - isMatch = strcmp(allActualNames, actualNames{i}); - if any(isMatch) - validNames{i} = allValidNames{isMatch}; - break; - end + + % Find the matching valid name + isMatch = strcmp(allActualNames, actualNames{i}); + if any(isMatch) + validNames{i} = allValidNames{isMatch}; end end end - function actualName = getActualNameFromValidName(obj, validName) + function actualName = getActualNameFromValidName(obj, validName, groupName) % getActualNameFromValidName - Reverse-map actual name from valid name - % Check name maps for each contained group - groupNames = obj.ValidNameMaps.keys(); + validNameMap = obj.ValidNameMaps(groupName); - for i = 1:numel(groupNames) - groupName = groupNames{i}; - validNameMap = obj.ValidNameMaps(groupName); - - if validNameMap.isKey(validName) - actualName = validNameMap(validName); - return; - end - end + assert(validNameMap.isKey(validName), ... + 'Expected "%s" to be present in group "%s"', ... + validName, groupName) + + actualName = validNameMap(validName); end end - methods % Dynamic property get method + methods % Dynamic property get methods function value = getDynamicPropertyValueFromSet(obj, name, groupName) % Get the actual name from the group's ValidNameMap - if obj.ValidNameMaps.isKey(groupName) && obj.ValidNameMaps(groupName).isKey(name) + + %Assume actual name is the same as the valid name. + actualName = name; + if obj.ValidNameMaps.isKey(groupName) ... + && obj.ValidNameMaps(groupName).isKey(name) nameMapForGroup = obj.ValidNameMaps(groupName); actualName = nameMapForGroup(name); - else - actualName = name; end value = obj.(groupName).get(actualName); end @@ -446,7 +418,7 @@ function deleteDynamicProperty(obj, name, groupName) methods (Access = private) % types.untyped.Set callback functions function onSetItemAdded(obj, name, groupName) % onSetItemAdded - Handle items being added to a contained types.untyped.Set - obj.addSingleDynamicProperty(name, groupName) + obj.createDynamicProperty(name, groupName) end function onSetItemRemoved(obj, name, groupName) diff --git a/+tests/+unit/untypedSetTest.m b/+tests/+unit/untypedSetTest.m index 2631cc45d..bad7d636e 100644 --- a/+tests/+unit/untypedSetTest.m +++ b/+tests/+unit/untypedSetTest.m @@ -72,5 +72,20 @@ function testSetCharValue(testCase) untypedSet.set('c', 'c'); testCase.verifyEqual(untypedSet.get('c'), 'c') end + + function testAddToSet(testCase) + nwbFile = tests.factory.NWBFile(); + ts = tests.factory.TimeSeriesWithTimestamps; + nwbFile.acquisition.add('ts', ts) + + testCase.verifyTrue(... + nwbFile.acquisition.isKey('ts'), ... + 'Object set with `add` not present in types.untyped.Set'); + + testCase.verifyClass(... + nwbFile.acquisition.get('ts'), ... + 'types.core.TimeSeries', ... + 'Object set with `add` is incorrect value'); + end end end From e7c4c0be79e0dc7698d825a10fce48f3b40d48cf Mon Sep 17 00:00:00 2001 From: ehennestad Date: Sun, 4 May 2025 09:07:36 +0200 Subject: [PATCH 25/65] Refactor HasUnnamedGroups Simplify some code sections Create nameExists method to check i name is already used in subgroup containers --- +matnwb/+mixin/HasUnnamedGroups.m | 72 +++++++++++++++++++------------ +types/+untyped/Anon.m | 4 ++ 2 files changed, 48 insertions(+), 28 deletions(-) diff --git a/+matnwb/+mixin/HasUnnamedGroups.m b/+matnwb/+mixin/HasUnnamedGroups.m index a1f38dd16..b1c2b74fc 100644 --- a/+matnwb/+mixin/HasUnnamedGroups.m +++ b/+matnwb/+mixin/HasUnnamedGroups.m @@ -47,7 +47,6 @@ properties (Abstract, Access = protected, Transient) GroupPropertyNames (1,:) string % String array of property names that contain Sets - % todo: string end properties (Access = private, Transient) @@ -55,6 +54,7 @@ % storing the dynamic property objects for each added dynamic % property, accessible by the dynamic property name DynamicPropertyMap + % ValidNameMaps - A containers.Map (groupName) -> (containers.Map) % Each group has its own ValidNameMap that maps valid MATLAB names to % actual NWB names @@ -70,8 +70,13 @@ methods function add(obj, name, value) + % add - Add a named data object to an un-named subgroup + + if obj.nameExists(name) + throwAsCaller( getNameExistsException(name, obj.TypeName) ) + end + wasSuccess = false; - for groupName = obj.GroupPropertyNames currentSet = obj.(groupName); @@ -81,17 +86,11 @@ function add(obj, name, value) try currentSet.set(name, value, ... - 'FailOnInvalidType', true, ... - 'FailIfKeyExists', true); + 'FailOnInvalidType', true); wasSuccess = true; break catch ME - if strcmp(ME.identifier, 'NWB:Set:KeyExists') - ME = MException('NWB:HasUnnamedGroupsMixin:KeyExists', ... - 'A neurodata object with name `%s` already exists in this `%s`', ... - name, obj.TypeName); - throwAsCaller(ME); - elseif strcmp(ME.identifier, 'NWB:Set:FailedValidation') + if strcmp(ME.identifier, 'NWB:Set:FailedValidation') continue else rethrow(ME) @@ -110,7 +109,7 @@ function add(obj, name, value) end function remove(obj, name) - % remove - remove object given it's (matlab-valid) name + % remove - remove data object given it's (matlab-valid) name for groupName = obj.GroupPropertyNames currentSet = obj.(groupName); @@ -254,6 +253,18 @@ function assignContainedSetCallbackFunctions(obj) end end end + + function tf = nameExists(obj, name) + % nameExists - Check if name already exists in subgroup + tf = false; + for groupName = obj.GroupPropertyNames + containerObj = obj.(groupName); + if containerObj.isKey(name) + tf = true; + break + end + end + end function addDynamicProperties(obj) % addDynamicProperties - Add dynamic properties for set values @@ -279,24 +290,23 @@ function createDynamicProperty(obj, name, groupName) % createDynamicProperty - Add a single dynamic property to the class matlabValidName = obj.createValidName(name, groupName); - if ~isprop(obj, matlabValidName) - p = obj.addprop(matlabValidName); - p.Dependent = true; - p.GetMethod = @(nm, gnm) obj.getDynamicPropertyValueFromSet(matlabValidName, groupName); - obj.DynamicPropertyMap(matlabValidName) = p; - - % Create ValidNameMap for this group if it doesn't exist - if ~obj.ValidNameMaps.isKey(groupName) - obj.ValidNameMaps(groupName) = containers.Map(); - end - - % Add mapping to the group's ValidNameMap - nameMapForGoup = obj.ValidNameMaps(groupName); - nameMapForGoup(matlabValidName) = name; %#ok - else - error('NWB:HasUnnamedGroupsMixin:DynamicPropertyExists', ... - 'Dynamic property with name "%s" already exists', matlabValidName) + assert( ~isprop(obj, matlabValidName), ... + 'NWB:HasUnnamedGroupsMixin:DynamicPropertyExists', ... + 'Dynamic property with name "%s" already exists', matlabValidName ) + + p = obj.addprop(matlabValidName); + p.Dependent = true; + p.GetMethod = @(nm, gnm) obj.getDynamicPropertyValueFromSet(matlabValidName, groupName); + obj.DynamicPropertyMap(matlabValidName) = p; + + % Create ValidNameMap for this group if it doesn't exist + if ~obj.ValidNameMaps.isKey(groupName) + obj.ValidNameMaps(groupName) = containers.Map(); end + + % Add mapping to the group's ValidNameMap + nameMapForGoup = obj.ValidNameMaps(groupName); + nameMapForGoup(matlabValidName) = name; %#ok end function deleteDynamicProperty(obj, name, groupName) @@ -427,3 +437,9 @@ function onSetItemRemoved(obj, name, groupName) end end end + +function ME = getNameExistsException(name, typeName) + ME = MException('NWB:HasUnnamedGroupsMixin:KeyExists', ... + 'A neurodata object with name `%s` already exists in this `%s`', ... + name, typeName); +end diff --git a/+types/+untyped/Anon.m b/+types/+untyped/Anon.m index 2bb165393..c2e21a185 100644 --- a/+types/+untyped/Anon.m +++ b/+types/+untyped/Anon.m @@ -33,5 +33,9 @@ function refs = export(obj, fid, fullpath, refs) refs = obj.value.export(fid, [fullpath obj.name '/'], refs); end + + function tf = isKey(obj, name) + tf = strcmp(obj.name, name); + end end end \ No newline at end of file From 160f7b29e5be00786922318ebf66bd7dd53f02a4 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Sun, 4 May 2025 21:43:34 +0200 Subject: [PATCH 26/65] Add new verification in test for Set --- +tests/+unit/untypedSetTest.m | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/+tests/+unit/untypedSetTest.m b/+tests/+unit/untypedSetTest.m index bad7d636e..7a81f5eba 100644 --- a/+tests/+unit/untypedSetTest.m +++ b/+tests/+unit/untypedSetTest.m @@ -78,7 +78,7 @@ function testAddToSet(testCase) ts = tests.factory.TimeSeriesWithTimestamps; nwbFile.acquisition.add('ts', ts) - testCase.verifyTrue(... + testCase.verifyTrue(... nwbFile.acquisition.isKey('ts'), ... 'Object set with `add` not present in types.untyped.Set'); @@ -86,6 +86,12 @@ function testAddToSet(testCase) nwbFile.acquisition.get('ts'), ... 'types.core.TimeSeries', ... 'Object set with `add` is incorrect value'); + + % Verify that the same name/key can not be used twice + newTs = tests.factory.TimeSeriesWithTimestamps(); + testCase.verifyError(... + @() nwbFile.acquisition.add('ts', newTs), ... + 'NWB:Set:KeyExists') end end end From 959625400310c5646766f351f9748e14f1d73fc6 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Sun, 4 May 2025 22:03:13 +0200 Subject: [PATCH 27/65] Update HasUnnamedGroupsTest.m Add verification the test that object is added and removed on the underlying subgroup object when using methods on the parent object --- +tests/+unit/HasUnnamedGroupsTest.m | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/+tests/+unit/HasUnnamedGroupsTest.m b/+tests/+unit/HasUnnamedGroupsTest.m index 4f56665fa..da4c792f6 100644 --- a/+tests/+unit/HasUnnamedGroupsTest.m +++ b/+tests/+unit/HasUnnamedGroupsTest.m @@ -26,10 +26,17 @@ function testAddRemove(testCase) 'types.core.TimeSeries', ... 'Dynamic property returned incorrect value'); + % Verify that object is present on the nwbdatainterface property + testCase.verifyTrue(module.nwbdatainterface.isKey('TimeSeries')) + % Remove the item and verify it's gone module.remove('TimeSeries'); testCase.verifyFalse(isprop(module, 'TimeSeries'), ... 'Dynamic property was not removed'); + + % Verify that object is also removed from the nwbdatainterface + % property + testCase.verifyFalse(module.nwbdatainterface.isKey('TimeSeries')) end function testLegacySyntax(testCase) From 5aa556830ec0d096e82c89b1e3c132de6a7bd499 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Sat, 10 May 2025 21:08:18 +0200 Subject: [PATCH 28/65] Add get methods on the mixin class + unittest --- +matnwb/+mixin/HasUnnamedGroups.m | 16 ++++++++++++++++ +tests/+unit/HasUnnamedGroupsTest.m | 19 +++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/+matnwb/+mixin/HasUnnamedGroups.m b/+matnwb/+mixin/HasUnnamedGroups.m index b1c2b74fc..c5b5792c0 100644 --- a/+matnwb/+mixin/HasUnnamedGroups.m +++ b/+matnwb/+mixin/HasUnnamedGroups.m @@ -107,6 +107,22 @@ function add(obj, name, value) error(identifier, message, name, class(value), allowedTypes) end end + + function value = get(obj, name) + % get - get a value using it's real name + for groupName = obj.GroupPropertyNames + currentSet = obj.(groupName); + if isKey(currentSet, name) + value = currentSet.get(name); + return + end + end + + % If we end up here, no value exists for the given name + error('NWB:HasUnnamedGroupsMixin:ObjectDoesNotExist', ... + 'No object with name %s was found in this %s', ... + name, obj.TypeName) + end function remove(obj, name) % remove - remove data object given it's (matlab-valid) name diff --git a/+tests/+unit/HasUnnamedGroupsTest.m b/+tests/+unit/HasUnnamedGroupsTest.m index da4c792f6..d643194b9 100644 --- a/+tests/+unit/HasUnnamedGroupsTest.m +++ b/+tests/+unit/HasUnnamedGroupsTest.m @@ -38,6 +38,25 @@ function testAddRemove(testCase) % property testCase.verifyFalse(module.nwbdatainterface.isKey('TimeSeries')) end + + function testGet(testCase) + % Create a ProcessingModule + module = types.core.ProcessingModule(); + + % Add items with the same name to different groups + module.nwbdatainterface.set('TimeSeries', types.core.TimeSeries()); + module.dynamictable.set('DynamicTable', types.hdmf_common.DynamicTable()); + + timeSeries = module.get('TimeSeries'); + testCase.verifyClass(timeSeries, 'types.core.TimeSeries') + + dynamicTable = module.get('DynamicTable'); + testCase.verifyClass(dynamicTable, 'types.hdmf_common.DynamicTable') + + testCase.verifyError(... + @() module.get('NonExistingName'), ... + 'NWB:HasUnnamedGroupsMixin:ObjectDoesNotExist') + end function testLegacySyntax(testCase) % Create a ProcessingModule From 4c31aabf548183929ad0d2de4c8943c9d2df503f Mon Sep 17 00:00:00 2001 From: ehennestad Date: Sat, 10 May 2025 21:28:32 +0200 Subject: [PATCH 29/65] Add function on NwbFile to retrieve remapped names --- +matnwb/+mixin/HasUnnamedGroups.m | 62 +++++++++++++++++++------------ NwbFile.m | 21 +++++++++++ 2 files changed, 59 insertions(+), 24 deletions(-) diff --git a/+matnwb/+mixin/HasUnnamedGroups.m b/+matnwb/+mixin/HasUnnamedGroups.m index c5b5792c0..755fa9354 100644 --- a/+matnwb/+mixin/HasUnnamedGroups.m +++ b/+matnwb/+mixin/HasUnnamedGroups.m @@ -215,37 +215,17 @@ function setupHasUnnamedGroupsMixin(obj) end function displayAliasWarning(obj) - allValidNames = string.empty; - allActualNames = string.empty; - - % Collect all valid and actual names from all groups - groupNames = obj.ValidNameMaps.keys(); - for i = 1:numel(groupNames) - groupName = groupNames{i}; - - validNameMap = obj.ValidNameMaps(groupName); - - if ~isempty(validNameMap) - allValidNames = [allValidNames, string(validNameMap.keys())]; %#ok - allActualNames = [allActualNames, string(validNameMap.values())]; %#ok - end - end + % displayAliasWarning - Display warning if any names have aliases + T = getTableWithAliasNames(obj); - if ~isequal(allValidNames, allActualNames) - hasAlias = ~strcmp(allValidNames, allActualNames); - - T = table(allValidNames(hasAlias)', allActualNames(hasAlias)', ... - 'VariableNames', {'ValidName', 'ActualName'} ); %#ok + if ~isempty(T) nameMap = evalc('disp(T)'); str = sprintf([... 'The following named elements of "%s" are remapped to have valid MATLAB ', ... 'names, but will be written to file with their actual names:', ... '\n%s\n'], obj.TypeName, strip(nameMap, 'right')); - else - str = ''; - end - if ~isempty(str) + warnState = warning('backtrace', 'off'); resetWarningObj = onCleanup(@() warning(warnState)); warning(str) @@ -420,6 +400,34 @@ function deleteDynamicProperty(obj, name, groupName) actualName = validNameMap(validName); end + + function T = getTableWithAliasNames(obj) + allValidNames = string.empty; + allActualNames = string.empty; + + % Collect all valid and actual names from all groups + groupNames = obj.ValidNameMaps.keys(); + for i = 1:numel(groupNames) + groupName = groupNames{i}; + + validNameMap = obj.ValidNameMaps(groupName); + + if ~isempty(validNameMap) + allValidNames = [allValidNames, string(validNameMap.keys())]; %#ok + allActualNames = [allActualNames, string(validNameMap.values())]; %#ok + end + end + + if ~isequal(allValidNames, allActualNames) + hasAlias = ~strcmp(allValidNames, allActualNames); + + T = table(allValidNames(hasAlias)', allActualNames(hasAlias)', ... + 'VariableNames', {'ValidName', 'ActualName'} ); %#ok + else + T = table.empty; + end + end + end methods % Dynamic property get methods @@ -452,6 +460,12 @@ function onSetItemRemoved(obj, name, groupName) obj.deleteDynamicProperty(name, groupName) end end + + methods (Access = ?NwbFile) + function T = getRemappedNames(obj) + T = obj.getTableWithAliasNames(obj); + end + end end function ME = getNameExistsException(name, typeName) diff --git a/NwbFile.m b/NwbFile.m index 627138d4a..107b4e97a 100644 --- a/NwbFile.m +++ b/NwbFile.m @@ -156,6 +156,27 @@ function export(obj, filename, mode) nwbTypeNames = includedNwbTypesWithParents; end end + + function listRemappedNames(obj) + objectMap = searchProperties(containers.Map, obj, '', ''); + + result = {}; + + allKeys = objectMap.keys(); + for i = 1:numel(objectMap.Count) + currentKey = allKeys{i}; + currentValue = objectMap(currentKey); + if isa(currentValue, 'matnwb.mixin.HasUnnamedGroups') + T = currentValue.getRemappedNames(); + if ~isempty(T) + S.Key = currentKey; + S.Type = class(currentValue); + S.Aliases = T; + result{end+1} = S; + end + end + end + end end %% PRIVATE From 13850981fd3863387017866175e113c2f97eaf5a Mon Sep 17 00:00:00 2001 From: ehennestad Date: Sat, 10 May 2025 22:16:45 +0200 Subject: [PATCH 30/65] Add method for listing remapped names in NwbFile + unittest + factory functions for new unittest --- +matnwb/+mixin/HasUnnamedGroups.m | 2 +- +tests/+factory/Fluorescence.m | 25 ++++++++ +tests/+factory/ImagingPlane.m | 2 +- +tests/+factory/PlaneSegmentation.m | 91 +++++++++++++++++++++++++++++ +tests/+factory/RoiResponseSeries.m | 53 +++++++++++++++++ +tests/+unit/HasUnnamedGroupsTest.m | 24 ++++++++ NwbFile.m | 16 +++-- 7 files changed, 205 insertions(+), 8 deletions(-) create mode 100644 +tests/+factory/Fluorescence.m create mode 100644 +tests/+factory/PlaneSegmentation.m create mode 100644 +tests/+factory/RoiResponseSeries.m diff --git a/+matnwb/+mixin/HasUnnamedGroups.m b/+matnwb/+mixin/HasUnnamedGroups.m index 755fa9354..6d829cdd5 100644 --- a/+matnwb/+mixin/HasUnnamedGroups.m +++ b/+matnwb/+mixin/HasUnnamedGroups.m @@ -463,7 +463,7 @@ function onSetItemRemoved(obj, name, groupName) methods (Access = ?NwbFile) function T = getRemappedNames(obj) - T = obj.getTableWithAliasNames(obj); + T = obj.getTableWithAliasNames(); end end end diff --git a/+tests/+factory/Fluorescence.m b/+tests/+factory/Fluorescence.m new file mode 100644 index 000000000..b72e788d1 --- /dev/null +++ b/+tests/+factory/Fluorescence.m @@ -0,0 +1,25 @@ +function fluorescence = Fluorescence(roiResponseSeries, options) +% Fluorescence - Create a Fluorescence object with default values +% +% Usage: +% fluorescence = tests.factory.Fluorescence(roiResponseSeries, options) +% +% Input: +% roiResponseSeries - RoiResponseSeries object +% options - Name-value pairs: +% 'Name' - Name to use for neurodata type (default: "RoiResponseSeries") +% +% Output: +% fluorescence - Fluorescence object + + arguments + roiResponseSeries (1,1) types.core.RoiResponseSeries = tests.factory.RoiResponseSeries + options.Name (1,1) string = "RoiResponseSeries" + end + + % Create the Fluorescence container + fluorescence = types.core.Fluorescence(); + + % Add the RoiResponseSeries to the Fluorescence container + fluorescence.add(options.Name, roiResponseSeries); +end diff --git a/+tests/+factory/ImagingPlane.m b/+tests/+factory/ImagingPlane.m index a7c6e527c..d25a34967 100644 --- a/+tests/+factory/ImagingPlane.m +++ b/+tests/+factory/ImagingPlane.m @@ -1,7 +1,7 @@ function imaging_plane = ImagingPlane(device) % ImagingPlane - Create imaging plane with values for all required properties arguments - device (1,1) types.core.Device % A device is required + device (1,1) types.core.Device = types.core.Device % A device is required end imaging_plane = types.core.ImagingPlane( ... 'device', types.untyped.SoftLink(device), ... diff --git a/+tests/+factory/PlaneSegmentation.m b/+tests/+factory/PlaneSegmentation.m new file mode 100644 index 000000000..b66745eca --- /dev/null +++ b/+tests/+factory/PlaneSegmentation.m @@ -0,0 +1,91 @@ +function planeSegmentation = PlaneSegmentation(imagingPlane, options) +% PlaneSegmentation - Create a PlaneSegmentation object with default values +% +% Usage: +% planeSegmentation = tests.factory.PlaneSegmentation(imagingPlane) +% planeSegmentation = tests.factory.PlaneSegmentation(imagingPlane, 'roi_type', 'image_mask') +% +% Input: +% imagingPlane - ImagingPlane object +% options - Name-value pairs: +% 'RoiType' - 'image_mask' (default) or 'pixel_mask' +% 'NumRois' - Number of ROIs to create (default: 20) +% 'ImageShape' - [height, width] of imaging plane (default: [100, 100]) +% +% Output: +% planeSegmentation - PlaneSegmentation object + + arguments + imagingPlane (1,1) types.core.ImagingPlane = tests.factory.ImagingPlane + options.RoiType (1,1) string ... + {mustBeMember(options.RoiType, ["image_mask", "pixel_mask"])} = 'image_mask' + options.NumRois (1,1) double = 20 + options.ImageShape (1,2) double = [100, 100] + end + + roiType = options.RoiType; + nRois = options.NumRois; + imageShape = options.ImageShape; + + % Generate fake image_mask data + y = imageShape(1); + x = imageShape(2); + + image_mask = zeros(y, x, nRois); + center = randi(90, 2, nRois); + for i = 1:nRois + % Create a small square ROI (10x10 pixels) + row_start = max(1, center(1,i)); + row_end = min(y, row_start + 10); + col_start = max(1, center(2,i)); + col_end = min(x, col_start + 10); + + image_mask(row_start:row_end, col_start:col_end, i) = 1; + end + + if strcmp(roiType, 'pixel_mask') + % Convert image_mask to pixel_mask + ind = find(image_mask); + [y_ind, x_ind, roi_ind] = ind2sub(size(image_mask), ind); + + pixel_mask_struct = struct(); + pixel_mask_struct.x = uint32(x_ind); + pixel_mask_struct.y = uint32(y_ind); + pixel_mask_struct.weight = single(ones(size(x_ind))); + + % Create pixel mask vector data + pixel_mask = types.hdmf_common.VectorData(... + 'data', struct2table(pixel_mask_struct), ... + 'description', 'pixel masks'); + + % Create pixel_mask_index vector + num_pixels_per_roi = zeros(nRois, 1); + for i_roi = 1:nRois + num_pixels_per_roi(i_roi) = sum(roi_ind == i_roi); + end + + pixel_mask_index_data = uint16(cumsum(num_pixels_per_roi)); + + pixel_mask_index = types.hdmf_common.VectorIndex(... + 'description', 'Index into pixel_mask VectorData', ... + 'data', pixel_mask_index_data, ... + 'target', types.untyped.ObjectView(pixel_mask)); + + planeSegmentation = types.core.PlaneSegmentation( ... + 'colnames', {'pixel_mask'}, ... + 'description', 'ROI pixel position (x,y) and pixel weight', ... + 'imaging_plane', types.untyped.SoftLink(imagingPlane), ... + 'pixel_mask_index', pixel_mask_index, ... + 'pixel_mask', pixel_mask ... + ); + else % image_mask + planeSegmentation = types.core.PlaneSegmentation( ... + 'colnames', {'image_mask'}, ... + 'description', 'Output from segmenting imaging plane', ... + 'imaging_plane', types.untyped.SoftLink(imagingPlane), ... + 'image_mask', types.hdmf_common.VectorData(... + 'data', image_mask, ... + 'description', 'image masks') ... + ); + end +end diff --git a/+tests/+factory/RoiResponseSeries.m b/+tests/+factory/RoiResponseSeries.m new file mode 100644 index 000000000..74473ab53 --- /dev/null +++ b/+tests/+factory/RoiResponseSeries.m @@ -0,0 +1,53 @@ +function roiResponseSeries = RoiResponseSeries(planeSegmentation, options) +% RoiResponseSeries - Create a RoiResponseSeries object with default values +% +% Usage: +% roiResponseSeries = tests.factory.RoiResponseSeries(planeSegmentation) +% roiResponseSeries = tests.factory.RoiResponseSeries(planeSegmentation, 'NumTimepoints', 100) +% +% Input: +% planeSegmentation - PlaneSegmentation object +% options - Name-value pairs: +% 'NumTimepoints' - Number of timepoints (default: 100) +% 'SamplingRate' - Sampling rate (default: 30) +% +% Output: +% roiResponseSeries - RoiResponseSeries object + + arguments + planeSegmentation (1,1) types.core.PlaneSegmentation = tests.factory.PlaneSegmentation + options.NumTimepoints (1,1) double = 100 + options.SamplingRate (1,1) double = 30 + end + + numTimepoints = options.NumTimepoints; + startingTime = 0; + startingTimeRate = options.SamplingRate; + + % Get the number of ROIs from the planeSegmentation + if ~isempty(planeSegmentation.image_mask) + n_rois = size(planeSegmentation.image_mask.data, 3); + elseif ~isempty(planeSegmentation.pixel_mask_index) + n_rois = length(planeSegmentation.pixel_mask_index.data); + else + n_rois = 20; % Default if we can't determine from planeSegmentation + end + + % Create a DynamicTableRegion that references all ROIs + roi_table_region = types.hdmf_common.DynamicTableRegion( ... + 'table', types.untyped.ObjectView(planeSegmentation), ... + 'description', 'all_rois', ... + 'data', (0:n_rois-1)'); + + % Generate random fluorescence data + % In MatNWB, time should be along the last dimension [nRoi, nT] + data = rand(n_rois, numTimepoints); + + % Create the RoiResponseSeries + roiResponseSeries = types.core.RoiResponseSeries( ... + 'rois', roi_table_region, ... + 'data', data, ... + 'data_unit', 'lumens', ... + 'starting_time_rate', startingTimeRate, ... + 'starting_time', startingTime); +end diff --git a/+tests/+unit/HasUnnamedGroupsTest.m b/+tests/+unit/HasUnnamedGroupsTest.m index d643194b9..df26d44da 100644 --- a/+tests/+unit/HasUnnamedGroupsTest.m +++ b/+tests/+unit/HasUnnamedGroupsTest.m @@ -228,5 +228,29 @@ function testObjectWithAliasedNames(testCase) % Would use startsWith instead of contains, but C contains some % hidden "display" characters in the beginning end + + function testListAliasNamesFromFile(testCase) + + nwbFile = tests.factory.NWBFile(); + + ophysModule = types.core.ProcessingModule(... + 'Description', 'optical physiology data'); + + nwbFile.processing.add('ophys', ophysModule) + + fluorescence = tests.factory.Fluorescence(... + tests.factory.RoiResponseSeries, ... + "Name", "Roi-Response-Series"); + + ophysModule.add('Raw-Fluorescence', fluorescence) + + result = nwbFile.listRemappedNames(); + + testCase.verifySize(result, [2,4]) + testCase.verifyClass(result, 'table') + + testCase.verifyEqual(result.ActualName, ... + ["Raw-Fluorescence"; "Roi-Response-Series"]) + end end end diff --git a/NwbFile.m b/NwbFile.m index 107b4e97a..87dc80925 100644 --- a/NwbFile.m +++ b/NwbFile.m @@ -157,25 +157,25 @@ function export(obj, filename, mode) end end - function listRemappedNames(obj) + function result = listRemappedNames(obj) objectMap = searchProperties(containers.Map, obj, '', ''); result = {}; allKeys = objectMap.keys(); - for i = 1:numel(objectMap.Count) + for i = 1:objectMap.Count currentKey = allKeys{i}; currentValue = objectMap(currentKey); if isa(currentValue, 'matnwb.mixin.HasUnnamedGroups') T = currentValue.getRemappedNames(); if ~isempty(T) - S.Key = currentKey; - S.Type = class(currentValue); - S.Aliases = T; - result{end+1} = S; + T.ContainerType = repmat(string(class(currentValue)), 1, height(T)); + T.Location = repmat(string(currentKey), 1, height(T)); + result{end+1} = T; %#ok end end end + result = cat(1, result{:}); end end @@ -325,6 +325,10 @@ function resolveReferences(obj, fid, references) || isa(propValue, 'types.untyped.Set')... || isa(propValue, 'types.untyped.Anon') % recursible (even if there is a match!) + if isa(obj, 'matnwb.mixin.HasUnnamedGroups') + % Recursive search on this object would yield duplicate objects + continue + end searchProperties(pathToObjectMap, propValue, fullPath, typename, varargin{:}); end end From bba85646d77c0e1611951d5228a825875670c8e9 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Sat, 10 May 2025 22:21:06 +0200 Subject: [PATCH 31/65] Fix wrong property name for type in test --- +tests/+unit/HasUnnamedGroupsTest.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/+tests/+unit/HasUnnamedGroupsTest.m b/+tests/+unit/HasUnnamedGroupsTest.m index df26d44da..4fe2d70a3 100644 --- a/+tests/+unit/HasUnnamedGroupsTest.m +++ b/+tests/+unit/HasUnnamedGroupsTest.m @@ -234,7 +234,7 @@ function testListAliasNamesFromFile(testCase) nwbFile = tests.factory.NWBFile(); ophysModule = types.core.ProcessingModule(... - 'Description', 'optical physiology data'); + 'description', 'optical physiology data'); nwbFile.processing.add('ophys', ophysModule) From 09629657dd03d508de26438b5cbbf3c094645c87 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Sun, 29 Jun 2025 20:42:09 +0200 Subject: [PATCH 32/65] Added dynamic properties to Set (#727) * Minor refactor to support dynamicprops Set * Rewrite Set to use dynamic properties * Re-add `clear` to Set * fix missing argout setting * vastly simplify Set clear * Fix NwbFile searchFor method for Sets * Undo unsupported syntax * Fix untypedSetTest - change test for construction with function input. - fix whitespace - remove validation function that displays text * Update addRawData.m Revert to use legacy syntax. Support "h5 name" over remapped "matlab-valid name", as remapped names should only be used for dot-syntax * Update addVecInd.m Remove reference to removed property of types.untyped.Set * Fix bugs in updates Set, refactor - Remove internal prefix from property names - Make properties private - Make more methods private - Reintroduce setValidationFunction (as the ValidationFunction prop is private), but make method Hidden because is it is not meant to be used by users. * Update NwbFile.m Keep use legacy syntax for Set, as the name here will refer to the h5 name * Fix failing test, add option to warn or fail if entry for set is invalid * "Standardise" error ids in types.untyped.Set * Update types.untyped.Set rename function validate -> validateEntry change error ids and message update dependent tests * Update untypedSetTest.m Update error id * Refactor constructor of types.untyped.Set Create separate function for extracting names and values for Set from varargin Skip putting names and values in "sourceMap" * Fix incomplete merge * Update Set.m Renamed isOverride to propertyAlreadyExists * Update Set/set - Renamed name to names as this can be an array - Renames val to value as this can be an array - Add validator function for values input * Update Set.m - Renamed elem to currentValue in loop for adding values to set - Fixed bug where wrong variable name was used to if property already exists - Added support for char input in mustBeSamLength validator * Update Set.m Changed header for displayNonScalarObject to be more precise * Update Set.m - Moved private methods further down in file - Update docstrings for some methods - Renamed val to value - Fixed bug where variable reference was not updated during merge - Renamed name to names in `get` where names can be an array * Update Set.m - More specific try/catch block - add method should error if value is invalid type * Fix failing test * Support running test workflow manually (#725) * Update Set.m Fix failing test. * Support option for testing with all releases or latest release when running test workflow manually (#726) * Update run_tests.yml * Update run_tests.yml Reorder code * Update untyped.rst - Updated documentation describing untyped types - Updated documentation for Sets and Anons * Update untyped.rst Updated with suggestions from chatGPT * Create NameRegistry.m * Create DynamicPropertyManager.m * Refactor Set * Update Set.m Rename variables, comments and error messages for more consistent naming * Misc cleanup * More cleanup Change wording Add check for reserved property names * Move warning to separate (internal) function and reuse across classes * Simplify getNameMappingTable method and modify some comments * Update DynamicPropertyManager.m - Updated internal class docstring - Fixed bug in class constructor, assigning input to wrong property - Updated logic in remove method - Renamed validName to propertyName in some places - Added getOriginalNameForPropertyName * Update Set.m - Updated renamed methods from PropertyManager - Added getOriginalName method - Added private method for displaying a warning that is used in two places * Update HasUnnamedGroups.m - Added arguments blocks to user-facing methods - Remove method requires original name for a set entry, will warn if original name does not exist but a property identifier does exist - Rearranged order of methods - ++ * Fix failing tests * Fixed failing test and added new tests for HasUnnamedgroups mixin * Update displayAliasWarning.m Added more detailed function description --------- Co-authored-by: Lawrence --- +matnwb/+mixin/HasUnnamedGroups.m | 532 ++++++++-------- +matnwb/+utility/DynamicPropertyManager.m | 177 ++++++ +matnwb/+utility/NameRegistry.m | 130 ++++ +tests/+unit/+schema/AnonTest.m | 2 +- +tests/+unit/HasUnnamedGroupsTest.m | 234 +++---- +tests/+unit/aberrantValuesTest.m | 14 +- +tests/+unit/untypedSetTest.m | 26 +- .../+untyped/+internal/displayAliasWarning.m | 24 + +types/+untyped/Set.m | 569 ++++++++++++------ +types/+util/+dynamictable/addVecInd.m | 2 +- +types/+util/checkSet.m | 9 +- +types/+util/parseConstrained.m | 2 +- .github/workflows/run_tests.yml | 37 +- .../getting_started/file_read/untyped.rst | 61 +- 14 files changed, 1233 insertions(+), 586 deletions(-) create mode 100644 +matnwb/+utility/DynamicPropertyManager.m create mode 100644 +matnwb/+utility/NameRegistry.m create mode 100644 +types/+untyped/+internal/displayAliasWarning.m diff --git a/+matnwb/+mixin/HasUnnamedGroups.m b/+matnwb/+mixin/HasUnnamedGroups.m index 6d829cdd5..98227b089 100644 --- a/+matnwb/+mixin/HasUnnamedGroups.m +++ b/+matnwb/+mixin/HasUnnamedGroups.m @@ -1,5 +1,5 @@ classdef HasUnnamedGroups < matlab.mixin.CustomDisplay & dynamicprops & handle -% HasUnnamedGroups - Mixin to simplify access to unnamed subgroup Sets +% HasUnnamedGroups - Mixin to simplify access to Sets of unnamed subgroups % % Overview: % Some NWB container types (e.g. ProcessingModule) include unnamed @@ -10,7 +10,7 @@ % module.MyData % % To also simplify the adding of new data, this class provides an `add` -% method. By default you must use: +% method. Using legacy MatNWB syntax, you must use: % module.nwbdatainterface.set('MyData', dataObject) % This mixin lets you write % module.add('MyData', dataObject) @@ -42,39 +42,43 @@ % ts = module.timeseries; % Note: Subclasses for this mixin might include Anon sets. Currently there -% are no schemas in NWB where Anon sets are used, and this class does not -% currently support contained Anon sets. +% are no schemas in NWB where Anon sets are used, and this class therefore +% does not support contained Anon sets. properties (Abstract, Access = protected, Transient) - GroupPropertyNames (1,:) string % String array of property names that contain Sets + % GroupPropertyNames - String array of property names that contain Sets + GroupPropertyNames (1,:) string end properties (Access = private, Transient) - % DynamicPropertyMap - A containers.Map (name) -> (meta.DynamicProperty) - % storing the dynamic property objects for each added dynamic - % property, accessible by the dynamic property name - DynamicPropertyMap - - % ValidNameMaps - A containers.Map (groupName) -> (containers.Map) - % Each group has its own ValidNameMap that maps valid MATLAB names to - % actual NWB names - ValidNameMaps + % PropertyManager - Manages dynamic properties for this object + PropertyManager end + % Constructor methods function obj = HasUnnamedGroups() - obj.DynamicPropertyMap = containers.Map(); - obj.ValidNameMaps = containers.Map(); + % Create the property manager + obj.PropertyManager = matnwb.utility.DynamicPropertyManager(obj); end end + % User-facing methods methods function add(obj, name, value) - % add - Add a named data object to an un-named subgroup + % add - Add a named data object to an unnamed subgroup + + arguments + obj (1,1) matnwb.mixin.HasUnnamedGroups + name (1,1) string + value % any type + end if obj.nameExists(name) - throwAsCaller( getNameExistsException(name, obj.TypeName) ) + throwAsCaller(getNameExistsException(name, obj.TypeName)) end + + obj.assertNameNotReserved(name) wasSuccess = false; for groupName = obj.GroupPropertyNames @@ -99,7 +103,7 @@ function add(obj, name, value) end if ~wasSuccess % If we end up here, the type is invalid. - identifier = 'NWB:HasUnnamedGroupsMixin:AddInvalidType'; + identifier = 'NWB:HasUnnamedGroups:AddInvalidType'; message = ['Object with name `%s` was a "%s", but must be ', ... 'one of the following type(s):\n%s\n']; allowedTypes = obj.getClassNamesForAllowedGroupTypes(); @@ -108,148 +112,85 @@ function add(obj, name, value) end end - function value = get(obj, name) - % get - get a value using it's real name - for groupName = obj.GroupPropertyNames - currentSet = obj.(groupName); - if isKey(currentSet, name) - value = currentSet.get(name); - return - end + function remove(obj, name) + % remove - remove data object given it's original (actual) name + + arguments + obj (1,1) matnwb.mixin.HasUnnamedGroups + name (1,1) string % Actual (original) name of a data object end - % If we end up here, no value exists for the given name - error('NWB:HasUnnamedGroupsMixin:ObjectDoesNotExist', ... - 'No object with name %s was found in this %s', ... - name, obj.TypeName) - end - - function remove(obj, name) - % remove - remove data object given it's (matlab-valid) name + warnState = warning('off', 'NWB:Set:PropertyNameExistsForEntry'); + warningCleanup = onCleanup(@() warning(warnState)); + for groupName = obj.GroupPropertyNames currentSet = obj.(groupName); if isa(currentSet, 'types.untyped.Anon') error('Not implemented yet') end - - if obj.ValidNameMaps(groupName).isKey(name) - actualName = obj.getActualNameFromValidName(name, groupName); - - if currentSet.isKey(actualName) - currentSet.remove(actualName); - break - end + + % Remove data entry if the name exists in this set + if currentSet.isKey(name) + currentSet.remove(name); + return + else + continue end end + + obj.warnIfNameIsPropertyName(name) end end - + + % Method for subclass to initialize the mixin methods (Access = protected) function setupHasUnnamedGroupsMixin(obj) - obj.addDynamicProperties() + obj.initializeDynamicProperties() obj.assignContainedSetCallbackFunctions() end end + methods (Access = private) + function initializeDynamicProperties(obj) + % initializeDynamicProperties - Init dynamic properties from set entries - methods (Access = protected) % matlab.mixin.CustomDisplay override - function groups = getPropertyGroups(obj) - % getPropertyGroups - Create property groups for display - - standardProps = properties(obj); - - % Remove the Set properties that we'll display separately - toSkip = false(1, length(obj.GroupPropertyNames)); - for groupName = obj.GroupPropertyNames - idx = strcmp(standardProps, groupName); - toSkip(idx) = true; - end - - % Todo: Use a nwbPreferences object - displayPref = getpref('matnwb', 'displaymode', 'groups'); % groups | flat - - if strcmp(displayPref, 'groups') % Remove dynamic props - dynamicPropNames = obj.DynamicPropertyMap.keys(); - for i = 1:length(dynamicPropNames) - idx = strcmp(standardProps, dynamicPropNames{i}); - toSkip(idx) = true; - end - end - standardProps(toSkip) = []; - - % Create a property group for standard properties - groups = matlab.mixin.util.PropertyGroup(standardProps); - - if strcmp(displayPref, 'groups') - - % Create property groups for each Set property - for groupName = obj.GroupPropertyNames - assert(isprop(obj, groupName), ... - 'Expected "%s" to be a property of class', groupName) - - % Get the Set property - setObj = obj.(groupName); - assert(~isempty(setObj) && isa(setObj, 'types.untyped.Set'), ... - 'Expected property "%s" to contain a Set', groupName) - - % Get all keys from the Set - keys = setObj.keys(); - validNames = obj.getValidNamesFromActualNames(keys, groupName); - - % Initialize property list - propList = string(missing); + containerObj = obj.(groupName); - if ~isempty(keys) - propList = cell2struct(setObj.values(), validNames, 2); + if isa(containerObj, 'types.untyped.Set') + keys = containerObj.keys(); + for j = 1:numel(keys) + obj.createDynamicProperty(keys{j}, groupName) + end + elseif isa(containerObj, 'types.untyped.Anon') + name = containerObj.name; + if ~isempty(name) + obj.createDynamicProperty(name, groupName) end - - % Create a title for this group - title = "" + groupName + " elements:"; - - % Add this group to the property groups - groups(end+1) = matlab.mixin.util.PropertyGroup(propList, title); %#ok end end - obj.displayAliasWarning() end - - function displayAliasWarning(obj) - % displayAliasWarning - Display warning if any names have aliases - T = getTableWithAliasNames(obj); - if ~isempty(T) - nameMap = evalc('disp(T)'); - - str = sprintf([... - 'The following named elements of "%s" are remapped to have valid MATLAB ', ... - 'names, but will be written to file with their actual names:', ... - '\n%s\n'], obj.TypeName, strip(nameMap, 'right')); - - warnState = warning('backtrace', 'off'); - resetWarningObj = onCleanup(@() warning(warnState)); - warning(str) - end - end - end - - methods (Access = private) function assignContainedSetCallbackFunctions(obj) for groupName = obj.GroupPropertyNames containerObj = obj.(groupName); if isa(containerObj, 'types.untyped.Set') - containerObj.ItemAddedFunction = ... - @(itemName) obj.onSetItemAdded(itemName, groupName); - containerObj.ItemRemovedFunction = ... - @(itemName) obj.onSetItemRemoved(itemName, groupName); + containerObj.EntryAddedFunction = ... + @(itemName) obj.onSetEntryAdded(itemName, groupName); + containerObj.EntryRemovedFunction = ... + @(itemName) obj.onSetEntryRemoved(itemName, groupName); else - warning('NWB:HasUnnamedGroupsMixin:NotImplemented', ... + warning('NWB:HasUnnamedGroups:NotImplemented', ... 'Callback functions are not implemented for Anon types.') end end end - + end + + % Internal methods for managing properties + methods (Access = private) + function tf = nameExists(obj, name) % nameExists - Check if name already exists in subgroup tf = false; @@ -261,57 +202,106 @@ function assignContainedSetCallbackFunctions(obj) end end end + + function assertNameNotReserved(obj, name) + % Property names for groups are reserved + if any( strcmp(obj.GroupPropertyNames, name) ) + ME = MException(... + 'NWB:HasUnnamedGroups:ReservedName', ... + ['`%s` is a reserved name for a %s object. Please use ', ... + 'another name.'], name, class(obj)); + throwAsCaller(ME) + end + end - function addDynamicProperties(obj) - % addDynamicProperties - Add dynamic properties for set values - - for groupName = obj.GroupPropertyNames - containerObj = obj.(groupName); - - if isa(containerObj, 'types.untyped.Set') - keys = containerObj.keys(); - for j = 1:numel(keys) - obj.createDynamicProperty(keys{j}, groupName) - end - elseif isa(containerObj, 'types.untyped.Anon') - name = containerObj.name; - if ~isempty(name) - obj.createDynamicProperty(name, groupName) + function warnIfNameIsPropertyName(obj, name) + % Issue warning if a given name exists as a property identifier + if isprop(obj, name) + for groupName = obj.GroupPropertyNames + currentSet = obj.(groupName); + + try + originalName = currentSet.getOriginalName(name); + catch + continue end end + + assert(exist('originalName', 'var'), ... + 'NWB:HasUnnamedGroups:OriginalNameNotFound', ... + ['Internal error. Could not find original name for ', ... + 'property %s'], name) + + warning('NWB:HasUnnamedGroups:UseOriginalName', ... + ['No objects with name "%s" is included in this %s, ', ... + 'but "%s" is the name of a property corresponding to ', ... + 'the object with name "%s"'], ... + name, ... + class(obj), ... + name, ... + originalName ) end end function createDynamicProperty(obj, name, groupName) % createDynamicProperty - Add a single dynamic property to the class - matlabValidName = obj.createValidName(name, groupName); + try + obj.assertNameNotReserved(name) + catch + error('NWB:HasUnnamedGroups:CouldNotAddEntry', ... + ['Failed to add an entry with the name "%s" as a property ', ... + 'of this object because "%s" is a reserved name in ', ... + '"%s".'], name, name, class(obj)) + end + + % Get the specified group's Set and a valid MATLAB identifier for + % the property to create + setObj = obj.(groupName); + propertyIdentifier = setObj.getPropertyName(name); + + % Verify that name only exists in one group + nameCount = obj.countInstancesOfName(name); + if nameCount > 1 + setObj.remove(name) + + error('NWB:HasUnnamedGroups:DuplicateEntry', ... + ['An entry with name `%s` was detected in multiple ', ... + 'contained groups. Removed entry from group `%s`.'], ... + name, groupName) + end - assert( ~isprop(obj, matlabValidName), ... - 'NWB:HasUnnamedGroupsMixin:DynamicPropertyExists', ... - 'Dynamic property with name "%s" already exists', matlabValidName ) - - p = obj.addprop(matlabValidName); - p.Dependent = true; - p.GetMethod = @(nm, gnm) obj.getDynamicPropertyValueFromSet(matlabValidName, groupName); - obj.DynamicPropertyMap(matlabValidName) = p; + % Ensure that property does not already exist. + assert(~isprop(obj, propertyIdentifier), ... + 'NWB:HasUnnamedGroups:DynamicPropertyExists', ... + 'Property with name "%s" already exists', propertyIdentifier) - % Create ValidNameMap for this group if it doesn't exist - if ~obj.ValidNameMaps.isKey(groupName) - obj.ValidNameMaps(groupName) = containers.Map(); - end + % Create a getter method that will retrieve the value from the Set + getMethod = @(~) obj.getDynamicPropertyValueFromSet(name, groupName); + setMethod = @(nm, value, gNnm) obj.setDynamicPropertyValueToSet(name, value, groupName); - % Add mapping to the group's ValidNameMap - nameMapForGoup = obj.ValidNameMaps(groupName); - nameMapForGoup(matlabValidName) = name; %#ok + % Add the property using the PropertyManager + obj.PropertyManager.addProperty(propertyIdentifier, ... + 'GetMethod', getMethod, ... + 'SetMethod', setMethod, ... + 'Dependent', true); end - function deleteDynamicProperty(obj, name, groupName) - dynamicPropertyMeta = obj.DynamicPropertyMap(name); - delete(dynamicPropertyMeta) - obj.DynamicPropertyMap.remove(name); + function deleteDynamicProperty(obj, name) + % Remove the property using the PropertyManager + if obj.PropertyManager.existOriginalName(name) + name = obj.PropertyManager.getPropertyNameForOriginalName(name); + obj.PropertyManager.removeProperty(name); + end + end - if obj.ValidNameMaps.isKey(groupName) && obj.ValidNameMaps(groupName).isKey(name) - obj.ValidNameMaps(groupName).remove(name); + function nameCount = countInstancesOfName(obj, name) + nameCount = 0; + + for groupName = obj.GroupPropertyNames + containerObj = obj.(groupName); + if containerObj.isKey(name) + nameCount = nameCount + 1; + end end end @@ -326,150 +316,140 @@ function deleteDynamicProperty(obj, name, groupName) isMatch = ismember(lower(typeClassNamesShort), groupPropertyNames); result = typeClassNames(isMatch); end - - function validName = createValidName(obj, name, groupName) - % createValidName - Create a valid MATLAB name to use for dynamic property. - - % Make sure the valid name is unique across groups - if numel(obj.GroupPropertyNames) > 1 - % Check if the name already exists in any other group - existingNames = []; - allGroupNames = obj.ValidNameMaps.keys(); - for i = 1:numel(allGroupNames) - currentGroupName = allGroupNames{i}; - if ~strcmp(currentGroupName, groupName) && obj.ValidNameMaps.isKey(currentGroupName) - currentGroupMap = obj.ValidNameMaps(currentGroupName); - if ~isempty(currentGroupMap) - existingNames = [existingNames, currentGroupMap.values()]; %#ok - end - end - end - - % If the name already exists in another group, prepend the group name - if any(strcmp(name, existingNames)) - name = sprintf('%s_%s', groupName, name); - end - end - - % Make sure the valid name is unique across all dynamic properties - isFinished = false; - suggestedName = name; - counter = 0; - while ~isFinished - suggestedName = matlab.lang.makeValidName(suggestedName); - if ~isprop(obj, suggestedName) - isFinished = true; - else - counter = counter+1; - suggestedName = sprintf('%s_%d', name, counter); - end - end - validName = suggestedName; - end - - function validNames = getValidNamesFromActualNames(obj, actualNames, groupName) - - validNames = cell(size(actualNames)); - if isempty(actualNames); return; end - validNameMap = obj.ValidNameMaps(groupName); - - % Get all valid names and actual names for this group - allValidNames = validNameMap.keys(); - allActualNames = validNameMap.values(); - - % Check each group's ValidNameMap - for i = 1:numel(actualNames) - - % Find the matching valid name - isMatch = strcmp(allActualNames, actualNames{i}); - if any(isMatch) - validNames{i} = allValidNames{isMatch}; - end - end - end - - function actualName = getActualNameFromValidName(obj, validName, groupName) - % getActualNameFromValidName - Reverse-map actual name from valid name - - validNameMap = obj.ValidNameMaps(groupName); - - assert(validNameMap.isKey(validName), ... - 'Expected "%s" to be present in group "%s"', ... - validName, groupName) - - actualName = validNameMap(validName); - end - function T = getTableWithAliasNames(obj) - allValidNames = string.empty; - allActualNames = string.empty; - % Collect all valid and actual names from all groups - groupNames = obj.ValidNameMaps.keys(); - for i = 1:numel(groupNames) - groupName = groupNames{i}; + T = cell(1, numel(obj.GroupPropertyNames)); - validNameMap = obj.ValidNameMaps(groupName); - - if ~isempty(validNameMap) - allValidNames = [allValidNames, string(validNameMap.keys())]; %#ok - allActualNames = [allActualNames, string(validNameMap.values())]; %#ok - end + for i = 1:numel(obj.GroupPropertyNames) + groupName = obj.GroupPropertyNames(i); + currentSet = obj.(groupName); + T{i} = currentSet.getPropertyMappingTable(); end - if ~isequal(allValidNames, allActualNames) - hasAlias = ~strcmp(allValidNames, allActualNames); - - T = table(allValidNames(hasAlias)', allActualNames(hasAlias)', ... - 'VariableNames', {'ValidName', 'ActualName'} ); %#ok - else - T = table.empty; + T(cellfun('isempty', T)) = []; + T = cat(1, T{:}); + + if ~isempty(T) + keep = T.ValidIdentifier ~= T.OriginalName; + T = T(keep, :); end end - end - methods % Dynamic property get methods + % Dynamic property getter methods + methods (Access = private) function value = getDynamicPropertyValueFromSet(obj, name, groupName) - % Get the actual name from the group's ValidNameMap - - %Assume actual name is the same as the valid name. - actualName = name; - if obj.ValidNameMaps.isKey(groupName) ... - && obj.ValidNameMaps(groupName).isKey(name) - nameMapForGroup = obj.ValidNameMaps(groupName); - actualName = nameMapForGroup(name); - end - value = obj.(groupName).get(actualName); + % Get the value from the Set + value = obj.(groupName).get(name); end + function value = setDynamicPropertyValueToSet(obj, name, value, groupName) + % Set the value to the Set of the contained subgroup + obj.(groupName).set(name, value); + end + + function value = getDynamicPropertyValueFromAnon(obj, groupName) value = obj.(groupName).value; end end - methods (Access = private) % types.untyped.Set callback functions - function onSetItemAdded(obj, name, groupName) - % onSetItemAdded - Handle items being added to a contained types.untyped.Set + % Callback methods for types.untyped.Set objects contained in this class + methods (Access = private) + function onSetEntryAdded(obj, name, groupName) + % onSetEntryAdded - Handle entries being added to a contained Set obj.createDynamicProperty(name, groupName) end - function onSetItemRemoved(obj, name, groupName) - % onSetItemRemoved - Handle items being removed from a contained types.untyped.Set - obj.deleteDynamicProperty(name, groupName) + function onSetEntryRemoved(obj, name, ~) + % onSetEntryRemoved - Handle entries being removed from a contained Set + obj.deleteDynamicProperty(name) end end - + + % Utility method that is only accessible from an NwbFile object methods (Access = ?NwbFile) function T = getRemappedNames(obj) T = obj.getTableWithAliasNames(); end end + + % matlab.mixin.CustomDisplay override + methods (Access = protected) + function groups = getPropertyGroups(obj) + % getPropertyGroups - Create property groups for display + + standardProps = properties(obj); + + % Remove the Set properties that we'll display separately + toSkip = false(1, length(obj.GroupPropertyNames)); + + for groupName = obj.GroupPropertyNames + idx = strcmp(standardProps, groupName); + toSkip(idx) = true; + end + + % Todo: Use a nwbPreferences object + displayPref = getpref('matnwb', 'displaymode', 'groups'); % groups | flat + + if strcmp(displayPref, 'groups') % Remove dynamic props + dynamicPropNames = obj.PropertyManager.getAllPropertyNames(); + for i = 1:length(dynamicPropNames) + idx = strcmp(standardProps, dynamicPropNames{i}); + toSkip(idx) = true; + end + end + standardProps(toSkip) = []; + + % Create a property group for standard properties + groups = matlab.mixin.util.PropertyGroup(standardProps); + + if strcmp(displayPref, 'groups') + + % Create property groups for each Set property + for groupName = obj.GroupPropertyNames + assert(isprop(obj, groupName), ... + 'Expected "%s" to be a property of class', groupName) + + % Get the Set property + setObj = obj.(groupName); + assert(~isempty(setObj) && isa(setObj, 'types.untyped.Set'), ... + 'Expected property "%s" to contain a Set', groupName) + + % Get all keys from the Set + keys = setObj.keys(); + propNames = cellfun(@(key) setObj.getPropertyName(key), keys, 'uni', 0); + + % Initialize property list + propList = string(missing); + + if ~isempty(keys) + propList = cell2struct(setObj.values(), propNames, 2); + end + + % Create a title for this group + title = "" + groupName + " entries:"; + + % Add this group to the property groups + groups(end+1) = matlab.mixin.util.PropertyGroup(propList, title); %#ok + end + end + obj.displayAliasWarning() + end + + function displayAliasWarning(obj) + % displayAliasWarning - Display warning if any names have aliases + T = getTableWithAliasNames(obj); + if ~isempty(T) + types.untyped.internal.displayAliasWarning(T, obj.TypeName) + end + end + end end function ME = getNameExistsException(name, typeName) - ME = MException('NWB:HasUnnamedGroupsMixin:KeyExists', ... + ME = MException('NWB:HasUnnamedGroups:KeyExists', ... 'A neurodata object with name `%s` already exists in this `%s`', ... name, typeName); end diff --git a/+matnwb/+utility/DynamicPropertyManager.m b/+matnwb/+utility/DynamicPropertyManager.m new file mode 100644 index 000000000..d966a24ba --- /dev/null +++ b/+matnwb/+utility/DynamicPropertyManager.m @@ -0,0 +1,177 @@ +classdef DynamicPropertyManager < handle +% DynamicPropertyManager - Manages dynamic properties for a target object + +% - This class provides a consistent interface for creating and removing +% dynamic properties on a target object. +% - It additionally provides an internal name registry, to keep track of +% original names of properties that might not be valid MATLAB +% identifiers. When adding a property with a name which is not a valid +% MATLAB identifier, a valid alias is registered and used as a name for +% the dynamic property. +% +% Used by types.untyped.Set and matnwb.mixin.HasUnnamedGroups to +% allow users to access neurodata types stored in object properties of +% other neurodata types through dot-syntax. + + properties (Access = private) + TargetObject % The object to manage dynamic properties for + DynamicPropertyMap % A containers.Map (name) -> (meta.DynamicProperty) + NameRegistry % NameRegistry instance for name mapping + end + + properties (SetAccess = immutable) + PropertyAddedFunction % Function handle called when a property is added + PropertyRemovedFunction % Function handle called when a property is removed + end + + methods + function obj = DynamicPropertyManager(targetObject, nameRegistry, propArgs) + % Create a new DynamicPropertyManager for the target object + arguments + targetObject (1,1) dynamicprops + nameRegistry (1,1) matnwb.utility.NameRegistry = matnwb.utility.NameRegistry + propArgs.propertyAddedFunction function_handle = function_handle.empty + propArgs.propertyRemovedFunction function_handle = function_handle.empty + end + + obj.TargetObject = targetObject; + obj.DynamicPropertyMap = containers.Map('KeyType', 'char', 'ValueType', 'any'); + obj.NameRegistry = nameRegistry; + obj.PropertyAddedFunction = propArgs.propertyAddedFunction; + obj.PropertyRemovedFunction = propArgs.propertyRemovedFunction; + end + + function metaProperty = addProperty(obj, originalName, options) + % Add a dynamic property to the target object + arguments + obj matnwb.utility.DynamicPropertyManager + originalName (1,1) string + options.GetMethod function_handle = function_handle.empty + options.SetMethod function_handle = function_handle.empty + options.Dependent (1,1) logical = false + end + + % Get or create valid name + if obj.NameRegistry.existOriginalName(originalName) + validName = obj.NameRegistry.getValidName(originalName); + else + validName = obj.NameRegistry.addMapping(originalName); + end + + % Check if property already exists + assert(~isprop(obj.TargetObject, validName), ... + 'NWB:DynamicPropertyManager:PropertyExists', ... + 'Property "%s" already exists on target object', validName); + + % Add the property + metaProperty = obj.TargetObject.addprop(validName); + + % Set get/set methods if provided + if ~isempty(options.GetMethod) + metaProperty.GetMethod = options.GetMethod; + end + + if ~isempty(options.SetMethod) + metaProperty.SetMethod = options.SetMethod; + end + + metaProperty.Dependent = options.Dependent; + + % Store the property metadata + obj.DynamicPropertyMap(validName) = metaProperty; + + % Call the callback if set + if ~isempty(obj.PropertyAddedFunction) + obj.PropertyAddedFunction(originalName); + end + + if ~nargout + clear metaProperty + end + end + + function removeProperty(obj, name) + % Remove a dynamic property from the target object + arguments + obj matnwb.utility.DynamicPropertyManager + name (1,1) string + end + + % Try to remove entry assuming original name is given, fall back + % to removing entry using property name. + if obj.existOriginalName(name) + originalName = name; + propertyName = obj.getPropertyNameForOriginalName(originalName); + elseif obj.existPropertyName(name) + propertyName = name; + originalName = obj.getOriginalNameForPropertyName(propertyName); + else + error('NWB:DynamicPropertyManager:UnknownProperty', ... + 'No property with name "%s" exists', name); + end + + % Check if the property exists in our map + assert(obj.DynamicPropertyMap.isKey(propertyName), ... + 'NWB:DynamicPropertyManager:PropertyNotManaged', ... + 'Property "%s" is not managed by this DynamicPropertyManager', propertyName); + + % Get the property metadata + propMeta = obj.DynamicPropertyMap(propertyName); + + % Delete the property + delete(propMeta); + + % Remove from internal maps + obj.DynamicPropertyMap.remove(propertyName); + obj.NameRegistry.removeMapping(propertyName); + + % Call the callback if set + if ~isempty(obj.PropertyRemovedFunction) + obj.PropertyRemovedFunction(originalName); + end + end + + function originalName = getOriginalNameForPropertyName(obj, propertyName) + originalName = obj.NameRegistry.getOriginalName(propertyName); + end + + function propertyName = getPropertyNameForOriginalName(obj, originalName) + propertyName = obj.NameRegistry.getValidName(originalName); + end + + function count = getPropertyCount(obj) + count = obj.DynamicPropertyMap.Count; + end + + function names = getAllPropertyNames(obj) + % Get all property names + names = obj.DynamicPropertyMap.keys(); + end + + function names = getAllOriginalNames(obj) + % Get all property names + names = obj.NameRegistry.getAllOriginalNames(); + end + + function tf = existPropertyName(obj, propertyName) + arguments + obj matnwb.utility.DynamicPropertyManager + propertyName (1,1) string + end + tf = obj.NameRegistry.existValidName(propertyName); + end + + function tf = existOriginalName(obj, originalName) + arguments + obj matnwb.utility.DynamicPropertyManager + originalName (1,1) string + end + tf = obj.NameRegistry.existOriginalName(originalName); + end + + function T = getPropertyMappingTable(obj) + % Get a table showing property mappings + T = obj.NameRegistry.getNameMappingTable(); + end + end +end diff --git a/+matnwb/+utility/NameRegistry.m b/+matnwb/+utility/NameRegistry.m new file mode 100644 index 000000000..adfa4fcfc --- /dev/null +++ b/+matnwb/+utility/NameRegistry.m @@ -0,0 +1,130 @@ +classdef NameRegistry < handle +% NameRegistry - Mapping between original NWB names and MATLAB-valid names +% +% Ensures unique, reversible (bi-directional) mapping from original names +% used for data objects in NWB files to valid MATLAB identifiers. + + properties (Access = private) + % Map from valid MATLAB names to original names + ValidToOriginalMap + + % Map from original names to valid MATLAB names + OriginalToValidMap + end + + methods + function obj = NameRegistry() + obj.ValidToOriginalMap = containers.Map('KeyType', 'char', 'ValueType', 'char'); + obj.OriginalToValidMap = containers.Map('KeyType', 'char', 'ValueType', 'char'); + end + + function validName = addMapping(obj, originalName, validName) + % Add a mapping between an original name and a MATLAB-valid name + % If validName is not provided, it will be generated + + arguments + obj matnwb.utility.NameRegistry + originalName (1,1) string + validName (1,1) string = missing + end + + if ismissing(validName) + validName = obj.createValidName(originalName); + end + + assert(~obj.existOriginalName(originalName), ... + 'NWB:NameRegistry:DuplicateOriginalName', ... + 'The original name "%s" is already mapped', originalName); + + assert(~obj.existValidName(validName), ... + 'NWB:NameRegistry:DuplicateValidName', ... + 'The valid name "%s" is already mapped', validName); + + % Add the mapping + obj.ValidToOriginalMap(validName) = originalName; + obj.OriginalToValidMap(originalName) = validName; + end + + function removeMapping(obj, nameToRemove) + % Remove a mapping by either valid or original name + + if obj.existValidName(nameToRemove) + originalName = obj.getOriginalName(nameToRemove); + obj.ValidToOriginalMap.remove(nameToRemove); + obj.OriginalToValidMap.remove(originalName); + elseif obj.existOriginalName(nameToRemove) + validName = obj.getValidName(nameToRemove); + obj.ValidToOriginalMap.remove(validName); + obj.OriginalToValidMap.remove(nameToRemove); + else + error('NWB:NameRegistry:UnknownName', ... + 'No mapping exists for name "%s"', nameToRemove); + end + end + + function validName = getValidName(obj, originalName) + % Get the valid MATLAB name for an original name + assert(obj.existOriginalName(originalName), ... + 'NWB:NameRegistry:UnknownOriginalName', ... + 'No mapping exists for original name "%s"', originalName); + validName = obj.OriginalToValidMap(originalName); + end + + function originalName = getOriginalName(obj, validName) + % Get the original name for a valid MATLAB name + assert(obj.existValidName(validName), ... + 'NWB:NameRegistry:UnknownValidName', ... + 'No mapping exists for valid name "%s"', validName); + originalName = obj.ValidToOriginalMap(validName); + end + + function tf = existValidName(obj, validName) + % Check if a valid MATLAB name exists in the mapping + tf = obj.ValidToOriginalMap.isKey(validName); + end + + function tf = existOriginalName(obj, originalName) + % Check if an original name exists in the mapping + tf = obj.OriginalToValidMap.isKey(originalName); + end + + function validNames = getAllValidNames(obj) + % Return all valid MATLAB names as a 1xn cell array + validNames = obj.ValidToOriginalMap.keys(); + end + + function originalNames = getAllOriginalNames(obj) + % Return all original names as a 1xn cell array + originalNames = obj.OriginalToValidMap.keys(); + end + + function T = getNameMappingTable(obj) + % Return a table showing all name mappings + validNames = obj.ValidToOriginalMap.keys(); + originalNames = obj.ValidToOriginalMap.values(); + + tableVariableNames = {'ValidIdentifier', 'OriginalName'}; + + T = table(string(validNames'), string(originalNames'), ... + 'VariableNames', tableVariableNames); + end + end + + methods (Access = private) + function validName = createValidName(obj, originalName) + % Create a valid MATLAB name from an original name + baseName = matlab.lang.makeValidName(originalName); + + % Ensure uniqueness + if obj.existValidName(baseName) + counter = 1; + while obj.existValidName(sprintf('%s_%d', baseName, counter)) + counter = counter + 1; + end + validName = sprintf('%s_%d', baseName, counter); + else + validName = baseName; + end + end + end +end diff --git a/+tests/+unit/+schema/AnonTest.m b/+tests/+unit/+schema/AnonTest.m index 38ed1b10b..7a881e370 100644 --- a/+tests/+unit/+schema/AnonTest.m +++ b/+tests/+unit/+schema/AnonTest.m @@ -8,7 +8,7 @@ methods (Test) function testAnonDataset(testCase) import matlab.unittest.fixtures.SuppressedWarningsFixture - warningIdentifier = 'NWB:HasUnnamedGroupsMixin:NotImplemented'; + warningIdentifier = 'NWB:HasUnnamedGroups:NotImplemented'; testCase.applyFixture(SuppressedWarningsFixture(warningIdentifier)) ag = types.anon.AnonGroup('ad', types.anon.AnonData('data', 0)); diff --git a/+tests/+unit/HasUnnamedGroupsTest.m b/+tests/+unit/HasUnnamedGroupsTest.m index 4fe2d70a3..349cde0d4 100644 --- a/+tests/+unit/HasUnnamedGroupsTest.m +++ b/+tests/+unit/HasUnnamedGroupsTest.m @@ -6,22 +6,20 @@ % which is used to simplify access to unnamed subgroup Sets. % It uses types.core.ProcessingModule as a test type because it's the only % NWB type that has two groups. - + methods (Test) function testAddRemove(testCase) - % Test add and remove methods of HasUnnamedGroups mixin + % Test `add` and `remove` methods of HasUnnamedGroups mixin - % Create a ProcessingModule + % Create a ProcessingModule and use the add method module = types.core.ProcessingModule(); - - % Add a new type using the mixin's add method module.add('TimeSeries', types.core.TimeSeries()); % Verify that the dynamic property was created testCase.verifyTrue(isprop(module, 'TimeSeries'), ... 'Dynamic property was not created'); - % Verify that the dynamic property returns the correct value + % Verify that the dynamic property returns the correct type testCase.verifyClass(module.TimeSeries, ... 'types.core.TimeSeries', ... 'Dynamic property returned incorrect value'); @@ -39,25 +37,33 @@ function testAddRemove(testCase) testCase.verifyFalse(module.nwbdatainterface.isKey('TimeSeries')) end - function testGet(testCase) - % Create a ProcessingModule - module = types.core.ProcessingModule(); - - % Add items with the same name to different groups - module.nwbdatainterface.set('TimeSeries', types.core.TimeSeries()); - module.dynamictable.set('DynamicTable', types.hdmf_common.DynamicTable()); - - timeSeries = module.get('TimeSeries'); - testCase.verifyClass(timeSeries, 'types.core.TimeSeries') - - dynamicTable = module.get('DynamicTable'); - testCase.verifyClass(dynamicTable, 'types.hdmf_common.DynamicTable') - - testCase.verifyError(... - @() module.get('NonExistingName'), ... - 'NWB:HasUnnamedGroupsMixin:ObjectDoesNotExist') + function testInitializeWithConstructorArgs(testCase) + module = types.core.ProcessingModule(... + 'description', 'test module', ... + 'TimeSeries', tests.factory.TimeSeriesWithTimestamps, ... + 'DynamicTable', types.hdmf_common.DynamicTable() ); + + testCase.verifyTrue( isprop(module, 'TimeSeries') ) + testCase.verifyTrue( isprop(module, 'DynamicTable') ) end + % % % function testGet(testCase) + % % % % Create a ProcessingModule + % % % module = types.core.ProcessingModule('description', 'test module'); + % % % module.nwbdatainterface.set('TimeSeries', types.core.TimeSeries()); + % % % module.dynamictable.set('DynamicTable', types.hdmf_common.DynamicTable()); + % % % + % % % timeSeries = module.get('TimeSeries'); + % % % testCase.verifyClass(timeSeries, 'types.core.TimeSeries') + % % % + % % % dynamicTable = module.get('DynamicTable'); + % % % testCase.verifyClass(dynamicTable, 'types.hdmf_common.DynamicTable') + % % % + % % % testCase.verifyError(... + % % % @() module.get('NonExistingName'), ... + % % % 'NWB:HasUnnamedGroups:ObjectDoesNotExist') + % % % end + function testLegacySyntax(testCase) % Create a ProcessingModule module = types.core.ProcessingModule(); @@ -68,9 +74,11 @@ function testLegacySyntax(testCase) % Verify that the dynamic property was created testCase.verifyTrue(isprop(module, 'TimeSeries'), ... 'Dynamic property was not created'); + + timeSeries = module.nwbdatainterface.get('TimeSeries'); % Verify that the dynamic property returns the correct value - testCase.verifyClass(module.TimeSeries, ... + testCase.verifyClass(timeSeries, ... 'types.core.TimeSeries', ... 'Dynamic property returned incorrect value'); @@ -80,32 +88,57 @@ function testLegacySyntax(testCase) 'Dynamic property was not removed'); end - function testInvalidMatlabName(testCase) - % Create a ProcessingModule - module = types.core.ProcessingModule(); + function testRemoveUsingPropertyName(testCase) + module = types.core.ProcessingModule('description', 'test module'); + module.add('time series', types.core.TimeSeries()) + + operationToVerify = @() module.remove('timeSeries'); + + testCase.verifyWarning(operationToVerify, ... + 'NWB:HasUnnamedGroups:UseOriginalName' ) + end + + function testWithReservedName(testCase) + module = types.core.ProcessingModule('description', 'test module'); + + operationToVerify = @() module.add(... + 'nwbdatainterface', types.core.NWBDataInterface()); - % Add items with similar names to nwbdatainterface + testCase.verifyError(operationToVerify, ... + 'NWB:HasUnnamedGroups:ReservedName'); + end + + function testWithReservedNameAddedToContainedSet(testCase) + module = types.core.ProcessingModule('description', 'test module'); + + operationToVerify = @() module.nwbdatainterface.set(... + 'nwbdatainterface', types.core.NWBDataInterface()); + + testCase.verifyError(operationToVerify, ... + 'NWB:HasUnnamedGroups:CouldNotAddEntry'); + end + + function testWithInvalidMatlabName(testCase) + % Add object with name which is not a valid matlab identifier + module = types.core.ProcessingModule(); module.add('Time-Series', types.core.TimeSeries()) - % Verify that the dynamic property was created and accessible + % Verify that the dynamic property was created and is accessible % with a valid MATLAB name testCase.verifyTrue(isprop(module, 'Time_Series'), ... 'Dynamic property was not created'); testCase.verifyClass(module.Time_Series, ... 'types.core.TimeSeries', ... - 'Dynamic property returned incorrect value'); + 'Dynamic property returned incorrect type'); end - function testSimilarNames(testCase) + function testWithSimilarNames(testCase) % Test handling of similar names that result in the same valid name - % Create a ProcessingModule + % Create module and add items with similar names to it: module = types.core.ProcessingModule(); - - % Add items with similar names to nwbdatainterface module.add('Time_Series', types.core.TimeSeries()) - module.add('Time-Series', types.core.TimeSeries()) % Verify that the dynamic property was created @@ -117,120 +150,103 @@ function testSimilarNames(testCase) 'Dynamic property was not created'); end - function testCrossGroupNameConflicts(testCase) - % Test handling of name conflicts across different groups - - % Create a ProcessingModule - module = types.core.ProcessingModule(); - - % Add items with the same name to different groups - module.nwbdatainterface.set('Test', types.core.TimeSeries()); - module.dynamictable.set('Test', types.hdmf_common.DynamicTable()); - - % Verify both properties exist with appropriate names - % One should be Test and the other should have the group name prepended - testCase.verifyTrue(isprop(module, 'Test'), ... - 'Dynamic property Test was not created'); - testCase.verifyTrue(isprop(module, 'dynamictable_Test'), ... - 'Dynamic property dynamictable_Test was not created'); - - % Verify the properties return the correct values - if isa(module.Test, 'types.core.TimeSeries') - testCase.verifyClass(module.Test, 'types.core.TimeSeries', ... - 'Dynamic property Test returned incorrect value'); - testCase.verifyClass(module.dynamictable_Test, 'types.hdmf_common.DynamicTable', ... - 'Dynamic property dynamictable_Test returned incorrect value'); - else - testCase.verifyClass(module.Test, 'types.hdmf_common.DynamicTable', ... - 'Dynamic property Test returned incorrect value'); - testCase.verifyClass(module.nwbdatainterface_Test, 'types.core.TimeSeries', ... - 'Dynamic property nwbdatainterface_Test returned incorrect value'); - end - end - function testAddWithExistingName(testCase) - % Create a ProcessingModule - module = types.core.ProcessingModule(); - + module = types.core.ProcessingModule('description', 'test module'); module.add('TimeSeries', types.core.TimeSeries()) - + % Adding a new object with the same name should fail - testCase.verifyError(... - @() module.add('TimeSeries', types.core.TimeSeries()), ... - 'NWB:HasUnnamedGroupsMixin:KeyExists') + operationToVerify = @()... + module.add('TimeSeries', types.core.TimeSeries()); + + testCase.verifyError(operationToVerify, ... + 'NWB:HasUnnamedGroups:KeyExists') end - - function testOverriding(testCase) - % Test overriding an existing item + + function testAddWithExistingNameToContainedSet(testCase) + module = types.core.ProcessingModule(... + 'description', 'test module', ... + 'TimeSeries', types.core.TimeSeries()); + + % Set a data object using the same name to the dynamic table group + % using legacy syntax. This should be intercepted by the + % ProcessingModule via the mixin. + operationToVerify = @()... + module.dynamictable.set( ... + 'TimeSeries', types.hdmf_common.DynamicTable()); - % Create a ProcessingModule - module = types.core.ProcessingModule(); + testCase.verifyError(operationToVerify, ... + 'NWB:HasUnnamedGroups:DuplicateEntry') + end + + function testOverrideExistingEntry(testCase) + module = types.core.ProcessingModule(... + 'description', 'test module', ... + 'Test', types.core.TimeSeries()); - % Add an item - module.nwbdatainterface.set('Test', types.core.TimeSeries()); - testCase.verifyTrue(isprop(module, 'Test'), 'Dynamic property Test was not created'); - testCase.verifyClass(module.Test, 'types.core.TimeSeries', ... - 'Dynamic property Test did not return expected value'); + testCase.verifyTrue(isprop(module, 'Test'), ... + 'Dynamic property Test was not created'); % Override it with a different type - module.nwbdatainterface.set('Test', types.core.Fluorescence()); + module.Test = types.core.Fluorescence(); % Verify the property has the new type testCase.verifyClass(module.Test, 'types.core.Fluorescence', ... 'Dynamic property Test did not return the overridden value'); end - function testInvalidType(testCase) + function testAddInvalidType(testCase) module = types.core.ProcessingModule(); - testCase.verifyError(... - @() module.add('Device', types.core.Device()), ... - 'NWB:HasUnnamedGroupsMixin:AddInvalidType') + operationToVerify = @()... + module.add('Device', types.core.Device()); + + testCase.verifyError(operationToVerify, ... + 'NWB:HasUnnamedGroups:AddInvalidType') end function testObjectDisplay(testCase) - % Create a ProcessingModule + % Create a ProcessingModule with objects in each subgroup module = types.core.ProcessingModule(); - - % Add one object to each of the subgroups module.add('TimeSeries', types.core.TimeSeries()); module.add('DynamicTable', types.hdmf_common.DynamicTable()); + % Verify both display modes origPrefValue = getpref('matnwb', 'displaymode', 'flat'); testCase.addTeardown(@() setpref('matnwb', 'displaymode', origPrefValue)) setpref('matnwb', 'displaymode', 'flat') C = evalc('disp(module)'); + testCase.verifyFalse(contains(C, 'nwbdatainterface entries:')) + testCase.verifyFalse(contains(C, 'dynamictable entries:')) testCase.verifyTrue(contains(C, 'TimeSeries:')) testCase.verifyTrue(contains(C, 'DynamicTable:')) setpref('matnwb', 'displaymode', 'groups') C = evalc('disp(module)'); - testCase.verifyTrue(contains(C, 'nwbdatainterface elements:')) - testCase.verifyTrue(contains(C, 'dynamictable elements:')) + testCase.verifyTrue(contains(C, 'nwbdatainterface entries:')) + testCase.verifyTrue(contains(C, 'dynamictable entries:')) + testCase.verifyTrue(contains(C, 'TimeSeries:')) end - function testObjectWithAliasedNames(testCase) - % Create a ProcessingModule - module = types.core.ProcessingModule(); - - % Add items with similar names that will evaluate to the same - % valid name + function testDisplayObjectWithAliasNamesShowsWarning(testCase) + % Create a ProcessingModule and add entries with names that + % will evaluate to the same valid identifier + module = types.core.ProcessingModule('description', 'test module'); module.add('Time_Series', types.core.TimeSeries()); module.add('Time-Series', types.core.TimeSeries()); - C = evalc('disp(module)'); - - % Verify that the displayed object will contain a warning - % message informing about "alias" names - expectedMessage = 'Warning: The following named elements of "ProcessingModule"'; % ... - testCase.verifyTrue( contains(C, expectedMessage)) - % Would use startsWith instead of contains, but C contains some - % hidden "display" characters in the beginning + % Display the object to trigger alias warning. Use evalc to hide + % output from test logs + C = evalc('disp(module)'); %#ok + + % Verify that warning was triggered + expectedWarningId = 'NWB:DynamicPropertyAliasWarning'; + [~, lastWarnId] = lastwarn(); + testCase.verifyTrue( strcmp(lastWarnId, expectedWarningId)) end function testListAliasNamesFromFile(testCase) - + nwbFile = tests.factory.NWBFile(); ophysModule = types.core.ProcessingModule(... @@ -249,7 +265,7 @@ function testListAliasNamesFromFile(testCase) testCase.verifySize(result, [2,4]) testCase.verifyClass(result, 'table') - testCase.verifyEqual(result.ActualName, ... + testCase.verifyEqual(result.OriginalName, ... ["Raw-Fluorescence"; "Roi-Response-Series"]) end end diff --git a/+tests/+unit/aberrantValuesTest.m b/+tests/+unit/aberrantValuesTest.m index ec303f78c..42958b974 100644 --- a/+tests/+unit/aberrantValuesTest.m +++ b/+tests/+unit/aberrantValuesTest.m @@ -35,6 +35,10 @@ function testExtraAttribute(TestCase) end function testInvalidConstraint(TestCase) + import matlab.unittest.fixtures.SuppressedWarningsFixture + expectedWarningId = 'NWB:CheckUnset:InvalidProperties'; + TestCase.applyFixture(SuppressedWarningsFixture(expectedWarningId)) + % Add a fake valid dataset to force the constrained validation to fail. fid = H5F.open(TestCase.TestFileName, 'H5F_ACC_RDWR', 'H5P_DEFAULT'); % add a fake valid dataset to force the constrained validation to fail. @@ -45,13 +49,17 @@ function testInvalidConstraint(TestCase) file = TestCase.verifyWarning( ... @() nwbRead(TestCase.TestFileName, 'ignorecache'), ... - 'NWB:Set:FailedValidation'); + 'NWB:Set:InvalidEntry'); TestCase.verifyWarning( ... @() file.acquisition.set('wrong', wrongData), ... 'NWB:Set:FailedValidation') - - TestCase.verifyTrue(~file.acquisition.isKey('wrong')); + + TestCase.verifyError( ... + @() file.acquisition.add('wrong', wrongData), ... + 'NWB:Set:FailedValidation') + + TestCase.verifyFalse(file.acquisition.isKey('wrong')); end end end diff --git a/+tests/+unit/untypedSetTest.m b/+tests/+unit/untypedSetTest.m index 7a81f5eba..6fa6a2b9f 100644 --- a/+tests/+unit/untypedSetTest.m +++ b/+tests/+unit/untypedSetTest.m @@ -10,22 +10,36 @@ function setupMethod(testCase) methods (Test) function testCreateSetWithFunctionInput(testCase) - set = types.untyped.Set(@(key, value) true); - testCase.verifyNotEmpty(set.ValidationFcn) + + % Verify a function that validates the input + set = types.untyped.Set(@(key, value) assert(strcmp(key, 'test'))); + try + set.validateEntry('test', 1) + catch + testCase.verifyFail('Expected validation to pass') + end + + % Verify a function that does not validate the input + set = types.untyped.Set(... + @(key, value) error('NWB:SetTest:ValidationError', 'Invalid value for `%s`', key)); + + testCase.verifyError( ... + @() set.validateEntry('test', 1), ... + 'NWB:Set:InvalidEntry') end function testCreateSetFromStruct(testCase) - untypedSet = types.untyped.Set( struct('a',1, 'b', 2) ); + untypedSet = types.untyped.Set( struct('a', 1, 'b', 2) ); testCase.verifyEqual(untypedSet.get('a'), 1) end function testCreateSetFromNvPairs(testCase) - untypedSet = types.untyped.Set( 'a',1, 'b', 2 ); + untypedSet = types.untyped.Set('a', 1, 'b', 2 ); testCase.verifyEqual(untypedSet.get('a'), 1) end function testCreateSetFromNvPairsPlusFunctionHandle(testCase) - untypedSet = types.untyped.Set( 'a',1, 'b', 2, @(key, value) disp('Hello World')); + untypedSet = types.untyped.Set('a', 1, 'b', 2, @(key, value) assert(ischar(key))); testCase.verifyEqual(untypedSet.get('a'), 1) end @@ -42,7 +56,7 @@ function testDisplayScalarObject(testCase) end function testGetSetSize(testCase) - untypedSet = types.untyped.Set( 'a',1, 'b', 2 ); + untypedSet = types.untyped.Set('a', 1, 'b', 2 ); [nRowsA, nColsA] = size(untypedSet); diff --git a/+types/+untyped/+internal/displayAliasWarning.m b/+types/+untyped/+internal/displayAliasWarning.m new file mode 100644 index 000000000..a5cc22b7a --- /dev/null +++ b/+types/+untyped/+internal/displayAliasWarning.m @@ -0,0 +1,24 @@ +function displayAliasWarning(aliasTable, className) +% displayAliasWarning - Display warning with table of alias names for an object +% +% Utility method that formats and displays a warning given an alias table +% and the class name for an object. Will typically be used for an object +% with dynamic properties where property identifiers are aliases for an +% original name which is not a valid MATLAB identifier. + + if ~isempty(aliasTable) + nameMap = evalc('disp(aliasTable)'); + + warningIdentifier = 'NWB:DynamicPropertyAliasWarning'; + warningMessage = sprintf([... + ['Names for some entries of "%s" have been modified to ', ... + 'make them valid MATLAB identifiers before adding them as ', ... + 'properties of the object. The original names will still ', ... + 'be used when data is exported to file:\n'], ... + '\n%s\n'], className, strip(nameMap, 'right')); + + warnState = warning('backtrace', 'off'); + resetWarningObj = onCleanup(@() warning(warnState)); + warning(warningIdentifier, warningMessage) %#ok + end +end diff --git a/+types/+untyped/Set.m b/+types/+untyped/Set.m index 302a4a37e..03a0a6ada 100644 --- a/+types/+untyped/Set.m +++ b/+types/+untyped/Set.m @@ -1,85 +1,121 @@ -classdef Set < handle & matlab.mixin.CustomDisplay - properties(SetAccess=protected) - Map; % containers.Map - ValidationFcn = @(key, value)[]; +classdef Set < dynamicprops & matlab.mixin.CustomDisplay +% Set - A (utility) container class for storing neurodata types. +% +% Neurodata types are added to the Set with name keys, forming name-value +% pairs referred to as entries. + +% Developer notes: +% `name` is used throughout this class to refer to the actual name of a Set +% entry, not the valid MATLAB identifier used for the Set s dynamic property +% names. In legacy methods, `key` is equivalent to `name`. + + properties (Access = private) + ValidationFunction function_handle = function_handle.empty() % validation function for entries + PropertyManager matnwb.utility.DynamicPropertyManager end properties (Access = ?matnwb.mixin.HasUnnamedGroups) % These properties enables the HasUnnamedGroups mixin to react when - % items are added or removed from the Set. - ItemAddedFunction function_handle - ItemRemovedFunction function_handle + % entries are added or removed from the Set. + EntryAddedFunction function_handle + EntryRemovedFunction function_handle end methods + %% Constructor function obj = Set(varargin) % obj = SET returns an empty set % obj = SET(field1,value1,...,fieldN,valueN) returns a set from key value pairs % obj = SET(src) can be a struct or map % obj = SET(__,fcn) adds a validation function from a handle - obj.Map = containers.Map; - + + obj.PropertyManager = matnwb.utility.DynamicPropertyManager(obj); + if nargin == 0 return; end - - switch class(varargin{1}) - case 'function_handle' - obj.ValidationFcn = varargin{1}; - case {'struct', 'containers.Map'} - src = varargin{1}; - if isstruct(src) - srcFields = fieldnames(src); - for i=1:length(srcFields) - obj.Map(srcFields{i}) = src.(srcFields{i}); - end - else - srcKeys = keys(src); - obj.set(srcKeys, values(src, srcKeys)); - end - - if nargin > 1 - assert(isa(varargin{2}, 'function_handle'),... - '`fcn` Expected a function_handle type'); - obj.ValidationFcn = varargin{2}; - end - case 'char' - if mod(length(varargin), 2) == 1 - assert(isa(varargin{end}, 'function_handle'),... - '`fcn` Expected a function_handle type'); - obj.ValidationFcn = varargin{end}; - varargin(end) = []; - end - assert(mod(length(varargin), 2) == 0,... - ['KeyWord Argument Count Mismatch. '... - 'Number of Keys do not match number of values']); - assert(iscellstr(varargin(1:2:end)),... - 'KeyWord Argument Error: Keys must be char'); - obj.Map = containers.Map(varargin(1:2:end), varargin(2:2:end)); - end + + % Handles case where `fcn` is passed as last input + varargin = obj.popValidationFunctionFromArgsIfPresent(varargin); + + obj.addDynamicPropertiesFromArgsIfPresent(varargin) end - - function tf = isKey(obj, name) - tf = isKey(obj.Map, name); + + %% validation function propagation + function set.ValidationFunction(obj, value) + obj.ValidationFunction = value; + + if ~isempty(obj.ValidationFunction) + obj.validateAll("mode", "warn") + end end - %return object's keys - function k = keys(obj) - k = keys(obj.Map); + function validateEntry(obj, name, value) + if ~isempty(obj.ValidationFunction) + try + obj.ValidationFunction(name, value); + catch MECause + ME = MException('NWB:Set:InvalidEntry', ... + 'Entry of Constrained Set with name `%s` is invalid.\n', name); + ME = ME.addCause(MECause); + throw(ME) + end + end end - - %return values of backed map - function v = values(obj) - v = values(obj.Map); + + function validateAll(obj, options) + arguments + obj types.untyped.Set + options.Mode (1,1) string ... + {mustBeMember(options.Mode, ["warn", "fail"])} = "warn" + end + + names = obj.keys(); + isInvalidEntry = false(size(names)); + + for i = 1:length(names) + currentName = names{i}; + try + obj.validateEntry(currentName, obj.get(currentName)); + catch ME + isInvalidEntry(i) = true; + if options.Mode == "warn" + warning('NWB:Set:InvalidEntry', ... + ['Failed to validate entry of Constrained Set with ', ... + 'name `%s`.\nReason:\n%s.\nData will be dropped.'], ... + currentName, ME.message); + else + rethrow(ME) + end + end + end + obj.remove(names(isInvalidEntry)) end - - %return number of entries - function cnt = Count(obj) - cnt = obj.Map.Count; + + %% Export + function refs = export(obj, fid, fullpath, refs) + io.writeGroup(fid, fullpath); + + allPropertyNames = obj.PropertyManager.getAllPropertyNames(); + for iPropName = 1:length(allPropertyNames) + propertyName = allPropertyNames{iPropName}; + propertyValue = obj.(propertyName); + + originalName = obj.PropertyManager.getOriginalNameForPropertyName(propertyName); + propertyFullPath = [fullpath '/' originalName]; + + if startsWith(class(propertyValue), 'types.') + refs = propertyValue.export(fid, propertyFullPath, refs); + else + io.writeDataset(fid, propertyFullPath, propertyValue); + end + end end - %overloads size(obj) + %% size() override + function varargout = size(obj, dim) + % overloads size(obj) if nargin > 1 if dim > 1 varargout{1} = 1; @@ -95,169 +131,364 @@ end end end - - %overloads horzcat(A1,A2,...,An) - function C = horzcat(varargin) + + function C = horzcat(varargin) %#ok + % horzcat - overloads horzcat(A1,A2,...,An) error('NWB:Set:Unsupported',... 'types.untyped.Set does not support concatenation'); end - - %overloads vertcat(A1, A2,...,An) - function C = vertcat(varargin) + + function C = vertcat(varargin) %#ok + % vertcat - overloads vertcat(A1, A2,...,An) error('NWB:Set:Unsupported',... 'types.untyped.Set does not support concatenation.'); end - - function setValidationFcn(obj, fcn) - assert(isa(fcn, 'function_handle'), ... - 'Validation must be a function handle of form @(name, val) or empty array.'); - obj.ValidationFcn = fcn; + + function add(obj, name, value) + % add - Add an element (name, value pair) to the set + obj.set(name, value, ... + 'FailIfKeyExists', true, ... + 'FailOnInvalidType', true); end - - function validateAll(obj) - mapkeys = keys(obj.Map); - keyFailed = false(size(mapkeys)); - for i=1:length(mapkeys) - mk = mapkeys{i}; - try - obj.ValidationFcn(mk, obj.Map(mk)); - catch ME - warning('NWB:Set:FailedValidation' ... - , 'Failed to validate Constrained Set key `%s` with message:\n%s' ... - , mk, ME.message); - keyFailed(i) = true; - end - end - remove(obj.Map, mapkeys(keyFailed)); + + function name = getPropertyName(obj, name) + % getPropertyName - Get property name given the actual name of an entry + + existsName = obj.PropertyManager.existOriginalName(name); + assert(existsName, ... + 'NWB:Set:MissingName', ... + 'Could not find name `%s` in Set', name); + + name = obj.PropertyManager.getPropertyNameForOriginalName(name); end - function add(obj, name, val) - % add - Add an element to the set - obj.set(name, val, 'FailIfKeyExists', true); + function name = getOriginalName(obj, propertyName) + existsName = obj.PropertyManager.existPropertyName(propertyName); + assert(existsName, ... + 'NWB:Set:MissingName', ... + 'Could not find property name `%s` in Set', propertyName); + + name = obj.PropertyManager.getOriginalNameForPropertyName(propertyName); end - - function obj = set(obj, name, val, varargin) - - if ischar(name) - name = {name}; + end + + methods (Hidden) % Allows setting custom validation function. + function setValidationFunction(obj, functionHandle) + obj.ValidationFunction = functionHandle; + end + + function T = getPropertyMappingTable(obj) + T = obj.PropertyManager.getPropertyMappingTable(); + end + end + + methods (Hidden) % Legacy set/get methods + function obj = set(obj, names, values, options) + arguments + obj types.untyped.Set + names (1,:) string + values {mustBeSameLength(values, names)} + options.FailOnInvalidType (1,1) logical = false + options.FailIfKeyExists (1,1) logical = false end - if ischar(val) - val = {val}; + % Wrap character vector in a cell array to treat it as a single + % element. NB: This workaround is also supported by mustBeSameLength + if ischar(values) + values = {values}; end - parser = inputParser(); - addParameter(parser, 'FailOnInvalidType', false); - addParameter(parser, 'FailIfKeyExists', false); - parser.parse(varargin{:}); - - cellExtract = iscell(val); - - assert(length(name) == length(val),... - 'number of property names should match number of vals on set.'); - for i = 1:length(name) - if cellExtract - elem = val{i}; + for i = 1:length(names) + if iscell(values) + currentValue = values{i}; % Extract from cell array else - elem = val(i); + currentValue = values(i); % Extract from regular array end - isOverride = obj.isKey(name{i}); + currentName = names{i}; + + existsEntry = obj.PropertyManager.existOriginalName(currentName); - if parser.Results.FailIfKeyExists - if obj.isKey(name{i}) - error('NWB:Set:KeyExists', ... - 'Key `%s` already exists in Set', name{i}) - end + if options.FailIfKeyExists && existsEntry + error('NWB:Set:KeyExists', ... + 'Entry with name `%s` already exists in Set', currentName) end try - obj.ValidationFcn(name{i}, elem); - obj.Map(name{i}) = elem; - if ~isOverride && ~isempty(obj.ItemAddedFunction) - obj.ItemAddedFunction(name{i}) - end + obj.validateEntry(currentName, currentValue) catch ME identifier = 'NWB:Set:FailedValidation'; - message = 'Failed to add key `%s` to Constrained Set with message:\n %s'; + message = 'Failed to add entry `%s` to Constrained Set with message:\n %s'; - if parser.Results.FailOnInvalidType - error(identifier, message, name{i}, ME.message) + if options.FailOnInvalidType + error(identifier, message, currentName, ME.message) + else % Skip while displaying warning + warning(identifier, message, currentName, ME.message); + continue + end + end + + if existsEntry + if isempty(currentValue) + obj.remove(currentName); else - warning(identifier, message, name{i}, ME.message); + propertyName = obj.getPropertyName(currentName); + obj.(propertyName) = currentValue; + end + else + obj.addProperty(currentName, currentValue); + if ~isempty(obj.EntryAddedFunction) + obj.EntryAddedFunction(currentName) end end end end - - function obj = remove(obj, name) - remove(obj.Map, name); - if ~isempty(obj.ItemRemovedFunction) - obj.ItemRemovedFunction(name) + + function values = get(obj, names) + + % NB: This method assumes the names being passed is the actual + % name, not the MATLAB-valid name. + + if ischar(names) + names = {names}; + end + + values = cell(length(names),1); + for i = 1:length(names) + obj.assertEntryExists(names{i}) + currentPropertyName = obj.getPropertyName(names{i}); + values{i} = obj.(currentPropertyName); + end + if isscalar(values) + values = values{1}; end end - - function obj = clear(obj) - obj.Map = containers.Map; + end + + % Legacy methods mirroring containers.Map interface + methods (Hidden) + function cnt = Count(obj) + cnt = obj.PropertyManager.getPropertyCount(); end - - function o = get(obj, name) - if ischar(name) - name = {name}; - end - o = cell(length(name),1); - for i=1:length(name) - o{i} = obj.Map(name{i}); + + function keySet = keys(obj) + keySet = obj.PropertyManager.getAllOriginalNames(); + if iscolumn(keySet) + keySet = transpose(keySet); % Return as row vector end - if isscalar(o) - o = o{1}; + end + + function valueSet = values(obj) + keySet = keys(obj); + valueSet = cell(size(keySet)); + for iKey = 1:length(keySet) + currentKey = keySet{iKey}; + valueSet{iKey} = obj.get(currentKey); end end + + function remove(obj, names) + % remove - Remove a set of entries given their names. + % + % Note: The name should be the original (actual) name of the entry, + % not the property identifier. - function refs = export(obj, fid, fullpath, refs) - io.writeGroup(fid, fullpath); - k = keys(obj.Map); - val = values(obj.Map, k); - for i=1:length(k) - v = val{i}; - nm = k{i}; - propFullPath = [fullpath '/' nm]; - if startsWith(class(v), 'types.') - refs = v.export(fid, propFullPath, refs); - else - refs = io.writeDataset(fid, propFullPath, v, refs); - end + arguments + obj types.untyped.Set + names (1,:) string + end + + for iEntry = 1:length(names) + obj.assertEntryExists(names(iEntry)) + obj.warnIfDataTypeIsBoundToFile(names(iEntry)) + obj.removeProperty(names(iEntry)) end end + + function tf = isKey(obj, name) + tf = obj.PropertyManager.existOriginalName(name); + if ~tf && isprop(obj, name) + obj.warnIfPropertyNameExistsButNotOriginalName(name) + end + end + + function clear(obj) + obj.remove( keys(obj) ); + end end - - methods(Access=protected) + + % matlab.mixin.CustomDisplay overrides + methods (Access = protected) function displayEmptyObject(obj) - hdr = sprintf(' %s with no elements.', ... + hdr = sprintf(' %s with no entries.', ... [''... 'Set']); footer = getFooter(obj); disp([hdr newline footer]); end - + function displayScalarObject(obj) displayNonScalarObject(obj) end - + function displayNonScalarObject(obj) hdr = getHeader(obj); + hdr = strrep(hdr, 'with properties:', 'with entries:'); + hdr = strrep(hdr, 'array ', ''); footer = getFooter(obj); - mkeys = keys(obj); - mklen = cellfun('length', mkeys); - max_mklen = max(mklen); - body = cell(size(mkeys)); - for i=1:length(mkeys) - mk = mkeys{i}; - spacing = repmat(' ', 1, max_mklen - mklen(i)); - body{i} = [spacing mk ': [' class(obj.Map(mk)) ']']; + + propertyNames = string( properties(obj) ); + paddedPropertyNames = pad(propertyNames, 'left'); + + numProperties = numel(propertyNames); + body = cell(1, numProperties); + for i = 1:numProperties + propertyName = propertyNames{i}; + propertyType = class(obj.(propertyName)); + body{i} = sprintf('%s: %s', paddedPropertyNames{i}, propertyType); end body = file.addSpaces(strjoin(body, newline), 4); disp([hdr newline body newline footer]); end + + function str = getFooter(obj) + T = obj.getPropertyMappingTable(); + if ~isempty(T) + T(T.ValidIdentifier==T.OriginalName, :) = []; + types.untyped.internal.displayAliasWarning(T, 'Set') + end + str = ''; + end + end + + % Methods for adding and removing dynamic properties + methods (Access = private) + function assertEntryExists(obj, name) + existsEntry = obj.PropertyManager.existOriginalName(name); + + if ~existsEntry && isprop(obj, name) + obj.warnIfPropertyNameExistsButNotOriginalName(name) + end + + assert(existsEntry, ... + 'NWB:Set:EntryDoesNotExist', ... + 'Set does not contain an entry with name `%s`', name) + end + + function addProperty(obj, name, value) + arguments + obj types.untyped.Set + name (1,1) string + value + end + + metaProperty = obj.PropertyManager.addProperty(name); + propertyName = metaProperty.Name; + + if ~isempty(obj.ValidationFunction) + metaProperty.SetMethod = getDynamicSetMethodFilterFunction(propertyName); + end + obj.(propertyName) = value; + end + + function removeProperty(obj, name) + obj.PropertyManager.removeProperty(name) + if ~isempty(obj.EntryRemovedFunction) + % Let potential Set "owner" know that entry was removed + obj.EntryRemovedFunction(name) + end + end + + function warnIfDataTypeIsBoundToFile(obj, name) + % propertyName = obj.getPropertyName(name); + % Todo: placeholder for future + end + + function warnIfPropertyNameExistsButNotOriginalName(obj, name) + originalName = obj.PropertyManager.getOriginalNameForPropertyName(name); + warning('NWB:Set:PropertyNameExistsForEntry' ,... + ['"%s" is not the name for an entry of this Set, ', ... + 'but it exists as the property identifier corresponding ', ... + 'to the entry with name `%s`'], ... + name, ... + originalName) + end + end + + % Constructor argument handling + methods (Access = private) + function args = popValidationFunctionFromArgsIfPresent(obj, args) + % Pop validation function handle from input arguments if present + if isa(args{end}, 'function_handle') + obj.ValidationFunction = args{end}; + args(end) = []; + end + end + + function addDynamicPropertiesFromArgsIfPresent(obj, args) + + if isempty(args) + return + end + + [names, values] = extractNamesAndValuesFromArgs(args{:}); + for i = 1:length(names) + obj.addProperty(names{i}, values{i}); + end + end + end +end + +function [names, values] = extractNamesAndValuesFromArgs(varargin) +% extractNamesAndValuesFromArgs - Extract names and values from varargin + if isscalar(varargin) + assert(isstruct(varargin{1}) || isa(varargin{1}, 'containers.Map'), ... + 'NWB:Set:InvalidArguments', ... + 'Expected a struct or a containers.Map. Got %s', class(varargin{1})); + + switch class(varargin{1}) + case 'struct' + names = fieldnames(varargin{1}); + values = struct2cell(varargin{1}); + case 'containers.Map' + names = varargin{1}.keys(); + values = varargin{1}.values(); + end + else + isValidKeywordArgs = mod(numel(varargin), 2) == 0 ... + && ( iscellstr(varargin(1:2:end)) || isstring(varargin(1:2:end)) ); + + assert( isValidKeywordArgs, ... + 'NWB:Set:InvalidArguments', ... + 'Expected keyword arguments'); + + names = varargin(1:2:end); + values = varargin(2:2:end); + end +end + +function setterFunction = getDynamicSetMethodFilterFunction(name) +% workaround as provided by +% https://www.mathworks.com/matlabcentral/answers/266684-how-do-i-write-setter-methods-for-properties-with-unknown-names + setterFunction = @setProp; + + function setProp(obj, val) + obj.validateEntry(name, val) + obj.(name) = val; + end +end + +function mustBeSameLength(values, names) + % Workaround to support character vectors as input for values. + if ischar(values) + values = {values}; + end + + isValid = length(names) == length(values); + if ~isValid + error(... + 'NWB:Set:NameValueLengthMismatch', ... + ['The number of values must match the number of names ', ... + 'provided to the Set.']) end -end \ No newline at end of file +end diff --git a/+types/+util/+dynamictable/addVecInd.m b/+types/+util/+dynamictable/addVecInd.m index 79f6c0f82..5248eb414 100644 --- a/+types/+util/+dynamictable/addVecInd.m +++ b/+types/+util/+dynamictable/addVecInd.m @@ -5,7 +5,7 @@ if isprop(DynamicTable, colName) VecData = DynamicTable.(colName); -elseif isprop(DynamicTable, 'vectorindex') && isKey(DynamicTable.vectorindex.Map, colName) +elseif isprop(DynamicTable, 'vectorindex') && isKey(DynamicTable.vectorindex, colName) VecData = DynamicTable.vectorindex.get(colName); else VecData = DynamicTable.vectordata.get(colName); diff --git a/+types/+util/checkSet.m b/+types/+util/checkSet.m index decdcf2ca..aa1d6b398 100644 --- a/+types/+util/checkSet.m +++ b/+types/+util/checkSet.m @@ -7,7 +7,8 @@ function checkSet(pname, namedprops, constraints, val) 'NWB:CheckSet:InvalidType',... 'Property `%s` must be a `types.untyped.Set`', pname); - val.setValidationFcn(... - @(nm, val)types.util.checkConstraint(pname, nm, namedprops, constraints, val)); - val.validateAll(); -end \ No newline at end of file + validationFunction = @(nm, val) types.util.checkConstraint(... + pname, nm, namedprops, constraints, val); + + val.setValidationFunction(validationFunction) +end diff --git a/+types/+util/parseConstrained.m b/+types/+util/parseConstrained.m index 7234bfd14..59111ccb1 100644 --- a/+types/+util/parseConstrained.m +++ b/+types/+util/parseConstrained.m @@ -38,7 +38,7 @@ end % append to currently existing set. - set.setValidationFcn(validationFunction); + set.setValidationFunction(validationFunction); keyIndices = find(ikeys); valIndices = find(ivals); diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml index 1048e4df8..94a4abf83 100644 --- a/.github/workflows/run_tests.yml +++ b/.github/workflows/run_tests.yml @@ -13,6 +13,13 @@ on: push: branches: - main + workflow_dispatch: + inputs: + test_all_matlab_releases: + description: 'Run test matrix with all matlab releases (true) or only latest MATLAB release (false)' + required: true + default: false + type: boolean concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -35,17 +42,29 @@ jobs: # Load the matrix configuration and extract latest version latest_matlab_version=$(yq '.[-1].matlab-version' .github/workflows/configurations/matlab_release_matrix_strategy.yml) - # Conditionally define the MATLAB test matrix based on the PR type. - # Draft pull requests are only tested against the latest MATLAB release, - # while non-draft PRs and push events are tested against all configured releases. - if [[ "${{ github.event_name }}" == "pull_request" && "${{ github.event.pull_request.draft }}" == "true" ]]; then - echo "Draft PR detected - using latest MATLAB version only" - # Create matrix with only the latest entry - matrix=$(yq -o=json '.[-1:] | {"include": .}' .github/workflows/configurations/matlab_release_matrix_strategy.yml | tr -d '\n') + # Determine whether to use full matrix of MATLAB releases or just + # latest MATLAB release + if [[ "${{ github.event_name }}" == "workflow_dispatch" && "${{ github.event.inputs.test_all_matlab_releases }}" == "true" ]]; then + use_full_matrix=true + echo "Workflow dispatch with full matrix for all MATLAB releases" + elif [[ "${{ github.event_name }}" != "workflow_dispatch" && "${{ github.event_name }}" != "pull_request" ]]; then + use_full_matrix=true + echo "Push event - using full matrix" + elif [[ "${{ github.event_name }}" == "pull_request" && "${{ github.event.pull_request.draft }}" != "true" ]]; then + use_full_matrix=true + echo "Non-draft PR - using full matrix" else - echo "Non-draft PR or push event - using full matrix" - # Create matrix with all entries + use_full_matrix=false + echo "Using latest MATLAB release only" + fi + + # Create the appropriate matrix based on the decision + if [[ "$use_full_matrix" == "true" ]]; then + # Create matrix with all MATLAB releases matrix=$(yq -o=json '{"include": .}' .github/workflows/configurations/matlab_release_matrix_strategy.yml | tr -d '\n') + else + # Create matrix with only the latest MATLAB release + matrix=$(yq -o=json '.[-1:] | {"include": .}' .github/workflows/configurations/matlab_release_matrix_strategy.yml | tr -d '\n') fi # Assign `matrix` and `latest_matlab_version` as outputs of this job diff --git a/docs/source/pages/getting_started/file_read/untyped.rst b/docs/source/pages/getting_started/file_read/untyped.rst index 9213a62d1..ec18dc8a8 100644 --- a/docs/source/pages/getting_started/file_read/untyped.rst +++ b/docs/source/pages/getting_started/file_read/untyped.rst @@ -5,17 +5,61 @@ Utility Types in MatNWB .. note:: - Documentation for "untyped" types will be added soon + API documentation for "untyped" types will be added in the future. +"Untyped" utility types are classes not defined by the NWB schema, but used alongside NWB data classes to provide additional functionality when reading or writing NWB files with MatNWB. These types are located in the ``+types/+untyped/`` namespace within the MatNWB root directory. The following untyped types are described in this section: -"Untyped" Utility types are tools which allow for both flexibility as well as limiting certain constraints that are imposed by the NWB schema. These types are commonly stored in the ``+types/+untyped/`` package directories in your MatNWB installation. +.. contents:: + :local: + :depth: 1 .. _matnwb-read-untyped-sets-anons: -Sets and Anons -~~~~~~~~~~~~~~ +Sets +~~~~ -The **Set** (``types.untyped.Set`` or Constrained Sets) is used to capture a dynamic number of particular NWB-typed objects. They may contain certain type constraints on what types are allowable to be set. Set keys and values can be set and retrieved using their ``set`` and ``get`` methods: +The **Set** class (``types.untyped.Set``) is used to store a dynamic collection of NWB-typed objects. +Some NWB data types may include other data types as property values. The **Set** class supports this by enforcing constraints on its members—for example, restricting the set to contain only specified data types. +For this reason, it is also referred to as a *constrained set*. + +Data objects are added to a **Set** as name-value pairs using the ``add`` method: + +.. code-block:: MATLAB + + aTimeSeries = types.core.TimeSeries('data', rand(1,10)); + someSet = types.untyped.Set(); + someSet.add('my timeseries', aTimeSeries) + +The example above creates a new **Set** with one entry: + +.. code-block:: MATLAB + + >> someSet + + someSet = + + Set with entries: + + myTimeseries: types.core.TimeSeries + +The data object (``TimeSeries``) is added as a dynamic property on the **Set** object. Because MATLAB does not support whitespace or special characters in property names, the name is remapped to a valid MATLAB identifier. + +.. note:: + + The name provided when adding a data object to a **Set** is preserved in the NWB file. Tools like PyNWB or other NWB/HDF5 readers will display this original name—for example, ``'my timeseries'``. + **In MatNWB, we recommend using a consistent naming style that is valid in MATLAB (e.g., PascalCase) to avoid naming ambiguities.** + +To retrieve the value, refer to the property directly: + +.. code-block:: MATLAB + + timeSeriesCopy = someSet.myTimeseries + + +Supporting legacy syntax +------------------------ + +MatNWB also supports legacy syntax for setting and retrieving items in a **Set**: .. code-block:: MATLAB @@ -27,9 +71,12 @@ The **Set** (``types.untyped.Set`` or Constrained Sets) is used to capture a dyn .. note:: - Sets also borrow ``containers.Map``'s ``keys`` and ``values`` methods to retrieve cell arrays of either. + The **Set** class also supports the ``keys`` and ``values`` methods, similar to ``containers.Map``, for retrieving cell arrays of keys or values. + -The **Anon** type (``types.untyped.Anon``) can be understood as a Set type with only a single key-value entry. This rarer type is only used for cases where the name for the stored object can be set by the user. Anon types may also hold NWB type constraints like Set. +.. + %% The paragraph describing Anon is commented out because the Anon appears to be unused %% + The **Anon** type (``types.untyped.Anon``) can be understood as a Set type with only a single key-value entry. This rarer type is only used for cases where the name for the stored object can be set by the user. Anon types may also hold NWB type constraints like Set. .. _matnwb-read-untyped-datastub-datapipe: From 885c1398654e663ad17950dfcc1150a3d2e11164 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Sun, 29 Jun 2025 21:24:23 +0200 Subject: [PATCH 33/65] Fix failing tests for older matlab releases --- +matnwb/+utility/DynamicPropertyManager.m | 2 +- +types/+untyped/Set.m | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/+matnwb/+utility/DynamicPropertyManager.m b/+matnwb/+utility/DynamicPropertyManager.m index d966a24ba..65f95b67a 100644 --- a/+matnwb/+utility/DynamicPropertyManager.m +++ b/+matnwb/+utility/DynamicPropertyManager.m @@ -28,7 +28,7 @@ function obj = DynamicPropertyManager(targetObject, nameRegistry, propArgs) % Create a new DynamicPropertyManager for the target object arguments - targetObject (1,1) dynamicprops + targetObject dynamicprops nameRegistry (1,1) matnwb.utility.NameRegistry = matnwb.utility.NameRegistry propArgs.propertyAddedFunction function_handle = function_handle.empty propArgs.propertyRemovedFunction function_handle = function_handle.empty diff --git a/+types/+untyped/Set.m b/+types/+untyped/Set.m index 03a0a6ada..ab5249732 100644 --- a/+types/+untyped/Set.m +++ b/+types/+untyped/Set.m @@ -6,7 +6,7 @@ % Developer notes: % `name` is used throughout this class to refer to the actual name of a Set -% entry, not the valid MATLAB identifier used for the Set s dynamic property +% entry, not the valid MATLAB identifier used for the Set's dynamic property % names. In legacy methods, `key` is equivalent to `name`. properties (Access = private) From 2b515d716bbc1a88b2ebfda072edb6b239cc07fe Mon Sep 17 00:00:00 2001 From: ehennestad Date: Mon, 30 Jun 2025 09:02:58 +0200 Subject: [PATCH 34/65] Update DynamicPropertyManager.m Added note to argument definition --- +matnwb/+utility/DynamicPropertyManager.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/+matnwb/+utility/DynamicPropertyManager.m b/+matnwb/+utility/DynamicPropertyManager.m index 65f95b67a..f8b0f8065 100644 --- a/+matnwb/+utility/DynamicPropertyManager.m +++ b/+matnwb/+utility/DynamicPropertyManager.m @@ -28,7 +28,7 @@ function obj = DynamicPropertyManager(targetObject, nameRegistry, propArgs) % Create a new DynamicPropertyManager for the target object arguments - targetObject dynamicprops + targetObject dynamicprops % Note: No size constraint because types.untyped.Set (a possible input type) overrides size and has an irregular size. nameRegistry (1,1) matnwb.utility.NameRegistry = matnwb.utility.NameRegistry propArgs.propertyAddedFunction function_handle = function_handle.empty propArgs.propertyRemovedFunction function_handle = function_handle.empty From 3934b4282f387a41de7ebf32ab4f708f60588ef9 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Mon, 30 Jun 2025 09:22:23 +0200 Subject: [PATCH 35/65] Update intro.mlx --- docs/source/_static/html/tutorials/intro.html | 83 +++++++----------- tutorials/intro.mlx | Bin 221757 -> 221679 bytes tutorials/private/mcode/intro.m | 11 ++- 3 files changed, 38 insertions(+), 56 deletions(-) diff --git a/docs/source/_static/html/tutorials/intro.html b/docs/source/_static/html/tutorials/intro.html index 019d40ff2..d5b9f5a92 100644 --- a/docs/source/_static/html/tutorials/intro.html +++ b/docs/source/_static/html/tutorials/intro.html @@ -1,28 +1,22 @@ -Introduction to MatNWB

Reading NWB Data in MATLAB (DandiHub edition)

Authors: Ryan Ly, with modification by Lawrence Niu
DandiHub edition* authors: Thomas Kuenzel & Vijay Iyer
Last Updated: 2023-09-05
(*) minimally modified to utilize dandi package for download and to skip the MatNWB installation

Introduction

In this tutorial, we will read single neuron spiking data that is in the NWB standard format and do a basic visualization of the data. More thorough documentation regarding reading files as well as the NwbFile class, can be found in the NWB Overview Documentation

Download the Dataset

Use the pre-installed dandi Python package to download the dataset to the user-local dandisets folder:
environment = "Local";
switch environment
case "DandiHub"
targetFolder = "/home/jovyan/dandisets/000004";
case "Local"
targetFolder = fullfile(userpath(), "dandisets", "000004");
end
py.dandi.download.download("dandi://dandi/000004/sub-P11HMH/", targetFolder, existing='overwrite')
PATH SIZE DONE DONE% CHECKSUM STATUS MESSAGE +.S13 { border-left: 1px solid rgb(217, 217, 217); border-right: 1px solid rgb(217, 217, 217); border-top: 1px solid rgb(217, 217, 217); border-bottom: 1px solid rgb(217, 217, 217); border-radius: 4px; padding: 6px 45px 4px 13px; line-height: 18.004px; min-height: 0px; white-space: nowrap; color: rgb(33, 33, 33); font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px; } +.S14 { margin: 10px 10px 9px 4px; padding: 0px; line-height: 21px; min-height: 0px; white-space: pre-wrap; color: rgb(33, 33, 33); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 14px; font-weight: 400; text-align: left; } +.S15 { border-left: 1px solid rgb(217, 217, 217); border-right: 1px solid rgb(217, 217, 217); border-top: 0px none rgb(33, 33, 33); border-bottom: 1px solid rgb(217, 217, 217); border-radius: 0px 0px 4px 4px; padding: 0px 45px 4px 13px; line-height: 18.004px; min-height: 0px; white-space: nowrap; color: rgb(33, 33, 33); font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px; }

Reading NWB Data in MATLAB (DandiHub edition)

Authors: Ryan Ly, with modification by Lawrence Niu
DandiHub edition* authors: Thomas Kuenzel & Vijay Iyer
Last Updated: 2023-09-05
(*) minimally modified to utilize dandi package for download and to skip the MatNWB installation

Introduction

In this tutorial, we will read single neuron spiking data that is in the NWB standard format and do a basic visualization of the data. More thorough documentation regarding reading files as well as the NwbFile class, can be found in the NWB Overview Documentation

Download the Dataset

Use the dandi Python package to download the dataset to the user-local dandisets folder. If you are running this livescript on DandiHub, the dandi package is already pre-installed. On a local environment, you need to install the dandi package in the python environment returned by running pyenv() in MATLAB. For more details on using Python from MATLAB, please refer to the MATLAB documentation.
environment = "Local"; % Local or DandiHub
switch environment
case "DandiHub"
targetFolder = "/home/jovyan/dandisets/000004";
case "Local"
targetFolder = fullfile(userpath(), "dandisets", "000004");
end
py.dandi.download.download("dandi://dandi/000004/sub-P11HMH/", targetFolder, existing='overwrite')
PATH SIZE DONE DONE% CHECKSUM STATUS MESSAGE sub-P11HMH/sub-P11HMH_ses-20061101_ecephys+image.nwb 72.6 MB 72.6 MB 100% ok done Summary: 72.6 MB 72.6 MB 1 done - 100.00%

Read the NWB file

You can read any NWB file using nwbRead. You will find that the print out for this shows a summary of the data within.
nwb = nwbRead(fullfile(targetFolder, "sub-P11HMH", "sub-P11HMH_ses-20061101_ecephys+image.nwb"))
nwb =
NwbFile with properties: - - nwb_version: '2.1.0' - file_create_date: [1×1 types.untyped.DataStub] - general_devices: [1×1 types.untyped.Set] - identifier: 'H11_9' - session_description: 'New/Old recognition task for ID: 9. ' - session_start_time: 2006-11-01T00:00:00.000000-07:00 - timestamps_reference_time: 2006-11-01T00:00:00.000000-07:00 - acquisition: [2×1 types.untyped.Set] - analysis: [0×1 types.untyped.Set] - general: [0×1 types.untyped.Set] - general_data_collection: 'learning: 80, recognition: 81' - general_experiment_description: 'The data contained within this file describes a new/old recogntion task performed in patients with intractable epilepsy implanted with depth electrodes and Behnke-Fried microwires in the human Medical Temporal Lobe (MTL).' - general_experimenter: '' - general_extracellular_ephys: [9×1 types.untyped.Set] - general_extracellular_ephys_electrodes: [1×1 types.core.DynamicTable] - general_institution: 'Hunigton Memorial Hospital' - general_intracellular_ephys: [0×1 types.untyped.Set] - general_intracellular_ephys_filtering: '' - general_intracellular_ephys_sweep_table: [] - general_keywords: [1×1 types.untyped.DataStub] - general_lab: 'Rutishauser' - general_notes: '' - general_optogenetics: [0×1 types.untyped.Set] - general_optophysiology: [0×1 types.untyped.Set] - general_pharmacology: '' - general_protocol: '' - general_related_publications: [1×1 types.untyped.DataStub] - general_session_id: '' - general_slices: '' - general_source_script: '' - general_source_script_file_name: '' - general_stimulus: '' - general_subject: [1×1 types.core.Subject] - general_surgery: '' - general_virus: '' - intervals: [0×1 types.untyped.Set] - intervals_epochs: [] - intervals_invalid_times: [] - intervals_trials: [1×1 types.core.TimeIntervals] - processing: [0×1 types.untyped.Set] - scratch: [0×1 types.untyped.Set] - stimulus_presentation: [1×1 types.untyped.Set] - stimulus_templates: [0×1 types.untyped.Set] - units: [1×1 types.core.Units] -

Stimulus

Now lets take a look at the visual stimuli presented to the subject. They will be in nwb.stimulus_presentation
nwb.stimulus_presentation
ans =
Set with properties: - - StimulusPresentation: [types.core.OpticalSeries] -
This results shows us that nwb.stimulus_presentation is a Set object that contains a single data object called StimulusPresentation, which is an OpticalSeries neurodata type. Use the get method to return this OpticalSeries. Set objects store a collection of other NWB objects.
nwb.stimulus_presentation.get('StimulusPresentation')
ans =
OpticalSeries with properties: - - distance: 0.7000 - field_of_view: [1×1 types.untyped.DataStub] - orientation: 'lower left' - dimension: [1×1 types.untyped.DataStub] - external_file: '' - external_file_starting_frame: [] - format: 'raw' - starting_time_unit: 'seconds' - timestamps_interval: 1 - timestamps_unit: 'seconds' - data: [1×1 types.untyped.DataStub] - data_unit: 'meters' - comments: 'no comments' - control: [] - control_description: '' - data_conversion: 1 - data_resolution: -1 - description: 'no description' - starting_time: [] - starting_time_rate: [] - timestamps: [1×1 types.untyped.DataStub] -
OpticalSeries is a neurodata type that stores information about visual stimuli presented to subjects. This print out shows all of the attributes in the OpticalSeries object named StimulusPresentation. The images are stored in StimulusPresentation.data
StimulusImageData = nwb.stimulus_presentation.get('StimulusPresentation').data
StimulusImageData =
DataStub with properties: - - filename: '/Users/Eivind/Documents/MATLAB/dandisets/000004/sub-P11HMH/sub-P11HMH_ses-20061101_ecephys+image.nwb' - path: '/stimulus/presentation/StimulusPresentation/data' - dims: [3 300 400 200] - ndims: 4 - dataType: 'uint8' -
When calling a data object directly, the data is not read but instead a DataStub is returned. This is because data is read "lazily" in MatNWB. Instead of reading the entire dataset into memory, this provides a "window" into the data stored on disk that allows you to read only a section of the data. In this case, the last dimension indexes over images. You can index into any DataStub as you would any MATLAB matrix.
% get the image and display it
% the dimension order is provided as follows:
% [rgb, y, x, image index]
img = StimulusImageData(1:3, 1:300, 1:400, 32);
A bit of manipulation allows us to display the image using MATLAB's imshow.
img = permute(img,[3, 2, 1]); % fix orientation
img = flip(img, 3); % reverse color order
F = figure();
imshow(img, 'InitialMagnification', 'fit');
daspect([3, 5, 5]);
To read an entire dataset, use the DataStub.load method without any input arguments. We will use this approach to read all of the image display timestamps into memory.
stimulus_times = nwb.stimulus_presentation.get('StimulusPresentation').timestamps.load();

Quick PSTH and raster

Here, I will pull out spike times of a particular unit, align them to the image display times, and finally display the results.
First, let us show the first row of the NWB Units table representing the first unit.
nwb.units.getRow(1)
ans = 1×8 table
 origClusterIDwaveform_mean_encodingwaveform_mean_recognitionIsolationDistSNRwaveform_mean_sampling_ratespike_timeselectrodes
11102256×1 double256×1 double11.29171.440798400373×1 double0
Let us specify some parameters for creating a cell array of spike times aligned to each stimulus time.
%% Align spikes by stimulus presentations
 
unit_ind =8;
before =1;
after =3;
getRow provides a convenient method for reading this data out.
unit_spikes = nwb.units.getRow(unit_ind, 'columns', {'spike_times'}).spike_times{1}
unit_spikes = 2116×1
103 ×
5.9338 - 5.9343 - 5.9346 - 5.9358 - 5.9364 - 5.9375 - 6.0772 - 6.0776 - 6.0797 - 6.0798 -
Spike times from this unit are aligned to each stimulus time and compiled in a cell array
results = cell(1, length(stimulus_times));
for itime = 1:length(stimulus_times)
stimulus_time = stimulus_times(itime);
spikes = unit_spikes - stimulus_time;
spikes = spikes(spikes > -before);
spikes = spikes(spikes < after);
results{itime} = spikes;
end

Plot results

Finally, here is a (slightly sloppy) peri-stimulus time histogram
figure();
hold on
for i = 1:length(results)
spikes = results{i};
yy = ones(length(spikes)) * i;
 
plot(spikes, yy, 'k.');
end
hold off
ylabel('trial');
xlabel('time (s)');
axis('tight')
figure();
all_spikes = cat(1, results{:});
histogram(all_spikes, 30);
ylabel('count')
xlabel('time (s)');
axis('tight')

Conclusion

This is an example of how to get started with understanding and analyzing public NWB datasets. This particular dataset was published with an extensive open analysis conducted in both MATLAB and Python, which you can find here. For more datasets, or to publish your own NWB data for free, check out the DANDI archive here.
+ 100.00%

Read the NWB file

You can read any NWB file using nwbRead. You will find that the print out for this shows a summary of the data within.
nwb = nwbRead(fullfile(targetFolder, "sub-P11HMH", "sub-P11HMH_ses-20061101_ecephys+image.nwb"))
Error using nwbRead
The class 'types.core.DynamicTable' is not a superclass of class 'types.core.TimeIntervals', as required to invoke a superclass constructor or method.

Caused by:
This error typically occurs if NWB objects created with a different version are still loaded in memory. Try using `clear all` and run `nwbRead` again.

Stimulus

Now lets take a look at the visual stimuli presented to the subject. They will be in nwb.stimulus_presentation
nwb.stimulus_presentation
This result shows that nwb.stimulus_presentation is a Set object. In MatNWB, a Set object stores a collection of other NWB objects. In this case, the Set contains a single data object named StimulusPresentation, which is of the OpticalSeries neurodata type. You can use dot notation of the form Set.objectName to access this OpticalSeries:
nwb.stimulus_presentation.StimulusPresentation
OpticalSeries is a neurodata type that stores information about visual stimuli presented to subjects. This print out shows all of the attributes in the OpticalSeries object named StimulusPresentation. The images are stored in StimulusPresentation.data
StimulusImageData = nwb.stimulus_presentation.StimulusPresentation.data
When calling a data object directly, the data is not read but instead a DataStub is returned. This is because data is read "lazily" in MatNWB. Instead of reading the entire dataset into memory, this provides a "window" into the data stored on disk that allows you to read only a section of the data. In this case, the last dimension indexes over images. You can index into any DataStub as you would any MATLAB matrix.
% get the image and display it
% the dimension order is provided as follows:
% [rgb, y, x, image index]
img = StimulusImageData(1:3, 1:300, 1:400, 32);
A bit of manipulation allows us to display the image using MATLAB's imshow.
img = permute(img,[3, 2, 1]); % fix orientation
img = flip(img, 3); % reverse color order
F = figure();
imshow(img, 'InitialMagnification', 'fit');
daspect([3, 5, 5]);
To read an entire dataset, use the DataStub.load method without any input arguments. We will use this approach to read all of the image display timestamps into memory.
stimulus_times = nwb.stimulus_presentation.StimulusPresentation.timestamps.load();

Quick PSTH and raster

Here, I will pull out spike times of a particular unit, align them to the image display times, and finally display the results.
First, let us show the first row of the NWB Units table representing the first unit.
nwb.units.getRow(1)
Let us specify some parameters for creating a cell array of spike times aligned to each stimulus time.
%% Align spikes by stimulus presentations
 
unit_ind =8;
before =1;
after =3;
getRow provides a convenient method for reading this data out.
unit_spikes = nwb.units.getRow(unit_ind, 'columns', {'spike_times'}).spike_times{1}
Spike times from this unit are aligned to each stimulus time and compiled in a cell array
results = cell(1, length(stimulus_times));
for itime = 1:length(stimulus_times)
stimulus_time = stimulus_times(itime);
spikes = unit_spikes - stimulus_time;
spikes = spikes(spikes > -before);
spikes = spikes(spikes < after);
results{itime} = spikes;
end

Plot results

Finally, here is a (slightly sloppy) peri-stimulus time histogram
figure();
hold on
for i = 1:length(results)
spikes = results{i};
yy = ones(length(spikes)) * i;
 
plot(spikes, yy, 'k.');
end
hold off
ylabel('trial');
xlabel('time (s)');
axis('tight')
figure();
all_spikes = cat(1, results{:});
histogram(all_spikes, 30);
ylabel('count')
xlabel('time (s)');
axis('tight')

Conclusion

This is an example of how to get started with understanding and analyzing public NWB datasets. This particular dataset was published with an extensive open analysis conducted in both MATLAB and Python, which you can find here. For more datasets, or to publish your own NWB data for free, check out the DANDI archive here.

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

x5pj829wB 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 literal 461060 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

N6>H`pe(dW^6x4u3Z@>GvW54}=Lt@~O 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�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%0D*N~#}nTQlTfMW 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

STJ8mP zAx8&=1@XLQUaz0UlYcg1pe=ltk9_Vl}Eu>gkyMg@k^u@z3FfYtI(e0#G>Ee^mZ2`B_&W z*Tw!r%>MSdfKOw?zC0qC?Ul zIhdw-yJop~I&m{W5V-HJ&+k9vnbSxCFbMz!zzX^Bd}&93Vi&&N^}9H1OR z+?Y0?Z%TPt7u>Y<7&gYb=aURL+mSt5_wLTm_o6)T< zx6qkc6kRhP&0)_|qFv2A%Qz?vaAzD@hFMjLqIeT+m^{yezNdKvnVwXX8={aJGPc~; z-4#B-e7ttc)Fsdouh{3!B~&5SD8D5T84$tCMiN*3r~K3}MFdW4Ebrg*YRpt*4>>^` zl${Qgp1AUf^38&}HM_t245kcn$wJt9W>v}#zGYljT1E2AxZjegc)e&F)+VgF5bN;I z{DxuKIJzaVJ`wS4Cp^!uJ+KvCJdD7&`tlwz!S&0v!y$Ge1+$IR`u0=buBT8})r{=m zG5n-w+v(ri&4caOm?X)UCieE_RaN6KXm8uh0pUix_Zy=IcxT2Yk6_7$Vc0`7U!pLi z165`B533%>vG`@Vb4x=YNanW;6Xh!AB)RV~JfDU;eY+_2tQ!VF{vV&e6Pw?@0ud4`hn%=4L8 zp&X~GKwvD6Od#Ck?O@#l^(a2yGm5W$W07r;KyKa6h6;OXHUy>tJgKS|EB#yi3Lg{C z`s*6u$-HeF?TF&Be_F*fjBMf$KSL3o*n`Qt?;)S&D2db01Vx-Sj2MK!m9eVEdE!)Y z7~TvVKhpJ+?HGnJHp;SPS*~}nTBkx#j@OF%@9r!~>N9w?*V}cz?cO7}+@IZ9eG0|pE_IkBTwdpXm#piMfN*kF<7BXA&EdvN za#==8sJ-CaoNhI_qT-sP=z_Eck~FcIlLy-#3f+tmT^`fUhBQl({%V>!pY)wCj&tMh(HA7i;|R(#fh@9Ep)2L8pvvOY!N+vrwxyTCo;XhRhP z0G5_$@4DU|xy6oc+b*(FDN#JGbJ=Embzz$$oc;B*Ht^2x&Qm%@Fq=V$ks9ix_b3{c zz2`EGC8t`IUYCWQg-sH(mZGPpH|}E3l&?Azo?6w02KBk1y{i-p_` zmdopzr`>c(^Yz#^)=?h5cbHWmHWpFi5edy@QA0j)|u z<(7k`49vTV-jxV8`Zg?|9*MT|kW&l^`=#N{I=@AMzxG_w#`9-7BYA5B-%ZRsU?a3$ z)-?|XZ%kMZJ2Y1PF6#uOQWQ{}r`B7LpDsNX-7Z1GB!&g{?JYmuCt*+4HWzooQ>~l4 z9qEsCtHMf>x9aSk#L2Q1^2HE`C#$eWC00$lFhv0IP-#LlUQuBEfyesIz8x4qrzZn2 zo~5x9o56f)Dl4mMXR|YD!dj?h%F=`8D1E1sRm9UIalAnD0J0as>B`KDU7X$#;3>vv zUA)gzlN9lcfj?BdLr(chmWHz&6z?)n?%maTYGcn+4=fh4lQ|dU3+%>4A`}=#mR088 zZI5v@9X>sl6gI;*VQrp{oHu;Qmv8M;e_bz=I(Pkh4~y<}`e@}~P}vQr)U8#oPv%v} zrzmZNQvk-M>*6L*_g`WCgM})w@8{{o2C-2!Ui^bb5JUdJJKYP79D04JZcIL3Dq0+! zniF4|9K3I~LAVaE7o|RCm|JecHDIpAahfEeE(H7{O_mVqqWHWNsYy!4aXoMS+*OD+ zdu%WrHx6Alp`H0{f1(OX?1Z9_GzHTi4J_p5cC7c_f0buV9wWCD1fdY5TC&`yah4WO z72e>#-#&&B1;No}7wg_!nfu~Suh$3IYI<>^+Rn;XIaI@lmBJ7Z)5xX*pbgIt{*!%K z4^34hH%$iFV<^I7&`5`IOcxyLAQ_%LL^q2h31kV{$N2IKc2v@vFK86fph;5 zc|KyAVm5~<3c?4G0ARDKw5LYpO#b+xVzqj`UW9or6kBpH{v83t_<1Upa?tnJ{IF>E zfxFa0aJAS=`K5qwHU+_UR-^57FJIpEdTmbIa0c^d_B?}_N4_7dVxR%=u@sp%Y{3Z{ z<|4lq#+Z^!7b_COj2o{a&K{=&mgqE1Q|=9znroCmrkq`EcJq6X+=P#AEhXN?j%478 z?nbh8vCnv#kJJuAn5Sq~NlezW>)i5uz7r zh;6%Zhg3fFQL*0V{uM2Ixwe`t6~TG%Ej$^Wx1I*kf=OWSq#-(a!u!-=lO2FK9(-!c zVkJqk1sXpI=f|9y>shM;b-#tL&IEewmJ1XJ2RGR{=Gv9}>$U;WKp3%6UC%)CB>&Z% zHHuIQU3!}xTmZQm9+*_!!qJOU?p2Sb;W+9U(6=xPHbM)Y-8C%FPcYC>yiV7BX~~!J zm`;?$VVDBu@kWc}R(z!D9uh#jMI*p+GesQr`PGBrMhNkf5~8y7t{~n6dk{dpXG`Vr zK2abtV1E-vB2_ z%sHwnkbY&tfBhhmJ1~e@mmT2t7#Rv+o)3Da#eZv8)=>qSfIThb#~?K@a;^VNvZq+g#ECsOn65&a{4qP!1cZjEbTHZXQ+8- zYraCwb8D4yZF}CFcW=af=YKa&cl6g$-BBwmv#K)U>&nX2 zxuMgy7Q>d~A>N$EBP`?>kmiA$ju%9Kjj|Hp_PvouTQ!Y`PBtnk^=*?i^N8%?`#@Th z6>!#bB?EQQi&aXsF#3o=l_zSO&)7BKY^sMggoPM(e$g%RhgV5%flwh0Vf z7yz@H&*vbao0Y#t4+dxt{0LM-KtFM(PaycdN{Y}5iR({=1iG2aSAhc8?}6o|4@3VC z%wGIoI50pd=bQ#UpX5`OpME=HedL`+N@Tt-@*fjnzOOTMcyEV7J>Dm&@Sk`2db|(+ z_K@#B|IFtn0!u>mdMwH=L7X>`siI{hj8tO#v4qmyeD4Ii{w4j2HfI8W9ie4u@=4e?$Mo$a~m!IXvwY>#Y&0*o$e)@AIGl ze~wZ*QAu4oRmPBuy)sh)fu4eK*o)h$fs_4*_HiIqvSFLNp7T;&eObAB;?07Mzh2te z=PaYTdo2F@RCLFyZh$LTl{{6i7}Z3Mpy#a^MvsHgFGtJk;KeXUAo_U@ER*2A&wuBK z$&^YlX<8!l`rk4iW@YUtxyil3if=rdGYEVVhCj#L%)ajzbV>Y@bm$$OEjA)9hx8S1 z_k$irHi1d0qNat5+qiBZxlZ!06{X5K3DefQIcA=BUZ2RESHuXpR^!@F;Qd%D;q`Q( z?l%^jALB3P&6RQ80*>_}L{>`}AHNOG&8Yb#@H~v0-i_4ZUd41j%}vNepnuQ1D7`_T zYuUH^thizU!kwG#&_`&_DB5A^+m>hYYw7f1Mm;L%@it1WYwk@IhU?iCh-)(iL`jOF zkw_(OCrv5RHWtFJ&Duy2UXyu$Ry))^3rkqwtkJD4X6m7=oJA%J6I2NKCxG6}P^X%m z(dx&GbOA7TKWmufZg)n5s~a7_yp!Vx5Vd>U7s3fXLP^sH#&FpMeGL|e-L$RK&3Sv! z%W6j-AitD!#eD^cadBe_qcn9@)O4+3oz0H~&uMg2N~5|JXj_CE=fga#lacb_3>G5o z#q-FoV58I9=~n|YOx9C>&Md!0Xhu%Kq{0h@J-*EJVUBWIZ0H?&GOJleo0v4_9ODJ; zE8+zpJmYkJMkAC+hASCL7&Vyid*y5%U{7%+3n$dTrr?P=H@6FQr+>Knm`-G%xLiCw z4=)qf!VM>S6ALh_k<=biJV&2V+O~9G%lI3$sK|P^~gV*~2cO2hVERoTu_^}Aqfh}BJhM}4WGgz z2qtOad_aMju|iE>Lw{+{H~ciH0t6`8_U| z4WB_nJ52H}Lei(kBSTmUV+|rT2Xf+CR`IrnUAnY3z!+cyGRw0{DOvuf@@kh=vZ~eJ zCYa$WXQpPFusgSDxIk@rRm1M?w;gP_!I1)v+lT2srUr!*^VD=3?d+LPky;(#dsXb@ z_VDw%fyh=~7Mq1@K+hs9r?edIbZHDv0qyaY-C$#6+{%)wcYirD7C<%so!^8O3FoYl zT=1(Pyg91EZ-STXjg@h{zgLTd&9I{7TY{c|Pe$5a>3qOM+C^%G{IP94AzFo}w8QRY z9XNn&D$`gum661rahhfcJVe$g25@s8=qUsN4i%Xe5{VRxld-!QS0MJg1yyUQ*N|VQ zvlxzz$i4IR4kr<0y+Ef%ej`ScF6N#9s@JQVUUnn*RY{6SAL_Li=(!etBV}c@EI7Bx zNqTUeq(213PNuLxIafN!9%~%6pF7SM*}C*`fjPwQllT=MXfP?}0Q6&o&wLJ}nP2a? zvF=e?;9lo^V~~?$)CROc`$?;=h`f@o?1S*((D^jtVbt)_1(*O8C8I$+cSkpUwR2Ft zQHOexv?p#vZVS|me=7(t|6F4QnIRCSm^M?PlxrioCIYb8K{cIh6_kd(RxwC}yUk!d zB;s#$?^Dp&a*1VJ-0^c6VODLDViLX7A=P>rDf{*eT&h8y!9m{D3%9rUZ_~mfpt-s_ zn>{UMy~>mj6KBtn_jrY>BtN1U-xtaMY7ov**xQN|BXk|R`#OJHC!E$Lft-M8c}(cj zG4m_9iN^UU71L)+o-@gWssaTz~#sto+-uCpp$FrMz>T;}0YS9BdDcjtt#6a%=7tNlz{f8vu*($<;RR zbG)}!(5usuxE{)Yr&Jajjn)wRVlGo(pXNLit^w{W|+N749U4B!kclFmOlOwhO*0uJEj?UT~qz zyx76!rjU)BTA7^fe1F<6!~#AxuoBO=Xp%vjGv*_&>j^foX|O=ssM?u5N=j5sI}iVK z=Qs!4(LHRKKv_6O8|VywjAZ-Vdbhm=(bW3;H@tYrkOYh?$h4v>F|oyxL}or5iPQ3{ z?pRA@)~MG(jjzA3n~s;pp^hh?T;7*c-aqAG8 z_Xq-@qBp$55e8}5Zan%hH(VM-U+w0IwxRVpm_$Nmu#jSO4BGIAvG@>FkD;ghhXv+H zOy~+|-z{>Sfy#XD0;nK5hfs@3S@C@su1m6+#nvsVqFvh6Mg6tq`jOph^QzbscTwoU zpP9>|Kz2ZO`}5ck$ywy_it*NR^*{3t>37${F>4lqwOYbPPtbn7I3y;d+yX!Zp1+z z=6yiB0NRBKyNn|*dSxI;VUV3guC5{4fU0qMVS8+ekhjtj3UKfvu6o~=JS(>XVcW}cZ>L7ssz5lv7^7|(1(XQ z?iPfGd8dJ z5Gtd1>Oesc$S`8&*<_IFDgf>xvG?Y0H^%@oYIkmvjhN3#Mq~)^#t*%V>hRdYVas~( zzCJor>&$n8?_kPBnZ`CH$mgWhw1Exu)f0E&=S~0hGKm*~#upl`W4&5avh3VM-6*xZDg}o0hd({f0m|YCn5I6N z@7x$FnAMbs0c+#r@#<(3n@uxIW1V&0eh5H%`O+%f%#kEIay=TD@PMyRR&N8n;oNRf z_A`=GNeic}rf6=84?3|3cV!FWJ2%B0!kj{-u5hzVEBjDgXUNf(UzvRvk_E>Tj;=b|WM6TTBUycp$uk=Wj+ z`O3|3*lb%-w5~Y?^Mh$%{BHf23Xbmz^i9^cGvgcB2dxC`s)WC5Rrsa)+~j-o?=F$T z^7*=_KsY%4&At<*;@XjcsWQ9iX(Dze2VbWx2d7iYY&~8V{oUcM@D0U|&EGBtLe~LS zEvo|sU)$0ca%@kyECaw#;yfT(8^WE>8sXoEYQMXzt9F`}_L=9E1%2>x8;b+@!EPlC zaotWfGRHFq=M4<2pF3}VGCv%xez6z+X)g^^EzCLJ-+7DqGNGfQVBs@H6g`#jW-xJ= zNXKhh^OYzyn%c>Anfyx^``}}LV)P9J*w##z0j8|Ls9(oX;>O}B^O?-EcHyM_R7cvX z$c)XeANo+j!HMUYUX*)^+fLSFFs}IKuF8cl-It9}`T_d8=7V6litIa4Ta6*?3cWJU z#n0cdfWkUm&!g*ch!wVcoJ@Kg6WOdpnbDSlv~jOzsR8S@yn8|Ni={eOW~OIIsB`)! z6?RDHE0rTR-@HSn4n$E+azeKI#0%1uXA5PkOas5^c0HR<#yQ!2-SfcDX0Pb`ZbCl8 z+B3kv`Pmb1Jmb(96LamHEBf5?EepUNF@v?Q5MZV|>^b|ma`(m+aeMI&(4GUu1$!tk zGOtq@u|AVQeNBN>q}*U(!nk7D6E*>;gac9P)>Erg=UqXe6+BQ`3uD1}Lg*Q{7ZBPL zom9sY>pjTkuD_(0n2%r^>GJ%m?1H?qZN~(;Wh+T}LKIS1=kjOxT*#%nF8qCRcVj#w zwb73P*Cz@i5i#Ob5<5|qYg^wo^C1Q@++MdnYONec|+E>sJa3PUnBaRea{vEofpQt8J~)0kh{*U4)`}HT*-oNHGP-9ay8))m<-{)e34q58eHtpv$=aqGiWLAZazG^kFA-y#$z3;acJXMEC>dN;pOL=S{+0G=+}^%3y9(?kohWHB9PTju zlMxmB>EL_73A<)_;^)s=O_(bucP7|37M+;Su~ya5;)1$9^v%0Y&7ekS=%kFt>2(Jx zwv)9)4~kl}nd68TWRyDh#^Fj=)zx~9Q`yt*s&YqQlEk{%3!as6F(q?L;@&azNR7W@ z;-dn*g}a9^Yd1zUDnY@vL~%AO%FH`Td(IgSJd_{AFBbm5DFEMRhLF z9;5F2h~h7*sQEQ-W(uK*Zt5OV%8Ocl#~yxb%%gS>f_b+@R^2|5;427y5ZM03*H1fH z*(SZ_$8)Nt2|r`_CVT&L2jRlTmOedP)mE`)bb-bAiQZCu;c;cH@&MY$e?jzV5;=v( zLUvXPjCUwrJSn_tR{ClrS8*tOSm$m%aJJcV@2uzjg)CPih}UZLR*LZnAccH*5;i6c zu5O$1Sabx^I~VYo2zWvZAa$ByDESSTl0PFa^a6RMi&}8rU9HC6I|sQ3`A0la6w$Jz zn)gFA9GIE|9~##(etYuO*Zy1v*YnWW+Ce{hUEZpb^ya27)`> zE0`gK`}ZVriTM429GQfz@hIbC< z(l(4~Su_`rIsR6rkGCw#E$kc7X6}@P?aCY&@R!Tg_m;S^EQPJ(sowT7rgq?&UNs9l zHy79rIySRCy2BE+cIgObdesb9UH~I)`jQ1 ztrc)@U32=iLr3n6!-m`-sVf%1NQ>W`;3n4*!S7~ID>Q)EwZlXQDLgV;5iU#epP54A zJmQ(9@&Lwt3&73`7B7N3lD4}qG_!Q02)OnPQ_()U+Q%eDz{2^%>N#rAa~^$PbaxFM z4nAh6wu@Zt>R-4AQR(VWl;@Lb1XTuyi9N#$?N8LLXvY7ZCVTVH@~jY)dGw`}Rh3-% zUN3qAj6KHsUO=XQK1(K~DKz#O^tAc+zAV47VwwrB@p^MNTja5Dm`1 zPy;FicuzoZI@h5I7`w0|wiEdf7<(H6K+KC$A0U>=wMD-Obf?vJ+31S!bJ>aVt?Iqm z6vE#~V^{A11nU$yDGIXe6r6oaZuDMTJK_Te+vVrWcDSy${@LY}kF?(pw|4s;#teAq zHxgE>#ibT_?<^5rsB?bLh)o{;#RzX3cb?Cp!21K;4te2S-LYXeV{R-K`ue*#oBtEe zzG~O|hj;U!jxgn<_;eF<%<-+dpBPVobTV^;!i3<14L~fOS2nKI6_Uc)Nc@X{)mTB5 z*fZD6Xtjvn@M2(CM7jSHLm@2SS_>ID=|~cyTT|jnAcOLwMf~77PWxl*t*$KY%^1Ne zj2T+ZSx=Q1K>H+Q9^D%t%$+O?VxCWQA4>(k3Har?ZSn3Q#SYVQGjWj-tlqfSx1?3i zJ9M6p^uZTGOVF+%`}6&)MGEdT#`y+-E%Tk*=nB#JcmuQ}UJ&uZW1C72(NCh1HvmWs@%6@2AXAc4^>D%S2;wPTLcv5vLx2PBIl2T$HXJF|*fy~gDm}n6iif4C^ma2^AnN7%8 zR&ZWty2=rKV+8b|Up|Gj5$@F7)w3%DI`I4Q@ePwF&2=E&{KIuPK>7PQPI4N}bA--$ z5gMVST%^MG-m7j21~67(tKza~*JbV_m@Ovru=~U#{OKv>%65N{P7&`McePx8?{u83 z-5k7qp`aFzSDaIw9~A&%14O!yg%D(oY_wg85_rH@O8^DZdvi<)P0g{VM_JSBLlEx8-PcAW1E9|yC@*R+g_-nl zui`eflMJ>DiFjI}@jbi!F-lRwt{T%|eis!r& zI0ijQt9~$n05iZ4W(_6E>`I!-_9agP3dc>XO3Pt{ zulz?!U503s36XaSp&n?u!x9>1-#xS=_Fi(Bn9sF{jz*x6ux*m|R|Ffx&JGR4(CCRe z+Ia>UjN7b5R05ZNpI(;bPf!zQsK+|8Pqo$mCIgfw!i-(3`; zX&NWnD@DvUp;a9X@KCH*WlR3Vg(j;3_Hi5KCG~^iu7Jh8gE0lv96ENYED))y4?H^< zIF+kUu@tj!?nJTXbTl&w0x?)kctim$#ISEGd8o+sFWR?(=uKT~7uU9vCBz-w3&|54 zY+0_ImE+Vu7IFYbrO&#+2J~g=gGDV1izKR4@i9kvauZbYlBAA;=HcEWmGB-RuMRo% zUC+Lb+dwIX;fNZNC_`BXj4FzGwV&L2+8LMfFT)9Tx8n|EUy}~n!$IGhO0ise*X;ng zxBWC6Col#GR0nRma9bs`WEkRU+(6&7AbcD>EoC;Q=6*g26{b(*SV7?&d836 zgmlqnxl(v_A)&k%pWp2_9w*SSQ=`FKJu7G{MOr9PL44*Vkz(;PYhN?p}e)se2Ucc>mWu~TeY%f+^l{=44-Pfg-x^h;HD)|c45#zo) zc$%7z6e_JPLv!DWhXIO#QR-GZF_*~ZKC!fZ8|$`;__0S5Ng#t67NUXVqvz09w^n26 zJsHKZcG;&d7))o@+;whO!6GHSxBX%~xPE(>?q<&>z8TPDV8?OGFi;j^U#iU6#Ft1g z=V<2dgt_(2!on5FaJ^I9(ar#kc`$UPPyGujPN;02kX; zl4jKmjw~7n%FYgK1w_iiY3Pr7H#-)`J9m#`x;U*Ee=~hK?dp4hj01ha%1$KUx?<>H z8`WS*3LnnpuxYXrCXhgJTSo!B!8w^=ILd8maOYFJdKf+$*LL_=8FwOJ85k{RmjKFj zSJJgDf8=@Oy%w^U_?pqY<>|=bdu}n}rdsT*DCubRJ!8YmZOcW2n?amSn3KEs^z5OU z23&kemh@)upxTL74oEdA&qbz#tq#}pD- zWTG5(XL&Kki7ffX9@57oXe%~|rkJ%^CMdpthX^Qj5`G-))4JoD#A4&OH0XnHL{NSv zZL}LJX#fn8Dqq8z< zg+Ym@gfolY>d=oZ!?At?r~u(utrJsDG4wet1!h^yL0~9*5oaUXIeDF>UjVc9 zjpq_cYzok9VfvJDaU;;>o-OW;3Os8SVF0N6U&8kl*f<71jojkl$& z%s1m)o}+gs$6`YfqYBhQ$%pGIDYe-h06^>8K#95 zW>83=T*QIa^!0fVv}7#A80=m-b@$o7W@>x=HCzn@a+9wm*-f4?aaAmuwRQD9?M*_EHQ;*Ojdu{qwm>jD6P4(LIQ4p z)Jn{xTEP5qV_yc)0~~TTYi*Su@~(a>={&0;v1}AL)FZQp7By)eT)_a7rM7ysjKLXM zC0Sx9-xI?n^pT^}%DXt%Bw*AH(njZGG&G}Tv3c(Xh%Qdu^e{c^N1l%BCIE=~1DSj8 zLg(=}Svlwf55nIHzPgWBX3>3exFb9ax*0uL3T~$1_s-ooF+I#HJvLVv>#m@CmIs82 z63rZJtSf>4AMP%;lZTxsWI#)cw+dFO0+$?=u!B|tLsM`4Ecyk-qyYM2aSMFvs*@Jjts8b$OG06ln!G`=GRu$E9aM1WFE1`l14O7x zhb!-o^}}Emgjm?aS*QZ>oyF|=sc6@qeEjYPo>P6A~{#(B{|t3X@vU2d)Z=_X-Q#cb?o zaW1tL9HJfPddmPpP`TALhlhRkBEzf~Q(`E_hYq{J{Gyp|3i<@<$g=3;X+%;$3ADg0 zfGOz@obObQ?ZBV6(g&%o=|(J+oCYHkq0I~}?Kh{Zs+h054|Qxk zCue20eIZLG%{}e%SOuy$X4PK7jtQBqZp8*Ujt*(VqWz+w{Pi0JM~2cTIh@rp7FWBE z7I3yitm?$FsS~U1j9Pj9T&(BRnd7$6r1&)KO@M_oe=eI8hNDYJuB#?d$XDwkLNq+v z>(NH1ww(z|_%#OF$IpBQlpDMrrO*E65N(%Mhi@`k9d=sjQ-}0%dj;ibN7uId81)^> z093YSB4ROv&a!J1)BWVpywwtOOafO*BowD_qxW@9yg~yE^c*3GD!LbkSgXM#q};uP1O9vNOi0`OV2!g^s)9L;$Sl=5cWX zL{r(DC3}oRTE}g|bQN4nq{zF6A)>+V5VgOfxKfcI(51%3;k7KyZ)=HSO*|?_TtI^A zrekUVt3azO+<< zR`v9-^?3oOmOlhg5;l~Pqmh-y&<8PUoMe6o)AP)vZ+yKlU+rZt9qMzMiJ`iY3K2K$ zE86gjuvOuA3JaE*09askr2(cKXv!~Ao!Ogc8baaQcy^!Z8>?WaBb04y-)>_L6p5~b zK56SV;%t_{N`3~-+EeE970t7PK$3c7{6CH6DJMHY^oZnBXXt;6<+wyOKqD=2AOUN} zSSHC-`Ojw{i)|LJRIfjX(Mi3Hxf5m@5*mQT{dpQ7`nxyyUhvlEz1||-TioFj)}GN2 z!`(LEN1AOS$nc@parKI#kv6R@HYP%nLR&)SW`A}X2lyD}Me*f0^|@ye7lIUnj?J^_ zC=Ej}ne#4LuZ!yF#eS&Ry3=-g(cOy3oL&NDK38BVCmDzik)&7rEd~cvh;Y-)#5qTpS{Air5cO#D$;WC z-i7k{DeDm-EVA(kC}wK-vi3Q~m(wBYx5I39*Lrzu*IEX_;Z%+7_)3F~DvAfjy^7n* z_1b{*GF?pDJKN5w9fE`o5MR-J5&AA7+_aSxv^W6Y=oeDgXdZjxuJfKMYfK^)z6WgY z%pO-LVg2a77SJ(T#%*Xg0I}LaQ@DDUw>VG!G@y0XO~ItA_pFZj{5n>s0f%_@fr)AE zDu!eBC~bPXk|x!-5gZ#`QOCJdEImFnRkrbi(@D7q$F}&w>`7^KR~Uxo^=gkeZ8%Q& zB#$M?c)>P0Qm7Tj>db--SisJ*@?;kY6C4cec7^7OHwQ&GDo!`#Jv+KSH%Hfv5+D{n z!UH(ZV`2vr3iO+`fIqn&=01)n^2C6yCKtNYxn?Ko-bGbb<@?0c2De5#Mk6;YOkh=w zuww!(yCou1XX8OUn;*tU6}^N3%nzo9+wDAt}6@2^m;f}Xt92NMcy zDunjuqHj>B?^mHwSJ6Un);5juV_`6PGcDFbwm-YIhjG`I>%$_jqYc6@g?b8^I0A#= z&~2Fvz-syqbjiHeV-uNTu*Ij$-Dx)u+^>?`B!?$+Gr(MuE_trC80mip;*@9)aO{A3 z@(gU??!A)4tXo*+CVG|an$P4W0HTozN3*UiQ2dT^4};iY?VrLL3|vXOA72fW94V3F zqpE;6r;eKI|CHzz*A6$GdH81@Ky|&+h~S; z+$s<3+-?Wo$#JGWS}jBFTFfCFP=u5uoUFzmSVyutfyekrfA67}$2iWEAT7z|2%vMo|)m-)$P|DKN>0A5YlUiUV1JbY)#4^V&-WQ;O z@8)`yOz-&&>a-HYGHx-iu1p5$j4L;qkVyf-{U;>qGn8W40Ht5f!>3#i2MJ!3M&^)h zHPDOjseM~uZuiQ_rd_eDZ3OnBp|f>IQ~VmQ2&>XW3ztP*p-L7H4;t6oK|mOnWq*7E zA!{K{SDc56$t$oRGDGj{Q~;(78x7EhqRr#DKD`@7H|kLqlcDc?m(lPr|KvP?Sm0+K z;iM2bsL>s^Mz482jDvOhZamz;<}YD3_~ROzz3t=&2)XQsRC}Tp77$8c2({Sm*j~zJ z=Ws+A-NziW6)^A5gJ23OcuW*Z@tR1wdO z{fme)m~UWs$@x*p6bQdw$vudpa=&invIm38Ya47y?&2K#6*pkC#3N8e2yJVi+=wT^)g!{13W4&U>{^trV#m&3wtnuuC2CXK$u=U( zd?U)-sT>Fl$!0s$D4blOLZQn1^fEJE%PvfI^YkI4ov1rf@#tOz3J6SgUyXmC@>7ul z)KjasT63hn8|`-Ij6AksPd5180}m!&)bm~#dhC@5UpY8dG5T(Mfj}TbHL@5i-Tfw{ zh-sn3?_Sd`F9kh!FDFL`@x_B37tji@otRO1npuiUGYL9#4X8Dlc|&Srn&_~cca~l4 zbNY2^k|{T7U-G=MGSQydcW-np(v&Y9eJ~1=i6yw13{x8QDFD$^d#RuV3UiFR&e<0? z)NQ~pkj*qiGTIXIE$S9J=%F1iSH$p1mY4joz$WQ`gRG5B&T);;zq{p@U-iN(Yj+WV zn|)!D?e%(1tW$|I=WL?>3NbIAc3?u?Qy91bx5*;iE3+`l0GeZ*j)mH!vigZoVO!Hs zFb^#&>ORLlO)9n(9e5BHLbcgk#5?vM9B5&7wV`{iF(Pm>!t}F`fUaZ9Tje)n2O2ti zJZz`q_s%#{IButoxoCrYcGyZW(*w7ftcv1}rjGQGKoWsIZwJsM6G9RZ1@$(ni+zm= zM1?WRi9Jo{BntJoVu~vwf#e_eJ~%GY`rIuIn)(o7f*b-Yn}GxI&gxsaj@G_lerz{p zziJ1%0dFIfP6*)cP-j_(HMjN_K*Jn4Mn}4S4*9K5l&V46+5a&u>qgd?`~ zHk?Ao6`G*O6oeCJ z$dPy_)QOt(-l_%??F9iO_f-(UW1id{<^W`Sgg9@Z6ESy$S@9NN+5+Y2I1K4Hts6|# zBj2FEkqKQ^`;=I4q-!F760lCGx@{K@xI({939QkS`#?0HlnTa$v-l5#;uJ-A40O*G zq?nk^@i4B#XK13`SE+@~49K6S+_o-$sDns{pj>KOoz%mD-r9GejLm+~2;%|4-oy5| z9-@^$I>W3ag8&N1AgcCk62#~1$nrV_-v*^!?+Ld7tAv3n&osE%^v~<$k#~%!Z#VKSX5<+7j4?&2w*eS5u9y-K!BKsU@^W8316xJ`~jE+NT=|6;a}&JhB4 z0#5FJ;*#=z+9$&3Mq;(5&}Rt_-~04~;2`(4#E&X>N}*)8>)x@Z_l zop%`r;P=ubfLe*}S!Z8VN6hefh!&3JX?T$&i}YlFPns=7Iki#ZlTIq%FJ(BL&?JE6 zWsy(3xcEs^#)ztj3D9Bu#070N)>&RqA|mxUrwz;EOOZ629j9`X4g7kaUkZNN5x!}! zTFw0sM4EQ+z3>XFId8Z5c&+baQ&ovUUa~l=GfU<%#rNB@txUHWq!JjBu2aWT}VbZ!P?o?c;W6n)bt_$8}z9Bd%&<9)y5o`zKCF*&qGLTW+u|Kfds4bGdDm$PU^td8BSiYWY_e z3@rugP&Tw8gk_sj=5oWfRAJGWWs?_Cr5L@oh?SJJQLperotbU`nkgS)X;?kKa~zHj zgZ1G9&$GGO(G1WZT&`ulPsT;r;JIfXIB`MUw)64+h9pK_X(suXU}=&8 z?bP>qnqZWmQrPr;Ag?_7M`|b#4l5*>K?7E|7Az5M6>5Nm`sE`*-wufSh?GfvS(Rm7 zAwIos-SzBfjSJILP&v1n6bf6Upwsc*9OQDL;Ev_IW*jYtSMlIz>4jEs>p^leUI6Q_73#hv z8>dn2EO$IQ+K_8?I~ek7#CeZ-2xHSNz@O`=V;ts>iUVPjGKfzT1KYgAtR;b8oU6e9 zaALy&pY$@^NPUNWcv*tQR_H=Awcg6Hr1v_7g&vNgMASdaxvbv-%pEGjMiB1tEk!`dPl1P=A?912&H?gadAcz$yLs(-jpzI*wtT#W#A@3K!#8`^Usn(Lu$n<=r23_N z?L-H9b8JbU1pU?hRXJ?W4sznTIZr(OZGl6`eH;dNU1Wpf*DiY|wS3)M2;H0Jr;7J# z4-t=SN6t)g&hp+pIf@BJgL$LIAi{`&Tt$=2pW z@B4i5x#rUE^R}fmx}p{L8=vC9?xqFJPnV2z*#}2KnZ$ zzUjeK8?-}IJE@_7zUBBP{Nnj~T*vsZ(iHNZ0txRK2k}J?@{{p_*mDYs*rwIwhJLPNkO=6JU) zbazcE-y>%Jnb9tvYlQcRwS-%%r-XLqq+jSOq#E&=kvfyBCG@S5R_q6DHt73T%KXA9 zsO~!*?EB}<%Q4vZqVs(w`iIq-pr5SHNspw?|815|+Vnluy;{?do#9Q*D(t<-oZ(j( zX_X!_{?YxPp$~W&&7LFi$z$uR*XNZNH{`VKfgL?3;v=X2sgKZLoNpE}Lte6r$sVy4 zzn0wrKbgX`X{ne=y{f2h(jU2^47pM0M>X}4-*7=a(zRbyUVeWI(xxRq@6{xRdd%oP z2BhyCaF{70_r$;5zi&pqq2;B3K~Mky03d!Y0)S^o>RK#7000ai0069?CpIR|2F3=? z26RStjwbSscJ?Me8#zs!Xx(kBW8wwmg6PphuRkJ--N=({GQd^@8WKrK4Vkwx?qXQx z<{DL+{p`YkORje6JaVtcmal1+ycYA}Yh|C>2Q?B5K{Ov?7HlGN&t$w~;_tQDI)BKM zUI5?Z^ ztSga;1xASRfC%krdUWD*bN^*g{cOJqWQS6)lzlb5wwH&QoPA~4R_QKldt(Vpdp3!7 zpE>TdU`my`$I#?27aM+SJDF|F^2nOrPZdJq*~6S5E&+H@gg-5j*W=UWsjV0*}9C)bK(|jLq8N z<#C-2HvzF5-&P%0u{AKP_q=Ns!KpsA4)_-juAVN(1n8(gbTDu(gHy9o%mX|Q zl5Y_L!>_1xmGHaX62-kt1P!?pf)?EI2Z+-YEu7BqJUe@lS+`7G>UV9HXbGHB{A7pN zQhZS}mL$*g)?ay#&W0a z$MqmZMDdY}sJn#-=f<%tMo z^bm3zIy1BUJ~;?<7aPLK;;gU+H|UpAf;_j;P_Q@#T5!oA%)Zgzm>45}Un%~KW3-F2 zjB(9G-)4Qijqn71YVWWLh*wrzX$^a*)+-{B=Mj7Swfi$3l`%?9S*hqC`tFz>*W7QSw$0T69Xp`30qUUf2r#tI|dg>kI;4hi|Dz&vGn%> zCf(K#7dla&Vtj2nYD_L2kyNL<*ZtD&x|>d)l!a2`-{B{mX|TmnR;mndquf|8q%|#r zTTlXfTy1&g7S&~ouvRg9@s9VR#iD>T&mOhm(9Mn8l53+XY6GKeV_n;X7B?k1F%B5t~fl;{XF)z!*sfI%9L(R=Z*X zt+DF<6-*Wm&)f5O@=}05PUC-E$?7mqDa()YRlooM$Ug@7*YQ*Q??X$-&i1F1o%NJG z>`k0>{-yap0oooocgTNg;DP`EK>v5O{{k@mx#>BYSUb_t{_FRj6}=)ZE=S=20E$Ha zDY@mRg*FDx)&_=j#&$+7Ha`vc-y{c#oA1QlfB|gWLjoZFo8;P`;(r6!xj5Uq{IAvj z=|um9@LvtL0RsO|F7=;^{L^#%4^SWQ{{!^D`H_D@{d4a957aowe}MY8nfOo4e-82g g!E6Ej519WL@bXfiVE?KK@pH2O^iMMw_)qEo0O3t$e*gdg From 58de3aa3a727754b0b902834b1dde2bf1dcbe6d9 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Mon, 30 Jun 2025 10:39:54 +0200 Subject: [PATCH 37/65] Updated behavior tutorial --- .../_static/html/tutorials/behavior.html | 54 +++++++++--------- tutorials/behavior.mlx | Bin 8482 -> 8466 bytes tutorials/private/mcode/behavior.m | 48 ++++++++-------- 3 files changed, 51 insertions(+), 51 deletions(-) diff --git a/docs/source/_static/html/tutorials/behavior.html b/docs/source/_static/html/tutorials/behavior.html index 3b5edf616..45d0d6deb 100644 --- a/docs/source/_static/html/tutorials/behavior.html +++ b/docs/source/_static/html/tutorials/behavior.html @@ -34,7 +34,7 @@ .S7 { margin: 3px 10px 5px 4px; padding: 0px; line-height: 20px; min-height: 0px; white-space: pre-wrap; color: rgb(33, 33, 33); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 20px; font-weight: 700; text-align: left; } .S8 { border-left: 1px solid rgb(217, 217, 217); border-right: 1px solid rgb(217, 217, 217); border-top: 1px solid rgb(217, 217, 217); border-bottom: 1px solid rgb(217, 217, 217); border-radius: 4px; padding: 6px 45px 4px 13px; line-height: 18.004px; min-height: 0px; white-space: nowrap; color: rgb(33, 33, 33); font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px; } .S9 { border-left: 1px solid rgb(217, 217, 217); border-right: 1px solid rgb(217, 217, 217); border-top: 0px none rgb(33, 33, 33); border-bottom: 1px solid rgb(217, 217, 217); border-radius: 0px 0px 4px 4px; padding: 0px 45px 4px 13px; line-height: 18.004px; min-height: 0px; white-space: nowrap; color: rgb(33, 33, 33); font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px; } -.S10 { margin: 15px 10px 5px 4px; padding: 0px; line-height: 18px; min-height: 0px; white-space: pre-wrap; color: rgb(33, 33, 33); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 17px; font-weight: 700; text-align: left; }

Behavior Data

Creating an NWB File

NwbFile with properties: +.S10 { margin: 15px 10px 5px 4px; padding: 0px; line-height: 18px; min-height: 0px; white-space: pre-wrap; color: rgb(33, 33, 33); font-family: Helvetica, Arial, sans-serif; font-style: normal; font-size: 17px; font-weight: 700; text-align: left; }

Behavior Data

This tutorial will guide you in writing behavioral data to NWB.

Creating an NWB File

Create an NWBFile object with the required fields (session_description, identifier, and session_start_time) and additional metadata.
nwb = NwbFile( ...
'session_description', 'mouse in open exploration',...
'identifier', 'Mouse5_Day3', ...
'session_start_time', datetime(2018, 4, 25, 2, 30, 3, 'TimeZone', 'local'), ...
'general_experimenter', 'My Name', ... % optional
'general_session_id', 'session_1234', ... % optional
'general_institution', 'University of My Institution', ... % optional
'general_related_publications', 'DOI:10.1016/j.neuron.2016.12.011'); % optional
nwb
nwb =
NwbFile with properties: nwb_version: '2.8.0' file_create_date: [] @@ -88,7 +88,7 @@ units: [] Warning: The following required properties are missing for instance for type "NwbFile": - timestamps_reference_time

SpatialSeries: Storing continuous spatial data

SpatialSeries is a subclass of TimeSeries that represents data in space, such as the spatial direction e.g., of gaze or travel or position of an animal over time.
Create data that corresponds to x, y position over time.
position_data = [linspace(0, 10, 50); linspace(0, 8, 50)]; % 2 x nT array
In SpatialSeries data, the first dimension is always time (in seconds), the second dimension represents the x, y position. However, as described in the dimensionMapNoDataPipes tutorial, when a MATLAB array is exported to HDF5, the array is transposed. Therefore, in order to correctly export the data, in MATLAB the last dimension of an array should be time. SpatialSeries data should be stored as one continuous stream as it is acquired, not by trials as is often reshaped for analysis. Data can be trial-aligned on-the-fly using the trials table. See the trials tutorial for further information.
For position data reference_frame indicates the zero-position, e.g. the 0,0 point might be the bottom-left corner of an enclosure, as viewed from the tracking camera.
timestamps = linspace(0, 50, 50)/ 200;
position_spatial_series = types.core.SpatialSeries( ...
'description', 'Postion (x, y) in an open field.', ...
'data', position_data, ...
'timestamps', timestamps, ...
'reference_frame', '(0,0) is the bottom left corner.' ...
)
position_spatial_series =
SpatialSeries with properties: + timestamps_reference_time

SpatialSeries: Storing continuous spatial data

SpatialSeries is a subclass of TimeSeries that represents data in space, such as the spatial direction e.g., of gaze or travel or position of an animal over time.
Create data that corresponds to x, y position over time.
position_data = [linspace(0, 10, 50); linspace(0, 8, 50)]; % 2 x nT array
In SpatialSeries data, the first dimension is always time (in seconds), the second dimension represents the x, y position. However, as described in the dimensionMapNoDataPipes tutorial, when a MATLAB array is exported to HDF5, the array is transposed. Therefore, in order to correctly export the data, in MATLAB the last dimension of an array should be time. SpatialSeries data should be stored as one continuous stream as it is acquired, not by trials as is often reshaped for analysis. Data can be trial-aligned on-the-fly using the trials table. See the trials tutorial for further information.
For position data reference_frame indicates the zero-position, e.g. the 0,0 point might be the bottom-left corner of an enclosure, as viewed from the tracking camera.
timestamps = linspace(0, 50, 50)/ 200;
position_spatial_series = types.core.SpatialSeries( ...
'description', 'Postion (x, y) in an open field.', ...
'data', position_data, ...
'timestamps', timestamps, ...
'reference_frame', '(0,0) is the bottom left corner.' ...
)
position_spatial_series =
SpatialSeries with properties: reference_frame: '(0,0) is the bottom left corner.' starting_time_unit: 'seconds' @@ -107,7 +107,7 @@ starting_time: [] starting_time_rate: [] timestamps: [0 0.0051 0.0102 0.0153 0.0204 0.0255 0.0306 0.0357 0.0408 0.0459 0.0510 0.0561 0.0612 0.0663 0.0714 0.0765 0.0816 0.0867 0.0918 0.0969 0.1020 0.1071 0.1122 0.1173 0.1224 0.1276 0.1327 0.1378 0.1429 0.1480 0.1531 … ] (1×50 double) -

Position: Storing position measured over time

To help data analysis and visualization tools know that this SpatialSeries object represents the position of the subject, store the SpatialSeries object inside a Position object, which can hold one or more SpatialSeries objects.
position = types.core.Position();
position.spatialseries.set('SpatialSeries', position_spatial_series);

Create a Behavior Processing Module

Create a processing module called "behavior" for storing behavioral data in the NWBFile, then add the Position object to the processing module.
behavior_processing_module = types.core.ProcessingModule('description', 'stores behavioral data.');
behavior_processing_module.nwbdatainterface.set("Position", position);
nwb.processing.set("behavior", behavior_processing_module);

CompassDirection: Storing view angle measured over time

Analogous to how position can be stored, we can create a SpatialSeries object for representing the view angle of the subject.
For direction data reference_frame indicates the zero direction, for instance in this case "straight ahead" is 0 radians.
view_angle_data = linspace(0, 4, 50);
direction_spatial_series = types.core.SpatialSeries( ...
'description', 'View angle of the subject measured in radians.', ...
'data', view_angle_data, ...
'timestamps', timestamps, ...
'reference_frame', 'straight ahead', ...
'data_unit', 'radians' ...
);
direction = types.core.CompassDirection();
direction.spatialseries.set('spatial_series', direction_spatial_series);
We can add a CompassDirection object to the behavior processing module the same way we have added the position data.
%behavior_processing_module = types.core.ProcessingModule("stores behavioral data."); % if you have not already created it
behavior_processing_module.nwbdatainterface.set('CompassDirection', direction);
%nwb.processing.set('behavior', behavior_processing_module); % if you have not already added it

BehaviorTimeSeries: Storing continuous behavior data

BehavioralTimeSeries is an interface for storing continuous behavior data, such as the speed of a subject.
speed_data = linspace(0, 0.4, 50);
 
speed_time_series = types.core.TimeSeries( ...
'data', speed_data, ...
'starting_time', 1.0, ... % NB: Important to set starting_time when using starting_time_rate
'starting_time_rate', 10.0, ... % Hz
'description', 'he speed of the subject measured over time.', ...
'data_unit', 'm/s' ...
);
 
behavioral_time_series = types.core.BehavioralTimeSeries();
behavioral_time_series.timeseries.set('speed', speed_time_series);
 
%behavior_processing_module = types.core.ProcessingModule("stores behavioral data."); % if you have not already created it
behavior_processing_module.nwbdatainterface.set('BehavioralTimeSeries', behavioral_time_series);
%nwb.processing.set('behavior', behavior_processing_module); % if you have not already added it

BehavioralEvents: Storing behavioral events

BehavioralEvents is an interface for storing behavioral events. We can use it for storing the timing and amount of rewards (e.g. water amount) or lever press times.
reward_amount = [1.0, 1.5, 1.0, 1.5];
event_timestamps = [1.0, 2.0, 5.0, 6.0];
 
time_series = types.core.TimeSeries( ...
'data', reward_amount, ...
'timestamps', event_timestamps, ...
'description', 'The water amount the subject received as a reward.', ...
'data_unit', 'ml' ...
);
 
behavioral_events = types.core.BehavioralEvents();
behavioral_events.timeseries.set('lever_presses', time_series);
 
%behavior_processing_module = types.core.ProcessingModule("stores behavioral data."); % if you have not already created it
behavior_processing_module.nwbdatainterface.set('BehavioralEvents', behavioral_events);
%nwb.processing.set('behavior', behavior_processing_module); % if you have not already added it
Storing only the timestamps of the events is possible with the ndx-events NWB extension. You can also add labels associated with the events with this extension. You can find information about installation and example usage here.

BehavioralEpochs: Storing intervals of behavior data

BehavioralEpochs is for storing intervals of behavior data. BehavioralEpochs uses IntervalSeries to represent the time intervals. Create an IntervalSeries object that represents the time intervals when the animal was running. IntervalSeries uses 1 to indicate the beginning of an interval and -1 to indicate the end.
run_intervals = types.core.IntervalSeries( ...
'description', 'Intervals when the animal was running.', ...
'data', [1, -1, 1, -1, 1, -1], ...
'timestamps', [0.5, 1.5, 3.5, 4.0, 7.0, 7.3] ...
);
 
behavioral_epochs = types.core.BehavioralEpochs();
behavioral_epochs.intervalseries.set('running', run_intervals);
You can add more than one IntervalSeries to a BehavioralEpochs object.
sleep_intervals = types.core.IntervalSeries( ...
'description', 'Intervals when the animal was sleeping', ...
'data', [1, -1, 1, -1], ...
'timestamps', [15.0, 30.0, 60.0, 95.0] ...
);
behavioral_epochs.intervalseries.set('sleeping', sleep_intervals);
 
% behavior_processing_module = types.core.ProcessingModule("stores behavioral data.");
% behavior_processing_module.nwbdatainterface.set('BehavioralEvents', behavioral_events);
% nwb.processing.set('behavior', behavior_processing_module);

Another approach: TimeIntervals

Using TimeIntervals to represent time intervals is often preferred over BehavioralEpochs and IntervalSeries. TimeIntervals is a subclass of DynamicTable, which offers flexibility for tabular data by allowing the addition of optional columns which are not defined in the standard DynamicTable class.
sleep_intervals = types.core.TimeIntervals( ...
'description', 'Intervals when the animal was sleeping.', ...
'colnames', {'start_time', 'stop_time', 'stage'} ...
);
 
sleep_intervals.addRow('start_time', 0.3, 'stop_time', 0.35, 'stage', 1);
sleep_intervals.addRow('start_time', 0.7, 'stop_time', 0.9, 'stage', 2);
sleep_intervals.addRow('start_time', 1.3, 'stop_time', 3.0, 'stage', 3);
 
nwb.intervals.set('sleep_intervals', sleep_intervals);

EyeTracking: Storing continuous eye-tracking data of gaze direction

EyeTracking is for storing eye-tracking data which represents direction of gaze as measured by an eye tracking algorithm. An EyeTracking object holds one or more SpatialSeries objects that represent the gaze direction over time extracted from a video.
eye_position_data = [linspace(-20, 30, 50); linspace(30, -20, 50)];
 
right_eye_position = types.core.SpatialSeries( ...
'description', 'The position of the right eye measured in degrees.', ...
'data', eye_position_data, ...
'starting_time', 1.0, ... % NB: Important to set starting_time when using starting_time_rate
'starting_time_rate', 50.0, ... % Hz
'reference_frame', '(0,0) is middle', ...
'data_unit', 'degrees' ...
);
 
left_eye_position = types.core.SpatialSeries( ...
'description', 'The position of the right eye measured in degrees.', ...
'data', eye_position_data, ...
'starting_time', 1.0, ... % NB: Important to set starting_time when using starting_time_rate
'starting_time_rate', 50.0, ... % Hz
'reference_frame', '(0,0) is middle', ...
'data_unit', 'degrees' ...
);
 
eye_tracking = types.core.EyeTracking();
eye_tracking.spatialseries.set('right_eye_position', right_eye_position);
eye_tracking.spatialseries.set('left_eye_position', left_eye_position);
 
% behavior_processing_module = types.core.ProcessingModule("stores behavioral data.");
behavior_processing_module.nwbdatainterface.set('EyeTracking', eye_tracking);
% nwb.processing.set('behavior', behavior_processing_module);

PupilTracking: Storing continuous eye-tracking data of pupil size

PupilTracking is for storing eye-tracking data which represents pupil size. PupilTracking holds one or more TimeSeries objects that can represent different features such as the dilation of the pupil measured over time by a pupil tracking algorithm.
pupil_diameter = types.core.TimeSeries( ...
'description', 'Pupil diameter extracted from the video of the right eye.', ...
'data', linspace(0.001, 0.002, 50), ...
'starting_time', 1.0, ... % NB: Important to set starting_time when using starting_time_rate
'starting_time_rate', 20.0, ... % Hz
'data_unit', 'meters' ...
);
 
pupil_tracking = types.core.PupilTracking();
pupil_tracking.timeseries.set('pupil_diameter', pupil_diameter);
 
% behavior_processing_module = types.core.ProcessingModule("stores behavioral data.");
behavior_processing_module.nwbdatainterface.set('PupilTracking', pupil_tracking);
% nwb.processing.set('behavior', behavior_processing_module);

Writing the behavior data to an NWB file

All of the above commands build an NWBFile object in-memory. To write this file, use nwbExport.
% Save to tutorials/tutorial_nwb_files folder
nwbFilePath = misc.getTutorialNwbFilePath('behavior_tutorial.nwb');
nwbExport(nwb, nwbFilePath);
fprintf('Exported NWB file to "%s"\n', 'behavior_tutorial.nwb')
Exported NWB file to "behavior_tutorial.nwb"
+

Position: Storing position measured over time

To help data analysis and visualization tools know that this SpatialSeries object represents the position of the subject, store the SpatialSeries object inside a Position object, which can hold one or more SpatialSeries objects.
position = types.core.Position();
position.add('SpatialSeries', position_spatial_series);

Create a Behavior Processing Module

Create a processing module called "behavior" for storing behavioral data in the NWBFile, then add the Position object to the processing module.
behavior_processing_module = types.core.ProcessingModule('description', 'stores behavioral data.');
behavior_processing_module.add("Position", position);
nwb.processing.add("behavior", behavior_processing_module);

CompassDirection: Storing view angle measured over time

Analogous to how position can be stored, we can create a SpatialSeries object for representing the view angle of the subject.
For direction data reference_frame indicates the zero direction, for instance in this case "straight ahead" is 0 radians.
view_angle_data = linspace(0, 4, 50);
direction_spatial_series = types.core.SpatialSeries( ...
'description', 'View angle of the subject measured in radians.', ...
'data', view_angle_data, ...
'timestamps', timestamps, ...
'reference_frame', 'straight ahead', ...
'data_unit', 'radians' ...
);
direction = types.core.CompassDirection();
direction.add('spatial_series', direction_spatial_series);
We can add a CompassDirection object to the behavior processing module the same way we have added the position data.
%behavior_processing_module = types.core.ProcessingModule("stores behavioral data."); % if you have not already created it
behavior_processing_module.add('CompassDirection', direction);
%nwb.processing.add('behavior', behavior_processing_module); % if you have not already added it

BehaviorTimeSeries: Storing continuous behavior data

BehavioralTimeSeries is an interface for storing continuous behavior data, such as the speed of a subject.
speed_data = linspace(0, 0.4, 50);
 
speed_time_series = types.core.TimeSeries( ...
'data', speed_data, ...
'starting_time', 1.0, ... % NB: Important to set starting_time when using starting_time_rate
'starting_time_rate', 10.0, ... % Hz
'description', 'he speed of the subject measured over time.', ...
'data_unit', 'm/s' ...
);
 
behavioral_time_series = types.core.BehavioralTimeSeries();
behavioral_time_series.add('speed', speed_time_series);
 
%behavior_processing_module = types.core.ProcessingModule("stores behavioral data."); % if you have not already created it
behavior_processing_module.add('BehavioralTimeSeries', behavioral_time_series);
%nwb.processing.add('behavior', behavior_processing_module); % if you have not already added it

BehavioralEvents: Storing behavioral events

BehavioralEvents is an interface for storing behavioral events. We can use it for storing the timing and amount of rewards (e.g. water amount) or lever press times.
reward_amount = [1.0, 1.5, 1.0, 1.5];
event_timestamps = [1.0, 2.0, 5.0, 6.0];
 
time_series = types.core.TimeSeries( ...
'data', reward_amount, ...
'timestamps', event_timestamps, ...
'description', 'The water amount the subject received as a reward.', ...
'data_unit', 'ml' ...
);
 
behavioral_events = types.core.BehavioralEvents();
behavioral_events.add('lever_presses', time_series);
 
%behavior_processing_module = types.core.ProcessingModule("stores behavioral data."); % if you have not already created it
behavior_processing_module.add('BehavioralEvents', behavioral_events);
%nwb.processing.add('behavior', behavior_processing_module); % if you have not already added it
Storing only the timestamps of the events is possible with the ndx-events NWB extension. You can also add labels associated with the events with this extension. You can find information about installation and example usage here.

BehavioralEpochs: Storing intervals of behavior data

BehavioralEpochs is for storing intervals of behavior data. BehavioralEpochs uses IntervalSeries to represent the time intervals. Create an IntervalSeries object that represents the time intervals when the animal was running. IntervalSeries uses 1 to indicate the beginning of an interval and -1 to indicate the end.
run_intervals = types.core.IntervalSeries( ...
'description', 'Intervals when the animal was running.', ...
'data', [1, -1, 1, -1, 1, -1], ...
'timestamps', [0.5, 1.5, 3.5, 4.0, 7.0, 7.3] ...
);
 
behavioral_epochs = types.core.BehavioralEpochs();
behavioral_epochs.add('running', run_intervals);
You can add more than one IntervalSeries to a BehavioralEpochs object.
sleep_intervals = types.core.IntervalSeries( ...
'description', 'Intervals when the animal was sleeping', ...
'data', [1, -1, 1, -1], ...
'timestamps', [15.0, 30.0, 60.0, 95.0] ...
);
behavioral_epochs.add('sleeping', sleep_intervals);
 
% behavior_processing_module = types.core.ProcessingModule("stores behavioral data.");
% behavior_processing_module.add('BehavioralEvents', behavioral_events);
% nwb.processing.add('behavior', behavior_processing_module);

Another approach: TimeIntervals

Using TimeIntervals to represent time intervals is often preferred over BehavioralEpochs and IntervalSeries. TimeIntervals is a subclass of DynamicTable, which offers flexibility for tabular data by allowing the addition of optional columns which are not defined in the standard DynamicTable class.
sleep_intervals = types.core.TimeIntervals( ...
'description', 'Intervals when the animal was sleeping.', ...
'colnames', {'start_time', 'stop_time', 'stage'} ...
);
 
sleep_intervals.addRow('start_time', 0.3, 'stop_time', 0.35, 'stage', 1);
sleep_intervals.addRow('start_time', 0.7, 'stop_time', 0.9, 'stage', 2);
sleep_intervals.addRow('start_time', 1.3, 'stop_time', 3.0, 'stage', 3);
 
nwb.intervals.add('sleep_intervals', sleep_intervals);

EyeTracking: Storing continuous eye-tracking data of gaze direction

EyeTracking is for storing eye-tracking data which represents direction of gaze as measured by an eye tracking algorithm. An EyeTracking object holds one or more SpatialSeries objects that represent the gaze direction over time extracted from a video.
eye_position_data = [linspace(-20, 30, 50); linspace(30, -20, 50)];
 
right_eye_position = types.core.SpatialSeries( ...
'description', 'The position of the right eye measured in degrees.', ...
'data', eye_position_data, ...
'starting_time', 1.0, ... % NB: Important to set starting_time when using starting_time_rate
'starting_time_rate', 50.0, ... % Hz
'reference_frame', '(0,0) is middle', ...
'data_unit', 'degrees' ...
);
 
left_eye_position = types.core.SpatialSeries( ...
'description', 'The position of the right eye measured in degrees.', ...
'data', eye_position_data, ...
'starting_time', 1.0, ... % NB: Important to set starting_time when using starting_time_rate
'starting_time_rate', 50.0, ... % Hz
'reference_frame', '(0,0) is middle', ...
'data_unit', 'degrees' ...
);
 
eye_tracking = types.core.EyeTracking();
eye_tracking.add('right_eye_position', right_eye_position);
eye_tracking.add('left_eye_position', left_eye_position);
 
% behavior_processing_module = types.core.ProcessingModule("stores behavioral data.");
behavior_processing_module.add('EyeTracking', eye_tracking);
% nwb.processing.add('behavior', behavior_processing_module);

PupilTracking: Storing continuous eye-tracking data of pupil size

PupilTracking is for storing eye-tracking data which represents pupil size. PupilTracking holds one or more TimeSeries objects that can represent different features such as the dilation of the pupil measured over time by a pupil tracking algorithm.
pupil_diameter = types.core.TimeSeries( ...
'description', 'Pupil diameter extracted from the video of the right eye.', ...
'data', linspace(0.001, 0.002, 50), ...
'starting_time', 1.0, ... % NB: Important to set starting_time when using starting_time_rate
'starting_time_rate', 20.0, ... % Hz
'data_unit', 'meters' ...
);
 
pupil_tracking = types.core.PupilTracking();
pupil_tracking.add('pupil_diameter', pupil_diameter);
 
% behavior_processing_module = types.core.ProcessingModule("stores behavioral data.");
behavior_processing_module.add('PupilTracking', pupil_tracking);
% nwb.processing.add('behavior', behavior_processing_module);

Writing the behavior data to an NWB file

All of the above commands build an NWBFile object in-memory. To write this file, use nwbExport.
% Save to tutorials/tutorial_nwb_files folder
nwbFilePath = misc.getTutorialNwbFilePath('behavior_tutorial.nwb');
nwbExport(nwb, nwbFilePath);
fprintf('Exported NWB file to "%s"\n', 'behavior_tutorial.nwb')
Exported NWB file to "behavior_tutorial.nwb"

-
- \ No newline at end of file +
+ + \ No newline at end of file diff --git a/tutorials/behavior.mlx b/tutorials/behavior.mlx index b98cdf231b709c129db1c8bab60b7899d06aa144..5bced949ce14368f9fc6fb121d4c77da067e8921 100644 GIT binary patch delta 7197 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 FzW_u4YtaAz delta 4953 zcmZ9QbyU>dx5j4}x|Eg}n4ysx8l*!&x~022Bn7^t4jm)XptK?&2n;ZEcPL6qOG-#c ziCo_Mu62L+-hI~D=j^@L^UrhsI-ddgb$&oc9fC~>0)g=FHXL--EziaR27z25AP~h} z$4t@7^O=L^Gb@8&ZwEgMz90|x2GodFj~wyi^UL@tcU{3)90g7n8Yx!M`)`lIj%%X2 zTcxz;XXoM`TvYCQ*qGYTu!DwDE)IIPUP8Ow*2)bBfpo0=-N6cd^~zD)ar1DKeT^Vxp;M>CMb{j0*N6cuQ}s`&AijpY=KHPlx~R%(1`(&>%fzRa-r zHR%7kY7(I9PIu>O{++8tcdlCbI=K7s^Zk>7eAJj$4}v)2Ff5+)Tx3s_T~0F)>z!Ck zKP0Qytx`l*4QpYkKtrK;wfv!^aa9kV*&S=rYgOmn@ z2dPgkbDH7NMznB(*VF0xPe-ECd7E${daw zajg+BOUkjBWQiA}ptNI*8ZbQ^6-gHkEKY}9AUCgQ#)cAZX6T&=07sN`CeNk5;cxK& zbA0>MmC6Ik?shu4BQ`QHMoE+L&+u=|`=&Vgsk4zq`8eP<($`zLhM9u+R{ zlqfoVo8q1L!Rp`ZvD6T_1DB5_!*jIRn`BlM7Y+Bz6CZHu=!FPy!=yB+0x{zpU zn_7M>Ms01=4$Ib^u;r_rzLbP@xeJ$G+sALhcv5IMsIYF@-Di2+lvSGpizPK9xD>x2)|H5I3HLwiomX47@rfpT8 zQ9Ytdm}aU*V8*%XwUP$@>CJdE04#Lpgq%S6}I-U!t zQ;7q-}<)R923Qkk7>iC$Du6`n~h zCGPy@4Zx0xSuM^V&Ka3)R|8F5tE8$me^T~bBX>H zRj93kfdan?a(Pq1^=BVuMa*TCCCDJch61}{VeQCbv4KFo#dWTG5??4UG~T5P>EMb!bA1CxKEocK2z-BZZCaUPeM(>Q$2JdfE$iqTO_3PC?7= zMfm|eF*&Bn2fOWgQxcA9D{P!fX6i$wf@8h z5oD^*DBWrfGoyR1k??XKA_D8C0eG-dp$vu18#}zCB(kIWu($3O@*A6Vnll|g^k?Sy zp+zduZ@vT=qi-_y_|6Ltk%~i4SD(}p`2vh(q=TU5) z@2XJ&E%-2AGlQ${cA&Um$(^ZFDJ&U8xb-2lv!3VKd-a^SgXE-mXRT7HkxcxNm3sgR z8^5JY?%JoPLmzq3OZml6r#`<)j#8Ts__xQ43pr23 zuor_YEvlssZEY>;X1+%Cc<>V16R#)^uj&t}sw;$iK)J{Ff9=lmlp{w7(Rsl*JBR3Y zhK6b0?uTB!Gl^Q_76*_9mrR;hx^#eyDl3zZ=9>BHW&68N+()iJvG68gt^=`2Ts<4j z)BA?6_GUFTy?+dop&jX!S_QV-GyHEHKi(@&g@W4OhaN_U8JY$npZIo|QCzz0<4Us- zwJ70Xk6NhW(UPkWURq}i2f|^I>g*+w+rXN-6@#RzD z>8GQKTtBAb@^V&|(uPF0&TjOK*d6nA=d;nd8Ki2EmAB0;2wqc+C+T9f=zfW8Pi`X~ z_FM|DIxBA+b!&5Jj{d&ASkw;e&Hf%PDK&}lSNm3*PJcePcnB_!MOH1$?ojyBVVAt! zE5kl2GkaWuEeB8=7RK#SF zU7pt;BAK94_KniEShXYqWQ`;+n`BKbDL$X1hNZJ&Fe#OJ@Pic!jXXfZuoIX0c~2Lo z-A+vC=LnJ0WWntyufoE^9e8pciO`oLkZkhNdbU`^i|2s~dN1S3hfGCOBJyno~i=TLC3ouYUv&`ol8)&p{WC#(uS9 zI?G8s%qj@7mm`bMeA|GLyr=BM2pwb+8{tATZdPvs6cMa`cjH7b zGX`TCjC3*GdxTgZ5lINZBg|;z<2hQ8{HS}&ms@pxGP_i6W^huicDflUQSC<)Iy;qKTOnhD@8v=AM#N8dr7K`%gi5jdAFt0LhPP zZT=k`q77Hnf}+bjj@x{R-z^eo$E*dWoA=&Y$~-TV1tI`$QVrp()~|sMC1*Ri;H>`B z{UMR-WAu}i>Jf<2TR7}&l8R(%}|kyyyO zvO36JKZOFOH*`D3-+bwaES_p@AuOf~p%msET=n5BT-x8xYD{k!$#(M6zMp%W79+pm zyMM>864yt}VA}iiF3=kgMEW1)#rE^0iqJFrT^5q()JiBaIf=v)pfS;<_l78}b(1j~ zz4JlncdN6pMrQ$AcFfO*e%v7vN>e^`dY_IW2ND2KWgoLu*@X6Waqlr|v6se%u1}Cf z9Ujw>Nr@x;ya#Yxu1U4#tr)%6%PJf?6T3h8s<@esMR*?;qn(Q#|Wu}WYWFNa4k z&?LQUoH+ef3wKYNo% z7D^Kn^z`6ij-Lr})U_onFr#p^WFs9tb zpUnAp2HV{S%X>PO-`n0xo|DgEf#j3nPpZ8xoc)Z1hKcG?NvRg!G0SIOrkiz5qnile z(AjCN^yJxi&w`4EUudH0Uwpg+p|qM3)e3$v-RhAs(1rvv@Jai^Pr045-yP*{`%S+KHP6c{snu#`1-|`i z`^I0;a!-_6>6)20rEl;MZ`g*I^pYCq-Nn)Z#BDe5~c9b#O zxICQH)IN4F5a{^sYgBr=tI7co+Z9qsdT(Oe$D& object to the behavior processing module the same way we % have added the position data. -%behavior_processing_module = types.core.ProcessingModule("stores behavioral data."); % if you have not already created it behavior_processing_module.add('CompassDirection', direction); -%nwb.processing.add('behavior', behavior_processing_module); % if you have not already added it %% BehaviorTimeSeries: Storing continuous behavior data % is an interface for storing continuous behavior data, @@ -104,9 +102,8 @@ behavioral_time_series = types.core.BehavioralTimeSeries(); behavioral_time_series.add('speed', speed_time_series); -%behavior_processing_module = types.core.ProcessingModule("stores behavioral data."); % if you have not already created it +% Add behavioral_time_series to the processing module behavior_processing_module.add('BehavioralTimeSeries', behavioral_time_series); -%nwb.processing.add('behavior', behavior_processing_module); % if you have not already added it %% BehavioralEvents: Storing behavioral events % is an interface for storing behavioral events. We can use @@ -126,9 +123,8 @@ behavioral_events = types.core.BehavioralEvents(); behavioral_events.add('lever_presses', time_series); -%behavior_processing_module = types.core.ProcessingModule("stores behavioral data."); % if you have not already created it +% Add behavioral_events to the processing module behavior_processing_module.add('BehavioralEvents', behavioral_events); -%nwb.processing.add('behavior', behavior_processing_module); % if you have not already added it %% % Storing only the timestamps of the events is possible with the ndx-events % NWB extension. You can also add labels associated with the events with this @@ -163,9 +159,8 @@ ); behavioral_epochs.add('sleeping', sleep_intervals); -% behavior_processing_module = types.core.ProcessingModule("stores behavioral data."); -% behavior_processing_module.add('BehavioralEvents', behavioral_events); -% nwb.processing.add('behavior', behavior_processing_module); +% Add behavioral_epochs to the processing module +behavior_processing_module.add('BehavioralEpochs', behavioral_epochs); % Another approach: TimeIntervals % Using to represent time intervals is often preferred over is for storing eye-tracking data which represents pupil size. @@ -239,9 +232,7 @@ pupil_tracking = types.core.PupilTracking(); pupil_tracking.add('pupil_diameter', pupil_diameter); -% behavior_processing_module = types.core.ProcessingModule("stores behavioral data."); behavior_processing_module.add('PupilTracking', pupil_tracking); -% nwb.processing.add('behavior', behavior_processing_module); %% Writing the behavior data to an NWB file % All of the above commands build an NWBFile object in-memory. To write this % file, use Date: Thu, 27 Nov 2025 10:21:02 +0100 Subject: [PATCH 47/65] Create public getAliasMap methods in Set / HasUnnamedGroups mixin --- +matnwb/+mixin/HasUnnamedGroups.m | 10 ++++++---- +matnwb/+utility/DynamicPropertyManager.m | 9 +++++++++ +types/+untyped/Set.m | 4 ++++ 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/+matnwb/+mixin/HasUnnamedGroups.m b/+matnwb/+mixin/HasUnnamedGroups.m index 9cbd36efa..dada60ceb 100644 --- a/+matnwb/+mixin/HasUnnamedGroups.m +++ b/+matnwb/+mixin/HasUnnamedGroups.m @@ -139,6 +139,10 @@ function remove(obj, name) obj.warnIfNameIsPropertyName(name) end + + function T = getAliasMap(obj) + T = obj.getTableWithAliasNames(); + end end % Method for subclass to initialize the mixin @@ -312,18 +316,16 @@ function deleteDynamicProperty(obj, name) for i = 1:numel(obj.GroupPropertyNames) groupName = obj.GroupPropertyNames(i); currentSet = obj.(groupName); - T{i} = currentSet.getPropertyMappingTable(); + T{i} = currentSet.getAliasMap(); end - T{end} = obj.PropertyManager.getPropertyMappingTable(); + T{end} = obj.PropertyManager.getAliasMap(); T(cellfun('isempty', T)) = []; T = cat(1, T{:}); if ~isempty(T) - keep = T.ValidIdentifier ~= T.OriginalName; - T = T(keep, :); T = unique(T, "rows"); end end diff --git a/+matnwb/+utility/DynamicPropertyManager.m b/+matnwb/+utility/DynamicPropertyManager.m index 29da8f03f..d4f6287b7 100644 --- a/+matnwb/+utility/DynamicPropertyManager.m +++ b/+matnwb/+utility/DynamicPropertyManager.m @@ -179,5 +179,14 @@ function removeProperty(obj, name) % Get a table showing property mappings T = obj.NameRegistry.getNameMappingTable(); end + + function T = getAliasMap(obj) + T = obj.getPropertyMappingTable(); + + % Only keep entries with an alias (i.e where the property name / + % valid matlab identifier is different than the original name) + keep = T.ValidIdentifier ~= T.OriginalName; + T = T(keep, :); + end end end diff --git a/+types/+untyped/Set.m b/+types/+untyped/Set.m index 8b6ab971a..2d86b443d 100644 --- a/+types/+untyped/Set.m +++ b/+types/+untyped/Set.m @@ -199,6 +199,10 @@ function add(obj, name, value) function setValidationFunction(obj, functionHandle) obj.ValidationFunction = functionHandle; end + + function T = getAliasMap(obj) + T = obj.PropertyManager.getAliasMap(); + end function T = getPropertyMappingTable(obj) T = obj.PropertyManager.getPropertyMappingTable(); From 5c18063d78156d15b2056b0f591970a5635bc99d Mon Sep 17 00:00:00 2001 From: ehennestad Date: Thu, 27 Nov 2025 10:21:23 +0100 Subject: [PATCH 48/65] Update displayAliasWarning.m Shorten warning message --- +types/+untyped/+internal/displayAliasWarning.m | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/+types/+untyped/+internal/displayAliasWarning.m b/+types/+untyped/+internal/displayAliasWarning.m index a5cc22b7a..4da02e517 100644 --- a/+types/+untyped/+internal/displayAliasWarning.m +++ b/+types/+untyped/+internal/displayAliasWarning.m @@ -12,9 +12,8 @@ function displayAliasWarning(aliasTable, className) warningIdentifier = 'NWB:DynamicPropertyAliasWarning'; warningMessage = sprintf([... ['Names for some entries of "%s" have been modified to ', ... - 'make them valid MATLAB identifiers before adding them as ', ... - 'properties of the object. The original names will still ', ... - 'be used when data is exported to file:\n'], ... + 'make them valid MATLAB identifiers (the original names will still ', ... + 'be used when data is exported to file):\n'], ... '\n%s\n'], className, strip(nameMap, 'right')); warnState = warning('backtrace', 'off'); From 62d01f5eedf30266f1b918c330bc9bab652acce2 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Thu, 27 Nov 2025 10:22:08 +0100 Subject: [PATCH 49/65] Update Set.m Add more details to comment --- +types/+untyped/Set.m | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/+types/+untyped/Set.m b/+types/+untyped/Set.m index 2d86b443d..12529bbbc 100644 --- a/+types/+untyped/Set.m +++ b/+types/+untyped/Set.m @@ -2,7 +2,8 @@ % Set - A (utility) container class for storing neurodata types. % % Neurodata types are added to the Set with name keys, forming name-value -% pairs referred to as entries. +% pairs referred to as entries. A validation function will ensure that +% only supported neurodata types are added to the set. % Developer notes: % `name` is used throughout this class to refer to the actual name of a Set From b7d6a8f1398a11e93abcdcb5a10ac1b7bf784415 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Thu, 27 Nov 2025 11:57:51 +0100 Subject: [PATCH 50/65] Update structure of how-to for container usage --- .../pages/how_to/working_with_containers.rst | 286 +++++++++--------- 1 file changed, 146 insertions(+), 140 deletions(-) diff --git a/docs/source/pages/how_to/working_with_containers.rst b/docs/source/pages/how_to/working_with_containers.rst index 3e8729c46..32ef9486e 100644 --- a/docs/source/pages/how_to/working_with_containers.rst +++ b/docs/source/pages/how_to/working_with_containers.rst @@ -1,9 +1,9 @@ .. _how_to_working_with_containers: -Working with Container Types Using Dot-Indexing -================================================ +Working with Container Properties and Types +=========================================== -This guide shows you how to work with NWB container types that hold multiple data objects using convenient dot-indexing syntax instead of the legacy ``.set()`` and ``.get()`` methods. +This guide shows you how to work with NWB properties and types that is designed to hold other data objects (containers). .. contents:: :local: @@ -11,28 +11,21 @@ This guide shows you how to work with NWB container types that hold multiple dat Overview -------- +Some neurodata types and properties of neurodata types in NWB are designed to hold one or more data objects of specific types. We will refer to these neurodata types and properties as "containers". For example, both the ``acquisition`` property of a :class:`types.core.NWBFile` and the :class:`types.core.ProcessingModule` neurodata type can contain multiple data objects of :class:`types.core.NWBDataInterface` or :class:`types.hdmf_common.DynamicTable` types (including subtypes). A container is represented internally using the :class:`types.untyped.Set` and MatNWB provides convenient syntax that mimics standard MATLAB property access for working with these containers. -Some NWB container types (like ``ProcessingModule``) are designed to hold multiple data objects of specific types. In older versions of MatNWB, you had to use ``.set()`` and ``.get()`` methods to add and retrieve these objects. Modern MatNWB provides more convenient syntax that mimics standard MATLAB property access. - -**Legacy approach:** +**Adding data objects:** .. code-block:: MATLAB - % Adding data - module.nwbdatainterface.set('MyTimeSeries', timeSeriesObject); - - % Retrieving data - timeSeries = module.nwbdatainterface.get('MyTimeSeries'); + % Use the add() method + container.add('MyTimeSeries', timeSeriesObject); -**Modern approach:** +**Retrieving data objects:** .. code-block:: MATLAB - % Adding data - module.add('MyTimeSeries', timeSeriesObject); - - % Retrieving data - timeSeries = module.MyTimeSeries; + % Use dot-indexing like any MATLAB property + timeSeries = container.MyTimeSeries; Adding Data Objects ------------------- @@ -40,12 +33,12 @@ Adding Data Objects Using the add() method ~~~~~~~~~~~~~~~~~~~~~~ -The ``add()`` method is the recommended way to add data objects to container types: +The ``add()`` method is the recommended way to add data objects to containers: .. code-block:: MATLAB % Create a processing module - module = types.core.ProcessingModule('description', 'My analysis module'); + processingModule = types.core.ProcessingModule('description', 'My processing module'); % Create some data objects timeSeries = types.core.TimeSeries( ... @@ -57,8 +50,8 @@ The ``add()`` method is the recommended way to add data objects to container typ 'description', 'My data table'); % Add them to the module - module.add('NeuralActivity', timeSeries); - module.add('ResultsTable', dataTable); + processingModule.add('NeuralActivity', timeSeries); + processingModule.add('DataTable', dataTable); During construction ~~~~~~~~~~~~~~~~~~~ @@ -67,10 +60,10 @@ You can also add data objects when creating the container: .. code-block:: MATLAB - module = types.core.ProcessingModule( ... - 'description', 'My analysis module', ... + processingModule = types.core.ProcessingModule( ... + 'description', 'My processing module', ... 'NeuralActivity', timeSeries, ... - 'ResultsTable', dataTable); + 'DataTable', dataTable); Accessing Data Objects ----------------------- @@ -83,14 +76,14 @@ Once added, data objects are accessible as properties of the container: .. code-block:: MATLAB % Retrieve by property name - timeSeries = module.NeuralActivity; - resultsTable = module.ResultsTable; + timeSeries = processingModule.NeuralActivity; + dataTable = processingModule.DataTable; % You can then access their properties data = timeSeries.data; timestamps = timeSeries.timestamps; -This works exactly like accessing any other MATLAB object property, making your code more readable and intuitive. +This works exactly like accessing any other MATLAB object property. Checking if an object exists ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -99,10 +92,12 @@ Use ``isprop()`` to check if a data object exists: .. code-block:: MATLAB - if isprop(module, 'NeuralActivity') - timeSeries = module.NeuralActivity; + if isprop(processingModule, 'NeuralActivity') + timeSeries = processingModule.NeuralActivity; end +This approach helps avoid errors when trying to access non-existent objects. + Removing Data Objects ---------------------- @@ -111,10 +106,10 @@ Use the ``remove()`` method to remove data objects: .. code-block:: MATLAB % Remove a data object by its name - module.remove('NeuralActivity'); + processingModule.remove('NeuralActivity'); % Verify it's gone - hasProperty = isprop(module, 'NeuralActivity'); % Returns false + hasProperty = isprop(processingModule, 'NeuralActivity'); % Returns false .. note:: @@ -131,145 +126,86 @@ MATLAB property names must follow specific rules (no spaces, special characters, .. code-block:: MATLAB % Add with spaces and special characters - module.add('my time series', timeSeries); - module.add('Raw-Fluorescence', fluorescence); + processingModule.add('my time series', timeSeries); + processingModule.add('Data-Table', dataTable); % Access using valid MATLAB identifiers - timeSeries = module.myTimeSeries; % Spaces removed, camelCase - fluorescence = module.RawFluorescence; % Hyphen replaced with uppercase + timeSeries = processingModule.myTimeSeries; % Spaces removed, camelCase + dataTable = processingModule.Data_Table; % Hyphen replaced with underscore .. important:: - The **original name** is preserved in the NWB file. Other tools (like PyNWB) will see ``'my time series'`` and ``'Raw-Fluorescence'``, not the MATLAB aliases. + The **original name** is preserved in the NWB file. Other tools (like PyNWB) will see ``'my time series'`` and ``'Data-Table'``, not the MATLAB aliases. .. tip:: - **Best practice:** Use names that are valid MATLAB identifiers from the start (e.g., PascalCase or camelCase) to avoid confusion: + **Best practice:** Use names that are valid MATLAB identifiers from the start (e.g., PascalCase, camelCase or snake_case) to avoid confusion: .. code-block:: MATLAB - module.add('MyTimeSeries', timeSeries); - module.add('RawFluorescence', fluorescence); + processingModule.add('MyTimeSeries', timeSeries); + processingModule.add('myTimeSeries', timeSeries); + processingModule.add('my_time_series', timeSeries); + +If you read files created by other tools with names that are not valid MATLAB identifiers, MatNWB will automatically create appropriate aliases when loading the data. -Viewing name mappings -~~~~~~~~~~~~~~~~~~~~~ +Viewing name mappings (aliases) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -If MatNWB creates aliases, it will display a warning showing the mapping between original names and property names. You can also check the ``nwbdatainterface`` or ``dynamictable`` properties to see the original names: +If MatNWB creates aliases, a warning will display showing the mapping between original names and property names when the container type is displayed in MATLAB's command window. .. code-block:: MATLAB - % See all original names in the Set - originalNames = module.nwbdatainterface.keys(); + % Create a processing module + processingModule = types.core.ProcessingModule('description', 'My processing module'); - % Get the mapping table - mappingTable = module.nwbdatainterface.getPropertyMappingTable(); - -Understanding Container Types ------------------------------- + % Add with spaces and special characters + processingModule.add('my time series', timeSeries); + processingModule.add('data-table', dataTable); + disp(processingModule) -ProcessingModule -~~~~~~~~~~~~~~~~ +**Output:** -The most common container type is ``ProcessingModule``, which can hold: +.. code-block:: MATLAB -- **NWBDataInterface objects** (stored in ``nwbdatainterface`` property) -- **DynamicTable objects** (stored in ``dynamictable`` property) + Warning: Names for some entries of "ProcessingModule" have been modified to make them valid + MATLAB identifiers (the original names will still be used when data is exported to file): -.. code-block:: MATLAB + ValidIdentifier OriginalName + _______________ ________________ - module = types.core.ProcessingModule('description', 'Optical physiology module'); + "myTimeSeries" "my time series" + "data_table" "data-table" - % Add a NWBDataInterface subclass - module.add('Fluorescence', types.core.Fluorescence()); - - % Add a DynamicTable - module.add('RegionOfInterestTable', types.hdmf_common.DynamicTable( ... - 'description', 'Region of interest properties')); - -The ``add()`` method automatically determines which internal Set (``nwbdatainterface`` or ``dynamictable``) to use based on the object's type. + ProcessingModule with properties: -Working with Sets directly (advanced) --------------------------------------- + description: 'My analysis module' + myTimeSeries: [1×1 types.core.TimeSeries] + data_table: [1×1 types.hdmf_common.DynamicTable] -For advanced use cases, you can still access the underlying ``types.untyped.Set`` objects directly: +You can also use the ``getAliasMap()`` method to retrieve a table showing the name mappings programmatically: .. code-block:: MATLAB - % Access the Set directly - dataSet = module.nwbdatainterface; - - % Legacy methods still work - dataSet.set('MyData', dataObject); - dataObject = dataSet.get('MyData'); - - % Set also supports direct property access - dataObject = dataSet.MyData; - - % Check what's in the Set - allKeys = dataSet.keys(); - allValues = dataSet.values(); - hasKey = dataSet.isKey('MyData'); - -.. seealso:: - - For more information about the underlying Set implementation, see :ref:`matnwb-read-untyped-sets-anons`. - -Legacy Syntax Support ---------------------- + nameMap = processingModule.getAliasMap() -All legacy syntax is still supported for backward compatibility: +**Output:** .. code-block:: MATLAB - % Legacy: add to Set directly - module.nwbdatainterface.set('MyData', dataObject); - - % Modern: use add() method - module.add('MyData', dataObject); - - % Legacy: get from Set - dataObject = module.nwbdatainterface.get('MyData'); - - % Modern: direct property access - dataObject = module.MyData; + nameMap = -Complete Example ----------------- + 2×2 table -Here's a complete workflow showing modern syntax: + ValidIdentifier OriginalName + _______________ ________________ -.. code-block:: MATLAB + "myTimeSeries" "my time series" + "data_table" "data-table" - % Create NWB file - nwbFile = NwbFile( ... - 'session_description', 'My experiment', ... - 'identifier', 'exp001', ... - 'session_start_time', datetime()); - - % Create a processing module - opticalPhysiologyModule = types.core.ProcessingModule( ... - 'description', 'Optical physiology data'); - - % Create and add data objects - fluorescence = types.core.Fluorescence(); - roiResponseSeries = types.core.RoiResponseSeries( ... - 'data', rand(100, 10), ... - 'data_unit', 'lumens', ... - 'timestamps', linspace(0, 10, 100)); - - fluorescence.add('RoiResponseSeries', roiResponseSeries); - opticalPhysiologyModule.add('Fluorescence', fluorescence); - - % Add module to NWB file - nwbFile.processing.set('ophys', opticalPhysiologyModule); - - % Later, retrieve your data using dot-indexing - fluorescence = opticalPhysiologyModule.Fluorescence; - roiResponseSeries = fluorescence.RoiResponseSeries; - traces = roiResponseSeries.data; - - % Export the file - nwbExport(nwbFile, 'my_experiment.nwb'); +.. note:: + + In addition to using alias names for property access, you can also use legacy ``.get()`` and ``.set()`` methods on the underlying ``types.untyped.Set`` objects if needed (see Advanced Topics below). Troubleshooting --------------- @@ -277,15 +213,34 @@ Troubleshooting Property name conflicts ~~~~~~~~~~~~~~~~~~~~~~~ -If you try to add an object with a name that conflicts with an internal container property (like ``'nwbdatainterface'`` or ``'dynamictable'``), MatNWB will automatically append an underscore: +If you try to add an object with a name that conflicts with an internal container property (like ``'nwbdatainterface'`` or ``'dynamictable'`` from :class:`types.core.ProcessingModule`, not recommended), MatNWB will automatically append an underscore: .. code-block:: MATLAB + someObject = types.core.TimeSeries(); + % This name conflicts with an internal container property - module.add('nwbdatainterface', someObject); + processingModule.add('nwbdatainterface', someObject); % Access it with an underscore appended - someObject = module.nwbdatainterface_; + someObject = processingModule.nwbdatainterface_; + +Duplicate names +~~~~~~~~~~~~~~~ +If you add multiple objects with the same name (case-insensitive), MatNWB will append numeric suffixes to create unique property names: + +.. code-block:: MATLAB + + % Add multiple objects with the same name (same alias) + processingModule = types.core.ProcessingModule('description', 'My processing module'); + processingModule.add('My_Data', types.core.TimeSeries()); + processingModule.add('My-Data', types.core.TimeSeries()); + processingModule.add('My.Data', types.core.TimeSeries()); + + % Access them with unique property names + data1 = processingModule.My_Data; % Original + data2 = processingModule.My_Data_1; % First duplicate + data3 = processingModule.My_Data_2; % Second duplicate Name not found error ~~~~~~~~~~~~~~~~~~~~ @@ -295,12 +250,63 @@ If you try to access a property that doesn't exist, you'll get an error. Always .. code-block:: MATLAB % Check before accessing - if isprop(module, 'MyData') - dataObject = module.MyData; + if isprop(processingModule, 'MyData') + dataObject = processingModule.MyData; else - warning('MyData not found in module'); + warning('MyData not found in processingModule'); end .. tip:: Remember to use the MATLAB property name (alias), not the original name, when checking with ``isprop()``. + +Advanced Topics +--------------- + +Legacy Syntax (Deprecated) +-------------------------- + +.. note:: + + The legacy ``.set()`` and ``.get()`` methods are deprecated. Use ``add()`` and dot-indexing instead. + +For users familiar with older versions of MatNWB, the legacy syntax is still supported for backward compatibility: + +.. code-block:: MATLAB + + dataObject = types.core.TimeSeries(); + + % Deprecated: add to Set directly + processingModule.nwbdatainterface.set('MyData', dataObject); + + % Recommended: use add() method + processingModule.add('MyData', dataObject); + + % Deprecated: get from Set + dataObject = processingModule.nwbdatainterface.get('MyData'); + + % Recommended: direct property access + dataObject = processingModule.MyData; + + +Working with Sets directly +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can still access the underlying ``types.untyped.Set`` objects directly: + +.. code-block:: MATLAB + + % Access the Set directly + dataSet = processingModule.nwbdatainterface; + + % Set supports direct property access + dataObject = dataSet.MyData; + + % Check what's in the Set + allKeys = dataSet.keys(); + allValues = dataSet.values(); + hasKey = dataSet.isKey('MyData'); + +.. seealso:: + + For more information about the underlying Set implementation, see :ref:`matnwb-read-untyped-sets-anons`. From be1d11e43ff4d8fe28640d7b88681236bc3e7107 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Fri, 28 Nov 2025 07:25:26 +0100 Subject: [PATCH 51/65] Update working_with_containers.rst --- .../pages/how_to/working_with_containers.rst | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/docs/source/pages/how_to/working_with_containers.rst b/docs/source/pages/how_to/working_with_containers.rst index 32ef9486e..4b43ace5e 100644 --- a/docs/source/pages/how_to/working_with_containers.rst +++ b/docs/source/pages/how_to/working_with_containers.rst @@ -11,7 +11,7 @@ This guide shows you how to work with NWB properties and types that is designed Overview -------- -Some neurodata types and properties of neurodata types in NWB are designed to hold one or more data objects of specific types. We will refer to these neurodata types and properties as "containers". For example, both the ``acquisition`` property of a :class:`types.core.NWBFile` and the :class:`types.core.ProcessingModule` neurodata type can contain multiple data objects of :class:`types.core.NWBDataInterface` or :class:`types.hdmf_common.DynamicTable` types (including subtypes). A container is represented internally using the :class:`types.untyped.Set` and MatNWB provides convenient syntax that mimics standard MATLAB property access for working with these containers. +Some neurodata types and properties of neurodata types in NWB are designed to hold one or more data objects of specific types. We will refer to these neurodata types and properties as "containers". For example, both the ``acquisition`` property of a :class:`types.core.NWBFile` and the :class:`types.core.ProcessingModule` neurodata type can contain multiple data objects of :class:`types.core.NWBDataInterface` or :class:`types.hdmf_common.DynamicTable` types (including subtypes). A container is represented internally using the :class:`types.untyped.Set` class and MatNWB provides convenient syntax that mimics standard MATLAB property access for working with these containers. **Adding data objects:** @@ -139,7 +139,7 @@ MATLAB property names must follow specific rules (no spaces, special characters, .. tip:: - **Best practice:** Use names that are valid MATLAB identifiers from the start (e.g., PascalCase, camelCase or snake_case) to avoid confusion: + **Best practice:** Use names that are valid MATLAB identifiers from the start (e.g., PascalCase, camelCase or snake_case) and stick to one style: .. code-block:: MATLAB @@ -147,12 +147,12 @@ MATLAB property names must follow specific rules (no spaces, special characters, processingModule.add('myTimeSeries', timeSeries); processingModule.add('my_time_series', timeSeries); -If you read files created by other tools with names that are not valid MATLAB identifiers, MatNWB will automatically create appropriate aliases when loading the data. +If you read files created by other tools with names that are not valid MATLAB identifiers, MatNWB will automatically create valid MATLAB identifers (aliases) when loading the data. Viewing name mappings (aliases) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -If MatNWB creates aliases, a warning will display showing the mapping between original names and property names when the container type is displayed in MATLAB's command window. +If a container contains entries with names that are not valid MATLAB identifiers, a warning will display showing the mapping between original names and property names (aliases) when the container type is displayed in MATLAB's command window. .. code-block:: MATLAB @@ -166,7 +166,7 @@ If MatNWB creates aliases, a warning will display showing the mapping between or **Output:** -.. code-block:: MATLAB +.. code-block:: matlabsession Warning: Names for some entries of "ProcessingModule" have been modified to make them valid MATLAB identifiers (the original names will still be used when data is exported to file): @@ -187,11 +187,13 @@ You can also use the ``getAliasMap()`` method to retrieve a table showing the na .. code-block:: MATLAB - nameMap = processingModule.getAliasMap() + nameMap = processingModule.getAliasMap(); **Output:** -.. code-block:: MATLAB +.. code-block:: matlabsession + + >> nameMap nameMap = @@ -200,8 +202,8 @@ You can also use the ``getAliasMap()`` method to retrieve a table showing the na ValidIdentifier OriginalName _______________ ________________ + "data_table" "data-table" "myTimeSeries" "my time series" - "data_table" "data-table" .. note:: From 3931ae06bb29b0af74b7246cfecbed3d2e559a52 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Fri, 28 Nov 2025 21:51:19 +0100 Subject: [PATCH 52/65] Fix warning message grammar in MetaClass Corrected the warning message in MetaClass to use 'instance of type' instead of 'instance for type'. --- +types/+untyped/MetaClass.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/+types/+untyped/MetaClass.m b/+types/+untyped/MetaClass.m index b28febbc5..9ef98160e 100644 --- a/+types/+untyped/MetaClass.m +++ b/+types/+untyped/MetaClass.m @@ -219,7 +219,7 @@ function displayWarningIfMissingRequiredProps(obj) propertyListStr = obj.prettyPrintPropertyList(missingRequiredProps); warning('NWB:RequiredPropertyMissing', ... ['The following required properties are missing for ', ... - 'instance for type "%s":\n%s'], class(obj), propertyListStr) + 'instance of type "%s":\n%s'], class(obj), propertyListStr) end end From 52459fb156f72e525705ef36c374efd94d2a2f88 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Sun, 30 Nov 2025 21:19:50 +0100 Subject: [PATCH 53/65] Update HasUnnamedGroups.m Improve object display --- +matnwb/+mixin/HasUnnamedGroups.m | 103 ++++++++++++++++++++++++------ 1 file changed, 82 insertions(+), 21 deletions(-) diff --git a/+matnwb/+mixin/HasUnnamedGroups.m b/+matnwb/+mixin/HasUnnamedGroups.m index dada60ceb..ffecc6fff 100644 --- a/+matnwb/+mixin/HasUnnamedGroups.m +++ b/+matnwb/+mixin/HasUnnamedGroups.m @@ -1,5 +1,6 @@ classdef HasUnnamedGroups < matlab.mixin.CustomDisplay & dynamicprops & handle % HasUnnamedGroups - Mixin to simplify access to Sets of unnamed subgroups +% of a neurodata type % % Overview: % Some NWB container types (e.g. ProcessingModule) include unnamed @@ -53,6 +54,7 @@ properties (Access = private, Transient) % PropertyManager - Manages dynamic properties for this object PropertyManager + PropertyManager matnwb.utility.DynamicPropertyManager end % Constructor @@ -190,6 +192,68 @@ function assignContainedSetCallbackFunctions(obj) end end + % Internal utility methods + methods (Access = private) + + function tf = isContainerLike(obj) + % isContainerLike - Whether neurodata type is purely a container + % for other data objects + + % Note: A neurodata type is considered a container if it only has + % properties for storing other neurodata types, i.e properties + % containing types.untyped.Set objects + + staticProperties = obj.getStaticProperties(); + groupProperties = obj.GroupPropertyNames; + + tf = isempty(setdiff(staticProperties, groupProperties)); + end + + function T = getTableWithAliasNames(obj) + + T = cell(1, numel(obj.GroupPropertyNames) + 1); + + for i = 1:numel(obj.GroupPropertyNames) + groupName = obj.GroupPropertyNames(i); + currentSet = obj.(groupName); + T{i} = currentSet.getAliasMap(); + end + + T{end} = obj.PropertyManager.getAliasMap(); + + T(cellfun('isempty', T)) = []; + T = cat(1, T{:}); + + if ~isempty(T) + T = unique(T, "rows"); + end + end + + function n = numEntries(obj) + nPerGroup = zeros(1, numel(obj.GroupPropertyNames)); + + for i = 1:numel(obj.GroupPropertyNames) + groupName = obj.GroupPropertyNames(i); + nPerGroup(i) = obj.(groupName).Count; + end + n = sum(nPerGroup); + end + + function staticProperties = getStaticProperties(obj) + allProperties = properties(obj); + dynamicPropNames = obj.PropertyManager.getAllPropertyNames(); + + staticProperties = setdiff(allProperties, dynamicPropNames); + end + end + + methods (Hidden, Sealed) + function p = addprop(obj, name) + % No reimplementation - just hide method + p = addprop@dynamicprops(obj, name); + end + end + % Internal methods for managing properties methods (Access = private) @@ -308,27 +372,6 @@ function deleteDynamicProperty(obj, name) isMatch = ismember(lower(typeClassNamesShort), groupPropertyNames); result = typeClassNames(isMatch); end - - function T = getTableWithAliasNames(obj) - - T = cell(1, numel(obj.GroupPropertyNames) + 1); - - for i = 1:numel(obj.GroupPropertyNames) - groupName = obj.GroupPropertyNames(i); - currentSet = obj.(groupName); - T{i} = currentSet.getAliasMap(); - end - - T{end} = obj.PropertyManager.getAliasMap(); - - - T(cellfun('isempty', T)) = []; - T = cat(1, T{:}); - - if ~isempty(T) - T = unique(T, "rows"); - end - end end % Dynamic property getter methods @@ -371,10 +414,28 @@ function onSetEntryRemoved(obj, name, ~) % matlab.mixin.CustomDisplay override methods (Access = protected) + function str = getHeader(obj) + str = getHeader@matlab.mixin.CustomDisplay(obj); + + if obj.isContainerLike() + % Change header format for container type + numEntries = obj.numEntries; + + if numEntries == 1 + replacement = sprintf('with %d entry', obj.numEntries); + else + replacement = sprintf('with %d entries', obj.numEntries); + end + + str = strrep(str, 'with properties:', replacement); + end + end + function groups = getPropertyGroups(obj) % getPropertyGroups - Create property groups for display standardProps = properties(obj); + standardProps = reshape(standardProps, 1, []); % Ensure row % Remove the Set properties that we'll display separately toSkip = false(1, length(obj.GroupPropertyNames)); From 98744b31df981627c956e6fea0846ea5ccd7ef1c Mon Sep 17 00:00:00 2001 From: ehennestad Date: Sun, 30 Nov 2025 21:21:09 +0100 Subject: [PATCH 54/65] Update HasUnnamedGroups.m Improve object display pt 2 --- +matnwb/+mixin/HasUnnamedGroups.m | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/+matnwb/+mixin/HasUnnamedGroups.m b/+matnwb/+mixin/HasUnnamedGroups.m index ffecc6fff..a7a097032 100644 --- a/+matnwb/+mixin/HasUnnamedGroups.m +++ b/+matnwb/+mixin/HasUnnamedGroups.m @@ -53,7 +53,6 @@ properties (Access = private, Transient) % PropertyManager - Manages dynamic properties for this object - PropertyManager PropertyManager matnwb.utility.DynamicPropertyManager end @@ -446,9 +445,10 @@ function onSetEntryRemoved(obj, name, ~) end % Todo: Use a nwbPreferences object - displayPref = getpref('matnwb', 'displaymode', 'groups'); % groups | flat + displayPref = getpref('matnwb', 'displaymode', 'groups'); % groups | flat | legacy + %displayPref = 'groups'; - if strcmp(displayPref, 'groups') % Remove dynamic props + if strcmp(displayPref, 'groups') || strcmp(displayPref, 'legacy') % Remove dynamic props dynamicPropNames = obj.PropertyManager.getAllPropertyNames(); for i = 1:length(dynamicPropNames) idx = strcmp(standardProps, dynamicPropNames{i}); @@ -469,7 +469,7 @@ function onSetEntryRemoved(obj, name, ~) % Get the Set property setObj = obj.(groupName); - assert(~isempty(setObj) && isa(setObj, 'types.untyped.Set'), ... + assert(~isempty(setObj) && (isa(setObj, 'types.untyped.Set') || isa(setObj, 'types.untyped.Anon')), ... 'Expected property "%s" to contain a Set', groupName) % Get all keys from the Set @@ -484,12 +484,27 @@ function onSetEntryRemoved(obj, name, ~) end % Create a title for this group - title = "" + groupName + " entries:"; + if ~isempty(keys) + if isscalar(keys) + title = "" + groupName + " group" + "" + sprintf(" with %d entry:", numel(keys)); + else + title = "" + groupName + " group" + "" + sprintf(" with %d entries:", numel(keys)); + end + else + title = "" + groupName + ": (no entries)" + ... + sprintf('\n Tip: Use the ''add'' method to add data objects to this group.'); + end % Add this group to the property groups groups(end+1) = matlab.mixin.util.PropertyGroup(propList, title); %#ok end + + elseif strcmp(displayPref, 'legacy') + standardProps = [standardProps, obj.GroupPropertyNames]; + groups = matlab.mixin.util.PropertyGroup(standardProps); + return end + obj.displayAliasWarning() end From 10563dfd6cb0e3f1568591a91a9a59409580b5ee Mon Sep 17 00:00:00 2001 From: ehennestad Date: Fri, 5 Dec 2025 08:28:19 +0100 Subject: [PATCH 55/65] Update requirements.txt --- +tests/requirements.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/+tests/requirements.txt b/+tests/requirements.txt index ab8ccbbe9..7e46f1ef1 100644 --- a/+tests/requirements.txt +++ b/+tests/requirements.txt @@ -3,4 +3,6 @@ matplotlib hdf5plugin dataframe_image git+https://github.com/NeurodataWithoutBorders/pynwb.git@dev -git+https://github.com/NeurodataWithoutBorders/nwbinspector.git@dev +nwbinspector +# older matlab releases requires python 3.9, which is not supported by nwbinspector +# git+https://github.com/NeurodataWithoutBorders/nwbinspector.git@dev From e2ef7159577f3d6d2c3be9000871bfedc1a7fead Mon Sep 17 00:00:00 2001 From: ehennestad Date: Fri, 5 Dec 2025 09:14:02 +0100 Subject: [PATCH 56/65] Fix typo in 'identifiers' in container docs --- docs/source/pages/how_to/working_with_containers.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/pages/how_to/working_with_containers.rst b/docs/source/pages/how_to/working_with_containers.rst index 4b43ace5e..a7d1a2ba7 100644 --- a/docs/source/pages/how_to/working_with_containers.rst +++ b/docs/source/pages/how_to/working_with_containers.rst @@ -147,7 +147,7 @@ MATLAB property names must follow specific rules (no spaces, special characters, processingModule.add('myTimeSeries', timeSeries); processingModule.add('my_time_series', timeSeries); -If you read files created by other tools with names that are not valid MATLAB identifiers, MatNWB will automatically create valid MATLAB identifers (aliases) when loading the data. +If you read files created by other tools with names that are not valid MATLAB identifiers, MatNWB will automatically create valid MATLAB identifiers (aliases) when loading the data. Viewing name mappings (aliases) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From 5d90a0522baba39a041c78e6854ac47952216965 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Fri, 5 Dec 2025 09:17:30 +0100 Subject: [PATCH 57/65] Fix failing test for HasUnnamedGroup mixin --- +tests/+unit/HasUnnamedGroupsTest.m | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/+tests/+unit/HasUnnamedGroupsTest.m b/+tests/+unit/HasUnnamedGroupsTest.m index eedb2b67d..81a4be068 100644 --- a/+tests/+unit/HasUnnamedGroupsTest.m +++ b/+tests/+unit/HasUnnamedGroupsTest.m @@ -220,15 +220,15 @@ function testObjectDisplay(testCase) setpref('matnwb', 'displaymode', 'flat') C = evalc('disp(module)'); - testCase.verifyFalse(contains(C, 'nwbdatainterface entries:')) - testCase.verifyFalse(contains(C, 'dynamictable entries:')) + testCase.verifyFalse(contains(C, 'nwbdatainterface group')) + testCase.verifyFalse(contains(C, 'dynamictable group')) testCase.verifyTrue(contains(C, 'TimeSeries:')) testCase.verifyTrue(contains(C, 'DynamicTable:')) setpref('matnwb', 'displaymode', 'groups') C = evalc('disp(module)'); - testCase.verifyTrue(contains(C, 'nwbdatainterface entries:')) - testCase.verifyTrue(contains(C, 'dynamictable entries:')) + testCase.verifyTrue(contains(C, 'nwbdatainterface group')) + testCase.verifyTrue(contains(C, 'dynamictable group')) testCase.verifyTrue(contains(C, 'TimeSeries:')) end From dbc7f95a64213fd982989a9a7e661503300cbb40 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Fri, 5 Dec 2025 16:05:11 +0100 Subject: [PATCH 58/65] Expand container documentation with Set usage and display modes The documentation now provides detailed instructions on working directly with types.untyped.Set objects, including using set/get methods with original names and handling invalid MATLAB identifiers. It also introduces and explains container display modes ('groups', 'flat', 'legacy') and how to configure them for different output formats in MATLAB. --- .../pages/how_to/working_with_containers.rst | 170 +++++++++++++++--- 1 file changed, 145 insertions(+), 25 deletions(-) diff --git a/docs/source/pages/how_to/working_with_containers.rst b/docs/source/pages/how_to/working_with_containers.rst index a7d1a2ba7..345f18bd0 100644 --- a/docs/source/pages/how_to/working_with_containers.rst +++ b/docs/source/pages/how_to/working_with_containers.rst @@ -207,7 +207,7 @@ You can also use the ``getAliasMap()`` method to retrieve a table showing the na .. note:: - In addition to using alias names for property access, you can also use legacy ``.get()`` and ``.set()`` methods on the underlying ``types.untyped.Set`` objects if needed (see Advanced Topics below). + In addition to using alias names for property access, you can also use ``.get()`` and ``.set()`` methods (legacy syntax) on the underlying ``types.untyped.Set`` objects with the original names (see :ref:`set-methods-with-invalid-names`). Troubleshooting --------------- @@ -265,50 +265,170 @@ If you try to access a property that doesn't exist, you'll get an error. Always Advanced Topics --------------- -Legacy Syntax (Deprecated) --------------------------- +Working with Sets directly +~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. note:: +Containers are represented internally using ``types.untyped.Set`` objects. While the recommended approach is to use the ``add()`` method and dot-indexing for accessing container entries, you can also work with the underlying Set objects directly. - The legacy ``.set()`` and ``.get()`` methods are deprecated. Use ``add()`` and dot-indexing instead. +Accessing the Set object +^^^^^^^^^^^^^^^^^^^^^^^^^ -For users familiar with older versions of MatNWB, the legacy syntax is still supported for backward compatibility: +You can access the Set object directly by accessing the container property: .. code-block:: MATLAB - dataObject = types.core.TimeSeries(); + % Access the Set directly + dataSet = processingModule.nwbdatainterface; + + % Set supports direct property access + dataObject = dataSet.MyData; - % Deprecated: add to Set directly - processingModule.nwbdatainterface.set('MyData', dataObject); +Using Set methods +^^^^^^^^^^^^^^^^^ + +The Set object provides additional methods for managing entries: + +.. code-block:: MATLAB + + dataObject = types.core.TimeSeries(); - % Recommended: use add() method - processingModule.add('MyData', dataObject); + % Add to Set using set() method + processingModule.nwbdatainterface.set('MyData', dataObject); - % Deprecated: get from Set + % Get from Set using get() method dataObject = processingModule.nwbdatainterface.get('MyData'); - % Recommended: direct property access - dataObject = processingModule.MyData; + % Check what's in the Set + allKeys = processingModule.nwbdatainterface.keys(); + allValues = processingModule.nwbdatainterface.values(); + hasKey = processingModule.nwbdatainterface.isKey('MyData'); +.. note:: -Working with Sets directly -~~~~~~~~~~~~~~~~~~~~~~~~~~ + While working with Set objects directly is fully supported, using the ``add()`` method and dot-indexing provides a more intuitive and MATLAB-like syntax for most use cases. + +.. _set-methods-with-invalid-names: + +Using Set methods with invalid MATLAB names +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -You can still access the underlying ``types.untyped.Set`` objects directly: +One advantage of using Set methods is that you can use the **original names** directly, even if they are not valid MATLAB identifiers: .. code-block:: MATLAB - % Access the Set directly - dataSet = processingModule.nwbdatainterface; + % Create a processing module + processingModule = types.core.ProcessingModule('description', 'My processing module'); - % Set supports direct property access - dataObject = dataSet.MyData; + % Add objects using original names with spaces and special characters + timeSeries = types.core.TimeSeries( ... + 'data', rand(100, 1), ... + 'data_unit', 'volts', ... + 'timestamps', linspace(0, 1, 100)); + + dataTable = types.hdmf_common.DynamicTable( ... + 'description', 'My data table'); + + processingModule.nwbdatainterface.set('my time series', timeSeries); + processingModule.dynamictable.set('data-table', dataTable); + + % Retrieve using original names + timeSeries = processingModule.nwbdatainterface.get('my time series'); + dataTable = processingModule.dynamictable.get('data-table'); - % Check what's in the Set - allKeys = dataSet.keys(); - allValues = dataSet.values(); - hasKey = dataSet.isKey('MyData'); .. seealso:: For more information about the underlying Set implementation, see :ref:`matnwb-read-untyped-sets-anons`. + +Container Display Modes +~~~~~~~~~~~~~~~~~~~~~~~ + +MatNWB provides different display modes for container properties to control how entries are shown in the MATLAB command window: + + - ``'groups'`` (default): Displays container entries in nested groups. + - ``'flat'``: Displays all entries directly without nesting. + - ``'legacy'``: Mimics the behavior of older MatNWB versions. + +You can change the display mode using MATLAB's ``setpref`` function with the preference group ``'matnwb'`` and preference name ``'displaymode'``. + +Create a processing module with some entries and see the different display modes: + +.. code-block:: MATLAB + + % Create a processing module + processingModule = types.core.ProcessingModule('description', 'My processing module'); + + % Create some data objects + timeSeries = types.core.TimeSeries( ... + 'data', rand(100, 1), ... + 'data_unit', 'volts', ... + 'timestamps', linspace(0, 1, 100)); + + dataTable = types.hdmf_common.DynamicTable( ... + 'description', 'My data table'); + + % Add them to the module + processingModule.add('NeuralActivity', timeSeries); + processingModule.add('DataTable', dataTable); + +Groups display mode (default) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +By default, MatNWB displays container properties (Sets) in a nested (``'groups'``) form: + +.. code-block:: matlabsession + + >> processingModule + + processingModule = + + ProcessingModule with properties: + + description: 'My processing module' + + nwbdatainterface group with 1 entry: + NeuralActivity: [1×1 types.core.TimeSeries] + + dynamictable group with 1 entry: + DataTable: [1×1 types.hdmf_common.DynamicTable] + + +Flat display mode +^^^^^^^^^^^^^^^^^ + +To see all entries directly without nesting, use the ``'flat'`` display mode: + +.. code-block:: MATLAB + + % Set flat display mode + setpref('matnwb', 'displaymode', 'flat'); + disp(processingModule); + +**Output:** + +.. code-block:: matlabsession + + ProcessingModule with properties: + + description: 'My processing module' + DataTable: [1×1 types.hdmf_common.DynamicTable] + NeuralActivity: [1×1 types.core.TimeSeries] + + +It is also possible to set the display mode to ``'legacy'``, which mimics the behavior of older MatNWB versions: + +.. code-block:: MATLAB + + % Set legacy display mode + setpref('matnwb', 'displaymode', 'legacy'); + disp(processingModule); + +**Output:** + +.. code-block:: matlabsession + + ProcessingModule with properties: + + description: 'My processing module' + nwbdatainterface: [1×1 types.untyped.Set] + dynamictable: [1×1 types.untyped.Set] From 923445dd138c23ce1071896d4e749e2eca040650 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Fri, 5 Dec 2025 21:33:56 +0100 Subject: [PATCH 59/65] Update container display mode preference and docs Changed preference name from 'displaymode' to 'ContainerDisplayMode' in HasUnnamedGroups.m and updated documentation to reflect this change. Improved explanations in the docs for containers, entries, and Set methods, and clarified usage of display modes and their configuration. --- +matnwb/+mixin/HasUnnamedGroups.m | 5 +- .../pages/how_to/working_with_containers.rst | 57 +++++++++---------- 2 files changed, 28 insertions(+), 34 deletions(-) diff --git a/+matnwb/+mixin/HasUnnamedGroups.m b/+matnwb/+mixin/HasUnnamedGroups.m index a7a097032..d0bccefad 100644 --- a/+matnwb/+mixin/HasUnnamedGroups.m +++ b/+matnwb/+mixin/HasUnnamedGroups.m @@ -444,9 +444,8 @@ function onSetEntryRemoved(obj, name, ~) toSkip(idx) = true; end - % Todo: Use a nwbPreferences object - displayPref = getpref('matnwb', 'displaymode', 'groups'); % groups | flat | legacy - %displayPref = 'groups'; + % Todo: Introduce/use an nwbPreferences object + displayPref = getpref('matnwb', 'ContainerDisplayMode', 'groups'); % groups | flat | legacy if strcmp(displayPref, 'groups') || strcmp(displayPref, 'legacy') % Remove dynamic props dynamicPropNames = obj.PropertyManager.getAllPropertyNames(); diff --git a/docs/source/pages/how_to/working_with_containers.rst b/docs/source/pages/how_to/working_with_containers.rst index 345f18bd0..98e4819c3 100644 --- a/docs/source/pages/how_to/working_with_containers.rst +++ b/docs/source/pages/how_to/working_with_containers.rst @@ -11,7 +11,9 @@ This guide shows you how to work with NWB properties and types that is designed Overview -------- -Some neurodata types and properties of neurodata types in NWB are designed to hold one or more data objects of specific types. We will refer to these neurodata types and properties as "containers". For example, both the ``acquisition`` property of a :class:`types.core.NWBFile` and the :class:`types.core.ProcessingModule` neurodata type can contain multiple data objects of :class:`types.core.NWBDataInterface` or :class:`types.hdmf_common.DynamicTable` types (including subtypes). A container is represented internally using the :class:`types.untyped.Set` class and MatNWB provides convenient syntax that mimics standard MATLAB property access for working with these containers. +Some neurodata types and properties of neurodata types in NWB are designed to hold one or more data objects of specific types. We will refer to these neurodata types and properties as **containers**. For example, both the ``acquisition`` property of a :class:`types.core.NWBFile` and the :class:`types.core.ProcessingModule` neurodata type can contain multiple data objects of :class:`types.core.NWBDataInterface` or :class:`types.hdmf_common.DynamicTable` types (including subtypes). + +Each data object stored in a container is called an **entry**. Entries are identified by unique names that you assign when adding them to the container. A container is represented internally using the :class:`types.untyped.Set` class and MatNWB provides convenient syntax that mimics standard MATLAB property access for working with these containers and their entries. **Adding data objects:** @@ -215,7 +217,7 @@ Troubleshooting Property name conflicts ~~~~~~~~~~~~~~~~~~~~~~~ -If you try to add an object with a name that conflicts with an internal container property (like ``'nwbdatainterface'`` or ``'dynamictable'`` from :class:`types.core.ProcessingModule`, not recommended), MatNWB will automatically append an underscore: +If you add an entry with a name that conflicts with an internal container property—e.g., 'nwbdatainterface' or 'dynamictable' from :class:types.core.ProcessingModule—MatNWB will automatically append an underscore. Note that using such names is not recommended. .. code-block:: MATLAB @@ -268,25 +270,13 @@ Advanced Topics Working with Sets directly ~~~~~~~~~~~~~~~~~~~~~~~~~~ -Containers are represented internally using ``types.untyped.Set`` objects. While the recommended approach is to use the ``add()`` method and dot-indexing for accessing container entries, you can also work with the underlying Set objects directly. - -Accessing the Set object -^^^^^^^^^^^^^^^^^^^^^^^^^ - -You can access the Set object directly by accessing the container property: - -.. code-block:: MATLAB +Containers are represented internally using ``types.untyped.Set`` objects. While the recommended approach is to use the ``add()`` method and dot-indexing for accessing container entries, you can also work with the underlying ``types.untyped.Set`` objects directly. - % Access the Set directly - dataSet = processingModule.nwbdatainterface; - - % Set supports direct property access - dataObject = dataSet.MyData; Using Set methods ^^^^^^^^^^^^^^^^^ -The Set object provides additional methods for managing entries: +The ``types.untyped.Set`` object provides ``set`` and ``get`` methods for managing entries of a container: .. code-block:: MATLAB @@ -298,21 +288,25 @@ The Set object provides additional methods for managing entries: % Get from Set using get() method dataObject = processingModule.nwbdatainterface.get('MyData'); +.. note:: + + While working with ``types.untyped.Set`` objects directly is fully supported, using the ``add()`` method and dot-indexing provides a more intuitive and MATLAB-like syntax for most use cases. + +The ``types.untyped.Set`` class also provides additional methods for inspecting entries, such as ``keys()``, ``values()``, and ``isKey()``: + +.. code-block:: MATLAB + % Check what's in the Set allKeys = processingModule.nwbdatainterface.keys(); allValues = processingModule.nwbdatainterface.values(); hasKey = processingModule.nwbdatainterface.isKey('MyData'); -.. note:: - - While working with Set objects directly is fully supported, using the ``add()`` method and dot-indexing provides a more intuitive and MATLAB-like syntax for most use cases. - .. _set-methods-with-invalid-names: Using Set methods with invalid MATLAB names ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -One advantage of using Set methods is that you can use the **original names** directly, even if they are not valid MATLAB identifiers: +One advantage of using ``types.untyped.Set`` methods is that you can use the **original names** directly, even if they are not valid MATLAB identifiers: .. code-block:: MATLAB @@ -334,22 +328,21 @@ One advantage of using Set methods is that you can use the **original names** di % Retrieve using original names timeSeries = processingModule.nwbdatainterface.get('my time series'); dataTable = processingModule.dynamictable.get('data-table'); - .. seealso:: - For more information about the underlying Set implementation, see :ref:`matnwb-read-untyped-sets-anons`. + For more information about the underlying ``types.untyped.Set`` implementation, see :ref:`matnwb-read-untyped-sets-anons`. Container Display Modes ~~~~~~~~~~~~~~~~~~~~~~~ -MatNWB provides different display modes for container properties to control how entries are shown in the MATLAB command window: +MatNWB provides different display modes for container types to control how entries are shown in the MATLAB command window: - ``'groups'`` (default): Displays container entries in nested groups. - ``'flat'``: Displays all entries directly without nesting. - ``'legacy'``: Mimics the behavior of older MatNWB versions. -You can change the display mode using MATLAB's ``setpref`` function with the preference group ``'matnwb'`` and preference name ``'displaymode'``. +You can change the display mode using MATLAB's ``setpref`` function with the preference group ``'matnwb'`` and preference name ``'ContainerDisplayMode'``. Create a processing module with some entries and see the different display modes: @@ -401,26 +394,28 @@ To see all entries directly without nesting, use the ``'flat'`` display mode: .. code-block:: MATLAB % Set flat display mode - setpref('matnwb', 'displaymode', 'flat'); + setpref('matnwb', 'ContainerDisplayMode', 'flat'); disp(processingModule); **Output:** .. code-block:: matlabsession - ProcessingModule with properties: + ProcessingModule with properties: - description: 'My processing module' - DataTable: [1×1 types.hdmf_common.DynamicTable] - NeuralActivity: [1×1 types.core.TimeSeries] + description: 'My processing module' + DataTable: [1×1 types.hdmf_common.DynamicTable] + NeuralActivity: [1×1 types.core.TimeSeries] +Legacy display mode +^^^^^^^^^^^^^^^^^^^ It is also possible to set the display mode to ``'legacy'``, which mimics the behavior of older MatNWB versions: .. code-block:: MATLAB % Set legacy display mode - setpref('matnwb', 'displaymode', 'legacy'); + setpref('matnwb', 'ContainerDisplayMode', 'legacy'); disp(processingModule); **Output:** From 5639d2d998becded2fd2ae63fa6538eab7f28256 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Fri, 5 Dec 2025 21:43:54 +0100 Subject: [PATCH 60/65] Fix typos and improve clarity in container guide --- docs/source/pages/how_to/working_with_containers.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/source/pages/how_to/working_with_containers.rst b/docs/source/pages/how_to/working_with_containers.rst index 98e4819c3..aa5f49b49 100644 --- a/docs/source/pages/how_to/working_with_containers.rst +++ b/docs/source/pages/how_to/working_with_containers.rst @@ -3,7 +3,7 @@ Working with Container Properties and Types =========================================== -This guide shows you how to work with NWB properties and types that is designed to hold other data objects (containers). +This guide shows you how to work with NWB properties and types that are designed to hold other data objects (containers). .. contents:: :local: @@ -181,7 +181,7 @@ If a container contains entries with names that are not valid MATLAB identifiers ProcessingModule with properties: - description: 'My analysis module' + description: 'My processing module' myTimeSeries: [1×1 types.core.TimeSeries] data_table: [1×1 types.hdmf_common.DynamicTable] @@ -217,7 +217,7 @@ Troubleshooting Property name conflicts ~~~~~~~~~~~~~~~~~~~~~~~ -If you add an entry with a name that conflicts with an internal container property—e.g., 'nwbdatainterface' or 'dynamictable' from :class:types.core.ProcessingModule—MatNWB will automatically append an underscore. Note that using such names is not recommended. +If you add an entry with a name that conflicts with an internal container property—e.g., ``nwbdatainterface`` or ``dynamictable`` from :class:`types.core.ProcessingModule`—MatNWB will automatically append an underscore. Note that using such names is not recommended. .. code-block:: MATLAB @@ -344,7 +344,7 @@ MatNWB provides different display modes for container types to control how entri You can change the display mode using MATLAB's ``setpref`` function with the preference group ``'matnwb'`` and preference name ``'ContainerDisplayMode'``. -Create a processing module with some entries and see the different display modes: +The following example creates a processing module with some entries to demonstrate the different display modes: .. code-block:: MATLAB From 6e5daec8a2b94c42de2fab8c7fc1ff660494a10e Mon Sep 17 00:00:00 2001 From: ehennestad Date: Fri, 5 Dec 2025 21:47:01 +0100 Subject: [PATCH 61/65] Clarify troubleshooting section in container docs Updated troubleshooting headings and descriptions in the 'working_with_containers.rst' documentation for improved clarity. Headings now more clearly describe property name conflicts, duplicate names, and error handling scenarios in MatNWB. --- .../pages/how_to/working_with_containers.rst | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/docs/source/pages/how_to/working_with_containers.rst b/docs/source/pages/how_to/working_with_containers.rst index aa5f49b49..e0e97a8f2 100644 --- a/docs/source/pages/how_to/working_with_containers.rst +++ b/docs/source/pages/how_to/working_with_containers.rst @@ -214,8 +214,8 @@ You can also use the ``getAliasMap()`` method to retrieve a table showing the na Troubleshooting --------------- -Property name conflicts -~~~~~~~~~~~~~~~~~~~~~~~ +My property name conflicts with an internal name +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If you add an entry with a name that conflicts with an internal container property—e.g., ``nwbdatainterface`` or ``dynamictable`` from :class:`types.core.ProcessingModule`—MatNWB will automatically append an underscore. Note that using such names is not recommended. @@ -229,9 +229,10 @@ If you add an entry with a name that conflicts with an internal container proper % Access it with an underscore appended someObject = processingModule.nwbdatainterface_; -Duplicate names -~~~~~~~~~~~~~~~ -If you add multiple objects with the same name (case-insensitive), MatNWB will append numeric suffixes to create unique property names: +Entries have the same name after conversion +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you add multiple objects with the same name (alias), MatNWB will append numeric suffixes to create unique property names: .. code-block:: MATLAB @@ -246,8 +247,8 @@ If you add multiple objects with the same name (case-insensitive), MatNWB will a data2 = processingModule.My_Data_1; % First duplicate data3 = processingModule.My_Data_2; % Second duplicate -Name not found error -~~~~~~~~~~~~~~~~~~~~ +I get an error when accessing a property +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If you try to access a property that doesn't exist, you'll get an error. Always check first or handle the error: From ac3e43adee6604446fe7331a0cdb3e3316b38c0e Mon Sep 17 00:00:00 2001 From: ehennestad Date: Fri, 5 Dec 2025 21:55:39 +0100 Subject: [PATCH 62/65] Update working_with_containers.rst --- docs/source/pages/how_to/working_with_containers.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/source/pages/how_to/working_with_containers.rst b/docs/source/pages/how_to/working_with_containers.rst index e0e97a8f2..b8c24c741 100644 --- a/docs/source/pages/how_to/working_with_containers.rst +++ b/docs/source/pages/how_to/working_with_containers.rst @@ -9,6 +9,9 @@ This guide shows you how to work with NWB properties and types that are designed :local: :depth: 2 +.. + todo: Move overview to a concepts page + Overview -------- Some neurodata types and properties of neurodata types in NWB are designed to hold one or more data objects of specific types. We will refer to these neurodata types and properties as **containers**. For example, both the ``acquisition`` property of a :class:`types.core.NWBFile` and the :class:`types.core.ProcessingModule` neurodata type can contain multiple data objects of :class:`types.core.NWBDataInterface` or :class:`types.hdmf_common.DynamicTable` types (including subtypes). From 109f84ee2bb8a3b13d68045f588205d593a392aa Mon Sep 17 00:00:00 2001 From: ehennestad Date: Fri, 5 Dec 2025 21:57:46 +0100 Subject: [PATCH 63/65] Update working_with_containers.rst --- docs/source/pages/how_to/working_with_containers.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/source/pages/how_to/working_with_containers.rst b/docs/source/pages/how_to/working_with_containers.rst index b8c24c741..4be7be21f 100644 --- a/docs/source/pages/how_to/working_with_containers.rst +++ b/docs/source/pages/how_to/working_with_containers.rst @@ -217,8 +217,8 @@ You can also use the ``getAliasMap()`` method to retrieve a table showing the na Troubleshooting --------------- -My property name conflicts with an internal name -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Name of entry conflicts with an internal name +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If you add an entry with a name that conflicts with an internal container property—e.g., ``nwbdatainterface`` or ``dynamictable`` from :class:`types.core.ProcessingModule`—MatNWB will automatically append an underscore. Note that using such names is not recommended. From d49bc3c0e3818e4dccf4b6360c117bb172ab4b0f Mon Sep 17 00:00:00 2001 From: ehennestad Date: Fri, 5 Dec 2025 22:15:11 +0100 Subject: [PATCH 64/65] Fix failing test Fix name of preference --- +tests/+unit/HasUnnamedGroupsTest.m | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/+tests/+unit/HasUnnamedGroupsTest.m b/+tests/+unit/HasUnnamedGroupsTest.m index 81a4be068..cb1247809 100644 --- a/+tests/+unit/HasUnnamedGroupsTest.m +++ b/+tests/+unit/HasUnnamedGroupsTest.m @@ -215,17 +215,17 @@ function testObjectDisplay(testCase) module.add('DynamicTable', types.hdmf_common.DynamicTable()); % Verify both display modes - origPrefValue = getpref('matnwb', 'displaymode', 'flat'); - testCase.addTeardown(@() setpref('matnwb', 'displaymode', origPrefValue)) + origPrefValue = getpref('matnwb', 'ContainerDisplayMode', 'flat'); + testCase.addTeardown(@() setpref('matnwb', 'ContainerDisplayMode', origPrefValue)) - setpref('matnwb', 'displaymode', 'flat') + setpref('matnwb', 'ContainerDisplayMode', 'flat') C = evalc('disp(module)'); testCase.verifyFalse(contains(C, 'nwbdatainterface group')) testCase.verifyFalse(contains(C, 'dynamictable group')) testCase.verifyTrue(contains(C, 'TimeSeries:')) testCase.verifyTrue(contains(C, 'DynamicTable:')) - setpref('matnwb', 'displaymode', 'groups') + setpref('matnwb', 'ContainerDisplayMode', 'groups') C = evalc('disp(module)'); testCase.verifyTrue(contains(C, 'nwbdatainterface group')) testCase.verifyTrue(contains(C, 'dynamictable group')) From b183bc59aa9ec0b1ce298cf9aa8107fe63798a60 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Sat, 6 Dec 2025 09:13:26 +0100 Subject: [PATCH 65/65] Hide and seal addprop method in Set class Introduces a Hidden, Sealed addprop method in the Set class to prevent its reimplementation while keeping it accessible internally. This change enhances encapsulation and control over dynamic property addition. --- +types/+untyped/Set.m | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/+types/+untyped/Set.m b/+types/+untyped/Set.m index 12529bbbc..3ef31c6ae 100644 --- a/+types/+untyped/Set.m +++ b/+types/+untyped/Set.m @@ -209,6 +209,13 @@ function setValidationFunction(obj, functionHandle) T = obj.PropertyManager.getPropertyMappingTable(); end end + + methods (Hidden, Sealed) + function p = addprop(obj, name) + % No reimplementation - just hide method + p = addprop@dynamicprops(obj, name); + end + end methods (Hidden) % Legacy set/get methods function obj = set(obj, names, values, options)