From 6080c6e5501ba5f9492696654465316e05c86ba6 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Tue, 13 Jan 2026 20:19:20 +0100 Subject: [PATCH 1/3] Update getNeurodataTypeInfo.m --- +io/getNeurodataTypeInfo.m | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/+io/getNeurodataTypeInfo.m b/+io/getNeurodataTypeInfo.m index 7e67a6c0..99313797 100644 --- a/+io/getNeurodataTypeInfo.m +++ b/+io/getNeurodataTypeInfo.m @@ -51,7 +51,9 @@ if strcmp(typeInfo.namespace, 'hdmf-experimental') && ~exist(typeInfo.typename, 'class') typeInfo = correctNamespaceIfShouldBeHdmfCommon(typeInfo); - end + elseif strcmp(typeInfo.namespace, 'core') && ~exist(typeInfo.typename, 'class') + typeInfo = correctCoreNamespaceIfShouldBeHdmfCommon(typeInfo); + end end end @@ -77,3 +79,16 @@ end end end + +function typeInfo = correctCoreNamespaceIfShouldBeHdmfCommon(typeInfo) +% correctCoreNamespaceIfShouldBeHdmfCommon - Correct namespace if value in file is wrong. + + + if strcmp(typeInfo.namespace, 'core') && ~exist(typeInfo.typename, 'class') + correctedTypename = replace(typeInfo.typename, 'core', 'hdmf_common'); + if exist(correctedTypename, 'class') == 8 + typeInfo.typename = correctedTypename; + typeInfo.namespace = 'hdmf-common'; + end + end +end From ff964858722eb1e7e27d94af1e5d817493ffcd46 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Tue, 13 Jan 2026 20:31:54 +0100 Subject: [PATCH 2/3] Update getNeurodataTypeInfo.m Add workaround for issue where core namespace was written to file, but namespace should be hdmf_common --- +io/getNeurodataTypeInfo.m | 58 ++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 33 deletions(-) diff --git a/+io/getNeurodataTypeInfo.m b/+io/getNeurodataTypeInfo.m index 99313797..29a283e2 100644 --- a/+io/getNeurodataTypeInfo.m +++ b/+io/getNeurodataTypeInfo.m @@ -49,46 +49,38 @@ typeInfo.typename = char( matnwb.common.composeFullClassName(... typeInfo.namespace, typeInfo.name) ); - if strcmp(typeInfo.namespace, 'hdmf-experimental') && ~exist(typeInfo.typename, 'class') - typeInfo = correctNamespaceIfShouldBeHdmfCommon(typeInfo); - elseif strcmp(typeInfo.namespace, 'core') && ~exist(typeInfo.typename, 'class') - typeInfo = correctCoreNamespaceIfShouldBeHdmfCommon(typeInfo); + if ~exist(typeInfo.typename, 'class') + typeInfo = tryCorrectNamespace(typeInfo); end end end -function typeInfo = correctNamespaceIfShouldBeHdmfCommon(typeInfo) -% correctNamespaceIfShouldBeHdmfCommon - Correct namespace if value in file is wrong. +function typeInfo = tryCorrectNamespace(typeInfo) +% tryCorrectNamespace - Try to correct namespace if type class doesn't exist % -% This function provides a workaround for a bug where the namespace of a -% neurodata type was wrongly written to file as hdmf-experimental instead -% of hdmf-common. -% -% If the namespace of a type is hdmf-experimental, and the corresponding type -% class does not exist in MATLAB, but the equivalent hdmf_common class exists, -% the namespace is changed from hdmf-experimental to hdmf-common. +% Some NWB files have incorrect namespace values written to them. +% This function attempts to find the correct namespace by checking +% if an equivalent class exists in hdmf_common. % -% The bug is described in this issue: -% https://github.com/hdmf-dev/hdmf/issues/1347 +% Known issues: +% - hdmf-experimental instead of hdmf-common (https://github.com/hdmf-dev/hdmf/issues/1347) +% - core instead of hdmf-common (https://github.com/NeurodataWithoutBorders/helpdesk/discussions/104) - if strcmp(typeInfo.namespace, 'hdmf-experimental') && ~exist(typeInfo.typename, 'class') - correctedTypename = replace(typeInfo.typename, 'hdmf_experimental', 'hdmf_common'); - if exist(correctedTypename, 'class') == 8 - typeInfo.typename = correctedTypename; - typeInfo.namespace = 'hdmf-common'; - end + % Map of namespace values that might be incorrectly used instead of hdmf-common + namespaceNames = {'hdmf-experimental', 'core'}; + packageNames = {'hdmf_experimental', 'core'}; % Corresponding MATLAB package names + namespaceToPackage = containers.Map(namespaceNames, packageNames); + + if ~isKey(namespaceToPackage, typeInfo.namespace) + return end -end - -function typeInfo = correctCoreNamespaceIfShouldBeHdmfCommon(typeInfo) -% correctCoreNamespaceIfShouldBeHdmfCommon - Correct namespace if value in file is wrong. - - - if strcmp(typeInfo.namespace, 'core') && ~exist(typeInfo.typename, 'class') - correctedTypename = replace(typeInfo.typename, 'core', 'hdmf_common'); - if exist(correctedTypename, 'class') == 8 - typeInfo.typename = correctedTypename; - typeInfo.namespace = 'hdmf-common'; - end + + currentPackage = namespaceToPackage(typeInfo.namespace); + correctedTypename = strrep(typeInfo.typename, ... + [currentPackage '.'], 'hdmf_common.'); + + if exist(correctedTypename, 'class') == 8 + typeInfo.typename = correctedTypename; + typeInfo.namespace = 'hdmf-common'; end end From 3914ace70c5ebc0ffcd1ae1dcff0de1bf3d47157 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Tue, 13 Jan 2026 20:43:34 +0100 Subject: [PATCH 3/3] Added unittest --- +tests/+unit/+io/GetNeurodataTypeInfoTest.m | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/+tests/+unit/+io/GetNeurodataTypeInfoTest.m b/+tests/+unit/+io/GetNeurodataTypeInfoTest.m index ad49d4a9..38732569 100644 --- a/+tests/+unit/+io/GetNeurodataTypeInfoTest.m +++ b/+tests/+unit/+io/GetNeurodataTypeInfoTest.m @@ -68,6 +68,21 @@ function testHdmfExperimentalFallbackToHdmfCommon(testCase, HDMFCommonType) testCase.verifyEqual(typeInfo.name, HDMFCommonType); testCase.verifyEqual(typeInfo.typename, sprintf('types.hdmf_common.%s', HDMFCommonType)); end + + function testCoreFallbackToHdmfCommon(testCase, HDMFCommonType) + % Test fallback correction for hdmf-common types with incorrect + % core namespace (should be hdmf-common) + attributeInfo = struct(... + 'Name', {'neurodata_type', 'namespace'}, ... + 'Value', {HDMFCommonType, 'core'}); + + typeInfo = io.getNeurodataTypeInfo(attributeInfo); + + % Should be corrected to hdmf-common + testCase.verifyEqual(typeInfo.namespace, 'hdmf-common'); + testCase.verifyEqual(typeInfo.name, HDMFCommonType); + testCase.verifyEqual(typeInfo.typename, sprintf('types.hdmf_common.%s', HDMFCommonType)); + end function testCellStringValueHandling(testCase) % Test that cell string values are handled correctly