diff --git a/lib/storage/@LevelData/LevelData.m b/lib/storage/@LevelData/LevelData.m
index 8c0baa8d3bc677b973dc0d04f54538e58da7b232..1d92859a38d61f6709d75559a926cdcfb16265e3 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 9d061780cdffafda5cd56d173b46f164de953e91..585f8090b5149de0b00c11c17e8e6012ab43470c 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 07a284d3a6c754ce5bfd3eb78275cce2e995b66e..6f4434e1aecc846693280b7155d8b19096c363de 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 0c3f750652bca176bfe1b40538e65573a2188b0a..d0f07d280788095be36f54149d10454bfec66e88 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 f61a6a8786a1c05317db8d71f873fa6da04ad07b..958a0fad58b86c67898295a94efcf4ac02d7864a 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 b39eb8c6a6edb06877b252644dd1892bbc657896..cfb332bf08806e4ec6f85cd7a03ef5619e3b7f1a 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