222 lines
9.3 KiB
Matlab
222 lines
9.3 KiB
Matlab
%% How do I ....
|
||
clc;clear all;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 |