diff --git a/lib/storage/@LevelData/LevelData.m b/lib/storage/@LevelData/LevelData.m
index bd02419bbdb9a107ce83508f541d71db005e1f8d..dcfae083c35c84f2758ea5c98079b01f2fdb2c0f 100644
--- a/lib/storage/@LevelData/LevelData.m
+++ b/lib/storage/@LevelData/LevelData.m
@@ -295,7 +295,7 @@ classdef LevelData < handle
                     separator = '\n';
                 end
                 t = obj.type.(obj.scalarVariable{j});
-                spec = [spec, '%', obj.getWidth(t), t.rawType.formatSpec, separator];
+                spec = [spec, '%', obj.getWidth(t), t.formatSpec, separator];
             end
         end
 
diff --git a/lib/storage/@LevelData/set.m b/lib/storage/@LevelData/set.m
index 7a8e287c4c4a9403b9be945890b996c4bf642009..07a284d3a6c754ce5bfd3eb78275cce2e995b66e 100644
--- a/lib/storage/@LevelData/set.m
+++ b/lib/storage/@LevelData/set.m
@@ -43,18 +43,17 @@ function set(obj, jLevel, variableName, value)
         name = variableName{j};
         val = value{j};
         % Determine type of data
-        if isa(val, 'Type')
+        if isa(val, 'ValueDetails')
             % Copy type argument
             currentType = val;
             valueList = repmat({nan}, length(jLevel), 1);
         else
             % Determine type by example data
-            [currentType, valueList] = ...
-                ValueDetails.determineTypeValue(length(jLevel), name, val);
+            [valueList, currentType] = splitIntoLevelWiseData(length(jLevel), val);
         end
         % Store type
         if ~ismember(name, obj.label)
-            obj.type.(name) = currentType;
+            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 0466416c1c1ef6ed8a8ab075ed60cb0969d4becb..0c3f750652bca176bfe1b40538e65573a2188b0a 100644
--- a/lib/storage/@LevelData/setAbsolute.m
+++ b/lib/storage/@LevelData/setAbsolute.m
@@ -46,19 +46,18 @@ function setAbsolute(obj, jLevel, variableName, value)
         name = variableName{j};
         val = value{j};
         % Determine type of data
-        if isa(val, 'Type')
+        if isa(val, 'ValueDetails')
             % Copy type argument
             currentType = val;
             valueList = repmat({nan}, length(jLevel), 1);
         else
             % Determine type by example data
-            [currentType, valueList] = ...
-                ValueDetails.determineTypeValue(length(jLevel), name, val);
+            [valueList, currentType] = splitIntoLevelWiseData(length(jLevel), val);
         end
 
         if ~ismember(name, obj.absoluteVariable)
             % Store type
-            obj.type.(name) = currentType;
+            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 a908568396bb3f1fa24645c9707504379be51af9..f61a6a8786a1c05317db8d71f873fa6da04ad07b 100644
--- a/lib/storage/@LevelData/setTime.m
+++ b/lib/storage/@LevelData/setTime.m
@@ -46,18 +46,17 @@ function setTime(obj, jLevel, variableName, value)
         name = variableName{j};
         val = value{j};
         % Determine type of data
-        if isa(val, 'Type')
+        if isa(val, 'ValueDetails')
             % Copy type argument
             currentType = val;
             valueList = repmat({nan}, length(jLevel), 1);
         else
             % Determine type by example data
-            [currentType, valueList] = ...
-                ValueDetails.determineTypeValue(length(jLevel), name, val);
+            [valueList, currentType] = splitIntoLevelWiseData(length(jLevel), val);
         end
         % Store type
         if ~ismember(name, obj.label)
-            obj.type.(name) = currentType;
+            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 d0d56d50bc8f236a30d66eef4a0e59ade5a84ef4..b39eb8c6a6edb06877b252644dd1892bbc657896 100644
--- a/lib/storage/@LevelDataCollection/LevelDataCollection.m
+++ b/lib/storage/@LevelDataCollection/LevelDataCollection.m
@@ -144,9 +144,9 @@ classdef LevelDataCollection < handle
             for j = 1:obj.nTimeVariable
                 t = obj.item{1}.type.(obj.timeVariable{j});
                 if j < obj.nTimeVariable
-                    spec = [spec, '%', obj.getWidth(t), t.rawType.formatSpec, obj.separator];
+                    spec = [spec, '%', obj.getWidth(t), t.formatSpec, obj.separator];
                 else
-                    spec = [spec, '%', obj.getWidth(t), t.rawType.formatSpec, '\n'];
+                    spec = [spec, '%', obj.getWidth(t), t.formatSpec, '\n'];
                 end
             end
             if obj.nTimeVariable == 0
diff --git a/lib/storage/Type/ValueDetails.m b/lib/storage/Type/ValueDetails.m
index 6dc7b66215f1ece6036c715ee538bf043ac95c64..e82680e5e5bc514d1530283422e44ee2fadaa34d 100644
--- a/lib/storage/Type/ValueDetails.m
+++ b/lib/storage/Type/ValueDetails.m
@@ -29,122 +29,79 @@ classdef ValueDetails
     end
 
     properties (Dependent)
+        % Format specification for printing
+        formatSpec
         % Boolean determining if type is scalar
         isScalar (1,1) boolean
     end
 
     methods
         %% CONSTRUCTOR
-        function obj = ValueDetails(name, value)
-            %%TYPE creates an object of the Type class given an example
+        function obj = ValueDetails(rawType, shape, printWidth)
+            %%VALUEDETAILS creates an instance of ValueDetails given an example
             %value of the corresponding data
-            %   obj = TYPE(name, value)
+            %   obj = VALUEDETAILS(rawType, shape, printWidth)
+
+            obj.rawType = rawType;
+            obj.shape = shape;
+            obj.printWidth = printWidth;
+        end
+
+        function obj = adaptPrintWidthTo(obj, name)
+            %ADAPTPRINTWIDTHTO updates the print width considering the length of
+            %variable name 
+            obj.printWidth = max(obj.printWidth, length(name));
+        end
+
+        function formatSpec = get.formatSpec(obj)
+            formatSpec = obj.rawType.formatSpec;
+        end
+
+        function bool = get.isScalar(obj)
+            bool = strcmp(obj.shape, 's');
+        end
+    end
+
+    % AUXILIARY
+    methods (Static)
+        function details = fromExample(value)
+            %%FROMEXAMPLE creates an instance of ValueDetails given an example
+            %value of the corresponding data
+            %   obj = FROMEXAMPLE(value)
 
             % Determine data type and width
             if isnan(value)
                 % NaN is treated as integer to avoid problems with plotting
-                obj.rawType = RawType.INT;
-                obj.printWidth = 3;
+                rawType = RawType.INT;
+                printWidth = 3;
             elseif isinteger(value)
-                obj.rawType = RawType.INT;
+                rawType = RawType.INT;
                 S = cellstr(num2str(value));
-                obj.printWidth = max(cellfun(@(x) length(x), S(:)));
+                printWidth = max(cellfun(@(x) length(x), S(:)));
             elseif isfloat(value)
-                obj.rawType = RawType.FLOAT;
+                rawType = RawType.FLOAT;
                 floatPrecision = str2double(RawType.FLOAT.formatSpec(2));
-                obj.printWidth = 6 + floatPrecision;
+                printWidth = 6 + floatPrecision;
             elseif ischar(value)
-                obj.rawType = RawType.TEXT;
-                obj.printWidth = length(value);
+                rawType = RawType.TEXT;
+                printWidth = length(value);
             elseif isstring(value)
-                obj.rawType = RawType.TEXT;
-                obj.printWidth = max(cellfun(@(x) length(x), value(:)));
+                rawType = RawType.TEXT;
+                printWidth = max(cellfun(@(x) length(x), value(:)));
             else
                 error('Invalid data type');
             end
 
             % Determine shape
             if isscalar(value)
-                obj.shape = 's';
+                shape = 's';
             elseif isvector(value)
-                obj.shape = 'v';
+                shape = 'v';
             else
-                obj.shape = 'a';
+                shape = 'a';
             end
 
-            % Update width considering length of the name
-            obj.printWidth = max(obj.printWidth, length(name));
-        end
-
-        function bool = get.isScalar(obj)
-            bool = strcmp(obj.shape, 's');
-        end
-    end
-
-    % AUXILIARY
-    methods (Static)
-        function [type, valueList] = determineTypeValue(nLevel, variableName, value)
-        %%DETERMINETYPEVALUE auxiliary function for determining type from an array
-        %of values
-        %    [type, valueList] = DETERMINETYPEVALUE(nLevel, variableName, value)
-
-        % Copyright 2023 Philipp Bringmann
-        %
-        % This program is free software: you can redistribute it and/or modify
-        % it under the terms of the GNU General Public License as published by
-        % the Free Software Foundation, either version 3 of the License, or
-        % (at your option) any later version.
-        %
-        % This program is distributed in the hope that it will be useful,
-        % but WITHOUT ANY WARRANTY; without even the implied warranty of
-        % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-        % GNU General Public License for more details.
-        %
-        % You should have received a copy of the GNU General Public License
-        % along with this program.  If not, see <http://www.gnu.org/licenses/>.
-        %
-
-
-            if nLevel == 1
-                % Array value represents data on a single level
-                type = ValueDetails(variableName, value);
-                valueList = {value};
-            else
-                if isvector(value)
-                    % Array value represents a vector of scalar values for each
-                    % level
-                    assert(length(value) == nLevel, ...
-                        'Length of argument invalid');
-                    type = ValueDetails(variableName, value(1));
-                    valueList = mat2cell(value(:), ones(nLevel, 1));
-                else
-                    % Array value represents an higher dimensional objects for each
-                    % level
-                    dims = size(value);
-                    if any(dims == nLevel)
-                        levelDim = find(dims == nLevel);
-                        remainingDim = 1:ndims(value);
-                        remainingDim(levelDim) = [];
-                        if sum(dims == nLevel) > 1
-                            % Several dimensions could represent the level
-                            % information
-                            warning(['Unclear dimensions of argument. ', ...
-                                    'Assume level-oriented data in dimension ', ...
-                                    num2str(levelDim)]);
-                        end
-                        % Extract and rearrange values
-                        value = permute(value, [levelDim, remainingDim]);
-                        valueList = cell(nLevel, 1);
-                        ind = repmat({':'}, length(remainingDim), 1);
-                        type = ValueDetails(variableName, value(1, ind{:}));
-                        for k = 1:nLevel
-                            valueList{k} = value(k, ind{:});
-                        end
-                    else
-                        error('Unable to extract data from argument');
-                    end
-                end
-            end
+            details = ValueDetails(rawType, shape, printWidth);
         end
     end
 end
diff --git a/lib/storage/Type/splitIntoLevelWiseData.m b/lib/storage/Type/splitIntoLevelWiseData.m
new file mode 100644
index 0000000000000000000000000000000000000000..d399959292ad181a627cda0b7569d19a40c02ef8
--- /dev/null
+++ b/lib/storage/Type/splitIntoLevelWiseData.m
@@ -0,0 +1,64 @@
+
+function [valueList, type] = splitIntoLevelWiseData(nLevel, value)
+%%DETERMINETYPEVALUE auxiliary function for determining type from an array
+%of values
+%    [type, valueList] = DETERMINETYPEVALUE(nLevel, variableName, value)
+
+% Copyright 2023 Philipp Bringmann
+%
+% This program is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% This program is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with this program.  If not, see <http://www.gnu.org/licenses/>.
+%
+
+    if nLevel == 1
+        % Array value represents data on a single level
+        type = ValueDetails.fromExample(value);
+        valueList = {value};
+    else
+        if isvector(value)
+            % Array value represents a vector of scalar values for each % level
+            assert(length(value) == nLevel, 'Length of argument invalid');
+            type = ValueDetails.fromExample(value(1));
+            valueList = mat2cell(value(:), ones(nLevel, 1));
+        else
+            % Array value represents an higher dimensional objects for each % level
+            dims = size(value);
+            [levelDim, idx] = extractSingleLevelDimension(dims, nLevel);
+            % Extract values
+            valueList = cell(nLevel, 1);
+            for k = 1:nLevel
+                idx(levelDim) = k;
+                valueList{k} = subsref(value, idx);
+            end
+            type = ValueDetails.fromExample(valueList{end});
+        end
+    end
+end
+
+function [levelDim, idx] = extractSingleLevelDimension(dims, nLevel)
+    levelDim = find(dims == nLevel);
+    if isempty(levelDim)
+        error('Unable to extract data from argument');
+    end
+
+    if length(levelDim) > 1
+        % Several dimensions could represent the level information
+        levelDim = levelDim(1);
+        warning('Unclear dimensions of argument. Assume level-oriented data in dimension %d.', levelDim);
+    end
+
+    % index that is ':' for all dimensions, and where the index in the level
+    % dimension can be changed
+    idx.subs = repmat({':'}, 1, ndims(value));
+    idx.type = '()';
+end
\ No newline at end of file