function DataTable = nappGenerateSpectra(DataTable,varargin) %NAPPGENERATESPECTRA Generate 1D spectra from image spectra. % DataTable = NAPPGENERATESPECTRA(DataTable) processes all data in the % input table and generates spectra for the data files in each row. The % spectra are written back into the table into new columns (table % variables). % % DataTable = NAPPGENERATESPECTRA(DataTable, tableSelection) restricts % processing to the rows where tableSelection is true. The length of % tableSelection must match the number of rows in DataTable. % % DataTable = NAPPGENERATESPECTRA(DataTable, tableSelection, Name, Value) % additionally customizes the source variable, reduction mode, and energy % or iteration ranges via Name-Value arguments. % % Required input % -------------- % DataTable % Table that contains at least the variables: % - name : file name as character vector or string % - image or imageRoh : 2D image or image stack stored in a cell % - scientaEkin_eV : kinetic energy axis % % Optional positional input % ------------------------- % tableSelection % Logical vector selecting rows to process. % Size: [height(DataTable) 1] or [1 height(DataTable)] % Default: all rows true % % Name-Value arguments % -------------------- % 'tableVariable' % Name of the variable in DataTable that contains the image data. % Type : char or string % Values : 'image' (default) | 'imageRoh' % % 'mode' % Reduction mode used to generate the spectra. % Type : char or string % Values : 'mean' (default) | 'sum' | 'trapz' | 'AugerMeitnerMean' % Behaviour: % - For '.h5' entries: % 'sum' or 'mean' : sum over the selected kinetic energy range % (currently identical behaviour; no % normalization by time implemented). % 'trapz' : trapezoidal integration over kinetic % energy for each column. % - For '.ibw' entries: % 'mean' or 'trapz': mean over the selected iteration range % (2nd dimension) and store as a column % vector. % 'sum' : sum over the selected iteration range. % % 'iterationRange' % Iteration indices for '.ibw' image stacks (2nd dimension). % Type : numeric 1x2 vector [startIdx endIdx] % Default: [0 0] -> use full range 1 : size(image,2) % % 'eKinStart' % Lower kinetic energy limit for '.h5' data. % Type : numeric scalar % Default: 0 -> use first element of scientaEkin_eV % % 'eKinEnd' % Upper kinetic energy limit for '.h5' data. % Type : numeric scalar % Default: 0 -> use last element of scientaEkin_eV % % Output % ------ % DataTable % Same table as input, with the following variables ensured and % updated for the selected rows: % % spectrum_counts % Cell array. Each cell contains a spectrum generated from the % selected image data, depending on file type and mode % ('sum', 'mean', or 'trapz'). % % spectrum_countsPerSecond % Cell array. For '.ibw' entries and modes 'mean' or 'trapz', % this stores the spectrum obtained by averaging over the chosen % iteration range. % % logGenerateMode % Cell array of character vectors specifying the mode used for % each processed row. % % logGenerateRange % Numeric matrix with two columns. For '.h5' entries this stores % [eKinStart eKinEnd]. For '.ibw' entries this stores % [iterationStart iterationEnd]. % % logGenerateDate % Cell array of character vectors containing the date and time % when the spectra were generated. % % Notes % ----- % - The function distinguishes between '.h5' and '.ibw' files based on % the file name stored in the variable 'name'. % Define conditions and defaults of input defaultTableVariable = 'image'; expectedTableVariable = {'image','imageRoh'}; defaultMode = 'mean'; expectedMode = {'mean','sum','trapz','AugerMeitnerMean'}; defaultEkinStart = 0; defaultEkinEnd = 0; defaultTableSelection = true(size(DataTable,1),1); % Parse input p = inputParser; addRequired(p,'DataTable',@istable); addOptional(p,'tableSelection',defaultTableSelection,@islogical); addParameter(p,'tableVariable',defaultTableVariable,... @(x) any(validatestring(x,expectedTableVariable))); addParameter(p,'mode',defaultMode,... @(x) any(validatestring(x,expectedMode))); addParameter(p,'iterationRange',[0:0]); addParameter(p,'eKinStart',defaultEkinStart,@isnumeric) addParameter(p,'eKinEnd',defaultEkinEnd,@isnumeric) parse(p,DataTable,varargin{:}); % add empty variable to table existColumn = strcmp('spectrum_countsPerSecond',p.Results.DataTable.Properties.VariableNames); if ~any(existColumn) DataTable.spectrum_countsPerSecond = cell(size(p.Results.DataTable,1),1); end existColumn = strcmp('spectrum_counts',p.Results.DataTable.Properties.VariableNames); if ~any(existColumn) DataTable.spectrum_counts = cell(size(p.Results.DataTable,1),1); end existColumn = strcmp('logGenerateRange',p.Results.DataTable.Properties.VariableNames); if ~any(existColumn) DataTable.logGenerateRange = NaN(size(p.Results.DataTable,1),2); end existColumn = strcmp('logGenerateDate',p.Results.DataTable.Properties.VariableNames); if ~any(existColumn) DataTable.logGenerateDate = cellstr(repmat(' ',size(p.Results.DataTable,1),1)); end existColumn = strcmp('logGenerateMode',p.Results.DataTable.Properties.VariableNames); if ~any(existColumn) DataTable.logGenerateDate = cellstr(repmat(' ',size(p.Results.DataTable,1),1)); end % check input (all elements of input variable need to have non-zero size) if ~all(cell2mat(cellfun(@size,p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable),'UniformOutput',false)),'all') disp('The table variable appears to be empty. I quit now') error('The table variable appears to be empty.') end % create empty variables tmp_3 = cell(size(p.Results.DataTable(p.Results.tableSelection,:),1),1); tmp_6 = cell(size(p.Results.DataTable(p.Results.tableSelection,:),1),1); tmp_4 = NaN(size(p.Results.DataTable(p.Results.tableSelection,:),1),1); tmp_5 = NaN(size(p.Results.DataTable(p.Results.tableSelection,:),1),1); % repeat this for all columns in input. for ii = 1:size(p.Results.DataTable(p.Results.tableSelection,:),1) if endsWith(p.Results.DataTable(p.Results.tableSelection,:).name{ii},'h5') % let's do NEXAFS first. % Get index of EkinStart and EkinEnd if (p.Results.eKinStart) == 0 tmp_1 = 1; else tmp_1 = find(p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii} >= p.Results.eKinStart,1); end if (p.Results.eKinEnd) == 0 tmp_2 = length(p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii}); else tmp_2 = find(p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii} >= p.Results.eKinEnd,1); end if contains(p.Results.mode,'trapz') tmp_3(ii,1)= {trapz(p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii}(tmp_1:tmp_2),... p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii}(tmp_1:tmp_2,:))'}; elseif (contains(p.Results.mode,'sum') | contains(p.Results.mode,'mean')) tmp_3(ii,1) = {sum(p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii}(tmp_1:tmp_2,:),1)'}; %#ok<*AGROW> end % log tmp_4(ii,1) = p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii}(tmp_1); tmp_5(ii,1) = p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii}(tmp_2); elseif endsWith(p.Results.DataTable(p.Results.tableSelection,:).name{ii},'ibw') || endsWith(p.Results.DataTable(p.Results.tableSelection,:).name{ii},'xy') % then do Igorfiles or xy files if p.Results.iterationRange(1) == 0 startRange = 1; endRange = size(p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii},2); else startRange = p.Results.iterationRange(1); endRange = p.Results.iterationRange(2); end if (contains(p.Results.mode,'mean') | contains(p.Results.mode,'trapz')) tmp_6(ii,1)= {mean(p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii}(:,startRange:endRange),2)}; elseif contains(p.Results.mode,'sum') tmp_3(ii,1) = {sum(p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii}(:,startRange:endRange),2)}; %#ok<*AGROW> end % log tmp_4(ii,1) = startRange; tmp_5(ii,1) = endRange; end end % write results to table DataTable.spectrum_counts(p.Results.tableSelection) = tmp_3; DataTable.spectrum_countsPerSecond(p.Results.tableSelection) = tmp_6; % write log to table DataTable.logGenerateMode(p.Results.tableSelection,:) = cellstr(repmat(p.Results.mode,size(p.Results.DataTable(p.Results.tableSelection,:),1),1)); DataTable.logGenerateRange(p.Results.tableSelection,:) = [tmp_4 tmp_5]; DataTable.logGenerateDate(p.Results.tableSelection,:) = cellstr(repmat(datestr(now),size(p.Results.DataTable(p.Results.tableSelection,:),1),1)); end