%% 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