diff --git a/+PlotID/Publish.m b/+PlotID/Publish.m index 4c7b154c5b3a5aa96a45e981c822f04a8185fa50..da8a62cdeb949cb1cdc40a3499f275da7e1a5e6d 100644 --- a/+PlotID/Publish.m +++ b/+PlotID/Publish.m @@ -1,128 +1,135 @@ -function Publish(DataPaths, ID, figure, options) -%Publishes saves plot, data and measuring script -% Location sets the storage location. 'local' sets the storage location -% to the current folder (an export folder will be created), 'server' is a -% remote path, that is defined in the config file. -% Two Methods are implemented 'individual' stores the data for -% each plot while 'centralized' uses a data folder and uses reference links -% to the original data (hdf5 only). - -arguments - DataPaths - ID (1,:) {mustBeNonzeroLengthText} % ID must be provided - figure (1,:) {mustBeFigure} % Checks if figure is a figure object - options.Location {mustBeMember(options.Location ,['local','server','CI-Test'])} = 'local' % storage path - options.Method {mustBeMember(options.Method ,['individual','centralized'])} = 'individual' - options.CopyUserFCN (1,1) {mustBeNumericOrLogical} = true - options.CSV (1,1) {mustBeNumericOrLogical} = false -end - -%catch multiple figures in fig -if numel(figure) > 1 - figure = figure(1); - msg = ['Publish is designed for handeling one figure at once' newline,... - '- publishes uses only the first figure.' newline , ... - 'Consider an external for loop for multi figure export as provided in example.m']; - warning(msg); -end - -switch options.Location - case 'local' - % use the script path as export path - scriptPath = fileparts(DataPaths.script); - storPath = fullfile(scriptPath,'export'); - case 'server' %from config File - txt = fileread('config.json'); - config = jsondecode(txt); - storPath = config.ServerPath; - case 'CI-Test' - storPath = fullfile(pwd,'CI_files','export'); -end -folderName = char(ID); - -%% Create Data-Directory -addpath(storPath); % ToDo necessary? - -if isfolder(fullfile(storPath,folderName)) - error(['Folder ',folderName, ' exists - Plot was already published ']); -elseif mkdir(fullfile(storPath,folderName)) -else - error('Directory could not be created - check remote path and permissions'); -end - -disp('Publishing started'); - -%% Create a Copy of the script and User functions(optional) -PlotID.createFileCopy({[DataPaths.script,'.m']},folderName,storPath,ID, 'script'); - -if options.CopyUserFCN - [fList,pList] = matlab.codetools.requiredFilesAndProducts(DataPaths.script); - % plist contains the required MATLAB Toolboxes, maybe usefull in future - fList = fList(~ismember(fList,[DataPaths.script,'.m'])); % rmv script from list - fList = PlotID.removePltIdFiles(fList); % Do not copy files that are part of plot ID - if ~isempty(fList) - PlotID.createFileCopy(fList,folderName,storPath,ID,'userFcn'); - end -end - -%% Research data handeling -switch options.Method - case 'centralized' - % check if data folder exists - if ~isfolder(fullfile(storPath,'data')) - mkdir(fullfile(storPath,'data')); - end - %list all files - fList = dir(fullfile(storPath,'data', '**\*.*')); %get list of files and folders in any subfolder - fList = fList(~[fList.isdir]); %remove folders from list - fList = struct2table(fList); - - % Check if the new plot is based on the original data-set - % copy the data(once) - for i=1:numel(DataPaths.rdata) - % check if identical file exists (status = 1) - [~, idx] = PlotID.fileCompare(DataPaths.rdata{i},fList); - % create Linked HDF5 files for identical files - if any(idx) - sourcePath = fList{idx,'name'}; % If there are multiple copies already, this only picks the last entry - if contains(sourcePath,{'.h5','.hdf5'}) % Linking only for HDF5 - PlotID.createLinkedHDF5(sourcePath,storPath,ID); - end - else % no identical file exists - PlotID.createFileCopy(DataPaths.rdata{i},'data',storPath,ID,'dataCentral'); - end - end - case 'individual' - % Create a copy of the research data - PlotID.createFileCopy(DataPaths.rdata,folderName,storPath,ID, 'data'); -end -%% Export the Plot -try - PlotName = [ID,'_plot']; % plotname - RemotePath = fullfile(storPath ,folderName, PlotName); - % Matlab figure - savefig(figure,RemotePath); - % the png should only be a preview - exportgraphics(figure,[RemotePath,'.png'],'Resolution',300); -catch - warning('Plot export was not successful') -end - -disp(['publishing of ', ID , ' done']); - -% CSV EXport -if options.CSV - T = table(); - T.research_Data = DataPaths.rdata'; T.PlotID(:) = {ID}; - T.Script_Name(:) = {[DataPaths.script,'.m']}; - T.Storage_Location(:) = {storPath}; - T.Date(:) = {datestr(now)}; - T = movevars(T,'PlotID','before',1); - writetable(T, fullfile(storPath, 'overview_table.csv'),'WriteMode','append'); -end - -end %function - -function tf = mustBeFigure(h) -%checks if input is a figure object - tf = strcmp(get(h, 'type'), 'figure') & isa(h, 'matlab.ui.Figure'); -end +function Publish(DataPaths, ID, figure, options) +%Publishes saves plot, data and measuring script +% Location sets the storage location. 'local' sets the storage location +% to the current folder (an export folder will be created), 'server' is a +% remote path, that is defined in the config file. +% Two Methods are implemented 'individual' stores the data for +% each plot while 'centralized' uses a data folder and uses reference links +% to the original data (hdf5 only). +% ParentFolder is the folder Name where the exported data is stored if an +% path is used, PlotId will use this path a storagePath + +arguments + DataPaths + ID (1,:) {mustBeNonzeroLengthText} % ID must be provided + figure (1,:) {mustBeFigure} % Checks if figure is a figure object + options.Location {mustBeMember(options.Location ,['local','server','CI-Test'])} = 'local' % storage path + options.Method {mustBeMember(options.Method ,['individual','centraliced'])} = 'individual' + options.ParentFolder (1,:) {mustBeText} = 'export' + options.CopyUserFCN (1,1) {mustBeNumericOrLogical} = true + options.CSV (1,1) {mustBeNumericOrLogical} = false +end + +%catch multiple figures in fig +if numel(figure) > 1 + figure = figure(1); + msg = ['Publish is designed for handeling one figure at once' newline,... + '- publishes uses only the first figure.' newline , ... + 'Consider an external for loop for multi figure export as provided in example.m']; + warning(msg); +end + +switch options.Location + case 'local' + if contains(options.ParentFolder, {'/','\'}) + storPath = options.ParentFolder; + else + % use the script path as export path + scriptPath = fileparts(DataPaths.script); + storPath = fullfile(scriptPath,options.ParentFolder); + end + case 'server' %from config File + txt = fileread('config.json'); + config = jsondecode(txt); + storPath = config.ServerPath; + case 'CI-Test' + storPath = fullfile(pwd,'CI_files',options.ParentFolder); +end +folderName = char(ID); + +%% Create Data-Directory +addpath(storPath); % ToDo necessary? - +if isfolder(fullfile(storPath,folderName)) + error(['Folder ',folderName, ' exists - Plot was already published ']); +elseif mkdir(fullfile(storPath,folderName)) +else + error('Directory could not be created - check remote path and permissions'); +end + +disp('Publishing started'); + +%% Create a Copy of the script and User functions(optional) +PlotID.createFileCopy({[DataPaths.script,'.m']},folderName,storPath,ID, 'script'); + +if options.CopyUserFCN + [fList,pList] = matlab.codetools.requiredFilesAndProducts(DataPaths.script); + % plist contains the required MATLAB Toolboxes, maybe usefull in future + fList = fList(~ismember(fList,[DataPaths.script,'.m'])); % rmv script from list + fList = PlotID.removePltIdFiles(fList); % Do not copy files that are part of plot ID + if ~isempty(fList) + PlotID.createFileCopy(fList,folderName,storPath,ID,'userFcn'); + end +end + +%% Research data handeling +switch options.Method + case 'centraliced' + % check if data folder exists + if ~isfolder(fullfile(storPath,'data')) + mkdir(fullfile(storPath,'data')); + end + %list all files + fList = dir(fullfile(storPath,'data', '**\*.*')); %get list of files and folders in any subfolder + fList = fList(~[fList.isdir]); %remove folders from list + fList = struct2table(fList); + + % Check if the new plot is based on the original data-set + % copy the data(once) + for i=1:numel(DataPaths.rdata) + % check if identical file exists (status = 1) + [~, idx] = PlotID.fileCompare(DataPaths.rdata{i},fList); + % create Linked HDF5 files for identical files + if any(idx) + sourcePath = fList{idx,'name'}; % If there are multiple copies already, this only picks the last entry + if contains(sourcePath,{'.h5','.hdf5'}) % Linking only for HDF5 + PlotID.createLinkedHDF5(sourcePath,storPath,ID); + end + else % no identical file exists + PlotID.createFileCopy(DataPaths.rdata{i},'data',storPath,ID,'dataCentral'); + end + end + case 'individual' + % Create a copy of the research data + PlotID.createFileCopy(DataPaths.rdata,folderName,storPath,ID, 'data'); +end +%% Export the Plot +try + PlotName = [ID,'_plot']; % plotname + RemotePath = fullfile(storPath ,folderName, PlotName); + % Matlab figure + savefig(figure,RemotePath); + % the png should only be a preview + exportgraphics(figure,[RemotePath,'.png'],'Resolution',300); +catch + warning('Plot export was not successful') +end + +disp(['publishing of ', ID , ' done']); + +% CSV EXport +if options.CSV + T = table(); + T.research_Data = DataPaths.rdata'; T.PlotID(:) = {ID}; + T.Script_Name(:) = {[DataPaths.script,'.m']}; + T.Storage_Location(:) = {storPath}; + T.Date(:) = {datestr(now)}; + T = movevars(T,'PlotID','before',1); + writetable(T, fullfile(storPath, 'overview_table.csv'),'WriteMode','append'); +end + +end %function + +function tf = mustBeFigure(h) +%checks if input is a figure object + tf = strcmp(get(h, 'type'), 'figure') & isa(h, 'matlab.ui.Figure'); +end diff --git a/+PlotID/createFileCopy.m b/+PlotID/createFileCopy.m index f8fb6f87ccb78dfbed207ca21cef2a2779a770d6..e10a1d9d3f9f9823ce9f788b90bce25a54537653 100644 --- a/+PlotID/createFileCopy.m +++ b/+PlotID/createFileCopy.m @@ -1,52 +1,54 @@ -function [] = createFileCopy(filePaths,folderName,storPath,ID,type) -% Creates a copy of the files (can be used for multiple paths in a cell array) -% folderName is the name of the exporting folder - disp(['start to copy ', type]); - - if ~iscell(filePaths) - %fixes Issue if Filepath is a char and not a cell array - filePaths = {filePaths}; - end - - try - for i = 1:numel(filePaths) - FileNameAndLocation = filePaths{i}; - [~,name,ext] = fileparts(filePaths{i}); % get the extension - - switch type - case 'data' - sufix = '_data'; - newfile = sprintf([ID, sufix, '_' , num2str(i) ,ext]); - case 'dataCentral' - %keep original name - newfile = sprintf([name,ext]); - case 'script' - sufix = '_script'; - newfile = sprintf([ID, sufix ,ext]); - case 'userFcn' - %keep original name - newfile = sprintf([name,ext]); - otherwise - error([type,' is not a valid type for createFileCopy']) - end %switch - - % Write the file - RemotePath = fullfile(storPath,folderName, newfile); - -% Check if remote file already exists - count = 0; - while isfile(RemotePath) && ismember(type,{'data','dataCentral'}) - % Add a Sufix number to new file name - count = count + 1; - [~,name,ext] = fileparts(RemotePath); - RemotePath = fullfile(storPath,folderName,... - [name,'_',num2str(count),ext]); - end - copyfile(FileNameAndLocation,RemotePath); - end - disp([type, ' sucessfully published']); - catch - warning([type,' export was not sucessful']) - end %try -end - +function [] = createFileCopy(filePaths,folderName,storPath,ID,type) +% Creates a copy of the files (can be used for multiple paths in a cell array) +% folderName is the name of the exporting folder + disp(['start to copy ', type]); + + if ~iscell(filePaths) + %fixes Issue if Filepath is a char and not a cell array + filePaths = {filePaths}; + end + + try + for i = 1:numel(filePaths) + FileNameAndLocation = filePaths{i}; + [~,name,ext] = fileparts(filePaths{i}); % get the extension + + switch type + case 'data' + sufix = '_data'; + newfile = sprintf([ID, sufix, '_' , num2str(i) ,ext]); + case 'dataCentral' + %keep original name + newfile = sprintf([name,ext]); + case 'script' + sufix = '_script'; + newfile = sprintf([ID, sufix ,ext]); + case 'userFcn' + %keep original name + newfile = sprintf([name,ext]); + otherwise + error([type,' is not a valid type for createFileCopy']) + end %switch + + % Write the file + RemotePath = fullfile(storPath,folderName, newfile); + +% Check if remote file already exists + count = 0; + while isfile(RemotePath) && ismember(type,{'data','dataCentral'}) + % Add a Sufix number to new file name + % TODO add more inteligent way then a simple sufix + count = count + 1; + [~,name,ext] = fileparts(RemotePath); + RemotePath = fullfile(storPath,folderName,... + [name,'_',num2str(count),ext]); + warning('Filename already exists in data folder'); + end + copyfile(FileNameAndLocation,RemotePath); + end + disp([type, ' sucessfully published']); + catch + warning([type,' export was not sucessful']) + end %try +end + diff --git a/+PlotID/createLinkedHDF5.m b/+PlotID/createLinkedHDF5.m index ea59760ecec0219ac4a2ac07476f7c913ccc7c51..17ad29de36e5613975a17afaf4a0d3f9afadf731 100644 --- a/+PlotID/createLinkedHDF5.m +++ b/+PlotID/createLinkedHDF5.m @@ -5,6 +5,11 @@ function [status] = createLinkedHDF5(SourceFile,TargetPath,ID) plist_id = 'H5P_DEFAULT'; +%catches error of wrong file type +if iscell(SourceFile) + SourceFile = SourceFile{1}; +end + % try fid = H5F.create(fullfile(TargetPath,ID,[ID,'_data.h5'])); %create External Link to Sourcefile in the Group linkToExternal diff --git a/CI_files/default_test.m b/CI_files/default_test.m index 3d1f20cf2420bac03b5f90a4ec7d1da38b21c49a..9f275accc9d660806a6208fa1c9bd4767d3ff090 100644 --- a/CI_files/default_test.m +++ b/CI_files/default_test.m @@ -61,7 +61,7 @@ try delete CI_files/export/* CI_files/*.mat CI_files/*.h5 rmdir('CI_files/export','s'); result = true; - clc; + clc; clear; catch result = false; warning('simple_test failed'); diff --git a/example.m b/example.m index 25707e6913a71fe0103cd78dc697cb1c01df19ab..86648e098ba9e3735bca16d0afe6768678fa0bfa 100644 --- a/example.m +++ b/example.m @@ -111,4 +111,4 @@ plot(x1,y1,'-r'); [fig2, ID] = PlotID.TagPlot(fig2,'ProjectID', ProjectID); -PlotID.Publish(path, ID, fig2, 'Location', 'local','Method','centralized') \ No newline at end of file +PlotID.Publish(path, ID, fig2, 'Location', 'local','Method','centraliced')