Files
nappMATLAB-toolbox/beamtime/documentedExampleScripts/HowDoI.m
T

222 lines
9.3 KiB
Matlab
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
%% How do I ....
clc;clearvars; close all
load FileList.mat
%% ... quick-and-dirty normalize
%
% Normalize counts per second to a reference intensity? You need to plot the
% two spectra and use the cursor to read the intensities from the figures.
% Then change the spectra intensities directly in the table as shown here:
%
% Do not save the FileList. This way you can reload it from the MAT file to
% start fresh.
close all;clc
tmpDataSelection = matches(FileList.name,"0146146_Cl2p_850eV.ibw");
FileList = nappGenerateSpectra(FileList,tmpDataSelection);
nappPlot(FileList,tmpDataSelection,'tableVariable','spectrum_countsPerSecond','mode','OneEach');
xlim([647 652])
FileList(tmpDataSelection,:).spectrum_countsPerSecond{:} = FileList(tmpDataSelection,:).spectrum_countsPerSecond{:} .* 22335./39687;
nappPlot(FileList,tmpDataSelection,'tableVariable','spectrum_countsPerSecond','mode','OneEach');
xlim([647 652])
ylabel("counts [norm to Al]")
legend
distFig
%% ... quick-and-dirty shift spectra
%
% If you do not want to generate the binding-energy scale using the
% nappMATLAB function.
close all;clc
% Select your data based on the filename
tmpDataSelection = startsWith(FileList.name, "0191191_O1s_VB_525eV");
% List the selected files in the command window
disp(FileList(tmpDataSelection,{'name','lastModifiedDatestr','scientaPassEnergy_eV'}))
% Generate spectra
FileList = nappGenerateSpectra(FileList,tmpDataSelection);
% Plot in kinetic-energy mode
nappPlot(FileList,tmpDataSelection,'tableVariable','spectrum_countsPerSecond','mode','AllInOne','energyScale','kinetic');
% Apply the shift to kinetic energy manually and plot
FileList(tmpDataSelection,:).scientaEkin_eV{:} = FileList(tmpDataSelection,:).scientaEkin_eV{:}-20;
nappPlot(FileList,tmpDataSelection,'tableVariable','spectrum_countsPerSecond','mode','AllInOne','energyScale','kinetic');
distFig
%% ... remove a sweep (sequence iteration) from data
close all; clc
% Remove sweep 3:
tmpDataSelection = contains(FileList.name,'0146146_Al2p_850eV.ibw');
nappPlot(FileList,tmpDataSelection,'tableVariable','image')
FileList(tmpDataSelection,:).image{:}(:,3)=[];
nappPlot(FileList,tmpDataSelection,'tableVariable','image')
distFig
%% ... remove several sweeps
close all; clc
tmpDataSelection = contains(FileList.name,'0146146_Al2p_850eV.ibw');
% Remove sweeps 5–9
nappPlot(FileList,tmpDataSelection,'tableVariable','image')
FileList(tmpDataSelection,:).image{:}(:,5:9)=[];
nappPlot(FileList,tmpDataSelection,'tableVariable','image')
distFig
%% ... correct beamline offset
% This will correct 1.6 eV on the X-ray energies, which is particularly
% important for NEXAFS data. One can also do this on selected data only.
FileList.xRayEkin_eV = cellfun(@(x) x+1.6,FileList.xRayEkin_eV,'UniformOutput',false);
%% ... on-the-fly shift data in a figure
tmpDataSelection = month(FileList.lastModifiedDatenum) == 11 ...
& year(FileList.lastModifiedDatenum) == 2025 ...
& ~contains(FileList.sample,"(bad data)") ...
& contains(FileList.name,"O_Kedge_Resonant") ...
& contains(FileList.name,"0025");
nappPlot(FileList,tmpDataSelection,'tableVariable','image','mode','AugerMeitner','AugerMeitnerEnergies',[525,545,550]);
hax = gca;
hax.XDir = 'reverse';
xlabel('Auger-Meitner binding energy [eV]');
% Shift data (same works in Y direction)
dataObjs = findobj(gcf,'-property','YData');
dataObjs(1).XData = dataObjs(1).XData -10;
dataObjs(2).XData = dataObjs(2).XData +10;
dataObjs(3).XData = dataObjs(3).XData +20;
%% ... on-the-fly smooth data in a figure
clc;close all
tmpDataSelection = month(FileList.lastModifiedDatenum) == 11 ...
& year(FileList.lastModifiedDatenum) == 2025 ...
& ~contains(FileList.sample,"(bad data)") ...
& contains(FileList.name,"O_Kedge_Resonant") ...
& contains(FileList.name,"0025");
nappPlot(FileList,tmpDataSelection,'tableVariable','image','mode','AugerMeitner','AugerMeitnerEnergies',[525,545,550]);
hax = gca;
hax.XDir = 'reverse';
xlabel('Auger-Meitner binding energy [eV]');
dataObjs = findobj(gcf,'-property','YData');
y = dataObjs(1).YData;
dataObjs(1).YData = smoothdata(y ,'sgolay',10);
y = dataObjs(2).YData;
dataObjs(2).YData = smoothdata(y ,'sgolay',10);
y = dataObjs(3).YData;
dataObjs(3).YData = smoothdata(y ,'sgolay',10);
%% ... on-the-fly remove data from a figure
clc;close all
tmpDataSelection = month(FileList.lastModifiedDatenum) == 11 ...
& year(FileList.lastModifiedDatenum) == 2025 ...
& ~contains(FileList.sample,"(bad data)") ...
& contains(FileList.name,"O_Kedge_Resonant") ...
& contains(FileList.name,"0025");
nappPlot(FileList,tmpDataSelection,'tableVariable','image','mode','AugerMeitner','AugerMeitnerEnergies',[525,545,550]);
hax = gca;
hax.XDir = 'reverse';
xlabel('Auger-Meitner binding energy [eV]');
dataObjs = findobj(gcf,'-property','YData');
delete(dataObjs(1))
legend('545','550');
%% ... on-the-fly change colors in a figure
clc;close all
tmpDataSelection = month(FileList.lastModifiedDatenum) == 11 ...
& year(FileList.lastModifiedDatenum) == 2025 ...
& ~contains(FileList.sample,"(bad data)") ...
& contains(FileList.name,"O_Kedge_Resonant") ...
& contains(FileList.name,"0025");
nappPlot(FileList,tmpDataSelection,'tableVariable','image','mode','AugerMeitner','AugerMeitnerEnergies',[525,545,550]);
hax = gca;
hax.XDir = 'reverse';
xlabel('Auger-Meitner binding energy [eV]');
dataObjs = findobj(gcf,'-property','YData');
dataObjs(2).Color = [184 184 185]/255;
dataObjs(3).Color = [58 162 190]/255;
%% ... combine two tables with common and different columns (variables) into one?
%
% This example shows how a helper function (outerjoinRowToTable) can
% append rows from one table to another even if the tables do not start
% with exactly the same set of variables (columns).[web:59]
for ii=1
%% Create simple table 1
%
% --- Table 1: one row, six columns of different types --------------------
%
% Types requested:
% 1) character -> stored as cell containing a char vector
% 2) string -> string scalar
% 3) cell array -> heterogeneous container
% 4) cell -> cell holding a scalar
% 5) array -> numeric vector
% 6) number -> scalar double
%
% MATLAB tables can hold mixed data types column-wise as long as each
% column has the same number of rows.[web:59]
%
% For "character": use a 1x1 cell that contains a char vector
charCol = {'name1'}; % cell containing a character vector
stringCol = "hello"; % string scalar
cellArrayCol = {1 2 3}; % 1x3 cell array
cellCol = {42}; % 1x1 cell, holding a number
arrayCol = 1:5; % numeric row vector
numberCol = 3.14; % scalar double
Table1 = table(charCol, stringCol, cellArrayCol, cellCol, arrayCol, numberCol, ...
'VariableNames', {'CharCol','StringCol','CellArrayCol','CellCol','ArrayCol','NumberCol'});
%% Create Table 2
%
% --- Table 2: one row, with a different set of variables -----------------
%
% Table2 shares the variable CharCol with Table1, but also has a new
% variable OneNumber that does not exist in Table1.
%
% When we combine the tables, CharCol will become a column with two rows
% (name1 and name2). The new variable OneNumber will be added to Table1,
% and the missing value for the first row will be filled with a numeric
% placeholder (NaN).
oneNumber = 99; % scalar double
charCol = {'name2'}; % cell containing a character vector
Table2 = table(oneNumber, charCol, ...
'VariableNames', {'OneNumber', 'CharCol'});
disp(Table1);
disp(Table2);
%% Combine both into one
%
% outerjoinRowToTable does the following:
% 1) It compares the VariableNames of both tables.
% - Columns with the same name (here CharCol) are aligned and will
% end up as a single column with multiple rows.
% 2) For variables that only exist in one table:
% - If a variable is missing in the incoming rows, a new column is
% added to that smaller table and filled with placeholder values
% (NaN for numeric types, ' ' or " " for text/cell/string types),
% so that the column exists for all rows.
% - This ensures both tables have the same set of columns before
% concatenation.
% 3) After the variable sets are harmonized, the rows are concatenated
% with standard vertical stacking, so the result is one table where:
% - Shared columns (CharCol) contain data from both input tables
% in separate rows.
% - Columns that were unique to one input (e.g. OneNumber or
% ArrayCol) show data where available and placeholder values where
% that column did not exist originally.[web:59]
Table3 = outerjoinRowToTable(Table1,Table2);
disp(Table3)
% In a real workflow, this pattern allows you to successively append
% FileList tables from multiple beamtimes, even if new metadata
% columns were introduced later. Older rows are back-filled with
% placeholder values for new variables, while shared columns accumulate
% additional rows representing more files / experiments.
%
% Example:
% tmpData = load('../beamtimes/20220828BeamTimeIceNappIss/FileList.mat');
% tmpData2 = load('../beamtimes/20211216BeamTimeLjSim/FileList.mat');
% FileList = outerjoinRowToTable(tmpData.FileList,tmpData2.FileList);
end