From 53bc521ad805710e88ad2a1561c561e595ab984a Mon Sep 17 00:00:00 2001
From: Michael Innerberger <michael.innerberger@asc.tuwien.ac.at>
Date: Wed, 9 Aug 2023 15:28:37 -0400
Subject: [PATCH] Use DataCategory in storage of variables

---
 lib/storage/@LevelData/LevelData.m    | 35 +++++++++------------------
 lib/storage/@LevelData/get.m          |  6 +----
 lib/storage/@LevelData/plot.m         |  9 -------
 lib/storage/@LevelData/plotAbsolute.m |  5 ----
 lib/storage/@LevelData/plotLevel.m    | 12 ++++++---
 lib/storage/@LevelData/plotTime.m     |  5 ----
 lib/storage/@LevelData/set.m          |  8 +++---
 lib/storage/@LevelData/setAbsolute.m  |  9 +++----
 lib/storage/@LevelData/setTime.m      | 12 ++++-----
 9 files changed, 35 insertions(+), 66 deletions(-)

diff --git a/lib/storage/@LevelData/LevelData.m b/lib/storage/@LevelData/LevelData.m
index 1d92859..a41af48 100644
--- a/lib/storage/@LevelData/LevelData.m
+++ b/lib/storage/@LevelData/LevelData.m
@@ -28,10 +28,6 @@ classdef LevelData < handle
         level (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)
@@ -60,6 +56,10 @@ classdef LevelData < handle
         nTimeVariable (1,1) int32
         % Boolean indicating whether data has been stored for a single level
         isInitialRun (1,1) logical
+        % Cell array of names of absolute value variables
+        absoluteVariable (1,:) cell
+        % Cell array of names of timing variables
+        timeVariable (1,:) cell
     end
 
     properties (Dependent, Access=private)
@@ -145,25 +145,12 @@ classdef LevelData < handle
         function bool = get.isScalar(obj)
             % Creates boolean vector determining whether a variable
             % contains a scalar value per level only
-            bool = false(1, obj.nVariable);
-            for j = 1:obj.nVariable
-                t = obj.type(obj.label{j});
-                if strcmp(t.shape, 's')
-                    bool(j) = true;
-                end
-            end
+            bool = [obj.type(obj.label).isScalar]';
         end
 
         function variables = get.scalarVariable(obj)
             % Returns list of names of all scalar variables
-            variables = cell(obj.nScalarVariable, 1);
-            k = 1;
-            for j = 1:obj.nVariable
-                if obj.isScalar(j)
-                    variables{k} = obj.label{j};
-                    k = k + 1;
-                end
-            end
+            variables = obj.label(obj.isScalar);
         end
 
         function nVariable = get.nScalarVariable(obj)
@@ -172,20 +159,22 @@ classdef LevelData < handle
 
         function variables = get.timeVariable(obj)
             % Returns list of names of all time variables
-            variables = obj.timeVariable;
+            idx = (obj.category(obj.label) == DataCategory.TIME);
+            variables = obj.label(idx);
         end
 
         function nVariable = get.nTimeVariable(obj)
-            nVariable = length(obj.timeVariable);
+            nVariable = nnz(obj.category.values() == DataCategory.TIME);
         end
 
         function variables = get.absoluteVariable(obj)
             % Returns list of names of all absolute variables
-            variables = obj.absoluteVariable;
+            idx = (obj.category(obj.label) == DataCategory.ABSOLUTE);
+            variables = obj.label(idx);
         end
 
         function nVariable = get.nAbsoluteVariable(obj)
-            nVariable = length(obj.absoluteVariable);
+            nVariable = nnz(obj.category.values() == DataCategory.ABSOLUTE);
         end
 
         function bool = get.isInitialRun(obj)
diff --git a/lib/storage/@LevelData/get.m b/lib/storage/@LevelData/get.m
index 585f809..c130089 100644
--- a/lib/storage/@LevelData/get.m
+++ b/lib/storage/@LevelData/get.m
@@ -36,7 +36,6 @@ function data = get(obj, jLevel, variableName)
 
     % Initialise return variable
     data = nan(length(jLevel), length(variableName));
-    containsCharOnly = true;
 
     % filter non-existing variables
     existingVariables = ismember(variableName, obj.label);
@@ -53,10 +52,7 @@ function data = get(obj, jLevel, variableName)
         idx = obj.getIndex(name);
         if obj.isScalar(idx)
             % Extract scalar variables for each level
-            value = zeros(length(jLevel), 1);
-            for k = 1:length(jLevel)
-                value(k) = obj.level(jLevel(k)).(name);
-            end
+            value = [obj.level.(name)];
         else
             % Extract non-scalar variables only in case of a single level
             if length(jLevel) > 1
diff --git a/lib/storage/@LevelData/plot.m b/lib/storage/@LevelData/plot.m
index 008d133..1151963 100644
--- a/lib/storage/@LevelData/plot.m
+++ b/lib/storage/@LevelData/plot.m
@@ -34,14 +34,5 @@ function ax = plot(obj, xVariable, yVariable)
         yVariable = setdiff(obj.label, xVariable);
     end
 
-    % TODO: introduce plot specification to allow for different plot types (time, absolute, level)
-
-    % Plot only scalar variables that do not belong to time or absolute
-    % variables
-    yVariable = intersect(yVariable, obj.scalarVariable);
-    yVariable = setdiff(yVariable, obj.absoluteVariable);
-    yVariable = setdiff(yVariable, obj.timeVariable);
-
-    % Creates double logarithmic splot 
     ax = obj.plotLevel(DataCategory.ERROR, xVariable, yVariable);
 end
\ No newline at end of file
diff --git a/lib/storage/@LevelData/plotAbsolute.m b/lib/storage/@LevelData/plotAbsolute.m
index 949b85f..931353f 100644
--- a/lib/storage/@LevelData/plotAbsolute.m
+++ b/lib/storage/@LevelData/plotAbsolute.m
@@ -35,10 +35,5 @@ function ax = plotAbsolute(obj, xVariable, yVariable)
         yVariable = setdiff(obj.label, xVariable);
     end
 
-    % Plot only scalar variables that do belong to absolute variables
-    yVariable = intersect(yVariable, obj.scalarVariable);
-    yVariable = intersect(yVariable, obj.absoluteVariable);
-
-    % Creates semilogx plot 
     ax = obj.plotLevel(DataCategory.ABSOLUTE, xVariable, yVariable);
 end
\ No newline at end of file
diff --git a/lib/storage/@LevelData/plotLevel.m b/lib/storage/@LevelData/plotLevel.m
index 0394ee4..a52dc28 100644
--- a/lib/storage/@LevelData/plotLevel.m
+++ b/lib/storage/@LevelData/plotLevel.m
@@ -28,6 +28,12 @@ function ax = plotLevel(obj, category, xVariable, yVariable)
         yVariable cell
     end
 
+    % Extract variables with correct category, type, and shape for y-axis
+    idx = (obj.category(yVariable) == category) ...
+        & ([obj.type(yVariable).rawType]' == RawType.FLOAT) ...
+        & [obj.type(yVariable).isScalar]';
+    yVariable = yVariable(idx); 
+
     % Create handle to currently active axis object
     ax = gca;
 
@@ -39,18 +45,16 @@ function ax = plotLevel(obj, category, xVariable, yVariable)
 
     % Iterate over given variables
     for j = 1:length(yVariable)
-        if obj.type(yVariable{j}).rawType ~= RawType.FLOAT
-            continue
-        end
-
         % Extract value for y-axis
         yValue = obj.get(1:obj.nLevel, yVariable{j});
+
         % Extract label for legend from dictionary
         if isfield(obj.dictionary, yVariable{j})
             variableLabel = obj.dictionary.(yVariable{j});
         else
             variableLabel = yVariable{j};
         end
+
         % Create plot
         category.plotFunction( ...
                 ax, xValue, yValue, '-', ...
diff --git a/lib/storage/@LevelData/plotTime.m b/lib/storage/@LevelData/plotTime.m
index be72731..3b7693f 100644
--- a/lib/storage/@LevelData/plotTime.m
+++ b/lib/storage/@LevelData/plotTime.m
@@ -34,10 +34,5 @@ function ax = plotTime(obj, xVariable, yVariable)
         yVariable = setdiff(obj.label, xVariable);
     end
 
-    % Plot only scalar variables that do belong to time variables
-    yVariable = intersect(yVariable, obj.scalarVariable);
-    yVariable = intersect(yVariable, obj.timeVariable);
-
-    % Creates double logarithmic splot 
     ax = obj.plotLevel(DataCategory.TIME, xVariable, yVariable);
 end
\ No newline at end of file
diff --git a/lib/storage/@LevelData/set.m b/lib/storage/@LevelData/set.m
index 6f4434e..7a3ee72 100644
--- a/lib/storage/@LevelData/set.m
+++ b/lib/storage/@LevelData/set.m
@@ -42,19 +42,21 @@ function set(obj, jLevel, variableName, value)
     for j = 1:nArgument
         name = variableName{j};
         val = value{j};
-        % Determine type of data
+        
         if isa(val, 'ValueDetails')
             % Copy type argument
             currentType = val;
             valueList = repmat({nan}, length(jLevel), 1);
         else
-            % Determine type by example data
             [valueList, currentType] = splitIntoLevelWiseData(length(jLevel), val);
         end
-        % Store type
+
+        % Store type and category
         if ~ismember(name, obj.label)
             obj.type(name) = currentType.adaptPrintWidthTo(name);
+            obj.category(name) = DataCategory.ERROR;
         end
+
         % Store level-oriented data
         for k = 1:length(jLevel)
             obj.level(jLevel(k)).(name) = valueList{k};
diff --git a/lib/storage/@LevelData/setAbsolute.m b/lib/storage/@LevelData/setAbsolute.m
index d0f07d2..d5fbf92 100644
--- a/lib/storage/@LevelData/setAbsolute.m
+++ b/lib/storage/@LevelData/setAbsolute.m
@@ -45,22 +45,21 @@ function setAbsolute(obj, jLevel, variableName, value)
     for j = 1:nArgument
         name = variableName{j};
         val = value{j};
-        % Determine type of data
+
         if isa(val, 'ValueDetails')
             % Copy type argument
             currentType = val;
             valueList = repmat({nan}, length(jLevel), 1);
         else
-            % Determine type by example data
             [valueList, currentType] = splitIntoLevelWiseData(length(jLevel), val);
         end
 
+        % Store type and category
         if ~ismember(name, obj.absoluteVariable)
-            % Store type
             obj.type(name) = currentType.adaptPrintWidthTo(name);
-            % Store variable as absolute variable
-            obj.absoluteVariable{end+1} = name;
+            obj.category(name) = DataCategory.ABSOLUTE;
         end
+
         % Store level-oriented data
         for k = 1:length(jLevel)
             obj.level(jLevel(k)).(name) = valueList{k};
diff --git a/lib/storage/@LevelData/setTime.m b/lib/storage/@LevelData/setTime.m
index 958a0fa..c492f28 100644
--- a/lib/storage/@LevelData/setTime.m
+++ b/lib/storage/@LevelData/setTime.m
@@ -45,23 +45,21 @@ function setTime(obj, jLevel, variableName, value)
     for j = 1:nArgument
         name = variableName{j};
         val = value{j};
-        % Determine type of data
+
         if isa(val, 'ValueDetails')
             % Copy type argument
             currentType = val;
             valueList = repmat({nan}, length(jLevel), 1);
         else
-            % Determine type by example data
             [valueList, currentType] = splitIntoLevelWiseData(length(jLevel), val);
         end
-        % Store type
+
+        % Store type and category
         if ~ismember(name, obj.label)
             obj.type(name) = currentType.adaptPrintWidthTo(name);
+            obj.category(name) = DataCategory.TIME;
         end
-        % Store variable as absolute variable
-        if ~ismember(name, obj.timeVariable)
-            obj.timeVariable{end+1} = name;
-        end
+
         % Store level-oriented data
         for k = 1:length(jLevel)
             obj.level(jLevel(k)).(name) = valueList{k};
-- 
GitLab