Skip to content
Snippets Groups Projects
Commit 954aa4ed authored by Lemmer, Jan's avatar Lemmer, Jan
Browse files

Development

parent 16ee59f3
No related branches found
No related tags found
2 merge requests!26Dev/ci testing,!25Development
classdef userDLG
%userDLG the userDLG Class is responsible for the user dialog
% error handeling, user messages and warnings will be provided from
% this class, depending on the user options and error type.
% This reduces messaging overhead and code length in PlotID.Publish()
properties
configError = false
scriptPublished = false
rdFilesPublished = false
figurePublished = false
msg = ''
end
properties (SetAccess = protected)
success = false
showMessages {mustBeNumericOrLogical}
forcePublish {mustBeNumericOrLogical}
ID %plotID
end
methods
function obj = userDLG(ID,options)
%CATCHERROR Construct an instance of this class
if isempty(ID)
ID = '';
end
obj.ID = ID;
obj.showMessages = options.ShowMessages;
obj.forcePublish = options.ForcePublish;
end
function output = get.success(obj)
% checks if all publish operations are true
obj.success = all([obj.scriptPublished; obj.rdFilesPublished;...
obj.figurePublished]);
output = obj.success;
end
function obj = set.msg(obj,message)
%setmsg Summary of this method goes here
% Detailed explanation goes here
obj.msg = message;
end
function [] = userMSG(obj,message)
%userMSG user message without priority
% MSG will only be displaye if ShowMessages is true
if obj.showMessages
disp(message);
end
end
function [] = error(obj,message)
%error handles critical errors
% critical errors will always result in a matlab error
%ToDO: Add function(s) before termination
error(message);
end
function [] = softError(obj,message)
%softError handles soft errors
% soft errors can be changed to warning if ForcePublish is
% selected by the user
if obj.forcePublish
warning(message);
else
error(message);
end
end
function outputArg = method1(obj,inputArg)
%METHOD1 Summary of this method goes here
% Detailed explanation goes here
outputArg = obj.Property1 + inputArg;
end
end
end
...@@ -24,8 +24,12 @@ arguments ...@@ -24,8 +24,12 @@ arguments
options.Location {mustBeMember(options.Location ,{'local','server','manual','CI-Test'})} = 'local' % storage path options.Location {mustBeMember(options.Location ,{'local','server','manual','CI-Test'})} = 'local' % storage path
options.Method {mustBeMember(options.Method ,{'individual','centralized'})} = 'individual' options.Method {mustBeMember(options.Method ,{'individual','centralized'})} = 'individual'
options.ParentFolder (1,:) {mustBeText} = 'export' options.ParentFolder (1,:) {mustBeText} = 'export'
options.ConfigFileName (1,:) {mustBeText} = 'config.json' %individual config names possible
options.CopyUserFCN (1,1) {mustBeNumericOrLogical} = true options.CopyUserFCN (1,1) {mustBeNumericOrLogical} = true
options.CSV (1,1) {mustBeNumericOrLogical} = false options.CSV (1,1) {mustBeNumericOrLogical} = false
options.ShowMessages(1,1) {mustBeNumericOrLogical} = true
options.ForcePublish (1,1) {mustBeNumericOrLogical} = false %publish anyway
end end
%% argument validation %% argument validation
...@@ -39,8 +43,8 @@ if numel(figure) > 1 ...@@ -39,8 +43,8 @@ if numel(figure) > 1
end end
%get ID from Figure %get ID from Figure
ID = figure.Tag; ID = figure.Tag;
if isempty(ID) if isempty(ID)
% no ID found, User dialog for Folder name % no ID found, User dialog for Folder name
ID = inputdlg(['No ID defined- ' newline,... ID = inputdlg(['No ID defined- ' newline,...
...@@ -51,17 +55,15 @@ if isempty(ID) ...@@ -51,17 +55,15 @@ if isempty(ID)
warning(msg); warning(msg);
end end
% Error and MSG handeling
dlgObj = PlotID.userDLG(ID,options);
%% read config file %% read config file
try try
txt = fileread('config.json'); txt = fileread('config.json');
config = jsondecode(txt); config = jsondecode(txt);
configError = false;
catch catch
msg = ['Error while reading the config file' newline,... dlgObj.configError = true;
' publishing on server not possible'];
warning(msg);
configError = true;
end end
%% storage location %% storage location
...@@ -75,26 +77,34 @@ switch options.Location ...@@ -75,26 +77,34 @@ switch options.Location
storPath = fullfile(scriptLocation,options.ParentFolder); storPath = fullfile(scriptLocation,options.ParentFolder);
end end
case 'server' %from config File case 'server' %from config File
if dlgObj.configError
msg = ['Error while reading the config file' newline,...
' publishing on server not possible'];
dlgObj.error(msg);
end
storPath = config.ServerPath; storPath = config.ServerPath;
case 'manual' %UI case 'manual' %UI
storPath = uigetdir(); storPath = uigetdir();
case 'CI-Test' case 'CI-Test'
storPath = fullfile(pwd,'CI_files',options.ParentFolder); storPath = fullfile(pwd,'CI_files',options.ParentFolder);
end end
folderName = char(ID);
%% Create Data-Directory folderName = ['.',char(ID)]; %hidden folder
%% Create data directory
if isfolder(fullfile(storPath,folderName)) if isfolder(fullfile(storPath,folderName))
error(['Folder ',folderName, ' exists - Plot was already published ']); dlgObj.error(['Folder ',folderName, ' exists - Plot was already published ']);
elseif mkdir(fullfile(storPath,folderName)) elseif mkdir(fullfile(storPath,folderName))
else else
error('Directory could not be created - check remote path and permissions'); dlgObj.error('Directory could not be created - check remote path and permissions');
end end
disp(['publishing of ', ID, ' started']); disp(['publishing of ', ID, ' started']);
%% Create a Copy of the script and user functions(optional) %% Create a copy of the script and user functions(optional)
% script % script
PlotID.createFileCopy({scriptPath},folderName,storPath,ID, 'script'); [~, status, msg] = PlotID.createFileCopy({scriptPath},folderName,storPath,ID, 'script');
dlgObj.scriptPublished =status;
dlgObj.userMSG(msg);
% user functions % user functions
[fList,pList] = matlab.codetools.requiredFilesAndProducts(scriptPath); [fList,pList] = matlab.codetools.requiredFilesAndProducts(scriptPath);
...@@ -136,27 +146,32 @@ switch options.Method ...@@ -136,27 +146,32 @@ switch options.Method
relativeSourcePath = strrep(sourcePath,currentPath,''); relativeSourcePath = strrep(sourcePath,currentPath,'');
if contains(sourcePath,{'.h5','.hdf5'}) % Linking only for HDF5 if contains(sourcePath,{'.h5','.hdf5'}) % Linking only for HDF5
PlotID.createLinkedHDF5(relativeSourcePath{1,1},storPath,ID); linkedHDFPath = fullfile(storPath,folderName);
PlotID.createLinkedHDF5(relativeSourcePath{1,1},linkedHDFPath);
end end
else % no identical file exists else % no identical file exists
%Copy the file in data and create the links (if hdf5) %Copy the file in data and create the links (if hdf5)
[dataPath] = PlotID.createFileCopy(DataPaths{i},'data',storPath,ID,'dataCentral'); [dataPath, status, msg] = PlotID.createFileCopy(DataPaths{i},'data',storPath,ID,'dataCentral');
relativeDataPath = strrep(dataPath,currentPath,''); pathToData = strrep(dataPath,currentPath,'');
%WIP %WIP
if contains(DataPaths{i},{'.h5','.hdf5'}) % Linking only for HDF5 if contains(DataPaths{i},{'.h5','.hdf5'}) % Linking only for HDF5
% and create also linked files in the plot folder % and create also linked files in the plot folder
PlotID.createLinkedHDF5(relativeDataPath,storPath,ID); linkedHDFPath = fullfile(storPath,folderName);
[status] = PlotID.createLinkedHDF5(pathToData,linkedHDFPath);
end %if end %if
end %if end %if
end %for end %for
clear DataFolderName clear DataFolderName
case 'individual' case 'individual'
% Create a copy of the research data % Create a copy of the research data
PlotID.createFileCopy(DataPaths,folderName,storPath,ID, 'data'); [~, status, msg] = PlotID.createFileCopy(DataPaths,folderName,storPath,ID, 'data');
end end
%% Write Config File %temporary:
dlgObj.rdFilesPublished = status;
dlgObj.userMSG(msg);
if ~configError %config File must exist %% Write Config File
if ~dlgObj.configError %config File must exist
% copy config file % copy config file
configPath = PlotID.createFileCopy('config.json',folderName,... configPath = PlotID.createFileCopy('config.json',folderName,...
storPath,ID, 'data'); storPath,ID, 'data');
...@@ -188,12 +203,11 @@ try ...@@ -188,12 +203,11 @@ try
savefig(figure,RemotePath); savefig(figure,RemotePath);
% the png should only be a preview % the png should only be a preview
exportgraphics(figure,[RemotePath,'.png'],'Resolution',300); exportgraphics(figure,[RemotePath,'.png'],'Resolution',300);
dlgObj.figurePublished = true;
catch catch
warning('Plot export was not successful') dlgObj.softError('Plot export was not successful');
end end
disp(['publishing of ', ID , ' done']);
% CSV EXport % CSV EXport
if options.CSV if options.CSV
T = table(); T = table();
...@@ -205,6 +219,25 @@ if options.CSV ...@@ -205,6 +219,25 @@ if options.CSV
writetable(T, fullfile(storPath, 'overview_table.csv'),'WriteMode','append'); writetable(T, fullfile(storPath, 'overview_table.csv'),'WriteMode','append');
end end
%% final renaming and error/warning handeling
% if no error orcurred or if force publish is activated, rename the hidden
% folder to a non hidden one, otherwise delete it.
if dlgObj.success || options.ForcePublish
oldPath = fullfile(storPath,folderName);
newPath = strrep(oldPath,'.',''); %remov dot
status = movefile(oldPath,newPath); %rename directory
else
% error from userDlg class!
end
if status
disp(['publishing of ', ID , ' done']); %always displayed onsucess
else % publish was not sucessfull!
%replace with error from userDLG Class
dlgObj.error(['publishing of ', ID , ' failed'])
end
end %function end %function
%% Argument Validation Functions %% Argument Validation Functions
...@@ -216,7 +249,7 @@ end ...@@ -216,7 +249,7 @@ end
function mustBeDataPath(DataPaths) function mustBeDataPath(DataPaths)
%checks if input is a valid DataPath object %checks if input is a valid DataPath object
if iscellstr(DataPaths) if isstring(DataPaths)
tf = zeros(1,numel(DataPaths)); tf = zeros(1,numel(DataPaths));
for i=1:numel(DataPaths) for i=1:numel(DataPaths)
tf(i) = ~isfile(DataPaths{i}); tf(i) = ~isfile(DataPaths{i});
......
...@@ -15,9 +15,10 @@ arguments ...@@ -15,9 +15,10 @@ arguments
figs (1,:) {mustBeFigure} figs (1,:) {mustBeFigure}
options.ProjectID (1,:) {mustBeText}= '' options.ProjectID (1,:) {mustBeText}= ''
options.Fontsize (1,1) {mustBeInteger} = 8 options.Fontsize (1,1) {mustBeInteger} = 8
options.Color (1,3) {mustBeNonnegative} = 0.65*[1 1 1] % grey
options.Location (1,:) {mustBeText} = 'east' options.Location (1,:) {mustBeText} = 'east'
options.Position (1,2) {mustBeVector} = [1,0.4] % default for east options.Position (1,2) {mustBeVector} = [1,0.4] % default for east
options.Rotation (1,1) {mustBeInteger} = 0 options.Rotation (1,1) {mustBeReal} = NaN
end end
if isempty(options.ProjectID) if isempty(options.ProjectID)
...@@ -41,16 +42,19 @@ end ...@@ -41,16 +42,19 @@ end
switch options.Location switch options.Location
case 'north' case 'north'
options.Position = [0.4,0.95]; options.Position = [0.4,0.95];
options.Rotation = 0; Rotation = 0;
case 'east' case 'east'
options.Position = [1,0.4]; options.Position = [1,0.4];
options.Rotation = 90; Rotation = 90;
case 'south' case 'south'
options.Position = [0.4,.02]; options.Position = [0.4,.02];
options.Rotation = 0; Rotation = 0;
case 'west' case 'west'
options.Position = [.05,0.4]; options.Position = [.05,0.4];
options.Rotation = 90; Rotation = 90;
case 'southeast'
options.Position = [0.8,.02];
Rotation = 0;
case 'custom' case 'custom'
% Check if Position is valid % Check if Position is valid
if ~all(0 <= options.Position & options.Position <= 1) if ~all(0 <= options.Position & options.Position <= 1)
...@@ -62,6 +66,10 @@ switch options.Location ...@@ -62,6 +66,10 @@ switch options.Location
options.Location = 'east'; options.Position = [1,0.4]; options.Location = 'east'; options.Position = [1,0.4];
end end
if ~isnan(options.Rotation)
Rotation = options.Rotation;
end
IDs = cell(numel(figs),1); IDs = cell(numel(figs),1);
for n = 1:numel(figs) for n = 1:numel(figs)
...@@ -72,10 +80,11 @@ for n = 1:numel(figs) ...@@ -72,10 +80,11 @@ for n = 1:numel(figs)
ylim =get(axes,'YLim'); ylim =get(axes,'YLim');
xlim =get(axes,'XLim'); xlim =get(axes,'XLim');
%ID %ID
position = [options.Position(1)*xlim(2), options.Position(2)*ylim(2)];
position = [options.Position(1), options.Position(2)];
text(axes,position(1),position(2), IDs{n},'Fontsize',options.Fontsize,... text(axes,position(1),position(2), IDs{n},'Fontsize',options.Fontsize,...
'Rotation',options.Rotation, 'VerticalAlignment','bottom','Color',... 'Rotation',Rotation, 'VerticalAlignment','bottom','Color',...
0.65*[1 1 1],'BackgroundColor','w'); options.Color,'BackgroundColor','w', 'Units', 'normalized');
set(figs(n),'Tag', IDs{n}); set(figs(n),'Tag', IDs{n});
end end
......
function [storagePaths] = createFileCopy(filePaths,folderName,storPath,ID,type) function [storagePaths, status, msg] = createFileCopy(filePaths,folderName,storPath,ID,type)
% Creates a copy of the files (can be used for multiple paths in a cell array) % Creates a copy of the files (can be used for multiple paths in a cell array)
% folderName is the name of the exporting folder % folderName is the name of the exporting folder
% returns the storage paths were files were stored % returns the storage paths were files were stored
...@@ -68,8 +68,10 @@ try ...@@ -68,8 +68,10 @@ try
copyfile(FileNameAndLocation,RemotePath); copyfile(FileNameAndLocation,RemotePath);
storagePaths{i} = RemotePath; storagePaths{i} = RemotePath;
end end
disp([type, ' successfully published']); status = true;
msg =([type, ' successfully published']);
catch catch
status = false;
warning([type,' export was not sucessful']) warning([type,' export was not sucessful'])
if exist('errorMSG') if exist('errorMSG')
error(errorMSG); error(errorMSG);
......
function [status] = createLinkedHDF5(SourceFile,TargetPath,ID) function [status] = createLinkedHDF5(SourceFile,TargetPath)
%createLinkedHDF5 creates a HDF file that references the Sourcefile %createLinkedHDF5 creates a HDF file that references the Sourcefile
% TargetPath is the storage location, ID the foldername % TargetPath is the storage location, ID the foldername
% Status returns true if the function was sucessfull % Status returns true if the function was sucessfull
...@@ -16,12 +16,12 @@ end ...@@ -16,12 +16,12 @@ end
%old %old
%fid = H5F.create(fullfile(TargetPath,ID,[ID,'_data.h5'])); %fid = H5F.create(fullfile(TargetPath,ID,[ID,'_data.h5']));
fid = H5F.create(fullfile(TargetPath,ID,[filename,ext])); fid = H5F.create(fullfile(TargetPath,[filename,ext]));
%create External Link to Sourcefile in the Group linkToExternal %create External Link to Sourcefile in the Group linkToExternal
H5L.create_external(['..',SourceFile],'/',fid, SourceFile ,plist_id,plist_id); H5L.create_external(['..',SourceFile],'/',fid, SourceFile ,plist_id,plist_id);
%H5L.create_external(['..',filesep,'data',filesep,SourceFile],'/',fid, SourceFile ,plist_id,plist_id); %original %H5L.create_external(['..',filesep,'data',filesep,SourceFile],'/',fid, SourceFile ,plist_id,plist_id); %original
H5F.close(fid); H5F.close(fid);
disp([fullfile(TargetPath,ID,[filename,ext]),' created']); disp([fullfile(TargetPath,[filename,ext]),' created']);
status = 1; status = 1;
% catch % catch
% warning('No linked HDF file was created'); % warning('No linked HDF file was created');
......
...@@ -7,7 +7,8 @@ names = strcat(names, ext); % add ext for comparison ...@@ -7,7 +7,8 @@ names = strcat(names, ext); % add ext for comparison
% Get a list of all .m files that are part of Plot id % Get a list of all .m files that are part of Plot id
packageContent = what('PlotID'); packageContent = what('PlotID');
PltID_flist = packageContent.m; %get list of files % packageContent.classes has no extensions
PltID_flist = [packageContent.m; strcat(packageContent.classes,'.m')];
% Comparison and filter % Comparison and filter
fListClean = fList(~ismember(names,PltID_flist)); fListClean = fList(~ismember(names,PltID_flist));
......
...@@ -37,6 +37,7 @@ testdata_2.h5 ...@@ -37,6 +37,7 @@ testdata_2.h5
testdata2.h5 testdata2.h5
test_data.mat test_data.mat
export/* export/*
unused*/*
# Octave session info # Octave session info
octave-workspace octave-workspace
......
cff-version: 1.2.0
title: >-
plotID a toolkit for connecting research data and
figures
message: >-
developed at the Chair of Fluid System, Techische
Universität Darmstadt within the framework of the NFDI4Ing consortium Funded by the German Research Foundation (DFG) - project number 442146713
type: software
authors:
- given-names: Jan
family-names: Lemmer
email: jan.lemmer@fst.tu-darmstadt.de
affiliation: 'Chair of Fluid Systems, TU Darmstadt'
orcid: 'https://orcid.org/0000-0002-0638-1567'
- given-names: Martin
family-names: Hock
email: martin.hock@fst.tu-darmstadt.de
affiliation: 'Chair of Fluid Systems, TU Darmstadt'
...@@ -43,7 +43,8 @@ h5write(fpath, "/y1", y1) ...@@ -43,7 +43,8 @@ h5write(fpath, "/y1", y1)
% Place for post-processing of the data, or additional related code. % Place for post-processing of the data, or additional related code.
% example_fcn is a dummy function to show the functionality % example_fcn is a dummy function to show the functionality
a = 1; a = example_fcn(a); a = 1; a = example_fcn(a);
p = betacdf(0.5,1,1); % to test toolboxes % Uncomment to include the Statistics and Machine learning Toolbox
% p = betacdf(0.5,1,1); % to test toolboxes
%% Plotting %% Plotting
% This is still part of a normal script to produce plots. % This is still part of a normal script to produce plots.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment