From 30b9d4bb83f50cadde8ac2edbc945dab682bfe83 Mon Sep 17 00:00:00 2001 From: Michael Innerberger <michael.innerberger@asc.tuwien.ac.at> Date: Mon, 7 Aug 2023 16:38:15 -0400 Subject: [PATCH] Make meta data a dictionary -> require 2022b! --- README.md | 2 +- lib/storage/@LevelData/LevelData.m | 48 ++++++---------- lib/storage/@LevelData/plotToFile.m | 2 +- lib/storage/@LevelData/saveToFile.m | 5 +- lib/storage/@LevelData/saveToTable.m | 2 +- .../LevelDataCollection.m | 55 +++++++------------ lib/storage/@LevelDataCollection/saveToFile.m | 2 +- .../@LevelDataCollection/saveToTable.m | 4 +- lib/storage/TimeIt.m | 6 +- 9 files changed, 50 insertions(+), 76 deletions(-) diff --git a/README.md b/README.md index f7c00b0..0e8f478 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ Advantages: To get started, run `setup.m` in the root folder. This adds everything to the path and compiles .mex files if necessary. -Note that, at least, Matlab version R2022a is required. +Note that, at least, Matlab version R2022b is required. ## First steps diff --git a/lib/storage/@LevelData/LevelData.m b/lib/storage/@LevelData/LevelData.m index 8275605..7018f7f 100644 --- a/lib/storage/@LevelData/LevelData.m +++ b/lib/storage/@LevelData/LevelData.m @@ -18,14 +18,7 @@ classdef LevelData < handle % properties - % Name of problem - problem = 'problem' - % Name of domain - domain = 'domain' - % Name of method - method = 'method' - % Identifier for computation - identifier = 'main' + metaData % Root folder for file storage root = 'results' % Structure array storing string representations of variables @@ -94,35 +87,30 @@ classdef LevelData < handle if nargin >= 1 obj.root = rootpath; end - ensureFolderExists(obj.root); - % Set hostname - obj.hostname = getHostname(); + + % TODO: set output of hostname to string and remove cast + obj.metaData = dictionary(... + "problem", "problem", ... + "domain", "domain", ... + "method", "method", ... + "identifier", "main", ... + "hostname", string(getHostname())); + % Save time of creation if isOctave() - obj.timestamp = datestr(now, 'yyyy-MM-dd_HH:mm:ss'); %#ok<TNOW1,DATST> + obj.metaData("timestamp") = datestr(now, 'yyyy-MM-dd_HH:mm:ss'); %#ok<TNOW1,DATST> else - obj.timestamp = char(datetime('now', 'Format', 'yyyy-MM-dd_HH:mm:ss')); + obj.metaData("timestamp") = char(datetime('now', 'Format', 'yyyy-MM-dd_HH:mm:ss')); end + + ensureFolderExists(obj.root); + % Set hostname + obj.hostname = getHostname(); % Initialise dictionary with some default values obj.dictionary = getDefaultDictionary(); end %% SET GLOBAL VARIABLES - function set.problem(obj, name) - assert(ischar(name), 'Insert character array as problem name.'); - obj.problem = name; - end - - function set.domain(obj, name) - assert(ischar(name), 'Insert character array as domain name.'); - obj.domain = name; - end - - function set.method(obj, name) - assert(ischar(name), 'Insert character array as method name.'); - obj.method = name; - end - function set.root(obj, path) assert(ischar(path), 'Insert character array as path name.'); obj.root = path; @@ -152,12 +140,12 @@ classdef LevelData < handle if numel(rootpath) > 0 && ~strcmp(rootpath(end), '/') rootpath = [rootpath, '/']; end - path = [rootpath, obj.problem, '_', obj.domain, '_', obj.method]; + path = rootpath + strjoin([obj.metaData("problem"), obj.metaData("domain"), obj.metaData("method")], '_'); end function file = get.filename(obj) % Name of file for file storage - file = [obj.identifier]; + file = [obj.metaData("identifier")]; end function bool = get.isScalar(obj) diff --git a/lib/storage/@LevelData/plotToFile.m b/lib/storage/@LevelData/plotToFile.m index 2efe1f1..23ffcee 100644 --- a/lib/storage/@LevelData/plotToFile.m +++ b/lib/storage/@LevelData/plotToFile.m @@ -37,7 +37,7 @@ function plotToFile(obj, xVariable, varargin) end % Export plot - print(h, '-dpng', '-r600', [obj.foldername, '/', obj.filename, '.png']); + print(h, '-dpng', '-r600', obj.foldername + '/' + obj.filename + '.png'); % Close figure close(h); diff --git a/lib/storage/@LevelData/saveToFile.m b/lib/storage/@LevelData/saveToFile.m index b6af1ce..b46a2b8 100644 --- a/lib/storage/@LevelData/saveToFile.m +++ b/lib/storage/@LevelData/saveToFile.m @@ -32,9 +32,10 @@ function saveToFile(obj, folder, file) % Create problem- and method-specific folder ensureFolderExists(folder); % Save this object to file + pathToMat = folder + '/' + file + '.mat'; if isOctave() - save([folder, '/', file, '.mat'], 'obj', '-v7'); + save(pathToMat, 'obj', '-v7'); else - save([folder, '/', file, '.mat'], 'obj', '-v7.3'); + save(pathToMat, 'obj', '-v7.3'); end end diff --git a/lib/storage/@LevelData/saveToTable.m b/lib/storage/@LevelData/saveToTable.m index 9ee04bf..8ac9fc8 100644 --- a/lib/storage/@LevelData/saveToTable.m +++ b/lib/storage/@LevelData/saveToTable.m @@ -33,7 +33,7 @@ function saveToTable(obj, separator) ensureFolderExists(obj.foldername); % Open file - fid = fopen([obj.foldername, '/', obj.filename, '.csv'], 'w'); + fid = fopen(obj.foldername + '/' + obj.filename + '.csv', 'w'); % Save header to file fprintf(fid, obj.headerSpecifier, obj.scalarVariable{:}); diff --git a/lib/storage/@LevelDataCollection/LevelDataCollection.m b/lib/storage/@LevelDataCollection/LevelDataCollection.m index 69c5efe..90fd021 100644 --- a/lib/storage/@LevelDataCollection/LevelDataCollection.m +++ b/lib/storage/@LevelDataCollection/LevelDataCollection.m @@ -19,8 +19,7 @@ classdef LevelDataCollection < handle properties - % Identifier for computation - identifier = '' + metaData % Root folder for file storage root = 'results' % Cell array of LevelData objects @@ -28,12 +27,6 @@ classdef LevelDataCollection < handle end properties (Dependent) - % Name of problem - problem (1,:) char - % Name of domain - domain (1,:) char - % Name of method - method (1,:) char % Path to folder for file storage foldername (1,:) char % Name of file for storage @@ -73,9 +66,25 @@ classdef LevelDataCollection < handle end ensureFolderExists(obj.root); + % TODO: set output of hostname to string and remove cast + % TODO: does it make sense to store this here? -> see e.g. get.problem before + obj.metaData = dictionary(... + "problem", "problem", ... + "domain", "domain", ... + "method", "method", ... + "identifier", "main", ... + "hostname", string(getHostname())); + + % Save time of creation + if isOctave() + obj.metaData("timestamp") = datestr(now, 'yyyy-MM-dd_HH:mm:ss'); %#ok<TNOW1,DATST> + else + obj.metaData("timestamp") = char(datetime('now', 'Format', 'yyyy-MM-dd_HH:mm:ss')); + end + % Set identifier if nargin >= 2 - obj.identifier = identifier; + obj.metaData("identifier") = identifier; end end @@ -100,40 +109,16 @@ classdef LevelDataCollection < handle bool = (obj.nItem <= 1); end - function name = get.problem(obj) - if isempty(obj.item) - name = ''; - else - name = [obj.item{1}.problem]; - end - end - - function name = get.domain(obj) - if isempty(obj.item) - name = ''; - else - name = [obj.item{1}.domain]; - end - end - - function name = get.method(obj) - if isempty(obj.item) - name = ''; - else - name = [obj.item{1}.method]; - end - end - function path = get.foldername(obj) rootpath = obj.root; if numel(rootpath) > 0 && ~strcmp(rootpath(end), '/') rootpath = [rootpath, '/']; end - path = [rootpath, obj.problem, '_', obj.domain, '_', obj.method]; + path = rootpath + strjoin([obj.metaData("problem"), obj.metaData("domain"), obj.metaData("method")], '_'); end function file = get.filename(obj) - file = [obj.identifier, '_collection']; + file = obj.metaData("identifier") + '_collection'; end function spec = get.headerSpecifier(obj) diff --git a/lib/storage/@LevelDataCollection/saveToFile.m b/lib/storage/@LevelDataCollection/saveToFile.m index 81d502c..b43d1e7 100644 --- a/lib/storage/@LevelDataCollection/saveToFile.m +++ b/lib/storage/@LevelDataCollection/saveToFile.m @@ -38,6 +38,6 @@ function saveToFile(obj, folder, file) warning(['LevelData not stored. Octave cannot save classdef objects. ', ... 'See GNU Octave Bug: #45833']); else - save([folder, '/', file, '.mat'], 'obj', '-v7.3'); + save(folder + '/' + file + '.mat', 'obj', '-v7.3'); end end diff --git a/lib/storage/@LevelDataCollection/saveToTable.m b/lib/storage/@LevelDataCollection/saveToTable.m index 1fe0f07..6f748df 100644 --- a/lib/storage/@LevelDataCollection/saveToTable.m +++ b/lib/storage/@LevelDataCollection/saveToTable.m @@ -35,8 +35,8 @@ function saveToTable(obj, separator) % Save data for each variable to a separate file data = obj.get(':', obj.timeVariable{:}); for j = 1:obj.nTimeVariable - fid = fopen([obj.foldername, '/', obj.filename, '_', ... - obj.timeVariable{j},'.csv'], 'w'); + fid = fopen(obj.foldername + '/' + obj.filename + '_' + ... + obj.timeVariable{j} + '.csv', 'w'); obj.printTable(fid, obj.timeVariable{j}, data{j}); fclose(fid); end diff --git a/lib/storage/TimeIt.m b/lib/storage/TimeIt.m index d84698b..c8b5334 100644 --- a/lib/storage/TimeIt.m +++ b/lib/storage/TimeIt.m @@ -25,13 +25,13 @@ function leveldatacollection = TimeIt(identifier, nRun, functionName, varargin) end % Welcome statement - fprintf('\n#\n# OCTAFEM - TIME MEASUREMENT\n'); + fprintf('\n#\n# MooAFEM - TIME MEASUREMENT\n'); fprintf('# Current Time: %s\n#\n\n', datestr(now)); fprintf('This is TimeIt wrapper for function "%s"\n\n', functionName); % Initialisation of collection for LevelData objects leveldatacollection = LevelDataCollection(); - leveldatacollection.identifier = identifier; + leveldatacollection.metaData("identifier") = identifier; % Run experiments for j = 1:nRun @@ -39,7 +39,7 @@ function leveldatacollection = TimeIt(identifier, nRun, functionName, varargin) temporaryIdentifier = sprintf('timingRun%04d', j); outputList = fevalc(functionName, varargin{:}); leveldata = outputList{1}; - leveldata.identifier = temporaryIdentifier; + leveldata.metaData("identifier") = temporaryIdentifier; % Remove unused information leveldata.removeNonscalar(); % Store information -- GitLab