From b7aca5890352d419edfdd4a9626b70e06c25b06d Mon Sep 17 00:00:00 2001
From: Michael Innerberger <michael.innerberger@asc.tuwien.ac.at>
Date: Wed, 9 Aug 2023 14:40:19 -0400
Subject: [PATCH] Change type struct to dictionary to avoid frequent reflective
 calls

---
 lib/storage/@LevelData/LevelData.m            | 29 ++++++++++++-------
 lib/storage/@LevelData/get.m                  |  2 +-
 lib/storage/@LevelData/set.m                  |  2 +-
 lib/storage/@LevelData/setAbsolute.m          |  2 +-
 lib/storage/@LevelData/setTime.m              |  2 +-
 .../LevelDataCollection.m                     |  4 +--
 6 files changed, 24 insertions(+), 17 deletions(-)

diff --git a/lib/storage/@LevelData/LevelData.m b/lib/storage/@LevelData/LevelData.m
index 8c0baa8..1d92859 100644
--- a/lib/storage/@LevelData/LevelData.m
+++ b/lib/storage/@LevelData/LevelData.m
@@ -19,21 +19,26 @@ classdef LevelData < handle
 
     properties
         % map for general metadata
-        metaData
+        metaData (1,1) dictionary
         % Root folder for file storage
         root
         % Structure array storing string representations of variables
         dictionary
-        % Cell array of level data
+        % Array of level data
         level (1,:) struct
-        % Structure array of data types
-        type (1,1) struct
+        % Dictionary of data types
+        type (1,1) dictionary
         % Cell array of names of absolute value variables
         absoluteVariable (1,:) cell
         % Cell array of names of timing variables
         timeVariable (1,:) cell
     end
 
+    properties (Access=private)
+        % Dictionary of categories for cataloguing and plotting
+        category (1,1) dictionary
+    end
+
     properties (Dependent)
         % Path to folder for file storage
         foldername (1,:) char
@@ -89,6 +94,8 @@ classdef LevelData < handle
                 obj.metaData("timestamp") = char(datetime('now', 'Format', 'yyyy-MM-dd_HH:mm:ss'));
             end
 
+            obj.category = dictionary();
+
             ensureFolderExists(obj.root);
             % Initialise dictionary with some default values
             obj.dictionary = getDefaultDictionary();
@@ -140,7 +147,7 @@ classdef LevelData < handle
             % contains a scalar value per level only
             bool = false(1, obj.nVariable);
             for j = 1:obj.nVariable
-                t = obj.type.(obj.label{j});
+                t = obj.type(obj.label{j});
                 if strcmp(t.shape, 's')
                     bool(j) = true;
                 end
@@ -225,11 +232,11 @@ classdef LevelData < handle
             end
 
             arguments (Repeating)
-                variableName
+                variableName {mustBeTextScalar}
             end
 
-            obj.level = rmfield(obj.level, variableName{:});
-            obj.type = rmfield(obj.type, variableName{:});
+            obj.level = rmfield(obj.level, variableName);
+            obj.type(variableName) = [];
         end
 
         function removeLevel(obj, jLevel)
@@ -246,7 +253,7 @@ classdef LevelData < handle
             %e.g., to reduce storage size
             %   REMOVENONSCALAR(obj)
             variableNonScalar = setdiff(obj.label, obj.scalarVariable);
-            obj.remove(variableNonScalar);
+            obj.remove(variableNonScalar{:});
         end
 
         %% OUTPUT LEVEL DATA
@@ -279,7 +286,7 @@ classdef LevelData < handle
             % Creates formatting string for the header of the output to command line
             spec = cell(1, obj.nScalarVariable);
             for j = 1:obj.nScalarVariable
-                t = obj.type.(obj.scalarVariable{j});
+                t = obj.type(obj.scalarVariable{j});
                 spec{j} = assembleSpecifier(obj.getWidth(t), 's');
             end
             spec = strjoin(spec, separator) + "\n";
@@ -289,7 +296,7 @@ classdef LevelData < handle
             % Creates formatting string for printing to command line
             spec = cell(1, obj.nScalarVariable);
             for j = 1:obj.nScalarVariable
-                t = obj.type.(obj.scalarVariable{j});
+                t = obj.type(obj.scalarVariable{j});
                 spec{j} = assembleSpecifier(obj.getWidth(t), t.formatSpec);
             end
             spec = strjoin(spec, separator) + "\n";
diff --git a/lib/storage/@LevelData/get.m b/lib/storage/@LevelData/get.m
index 9d06178..585f809 100644
--- a/lib/storage/@LevelData/get.m
+++ b/lib/storage/@LevelData/get.m
@@ -71,7 +71,7 @@ function data = get(obj, jLevel, variableName)
         % Save extracted data to return variable
         data(:,jVariable) = value;
         % Post-process character arrays
-        if obj.type.(name).rawType == RawType.TEXT
+        if obj.type(name).rawType == RawType.TEXT
             data = mat2cell(char(data), ones(length(data), 1));
         end
     end
diff --git a/lib/storage/@LevelData/set.m b/lib/storage/@LevelData/set.m
index 07a284d..6f4434e 100644
--- a/lib/storage/@LevelData/set.m
+++ b/lib/storage/@LevelData/set.m
@@ -53,7 +53,7 @@ function set(obj, jLevel, variableName, value)
         end
         % Store type
         if ~ismember(name, obj.label)
-            obj.type.(name) = currentType.adaptPrintWidthTo(name);
+            obj.type(name) = currentType.adaptPrintWidthTo(name);
         end
         % Store level-oriented data
         for k = 1:length(jLevel)
diff --git a/lib/storage/@LevelData/setAbsolute.m b/lib/storage/@LevelData/setAbsolute.m
index 0c3f750..d0f07d2 100644
--- a/lib/storage/@LevelData/setAbsolute.m
+++ b/lib/storage/@LevelData/setAbsolute.m
@@ -57,7 +57,7 @@ function setAbsolute(obj, jLevel, variableName, value)
 
         if ~ismember(name, obj.absoluteVariable)
             % Store type
-            obj.type.(name) = currentType.adaptPrintWidthTo(name);
+            obj.type(name) = currentType.adaptPrintWidthTo(name);
             % Store variable as absolute variable
             obj.absoluteVariable{end+1} = name;
         end
diff --git a/lib/storage/@LevelData/setTime.m b/lib/storage/@LevelData/setTime.m
index f61a6a8..958a0fa 100644
--- a/lib/storage/@LevelData/setTime.m
+++ b/lib/storage/@LevelData/setTime.m
@@ -56,7 +56,7 @@ function setTime(obj, jLevel, variableName, value)
         end
         % Store type
         if ~ismember(name, obj.label)
-            obj.type.(name) = currentType.adaptPrintWidthTo(name);
+            obj.type(name) = currentType.adaptPrintWidthTo(name);
         end
         % Store variable as absolute variable
         if ~ismember(name, obj.timeVariable)
diff --git a/lib/storage/@LevelDataCollection/LevelDataCollection.m b/lib/storage/@LevelDataCollection/LevelDataCollection.m
index b39eb8c..cfb332b 100644
--- a/lib/storage/@LevelDataCollection/LevelDataCollection.m
+++ b/lib/storage/@LevelDataCollection/LevelDataCollection.m
@@ -126,7 +126,7 @@ classdef LevelDataCollection < handle
             % to command line
             spec = [' run', obj.separator];
             for j = 1:obj.nTimeVariable
-                t = obj.item{1}.type.(obj.timeVariable{j});
+                t = obj.item{1}.type(obj.timeVariable{j});
                 if j < obj.nTimeVariable
                     spec = [spec, '%', obj.getWidth(t), 's', obj.separator]; %#ok<*AGROW>
                 else
@@ -142,7 +142,7 @@ classdef LevelDataCollection < handle
             % Creates formatting string for printing to command line
             spec = ['%4d', obj.separator];
             for j = 1:obj.nTimeVariable
-                t = obj.item{1}.type.(obj.timeVariable{j});
+                t = obj.item{1}.type(obj.timeVariable{j});
                 if j < obj.nTimeVariable
                     spec = [spec, '%', obj.getWidth(t), t.formatSpec, obj.separator];
                 else
-- 
GitLab