From 0d4dbe77bc8ca9bdaacf9cc093dd3f7392aaa26c Mon Sep 17 00:00:00 2001 From: ehennestad Date: Fri, 6 Mar 2026 13:56:44 +0100 Subject: [PATCH 01/10] Update getSchemaName.m Remove concatenation of structs. Structs might have different fields, and the concatenation would fail. Only need name and potentially label, so explicitly get these instead of relying on struct concatenation --- code/internal/+openminds/+internal/+vocab/getSchemaName.m | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/code/internal/+openminds/+internal/+vocab/getSchemaName.m b/code/internal/+openminds/+internal/+vocab/getSchemaName.m index c9130968..e10bf6d6 100644 --- a/code/internal/+openminds/+internal/+vocab/getSchemaName.m +++ b/code/internal/+openminds/+internal/+vocab/getSchemaName.m @@ -24,14 +24,12 @@ end C = struct2cell(typesVocab); - S = [C{:}]; - - allNames = {S.name}; + allNames = cellfun(@(c) string(c.name), C); isMatch = strcmpi(allNames, nameAlias); if ~any(isMatch) - allLabels = {S.label}; + allLabels = cellfun(@(c) string(c.label), C); isMatch = strcmpi(allLabels, nameAlias); end From dc56c7c21fa7da0c1ca7c5e174cb1ee086d55c3a Mon Sep 17 00:00:00 2001 From: ehennestad Date: Thu, 26 Mar 2026 21:42:17 +0100 Subject: [PATCH 02/10] Warn once for unmapped instance folders Replace a hard error for unimplemented instance folder names with a warning that is emitted only once per unique folder name. Introduces a containers.Map (hasWarned) to track which folder names have already triggered the warning and uses the identifier 'OPENMINDS:InstanceLibrary:createInstanceTable:MissingTypeMapping'. This avoids aborting execution for unmapped folders while preventing repeated duplicate warnings. --- .../+internal/@InstanceLibrary/InstanceLibrary.m | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/code/internal/+openminds/+internal/@InstanceLibrary/InstanceLibrary.m b/code/internal/+openminds/+internal/@InstanceLibrary/InstanceLibrary.m index 333e1cbc..de242631 100644 --- a/code/internal/+openminds/+internal/@InstanceLibrary/InstanceLibrary.m +++ b/code/internal/+openminds/+internal/@InstanceLibrary/InstanceLibrary.m @@ -148,6 +148,9 @@ function postSetLibraryVersion(obj) numInstances = numel(filePaths); [types, modules, subGroups] = deal(repmat("", numInstances, 1)); + + hasWarned = containers.Map(); + for i = 1:numInstances thisFolderSplit = split(folderNames(i), filesep); @@ -179,7 +182,13 @@ function postSetLibraryVersion(obj) modules(i) = "core"; subGroups(i) = missing; else - error('The instance folder with name "%s" is not implemented. Please report', thisFolderSplit(1)) + + if ~isKey(hasWarned, thisFolderSplit(1)) + warning('OPENMINDS:InstanceLibrary:createInstanceTable:MissingTypeMapping', ... + ['The instance folder with name "%s" is not ', ... + 'mapped to an openMINDS type. Please report'], thisFolderSplit(1)) + hasWarned(thisFolderSplit(1)) = true; + end end end From 86ced8e4928b917ff1721105cb097c2cbcc23c10 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Thu, 26 Mar 2026 22:08:12 +0100 Subject: [PATCH 03/10] Update getModelVersion.m --- code/internal/+openminds/getModelVersion.m | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/code/internal/+openminds/getModelVersion.m b/code/internal/+openminds/getModelVersion.m index 556207e3..c6172a44 100644 --- a/code/internal/+openminds/getModelVersion.m +++ b/code/internal/+openminds/getModelVersion.m @@ -29,6 +29,12 @@ end versionNum = cachedVersionNumber; + % Todo: remove. Pin latest version to v4.0 as v5.0 is not supported yet. + if versionNum == "latest" + versionNum = openminds.internal.utility.VersionNumber("4.0"); + versionNum.Format = "vX.Y"; + end + if outputType == "char" versionNum = char(versionNum); end From bfd797f0f6cbe4f7da1c4494ae7fed77c8b6e618 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Thu, 26 Mar 2026 22:30:20 +0100 Subject: [PATCH 04/10] Temporarily skip latest model version assertion in MetaTypeTest --- tools/tests/+ommtest/+internal/MetaTypeTest.m | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/tests/+ommtest/+internal/MetaTypeTest.m b/tools/tests/+ommtest/+internal/MetaTypeTest.m index 6452a9d6..29fffd34 100644 --- a/tools/tests/+ommtest/+internal/MetaTypeTest.m +++ b/tools/tests/+ommtest/+internal/MetaTypeTest.m @@ -6,7 +6,8 @@ function testRegistrySingleton(testCase) registry = MetaTypeRegistry.getSingleton(); testCase.verifyClass(registry, 'openminds.internal.meta.MetaTypeRegistry'); - testCase.verifyEqual(registry.ModelVersion, "latest") + % Todo: uncomment. Currently pinned to v4.0 as v5.0 is not supported yet. + % testCase.verifyEqual(registry.ModelVersion, "latest") % Verify that we get the same handle if we ask for the singleton again newRegistry = MetaTypeRegistry.getSingleton(); From 609019cf254a579b4c795103bb46d72ea79c5173 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Thu, 26 Mar 2026 22:47:56 +0100 Subject: [PATCH 05/10] debug uriJoin --- code/internal/+openminds/+internal/+utility/+string/uriJoin.m | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/code/internal/+openminds/+internal/+utility/+string/uriJoin.m b/code/internal/+openminds/+internal/+utility/+string/uriJoin.m index 7eef8820..7b8048cf 100644 --- a/code/internal/+openminds/+internal/+utility/+string/uriJoin.m +++ b/code/internal/+openminds/+internal/+utility/+string/uriJoin.m @@ -1,5 +1,6 @@ function strURI = uriJoin(varargin) %uriJoin Join segments of a URI using the forward slash (/) + try if isa(varargin{1}, 'string') listOfStrings = [varargin{:}]; strURI = join(listOfStrings, "/"); @@ -7,4 +8,7 @@ listOfStrings = varargin; strURI = strjoin(listOfStrings, '/'); end + catch + disp(varargin{:}) + end end From 05b60117931ac24bf073d651a6510edac9045fbe Mon Sep 17 00:00:00 2001 From: ehennestad Date: Thu, 26 Mar 2026 22:54:00 +0100 Subject: [PATCH 06/10] debug urijoin --- code/internal/+openminds/+internal/+utility/+string/uriJoin.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/internal/+openminds/+internal/+utility/+string/uriJoin.m b/code/internal/+openminds/+internal/+utility/+string/uriJoin.m index 7b8048cf..7768a5fb 100644 --- a/code/internal/+openminds/+internal/+utility/+string/uriJoin.m +++ b/code/internal/+openminds/+internal/+utility/+string/uriJoin.m @@ -9,6 +9,6 @@ strURI = strjoin(listOfStrings, '/'); end catch - disp(varargin{:}) + varargin{:} end end From 819298b29b61c514acbb7cff0c9900dbdd94292f Mon Sep 17 00:00:00 2001 From: ehennestad Date: Thu, 26 Mar 2026 23:02:37 +0100 Subject: [PATCH 07/10] debug --- code/internal/+openminds/+internal/+utility/+string/uriJoin.m | 1 + tools/tests/unitTests/InstanceTest.m | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/code/internal/+openminds/+internal/+utility/+string/uriJoin.m b/code/internal/+openminds/+internal/+utility/+string/uriJoin.m index 7768a5fb..61103f10 100644 --- a/code/internal/+openminds/+internal/+utility/+string/uriJoin.m +++ b/code/internal/+openminds/+internal/+utility/+string/uriJoin.m @@ -10,5 +10,6 @@ end catch varargin{:} + error('Debug') end end diff --git a/tools/tests/unitTests/InstanceTest.m b/tools/tests/unitTests/InstanceTest.m index 8bd0239d..b5cc6385 100644 --- a/tools/tests/unitTests/InstanceTest.m +++ b/tools/tests/unitTests/InstanceTest.m @@ -41,7 +41,11 @@ function testCreateType(testCase, MetadataType) end function dispNoOutput(instance) %#ok + try c = evalc('disp(instance)'); %#ok + catch + disp(c) + end end end From 51f2de547c4987cc7ea6cb07589b07055943dd48 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Thu, 26 Mar 2026 23:24:05 +0100 Subject: [PATCH 08/10] Remove debug code, more targeted version pin in getControlledInstances --- .../+openminds/+internal/+utility/+string/uriJoin.m | 5 ----- .../+openminds/+internal/getControlledInstance.m | 9 ++++++++- code/internal/+openminds/getModelVersion.m | 6 ------ tools/tests/+ommtest/+internal/MetaTypeTest.m | 3 +-- tools/tests/unitTests/InstanceTest.m | 4 ---- 5 files changed, 9 insertions(+), 18 deletions(-) diff --git a/code/internal/+openminds/+internal/+utility/+string/uriJoin.m b/code/internal/+openminds/+internal/+utility/+string/uriJoin.m index 61103f10..7eef8820 100644 --- a/code/internal/+openminds/+internal/+utility/+string/uriJoin.m +++ b/code/internal/+openminds/+internal/+utility/+string/uriJoin.m @@ -1,6 +1,5 @@ function strURI = uriJoin(varargin) %uriJoin Join segments of a URI using the forward slash (/) - try if isa(varargin{1}, 'string') listOfStrings = [varargin{:}]; strURI = join(listOfStrings, "/"); @@ -8,8 +7,4 @@ listOfStrings = varargin; strURI = strjoin(listOfStrings, '/'); end - catch - varargin{:} - error('Debug') - end end diff --git a/code/internal/+openminds/+internal/getControlledInstance.m b/code/internal/+openminds/+internal/getControlledInstance.m index d8d7c7d3..833794c7 100644 --- a/code/internal/+openminds/+internal/getControlledInstance.m +++ b/code/internal/+openminds/+internal/getControlledInstance.m @@ -13,6 +13,13 @@ if ismissing(versionNumber) versionNumber = openminds.getModelVersion("VersionNumber"); end + + % Todo: remove. Pin latest version to v4.0 as instances from v5.0 are not + % supported yet. + if versionNumber == "latest" + versionNumber = openminds.internal.utility.VersionNumber("4.0"); + versionNumber.Format = "vX.Y"; + end versionNumber = string(versionNumber); % Make type name lowercase unless it is an abbreviated typename like @@ -51,7 +58,7 @@ % assert(size(instanceTable, 1) == 1, 'Expected a single match for instance "%s", but %d was found.', instanceName, size(instanceTable, 1)) % jsonStr = fileread(instanceTable.Filepath); - + filePath = getOfflineFilepath(instanceName, schemaName, moduleName, versionNumber); if ~isfile(filePath) diff --git a/code/internal/+openminds/getModelVersion.m b/code/internal/+openminds/getModelVersion.m index c6172a44..556207e3 100644 --- a/code/internal/+openminds/getModelVersion.m +++ b/code/internal/+openminds/getModelVersion.m @@ -29,12 +29,6 @@ end versionNum = cachedVersionNumber; - % Todo: remove. Pin latest version to v4.0 as v5.0 is not supported yet. - if versionNum == "latest" - versionNum = openminds.internal.utility.VersionNumber("4.0"); - versionNum.Format = "vX.Y"; - end - if outputType == "char" versionNum = char(versionNum); end diff --git a/tools/tests/+ommtest/+internal/MetaTypeTest.m b/tools/tests/+ommtest/+internal/MetaTypeTest.m index 29fffd34..6452a9d6 100644 --- a/tools/tests/+ommtest/+internal/MetaTypeTest.m +++ b/tools/tests/+ommtest/+internal/MetaTypeTest.m @@ -6,8 +6,7 @@ function testRegistrySingleton(testCase) registry = MetaTypeRegistry.getSingleton(); testCase.verifyClass(registry, 'openminds.internal.meta.MetaTypeRegistry'); - % Todo: uncomment. Currently pinned to v4.0 as v5.0 is not supported yet. - % testCase.verifyEqual(registry.ModelVersion, "latest") + testCase.verifyEqual(registry.ModelVersion, "latest") % Verify that we get the same handle if we ask for the singleton again newRegistry = MetaTypeRegistry.getSingleton(); diff --git a/tools/tests/unitTests/InstanceTest.m b/tools/tests/unitTests/InstanceTest.m index b5cc6385..8bd0239d 100644 --- a/tools/tests/unitTests/InstanceTest.m +++ b/tools/tests/unitTests/InstanceTest.m @@ -41,11 +41,7 @@ function testCreateType(testCase, MetadataType) end function dispNoOutput(instance) %#ok - try c = evalc('disp(instance)'); %#ok - catch - disp(c) - end end end From 4a8f103a0726d07d5e118b514a4d7c2256292099 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Thu, 26 Mar 2026 23:24:58 +0100 Subject: [PATCH 09/10] Update getControlledInstance.m --- code/internal/+openminds/+internal/getControlledInstance.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/internal/+openminds/+internal/getControlledInstance.m b/code/internal/+openminds/+internal/getControlledInstance.m index 833794c7..87c151a9 100644 --- a/code/internal/+openminds/+internal/getControlledInstance.m +++ b/code/internal/+openminds/+internal/getControlledInstance.m @@ -58,7 +58,7 @@ % assert(size(instanceTable, 1) == 1, 'Expected a single match for instance "%s", but %d was found.', instanceName, size(instanceTable, 1)) % jsonStr = fileread(instanceTable.Filepath); - + filePath = getOfflineFilepath(instanceName, schemaName, moduleName, versionNumber); if ~isfile(filePath) From 62b5c510d61f4f6f5ee89245bef4cc5b10a01576 Mon Sep 17 00:00:00 2001 From: ehennestad Date: Thu, 26 Mar 2026 23:41:03 +0100 Subject: [PATCH 10/10] Update testReadTheDocLinks.m Replace UBERONParcellation with BiologicalSex. UBERONParcellation has been removed in latest --- tools/tests/unitTests/testReadTheDocLinks.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/tests/unitTests/testReadTheDocLinks.m b/tools/tests/unitTests/testReadTheDocLinks.m index bc8af99c..62320deb 100644 --- a/tools/tests/unitTests/testReadTheDocLinks.m +++ b/tools/tests/unitTests/testReadTheDocLinks.m @@ -31,18 +31,18 @@ function testInvalidDocumentationUrl(testCase) 'MATLAB:webservices:HTTP404StatusCodeError') end - function testSchemaDocLinkUBERONParcellation(testCase) + function testSchemaDocLinkBiologicalSex(testCase) import openminds.internal.utility.getSchemaDocLink url = getSchemaDocLink(... - "openminds.controlledterms.UBERONParcellation", ... + "openminds.controlledterms.BiologicalSex", ... "Raw URL"); try webread(url); catch ME errorMessage = sprintf([... - 'Failed to read documentation for UBERONParcellation with error:\n', ... + 'Failed to read documentation for BiologicalSex with error:\n', ... '%s'], ME.message); testCase.verifyFail(errorMessage) end