Added documentation to readme file. Re-arranged folder content slightly
This commit is contained in:
1 parent
7677ad8668
commit
1b89885447
25 files changed
+1728
-432
No files matched your search
@@ -1,6 +1,5 @@
|
||||
function relHum = Napp_RH_p(T_current,partial_pressure_water)
|
||||
%Napp_RH_p calculates the relative humidity for a given
|
||||
% temperature and water pressure.
|
||||
%Napp_RH_p helper function that calculates the relative humidity for a given temperature and water pressure.
|
||||
%
|
||||
% With the relative humidity referenced
|
||||
% to liquid water (RH_w) as opposed to ice (RH_i), the activity of water
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
function Napp_p_RH(T_current,RH)
|
||||
%Napp_p_RH calculates the partial pressure of water for a given
|
||||
% temperature and relative humidity. With the relative humidity referenced
|
||||
%Napp_p_RH helper function that calculates the partial pressure of water for a given temperature and relative humidity.
|
||||
% With the relative humidity referenced
|
||||
% to liquid water (RH_w) as opposed to ice (RH_i), the activity of water
|
||||
% is: activity_w = RH_{water}/100
|
||||
%
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
function p = Napp_p_ice(T_current)
|
||||
%Napp_p_ice(T_current) plots the vapour pressure of ice between 200-270 K
|
||||
% and marks the vapour pressure of ice at a given temperature. It also
|
||||
% displays the vapour pressure at a temperature of choice in the command
|
||||
%Napp_p_ice marks the vapor pressure at a given temperature in a plot of the vapor pressure of ice between 200-270 K
|
||||
% It also displays the vapor pressure at a temperature of choice in the command
|
||||
% window.
|
||||
%
|
||||
% * Napp_p_ice(T_current)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
function FileList = addPhotonEnergy(FileList,fileNumber,notesToAdd,dataMonth,dataYear)
|
||||
%addPhotonEnergy adds the beam lines photon energy to the data table
|
||||
%addPhotonEnergy adds the Xray photon energy for selected measurements to the data table
|
||||
%
|
||||
% FileList = addPhotonEnergy(FileList,[1,8:12,26],1000,2,2022);
|
||||
%
|
||||
|
||||
@@ -8,7 +8,7 @@ function DataTable = addSampleNotes(DataTable,fileNumber,notesToAdd,dataMonth,da
|
||||
% * the name of the data table,
|
||||
% * the file numbers of the SES scans to which the info should be added
|
||||
% * a text string describing the sample,
|
||||
% * the month and the year that the data was aquired
|
||||
% * the month and the year that the data was acquired
|
||||
% * optional: 'XPS' or 'NEXAFS' as last input argument to limit to either XPS data or NEXAFS
|
||||
% data
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
function DataTable = nappAlignImages(DataTable,varargin)
|
||||
%nappAlignImages shifts each sequence iteration to align images with a
|
||||
%drifting kinetic energy of the PE features.
|
||||
%nappAlignImages shifts each sequence iteration to align images with a drifting kinetic energy of the PE features.
|
||||
% The kinetic energy must be determined first, before running this function.
|
||||
%
|
||||
% FileList = nappAlignImages(FileList,'tableSelection',tmpDataSelection,...
|
||||
% 'tableVariable','image');
|
||||
|
||||
@@ -1,5 +1,19 @@
|
||||
function nappAnnotateSurvey(X,Y,dataObjs,labeltext)
|
||||
% nappAnnotateSurvey adds region labels to a survey in the topmost figure.
|
||||
%nappAnnotateSurvey is a small helper function that adds region labels to a survey in the topmost figure.
|
||||
%
|
||||
%
|
||||
% nappAnnotateSurvey(tmpxRayEnergy-84-tmpxShift,tmpyPosition,dataObjs(1),'Au4f7/2');
|
||||
%
|
||||
% The input is:
|
||||
%
|
||||
% y position of label: dataObjs = findobj(gcf,'-property','YData');
|
||||
% x position of label: tmpxRayEnergy-84-tmpxShift: X-ray energy - binding
|
||||
% energy - shift (including beamline offset)
|
||||
% tmpxShift = 7;
|
||||
% tmpxRayEnergy = 850;
|
||||
% tmpyPosition = 0.5E5; % shift of label above data.
|
||||
% tmpyPositionTwo = 0.8E5;
|
||||
%
|
||||
ha = annotation('arrow'); % store the arrow information in ha
|
||||
ha.Parent = gca; % associate the arrow the the current axes
|
||||
ha.X = [X X]; % the location in data units
|
||||
|
||||
+92
-26
@@ -1,37 +1,103 @@
|
||||
function DataTable = nappBackground(DataTable,varargin)
|
||||
%nappBackground determines and subtracts the background from PE or XAS spectra
|
||||
%NAPPBACKGROUND Removes background from photoelectron or XAS spectra.
|
||||
% This function determines and removes the background from PE or XAS
|
||||
% spectra using mean subtraction or curve fitting (linear or exponential).
|
||||
% Background correction can be performed on kinetic energy, binding energy,
|
||||
% or X-ray photon energy scales. Results are optionally normalized by
|
||||
% dividing instead of subtracting.
|
||||
%
|
||||
% FileList = nappBackground(FileList,energyStart,energyEnd);
|
||||
% SYNTAX
|
||||
% ------
|
||||
% DataTable = NAPPBACKGROUND(DataTable, energyStart, energyEnd)
|
||||
%
|
||||
% FileList = nappBackground(FileList,368,370,'tableSelection',tmpDataSelection,'energyScale','kinetic',...
|
||||
% 'mode','mean','showFigures','off');
|
||||
% DataTable = NAPPBACKGROUND(DataTable, energyStart, energyEnd, 'Name', Value)
|
||||
%
|
||||
% EXAMPLES
|
||||
% --------
|
||||
% % Simple mean subtraction with kinetic energy scale
|
||||
% DataTable = nappBackground(DataTable, 368, 370);
|
||||
%
|
||||
% *input*
|
||||
% FileList: data table
|
||||
% energyStart: smallest value of energy range to use for background calculation
|
||||
% (can also be binding energy)
|
||||
% energyEnd: largest value of energy energy range to use for background calculation
|
||||
% (can also be binding energy)
|
||||
% tableSelection (optional): logical array to filter data table
|
||||
% tableVariable: choose to process either
|
||||
% 'spectrum_counts','spectrum_countsPerSecond' (default), or
|
||||
% 'spectrum_countsNorm'.
|
||||
% mode: mean(default) subtract the mean of the energy range from
|
||||
% spectrum; linfit subtract a linear regression through the energy range
|
||||
% from spectrum
|
||||
% showFigures, on(default): show fit in figure, off do not show fit in
|
||||
% figure
|
||||
% energyScale: kinetic(default): work with kinetic energy scale; binding
|
||||
% works with binding energy scale.
|
||||
% % Linear fit on selected rows with binding energy scale
|
||||
% DataTable = nappBackground(DataTable, 368, 370, ...
|
||||
% 'tableSelection', tmpDataSelection, ...
|
||||
% 'energyScale', 'binding', ...
|
||||
% 'mode', 'linfit', ...
|
||||
% 'showFigures', 'off');
|
||||
%
|
||||
% INPUT ARGUMENTS
|
||||
% ---------------
|
||||
% DataTable table
|
||||
% Data table containing spectra and energy scales. Must contain
|
||||
% one of the following variables: 'spectrum_counts',
|
||||
% 'spectrum_countsPerSecond', or 'spectrum_countsNorm'.
|
||||
%
|
||||
% *output*
|
||||
% The table variable passed to the function as tableVariable
|
||||
% parameter will be overwritten with the background subtracted spectrum.
|
||||
% energyStart numeric scalar or vector
|
||||
% Lower bound(s) of energy range for background calculation.
|
||||
% Scalar: single energy range.
|
||||
% Vector [E1, E2]: two disjoint ranges [E1, E2] to [end] and [E2, E1].
|
||||
% Note: For binding energy scale, comparison direction reverses.
|
||||
%
|
||||
% The function parameters (mode, energyStart, energyEnd) are written
|
||||
% to the table as log.
|
||||
% energyEnd numeric scalar or vector
|
||||
% Upper bound(s) of energy range for background calculation.
|
||||
% See energyStart for vector behavior.
|
||||
%
|
||||
% NAME-VALUE PAIR ARGUMENTS (optional)
|
||||
% ------------------------------------
|
||||
% 'tableSelection' logical array (default: all rows)
|
||||
% Logical index to filter rows in DataTable.
|
||||
% Example: tableSelection = DataTable.quality > 0.8
|
||||
%
|
||||
% 'tableVariable' char vector (default: 'spectrum_countsPerSecond')
|
||||
% Spectral variable to process. Must be one of:
|
||||
% - 'spectrum_counts'
|
||||
% - 'spectrum_countsPerSecond'
|
||||
% - 'spectrum_countsNorm'
|
||||
%
|
||||
% 'mode' char vector (default: 'mean')
|
||||
% Background subtraction method:
|
||||
% - 'mean': subtract mean intensity in energy range
|
||||
% - 'linfit': subtract linear regression (poly1 fit)
|
||||
% - 'exponential': subtract exponential fit (exp2)
|
||||
% - 'mean, divide': divide by mean (normalization)
|
||||
% - 'linfit, divide': divide by linear fit
|
||||
% - 'exponential, divide': divide by exponential fit
|
||||
%
|
||||
% 'energyScale' char vector (default: 'kinetic')
|
||||
% Energy axis to use for background calculation:
|
||||
% - 'kinetic': uses scientaEkin_eV column
|
||||
% - 'binding': uses bindingEnergy_eV column
|
||||
% - 'xRay': uses xRayEkin_eV column (for NEXAFS data)
|
||||
%
|
||||
% 'showFigures' char vector (default: 'on')
|
||||
% Display fit visualization:
|
||||
% - 'on': show fit plot with data and excluded points
|
||||
% - 'off': suppress figure output
|
||||
%
|
||||
% OUTPUT ARGUMENTS
|
||||
% ----------------
|
||||
% DataTable table
|
||||
% Updated data table with background-corrected spectra. The table
|
||||
% variable specified by 'tableVariable' is overwritten with
|
||||
% corrected data. If mode contains 'divide', results are written
|
||||
% to 'spectrum_countsNorm' instead.
|
||||
%
|
||||
% Three log columns are added/updated:
|
||||
% - logBackgroundMode: fitting method used
|
||||
% - logBackgroundRange: [energyStart, energyEnd] for each row
|
||||
% - logBackgroundDate: timestamp of processing
|
||||
%
|
||||
% NOTES
|
||||
% -----
|
||||
% - Empty or missing spectra in tableVariable will trigger an error.
|
||||
% - For 'mean' mode with binding energy, energy comparisons use <= operator
|
||||
% (reversed compared to kinetic energy mode).
|
||||
% - Exponential fits ('exp2' type) are computed via nonlinear least squares
|
||||
% excluding points outside the specified energy range.
|
||||
% - Generated log entries are identical for all rows in tableSelection.
|
||||
%
|
||||
% SEE ALSO
|
||||
% --------
|
||||
% inputParser, fit, fittype, prepareCurveData, excludedata
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,114 +0,0 @@
|
||||
function DataTable = nappBackground(DataTable,varargin)
|
||||
%nappBackground determines and subtracts the background from PE or XAS spectra
|
||||
%
|
||||
% FileList = nappBackground(FileList,energyStart,energyEnd);
|
||||
%
|
||||
% FileList = nappBackground(FileList,368,370,'tableSelection',tmpDataSelection,'energyScale','kinetic',...
|
||||
% 'mode','mean','showFigures','off');
|
||||
%
|
||||
%
|
||||
% *input*
|
||||
% FileList: data table
|
||||
% energyStart: smallest value of energy range to use for background calculation
|
||||
% (can also be binding energy)
|
||||
% energyEnd: largest value of energy energy range to use for background calculation
|
||||
% (can also be binding energy)
|
||||
% tableSelection (optional): logical array to filter data table
|
||||
% tableVariable: choose to process either
|
||||
% 'spectrum_counts','spectrum_countsPerSecond' (default), or
|
||||
% 'spectrum_countsNorm'.
|
||||
% mode: mean(default) subtract the mean of the energy range from
|
||||
% spectrum; linfit subtract a linear regression through the energy range
|
||||
% from spectrum
|
||||
% showFigures, on(default): show fit in figure, off do not show fit in
|
||||
% figure
|
||||
% energyScale: kinetic(default): work with kinetic energy scale; binding
|
||||
% works with binding energy scale.
|
||||
%
|
||||
%
|
||||
% *output*
|
||||
% The table variable passed to the function as tableVariable
|
||||
% parameter will be overwritten with the background subtracted spectrum.
|
||||
%
|
||||
% The function parameters (mode, energyStart, energyEnd) are written
|
||||
% to the table as log.
|
||||
|
||||
|
||||
|
||||
% Define conditions and defaults of input
|
||||
defaultTableVariable = 'spectrum_countsPerSecond';
|
||||
expectedTableVariable = {'spectrum_counts','spectrum_countsPerSecond','spectrum_countsNorm'};
|
||||
defaultMode = 'mean';
|
||||
expectedMode = {'mean','linfit'};
|
||||
defaultTableSelection = true(size(DataTable,1),1);
|
||||
defaultShowFigures = 'on';
|
||||
expectedShowFigures = {'on','off'};
|
||||
defaultEnergyScale = 'kinetic';
|
||||
expectedEnergyScale = {'kinetic','binding'};
|
||||
|
||||
% Parse input
|
||||
p = inputParser;
|
||||
addRequired(p,'DataTable',@istable);
|
||||
addRequired(p,'energyStart',@isnumeric)
|
||||
addRequired(p,'energyEnd',@isnumeric)
|
||||
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,'showFigures',defaultShowFigures,...
|
||||
@(x) any(validatestring(x,expectedShowFigures)));
|
||||
addParameter(p,'energyScale',defaultEnergyScale,...
|
||||
@(x) any(validatestring(x,expectedEnergyScale)));
|
||||
parse(p,DataTable,varargin{:});
|
||||
|
||||
% 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
|
||||
|
||||
% repeat this for all columns in input.
|
||||
for ii = 1:size(p.Results.DataTable(p.Results.tableSelection,:),1)
|
||||
if contains(p.Results.energyScale,'kinetic')
|
||||
% LINEAR FIT
|
||||
if contains(p.Results.mode,'linfit')
|
||||
disp('linfit not yet supported')
|
||||
% MEAN
|
||||
else
|
||||
b_1 = find(p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii} >= p.Results.energyStart,1);
|
||||
b_2 = find(p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii} >= p.Results.energyEnd,1);
|
||||
|
||||
if b_2 == 1
|
||||
b_2=10;
|
||||
end
|
||||
|
||||
b_mean = mean(p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii}(b_1:b_2),'omitnan');
|
||||
tmp(ii,1) = cellfun(@(x) x-b_mean,p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable)(ii),'UniformOutput',false);
|
||||
|
||||
|
||||
end
|
||||
|
||||
elseif contains(p.Results.energyScale,'binding')
|
||||
if contains(p.Results.mode,'linfit')
|
||||
disp('linfit not yet supported')
|
||||
% MEAN
|
||||
else
|
||||
b_1 = find(p.Results.DataTable(p.Results.tableSelection,:).bindingEnergy_eV{ii} <= p.Results.energyStart,1);
|
||||
b_2 = find(p.Results.DataTable(p.Results.tableSelection,:).bindingEnergy_eV{ii} <= p.Results.energyEnd,1);
|
||||
|
||||
if b_2 == 1
|
||||
b_2=10;
|
||||
end
|
||||
|
||||
b_mean = mean(p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii}(b_2:b_1),'omitnan');
|
||||
tmp(ii,1) = cellfun(@(x) x-b_mean,p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable)(ii),'UniformOutput',false);
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
% fill selected rows
|
||||
DataTable(p.Results.tableSelection,:).(p.Results.tableVariable) = tmp;
|
||||
|
||||
end
|
||||
@@ -1,10 +1,9 @@
|
||||
function DataTable = nappBindingEnergyXps(DataTable,varargin)
|
||||
%nappBindingEnergyXps calculates the binding energy scale for spectra based
|
||||
%on the binding energy shift.
|
||||
%nappBindingEnergyXps calculates the binding energy scale for spectra based on the kinetic energy shift.
|
||||
%
|
||||
% *Requirement*
|
||||
% Needs table variable bindingEnergyShift as input. Run
|
||||
% nappDetermineShiftXps.m or nappCopyShift.m first
|
||||
% nappDetermineShiftXps.m and nappCopyShift.m first
|
||||
%
|
||||
% FileList = nappBindingEnergyXps(FileList,'tableSelection',...
|
||||
% tmpDataSelection);
|
||||
|
||||
+107
-60
@@ -1,67 +1,28 @@
|
||||
function combinedSpectrum = nappCombineSpectra(DataTable,varargin)
|
||||
%nappCombineSpectra Combine multiple PE or NEXAFS spectra through averaging or summation
|
||||
%NAPPCOMBINESPECTRA Combine multiple PE or NEXAFS spectra through averaging or summation.
|
||||
% This function combines selected photoelectron (PE) or X-ray absorption
|
||||
% spectroscopy (NEXAFS) spectra into a single spectrum by averaging or
|
||||
% summing. Data are automatically interpolated onto a common energy axis
|
||||
% to handle slight variations in energy sampling between acquisitions.
|
||||
%
|
||||
% combinedSpectrum = nappCombineSpectra(DataTable)
|
||||
% combinedSpectrum = nappCombineSpectra(DataTable, Name, Value)
|
||||
% The output format is controlled by the 'output' parameter:
|
||||
% - 'simple' (default): Returns a numeric matrix [energy, intensity, (std)]
|
||||
% suitable for quick plotting and analysis. Requires custom code for
|
||||
% plotting and further processing.
|
||||
% - 'complete': Returns a MATLAB table (same format as input DataTable) with
|
||||
% energy axis and combined spectrum plus metadata. Critically, this allows
|
||||
% all existing nappXXX functions to operate directly on the combined result
|
||||
% without conversion. Output table is named '<originalName>_combined.h5'
|
||||
% where originalName is from the first selected row's name field.
|
||||
%
|
||||
% Combines selected photoelectron or NEXAFS spectra into a single spectrum.
|
||||
% Data are interpolated onto a common energy axis to handle slight variations
|
||||
% in energy sampling between different acquisitions.
|
||||
% SYNTAX
|
||||
% ------
|
||||
% combinedSpectrum = NAPPCOMBINESPECTRA(DataTable)
|
||||
%
|
||||
% INPUTS:
|
||||
% DataTable - Table containing spectroscopy data with spectrum variables and
|
||||
% energy scales
|
||||
%
|
||||
% NAME-VALUE PAIR ARGUMENTS:
|
||||
%
|
||||
% 'tableSelection' - Logical array to filter which rows of DataTable to combine
|
||||
% Default: all rows (true(size(DataTable,1),1))
|
||||
% Example: contains(DataTable.name, 'C1s') to select C1s spectra
|
||||
%
|
||||
% 'tableVariable' - Select which spectrum type to combine:
|
||||
% PE spectra:
|
||||
% 'spectrum_counts' - Raw spectrum counts
|
||||
% 'spectrum_countsPerSecond' - Count rate normalized spectrum
|
||||
% 'spectrum_countsNorm' - Normalized spectrum (arbitrary units)
|
||||
%
|
||||
% NEXAFS spectra:
|
||||
% 'nexafsSpectrum' - Processed NEXAFS spectrum
|
||||
% 'nexafsSpectrumPreBackground' - Before background subtraction
|
||||
% 'nexafsSpectrumPreNorm' - Before normalization
|
||||
% 'nexafsSpectrumPreGasPhase' - Before gas phase correction
|
||||
% 'nexafsSpectrumPreI0' - Before I0 normalization
|
||||
% 'nexafsSpectrumPreAdvCarb' - Before adventitious carbon correction
|
||||
%
|
||||
% 'tableRow' - Index of the spectrum whose energy axis will be used as the
|
||||
% interpolation reference (within the filtered table)
|
||||
% Default: 1 (first spectrum in filtered selection)
|
||||
% The common energy range will span the overlap of all spectra
|
||||
%
|
||||
% 'mode' - Method for combining spectra:
|
||||
% 'sum' (default) - Add all spectra together (increases signal)
|
||||
% 'average' - Calculate mean and standard deviation across spectra
|
||||
% 'subtract' - Subtract spectra (not yet implemented)
|
||||
%
|
||||
% 'energyScale' - Energy axis for PE spectra (ignored for NEXAFS):
|
||||
% 'kinetic' (default) - Kinetic energy scale (eV)
|
||||
% 'binding' - Binding energy scale (eV)
|
||||
% 'xRay' - Photon energy scale (eV)
|
||||
%
|
||||
% OUTPUT:
|
||||
% combinedSpectrum - Matrix containing the combined spectrum:
|
||||
% Column 1: Energy values (eV) on common interpolated axis
|
||||
% Column 2: Combined intensity (sum or mean depending on mode)
|
||||
% Column 3: Standard deviation (only when mode = 'average')
|
||||
%
|
||||
% NOTES:
|
||||
% - The function automatically determines the overlapping energy range across
|
||||
% all selected spectra and interpolates onto a common grid
|
||||
% - The reference energy grid comes from the spectrum specified by 'tableRow'
|
||||
% - Missing or NaN values are excluded from calculations
|
||||
% - For 'average' mode, standard deviation quantifies variability between spectra
|
||||
%
|
||||
% EXAMPLES:
|
||||
% combinedSpectrum = NAPPCOMBINESPECTRA(DataTable, 'Name', Value)
|
||||
%
|
||||
% EXAMPLES
|
||||
% --------
|
||||
% % Average normalized C1s spectra with binding energy scale
|
||||
% selection = contains(DataTable.name, 'C1s');
|
||||
% avgSpectrum = nappCombineSpectra(DataTable, ...
|
||||
@@ -93,7 +54,93 @@ function combinedSpectrum = nappCombineSpectra(DataTable,varargin)
|
||||
% 'tableVariable', 'nexafsSpectrumPreNorm', ...
|
||||
% 'mode', 'average');
|
||||
%
|
||||
% See also: nappPlot, interp1
|
||||
% INPUT ARGUMENTS
|
||||
% ---------------
|
||||
% DataTable table
|
||||
% Data table containing spectroscopy spectra and corresponding energy
|
||||
% scales. Must contain at least one spectrum variable and matching
|
||||
% energy axis variable.
|
||||
%
|
||||
% NAME-VALUE PAIR ARGUMENTS (optional)
|
||||
% ------------------------------------
|
||||
% 'tableSelection' logical array (default: all rows)
|
||||
% Logical index to filter which rows of DataTable to combine.
|
||||
% Example: contains(DataTable.name, 'C1s') to select C1s spectra
|
||||
% Example: DataTable.quality > 0.8 to select high-quality measurements
|
||||
%
|
||||
% 'tableVariable' char vector (default: 'spectrum_counts')
|
||||
% Select which spectrum type to combine. Must be one of:
|
||||
%
|
||||
% PE spectra:
|
||||
% - 'spectrum_counts'
|
||||
% - 'spectrum_countsPerSecond'
|
||||
% - 'spectrum_countsNorm'
|
||||
%
|
||||
% NEXAFS spectra:
|
||||
% - 'nexafsSpectrum'
|
||||
% - 'nexafsSpectrumPreBackground'
|
||||
% - 'nexafsSpectrumPreNorm'
|
||||
% - 'nexafsSpectrumPreGasPhase'
|
||||
% - 'nexafsSpectrumPreI0'
|
||||
% - 'nexafsSpectrumPreAdvCarb'
|
||||
%
|
||||
% 'tableRow' numeric scalar (default: 1)
|
||||
% Index of the spectrum whose energy axis is used as reference for
|
||||
% interpolation (index within the filtered table defined by
|
||||
% 'tableSelection'). The combined spectrum's common energy grid
|
||||
% is extracted from this row. Range: 1 to number of selected rows.
|
||||
%
|
||||
% 'mode' char vector (default: 'sum')
|
||||
% Method for combining spectra:
|
||||
% - 'sum': add all spectra together (increases signal)
|
||||
% - 'average': calculate mean and standard deviation across spectra
|
||||
% - 'subtract': subtract spectra (not yet implemented)
|
||||
%
|
||||
% 'energyScale' char vector (default: 'kinetic')
|
||||
% Energy axis to use for PE spectra (ignored for NEXAFS):
|
||||
% - 'kinetic': kinetic energy scale (eV) - uses scientaEkin_eV
|
||||
% - 'binding': binding energy scale (eV) - uses bindingEnergy_eV
|
||||
% - 'xRay': photon energy scale (eV) - uses xRayEkin_eV
|
||||
%
|
||||
% 'output' char vector (default: 'simple')
|
||||
% Output format:
|
||||
% - 'simple': return matrix with energy and combined intensity
|
||||
% - 'complete': return table with full metadata and sorting info
|
||||
%
|
||||
% OUTPUT ARGUMENTS
|
||||
% ----------------
|
||||
% combinedSpectrum numeric matrix or table
|
||||
% Combined spectroscopy data. Format depends on 'output' parameter:
|
||||
%
|
||||
% For 'simple' output (default):
|
||||
% - Column 1: Energy values (eV) on common interpolated axis
|
||||
% - Column 2: Combined intensity (sum or mean depending on mode)
|
||||
% - Column 3: Standard deviation (only when mode = 'average')
|
||||
%
|
||||
% For 'complete' output:
|
||||
% - Returns table with energy axis and spectrum(s) plus metadata columns
|
||||
% (name, folder, creationDate, analysisDir, lastModifiedDatestr,
|
||||
% lastModifiedDatenum) and is sorted by modification date
|
||||
%
|
||||
% NOTES
|
||||
% -----
|
||||
% - The function automatically determines the overlapping energy range across
|
||||
% all selected spectra and interpolates to a common grid defined by the
|
||||
% reference spectrum ('tableRow' parameter).
|
||||
% - For binding energy scale, the overlap is computed using <= comparisons
|
||||
% (reversed from kinetic energy behavior).
|
||||
% - Missing or NaN values are excluded from calculations using 'omitnan' flag.
|
||||
% - For 'average' mode, standard deviation quantifies variability between
|
||||
% acquisitions and indicates measurement uncertainty.
|
||||
% - Energy axes must be monotonic (strictly increasing or decreasing) for
|
||||
% interpolation to work correctly.
|
||||
% - All selected spectra must have compatible energy ranges with sufficient
|
||||
% overlap (at least one common point).
|
||||
%
|
||||
% SEE ALSO
|
||||
% --------
|
||||
% interp1, nappPlot, nappBackground, mean, std, outerjoinRowToTable
|
||||
|
||||
|
||||
|
||||
expectedTableVariable = {'nexafsSpectrum','spectrum_counts','spectrum_countsPerSecond',...
|
||||
|
||||
Binary file not shown.
+148
-21
@@ -1,31 +1,145 @@
|
||||
function DataTable = nappCopyShift(DataTable,varargin)
|
||||
%nappBindingEnergyXps calculates the binding energy scale for spectra based
|
||||
%on the binding energy shift.
|
||||
%NAPPCOPYSHIFT Copy energy shift from one XPS region to spectra of the same sequence but other regions.
|
||||
% This function transfers energy shift calibration data (kinetic or binding
|
||||
% energy) from a reference region to spectra of the same sequence iteration in a different
|
||||
% region. It matches spectra based on filename and acquisition timestamp,
|
||||
% enabling consistent energy axis calibration across XPS
|
||||
% measurements of the same sequence (e.g., copying O1s shift to C1s spectra acquired simultaneously).
|
||||
%
|
||||
% For each spectrum with a given file number, the function copies the shift from data of a specified
|
||||
% region to another region of choice.
|
||||
% This approach ensures that energy calibrations determined from a
|
||||
% reference region (typically C1s or O1s) are consistently applied to
|
||||
% other regions in the same sequence. Works with both spectral data in
|
||||
% binding and in kinetic energy scale and with images - that is can be
|
||||
% used to align all sweeps in one image. Multiple destination rows can
|
||||
% receive the same shift value if acquired simultaneously (one-to-many
|
||||
% copying).
|
||||
%
|
||||
% *Requirement*
|
||||
% Needs table variable bindingEnergyShift as input. Run
|
||||
% nappDetermineShiftXps.m first on selected region.
|
||||
% SYNTAX
|
||||
% ------
|
||||
% DataTable = NAPPCOPYSHIFT(DataTable)
|
||||
%
|
||||
% FileList = nappCopyShift(FileList,tmpDataSelection,'energyScale','binding');
|
||||
% DataTable = NAPPCOPYSHIFT(DataTable, tableSelection, 'Name', Value)
|
||||
%
|
||||
% *input*
|
||||
% FileList: data table
|
||||
% tableSelection (optional): logical array to filter data table
|
||||
% regionOld: O1s (default) or C1s - source of shift data
|
||||
% regionNew: C1s (default), N1s or O1s - shift data will be copied to this
|
||||
% region
|
||||
% energyScale: kinetic (default) or binding: process either the kinetic
|
||||
% (for images) or the binding energy shift data (for spectra)
|
||||
% EXAMPLES
|
||||
% --------
|
||||
% % Copy O1s kinetic energy shift to C1s spectra
|
||||
% DataTable = nappCopyShift(DataTable, ...
|
||||
% 'regionOld', 'O1s', ...
|
||||
% 'regionNew', 'C1s', ...
|
||||
% 'energyScale', 'kinetic');
|
||||
%
|
||||
% *output*
|
||||
% Table variable bindingEnergy_eV holding the binding energy for
|
||||
% the data.
|
||||
% % Copy binding energy shift from N1s to Cl2p on selected rows
|
||||
% selection = contains(DataTable.name, 'polymer_sample');
|
||||
% DataTable = nappCopyShift(DataTable, selection, ...
|
||||
% 'regionOld', 'N1s', ...
|
||||
% 'regionNew', 'Cl2p', ...
|
||||
% 'energyScale', 'binding');
|
||||
%
|
||||
% See also nappnappAlignImages.m nappBindingEnergyXps nappFitGaussXps.m
|
||||
% nappCopyShift.m nappDetermineShiftXps.m
|
||||
% % Copy C1s calibration (binding energy) to all matching O1s spectra
|
||||
% DataTable = nappCopyShift(DataTable, ...
|
||||
% 'regionOld', 'C1s', ...
|
||||
% 'regionNew', 'O1s');
|
||||
%
|
||||
% INPUT ARGUMENTS
|
||||
% ---------------
|
||||
% DataTable table
|
||||
% Data table containing XPS spectra with energy shift calibration data
|
||||
% and time stamps. Ideally the napp standard format, but must at least contain:
|
||||
% - name field: spectrum identifiers with region designation (e.g.,
|
||||
% 'sample_C1s', 'sample_O1s')
|
||||
% - lastModifiedDatenum field: acquisition timestamps (MATLAB datenum format)
|
||||
% - kineticEnergyShift or bindingEnergyShift field: calibration shift values
|
||||
% (created by nappDetermineShiftXps)
|
||||
%
|
||||
% NAME-VALUE PAIR ARGUMENTS (optional)
|
||||
% ------------------------------------
|
||||
% 'tableSelection' logical array (default: all rows)
|
||||
% Logical index to filter which rows in DataTable contain the source
|
||||
% shift data (regionOld spectra). Only spectra in this selection will
|
||||
% be processed as source regions. Their shifts will be copied to matching
|
||||
% spectra in regionNew (which may or may not be in tableSelection).
|
||||
% Example: contains(DataTable.name, 'C1s') to use only C1s as source
|
||||
%
|
||||
% 'regionOld' char vector (default: 'O1s')
|
||||
% Source region containing the energy shift calibration data.
|
||||
% Must be one of:
|
||||
% - 'O1s'
|
||||
% - 'C1s'
|
||||
% - 'N1s'
|
||||
%
|
||||
% 'regionNew' char vector (default: 'C1s')
|
||||
% Destination region to which shift data will be copied.
|
||||
% Must be one of:
|
||||
% - 'O1s'
|
||||
% - 'C1s'
|
||||
% - 'N1s'
|
||||
% - 'Cl2p'
|
||||
%
|
||||
% 'energyScale' char vector (default: 'kinetic')
|
||||
% Energy scale type for shift calibration:
|
||||
% - 'kinetic': copies kineticEnergyShift column (used for image analysis)
|
||||
% - 'binding': copies bindingEnergyShift column (used for spectral analysis)
|
||||
%
|
||||
% OUTPUT ARGUMENTS
|
||||
% ----------------
|
||||
% DataTable table
|
||||
% Updated data table with energy shift values copied to destination region
|
||||
% spectra. The appropriate column is populated:
|
||||
% - kineticEnergyShift (if energyScale = 'kinetic')
|
||||
% - bindingEnergyShift (if energyScale = 'binding')
|
||||
%
|
||||
% Shift values are matched and copied for all spectra in the destination
|
||||
% region (regionNew) that share the same acquisition timestamp as spectra
|
||||
% in the source region (regionOld, filtered by tableSelection).
|
||||
%
|
||||
% MATCHING ALGORITHM
|
||||
% ------------------
|
||||
% The function matches source spectra (regionOld) to destination spectra
|
||||
% (regionNew) using:
|
||||
% 1. Filename: region name is replaced (O1s → C1s, etc.)
|
||||
% 2. Acquisition timestamp: year, month, day, hour, and minute must all match
|
||||
%
|
||||
% This ensures that shift calibrations from simultaneously acquired reference
|
||||
% regions are correctly applied to their complementary spectra. An error is
|
||||
% displayed if a matching spectrum cannot be found.
|
||||
%
|
||||
% NOTES
|
||||
% -----
|
||||
% - PREREQUISITE: Run nappDetermineShiftXps on the source region (regionOld)
|
||||
% BEFORE running this function. This populates the shift column in DataTable.
|
||||
% - Timestamp matching is strict: year, month, day, hour, and minute must all
|
||||
% match exactly. Second-level precision is not used.
|
||||
% - If regionOld and regionNew are the same, no copy operation is performed.
|
||||
% - Timestamps with mismatches indicate possible data organization issues and
|
||||
% trigger a diagnostic message.
|
||||
% - The function operates on selected rows only when tableSelection is provided.
|
||||
% Rows outside the selection are not processed as source regions.
|
||||
%
|
||||
% WORKFLOW EXAMPLE
|
||||
% ----------------
|
||||
% % Typical usage sequence for multi-region XPS dataset:
|
||||
% % 1. Determine shift for reference region (C1s)
|
||||
% DataTable = nappDetermineShiftXps(DataTable, ...
|
||||
% contains(DataTable.name, 'C1s'), ...
|
||||
% 'energyScale', 'binding');
|
||||
%
|
||||
% % 2. Copy C1s shift to complementary regions
|
||||
% DataTable = nappCopyShift(DataTable, ...
|
||||
% contains(DataTable.name, 'C1s'), ...
|
||||
% 'regionOld', 'C1s', ...
|
||||
% 'regionNew', 'O1s', ...
|
||||
% 'energyScale', 'binding');
|
||||
%
|
||||
% DataTable = nappCopyShift(DataTable, ...
|
||||
% contains(DataTable.name, 'C1s'), ...
|
||||
% 'regionOld', 'C1s', ...
|
||||
% 'regionNew', 'N1s', ...
|
||||
% 'energyScale', 'binding');
|
||||
%
|
||||
% SEE ALSO
|
||||
% --------
|
||||
% nappDetermineShiftXps, nappBindingEnergyXps, nappAlignImages,
|
||||
% nappFitGaussXps, datenum
|
||||
|
||||
% Define conditions and defaults of input
|
||||
% Old region must be also selected in tableSelection! it is kind like
|
||||
@@ -51,6 +165,19 @@ addParameter(p,'energyScale',defaultEnergyScale,...
|
||||
@(x) any(validatestring(x,expectedEnergyScale)));
|
||||
parse(p,DataTable,varargin{:});
|
||||
|
||||
|
||||
|
||||
% The function operates as follows:
|
||||
% 1. For each source spectrum/image (regionOld) in tableSelection:
|
||||
% - Extract the energy shift value (kinetic or binding scale)
|
||||
% - Extract the acquisition timestamp
|
||||
% 2. Generate search criteria by replacing the region name in the source
|
||||
% filename (e.g., "sample_O1s" becomes "sample_C1s")
|
||||
% 3. Search entire DataTable for destination spectra/images (regionNew) that:
|
||||
% - Have the transformed filename
|
||||
% - Match the acquisition timestamp exactly (year, month, day, hour, minute)
|
||||
% 4. Copy the source energy shift value to all matching destination rows
|
||||
|
||||
if contains(p.Results.energyScale,'kinetic')
|
||||
% repeat this for all columns in input.
|
||||
for ii = 1:size(p.Results.DataTable(p.Results.tableSelection,:),1)
|
||||
|
||||
@@ -1,44 +1,228 @@
|
||||
function DataTable = nappDetermineShiftXps(DataTable, varargin)
|
||||
%nappDetermineShiftXps determines the relative shift of each sequence
|
||||
%iteration in images or the absolute shift of spectra to a binding energy reference
|
||||
%NAPPDETERMINESHIFTXPS Determine energy shift calibration from XPS images or spectra.
|
||||
% This function calculates the energy shift needed to calibrate XPS
|
||||
% spectra to a binding energy reference or align all sequence iterations
|
||||
% of the same file to a common kinetic energy. For spectra data, it
|
||||
% computes absolute binding energy shifts relative to a reference binding
|
||||
% energy value. For images, it computes relative kinetic energy shifts
|
||||
% between sequence iterations. Shifts are determined by fitting Gaussian
|
||||
% peaks or finding maxima in the spectra (simpler option using Matlab's
|
||||
% findpeaks function).
|
||||
%
|
||||
% FileList = nappDetermineShiftXps(FileList,eKinStart,eKinEnd,'tableSelection',tmpDataSelection,...
|
||||
% 'showFigures','off','tableVariable','spectrum_countsPerSecond','binEnReference',535);
|
||||
%
|
||||
% FileList = nappDetermineShiftXps(FileList,'tableSelection',tmpDataSelection,...
|
||||
% 'showFigures','on','tableVariable','image');
|
||||
%
|
||||
% *input*
|
||||
% FileList: data table
|
||||
% eKinStart (optional): smallest value of energy range to use for
|
||||
% peak fitting. Peak fitting is used to get position of peak
|
||||
% eKinEnd (optional): largest value of energy energy range to use for
|
||||
% peak fitting. Peak fitting is used to get position of peak
|
||||
% tableSelection (optional): logical array to filter data table
|
||||
% tableVariable: choose to process either
|
||||
% 'spectrum_counts','spectrum_countsPerSecond' (default), => absolute binding energy shift will be determined or
|
||||
% ,'image','imageRoh'=> relative kinetic energy shift will be determined.
|
||||
% binEnReference: Reference BE in eV for spectra energy scale
|
||||
% kinEnReference: Sequence iteration to which the image should be
|
||||
% aligned, default is 1.
|
||||
% refPeak: Peak number the position of which will be used to compute the
|
||||
% BE shift. Only for Gauss fit. Default 1.
|
||||
% minPeakWidth: findpeak parameter, default 0.1
|
||||
% minPeakHeight: findpeak parameter, default 0.1
|
||||
% movMeanWindow: findpeak parameter, default 1
|
||||
% showFigures, on(default): show fit in figure, off do not show fit in figure
|
||||
% Needs X-ray energy in data table. Run addPhotonEnergy.m first.
|
||||
%
|
||||
%
|
||||
% *output*
|
||||
% new table variable kineticEnergyShift for images
|
||||
% new table variable bindingEnergyShift for spectra
|
||||
% SYNTAX
|
||||
% ------
|
||||
% DataTable = NAPPDETERMINESHIFTXPS(DataTable)
|
||||
%
|
||||
% DataTable = NAPPDETERMINESHIFTXPS(DataTable, eKinStart, eKinEnd, 'Name', Value)
|
||||
%
|
||||
% *ToDo*
|
||||
% November 2023: Use nappFitGaussXps.m function to find peak position
|
||||
% EXAMPLES
|
||||
% --------
|
||||
% % Determine binding energy shift for C1s spectra using peak finding
|
||||
% DataTable = nappDetermineShiftXps(DataTable, ...
|
||||
% 'tableVariable', 'spectrum_countsPerSecond', ...
|
||||
% 'binEnReference', 285.0, ...
|
||||
% 'mode', 'findPeak');
|
||||
%
|
||||
% See also nappnappAlignImages.m nappBindingEnergyXps nappFitGaussXps.m nappCopyShift.m
|
||||
|
||||
% % Determine kinetic energy shift for imaging data using the first
|
||||
% iteration as reference
|
||||
% DataTable = nappDetermineShiftXps(DataTable, 100, 200, ...
|
||||
% 'tableVariable', 'image', ...
|
||||
% 'kinEnReference', 1, ...
|
||||
% 'showFigures', 'on');
|
||||
%
|
||||
% % Determine binding energy shift using Gaussian fitting with custom
|
||||
% parameters specified in tmpFitParameters
|
||||
% FitPar.fitMode = 'position';
|
||||
% FitPar.refPeak = 1;
|
||||
% DataTable = nappDetermineShiftXps(DataTable, 280, 290, ...
|
||||
% 'tableVariable', 'spectrum_countsPerSecond', ...
|
||||
% 'binEnReference', 284.8, ...
|
||||
% 'mode', 'gaussFit', ...
|
||||
% 'FitParameter', tmpFitParameters);
|
||||
%
|
||||
% tmpFitParameters.peakArea = [1e5 0.5 0.1 0.1 0.1] ;
|
||||
% tmpFitParameters.peakWidth = 1.2;
|
||||
% tmpFitParameters.peakPos = [198 1.6 10 10 10];
|
||||
%
|
||||
% tmpFitParameters.peakAreaUpperBond = [Inf 0.5 0.1 0.1 0.1];
|
||||
% tmpFitParameters.peakWidthUpperBond = [3 NaN NaN NaN NaN];
|
||||
% tmpFitParameters.peakPosUpperBond = [200 1.6 10 10 10];
|
||||
%
|
||||
% tmpFitParameters.peakAreaLowerBond = [100 10 0.5 0.1 0.1 0.1];
|
||||
% tmpFitParameters.peakWidthLowerBond = [1.2 NaN NaN NaN NaN];
|
||||
% tmpFitParameters.peakPosLowerBxxond = [195 1.3 0.1 0.1 0.1];
|
||||
%
|
||||
% tmpFitParameters.backgroundRange = [6 5];
|
||||
% tmpFitParameters.weight = [198 200 0.1];
|
||||
% tmpFitParameters.fitMode = 'widthPosition';
|
||||
%
|
||||
% PROCESSING OVERVIEW
|
||||
% -------------------
|
||||
% The function operates differently depending on data type:
|
||||
%
|
||||
% FOR IMAGES (tableVariable = 'image' or 'imageRoh'):
|
||||
% 1. For each image in tableSelection:
|
||||
% - Extract kinetic energy axis (scientaEkin_eV or scientaEkinRoh_eV)
|
||||
% - Fit 2-peak Gaussian model to each sequence iteration (WIP: change
|
||||
% this to use nappFitGaussXPS.m)
|
||||
% - Extract peak position from fitting results
|
||||
% - Normalize shifts relative to reference iteration (kinEnReference)
|
||||
% 2. Result: kineticEnergyShift column contains shifts relative to reference iteration
|
||||
% (reference iteration has shift = 0)
|
||||
%
|
||||
% FOR SPECTRA (tableVariable = 'spectrum_counts', 'spectrum_countsPerSecond', or 'spectrum_countsNorm'):
|
||||
% 1. For each spectrum in tableSelection:
|
||||
% - Optional: restrict energy range using eKinStart/eKinEnd
|
||||
% - Find peak position using either:
|
||||
% * findPeak method: standard matlab peak detection
|
||||
% * gaussFit method: Gaussian fitting with global optimization
|
||||
% - Compute binding energy shift as: xRayPhotonEnergy - peakPosition - binEnReference
|
||||
% 2. Result: bindingEnergyShift column contains absolute shifts relative to reference BE
|
||||
% (positive shift means peak is at lower kinetic energy than expected)
|
||||
%
|
||||
% PEAK DETECTION METHODS
|
||||
% ----------------------
|
||||
% Two methods are available for finding peak positions in spectral
|
||||
%
|
||||
% 1. 'findPeak' (default): Fast automated detection using MATLAB's findpeaks
|
||||
% function with moving mean smoothing. Uses minPeakWidth, minPeakHeight,
|
||||
% and movMeanWindow parameters to control sensitivity. Best for well-defined
|
||||
% peaks with good signal-to-noise ratio. Accuracy: ±0.1-0.2 eV typical.
|
||||
%
|
||||
% 2. 'gaussFit': Slower but more accurate Gaussian fitting with global
|
||||
% optimization using GlobalSearch. Fits background, Gaussian peaks,
|
||||
% and extracts precise peak positions. Requires FitParameter structure.
|
||||
% Best for noisy data or when high precision is required. Accuracy: ±0.05 eV typical.
|
||||
%
|
||||
% IMPORTANT LIMITATION: This function requires distinct photoelectron peaks
|
||||
% to determine energy shifts. It will NOT work for background-only spectra
|
||||
% or featureless data. The fitting algorithms assume at least one measurable
|
||||
% peak is present in the specified energy range.
|
||||
%
|
||||
% INPUT ARGUMENTS
|
||||
% ---------------
|
||||
% DataTable table
|
||||
% Data table containing XPS image or spectral data. Must contain:
|
||||
% - scientaEkin_eV or scientaEkinRoh_eV: kinetic energy axis
|
||||
% - tableVariable data: images or spectra
|
||||
% - xRayEkin_eV: X-ray photon energy (eV) for each row
|
||||
%
|
||||
% eKinStart numeric scalar (optional)
|
||||
% Lower kinetic energy bound for peak fitting (eV). If omitted, uses
|
||||
% first energy point. Restricts the fitting region to improve accuracy.
|
||||
%
|
||||
% eKinEnd numeric scalar (optional)
|
||||
% Upper kinetic energy bound for peak fitting (eV). If omitted, uses
|
||||
% last energy point. Restricts the fitting region to improve accuracy.
|
||||
%
|
||||
% NAME-VALUE PAIR ARGUMENTS (optional)
|
||||
% ------------------------------------
|
||||
% 'tableSelection' logical array (default: all rows)
|
||||
% Logical index to filter which rows in DataTable to process.
|
||||
% Example: contains(DataTable.name, 'C1s') to process only C1s spectra
|
||||
%
|
||||
% 'tableVariable' char vector (default: 'spectrum_countsPerSecond')
|
||||
% Data type to process. Must be one of:
|
||||
%
|
||||
% Spectral data (compute binding energy shifts):
|
||||
% - 'spectrum_counts'
|
||||
% - 'spectrum_countsPerSecond'
|
||||
% - 'spectrum_countsNorm'
|
||||
%
|
||||
% Imaging data (compute kinetic energy shifts):
|
||||
% - 'image'
|
||||
% - 'imageRoh'
|
||||
%
|
||||
% 'mode' char vector (default: 'findPeak')
|
||||
% Peak detection method (spectral data only):
|
||||
% - 'findPeak': automated peak detection using moving mean smoothing
|
||||
% - 'gaussFit': 2-peak Gaussian fitting with global optimization
|
||||
%
|
||||
% 'binEnReference' numeric scalar (required for spectra)
|
||||
% Reference binding energy value (eV) for spectral calibration.
|
||||
% Typically the known BE of the primary peak (e.g., 285.0 eV for C1s C-H).
|
||||
% Example: 'binEnReference', 285.0
|
||||
%
|
||||
% 'kinEnReference' numeric scalar (default: 1)
|
||||
% Reference iteration index for imaging data. All kinetic energy shifts
|
||||
% are computed relative to this iteration. Reference iteration gets shift = 0.
|
||||
% Range: 1 to number of image columns.
|
||||
%
|
||||
% 'mode' char vector (default: 'findPeak')
|
||||
% Peak finding method for spectra:
|
||||
% - 'findPeak': uses findpeaks with smoothing and height/width constraints
|
||||
% - 'gaussFit': uses nappFitGaussXps with global optimization (slower, more accurate)
|
||||
%
|
||||
% 'minPeakWidth' numeric scalar (default: 0.1)
|
||||
% Minimum peak width (eV) for findPeak method. Peaks narrower than this
|
||||
% are rejected. Typical range: 0.05-0.5 eV depending on spectrometer resolution.
|
||||
%
|
||||
% 'minPeakHeight' numeric scalar (default: 0.1)
|
||||
% Minimum peak height (intensity) for findPeak method. Peaks below this
|
||||
% are rejected. Units match tableVariable data.
|
||||
%
|
||||
% 'movMeanWindow' numeric scalar (default: 1)
|
||||
% Moving mean window width (number of points) for smoothing before peak
|
||||
% detection in findPeak method. Reduces noise; typical range: 1-5 points.
|
||||
%
|
||||
% 'FitParameter' struct
|
||||
% Structure containing Gaussian fitting parameters for gaussFit mode.
|
||||
% Required fields:
|
||||
% - fitMode: 'position', 'width', 'unconstrained', etc.
|
||||
% - refPeak: peak number (1 or 2) whose position is used for shift calculation
|
||||
% Example: FitPar.fitMode = 'position'; FitPar.refPeak = 1;
|
||||
%
|
||||
% 'refPeak' numeric scalar (default: 1)
|
||||
% Peak number (1 or 2) whose position is used for binding energy shift
|
||||
% calculation in gaussFit mode. Peak 1 is typically the main photoelectron peak.
|
||||
%
|
||||
% 'showFigures' char vector (default: 'off')
|
||||
% Display fitting results:
|
||||
% - 'on': show Gaussian fit plot, peak table, and peak finding results
|
||||
% - 'off': suppress all figure output
|
||||
%
|
||||
% OUTPUT ARGUMENTS
|
||||
% ----------------
|
||||
% DataTable table
|
||||
% Updated data table with new columns:
|
||||
%
|
||||
% For imaging data (tableVariable = 'image' or 'imageRoh'):
|
||||
% - kineticEnergyShift: column vector of relative kinetic energy shifts (eV)
|
||||
% relative to kinEnReference iteration. Reference = 0.
|
||||
%
|
||||
% For spectral data (tableVariable = 'spectrum_*'):
|
||||
% - bindingEnergyShift: column vector of absolute binding energy shifts (eV)
|
||||
% relative to binEnReference. Typically small values (±0.5 eV range).
|
||||
%
|
||||
% For gaussFit mode on spectra, additional columns are added:
|
||||
% - peakPosition: [peak1, peak2] positions (eV) for each spectrum
|
||||
% - peakArea: [peak1, peak2] areas (eV·counts) for each spectrum
|
||||
% - peakFWHM: [peak1, peak2] full-width half-maximum (eV) for each spectrum
|
||||
% - peakBackground: linear background parameters [slope, intercept]
|
||||
%
|
||||
% NOTES
|
||||
% -----
|
||||
% - PREREQUISITE: X-ray photon energy (xRayEkin_eV) must be present in DataTable.
|
||||
% If empty, function returns with warning.
|
||||
% - For imaging: Gaussian fitting assumes 2 peaks in each iteration. Adjust
|
||||
% eKinStart/eKinEnd to isolate peak region if data is complex.
|
||||
% - For spectra: findPeak method is fast but less accurate (±0.1-0.2 eV typical).
|
||||
% gaussFit method is slower but more accurate (±0.05 eV typical).
|
||||
% - Peak detection may fail if signal-to-noise is poor. Check showFigures output
|
||||
% to diagnose fitting quality.
|
||||
% - For imageRoh variant: uses scientaEkinRoh_eV if available; falls back to
|
||||
% scientaEkin_eV if not populated.
|
||||
% - Binding energy shifts can be negative (peak at higher BE than reference) or
|
||||
% positive (peak at lower BE than reference).
|
||||
% - Figure windows are automatically closed after processing to prevent clutter.
|
||||
%
|
||||
% SEE ALSO
|
||||
% --------
|
||||
% nappCopyShift, nappBindingEnergyXps, nappFitGaussXps, nappAlignImages,
|
||||
% findpeaks, GaussFitOnePeak
|
||||
defaultKinEnReference = 1;
|
||||
defaultTableVariable = 'spectrum_countsPerSecond';
|
||||
expectedTableVariable = {'spectrum_counts','spectrum_countsPerSecond','spectrum_countsNorm','image','imageRoh'};
|
||||
|
||||
@@ -1,74 +1,250 @@
|
||||
function ListFiles = nappFileList(dataPath,varargin)
|
||||
% nappFileList lists all XAS, PE, and picture data of a specific beam
|
||||
% time. Analyser and sample settings such as pass energy, lens mode,
|
||||
% temperature, position, and pressure are added.
|
||||
%NAPPFILELIST Import spectroscopy data (XPS, NEXAFS) from a beam time folder into data table.
|
||||
% Photos, analyser and sample settings such as pass energy, lens mode, temperature,
|
||||
% position, and pressure are automatically extracted and added to the table.
|
||||
%
|
||||
% SYNTAX
|
||||
% ------
|
||||
% ListFiles = NAPPFILELIST(dataPath)
|
||||
% ListFiles = NAPPFILELIST(dataPath, DataTable)
|
||||
% ListFiles = NAPPFILELIST(dataPath, DataTable, 'Name', Value)
|
||||
%
|
||||
% * listFiles = nappFileList('2019\April_NanoXAS') imports data from beam
|
||||
% time folder on local computer, generates a new matlab table 'listFiles'
|
||||
% in the current workspace, and a csv file from data in the
|
||||
% 'SC_Data/2019/April_NanoXAS' .
|
||||
% DESCRIPTION
|
||||
% -----------
|
||||
% NAPPFILELIST scans a beam time folder and imports all experimental data
|
||||
% files (XPS, NEXAFS, and photos) with their associated
|
||||
% metadata into a MATLAB table. The function automatically:
|
||||
% - Reads XPS data and metadata from SES (.ibw) or Specs (.xy) files
|
||||
% - Reads NEXAFS data and metadata from HDF5 (.h5) files
|
||||
% - Splits multi-scan HDF5 files into individual single-scan files
|
||||
% - Extracts instrument settings (pass energy, dwell time, lens mode, etc.)
|
||||
% - Normalizes count rates (per dwell time) to counts per second (cps)
|
||||
% - Averages region iterations during import
|
||||
% - Creates a semicolon-separated CSV file for Excel import
|
||||
%
|
||||
% * listFiles = nappFileList('2019\April_NanoXAS',listFiles) imports data from beam
|
||||
% time folder on local computer, adds data to the existing matlab table
|
||||
% 'listFiles' in the current workspace, and a csv file from data in the
|
||||
% 'SC_Data/2019/April_NanoXAS' .
|
||||
% REQUIRED INPUT ARGUMENTS
|
||||
% ------------------------
|
||||
% dataPath
|
||||
% Beam time folder path (string or char vector).
|
||||
% Format: 'YYYY/BeamtimeName'(Mac,Linux,Unix) or 'YYYY\BeamtimeName' (Windows)
|
||||
% Examples: '2025/November_NappIss', '2024/March_PolLux'
|
||||
%
|
||||
% Input Arguments
|
||||
% Note: The folder structure must follow the strict naming convention
|
||||
% described in the "Folder Structure" section below.
|
||||
%
|
||||
% * dataPath, mandatory: year and name of folder that holds the beam time data.
|
||||
% Text string with format year/name of folder: '2019/April_NanoXAS'
|
||||
% * DataTable, optional: DataTable to which imported data is added.
|
||||
% * 'mode','local'; default: imports from local server address
|
||||
% * 'mode','nappDrive'; imports from napp drive. Needs to be mounted.
|
||||
% * 'mode','localNew'; imports only new files that have not yet been
|
||||
% imported. Needs existing data table as input.
|
||||
% * 'mode','nappDrivePick'; lets user select files in file browser window. Default address is Napp beam time folder.
|
||||
% * 'mode','localPick'; lets user select files in file browser window. Default address is local beam time folder.
|
||||
% OPTIONAL POSITIONAL INPUT
|
||||
% -------------------------
|
||||
% DataTable
|
||||
% Existing data table to append imported data to (table object).
|
||||
% If provided, new files are merged with existing table.
|
||||
% If not provided, a new table is created from scratch.
|
||||
%
|
||||
% Dependencies
|
||||
% NAME-VALUE PAIR ARGUMENTS
|
||||
% -------------------------
|
||||
% 'mode'
|
||||
% Import mode (char or string, default: 'local').
|
||||
% Supported values:
|
||||
% 'local' - Import from local computer (default)
|
||||
% 'nappDrive' - Import from mounted NAPP network drive
|
||||
% 'dataDrive' - Import from mounted group drive (5505)
|
||||
% 'localNew' - Import only new files not in existing DataTable
|
||||
% 'nappDrivePick' - Browse and select files from NAPP drive
|
||||
% 'localPick' - Browse and select files from local folder
|
||||
% 'dataPick' - Browse and select files from mounted group drive
|
||||
%
|
||||
% * beam time folder must be located at server/NAPP/SC Data/dataPath.
|
||||
% dataPath is user input. server needs to be defined at line ~100 of this
|
||||
% function.
|
||||
% * XPS data in igor *.ibw format need to be in SES subfolder
|
||||
% * Photos in *.bmp format need to be in Photos folder
|
||||
% * NEXAFS data in *.h5 format need to be in NEXAFS subfolder
|
||||
% * Labview pressure and temperature log need to be in Pressure subfolder.
|
||||
% * Uses the IgorPro importer for Matlab:
|
||||
% https://ch.mathworks.com/matlabcentral/fileexchange/42679-igor-pro-file-format-ibw-to-matlab-variable
|
||||
% * needs at least 1 .*ibw file in the SES subfolder
|
||||
% 'importLabView'
|
||||
% Import LabView pressure/temperature logs (char or string).
|
||||
% Default: 'on'
|
||||
% Supported values:
|
||||
% 'on' - Import LabView logs from Pressure subfolder
|
||||
% 'off' - Skip LabView log import (this is much,much faster)
|
||||
%
|
||||
% OUTPUT ARGUMENTS
|
||||
% ----------------
|
||||
% ListFiles
|
||||
% MATLAB table with the following columns (variables):
|
||||
% - name: file name (string)
|
||||
% - folder: full path to file (string)
|
||||
% - date: file modification date (datetime)
|
||||
% - bytes: file size in bytes (numeric)
|
||||
% - isdir: directory flag (logical)
|
||||
% - datenum: date as serial number (numeric)
|
||||
% - creationDate: acquisition timestamp (datevec format)
|
||||
% - image: 2D spectral map or image (cell array)
|
||||
% - imageRoh: raw 2D spectral map (cell array)
|
||||
% - spectrum_counts: integrated spectrum (numeric or cell array)
|
||||
% - spectrum_countsPerSecond: mean spectrum normalized to cps
|
||||
% - scientaEkin_eV: kinetic energy axis (cell array, eV)
|
||||
% - scientaEkinRange_eV: [min max] kinetic energy range
|
||||
% - scientaPassEnergy_eV: analyzer pass energy (numeric, eV)
|
||||
% - scientaDwellTime_ms: dwell time per channel (numeric, ms)
|
||||
% - regionName: region label (e.g., 'C1s', 'O K-edge NEXAFS')
|
||||
% - scientaAcquisitionMode: 'Swept' or 'Fixed' mode
|
||||
% - scientaLensMode: lens transmission mode (string)
|
||||
% - scientaRegionIterations: number of region scans (numeric)
|
||||
% - scientaSequenceIterations: number of sequence repeats (numeric)
|
||||
% - xRayEkin_eV: X-ray photon energy for XPS (numeric or cell array, eV)
|
||||
% - xRayEkinRange_eV: [min max] photon energy range
|
||||
% - beamlineInt: beamline intensity (I_0 for NEXAFS)
|
||||
% - importDate: timestamp of table generation (char)
|
||||
% - analysisDir: working directory at import time (string)
|
||||
%
|
||||
% Output
|
||||
% Also creates: YYYYMmm_DataList.csv
|
||||
% Semicolon-separated ASCII file in beam time folder for Excel import.
|
||||
%
|
||||
% * ListFiles: Matlab table listing XPS, NEXAFS, and photo files with settings
|
||||
% * YYYYmmm_DataList.csv (2019Apr_DataList.csv): Semicolon separated ASCII
|
||||
% file for import to Excel in beamtime folder
|
||||
% FOLDER STRUCTURE & NAMING CONVENTIONS
|
||||
% =====================================
|
||||
%
|
||||
% REQUIRED DIRECTORY STRUCTURE
|
||||
% ----------------------------
|
||||
% The beam time folder must contain the following sub-directories:
|
||||
%
|
||||
% Further info
|
||||
% SES/ - XPS data in Igor (.ibw) or Specs (.xy) format
|
||||
% NEXAFS/ - NEXAFS maps in HDF5 (.h5) format
|
||||
% Photos/ - Sample photographs in BMP (.bmp) format
|
||||
% Pressure/ - LabView pressure and temperature logs
|
||||
%
|
||||
% * Do not run while SES or NEXAFS data are being recorded. Data will be
|
||||
% lost by SES software.
|
||||
% * Region iterations are averaged during import
|
||||
% * counts are normalised to 1s dwell time during import. That is, the
|
||||
% counts are in cps after import.
|
||||
% Full path convention:
|
||||
% LOCAL: ~/Forschung_Einsam/PSI_SLS/NAPP/SC Data/YYYY/BeamtimeName
|
||||
% NAPP DRIVE: /Volumes/NAPP/SC Data/YYYY/BeamtimeName (Mac)
|
||||
% \\fs03\NAPP\SC Data\YYYY\BeamtimeName (Windows)
|
||||
% DATA DRIVE: /Volumes/5505/Data/YYYY/BeamtimeName (Mac)
|
||||
% \\fs101\5505\Data\YYYY\BeamtimeName (Windows)
|
||||
%
|
||||
% EXAMPLE FOLDER LAYOUT
|
||||
% ---------------------
|
||||
% 2025/November_NappIss/
|
||||
% SES/ [XPS data]
|
||||
% 0001_C1s_525eV.ibw
|
||||
% 0002_O1s_850eV.ibw
|
||||
% 0003_Survey_850eV.ibw
|
||||
% ...
|
||||
% NEXAFS/ [NEXAFS maps]
|
||||
% 0010_O_Kedge.h5
|
||||
% 0011_N_Kedge.h5
|
||||
% ...
|
||||
% Photos/ [Sample photos]
|
||||
% A0001-20251123_102407.bmp
|
||||
% A0002-20251123_102408.bmp
|
||||
% ...
|
||||
% Pressure/ [Environmental logs]
|
||||
% LabView_T_RH_20251119.txt
|
||||
% logfile-23-11-2025-12h46min.txt
|
||||
%
|
||||
% Matlab Version
|
||||
% FILE NAMING CONVENTIONS
|
||||
% -----------------------
|
||||
%
|
||||
% * Matlab 2018a or higher
|
||||
% XPS FILES (.ibw, .xy)
|
||||
% Format: NNNN_RegionName_PhotonEnergy.ext
|
||||
% Example: 0191_C1s_525eV.ibw
|
||||
% 0192_O1s_850eV.ibw
|
||||
% 0045_Survey_1000eV.ibw
|
||||
%
|
||||
% NNNN = Four-digit SES file number (from instrument)
|
||||
% RegionName = XPS region: C1s, O1s, N1s, Si2p, Cl2p, Survey, etc.
|
||||
% PhotonEnergy = X-ray photon energy in eV
|
||||
% .ibw = Igor file format (Scienta SES analyzer)
|
||||
% .xy = Specs SpecsLab file format
|
||||
%
|
||||
% See also TABLE IBWread h5read DIR LabView_importData
|
||||
% NEXAFS FILES (.h5)
|
||||
% Format: NNNN_ElementName_EdgeType.h5
|
||||
% Example: 0200_O_Kedge.h5
|
||||
% 0201_N_Kedge.h5
|
||||
% 0202_C_Kedge.h5
|
||||
%
|
||||
%%
|
||||
% NNNN = Four-digit file number
|
||||
% ElementName = Element symbol: O, N, C, etc.
|
||||
% EdgeType = K-edge, L-edge, etc.
|
||||
%
|
||||
% TODO
|
||||
% Note: Files starting with "N" are recognized. Files starting with
|
||||
% other characters (e.g., from old naming schemes) will be ignored.
|
||||
%
|
||||
% * FIXME: Add videos and jpg
|
||||
% PHOTO FILES (.bmp)
|
||||
% Format: descriptive_name.bmp
|
||||
% Example: sample_overview.bmp
|
||||
% before_dosing.bmp
|
||||
% after_annealing.bmp
|
||||
%
|
||||
% DATA FILE REQUIREMENTS & LIMITATIONS
|
||||
% ====================================
|
||||
%
|
||||
% - At least ONE .ibw or .xy file must exist in SES/ subfolder
|
||||
% - Do NOT run while SES or NEXAFS data are being actively recorded
|
||||
% - Multi-scan HDF5 files are automatically split (one scan per file)
|
||||
% - Region iterations are averaged during import (not preserved individually)
|
||||
% - Counts are normalized to 1 second dwell time (results in cps)
|
||||
% - System files starting with '.' or '~' are automatically excluded
|
||||
%
|
||||
% HDF5 MULTI-SCAN HANDLING
|
||||
% -------------------------
|
||||
% If an HDF5 file contains multiple scans (>3 groups detected):
|
||||
% 1. Function calls splitH5Scans(filename)
|
||||
% 2. Each scan is extracted into a separate file
|
||||
% 3. New files: original_name_scan_1.h5, original_name_scan_2.h5, etc.
|
||||
% 4. Original multi-scan file is deleted after splitting
|
||||
%
|
||||
% EXAMPLES
|
||||
% ========
|
||||
%
|
||||
% % Example 1: Import all data from local folder
|
||||
% FileList = nappFileList('2025/November_NappIss', 'mode', 'local');
|
||||
%
|
||||
% % Example 2: Add new data to existing table
|
||||
% FileList = nappFileList('2025/November_NappIss', FileList, 'mode', 'local');
|
||||
%
|
||||
% % Example 3: Import only new files not yet in table
|
||||
% FileList = nappFileList('2025/November_NappIss', FileList, ...
|
||||
% 'mode', 'localNew');
|
||||
%
|
||||
% % Example 4: Import from network drive with file browser
|
||||
% FileList = nappFileList('2025/November_NappIss', ...
|
||||
% 'mode', 'nappDrivePick');
|
||||
%
|
||||
% % Example 5: Skip LabView pressure/temperature logs
|
||||
% FileList = nappFileList('2025/November_NappIss', ...
|
||||
% 'mode', 'local', 'importLabView', 'off');
|
||||
%
|
||||
% DEPENDENCIES
|
||||
% ============
|
||||
% - IBWread function (Igor Pro format reader for MATLAB)
|
||||
% https://ch.mathworks.com/matlabcentral/fileexchange/42679-igor-pro-file-format-ibw-to-matlab-variable
|
||||
% - h5info, h5read (HDF5 file support, built-in MATLAB)
|
||||
% - splitH5Scans function (custom, included in toolkit)
|
||||
% - LabView_importData function (custom, included in toolkit)
|
||||
%
|
||||
% TROUBLESHOOTING
|
||||
% =======================
|
||||
%
|
||||
% - If "path wrong" warning appears: check folder spelling and that
|
||||
% network drives are mounted
|
||||
% - If Igor files fail to read: verify files are complete and not corrupted
|
||||
% (partially recorded files should be renamed with "ignore_" prefix)
|
||||
% - For older data (pre-2020): HDF5 file structure may differ; function
|
||||
% attempts multiple path conventions automatically
|
||||
% - Mac: Creation date for NEXAFS files obtained via 'stat' command
|
||||
% - Windows: Creation date for NEXAFS files set to NaN
|
||||
%
|
||||
% MATLAB VERSION REQUIREMENTS
|
||||
% ===========================
|
||||
% - MATLAB 2018a or higher (for '**' notation in dir patterns)
|
||||
%
|
||||
% HISTORY & UPDATES
|
||||
% =================
|
||||
% - January 2020: Added new h5 file structure and naming convention
|
||||
% - March 2021: Added local file structure support (not just network)
|
||||
% - March 2021: Added Lens Mode column support
|
||||
% - April 2021: X-ray kinetic energy and images now made unique
|
||||
% - March 2022: Refactored to use varargin instead of positional arguments
|
||||
% - March 2022: Strict data structure required for local and remote sources
|
||||
% - November 2025: Added support for PShell h5 file structure (NEXAFS)
|
||||
% - November 2025: Added creation date extraction for Mac (NEXAFS)
|
||||
%
|
||||
% See also: TABLE, IBWread, h5read, h5info, DIR, inputParser
|
||||
%
|
||||
% Copyright: Laboratory of Atmospheric Chemistry, Paul Scherrer Institut (PSI)
|
||||
% thorsten.bartels-rausch@psi.ch
|
||||
%
|
||||
% =========================================================================
|
||||
%% Updated
|
||||
%
|
||||
% * January 2020, added new h5 file structure and naming convention.
|
||||
@@ -78,8 +254,12 @@ function ListFiles = nappFileList(dataPath,varargin)
|
||||
% * April 2021, X-ray kinetic energy and images are now made unique
|
||||
% * March 2022, input now using varargin
|
||||
% * March 2022, strict data structure required for local and remote sources
|
||||
% * November 2025, PShell h5 files for NEXAFS have a new structure; added
|
||||
% creation date to mac for NEXAFS.
|
||||
% * November 2025, PShell h5 files for NEXAFS have a new structure;
|
||||
% % November 2025, added creation date to mac for NEXAFS.
|
||||
%% ToDo
|
||||
%
|
||||
% * Check if jpg are imported. Before Nov25 standard format was bitmap
|
||||
% * replace the hard coded table consistency with function.
|
||||
|
||||
%% Input
|
||||
% Define conditions and defaults of input
|
||||
@@ -153,9 +333,7 @@ end
|
||||
% * Variable: mixed case words starting with lower case: credibleThreat, qualityOfLife
|
||||
% * Variables with a large scope should have meaningful names. Variables
|
||||
% with a small scope can have short names.
|
||||
% * A convention on pluralisation should be followed consistently.
|
||||
% * Named constants (including globals) should be all uppercase using
|
||||
% underscore to separate words. MAX_ITERATIONS, COLOR_RED
|
||||
% * A convention on pluralization should be followed consistently.
|
||||
% * Structure names should begin with a capital letter: SegmentData.length
|
||||
% * The prefix n should be used for variables representing the number of
|
||||
% objects. A MATLAB-specific addition is the use of m for number of rows
|
||||
@@ -164,9 +342,6 @@ end
|
||||
% 1:nPositions, ii, ij, ik....
|
||||
% * Functions should have meaningful names written in lower case.
|
||||
% computetotalwidth(), Avoid compwid();
|
||||
%
|
||||
|
||||
|
||||
|
||||
%% Query beam time folder content
|
||||
%
|
||||
@@ -245,7 +420,7 @@ else
|
||||
|
||||
% The second line of code filters all files that start with Numbers or
|
||||
% letters. All system files starting with a . or ~ are discarded.
|
||||
% =========================================================================
|
||||
% =========================================================================
|
||||
% SPLIT HDF5 FILES WITH MULTIPLE DATASETS INTO INDIVIDUAL FILES
|
||||
% =========================================================================
|
||||
%
|
||||
@@ -272,7 +447,6 @@ else
|
||||
% Example: 0002_..._O_Kedge.h5 0002_..._O_Kedge_scan_1.h5
|
||||
% 0002_..._O_Kedge_scan_2.h5
|
||||
% =========================================================================
|
||||
|
||||
% Loop through each file in the NEXAFS file list
|
||||
% TmpFileList{2} contains the full paths to all NEXAFS HDF5 files
|
||||
% ii is the loop counter (1, 2, 3, ... up to the total number of files)
|
||||
@@ -715,7 +715,7 @@ for ii = 1:size(DataTable(p.Results.tableSelection,:),1)
|
||||
Gauss = @(energyValues, A, Pos, Wdt) A./(Wdt.*sqrt(pi/2))*exp(-2.*((energyValues - Pos).^2/Wdt.^2));
|
||||
linear = @(energyValues,slp,intrcpt) slp*energyValues+intrcpt;
|
||||
figure( 'Name', DataTable(p.Results.tableSelection,:).name{ii})
|
||||
tiledlayout(3,1)
|
||||
t = tiledlayout(3,1);
|
||||
|
||||
ax(1) = nexttile(2,[2,1]);
|
||||
% define high-resolution energyValues for plotting
|
||||
@@ -786,8 +786,17 @@ ax(2) = nexttile(1,[1,1]);
|
||||
residuals = fitIntensityValues - (yData_pk1+yData_pk2+yData_pk3+yData_pk4+yData_pk5+bkgrd); % Calculate residuals
|
||||
plot(fitEnergyValues, residuals, 'b.');
|
||||
ylabel('Residuals (Data - Fit)');
|
||||
title('Residuals Plot');
|
||||
% title('Residuals Plot');
|
||||
grid on;
|
||||
|
||||
if fitEnergyValues(1)<= fitEnergyValues(end)
|
||||
% xlabel('Kinetic Energy [eV]');
|
||||
else
|
||||
set(ax(2),'Xdir','reverse');
|
||||
% xlabel('Binding Energy [eV]');
|
||||
end
|
||||
|
||||
title(t,DataTable(p.Results.tableSelection,:).name{ii}, 'Interpreter', 'none');
|
||||
end
|
||||
|
||||
catch
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
function DataTable = nappFitGaussXps(DataTable,varargin)
|
||||
% nappFitGaussXps fits photoelectron (PE) spectra with up to 4 or 5 Gaussian peaks.
|
||||
function DataTable = nappFitGaussXpsDevelopment(DataTable,varargin)
|
||||
% nappFitGaussXpsDevelopment Playground to add Shirley background :-).
|
||||
% It allows different sets of constraints for the fitting process.
|
||||
%
|
||||
% INPUT:
|
||||
|
||||
@@ -1,19 +1,106 @@
|
||||
function DataTable = nappGenerateSpectra(DataTable,varargin)
|
||||
%nappGenerateSpectra reduces the dimension of images to generate spectra
|
||||
%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).
|
||||
%
|
||||
% nappGenerateSpectra(FileList,tmpDataSelection)
|
||||
% 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.
|
||||
%
|
||||
% *input*
|
||||
% FileList: data table
|
||||
% tableSelection (optional): logical array to filter data table
|
||||
% tableVariable (optional): select source: image(default),'imageRoh'
|
||||
% mode: mean (default) averages the sequence iterations; sum adds them
|
||||
% DataTable = NAPPGENERATESPECTRA(DataTable, tableSelection, Name, Value)
|
||||
% additionally customizes the source variable, reduction mode, and energy
|
||||
% or iteration ranges via Name-Value arguments.
|
||||
%
|
||||
% *output*
|
||||
% with mode mean the spectrum will be saved in the table variable spectrum_countsPerSecond
|
||||
% with mode sum the spectrum will be saved in the table variable spectrum_counts
|
||||
% 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
|
||||
%
|
||||
% FIXME: spectrum_counts is not implemented yet.
|
||||
% 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';
|
||||
|
||||
+113
-67
@@ -1,84 +1,130 @@
|
||||
function hdl = nappPlot(DataTable,varargin)
|
||||
%nappPlot Plot photoelectron spectra and NEXAFS images with flexible visualization options
|
||||
%NAPPLOT Plot photoelectron spectra and NEXAFS images from a data table.
|
||||
% hdl = NAPPLOT(DataTable) creates figures for all rows in DataTable
|
||||
% using the default visualization options and returns the handle(s) to
|
||||
% the generated figure(s).
|
||||
%
|
||||
% hdl = nappPlot(DataTable)
|
||||
% hdl = nappPlot(DataTable, tableSelection)
|
||||
% hdl = nappPlot(DataTable, tableSelection, Name, Value)
|
||||
% hdl = NAPPLOT(DataTable, tableSelection) restricts plotting to rows for
|
||||
% which tableSelection is true. The length of tableSelection must
|
||||
% match the height of DataTable.
|
||||
%
|
||||
% nappPlot is a one-and-only function for visualizing photoelectron spectroscopy
|
||||
% data including XPS spectra, NEXAFS images, and Auger-Meitner electron yield.
|
||||
% hdl = NAPPLOT(DataTable, tableSelection, Name, Value) additionally
|
||||
% customizes the data source, energy axis, layout mode, and figure
|
||||
% formatting using Name-Value arguments.
|
||||
%
|
||||
% INPUTS:
|
||||
% DataTable - Table containing spectroscopy data with variables for spectra,
|
||||
% images, energy scales, and metadata
|
||||
% NAPPLOT is a general-purpose visualization routine for spectroscopy
|
||||
% experiments that can display:
|
||||
% - NEXAFS images (h5)
|
||||
% - time-resolved XPS/Auger maps (ibw)
|
||||
% - 1D spectra from previously generated table variables
|
||||
% - interactive NEXAFS + Auger-Meitner views
|
||||
%
|
||||
% tableSelection - (Optional) Logical array to filter rows of DataTable
|
||||
% Default: all rows (true(size(DataTable,1),1))
|
||||
% Required input
|
||||
% --------------
|
||||
% DataTable
|
||||
% Table that contains spectroscopy data and metadata.
|
||||
% Depending on the chosen tableVariable and energyScale, the
|
||||
% following variables are typically used:
|
||||
% - name : file name (string/char), used to
|
||||
% distinguish '.h5', '.ibw', '.xy'
|
||||
% - image : processed 2D image (cell of numeric)
|
||||
% - imageRoh : raw 2D image (cell of numeric)
|
||||
% - spectrum_counts : 1D spectrum (in arbitrary counts
|
||||
% - spectrum_countsPerSecond
|
||||
% : 1D spectrum (normalized to counts per second)
|
||||
% - spectrum_countsNorm : 1D normalized spectrum
|
||||
% - scientaEkin_eV : kinetic energy axis (cell of numeric)
|
||||
% - bindingEnergy_eV : binding energy axis (cell of numeric)
|
||||
% - xRayEkin_eV : photon energy axis (cell of numeric)
|
||||
% - scientaEkinRange_eV : [emin emax] for plotting
|
||||
% - xRayEkinRange_eV : [emin emax] for plotting
|
||||
% - lastModifiedDatestr : acquisition or file time stamp
|
||||
% - sample : (optional) sample name for titles
|
||||
%
|
||||
% NAME-VALUE PAIR ARGUMENTS:
|
||||
% Optional positional input
|
||||
% -------------------------
|
||||
% tableSelection
|
||||
% Logical vector selecting rows of DataTable to plot.
|
||||
% Default: all rows true
|
||||
%
|
||||
% 'tableVariable' - Select data type to plot:
|
||||
% 'image' (default) - Processed 2D image data
|
||||
% 'imageRoh' - Raw 2D image data
|
||||
% 'spectrum_countsPerSecond' - Spectrum normalized to count rate
|
||||
% 'spectrum_counts' - Raw spectrum counts
|
||||
% 'spectrum_countsNorm' - Normalized spectrum (arbitrary units)
|
||||
% Name-Value arguments
|
||||
% --------------------
|
||||
% 'tableVariable'
|
||||
% Name of the variable in DataTable to plot.
|
||||
% Type : char or string
|
||||
% Values : 'image' (default)
|
||||
% 'imageRoh'
|
||||
% 'spectrum_countsPerSecond'
|
||||
% 'spectrum_counts'
|
||||
% 'spectrum_countsNorm'
|
||||
%
|
||||
% 'energyScale' - Choose energy axis for plotting:
|
||||
% 'kinetic' (default) - Kinetic energy scale (eV)
|
||||
% 'binding' - Binding energy scale (eV)
|
||||
% 'xRay' - Photon energy scale (eV, for NEXAFS)
|
||||
% 'sweeps' - Plot by sweep/column number (no energy scale)
|
||||
% 'energyScale'
|
||||
% Energy axis used for plotting
|
||||
% Type : char or string
|
||||
% Values : 'kinetic' (default) - use scientaEkin_eV
|
||||
% 'binding' - use bindingEnergy_eV
|
||||
% 'xRay' - use xRayEkin_eV
|
||||
% 'sweeps' - use column/iteration index
|
||||
%
|
||||
% 'mode' - Control plot layout and grouping:
|
||||
% 'AllInOne' (default) - All spectra overlaid in single figure;
|
||||
% images plotted separately
|
||||
% 'OneEach' - Each spectrum/image in separate figure
|
||||
% 'iterations' - Show iteration-by-iteration evolution for
|
||||
% time-series acquisitions
|
||||
% 'AugerMeitner' - Plot Auger-Meitner spectra at specified energies
|
||||
% 'interactive' - Interactive NEXAFS image browser with linked
|
||||
% Auger-Meitner and NEXAFS line plots
|
||||
% 'mode'
|
||||
% Layout and plotting mode
|
||||
% Type : char or string
|
||||
% Values : 'AllInOne' (default)
|
||||
% - Plot all selected 1D spectra in a single axes
|
||||
% (overlaid).
|
||||
% 'OneEach'
|
||||
% - One figure per single spectrum or image.
|
||||
% 'iterations'
|
||||
% - Plot multiple iterations from a 2D stack in different
|
||||
% colors to show time/sequence evolution.
|
||||
% 'AugerMeitner'
|
||||
% - Extract and plot Auger-Meitner spectra at specified
|
||||
% photon energies for NEXAFS maps ('.h5').
|
||||
% 'interactive'
|
||||
% - Interactive layout for NEXAFS images with linked
|
||||
% Auger-Meitner and NEXAFS line cuts controlled by
|
||||
% mouse / data cursor callbacks.
|
||||
%
|
||||
% 'figureMode' - Optimize figure formatting for output:
|
||||
% 'screen' (default) - Standard screen display (800×500 px)
|
||||
% 'powerpoint' - Presentation format (1280×720 px, larger fonts)
|
||||
% 'word' - Document format (8×10 cm, compact layout)
|
||||
% 'figureMode'
|
||||
% Overall figure formatting, size, and font presets.
|
||||
% Type : char or string
|
||||
% Values : 'screen' (default)
|
||||
% - Standard display window in pixels, moderate fonts.
|
||||
% 'powerpoint'
|
||||
% - Larger window and fonts optimized for slides.
|
||||
% 'word'
|
||||
% - Compact figure in centimeters for documents.
|
||||
%
|
||||
% 'plotStep' - (For 'iterations' mode) Plot every N-th iteration
|
||||
% Default: 1 (plot all iterations)
|
||||
% 'plotStep'
|
||||
% Step size in iteration index for 'iterations' mode.
|
||||
% Type : positive numeric scalar
|
||||
% Default: 1 (plot every iteration)
|
||||
%
|
||||
% 'AugerMeitnerEnergies' - (For 'AugerMeitner' mode) Numeric array of
|
||||
% photon energies (eV) at which to extract and
|
||||
% plot Auger-Meitner electron spectra
|
||||
% 'AugerMeitnerEnergies'
|
||||
% Photon energies (in eV) for 'AugerMeitner' mode
|
||||
% At each value, the function extracts one column from the image and
|
||||
% plots the corresponding Auger-Meitner electron spectrum.
|
||||
% Type : numeric vector
|
||||
%
|
||||
% OUTPUT:
|
||||
% hdl - Handle to generated figure(s)
|
||||
% Output
|
||||
% ------
|
||||
% hdl
|
||||
% Handle or array of handles to the generated figure(s)
|
||||
% For 'AllInOne' this is a single figure. For 'OneEach',
|
||||
% 'iterations', 'AugerMeitner', and 'interactive', hdl may contain
|
||||
% one handle per processed row.
|
||||
%
|
||||
% EXAMPLES:
|
||||
%
|
||||
% % Plot all spectra with binding energy scale
|
||||
% nappPlot(myDataTable, 'energyScale', 'binding')
|
||||
%
|
||||
% % Plot selected images only
|
||||
% selection = contains(myDataTable.name, 'C1s');
|
||||
% nappPlot(myDataTable, selection, 'tableVariable', 'image')
|
||||
%
|
||||
% % Interactive NEXAFS browser
|
||||
% nappPlot(myDataTable, 'mode', 'interactive')
|
||||
%
|
||||
% % Plot Auger-Meitner spectra at specific photon energies
|
||||
% nappPlot(myDataTable, 'mode', 'AugerMeitner', ...
|
||||
% 'AugerMeitnerEnergies', [280, 285, 290, 295])
|
||||
%
|
||||
% % Format for PowerPoint presentation
|
||||
% nappPlot(myDataTable, 'mode', 'AllInOne', 'figureMode', 'powerpoint')
|
||||
%
|
||||
% % Show every 5th iteration with normalized counts
|
||||
% nappPlot(myDataTable, 'mode', 'iterations', 'plotStep', 5, ...
|
||||
% 'tableVariable', 'spectrum_countsNorm')
|
||||
%
|
||||
% See also: image, plot, inputParser
|
||||
% Notes
|
||||
% -----
|
||||
% - The function checks that the chosen tableVariable is non-empty for
|
||||
% all selected rows and throws an error otherwise.
|
||||
% - File type is inferred from the 'name' variable to distinguish h5,
|
||||
% ibw, and xy-type data
|
||||
% - Axis labels, limits, and titles are adapted automatically based on
|
||||
% energyScale, tableVariable, and available metadata (sample name,
|
||||
% time stamp)
|
||||
% - In 'interactive' mode, datacursor and mouse motion callbacks update
|
||||
% linked line plots for Auger-Meitner and NEXAFS traces.
|
||||
%% TODO
|
||||
%
|
||||
% TODO: Add averaging in image and in iteration plot
|
||||
|
||||
+137
-17
@@ -1,26 +1,146 @@
|
||||
function DataTable = nappScale(DataTable,varargin)
|
||||
%nappScale can be used to normalise XPS spectra to the peak area. The peak
|
||||
%of the same region or of a different region with identical SES file
|
||||
%number can be used for XPS data. NEXAFS spectra can be normed to their
|
||||
%area or to the intensity at an energy range of choice.
|
||||
%NAPPSCALE Normalize XPS and NEXAFS spectra.
|
||||
% The peak of the same region or of a different region with identical
|
||||
% SES file number (same sequence iteration) can be used for XPS data.
|
||||
% NEXAFS spectra can be normed to their area or to the intensity
|
||||
% at an energy range of choice.
|
||||
%
|
||||
% FileList = nappScale(FileList,tmpDataSelection,'regionOld','C1s','regionNew','O1s');
|
||||
% For XPS ('.ibw') data, NAPPSCALE divides spectra of one region
|
||||
% (regionOld, default is C1s) by the fitted peak area taken from a
|
||||
% spectrum of the same sequence but different region (regionNew, default
|
||||
% is O1s). The same sequence iteration is identified by the SES file
|
||||
% number and acquisition time. For NEXAFS ('.h5') data, NAPPSCALE
|
||||
% normalizes spectra to the mean intensity or to the integrated area over
|
||||
% a chosen photon-energy interval.
|
||||
%
|
||||
% *input*
|
||||
% FileList: data table
|
||||
% tableSelection (optional): logical array to filter data table. These
|
||||
% spectra will be normalised.
|
||||
% regionOld: C1s (default) or O1s, N1s - region spectra that will be
|
||||
% normalised. Needs to be identical to the table selection (filter).
|
||||
% regionNew: O1s (default) or C1s, N1s - peak area that will be used to normalise
|
||||
% peakNumber: Number of the feature that should be used for fitting
|
||||
% (nappFitGaussXps gives results for 4 features, default is 1)
|
||||
% DataTable = NAPPSCALE(DataTable) normalizes spectra in the input table
|
||||
% using default options and returns the updated table with
|
||||
% normalized spectra in the variable spectrum_countsNorm.
|
||||
%
|
||||
% The region in tableSelection and regionOld MUST be identical.
|
||||
% DataTable = NAPPSCALE(DataTable, tableSelection) restricts
|
||||
% normalization to rows where tableSelection is true. The length
|
||||
% of tableSelection must match the height of DataTable.
|
||||
%
|
||||
% DataTable = NAPPSCALE(DataTable, tableSelection, energyStart, energyEnd)
|
||||
% additionally specifies an energy interval used to normalize NEXAFS
|
||||
% spectra ('.h5' data)
|
||||
%
|
||||
% *output*
|
||||
% table variable spectrum_countsNorm
|
||||
% DataTable = NAPPSCALE(..., Name, Value) customizes the source variable,
|
||||
% normalization mode, line region mapping, and peak selection via
|
||||
% Name-Value arguments (see below):
|
||||
%
|
||||
|
||||
%
|
||||
% Required input
|
||||
% --------------
|
||||
% DataTable
|
||||
% Table containing spectroscopy data and metadata.[web:2]
|
||||
% Depending on file type and options, the function uses:
|
||||
% - name : file name, used to distinguish 'ibw'
|
||||
% and 'h5' and to construct regionNew
|
||||
% file names (XPS)
|
||||
% - spectrum_counts : 1D spectrum (cell of numeric)
|
||||
% - spectrum_countsPerSecond
|
||||
% : 1D spectrum normalized to rate
|
||||
% - spectrum_countsNorm : (created/overwritten) normalized
|
||||
% spectrum
|
||||
% - peakArea : numeric vector of fitted peak areas
|
||||
% (XPS, one row per region)
|
||||
% - lastModifiedDatenum : datenum time stamp used to find the
|
||||
% matching regionNew spectrum
|
||||
% - xRayEkin_eV : photon energy axis (NEXAFS)
|
||||
%
|
||||
% Optional positional input
|
||||
% -------------------------
|
||||
% tableSelection
|
||||
% Logical vector selecting rows in DataTable to normalize.
|
||||
% Default: all rows true
|
||||
%
|
||||
% energyStart, energyEnd
|
||||
% Photon-energy limits (in eV) that define the normalization
|
||||
% interval for NEXAFS spectra ('.h5').
|
||||
% Type : numeric scalars
|
||||
% Use : required for 'intensity' or 'area' mode on '.h5' data.
|
||||
%
|
||||
% Name-Value arguments
|
||||
% --------------------
|
||||
% 'tableVariable'
|
||||
% Name of the spectral variable to be normalized.[web:10]
|
||||
% Type : char or string
|
||||
% Values : 'spectrum_countsPerSecond' (default)
|
||||
% 'spectrum_counts'
|
||||
% 'spectrum_countsNorm'
|
||||
%
|
||||
% 'regionOld'
|
||||
% XPS region name of the spectra to be normalized ('.ibw').
|
||||
% Used for file-name replacement when searching the reference
|
||||
% region
|
||||
% Type : char or string
|
||||
% Values : 'C1s' (default) | 'O1s' | 'N1s' | 'Cl2p'
|
||||
%
|
||||
% 'regionNew'
|
||||
% XPS region name that provides the reference peak area used for
|
||||
% normalization.
|
||||
% Type : char or string
|
||||
% Values : 'O1s' (default) | 'C1s' | 'N1s'
|
||||
%
|
||||
% 'peakNumber'
|
||||
% Index of the peak in the peakArea vector used as normalization
|
||||
% reference for XPS data.
|
||||
% Type : positive integer scalar
|
||||
% Default: 1
|
||||
%
|
||||
% 'mode'
|
||||
% Normalization mode.
|
||||
% Type : char or string
|
||||
% Values : 'area' (default)
|
||||
% 'intensity'
|
||||
%
|
||||
% Behaviour:
|
||||
% - For '.ibw' (XPS)
|
||||
% 'area' : divide selected spectra by the chosen peakArea
|
||||
% of the corresponding regionNew spectrum.
|
||||
% 'intensity' : currently not implemented (warning printed).
|
||||
% - For '.h5' (NEXAFS)
|
||||
% 'intensity' : divide spectra by the mean intensity over
|
||||
% [energyStart, energyEnd].
|
||||
% 'area' : divide spectra by the integrated area under
|
||||
% the curve over [energyStart, energyEnd]
|
||||
% (trapz).
|
||||
%
|
||||
% Output
|
||||
% ------
|
||||
% DataTable
|
||||
% Updated input table with normalized spectra and log variables.
|
||||
% The function ensures the following variables:
|
||||
%
|
||||
% spectrum_countsNorm
|
||||
% Cell array containing the normalized spectrum for each
|
||||
% processed row. Existing values are overwritten.
|
||||
%
|
||||
% logScaleRange
|
||||
% Numeric matrix with two columns. For '.h5' rows, stores the
|
||||
% [energyStart energyEnd] interval used for normalization.
|
||||
%
|
||||
% logScaleMode
|
||||
% Cell array of character vectors with the mode ('area' or
|
||||
% 'intensity') used for each normalized row.
|
||||
%
|
||||
% logScaleDate
|
||||
% Cell array of character vectors containing the time stamp of
|
||||
% the normalization (datestr(now)).
|
||||
%
|
||||
% Notes
|
||||
% -----
|
||||
% - All selected entries in the chosen tableVariable must contain
|
||||
% non-empty spectra; otherwise, the function throws an error.
|
||||
% - For XPS data, regionOld and the tableSelection filter must refer to
|
||||
% the same region; regionNew is found by name replacement and by
|
||||
% matching date and time to locate the correct reference spectrum.
|
||||
% - For NEXAFS data, the function supports both increasing and decreasing
|
||||
% photon-energy axes when locating the normalization interval.
|
||||
|
||||
|
||||
|
||||
% Define conditions and defaults of input
|
||||
defaultTableVariable = 'spectrum_countsPerSecond';
|
||||
|
||||
@@ -0,0 +1,505 @@
|
||||
# nappMATLAB toolbox 🧪📈
|
||||
|
||||
> One data table to rule them all:
|
||||
> XPS & NEXAFS analysis in MATLAB, with a bit of structure and a lot of spectra. 😎
|
||||
|
||||
This repo contains shared MATLAB tools and example scripts to analyse XPS
|
||||
and NEXAFS data from PSI beamlines using a **common table‑based data structure**.
|
||||
Everyone is encouraged to use it, break it (gently), fix it, and extend it. 😄🚀
|
||||
|
||||
***
|
||||
|
||||
## Table of contents
|
||||
|
||||
- [What this is](#what-this-is)
|
||||
- [Core ideas](#core-ideas)
|
||||
- [Prerequisites](#prerequisites)
|
||||
- [Installation](#installation)
|
||||
- [Add to the MATLAB path](#add-to-the-matlab-path)
|
||||
- [Data folders and naming](#data-folders-and-naming)
|
||||
- [The shared data table](#the-shared-data-table)
|
||||
- [MATLAB help & docs](#matlab-help--docs)
|
||||
- [Python / pandas side quests](#python--pandas-side-quests)
|
||||
- [Contributing](#contributing)
|
||||
- [License / usage](#license--usage)
|
||||
|
||||
***
|
||||
|
||||
## What this is
|
||||
|
||||
This toolbox provides XPS & NEXAFS functions to
|
||||
import, bookkeeping, spectra generation, background handling, peak fitting,
|
||||
plotting, and data export.
|
||||
|
||||
All nappMATLAB functions operate on a **single MATLAB table**,
|
||||
where each row is one data file (SES or PShell measurement) and columns
|
||||
store image data, spectra, meta‑data, fit results, etc.
|
||||
|
||||
***
|
||||
|
||||
## Core ideas
|
||||
|
||||
- **One table to rule them all**
|
||||
Data from various beamtimes and instruments get imported into the same type of MATLAB table.
|
||||
|
||||
- **Scripts call functions, functions operate on tables**
|
||||
Scripts are your personal playground for "what do I want to see today?",
|
||||
while shared napp* functions offer the tools for your analysis. 🧰
|
||||
|
||||
- **Input → script → output**
|
||||
To keep the overview, it is suggested to split your analysis topics into individual script files:
|
||||
Each of your scripts takes an existing table as input, applies a series of operations,
|
||||
and saves an updated table with the **same name as the script file**.
|
||||
|
||||
- **Raw data stays raw**
|
||||
Data columns (`image`, `spectrum_countsPerSecond`, etc.) are overwritten
|
||||
by processing, so that there is only one recent and up‑to‑date version.
|
||||
The advantage is that the processing function can be called in (almost)
|
||||
any order or sequence. But each has a corresponding `*_Roh` column to go
|
||||
back to the original state.
|
||||
|
||||
- **Collaborative by design**
|
||||
Everyone in the group is more than welcome to contribute new functions and
|
||||
examples so that the next beamtime is easier for everyone. 🤝
|
||||
|
||||
|
||||
## 🧭 Keep an Overview — FAIR and open research
|
||||
|
||||
### 💡 The Big Idea
|
||||
|
||||
Use **scripts** (or live scripts) that call **nappMATLAB** functions to process data step by step.
|
||||
Each script documents what was done, why it was done, and what the outcome looks like (including plots).
|
||||
This turns everyday analysis into a lightweight data‑management practice that
|
||||
supports open and FAIR research from day one. 🙂 It helps you quickly find and share data in typical situations:
|
||||
|
||||
- A team member might ask: Can you send me the figure from your last presentation so that I can edit it?
|
||||
- You might ask: Can I compare this NEXAFS spectrum to one from my first beamtime 2 years ago?
|
||||
- A referee for your publication might ask: Have you used all data, or were some discarded?
|
||||
|
||||
Concretely, concepts like the **ACTRIS data levels** (Level 0 raw, Level 1 calibrated, Level 2 processed, Level 3 publication‑ready)
|
||||
can be mirrored in how scripts and data tables are named and stored, and aligned with the [SNSF Open Research Data policy](https://www.snf.ch/en/dMILj9t4LNk8NwyR/topic/open-research-data)
|
||||
and the [ACTRIS Data Policy](https://data.actris.eu/data-policy).
|
||||
|
||||
---
|
||||
|
||||
### 📊 Data Levels
|
||||
|
||||
| Level | Description |
|
||||
|:------|:-------------|
|
||||
| **0 – Raw data** | Native resolution with acquisition metadata (instrumental, beamline, sample info). |
|
||||
| **1 – Calibrated** | Basic QC — excludes faulty or aborted spectra. |
|
||||
| **2 – Processed** | Fully QC-checked, calibrated, normalized, and outlier-filtered (for scientific, not technical, reasons). |
|
||||
| **3 – Final** | Publication-ready results for figures, tables, and discussions. 🎯 |
|
||||
|
||||
---
|
||||
|
||||
### 🧪 Processing Workflow
|
||||
|
||||
Beamtime data are processed in *two main phases*:
|
||||
|
||||
- **Levels 0–1:** during the beamtime 🕰️ — ensures data quality and guides ongoing experiments. Scripts live in the **beamtime folder** and are usually shared.
|
||||
- **Levels 2–3:** after the beamtime 🧠 — selects and combines results from multiple sources (e.g. lab experiments, simulations) and beamtimes.
|
||||
Scripts live in your **personal analysis folder** on the shared drive.
|
||||
|
||||
---
|
||||
|
||||
### ⚙️ Script Overview
|
||||
|
||||
#### `importData.m`
|
||||
- Level 1 data
|
||||
- Shared script in **beamtime folder**
|
||||
- Imports all data from one beamtime
|
||||
- Load data into MATLAB tables
|
||||
- Add X-ray energy and sample descriptions
|
||||
- Identify and document faulty data
|
||||
- Saves output as **FileList.mat** *(name has legacy reasons)* 🧓
|
||||
|
||||
#### `generateSpectra.m`
|
||||
- Level 1 data
|
||||
- Shared script in **beamtime folder**
|
||||
- Processes all spectra
|
||||
- Generate spectra (dimensional reduction)
|
||||
- Plot & QC XPS/NEXAFS spectra
|
||||
- Compare key edges/regions
|
||||
- Identify outliers
|
||||
- Calculate binding energies & peak widths
|
||||
- Saves output as **SpectrumList.mat** *(tradition beats convention, again!)* 😄
|
||||
|
||||
#### `specificScienceQuestion.m`
|
||||
- Level 2 or level 3 data
|
||||
- Your personal data-analysis script 👩🔬
|
||||
- Combines selected datasets to answer one question
|
||||
Examples:
|
||||
- `AnalysisStep3DepthProfiles.m`
|
||||
- `AnalysisStep4SurfaceConcentration.m`
|
||||
- `BeamTimeNov2025isItChlorineFits.m`
|
||||
- `GaussFitHClOnIce.m`
|
||||
- `FigureHexylamineN1sLjIce.m`
|
||||
- Saves output as a `.mat` file with the same name 🧾
|
||||
|
||||
---
|
||||
|
||||
### 🔁 Typical Processing Chain
|
||||
`````
|
||||
beamtime raw files
|
||||
↓
importData.m → FileList.mat
|
||||
↓
generateSpectra.m → SpectrumList.mat
|
||||
↓
AnalysisStep4SurfaceConcentration.m → AnalysisStep4SurfaceConcentration.mat
|
||||
↓
GaussFitHClOnIce.m → GaussFitHClOnIce.mat
|
||||
|
||||
SpectrumList.mat
|
||||
↓
FigureHexylamineN1sLjIce.m → FigureHexylamineN1sLjIce.mat
|
||||
``````
|
||||
|
||||
Reuse `.mat` outputs to skip re-running previous steps 🧠💤
|
||||
|
||||
***
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- MATLAB (reasonably recent; minimum R2018; R2025b+ recommended).
|
||||
|
||||
To get it, create a MathWorks account using your PSI email. Your PSI license will then automatically be assigned to your account (assuming you have an older version installed via the software kiosk), and you can go ahead and download the latest version from the MathWorks homepage, even if it is not yet available through the software kiosk.
|
||||
|
||||
- Access to the Napp data folders (Windows network share).
|
||||
- Git (if you want to clone and contribute instead of downloading zips).
|
||||
|
||||
Optional but handy:
|
||||
|
||||
- A Python environment if you want to poke at the tables with pandas later. 🐼
|
||||
|
||||
***
|
||||
|
||||
### 1. Get the code
|
||||
|
||||
**Option A – clone via git (recommended)**
|
||||
|
||||
WIP: No idea yet what it takes to set up gitea git on a PSI computer. Can one of the Windows users update this section here, so that the others know? 🙂
|
||||
|
||||
**Option B – download zip (for non‑git days)**
|
||||
|
||||
1. Open the repository in your browser.
|
||||
2. Click **Download ZIP**.
|
||||
3. Unzip to your favorite folder to store shared functions such as `D:\MATLAB\napp-matlab` or `/Users/you/Code/napp-matlab`.
|
||||
|
||||
***
|
||||
|
||||
### Add to the MATLAB path
|
||||
|
||||
You need the repository (and its subfolders) on the MATLAB path.
|
||||
|
||||
In MATLAB:
|
||||
|
||||
```matlab
|
||||
% Adapt this to where you cloned/unzipped the repo
|
||||
toolboxPath = 'C:\Users\you\Code\napp-matlab';
|
||||
addpath(genpath(toolboxPath));
|
||||
% Optionally make it persistent
|
||||
savepath;
|
||||
```
|
||||
|
||||
***
|
||||
|
||||
### Data folders and naming
|
||||
|
||||
The functions require a specific file organisation and folder naming for the beamtime data to locate and importe SES, NEXAFS, photo, and pressure data consistently across beamtimes. A single beamtime is organised in a top‑level "beamtime folder" that contains four data subfolders and no further nesting inside them:
|
||||
|
||||
```text
|
||||
202202_Feb_IssIceNapp/
|
||||
├─ SES/ # SES XPS/PE images in IgorPro .ibw or .xy files
|
||||
├─ NEXAFS/ # NEXAFS (XAS) data in .h5 files
|
||||
├─ Photos/ # Experimental photographs in .bmp format
|
||||
└─ Pressure/ # LabView pressure logs in ASCII .dat or .txt files
|
||||
```
|
||||
|
||||
Additional folders might be added to the beamtime folder to hold the scripts, reports, lab notes.
|
||||
You usually start by scanning such a folder into a table (see MATLAB example files):
|
||||
|
||||
```matlab
|
||||
FileList = nappFileList('2025/20251119_NappIss', ...
|
||||
'mode','local', ...
|
||||
'importLabView','off');
|
||||
save('FileList.mat',"FileList");
|
||||
```
|
||||
|
||||
- The first argument is a **relative path under your data root**.
|
||||
- `mode` selects where to look for data (local / network), i.e. it defines the data root.
|
||||
- The result is a MATLAB table (by convention often called `FileList` because it lists all the files acquired during a beamtime).
|
||||
|
||||
**Naming conventions**
|
||||
|
||||
- Folders: `YYYYMMDD_BeamlineName` (e.g. `20251119_NappIss`).
|
||||
- Scripts: descriptive names like `generateSpectra.m`, `PlottingForAnand.m`.
|
||||
- Output: typically script‑matching names, saved into `.mat` files.
|
||||
|
||||
***
|
||||
|
||||
## The shared data table
|
||||
|
||||
All nappMATLAB functions operate on a MATLAB table with one row per file and a set of standard variables (columns). Using the same column (variable) names across users and across software helps to share data and is a prerequisite for programming.
|
||||
|
||||
### Table Variables: Identification & meta
|
||||
|
||||
- `name`
|
||||
Filename and ID as given by the instrument software during acquisition. Typically includes run number, edge, and photon energy.
|
||||
|
||||
- `sample`
|
||||
Free‑text description of the sample or experiment. Often used to mark data quality, e.g. including `(bad data)` for files that should be excluded from analysis.
|
||||
|
||||
- `lastModifiedDatenum`
|
||||
Timestamp (numeric datenum) from the data file metadata indicating when the acquisition was finished.
|
||||
|
||||
- `lastModifiedDatestr`
|
||||
Human‑readable string version of the `lastModifiedDatenum`.
|
||||
|
||||
- `creationDate`
|
||||
File creation date as reported by the operating system (this logs when the measurement was started).
|
||||
|
||||
- `importDate`
|
||||
Date/time when the file was imported into the MATLAB table (can differ from acquisition/creation time, useful for tracking when data entered the workflow).
|
||||
|
||||
- `analysisDir`
|
||||
Path to the analysis directory where the current table and related scripts live.
|
||||
|
||||
***
|
||||
|
||||
### Table Variables: Raw and processed data
|
||||
|
||||
- `image`
|
||||
Primary result from SES software; multidimensional data (typically counts per second vs kinetic energy vs sequence iteration). This is the original measurement data.
|
||||
|
||||
- `imageRoh`
|
||||
Snapshot of `image` at import time. Remains unchanged so you can always go back to the original image regardless of later processing steps.
|
||||
|
||||
- `spectrum_countsPerSecond`
|
||||
Spectrum derived from `image` (counts per second vs energy), usually by averaging or summing over sequence iterations and normalising to 1 s.
|
||||
|
||||
- `spectrum_counts`
|
||||
Same as above but in raw counts (not normalised per second), depending on context and instrument output.
|
||||
|
||||
- `spectrumRoh_countsPerSecond`
|
||||
Snapshot of `spectrum_countsPerSecond` at generation time. Used to restore or compare against the original spectrum.
|
||||
|
||||
- `spectrumRoh_counts`
|
||||
Snapshot of `spectrum_counts` at generation time. Preserves the initial integrated spectrum even if later processing modifies the live columns.
|
||||
|
||||
***
|
||||
|
||||
### Table Variables: Analyzer and X‑ray settings
|
||||
|
||||
- `scientaEkin_eV`
|
||||
Array of kinetic energies (in eV) corresponding to the analyser energy axis for the spectrum or image.
|
||||
|
||||
- `scientaEkinRange_eV`
|
||||
Two‑element range of the kinetic energy window in a human‑readable form.
|
||||
|
||||
- `scientaPassEnergy_eV`
|
||||
Pass energy (in eV) used by the Scienta analyser; controls resolution vs line shapes.
|
||||
|
||||
- `scientaDwellTime_ms`
|
||||
Dwell time per channel/step (in ms); influences counting statistics and total acquisition time.
|
||||
|
||||
- `regionName`
|
||||
Name of the acquisition region as defined in the SES software (e.g. "C1s", "Survey", "O_Kedge_Resonant").
|
||||
|
||||
- `scientaAcquisitionMode`
|
||||
Acquisition mode selected in the analyser, sweep or fixed (snapshot).
|
||||
|
||||
- `beamlineInt`
|
||||
X‑ray flux, typically the output from a diode.
|
||||
|
||||
- `scientaLensMode`
|
||||
Lens mode of the analyser such as HiPPHAXPES.
|
||||
|
||||
- `scientaRegionIterations`
|
||||
Number of region iterations.
|
||||
|
||||
- `scientaSequenceIterations`
|
||||
Number of sequence iterations.
|
||||
|
||||
- `xRayEkin_eV`
|
||||
X‑ray photon energy (in eV); essential for converting to binding energy in XPS and for obvious reasons for NEXAFS. It is automatically recorded for NEXAFS and needs to be added manually for XPS.
|
||||
|
||||
- `xRayEkinRange_eV`
|
||||
Human‑readable X‑ray energy range in eV.
|
||||
|
||||
- *(SLITS – WIP)*
|
||||
Slit settings (horizontal/vertical or monochromator slits). Once implemented, these should store the X‑ray beamline slit openings used during acquisition.
|
||||
|
||||
***
|
||||
|
||||
### Table Variables: Sample settings
|
||||
|
||||
- `temperature_dC`
|
||||
Sample temperature during the measurement (units °C).
|
||||
|
||||
- `pressure_mbar`
|
||||
Pressure of the sample environment.
|
||||
|
||||
- `x-y-z position_mm`
|
||||
Sample position coordinates (stage x/y/z).
|
||||
|
||||
- `gas flows`
|
||||
Gas flow rates (e.g. in sccm) for reactants or carrier gases in the experimental cell.
|
||||
|
||||
***
|
||||
|
||||
### Table Variables: Processing outcome
|
||||
|
||||
These variables are typically created or updated by fitting/analysis functions.
|
||||
|
||||
- `peakPosition`
|
||||
Fitted peak position(s).
|
||||
|
||||
***
|
||||
|
||||
### Live vs Roh columns
|
||||
|
||||
- Columns without `Roh` (`image`, `spectrum_countsPerSecond`, …) are **live** and will be overwritten by processing functions.
|
||||
- Columns ending in `Roh` store the state at **import / generation** time and are never touched again by the common functions.
|
||||
|
||||
This allows:
|
||||
|
||||
- iterative processing during beamtime, and
|
||||
- going back to clean starting points without reimporting everything. 🔁
|
||||
|
||||
***
|
||||
|
||||
## MATLAB help & function call conventions
|
||||
|
||||
Most functions in this toolbox operate on the shared MATLAB data table and follow a few simple calling patterns.
|
||||
|
||||
***
|
||||
|
||||
### Basic in‑place call
|
||||
|
||||
Many functions take a table as input and return the **same** table with additional variables or modified content:
|
||||
|
||||
```matlab
|
||||
InputTable = nappFunctionAbc(InputTable);
|
||||
```
|
||||
|
||||
- `InputTable` is a MATLAB table containing your data.
|
||||
- The function reads from `InputTable`, writes its results into new or existing columns, and returns the updated table.
|
||||
- Plotting functions are an exception: they often **do not** modify the table and only create figures.
|
||||
|
||||
***
|
||||
|
||||
#### Copy‑on‑write call (not recommended)
|
||||
|
||||
If you want to keep the input table unchanged and work on a copy, use different variable names:
|
||||
|
||||
```matlab
|
||||
CopyOfTable = nappFunctionAbc(InputTable);
|
||||
```
|
||||
|
||||
- `InputTable` remains untouched.
|
||||
- `CopyOfTable` is a full copy of `InputTable` plus the additional results created by `nappFunctionAbc`.
|
||||
|
||||
***
|
||||
|
||||
#### Mandatory vs optional inputs
|
||||
|
||||
Function calls typically look like this:
|
||||
|
||||
```matlab
|
||||
OutputTable = nappFunctionAbc(InputTable, x, y, ...
|
||||
'tableSelection', tmpDataSelection, ...
|
||||
'tableVariable', 'TableVariableName', ...
|
||||
'energyScale', 'kinetic', ...
|
||||
'mode', 'mean', ...
|
||||
'showFigures', true);
|
||||
```
|
||||
|
||||
- **Mandatory inputs** (e.g. `InputTable`, `x`, `y`) come first and are positional.
|
||||
- **Optional inputs** are given as name–value pairs, just like in standard MATLAB functions.
|
||||
|
||||
Common options:
|
||||
|
||||
- `'tableSelection': tmpDataSelection`
|
||||
Logical array that selects the rows to operate on. Only rows where `tmpDataSelection` is `true` are processed.
|
||||
|
||||
- `'tableVariable': 'TableVariableName'`
|
||||
Name of the column in the table that the function should use as its primary data (e.g. `'image'`, `'spectrum_countsPerSecond'`).
|
||||
|
||||
- `'energyScale': 'kinetic'` (or `'binding'`, `'xRay'`, depending on the function)
|
||||
Specifies which energy scale to use for plotting or calculations.
|
||||
|
||||
- `'mode': 'mean'`
|
||||
Selects a specific processing mode, for example whether to compute a mean or sum over iterations, or which plotting style to use. The available modes depend on the function.
|
||||
|
||||
- `'showFigures': true` (or `false`)
|
||||
Controls whether figures and other graphical output are displayed.
|
||||
|
||||
Each function may define additional options; always check the help text for the full list.
|
||||
|
||||
***
|
||||
|
||||
### Getting help from within MATLAB
|
||||
|
||||
Each function should ship with a short header and usage examples. You can get a list of all functions and a short description by navigating to the function folder `beamtime` in MATLAB and running:
|
||||
|
||||
- `help beamtime`
|
||||
|
||||
You can access a more detailed description of each function via standard MATLAB commands:
|
||||
|
||||
- `help nappFunctionAbc`
|
||||
- `doc nappFunctionAbc`
|
||||
|
||||
The separate MATLAB documents **" WIP will be added soon "** give examples:
|
||||
|
||||
- concept and function call patterns,
|
||||
- data structure and table variables,
|
||||
- import workflows,
|
||||
- processing steps from raw data to publication plots. 📚
|
||||
|
||||
***
|
||||
|
||||
## Python / pandas side quests 🐍
|
||||
|
||||
If you or a future group member want to explore data in Python:
|
||||
|
||||
- The MATLAB table maps naturally to a `pandas.DataFrame`: one row per experiment, columns identical to MATLAB variable names.
|
||||
- Image and spectrum columns can be stored as arrays (NumPy) in "object" columns.
|
||||
- Keep the **same column naming scheme** (`image`, `imageRoh`, `spectrum_countsPerSecond`, …) and document any mapping if you deviate.
|
||||
|
||||
A simple workflow is:
|
||||
|
||||
1. Save the MATLAB table (`FileList`) as `.mat` or HDF5.
|
||||
2. Load it in Python and convert to a `DataFrame`, preserving column names.
|
||||
3. Use pandas for tabular manipulations and matplotlib for plotting and processing.
|
||||
|
||||
***
|
||||
|
||||
## Contributing
|
||||
|
||||
This is a **group toolbox**. Contributions are welcome. 🎯
|
||||
|
||||
Guidelines:
|
||||
|
||||
- Reuse the **shared table structure** and column naming (especially data vs Roh columns).
|
||||
- Keep functions focused and composable; put experiment‑specific logic in scripts.
|
||||
- Prefer updating existing functions over creating new (personal) versions.
|
||||
- Document new functions with:
|
||||
- a clear help header,
|
||||
- input / output description,
|
||||
- at least one minimal example.
|
||||
- Add or update example scripts (`examples/` or `scripts/`) showing how to use your new features.
|
||||
- If you introduce new table variables, add a short description in the data‑structure docs.
|
||||
|
||||
Git hygiene (short version):
|
||||
|
||||
- Use feature branches for non‑trivial changes.
|
||||
- Write clear commit messages and push changes for every major update or change.
|
||||
- Do **not** commit raw beamline data; keep those on shared drives and refer to them from scripts.
|
||||
|
||||
***
|
||||
|
||||
## License / usage
|
||||
|
||||
This code is intended for internal use within the research group (and close collaborators). If you plan to use or release it outside the group, please check first.
|
||||
|
||||
***
|
||||
|
||||
Happy NAPPing! 🎉🧊
|
||||
If you are lost, confused, or plotting the wrong edge – reach out.
|
||||
@@ -1,5 +1,7 @@
|
||||
function ListFiles = QuickAndDirtyNexafsImport(DataTable)
|
||||
|
||||
|
||||
|
||||
%% QuickAndDirtyNexafsImport
|
||||
%
|
||||
[filePick,pathPick] = uigetfile({'*.h5'},...
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
## MATLAB
|
||||
*.asv
|
||||
*.m~
|
||||
*.mldatx
|
||||
|
||||
## LaTeX
|
||||
*.aux
|
||||
*.fls
|
||||
*.toc
|
||||
*.synctex.gz
|
||||
*.fdb_latexmk
|
||||
*.log
|
||||
*.out
|
||||
|
||||
## Development folder
|
||||
dev/
|
||||
|
||||
## Testing folders and files
|
||||
test/coverage/
|
||||
test/File.h5
|
||||
test/AttributeTest.h5
|
||||
test/AttributesTest.h5
|
||||
test/CopyTest1.h5
|
||||
test/CopyTest2.h5
|
||||
test/Dataset.h5
|
||||
test/Collection.h5
|
||||
test/EnumClassTest.h5
|
||||
test/GroupTest.h5
|
||||
test/LinkTest.h5
|
||||
test/MoveTest.h5
|
||||
test/ValidatorTest.h5
|
||||
test/Test.h5
|
||||
|
||||
## Misc
|
||||
*.DS_Store
|
||||
*.vscode
|
||||
Binary file not shown.
@@ -1,10 +1,6 @@
|
||||
function nappImage(DataTable,varargin)
|
||||
%
|
||||
% h_img = Napp_plotImage(StructArrayData) plots an image of the
|
||||
% NEXAFS data set in the NEXAFS data structure.
|
||||
%
|
||||
% Output: an image figure, with a handle. The handle is important to
|
||||
% select these images for XPS removal
|
||||
% no longer used.
|
||||
|
||||
% Define conditions and defaults of input
|
||||
defaultTableVariable = {'image'};
|
||||
Reference in new issue
Block a user