Files
nappMATLAB-toolbox/nappIce/HowTo/html/nappIceHowTo.html
T
2023-08-09 15:02:10 +02:00

1828 lines
122 KiB
HTML

<!DOCTYPE html
PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<!--
This HTML was auto-generated from MATLAB code.
To make changes, update the MATLAB code and republish this document.
--><title>How to analyse ISS XPS and NEXAFS data using Matlab</title><meta name="generator" content="MATLAB 9.11"><link rel="schema.DC" href="http://purl.org/dc/elements/1.1/"><meta name="DC.date" content="2022-11-30"><meta name="DC.source" content="nappIceHowTo.m"><style type="text/css">
html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,font,img,ins,kbd,q,s,samp,small,strike,strong,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td{margin:0;padding:0;border:0;outline:0;font-size:100%;vertical-align:baseline;background:transparent}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:'';content:none}:focus{outine:0}ins{text-decoration:none}del{text-decoration:line-through}table{border-collapse:collapse;border-spacing:0}
html { min-height:100%; margin-bottom:1px; }
html body { height:100%; margin:0px; font-family:Arial, Helvetica, sans-serif; font-size:10px; color:#000; line-height:140%; background:#fff none; overflow-y:scroll; }
html body td { vertical-align:top; text-align:left; }
h1 { padding:0px; margin:0px 0px 25px; font-family:Arial, Helvetica, sans-serif; font-size:1.5em; color:#d55000; line-height:100%; font-weight:normal; }
h2 { padding:0px; margin:0px 0px 8px; font-family:Arial, Helvetica, sans-serif; font-size:1.2em; color:#000; font-weight:bold; line-height:140%; border-bottom:1px solid #d6d4d4; display:block; }
h3 { padding:0px; margin:0px 0px 5px; font-family:Arial, Helvetica, sans-serif; font-size:1.1em; color:#000; font-weight:bold; line-height:140%; }
a { color:#005fce; text-decoration:none; }
a:hover { color:#005fce; text-decoration:underline; }
a:visited { color:#004aa0; text-decoration:none; }
p { padding:0px; margin:0px 0px 20px; }
img { padding:0px; margin:0px 0px 20px; border:none; }
p img, pre img, tt img, li img, h1 img, h2 img { margin-bottom:0px; }
ul { padding:0px; margin:0px 0px 20px 23px; list-style:square; }
ul li { padding:0px; margin:0px 0px 7px 0px; }
ul li ul { padding:5px 0px 0px; margin:0px 0px 7px 23px; }
ul li ol li { list-style:decimal; }
ol { padding:0px; margin:0px 0px 20px 0px; list-style:decimal; }
ol li { padding:0px; margin:0px 0px 7px 23px; list-style-type:decimal; }
ol li ol { padding:5px 0px 0px; margin:0px 0px 7px 0px; }
ol li ol li { list-style-type:lower-alpha; }
ol li ul { padding-top:7px; }
ol li ul li { list-style:square; }
.content { font-size:1.2em; line-height:140%; padding: 20px; }
pre, code { font-size:12px; }
tt { font-size: 1.2em; }
pre { margin:0px 0px 20px; }
pre.codeinput { padding:10px; border:1px solid #d3d3d3; background:#f7f7f7; }
pre.codeoutput { padding:10px 11px; margin:0px 0px 20px; color:#4c4c4c; }
pre.error { color:red; }
@media print { pre.codeinput, pre.codeoutput { word-wrap:break-word; width:100%; } }
span.keyword { color:#0000FF }
span.comment { color:#228B22 }
span.string { color:#A020F0 }
span.untermstring { color:#B20000 }
span.syscmd { color:#B28C00 }
span.typesection { color:#A0522D }
.footer { width:auto; padding:10px 0px; margin:25px 0px 0px; border-top:1px dotted #878787; font-size:0.8em; line-height:140%; font-style:italic; color:#878787; text-align:left; float:none; }
.footer p { margin:0px; }
.footer a { color:#878787; }
.footer a:hover { color:#878787; text-decoration:underline; }
.footer a:visited { color:#878787; }
table th { padding:7px 5px; text-align:left; vertical-align:middle; border: 1px solid #d6d4d4; font-weight:bold; }
table td { padding:7px 5px; text-align:left; vertical-align:top; border:1px solid #d6d4d4; }
</style></head><body><div class="content"><h1>How to analyse ISS XPS and NEXAFS data using Matlab</h1><!--introduction--><!--/introduction--><h2>Contents</h2><div><ul><li><a href="#1">Introduction: Concept</a></li><li><a href="#2">Introduction: Function calls</a></li><li><a href="#11">Introduction: Data structure</a></li><li><a href="#12">ToDo</a></li><li><a href="#13">Prepare: Initialise MATLAB</a></li><li><a href="#19">Prepare: ISS data structure and path to local copy of ISS data</a></li><li><a href="#22">Helper functions</a></li><li><a href="#23">Import ISS data: Complete beam time folder</a></li><li><a href="#29">Import ISS data: Error messages</a></li><li><a href="#33">Import ISS data: Add data to existing data table</a></li><li><a href="#35">Import ISS data: Add new SES or NEXAFS files from local beam time folder</a></li><li><a href="#37">Import ISS data: Choose files manually</a></li><li><a href="#39">Work with data: Excel</a></li><li><a href="#41">Work with data: Add photon energy to table (XPS)</a></li><li><a href="#43">Work with data: Add sample description</a></li><li><a href="#45">Work with data: Filter table</a></li><li><a href="#48">Work with data: Display filtered table and selected columns</a></li><li><a href="#52">Work with data: Modify data in table</a></li><li><a href="#60">Add data (columns) to table</a></li><li><a href="#62">Plot data: XPS images</a></li><li><a href="#65">Plot data: XPS and NEXAFS images</a></li><li><a href="#68">Plot data: XPS spectra</a></li><li><a href="#71">Plot data: NEXAFS spectra</a></li><li><a href="#74">Plot data: Figure layout</a></li><li><a href="#81">Plot data: Export the Figure (for use in powerpoint)</a></li><li><a href="#83">Plot data: Add region labels to survey</a></li><li><a href="#86">Process data: Align sequence iterations in images</a></li><li><a href="#89">Process data: Generate XPS spectra</a></li><li><a href="#91">Process data: Generate NEXAFS spectra</a></li><li><a href="#95">Process data: Align XPS spectra to background</a></li><li><a href="#98">Process data: Align NEXAFS spectra to background</a></li><li><a href="#101">Process data: Gauss peak fit</a></li><li><a href="#105">Process data: Norm spectra</a></li><li><a href="#108">Process data: Binding energy scale</a></li><li><a href="#111">Process data: Combine spectra</a></li></ul></div><h2 id="1">Introduction: Concept</h2><p>NEXAFS and XPS data from beam times is imported into a MATLAB table. The table allows to add meta data such as sample temperature, cell pressure, or Scienta settings (pass energy, etc). Further, data from several beam times can be imported and then filtered - for example to process all gas-phase CO2 PE from the last 5 years; or all ice NEXAFS at -10&deg; to -12&deg;C. Functions and the table are organised such that one can always go back to raw data to re-do the analysis or continue with processed data.</p><p>The basic idea is that a set of MATLAB functions that import the data of different format and from various sources and that can be used to perform basic XPS and NEXAFS data processing are used, shared, and developed by all group members. This requires common data formats and naming. The scripts/live scripts/functions that are used to call the common MATLAB functions are written, stored, named individually by each user.</p><p>
<img src="../Bildschirmfoto 2022-03-24 um 07.17.54.png" width="800">
</p><h2 id="2">Introduction: Function calls</h2><p>Most functions need the MATLAB data table as input. The output can be stored in the same data table adding data to the original data table, or in a new one - thus creating a copy. Some functions such as those used for plotting do not write data.</p><pre class="language-matlab">InputTable = nappFunctionAbc(InputTable);
</pre><p>This command runs the function nappFunctionAbc on the data table <i>InputTable</i> and writes the results into the same table (with the name <i>InputTable</i>.</p><p>The <i>InputTable</i> may hold different data types such as XPS data, NEXAFS, and pictures. Mostly, the functions require one and the same data type as input. <b>The <i>InputTable</i> needs to be filtered when passed to a function</b> (see below). Exceptions from this are the <tt>nappGenerateSpectra</tt> and <tt>nappPlot</tt> functions that can be called with some limitations with mixed data as input (including pictures, that are ignored).</p><pre class="language-matlab">OutputTable = nappFunctionAbc(InputTable);
</pre><p>This command runs the same function on the data in the table <i>InputTable and writes the results into the data table _OutputTable</i> which is a full copy of <i>InputTable</i> plus the results of the function nappFunctionAbc.</p><p>Most functions allow to set a number of optional input parameters, some require additional mandatory input. Please check the documentation of each function for further help:</p><pre class="language-matlab">help <span class="string">nappFunctionAbc</span>
</pre><p>The mandatory input comes first in each function call. In the following example the data of the <i>InputTable</i> is passed to the function as well as the variables <i>x</i> and <i>y</i>. The optional function input is given just like in any MATLAB function using parameter descriptions: 'option',setting. Setting can be a text string in quotes, or a variable (array, logical, table, date number, etc). Most common are:</p><pre class="language-matlab">OutputTable = nappFunctionAbc(InputTable,x,y,<span class="string">'tableSelection'</span>,tmpDataSelection,<span class="untermstring">'...</span>
<span class="string">'tableVariable'</span>,<span class="string">'TableVariable'</span>, energyScale',<span class="string">'kinetic'</span>,<span class="string">'mode'</span>,<span class="string">'mean'</span>);
</pre><div><ul><li>'tableSelection': allows to filter the table and run the function only on selected table lines. tmpDataSelection is a logical array, see section Work with data: Filter table in this document.</li><li>'tableVariable': allows to choose the data of the data table that the function should work with. See Introduction: Data structure section in this document.</li><li>'energyScale': allows to use kinetic or binding energy scale to plot or perform calculation.</li><li>'mode': allows to select options for functions such as using mean or sum for calculations, etc.</li><li>'showFigures': allows to view or view not figures and function output.</li></ul></div><p>Please consult the help files of each function for a complete list of options.</p><h2 id="11">Introduction: Data structure</h2><p>It starts with importing the multi-dimensional IgorPro files that the SES software saves or with the h5 file structure that is saved for the NEXAFS data.</p><div><ul><li>Upon import of the SES data, region iterations are averaged and counts are normalised to 1 s.</li><li>NEXAFS data...</li></ul></div><p>The data are then saved in a data table, each file in one row and the data in columns. Columns are called table variables in MATLAB and in the nappFunctions. The data columns are:</p><div><ul><li><b>image</b>: PE data: Intensity in counts-per-second vs. kinetic energy and sequence iteration. Functions that work with image data, overwrite this column.</li><li><b>imageRoh</b>: a copy of image at the time of data import.</li><li><b>spectrum_countsPerSecond</b> and <b>spectrum_counts</b>: Hold the spectra that are computed from the image. These data columns are modified by nappFunctions that work with spectrum data.</li><li><b>spectrumRoh_countsPerSecond</b> and <b>spectrumRoh_counts</b>: a copy of the spectrum data at time of generation.</li></ul></div><p>In other words, the data in the columns spectrum_countsPerSecond, spectrum_counts, image always hold the processed data and are modified by each function call. The Roh data allows to go back and re-do the processing. Next to this the data table stores analyser settings such as scientaEkin and sample parameters such as temperature and pressure. View the data table in the data viewer or command window of MATLAB to see all columns. This data structure allows to process all data and then still plot images, unprocessed data, or processed data of selected experiments.</p><h2 id="12">ToDo</h2><div><ul><li>add code for intensity vs. time plotting</li><li>add code for average and plot iterations.</li><li>get rid of peakfind and replace by gauss fitting</li><li>use gauss fitting function within functions?</li><li>Tidy html output, and get Yanisha's feedback</li><li>Add section on how to modify figures after plotting</li><li>add section on how to access data in table</li><li>add section on how to merge data tables</li><li>Work on code and add section how to remove XPS from NEXAFS</li><li>Work on code and add section on I0 including 2nd order light</li><li>Add code to add combined spectra to data table as row.</li><li>Update help files for NEXAFS functions and NEXAFS options in general functions.</li><li>Set-up folders for Yanisha</li></ul></div><h2 id="13">Prepare: Initialise MATLAB</h2><p>You need to have access to the folder holding the functions and helper files. These are shared via switch drive.</p><p><b>Add the paths to the initializeMatlab function at the end of this script</b> This function needs to be added to the end of each of your scripts or live scripts. Below is an example.</p><pre>function [myColorMap, PsiFarbe] = initializeMatlab
%initializeMatlab Sets NappIce specific settings
% Adds Napp files to path and defines file locations for mac, windows,
% and Matlab online (which runs on unix)</pre><pre>% change working directory
path = matlab.desktop.editor.getActiveFilename;
[filepath,~,~] = fileparts(path);
cd(filepath);</pre><pre>% The fitting routines writes quite a lot of feedback and warnings. I shut them off.
warning('off','all')
warning off backtrace
warning off verbose</pre><pre>% Functions and helper files path:
if ismac
% add Napp files to path
addpath('/Users/bartels-rausch/SwitchDrive/PSI_Matlab/Add-Ons');
addpath('/Users/bartels-rausch/SwitchDrive/PSI_Matlab/nappIce');
elseif ispc
% add Napp files to path
addpath('/Users/bartels-rausch/SwitchDrive/PSI_Matlab/Add-Ons');
addpath('/Users/bartels-rausch/SwitchDrive/PSI_Matlab/nappIce');
elseif isunix
% add Napp files to path
addpath('/Users/bartels-rausch/SwitchDrive/PSI_Matlab/Add-Ons');
addpath('/Users/bartels-rausch/SwitchDrive/PSI_Matlab/nappIce');
end</pre><pre>% Color maps
myColorMap.red = colormap(autumn(7));
myColorMap.blue = colormap(winter(7));</pre><pre>% define PSI cooperate identity colours
PsiFarbe.hellgrau = [226 226 226]/255;
PsiFarbe.mittelgrau = [184 184 184]/255;
PsiFarbe.dunkelgrau = [78 78 77]/255;
PsiFarbe.blaugrau = [236 236 243]/255; % This is actually not a PSI colour
PsiFarbe.gelb = [239 200 37]/255;
PsiFarbe.hellorange = [227 164 31]/255;
PsiFarbe.dunkelorange = [207 92 22]/255;
PsiFarbe.hellrot = [164 36 23]/255;
PsiFarbe.dunkelbraun = [114 85 65]/255;
PsiFarbe.hellbraun = [127 119 47]/255;
PsiFarbe.mittelgruen = [135 150 59]/255;
PsiFarbe.hellgruen = [195 214 47]/255;
PsiFarbe.dunkelgruen = [72 130 33]/255;
PsiFarbe.dunkelrot = [104 47 86]/255;
PsiFarbe.dunkelblau = [37 65 108]/255;
PsiFarbe.mittelgruenblau = [61 164 168]/255;
PsiFarbe.hellblau = [58 162 190]/255;
PsiFarbe.mittelblau = [50 118 158]/255;</pre><pre>end</pre><p>The path might be different on your computer depending how you have set up SwitchDrive:</p><pre class="language-matlab">addpath(<span class="string">'C:\Users\bletry_c\switchdrive\PSI_Matlab\nappIce'</span>);
addpath(<span class="string">'C:\Users\bletry_c\switchdrive\PSI_Matlab\Add-Ons'</span>);
</pre><p>then run the initialiseMatlab function:</p><pre class="language-matlab">clearvars
[myColorMap, PsiFarbe] = initializeMatlab;
close <span class="string">all</span>
clc
</pre><h2 id="19">Prepare: ISS data structure and path to local copy of ISS data</h2><p>Data needs to be organised in beam time folders that can be located on the Napp drive or locally on your computer. The data folder naming and structure within the beam time folder (orange on figure) is strict and there must not be any subfolders in the data folders:</p><p>
<img src="../Bildschirmfoto 2022-03-23 um 08.19.22.png" width="400">
</p><div><ul><li>NEXAFS holds *.h5 XAS data</li><li>Photos holds *.bmp pictures</li><li>Pressure holds the *.dat LabView files</li><li>SES holds the *.ibw PE data.</li><li>To run the scripts, there <b>needs to be at least ONE *.ibw file in the SES folder</b></li></ul></div><p><b>beam time folder location</b></p><div><ul><li>The beam time folder can be a subfolder of any number of folders.</li><li>The beam time folder needs to have the same name, same subfolders, and folders above (path) locally and on the NAPP drive. This can be set by the user when calling the import function. As standard, we use "year:YYYY_MM__monthIssIceNapp"</li><li>on Napp drive: the beam time folder (and folders above) needs to be within the "SC Data" folder</li><li>locally: the beam time folder (and folders above) needs to be within your "MATLAB home folder:NAPP:SC Data" folder</li></ul></div><p>The see all import options (few examples given below) check out the nappFileList.m help (this works for all nappIce functions):</p><pre class="language-matlab">help <span class="string">nappFileList.m</span>
</pre><h2 id="22">Helper functions</h2><div><ul><li>Napp_p_ice(T_current) states and plots the vapour pressure of ice between 200-270 K</li><li>Napp_p_RH(T_current,RH) calculates the partial pressure of water for a given temperature and relative humidity.</li><li>Napp_RH_p(T_current,partial_pressure_water) calculates the relative humidity for a given temperature and water pressure.</li></ul></div><h2 id="23">Import ISS data: Complete beam time folder</h2><pre class="language-matlab">FileList = nappFileList(<span class="string">'2022/2022_02__FebIssIceNapp'</span>);
</pre><p>This will create a new data table "FileList" overwriting any previous versions of this list with data imported from the local copy of the beam time folder with the name "2022_02__FebIssIceNapp" being a subfolder of the folder "2022".</p><pre class="codeoutput">data read from mat file
</pre><h2 id="29">Import ISS data: Error messages</h2><p>If you get a message like this in the command window</p><pre>There appears to be no file in the SES folder. Add at least one file first.
I quit now</pre><p>and MATLAB quits running the script, please check that there is at least a *.ibw file in the SES folder</p><p>If you instead get a message like this</p><pre>There is something wrong with the path. Check for typo and that the drives are mounted
I quit now</pre><p>and MATLAB quits running the script, please check</p><div><ul><li>that there are no typos in the path names</li><li>that the drives are mounted.</li></ul></div><h2 id="33">Import ISS data: Add data to existing data table</h2><p>This will import data from the beam time folder "2021/2021_08__AugIssIceNapp" on the NAPP drive adding the data to the data table "FileList" in the MATLAB workspace</p><pre class="language-matlab">FileList = nappFileList(<span class="string">'2021/2021_08__AugIssIceNapp'</span>,FileList,<span class="string">'mode'</span>,<span class="string">'nappDrive'</span>);
</pre><h2 id="35">Import ISS data: Add new SES or NEXAFS files from local beam time folder</h2><p>Using the mode 'localNew' the content of the beam time folder will be compared to that of the FileList in the workspace and only those files not yet imported will be processed. This is a little faster and preserves any changes to the FileList. <b>To prevent data failure of running SES measurements, this only works on the local copy of the beam time folder</b></p><pre class="language-matlab">FileList = nappFileList(<span class="string">'2022/2022_02__FebIssIceNapp'</span>,FileList,<span class="string">'mode'</span>,<span class="string">'localNew'</span>);
</pre><h2 id="37">Import ISS data: Choose files manually</h2><p>This will open a windows file explorer window where you can choose as many data files to be imported as you want. In this example, a new FileList is written, overwriting any previous versions in the workspace.</p><pre class="language-matlab">FileList = nappFileList(<span class="string">'2022/2022_02__FebIssIceNapp'</span>,<span class="string">'mode'</span>,<span class="string">'nappDrivePick'</span>);
</pre><p>
<img src="../Bildschirmfoto 2022-03-23 um 11.14.44.png" width="400">
</p><h2 id="39">Work with data: Excel</h2><p>The nappFileList.m function also writes a csv file to the beam time folder. Open it as xlsx and use Excels formatting and filtering tools to work with your data set. So, the xlsx file is edited manually and might contain additional information that you have added such as slit settings, comments, type of sample, scope of the measurement, etc. The csv file it automatically generated and might thus be frequently be over-written. Use copy/paste to update the xlsx file with new data, formatting will be automatically applied to new data then.</p><p>
<img src="../Bildschirmfoto 2019-05-08 um 09.58.47.png" width="800">
</p><h2 id="41">Work with data: Add photon energy to table (XPS)</h2><p>ISS beamline does not log settings of SES data. Photon energy, which is needed to calculate the binding energy later, needs to be added manually. This will read the FileList table and add the photon energy "1000" to the SES data with file numbers 1,8 to 12, and 26 acquired in February (month "2") of the year "2022"). Note, this is only adding to XPS data, NEXAFS data are not touched:</p><pre class="language-matlab">FileList = addPhotonEnergy(FileList,[1,8:12,26],1000,2,2022);
</pre><h2 id="43">Work with data: Add sample description</h2><p>Sample description to label figures and for filtering data can be added. It does not make sense to use temperature or pressure, as these data are written to the table anyway. It does make sense to use standard phrases to enable filtering all beam time data. This code example follow the same input structure as the addPhotonEnergy function. This function works on both NEXAFS and XPS data. One may limit and select either one specifically by adding either 'NEXAFS' or 'XPS' strings as last input parameter. This is optional, if not specified function runs on both data types:</p><pre class="language-matlab">FileList = addSampleNotes(FileList,[1,8:11],<span class="string">'Sample holder'</span>,2,2022,<span class="string">'XPS'</span>);
FileList = addSampleNotes(FileList,[1,8:11],<span class="string">'Sample holder'</span>,2,2022,<span class="string">'NEXAFS'</span>);
FileList = addSampleNotes(FileList,[2:7,35:36,56:60],<span class="string">'Ice with N2'</span>,2,2022);
FileList = addSampleNotes(FileList,73:76,<span class="string">'H2O gas-phase'</span>,2,2022);
FileList = addSampleNotes(FileList,73,<span class="string">'H2O gas-phase (bad data)'</span>,2,2022);
</pre><h2 id="45">Work with data: Filter table</h2><p>An advantage of the data table is filtering. This works with standard MATLAB functions using logical operations. Main motivation of filtering is to work with selected subset of data which for example can be processed with the same settings, fitted with the same constrains, or shall be plotted in one graph for comparison.</p><p>Further, the <i>InputTable</i> may hold different data types such as XPS data, NEXAFS, and pictures. Mostly, the functions require one and the same data type as input. Therefore, <b>the <i>InputTable</i> needs to be filtered when passed to most functions</b>. Exceptions from this are the <tt>nappGenerateSpectra</tt> and <tt>nappPlot</tt> functions that can be called with some limitations in the settings with mixed data as input (including pictures, that are ignored).</p><p>The first example filter CO2 gas-phase C1s PE data that is not "(bad data)" and has a pass energy of 50 eV. In the second example, we pick a C1s or O1s PE data from the SES file #77 from February 2022. Any table column can be used for filtering. "&amp;" means AND "|" is OR.</p><pre class="language-matlab">tmpDataSelection1 = matches(FileList.sample,<span class="string">'CO2 gas-phase'</span>) <span class="keyword">...</span>
&amp; ~contains(FileList.sample,<span class="string">'(bad data)'</span>)<span class="keyword">...</span>
&amp; contains(FileList.name,<span class="string">'C1s'</span>)<span class="keyword">...</span>
&amp; FileList.scientaPassEnergy_eV == 50 ;
</pre><pre class="language-matlab">tmpDataSelection2 = (contains(FileList.name,<span class="string">'077_C1s'</span>) | contains(FileList.name,<span class="string">'077_O1s'</span>)) <span class="keyword">...</span>
(month(FileList.lastModifiedDatenum) == 2) &amp;<span class="keyword">...</span>
(year(FileList.lastModifiedDatenum) == 2022);
</pre><h2 id="48">Work with data: Display filtered table and selected columns</h2><p>MATLAB tables allow to address the columns by name. To display only the rows that match the filter criteria and only specific columns, code like the examples below can be used:</p><pre class="language-matlab">disp(FileList(tmpDataSelection1,{<span class="string">'name'</span>,<span class="string">'sample'</span>,<span class="string">'xRayEkin_eV'</span>,<span class="string">'scientaPassEnergy_eV'</span>,<span class="string">'lastModifiedDatestr'</span>,<span class="string">'sampleTemp_dC'</span>,<span class="keyword">...</span>
<span class="string">'cellPressure_mbar'</span> }))
disp(FileList(tmpDataSelection2,{<span class="string">'name'</span>,<span class="string">'scientaLensMode'</span>,<span class="string">'xRayEkinRange_eV'</span>,<span class="string">'scientaPassEnergy_eV'</span>}))
</pre><pre class="codeoutput"> name sample xRayEkin_eV scientaPassEnergy_eV lastModifiedDatestr sampleTemp_dC cellPressure_mbar
_________________________ _________________ ___________ ____________________ ________________________ _____________ _________________
{'0077077_C1s_900eV.ibw'} {'CO2 gas-phase'} {[900]} 50 {'28-Feb-2022 20:52:12'} 19.966 1.3599
{'0080080_C1s_650eV.ibw'} {'CO2 gas-phase'} {[650]} 50 {'28-Feb-2022 20:59:57'} 19.993 1.432
{'0081081_C1s_650eV.ibw'} {'CO2 gas-phase'} {[650]} 50 {'28-Feb-2022 21:03:12'} 20.015 1.0105
{'0082082_C1s_900eV.ibw'} {'CO2 gas-phase'} {[900]} 50 {'28-Feb-2022 21:07:49'} 19.994 0.99001
name scientaLensMode xRayEkinRange_eV scientaPassEnergy_eV
_________________________ ________________ ________________ ____________________
{'0077077_C1s_900eV.ibw'} {'T_HiPPHAXPES'} 900 900 50
{'0077077_O1s_900eV.ibw'} {'T_HiPPHAXPES'} 900 900 50
</pre><h2 id="52">Work with data: Modify data in table</h2><p>There might be bad sweeps (sequence iterations) either with too low signal to noise or because some setting was changed during the run. These can be removed by directly addressing the data in the images. Same procedure, first the data (table row) is filtered, then the image modified for the selected data.</p><p><b>remove one sweep</b></p><pre class="language-matlab">tmpDataSelection = contains(FileList.name,<span class="string">'077_C1s'</span>)&amp; <span class="keyword">...</span>
(month(FileList.lastModifiedDatenum) == 2) &amp;<span class="keyword">...</span>
(year(FileList.lastModifiedDatenum) == 2022);
FileList(tmpDataSelection,:).image{:}(:,3)=[];
</pre><pre class="language-matlab">tmpDataSelection = contains(FileList.name,<span class="string">'077_O1s'</span>)&amp; <span class="keyword">...</span>
(month(FileList.lastModifiedDatenum) == 2) &amp;<span class="keyword">...</span>
(year(FileList.lastModifiedDatenum) == 2022);
FileList(tmpDataSelection,:).image{:}(:,3)=[];
</pre><p><b>remove several sweeps</b></p><pre class="language-matlab">tmpDataSelection = contains(FileList.name,<span class="string">'059_C1s'</span>)&amp; <span class="keyword">...</span>
(month(FileList.lastModifiedDatenum) == 10) &amp;<span class="keyword">...</span>
(year(FileList.lastModifiedDatenum) == 2021);
FileList(tmpDataSelection,:).image{:}(:,5:15)=[];
</pre><p><b>remove all data (complete table rows) outside a specific time window</b></p><pre class="language-matlab">tmpTime.start = datenum(<span class="string">'30-Apr-2019 02:00:00'</span>);
tmpTime.end = datenum(<span class="string">'30-Apr-2019 05:00:00'</span>);
toDelete = Table_FileList.datenum &lt;= tmpTime.start;
Table_FileList(toDelete,:) = [];
toDelete = Table_FileList.datenum &gt;= tmpTime.end;
Table_FileList(toDelete,:) = [];
</pre><p><b>Correct beam line-offset in data</b></p><p>This will correct 1.6 from the X-ray energies, of particular importance for NEXAFS data. One can also do this on selected data.</p><pre class="language-matlab">beamlineOffset = 1.6;
FileList.xRayEkin_eV = cellfun(@(x) x+beamlineOffset,FileList.xRayEkin_eV,<span class="string">'UniformOutput'</span>,false);
</pre><h2 id="60">Add data (columns) to table</h2><p>Calculation results for each row can be added to data tables using standard Matlab functions. This example illustrates the use of anonymous functions, their call for each row using <tt>cellfun</tt>, and the generation of additional columns to which (selection of) the data are written.</p><pre class="language-matlab">fun1 =@(c) interp1(IzeroAugInCell(:,1),IzeroAugInCell(:,2), c);
fun2 =@(c) interp1(IzeroAugInCell(:,1),IzeroAugInCell(:,3), c);
tmpMatch = (month(ListNexafs.lastModifiedDatenum) == 8) &amp;<span class="keyword">...</span>
(year(ListNexafs.lastModifiedDatenum) == 2020) |<span class="keyword">...</span>
(startsWith(ListNexafs.name, <span class="string">'sum_Aug'</span>));
ListNexafs.uhvI0(tmpMatch) = cellfun(fun1, ListNexafs.xRayEkin_eV(tmpMatch) ,<span class="string">'uni'</span> , 0);
ListNexafs.uhvI0std(tmpMatch) = cellfun(fun2, ListNexafs.xRayEkin_eV(tmpMatch) ,<span class="string">'uni'</span> , 0);
clearvars <span class="string">tmp*</span> <span class="string">fun*</span>
</pre><h2 id="62">Plot data: XPS images</h2><p>We use the nappPlot function to plot the images. For this, we specify the column of the data table that should be plotted: 'tableVarialbe','image' plots the image for all data in FileList that are selected by the logical array tmpDataSelection (See <i>Filtering table</i> above).</p><pre class="language-matlab">nappPlot(FileList,tmpDataSelection,<span class="string">'tableVariable'</span>,<span class="string">'image'</span>);
</pre><img vspace="5" hspace="5" src="nappIceHowTo_01.png" alt=""> <h2 id="65">Plot data: XPS and NEXAFS images</h2><p>This example filters for a XPS file name and a NEXAFS file name and shows two things. First, that the XPS file name is not unique and filtering thus needs to be combined with extra parameters such as date and second how NEXAS and XPS data can be simultaneously passed to the <tt>nappPlot</tt> function</p><pre class="language-matlab">tmpDataSelection = matches(FileList.name,<span class="string">'0067067_O1s_1000eV.ibw'</span>) | matches(FileList.name, <span class="string">'0063_20200824_042852_O_K_edge.h5'</span>);
nappPlot(FileList,tmpDataSelection);
</pre><img vspace="5" hspace="5" src="nappIceHowTo_02.png" alt=""> <img vspace="5" hspace="5" src="nappIceHowTo_03.png" alt=""> <img vspace="5" hspace="5" src="nappIceHowTo_04.png" alt=""> <h2 id="68">Plot data: XPS spectra</h2><p>We use the nappPlot function to plot the spectra by selecting 'spectrum_countsPerSecond' as 'tableVariable'. Further options include the binding or kinetic energy scale, and each spectrum in a separate window, or all in one window by setting the 'mode'. This works, of course, only after the spectrum has been generated using the function nappGenerateSpectra.</p><pre class="language-matlab">nappPlot(FileList,tmpDataSelection,<span class="string">'tableVariable'</span>,<span class="string">'spectrum_countsPerSecond'</span>,<span class="keyword">...</span>
<span class="string">'mode'</span>,<span class="string">'AllInOne'</span>,<span class="string">'energyScale'</span>,<span class="string">'kinetic'</span>);
</pre><img vspace="5" hspace="5" src="nappIceHowTo_05.png" alt=""> <h2 id="71">Plot data: NEXAFS spectra</h2><p>We use the same, one-and-only nappPlot function to plot the NEXAFS spectra by selecting 'spectrum_counts' as 'tableVariable' and 'energyScale' as 'xRay'. Further options include plotting each spectrum in a separate window, or all in one window by setting the 'mode'. This works, of course, only after the spectrum has been generated using the function nappGenerateSpectra.</p><pre class="language-matlab">nappPlot(FileList,tmpDataSelection,<span class="string">'tableVariable'</span>,<span class="string">'spectrum_counts'</span>,<span class="string">'energyScale'</span>,<span class="string">'xRay'</span>,<span class="string">'mode'</span>,<span class="string">'OneEach'</span>)
</pre><img vspace="5" hspace="5" src="nappIceHowTo_06.png" alt=""> <h2 id="74">Plot data: Figure layout</h2><p>The <tt>nappPlot</tt> function has 3 pre-defined figure layouts optimised for the computer screen, for powerpoint presentation or for word (and other text) files:</p><pre class="language-matlab">nappPlot(FileList,tmpDataSelection,<span class="string">'tableVariable'</span>,<span class="string">'spectrum_counts'</span>,<span class="string">'energyScale'</span>,<span class="string">'xRay'</span>,<span class="string">'mode'</span>,<span class="string">'OneEach'</span>,<span class="string">'figureMode'</span>,<span class="string">'screen'</span>);
</pre><img vspace="5" hspace="5" src="nappIceHowTo_07.png" alt=""> <pre class="language-matlab">nappPlot(FileList,tmpDataSelection,<span class="string">'tableVariable'</span>,<span class="string">'spectrum_counts'</span>,<span class="string">'energyScale'</span>,<span class="string">'xRay'</span>,<span class="string">'mode'</span>,<span class="string">'OneEach'</span>,<span class="string">'figureMode'</span>,<span class="string">'word'</span>);
</pre><img vspace="5" hspace="5" src="nappIceHowTo_08.png" alt=""> <p>nappPlot(FileList,tmpDataSelection,'tableVariable','spectrum_counts','energyScale','xRay','mode','OneEach','figureMode','powerpoint');</p><img vspace="5" hspace="5" src="nappIceHowTo_09.png" alt=""> <h2 id="81">Plot data: Export the Figure (for use in powerpoint)</h2><p>Either, copy paste the figure, or use this command on the front most figure in Matlab:</p><pre class="language-matlab">set(gcf,<span class="string">'InvertHardcopy'</span>,<span class="string">'on'</span>);
print(<span class="string">'NameForFigureFile, '</span>-dpng', <span class="string">'-r220'</span>);
</pre><h2 id="83">Plot data: Add region labels to survey</h2><p>Here is an example of how to mark regions of interest in survey plots. For this, a survey must be the topmost figure.</p><pre> dataObjs = findobj(gcf,'-property','YData');
tmpxShift = 5; % binding energy shift and mono offset
tmpxRayEnergy = 900; % of this survey
tmpyPosition = 0.5E5; % y position of labels, delta to signal height, in axis scale
tmpyPositionTwo = 0.1E5; % optional, to shift neighouring labels up and dow
% n
% Au peaks
nappAnnotateSurvey(tmpxRayEnergy-57-tmpxShift,tmpyPosition-tmpyPositionTwo,dataObjs(1),'Au5p3/2');
nappAnnotateSurvey(tmpxRayEnergy-74-tmpxShift,tmpyPosition+tmpyPositionTwo,dataObjs(1),'Au5p5/2');
nappAnnotateSurvey(tmpxRayEnergy-84-tmpxShift,tmpyPosition,dataObjs(1),'Au4f7/2');
nappAnnotateSurvey(tmpxRayEnergy-88-tmpxShift,tmpyPosition-tmpyPositionTwo,dataObjs(1),'Au4f5/2');
nappAnnotateSurvey(tmpxRayEnergy-107-tmpxShift,tmpyPosition,dataObjs(1),'Au5s');
nappAnnotateSurvey(tmpxRayEnergy-335-tmpxShift,tmpyPosition+tmpyPositionTwo,dataObjs(1),'Au4d1/2');
nappAnnotateSurvey(tmpxRayEnergy-353-tmpxShift,tmpyPosition,dataObjs(1),'Au4d3/2');
nappAnnotateSurvey(tmpxRayEnergy-546-tmpxShift,tmpyPosition+tmpyPositionTwo,dataObjs(1),'Au4p3/2');
nappAnnotateSurvey(tmpxRayEnergy-643-tmpxShift,tmpyPosition,dataObjs(1),'Au4p1/2');
nappAnnotateSurvey(tmpxRayEnergy-762-tmpxShift,tmpyPosition+tmpyPositionTwo,dataObjs(1),'Au4s');
nappAnnotateSurvey(tmpxRayEnergy-8-tmpxShift,tmpyPosition,dataObjs(1),'AuVB');
% usual suspects
nappAnnotateSurvey(tmpxRayEnergy-285-tmpxShift,tmpyPosition+tmpyPositionTwo,dataObjs(1),'C1s');
nappAnnotateSurvey(tmpxRayEnergy-534-tmpxShift,tmpyPosition,dataObjs(1),'O1s');
nappAnnotateSurvey(tmpxRayEnergy-30-tmpxShift,tmpyPosition+tmpyPositionTwo,dataObjs(1),'O2s');
nappAnnotateSurvey(tmpxRayEnergy-405-tmpxShift,tmpyPosition+tmpyPositionTwo,dataObjs(1),'N1s');
nappAnnotateSurvey(tmpxRayEnergy-495-tmpxShift,tmpyPosition,dataObjs(1),'Sn3d');
nappAnnotateSurvey(tmpxRayEnergy-691-tmpxShift,tmpyPosition+tmpyPositionTwo,dataObjs(1),'F1s');
nappAnnotateSurvey(tmpxRayEnergy-295-tmpxShift,tmpyPosition,dataObjs(1),'K2p');
nappAnnotateSurvey(tmpxRayEnergy-380-tmpxShift,tmpyPosition+tmpyPositionTwo,dataObjs(1),'K2s');
nappAnnotateSurvey(tmpxRayEnergy-153-tmpxShift,tmpyPosition,dataObjs(1),'Si2s');
nappAnnotateSurvey(tmpxRayEnergy-100-tmpxShift,tmpyPosition+tmpyPositionTwo,dataObjs(1),'Si2p');
nappAnnotateSurvey(tmpxRayEnergy-197-tmpxShift,tmpyPosition,dataObjs(1),'Cl2p');
nappAnnotateSurvey(tmpxRayEnergy-286-tmpxShift,tmpyPosition-tmpyPositionTwo,dataObjs(1),'Sn3p');
% Some Auger
nappAnnotateSurvey(360-tmpxShift,tmpyPosition-tmpyPositionTwo,dataObjs(1),'N KLL');
nappAnnotateSurvey(500-tmpxShift,tmpyPosition-tmpyPositionTwo,dataObjs(1),'O KLL');
% tid up
clearvars tmp*</pre><img vspace="5" hspace="5" src="nappIceHowTo_10.png" alt=""> <h2 id="86">Process data: Align sequence iterations in images</h2><p>To shift and align the kinetic energy of each sequence iteration relative to each other, one can use</p><div><ol><li>nappDetermineShiftXps: calculate the kinetic energy shift of each sequence iteration of an image relative to one sequence iteration (first is default)</li><li>nappCopyShift: optionally copy the kinetic energy shift to other data</li><li>nnappAlignImages: shift each sequence iterations of an image so that the peak maxima align.</li></ol></div><pre class="language-matlab"><span class="comment">% compile data</span>
tmpDataSelection = contains(FileList.name,<span class="string">'67_O1s'</span>) <span class="keyword">...</span>
&amp; (month(FileList.lastModifiedDatenum) == 8) <span class="keyword">...</span>
&amp; (year(FileList.lastModifiedDatenum) == 2021);
<span class="comment">% plot images</span>
nappPlot(FileList,tmpDataSelection,<span class="string">'tableVariable'</span>,<span class="string">'image'</span>);
<span class="comment">% align images</span>
FileList = nappDetermineShiftXps(FileList,<span class="string">'tableSelection'</span>,tmpDataSelection,<span class="keyword">...</span>
<span class="string">'showFigures'</span>,<span class="string">'off'</span>,<span class="string">'tableVariable'</span>,<span class="string">'image'</span>);
FileList = nappAlignImages(FileList,<span class="string">'tableSelection'</span>,tmpDataSelection,<span class="keyword">...</span>
<span class="string">'tableVariable'</span>,<span class="string">'image'</span>);
<span class="comment">% plot images</span>
nappPlot(FileList,tmpDataSelection,<span class="string">'tableVariable'</span>,<span class="string">'image'</span>);
</pre><pre class="codeoutput">
GlobalSearch stopped because it analyzed all the trial points.
All 26 local solver runs converged with a positive local solver exit flag.
GlobalSearch stopped because it analyzed all the trial points.
All 17 local solver runs converged with a positive local solver exit flag.
GlobalSearch stopped because it analyzed all the trial points.
All 14 local solver runs converged with a positive local solver exit flag.
GlobalSearch stopped because it analyzed all the trial points.
All 29 local solver runs converged with a positive local solver exit flag.
GlobalSearch stopped because it analyzed all the trial points.
All 27 local solver runs converged with a positive local solver exit flag.
GlobalSearch stopped because it analyzed all the trial points.
All 36 local solver runs converged with a positive local solver exit flag.
GlobalSearch stopped because it analyzed all the trial points.
All 25 local solver runs converged with a positive local solver exit flag.
GlobalSearch stopped because it analyzed all the trial points.
All 26 local solver runs converged with a positive local solver exit flag.
GlobalSearch stopped because it analyzed all the trial points.
All 43 local solver runs converged with a positive local solver exit flag.
GlobalSearch stopped because it analyzed all the trial points.
All 22 local solver runs converged with a positive local solver exit flag.
GlobalSearch stopped because it analyzed all the trial points.
All 37 local solver runs converged with a positive local solver exit flag.
GlobalSearch stopped because it analyzed all the trial points.
All 36 local solver runs converged with a positive local solver exit flag.
GlobalSearch stopped because it analyzed all the trial points.
All 42 local solver runs converged with a positive local solver exit flag.
GlobalSearch stopped because it analyzed all the trial points.
All 38 local solver runs converged with a positive local solver exit flag.
GlobalSearch stopped because it analyzed all the trial points.
All 41 local solver runs converged with a positive local solver exit flag.
</pre><img vspace="5" hspace="5" src="nappIceHowTo_11.png" alt=""> <img vspace="5" hspace="5" src="nappIceHowTo_12.png" alt=""> <h2 id="89">Process data: Generate XPS spectra</h2><p>All sequence iterations of an image are summed or the mean of all sequence iterations is calculated. The following command calculates the average of all sequence iterations from the filtered files in the FileList table. The spectrum based on the mean is saved in the column 'spectrum_countsPerSecond'.</p><pre class="language-matlab">FileList = nappGenerateSpectra(FileList,tmpDataSelection);
</pre><h2 id="91">Process data: Generate NEXAFS spectra</h2><p>% All Auger spectra of an image are summed. Options include to sum the data with the energy interval of the aquisition, or to use the trapz function to normalise to 1 eV data spacing. The NEXAFS spectrua are always saved in the column 'spectrum_counts'.</p><pre class="language-matlab">FileList = nappGenerateSpectra(FileList,<span class="string">'tableSelection'</span>,tmpDataSelection,<span class="string">'mode'</span>,<span class="string">'sum'</span>);
</pre><img vspace="5" hspace="5" src="nappIceHowTo_13.png" alt=""> <pre class="language-matlab">FileList = nappGenerateSpectra(FileList,tmpDataSelection);
</pre><h2 id="95">Process data: Align XPS spectra to background</h2><p>To align the spectra to a background the function nappBacktround can be used. Options include to compute the mean or a linear regression. Here, we calculate the mean between 367 and 370 eV.</p><pre class="language-matlab">FileList = nappBackground(FileList,367,370,<span class="string">'tableSelection'</span>,tmpDataSelection,<span class="untermstring">'...</span>
energyScale',<span class="string">'kinetic'</span>,<span class="string">'mode'</span>,<span class="string">'mean'</span>);
</pre><img vspace="5" hspace="5" src="nappIceHowTo_14.png" alt=""> <h2 id="98">Process data: Align NEXAFS spectra to background</h2><p>To align the spectra to a background the function nappBacktround can be used. Options include to compute the mean or a linear regression. Here, we calculate the mean between 522 and 525 eV xRay energy.</p><pre class="language-matlab">FileList = nappBackground(FileList,522,525,<span class="string">'tableSelection'</span>,tmpDataSelection,<span class="keyword">...</span>
<span class="string">'tableVariable'</span>,<span class="string">'spectrum_counts'</span>,<span class="string">'energyScale'</span>,<span class="string">'xRay'</span>,<span class="string">'mode'</span>,<span class="string">'mean'</span>);
</pre><img vspace="5" hspace="5" src="nappIceHowTo_15.png" alt=""> <h2 id="101">Process data: Gauss peak fit</h2><p>Gauss fitting can be used to determine area, width, and position of PE peaks. nappFitGaussXps de-convolutes the PE signal using 4 features. The fits can be constrained by</p><div><ul><li>'widthPosition' (Default): With of all peaks is identical. Position of peaks 2-3 is set relative to peak 1.</li><li>'position': Position of peaks 2-3 is set relative to peak 1.</li><li>'width': all peaks have same width</li><li>'unconstrained': Each gauss peak is fitted independent.</li><li>'unconstrainedAndWidthPosition': One unconstrained peak #3 (for gas phase feature) and 4 peaks constrained in width and/or position</li></ul></div><p>The function needs fit parameters as input, such as min and max peak area, width, and position; initial values for fitting; and the spectrum range.</p><div><ul><li>spectrum range: define the region of the PE spectrum used for fitting (plus and minus from peak 1 position). % position of peak 2-4 are relative to peak 1, that of peak 1 absolute (either in binding or kinetic energy scale)</li><li>If you are only interested in less than 4 peaks, choose small dummy constrains for those peaks you don't want to fit.</li></ul></div><pre class="language-matlab"><span class="comment">% initial fit parameters</span>
tmpFitParameters.peakArea = [1E4 5E3 0.1 0.1];
tmpFitParameters.peakWidth = [2.0 2.0 0.1 0.1];
tmpFitParameters.peakPos = [363 -1 -2 -3];
<span class="comment">% lower bonds</span>
tmpFitParameters.peakAreaLowerBond = [1E3 5E3 0.1 0.1];
tmpFitParameters.peakWidthLowerBond = [2.0 2.0 0.1 0.1];
tmpFitParameters.peakPosLowerBond = 361;
<span class="comment">% upper bonds</span>
tmpFitParameters.peakAreaUpperBond = [1E6 10E4 0.1 0.1];
tmpFitParameters.peakWidthUpperBond = [3.0 2.0 0.1 0.1];
tmpFitParameters.peakPosUpperBond = 365;
<span class="comment">% spectrum range</span>
tmpFitParameters.backgroundRange = [5 5];
</pre><p>% &#8222;position&#8220; mode tmpFitParameters.peakArea = [abs#1 abs#2 abs#3 abs#4]; tmpFitParameters.peakWidth = [abs#1 abs#2 abs#3 abs#4]; tmpFitParameters.peakPos = [abs#1 rel#2 rel#3 rel#4];</p><p>tmpFitParameters.peakAreaUpperBond = [#1 #2 #3 #4]; tmpFitParameters.peakWidthUpperBond = [#1 #2 #3 #4]; tmpFitParameters.peakPosUpperBond = #1; tmpFitParameters.peakAreaLowerBond = [#1 #2 #3 #4]; tmpFitParameters.peakWidthLowerBond = [#1 #2 #3 #4]; tmpFitParameters.peakPosLowerBond = #1;</p><p>% &#8222;unconstrained&#8220; mode tmpFitParameters.peakArea = [abs#1 abs#2 abs#3 abs#4]; tmpFitParameters.peakWidth = [abs#1 abs#2 abs#3 abs#4]; tmpFitParameters.peakPos = [abs#1 abs#2 abs#3 abs#4];</p><p>tmpFitParameters.peakAreaUpperBond = [#1 #2 #3 #4]; tmpFitParameters.peakWidthUpperBond = [#1 #2 #3 #4]; tmpFitParameters.peakPosUpperBond = [#1 #2 #3 #4]; tmpFitParameters.peakAreaLowerBond = [#1 #2 #3 #4]; tmpFitParameters.peakWidthLowerBond = [#1 #2 #3 #4]; tmpFitParameters.peakPosLowerBond = [#1 #2 #3 #4];</p><p>% &#8222; widthPosition&#8220; mode tmpFitParameters.peakArea = [abs#1 abs#2 abs#3 abs#4]; tmpFitParameters.peakWidth = [abs#1-#4]; tmpFitParameters.peakPos = [abs#1 rel#2 rel#3 rel#4];</p><p>tmpFitParameters.peakAreaUpperBond = [#1 #2 #3 #4]; tmpFitParameters.peakWidthUpperBond = #1-#4; tmpFitParameters.peakPosUpperBond = #1; tmpFitParameters.peakAreaLowerBond = [#1 #2 #3 #4]; tmpFitParameters.peakWidthLowerBond = #1-#4; tmpFitParameters.peakPosLowerBond = #1;</p><p>% &#8222; width&#8220; mode tmpFitParameters.peakArea = [abs#1 abs#2 abs#3 abs#4]; tmpFitParameters.peakWidth = [abs#1-#4]; tmpFitParameters.peakPos = [abs#1 abs#2 abs#3 abs#4];</p><p>tmpFitParameters.peakAreaUpperBond = [#1 #2 #3 #4]; tmpFitParameters.peakWidthUpperBond = #1-#4; tmpFitParameters.peakPosUpperBond = [#1 #2 #3 #4]; tmpFitParameters.peakAreaLowerBond = [#1 #2 #3 #4]; tmpFitParameters.peakWidthLowerBond = #1-#4; tmpFitParameters.peakPosLowerBond = [#1 #2 #3 #4];</p><p>% &#8222; unconstrainedAndWidthPosition" mode (novel: rel distance fit parameter) tmpFitParameters.peakArea = [abs#1 abs#2 abs#3 abs#4 abs#5]; tmpFitParameters.peakWidth = [abs#1,2,4,5 abs#3]; tmpFitParameters.peakPos = [rel#1 abs#2 abs#3 abs#4 abs#5];</p><p>tmpFitParameters.peakAreaUpperBond = [#1 #2 #3 #4 #5]; tmpFitParameters.peakWidthUpperBond = [#1,2,4,5 #3]; tmpFitParameters.peakPosUpperBond = [#1 #2 #3 #4 #5]; tmpFitParameters.peakAreaLowerBond = [#1 #2 #3 #4]; tmpFitParameters.peakWidthLowerBond = [#1,2,4,5 #3]; tmpFitParameters.peakPosLowerBond = [#1 #2 #3 #4];</p><pre class="language-matlab">FileList = nappFitGaussXps(FileList,tmpDataSelection,tmpFitParameters,<span class="string">'tableSelection'</span>,tmpDataSelection,<span class="keyword">...</span>
<span class="string">'energyScale'</span>,<span class="string">'kinetic'</span>,<span class="string">'mode'</span>,<span class="string">'position'</span>,<span class="string">'showFigures'</span>,<span class="string">'on'</span>);
</pre><p>% The fit results are written to the data table. Peak position is only written to the table if in binding energy mode. Further, results are plotted to the command line and fits are shown in graphs:</p><pre class="codeoutput">
GlobalSearch stopped because it analyzed all the trial points.
All 32 local solver runs converged with a positive local solver exit flag.
Fit results
0035035_O1s_900eV.ibw
position FWHW width area
_________ _______ _______ ___________
peak1 {'363.6'} {'2.4'} {'2.0'} {' 644646'}
peak2 {'362.6'} {'2.4'} {'2.0'} {' 5000'}
peak3 {'361.6'} {'0.1'} {'0.1'} {' 0'}
peak4 {'360.6'} {'0.1'} {'0.1'} {' 0'}
peak5 {'NaN' } {'NaN'} {'NaN'} {' NaN'}
GlobalSearch stopped because it analyzed all the trial points.
All 43 local solver runs converged with a positive local solver exit flag.
Fit results
0056056_O1s_900eV.ibw
position FWHW width area
_________ _______ _______ ___________
peak1 {'363.2'} {'2.4'} {'2.0'} {' 291250'}
peak2 {'362.2'} {'2.4'} {'2.0'} {' 5000'}
peak3 {'361.2'} {'0.1'} {'0.1'} {' 0'}
peak4 {'360.2'} {'0.1'} {'0.1'} {' 0'}
peak5 {'NaN' } {'NaN'} {'NaN'} {' NaN'}
GlobalSearch stopped because it analyzed all the trial points.
All 36 local solver runs converged with a positive local solver exit flag.
Fit results
0060060_O1s_900eV.ibw
position FWHW width area
_________ _______ _______ ___________
peak1 {'363.4'} {'2.4'} {'2.0'} {' 291466'}
peak2 {'362.4'} {'2.4'} {'2.0'} {' 5000'}
peak3 {'361.4'} {'0.1'} {'0.1'} {' 0'}
peak4 {'360.4'} {'0.1'} {'0.1'} {' 0'}
peak5 {'NaN' } {'NaN'} {'NaN'} {' NaN'}
Could not write results to table. Writing only 4 entries
</pre><img vspace="5" hspace="5" src="nappIceHowTo_16.png" alt=""> <img vspace="5" hspace="5" src="nappIceHowTo_17.png" alt=""> <img vspace="5" hspace="5" src="nappIceHowTo_18.png" alt=""> <img vspace="5" hspace="5" src="nappIceHowTo_19.png" alt=""> <h2 id="105">Process data: Norm spectra</h2><p>To normalise spectra, nappScaleToArea can be used. A typical example is to normalise C1s to the O1s peak area to compensate for changes in the working distance. The function uses the peakArea table column, thus nappFitGaussXps needs to run first. Results are written to the table variable spectrum_countsNorm (as the unit is no longer countsPerSecond). To normalise C1s to the O1s peak area, select C1s spectra using a logical (tmpDataSelection), and choose C1s for regionOld and O1s for regionNew:</p><div><ul><li>regionOld: C1s (default) or O1s - region that will be normalised</li><li>regionNew: O1s (default) or C1s - peak area that will be used to normalise</li></ul></div><pre class="language-matlab">FileList = nappScale(FileList,tmpDataSelection,<span class="string">'regionOld'</span>,<span class="string">'C1s'</span>,<span class="string">'regionNew'</span>,<span class="string">'O1s'</span>);
nappPlot(FileList,tmpDataSelection,<span class="string">'tableVariable'</span>,<span class="string">'spectrum_countsNorm'</span>);
</pre><img vspace="5" hspace="5" src="nappIceHowTo_20.png" alt=""> <img vspace="5" hspace="5" src="nappIceHowTo_21.png" alt=""> <img vspace="5" hspace="5" src="nappIceHowTo_22.png" alt=""> <img vspace="5" hspace="5" src="nappIceHowTo_23.png" alt=""> <h2 id="108">Process data: Binding energy scale</h2><p>To calculate the binding energy, you need to</p><div><ol><li>nappDetermineShiftXps: calculate the kinetic energy shift relative to a reference value</li><li>nappCopyShift: optionally copy the kinetic energy shift to other data</li><li>nappBindingEnergyXps: calculate the binding energy based on the kinetic energy shift either determined relative to a reference or copied to the individual data.</li></ol></div><p>The following example shows how the kinetic energy shift is calculated based on selected O1s spectra relative to 535 eV, copied to the C1s data with the same file number, and finally the binding energy of the C1s data is calculated (based on the observed shift of the O1s of the same sequence run) and plotted</p><pre class="language-matlab">close <span class="string">all</span>
<span class="comment">% generate spectra for C1s and O1s</span>
tmpDataSelection = matches(FileList.sample,<span class="string">'Ice with N2'</span>)<span class="keyword">...</span>
&amp; ~contains(FileList.sample,<span class="string">'(bad data)'</span>)<span class="keyword">...</span>
&amp; (contains(FileList.name,<span class="string">'O1s'</span>) | contains(FileList.name,<span class="string">'C1s'</span>))<span class="keyword">...</span>
&amp; FileList.xRayEkinRange_eV(:,1) == 900 <span class="keyword">...</span>
&amp; FileList.scientaPassEnergy_eV == 50 <span class="keyword">...</span>
&amp; (month(FileList.lastModifiedDatenum) == 2) <span class="keyword">...</span>
&amp; (year(FileList.lastModifiedDatenum) == 2022) <span class="keyword">...</span>
&amp; (day(FileList.lastModifiedDatenum) &gt;= 27);
FileList = nappGenerateSpectra(FileList,tmpDataSelection);
FileList = nappBackground(FileList,367,370,<span class="string">'tableSelection'</span>,tmpDataSelection,<span class="string">'energyScale'</span>,<span class="string">'kinetic'</span>,<span class="keyword">...</span>
<span class="string">'mode'</span>,<span class="string">'mean'</span>);
<span class="comment">% determine shift of O1s</span>
tmpDataSelection = matches(FileList.sample,<span class="string">'Ice with N2'</span>)<span class="keyword">...</span>
&amp; ~contains(FileList.sample,<span class="string">'(bad data)'</span>)<span class="keyword">...</span>
&amp; contains(FileList.name,<span class="string">'O1s'</span>)<span class="keyword">...</span>
&amp; FileList.xRayEkinRange_eV(:,1) == 900 <span class="keyword">...</span>
&amp; FileList.scientaPassEnergy_eV == 50 <span class="keyword">...</span>
&amp; (month(FileList.lastModifiedDatenum) == 2) <span class="keyword">...</span>
&amp; (year(FileList.lastModifiedDatenum) == 2022) <span class="keyword">...</span>
&amp; (day(FileList.lastModifiedDatenum) &gt;= 27);
FileList = nappDetermineShiftXps(FileList,<span class="string">'tableSelection'</span>,tmpDataSelection,<span class="keyword">...</span>
<span class="string">'showFigures'</span>,<span class="string">'off'</span>,<span class="string">'tableVariable'</span>,<span class="string">'spectrum_countsPerSecond'</span>,<span class="string">'binEnReference'</span>,533);
<span class="comment">% copy shift from O1s to C1s</span>
FileList = nappCopyShift(FileList,tmpDataSelection,<span class="string">'energyScale'</span>,<span class="string">'binding'</span>);
<span class="comment">% calculate binding energy of these C1s</span>
tmpDataSelection = matches(FileList.sample,<span class="string">'Ice with N2'</span>)<span class="keyword">...</span>
&amp; ~contains(FileList.sample,<span class="string">'(bad data)'</span>)<span class="keyword">...</span>
&amp; contains(FileList.name,<span class="string">'C1s'</span>) &amp; FileList.xRayEkinRange_eV(:,1) == 900 <span class="keyword">...</span>
&amp; FileList.scientaPassEnergy_eV == 50 <span class="keyword">...</span>
&amp; (month(FileList.lastModifiedDatenum) == 2) <span class="keyword">...</span>
&amp; (year(FileList.lastModifiedDatenum) == 2022) <span class="keyword">...</span>
&amp; (day(FileList.lastModifiedDatenum) &gt;= 27);
FileList = nappBindingEnergyXps(FileList,<span class="string">'tableSelection'</span>,tmpDataSelection);
<span class="comment">% plot C1s spectra</span>
nappPlot(FileList,tmpDataSelection,<span class="string">'tableVariable'</span>,<span class="string">'spectrum_countsPerSecond'</span>,<span class="keyword">...</span>
<span class="string">'mode'</span>,<span class="string">'AllInOne'</span>,<span class="string">'energyScale'</span>,<span class="string">'kinetic'</span>);
nappPlot(FileList,tmpDataSelection,<span class="string">'tableVariable'</span>,<span class="string">'spectrum_countsPerSecond'</span>,<span class="keyword">...</span>
<span class="string">'mode'</span>,<span class="string">'AllInOne'</span>,<span class="string">'energyScale'</span>,<span class="string">'binding'</span>);
</pre><img vspace="5" hspace="5" src="nappIceHowTo_24.png" alt=""> <img vspace="5" hspace="5" src="nappIceHowTo_25.png" alt=""> <h2 id="111">Process data: Combine spectra</h2><p>To get better statistics (signal-to-noise), repeated measurements can be added or averaged into one spectrum. The results are written into a matrix with energy in column 1, counts in column2, and standard deviation in column 3 (only for mean). So, the nappFunctions can no longer be used for this data format.</p><pre class="language-matlab">tmpDataSelection = contains(FileList.name,<span class="string">'C1s'</span>)<span class="keyword">...</span>
&amp; contains(FileList.sample,<span class="string">'MgO ice AA'</span>)<span class="keyword">...</span>
&amp; ~endsWith(FileList.sample,<span class="string">'(bad data)'</span>)<span class="keyword">...</span>
&amp; FileList.sampleTemp_dC &gt;= -26 &amp; FileList.sampleTemp_dC &lt;= -24;
MgO_C1s_Warm = nappCombineSpectra(FileList,<span class="string">'tableRow'</span>,1,<span class="keyword">...</span>
<span class="string">'tableSelection'</span>,tmpDataSelection,<span class="string">'tableVariable'</span>,<span class="keyword">...</span>
<span class="string">'spectrum_countsPerSecond'</span>,<span class="string">'EnergyScale'</span>,<span class="string">'binding'</span>,<span class="string">'mode'</span>,<span class="string">'average'</span>);
</pre><img vspace="5" hspace="5" src="nappIceHowTo_26.png" alt=""> <p class="footer"><br><a href="https://www.mathworks.com/products/matlab/">Published with MATLAB&reg; R2021b</a><br></p></div><!--
##### SOURCE BEGIN #####
%% How to analyse ISS XPS and NEXAFS data using Matlab
%
%% Introduction: Concept
%
% NEXAFS and XPS data from beam times is imported into a MATLAB table. The
% table allows to add meta data such as sample temperature, cell pressure,
% or Scienta settings (pass energy, etc). Further, data from several
% beam times can be imported and then filtered - for example to process all
% gas-phase CO2 PE from the last 5 years; or all ice NEXAFS at -10° to
% -12°C. Functions and the table are organised such that one can always go
% back to raw data to re-do the analysis or continue with processed data.
%
% The basic idea is that a set of MATLAB functions that import the data of
% different format and from various sources and that can be used to perform
% basic XPS and NEXAFS data processing are used, shared, and developed by
% all group members. This requires common data formats and naming. The
% scripts/live scripts/functions that are used to call the common MATLAB
% functions are written, stored, named individually by each user.
%
%
% <html>
% <img src="../Bildschirmfoto 2022-03-24 um 07.17.54.png" width="800">
% </html>
%% Introduction: Function calls
%
% Most functions need the MATLAB data table as input. The output can be
% stored in the same data table adding data to the original data table, or
% in a new one - thus creating a copy. Some functions such as those used
% for plotting do not write data.
%%
%
% InputTable = nappFunctionAbc(InputTable);
%
%%
% This command runs the function nappFunctionAbc on the data table
% _InputTable_ and writes the results into the same table (with the name
% _InputTable_.
%
% The _InputTable_ may hold different data types such as XPS data, NEXAFS,
% and pictures. Mostly, the functions require one and the same data type as
% input. *The _InputTable_ needs to be filtered when passed to a function*
% (see below). Exceptions from this are the |nappGenerateSpectra| and
% |nappPlot| functions that can be called with some limitations with
% mixed data as input (including pictures, that are ignored).
%
%%
%
% OutputTable = nappFunctionAbc(InputTable);
%
%%
%
% This command runs the same function on the data in the table _InputTable and
% writes the results into the data table _OutputTable_ which is a full copy
% of _InputTable_ plus the results of the function nappFunctionAbc.
%
%
% Most functions allow to set a number of optional input parameters, some
% require additional mandatory input. Please check the documentation of
% each function for further help:
%
%%
%
% help nappFunctionAbc
%
%%
%
% The mandatory input comes first in each function call. In the following
% example the data of the _InputTable_ is passed to the function as well as
% the variables _x_ and _y_. The optional function input is given just like
% in any MATLAB function using parameter descriptions: 'option',setting.
% Setting can be a text string in quotes, or a variable (array, logical,
% table, date number, etc). Most common are:
%
%%
%
% OutputTable = nappFunctionAbc(InputTable,x,y,'tableSelection',tmpDataSelection,'...
% 'tableVariable','TableVariable', energyScale','kinetic','mode','mean');
%
%%
% * 'tableSelection': allows to filter the table and run the function only
% on selected table lines. tmpDataSelection is a logical array, see section
% Work with data: Filter table in this document.
% * 'tableVariable': allows to choose the data of the data table that the
% function should work with. See Introduction: Data structure section in
% this document.
% * 'energyScale': allows to use kinetic or binding energy scale to plot or
% perform calculation.
% * 'mode': allows to select options for functions such as using mean or
% sum for calculations, etc.
% * 'showFigures': allows to view or view not figures and function output.
%
% Please consult the help files of each function for a complete list of
% options.
%
%% Introduction: Data structure
%
% It starts with importing the multi-dimensional IgorPro files that the SES
% software saves or with the h5 file structure that is saved for the NEXAFS
% data.
%
% * Upon import of the SES data, region iterations are averaged and
% counts are normalised to 1 s.
% * NEXAFS data...
%
% The data are then saved in a data table, each file in one row and the
% data in columns. Columns are called table variables in MATLAB and in the
% nappFunctions. The data columns are:
%
% * *image*: PE data: Intensity in counts-per-second vs. kinetic energy and sequence
% iteration. Functions that work with image data, overwrite this column.
% * *imageRoh*: a copy of image at the time of data import.
% * *spectrum_countsPerSecond* and *spectrum_counts*: Hold the spectra that
% are computed from the image. These data columns are modified by
% nappFunctions that work with spectrum data.
% * *spectrumRoh_countsPerSecond* and *spectrumRoh_counts*: a copy of the
% spectrum data at time of generation.
%
% In other words, the data in the columns spectrum_countsPerSecond,
% spectrum_counts, image always hold the processed data and are modified by
% each function call. The Roh data allows to go back and re-do the
% processing. Next to this the data table stores analyser settings such as
% scientaEkin and sample parameters such as temperature and pressure. View
% the data table in the data viewer or command window of MATLAB to see all
% columns. This data structure allows to process all data and then still plot
% images, unprocessed data, or processed data of selected experiments.
%% ToDo
%
% * add code for intensity vs. time plotting
% * add code for average and plot iterations.
% * get rid of peakfind and replace by gauss fitting
% * use gauss fitting function within functions?
% * Tidy html output, and get Yanisha's feedback
% * Add section on how to modify figures after plotting
% * add section on how to access data in table
% * add section on how to merge data tables
% * Work on code and add section how to remove XPS from NEXAFS
% * Work on code and add section on I0 including 2nd order light
% * Add code to add combined spectra to data table as row.
% * Update help files for NEXAFS functions and NEXAFS options in general
% functions.
% * Set-up folders for Yanisha
%% Prepare: Initialise MATLAB
%
% You need to have access to the folder holding the functions and helper
% files. These are shared via switch drive.
%
% *Add the paths to the initializeMatlab function at the end of this
% script* This function needs to be added to the end of each of your
% scripts or live scripts. Below is an example.
%
%%
%
% function [myColorMap, PsiFarbe] = initializeMatlab
% %initializeMatlab Sets NappIce specific settings
% % Adds Napp files to path and defines file locations for mac, windows,
% % and Matlab online (which runs on unix)
%
% % change working directory
% path = matlab.desktop.editor.getActiveFilename;
% [filepath,~,~] = fileparts(path);
% cd(filepath);
%
% % The fitting routines writes quite a lot of feedback and warnings. I shut them off.
% warning('off','all')
% warning off backtrace
% warning off verbose
%
% % Functions and helper files path:
% if ismac
% % add Napp files to path
% addpath('/Users/bartels-rausch/SwitchDrive/PSI_Matlab/Add-Ons');
% addpath('/Users/bartels-rausch/SwitchDrive/PSI_Matlab/nappIce');
% elseif ispc
% % add Napp files to path
% addpath('/Users/bartels-rausch/SwitchDrive/PSI_Matlab/Add-Ons');
% addpath('/Users/bartels-rausch/SwitchDrive/PSI_Matlab/nappIce');
% elseif isunix
% % add Napp files to path
% addpath('/Users/bartels-rausch/SwitchDrive/PSI_Matlab/Add-Ons');
% addpath('/Users/bartels-rausch/SwitchDrive/PSI_Matlab/nappIce');
% end
%
% % Color maps
% myColorMap.red = colormap(autumn(7));
% myColorMap.blue = colormap(winter(7));
%
% % define PSI cooperate identity colours
% PsiFarbe.hellgrau = [226 226 226]/255;
% PsiFarbe.mittelgrau = [184 184 184]/255;
% PsiFarbe.dunkelgrau = [78 78 77]/255;
% PsiFarbe.blaugrau = [236 236 243]/255; % This is actually not a PSI colour
% PsiFarbe.gelb = [239 200 37]/255;
% PsiFarbe.hellorange = [227 164 31]/255;
% PsiFarbe.dunkelorange = [207 92 22]/255;
% PsiFarbe.hellrot = [164 36 23]/255;
% PsiFarbe.dunkelbraun = [114 85 65]/255;
% PsiFarbe.hellbraun = [127 119 47]/255;
% PsiFarbe.mittelgruen = [135 150 59]/255;
% PsiFarbe.hellgruen = [195 214 47]/255;
% PsiFarbe.dunkelgruen = [72 130 33]/255;
% PsiFarbe.dunkelrot = [104 47 86]/255;
% PsiFarbe.dunkelblau = [37 65 108]/255;
% PsiFarbe.mittelgruenblau = [61 164 168]/255;
% PsiFarbe.hellblau = [58 162 190]/255;
% PsiFarbe.mittelblau = [50 118 158]/255;
%
% end
%%
% The path might be different
% on your computer depending how you have set up SwitchDrive:
%
%%
%
% addpath('C:\Users\bletry_c\switchdrive\PSI_Matlab\nappIce');
% addpath('C:\Users\bletry_c\switchdrive\PSI_Matlab\Add-Ons');
%
%%
% then run the initialiseMatlab function:
%%
% clearvars
% [myColorMap, PsiFarbe] = initializeMatlab;
% close all
% clc
%% Prepare: ISS data structure and path to local copy of ISS data
%
% Data needs to be organised in beam time folders that can be located on the
% Napp drive or locally on your computer. The data folder naming and
% structure within the beam time folder (orange on figure) is strict and
% there must not be any subfolders in the data folders:
%
% <html>
% <img src="../Bildschirmfoto 2022-03-23 um 08.19.22.png" width="400">
% </html>
%%
% * NEXAFS holds *.h5 XAS data
% * Photos holds *.bmp pictures
% * Pressure holds the *.dat LabView files
% * SES holds the *.ibw PE data.
% * To run the scripts, there *needs to be at
% least ONE *.ibw file in the SES folder*
%
%
%
% *beam time folder location*
%
% * The beam time folder can be a subfolder of any number of folders.
% * The beam time folder needs to have the same name, same subfolders, and
% folders above (path) locally and on the NAPP drive. This can be set by
% the user when calling the import function. As standard, we use
% "year:YYYY_MM__monthIssIceNapp"
% * on Napp drive: the beam time folder (and folders above) needs to be
% within the "SC Data" folder
% * locally: the beam time folder (and folders above) needs to be within
% your "MATLAB home folder:NAPP:SC Data" folder
%
%
% The see all import options (few examples given below) check out the
% nappFileList.m help (this works for all nappIce functions):
%%
%
% help nappFileList.m
%
%% Helper functions
%
% * Napp_p_ice(T_current) states and plots the vapour pressure of ice between 200-270 K
% * Napp_p_RH(T_current,RH) calculates the partial pressure of water for a given
% temperature and relative humidity.
% * Napp_RH_p(T_current,partial_pressure_water) calculates the relative humidity for a given
% temperature and water pressure.
%% Import ISS data: Complete beam time folder
%
%%
%
% FileList = nappFileList('2022/2022_02__FebIssIceNapp');
%
%%
% This will create a new data table "FileList" overwriting any previous
% versions of this list with data imported from the local copy of the beam
% time folder with the name "2022_02__FebIssIceNapp" being a subfolder of
% the folder "2022".
%%
clearvars
%%
[myColorMap, PsiFarbe] = initializeMatlab;
close all
clc
%%
if isfile('nappIceHowToData.mat')
load('nappIceHowToData.mat')
disp('data read from mat file')
else
FileList = nappFileList('2022/2022_02__FebIssIceNapp');
% add photon energy to table
FileList = addPhotonEnergy(FileList,[1,8:12,26],1000,2,2022);
FileList = addPhotonEnergy(FileList,[2:3,5,7,13:14,16:18,20:25,27:31,33:35,37:38,40,42,44,46,47,49:51,54:56,60:62,65:66,68,70,73,74,76,77,82],900,2,2022);
FileList = addPhotonEnergy(FileList,[4,6,15,19,58,59,64,67,72,80,81],650,2,2022);
FileList = addPhotonEnergy(FileList,[32,36,39,41,43,45,48,57,63,69,71,75,78,83],1150,2,2022);
FileList = addPhotonEnergy(FileList,79,NaN,2,2022);
% add sample description
FileList = addSampleNotes(FileList,[1,8:11],'Sample holder',2,2022);
FileList = addSampleNotes(FileList,[2:7,35:36,56:60],'Ice with N2',2,2022);
FileList = addSampleNotes(FileList,[12:34,54:55],'Ice',2,2022);
FileList = addSampleNotes(FileList,[16,20],'Ice (bad data)',2,2022);
FileList = addSampleNotes(FileList,[37:51,61:72],'Ice with N2 and phenol in Ar',2,2022);
FileList = addSampleNotes(FileList,44,'Ice with N2 and phenol in Ar (bad data)',2,2022);
FileList = addSampleNotes(FileList,73:76,'H2O gas-phase',2,2022);
FileList = addSampleNotes(FileList,73,'H2O gas-phase (bad data)',2,2022);
FileList = addSampleNotes(FileList,77:83,'CO2 gas-phase',2,2022);
FileList = addSampleNotes(FileList,79,'CO2 gas-phase (bad data)',2,2022);
% import data and add to data table
FileList = nappFileList('2021/2021_10__OctIssIceNapp',FileList);
FileList = nappFileList('2021/2021_08__AugIssIceNapp',FileList);
% add photon energy to table
FileList = addPhotonEnergy(FileList,1:10,1000,8,2021);
FileList = addPhotonEnergy(FileList,36:42,1000,8,2021);
FileList = addPhotonEnergy(FileList,51:72,1000,8,2021);
FileList = addPhotonEnergy(FileList,78:120,1000,8,2021);
FileList = addPhotonEnergy(FileList,1:6,1000,10,2021);
FileList = addPhotonEnergy(FileList,8,500,10,2021);
FileList = addPhotonEnergy(FileList,10,750,10,2021);
FileList = addPhotonEnergy(FileList,13,500,10,2021);
FileList = addPhotonEnergy(FileList,16,500,10,2021);
FileList = addPhotonEnergy(FileList,17,750,10,2021);
FileList = addPhotonEnergy(FileList,18:20,500,10,2021);
FileList = addPhotonEnergy(FileList,21,750,10,2021);
FileList = addPhotonEnergy(FileList,23,500,10,2021);
FileList = addPhotonEnergy(FileList,26,600,10,2021);
FileList = addPhotonEnergy(FileList,27,850,10,2021);
FileList = addPhotonEnergy(FileList,28:31,600,10,2021);
FileList = addPhotonEnergy(FileList,32:51,1000,10,2021);
FileList = addPhotonEnergy(FileList,53:68,1000,10,2021);
FileList = addPhotonEnergy(FileList,[74,76:85,87:91,93:94],1000,10,2021);
% add sample description
FileList = addSampleNotes(FileList,1:10,'MgO in N2',8,2021);
FileList = addSampleNotes(FileList,36:39,'MgO in H2O',8,2021);
FileList = addSampleNotes(FileList,40:44,'MgO in N2',8,2021);
FileList = addSampleNotes(FileList,45:49,'MgO in Ar',8,2021);
FileList = addSampleNotes(FileList,[51,53:55],'MgO in UHV',8,2021);
FileList = addSampleNotes(FileList,56:60,'MgO ice (bad data)',8,2021);
FileList = addSampleNotes(FileList,[61,66:72],'MgO ice in Ar HONO',8,2021);
FileList = addSampleNotes(FileList,61,'MgO ice in Ar HONO (bad data)',8,2021);
FileList = addSampleNotes(FileList,[68,69,70, 72],'MgO ice in Ar HONO on(bad data)',8,2021);
FileList = addSampleNotes(FileList,78:80,'MgO in UHV',8,2021);
FileList = addSampleNotes(FileList,81:82,'MgO in H2O',8,2021);
FileList = addSampleNotes(FileList,83:85,'MgO ice',8,2021);
FileList = addSampleNotes(FileList,86:94,'MgO ice AA in Ar',8,2021);
FileList = addSampleNotes(FileList,[86 88],'MgO ice AA in Ar (bad data)',8,2021); % temporarily, Ar very dominating
FileList = addSampleNotes(FileList,89,'MgO ice AA in Ar (bad data)',8,2021);
FileList = addSampleNotes(FileList,98,'Ar',8,2021);
FileList = addSampleNotes(FileList,99,'SiO2 in H2O',8,2021);
FileList = addSampleNotes(FileList,100:103,'SiO2 ice',8,2021);
FileList = addSampleNotes(FileList,104:110,'SiO2 ice AA in Ar',8,2021);
FileList = addSampleNotes(FileList,111:112,'SiO2 ice',8,2021);
FileList = addSampleNotes(FileList,113:118,'SiO2 ice AA in Ar',8,2021);
FileList = addSampleNotes(FileList,119:120,'CO2',8,2021);
FileList = addSampleNotes(FileList,1,'MgO in N2',10,2021);
FileList = addSampleNotes(FileList,2,'MgO in N2, PE 50, Slits 1/1/1',10,2021);
FileList = addSampleNotes(FileList,3,'MgO in N2, PE 50, Slits 1/1/1',10,2021);
FileList = addSampleNotes(FileList,5,'MgO in N2, PE 50, Slits 1/0.5/0.5',10,2021);
FileList = addSampleNotes(FileList,6,'MgO in N2, PE 50, Slits 1/1/1',10,2021);
FileList = addSampleNotes(FileList,8,'MgO in N2, PE 20, Slits 1/1/1',10,2021);
FileList = addSampleNotes(FileList,10,'MgO in N2, PE 20, Slits 1/1/1',10,2021);
FileList = addSampleNotes(FileList,13,'MgO in N2, PE 20, Slits 1/1/1',10,2021);
FileList = addSampleNotes(FileList,16,'MgO in N2, PE 20, Slits 1/0.8/0.8',10,2021);
FileList = addSampleNotes(FileList,18,'MgO in N2, PE 20, Slits 1/0.8/0.8',10,2021);
FileList = addSampleNotes(FileList,19,'MgO in N2, PE 20, Slits 0.5/1/1',10,2021);
FileList = addSampleNotes(FileList,20,'MgO in N2, PE 20, Slits 0.5/1/1',10,2021);
FileList = addSampleNotes(FileList,21,'MgO in N2, PE 20, Slits 0.5/1/1',10,2021);
FileList = addSampleNotes(FileList,23,'MgO in N2, PE 20, Slits 0.5/1/1',10,2021);
FileList = addSampleNotes(FileList,26,'MgO in N2, PE 50, Slits 0.5/1/1',10,2021);
FileList = addSampleNotes(FileList,27,'MgO in N2, PE 20, Slits 0.5/1/1',10,2021);
FileList = addSampleNotes(FileList,28,'MgO in N2, PE 50, Slits 0.5/0.5/0.5',10,2021);
FileList = addSampleNotes(FileList,29,'MgO in N2, PE 50, Slits 1/1/1',10,2021);
FileList = addSampleNotes(FileList,31,'MgO in N2, PE 20, Slits 1/1/1',10,2021);
FileList = addSampleNotes(FileList,32:33,'MgO in N2',10,2021);
FileList = addSampleNotes(FileList,34:36,'MgO ice',10,2021);
FileList = addSampleNotes(FileList,37:41,'MgO in H2O',10,2021);
FileList = addSampleNotes(FileList,42:51,'MgO ice',10,2021);
FileList = addSampleNotes(FileList,45,'MgO ice (bad data)',10,2021);
FileList = addSampleNotes(FileList,[53:68,70:71],'MgO ice AA in N2' ,10,2021);
FileList = addSampleNotes(FileList,54,'MgO ice AA in N2 (bad data)' ,10,2021);
FileList = addSampleNotes(FileList,68,'MgO ice AA in N2 (bad data)' ,10,2021);
FileList = addSampleNotes(FileList,63,'MgO ice AA in N2 (bad data)' ,10,2021);
FileList = addSampleNotes(FileList, [72,74],'MgO in H2O' ,10,2021);
FileList = addSampleNotes(FileList, [76,78:80],'MgO in N2 AA plus H2O' ,10,2021);
FileList = addSampleNotes(FileList,81:82,'SiO2 in N2',10,2021);
FileList = addSampleNotes(FileList,83:85,'SiO2 ice',10,2021);
FileList = addSampleNotes(FileList,87:90,'SiO2 in H2O',10,2021);
FileList = addSampleNotes(FileList,91,'SiO2 AA in N2',10,2021);
FileList = addSampleNotes(FileList,93:94,'SiO2 in H2O AA',10,2021);
% import
FileList = nappFileList('2020/202008AugustISS',FileList);
FileList = addSampleNotes(FileList,3,'diode upstream',8,2020);
FileList = addSampleNotes(FileList,4,'diode in-cell',8,2020);
FileList = addSampleNotes(FileList,8,'diode upstream',8,2020);
FileList = addSampleNotes(FileList,9,'diode in-cell',8,2020);
FileList = addSampleNotes(FileList,10,'diode in-cell',8,2020);
FileList = addSampleNotes(FileList,11,'diode upstream',8,2020);
FileList = addSampleNotes(FileList,13:23,'O_K-edge ice',8,2020);
FileList = addSampleNotes(FileList,13:18,'O_K-edge ice (bad S/N)',8,2020);
FileList = addSampleNotes(FileList,[15,19,20],'O_K-edge ice (no notes)',8,2020);
%ListNexafs = addSampleNotes(ListNexafs,21:23,'O_K-edge ice (ice unstable)',8,2020);
FileList = addSampleNotes(FileList,24,'diode (no notes)',8,2020);
FileList = addSampleNotes(FileList,25,'diode upstream',8,2020);
FileList = addSampleNotes(FileList,[26,28,30],'O_K-edge gold',8,2020);
FileList = addSampleNotes(FileList,[27,29,31],'O_K-edge gold (no notes)',8,2020);
FileList = addSampleNotes(FileList,[32,33],'(no notes)',8,2020);
FileList = addSampleNotes(FileList,[34,35,37,38],'diode in-cell',8,2020);
FileList = addSampleNotes(FileList,[36,39:42],'diode upstream',8,2020);
FileList = addSampleNotes(FileList,43:45,'O_K-edge gold',8,2020);
FileList = addSampleNotes(FileList,[48,50],'diode upstream',8,2020);
FileList = addSampleNotes(FileList,[49,51,54],'(no notes)',8,2020);
FileList = addSampleNotes(FileList,[43:45,52,53,55:59],'O_K-edge gold',8,2020);
FileList = addSampleNotes(FileList,53,'O_K-edge gas-phase (interference)',8,2020);
FileList = addSampleNotes(FileList,54,'O_K-edge (no data)',8,2020);
FileList = addSampleNotes(FileList,55,'O_K-edge gas-phase',8,2020);
FileList = addSampleNotes(FileList,60,'diode upstream',8,2020);
FileList = addSampleNotes(FileList,[61,63],'O_K-edge ice',8,2020);
% ListNexafs = addSampleNotes(ListNexafs,61,'O_K-edge ice (ice unstable)',8,2020);
FileList = addSampleNotes(FileList,62,'O_K-edge ice (no notes)',8,2020);
FileList = addSampleNotes(FileList,64,'diode upstream',8,2020);
FileList = addSampleNotes(FileList,65,'diode in-cell',8,2020);
FileList = addSampleNotes(FileList,66,'diode in-cell',8,2020);
save('nappIceHowToData.mat','FileList');
end
%% Import ISS data: Error messages
%
% If you get a message like this in the command window
%
% There appears to be no file in the SES folder. Add at least one file first.
% I quit now
%
%%
% and MATLAB quits running the script, please check that there is at least
% a *.ibw file in the SES folder
%%
% If you instead get a message like this
%
% There is something wrong with the path. Check for typo and that the drives are mounted
% I quit now
%
%%
% and MATLAB quits running the script, please check
%
% * that there are no typos in the path names
% * that the drives are mounted.
%% Import ISS data: Add data to existing data table
%
% This will import data from the beam time folder
% "2021/2021_08__AugIssIceNapp" on the NAPP drive adding the data to the data table
% "FileList" in the MATLAB workspace
%%
% FileList = nappFileList('2021/2021_08__AugIssIceNapp',FileList,'mode','nappDrive');
%% Import ISS data: Add new SES or NEXAFS files from local beam time folder
%
% Using the mode 'localNew' the content of the beam time folder will be
% compared to that of the FileList in the workspace and only those files
% not yet imported will be processed. This is a little faster and preserves
% any changes to the FileList. *To prevent data failure of running SES
% measurements, this only works on the local copy of the beam time folder*
%%
%
% FileList = nappFileList('2022/2022_02__FebIssIceNapp',FileList,'mode','localNew');
%
%% Import ISS data: Choose files manually
%
% This will open a windows file explorer window where you can choose as
% many data files to be imported as you want. In this example, a new
% FileList is written, overwriting any previous versions in the workspace.
%%
%
% FileList = nappFileList('2022/2022_02__FebIssIceNapp','mode','nappDrivePick');
%
%
% <html>
% <img src="../Bildschirmfoto 2022-03-23 um 11.14.44.png" width="400">
% </html>
%% Work with data: Excel
%
% The nappFileList.m function also writes a csv file to the beam time
% folder. Open it as xlsx and use Excels formatting and filtering tools to
% work with your data set. So, the xlsx file is edited manually and might
% contain additional information that you have added such as slit settings,
% comments, type of sample, scope of the measurement, etc. The csv file it
% automatically generated and might thus be frequently be over-written. Use
% copy/paste to update the xlsx file with new data, formatting will be
% automatically applied to new data then.
%%
%
%
% <html>
% <img src="../Bildschirmfoto 2019-05-08 um 09.58.47.png" width="800">
% </html>
%% Work with data: Add photon energy to table (XPS)
%
% ISS beamline does not log settings of SES data. Photon energy, which is
% needed to calculate the binding energy later, needs to be added manually.
% This will read the FileList table and add the photon energy "1000" to the
% SES data with file numbers 1,8 to 12, and 26 acquired in February (month
% "2") of the year "2022"). Note, this is only adding to XPS data, NEXAFS
% data are not touched:
%%
%
% FileList = addPhotonEnergy(FileList,[1,8:12,26],1000,2,2022);
%
%% Work with data: Add sample description
%
% Sample description to label figures and for filtering data can be added.
% It does not make sense to use temperature or pressure, as these data are
% written to the table anyway. It does make sense to use standard phrases
% to enable filtering all beam time data. This code example follow the same
% input structure as the addPhotonEnergy function. This function works on
% both NEXAFS and XPS data. One may limit and select either one
% specifically by adding either 'NEXAFS' or 'XPS' strings as last input
% parameter. This is optional, if not specified function runs on both data
% types:
%%
%
% FileList = addSampleNotes(FileList,[1,8:11],'Sample holder',2,2022,'XPS');
% FileList = addSampleNotes(FileList,[1,8:11],'Sample holder',2,2022,'NEXAFS');
% FileList = addSampleNotes(FileList,[2:7,35:36,56:60],'Ice with N2',2,2022);
% FileList = addSampleNotes(FileList,73:76,'H2O gas-phase',2,2022);
% FileList = addSampleNotes(FileList,73,'H2O gas-phase (bad data)',2,2022);
%% Work with data: Filter table
%
% An advantage of the data table is filtering. This works with standard
% MATLAB functions using logical operations. Main motivation of filtering
% is to work with selected subset of data which for example can be
% processed with the same settings, fitted with the same constrains, or
% shall be plotted in one graph for comparison.
%
% Further, the _InputTable_ may hold different data types such as XPS data,
% NEXAFS, and pictures. Mostly, the functions require one and the same data
% type as input. Therefore, *the _InputTable_ needs to be filtered when
% passed to most functions*. Exceptions from this are the
% |nappGenerateSpectra| and |nappPlot| functions that can be called with
% some limitations in the settings with mixed data as input (including
% pictures, that are ignored).
%
% The first example filter CO2 gas-phase C1s PE data that is not "(bad
% data)" and has a pass energy of 50 eV. In the second example, we pick a
% C1s or O1s PE data from the SES file #77 from February 2022. Any table
% column can be used for filtering. "&" means AND "|" is OR.
%
%%
% tmpDataSelection1 = matches(FileList.sample,'CO2 gas-phase') ...
% & ~contains(FileList.sample,'(bad data)')...
% & contains(FileList.name,'C1s')...
% & FileList.scientaPassEnergy_eV == 50 ;
%
% tmpDataSelection2 = (contains(FileList.name,'077_C1s') | contains(FileList.name,'077_O1s')) ...
% (month(FileList.lastModifiedDatenum) == 2) &...
% (year(FileList.lastModifiedDatenum) == 2022);
%%
tmpDataSelection1 = matches(FileList.sample,'CO2 gas-phase') ...
& ~contains(FileList.sample,'(bad data)')...
& contains(FileList.name,'C1s')...
& FileList.scientaPassEnergy_eV == 50 ;
tmpDataSelection2 = (contains(FileList.name,'077_C1s') | contains(FileList.name,'077_O1s'))& ...
(month(FileList.lastModifiedDatenum) == 2) &...
(year(FileList.lastModifiedDatenum) == 2022);
%% Work with data: Display filtered table and selected columns
%
% MATLAB tables allow to address the columns by name. To display only the
% rows that match the filter criteria and only specific columns, code like
% the examples below can be used:
%%
% disp(FileList(tmpDataSelection1,{'name','sample','xRayEkin_eV','scientaPassEnergy_eV','lastModifiedDatestr','sampleTemp_dC',...
% 'cellPressure_mbar' }))
% disp(FileList(tmpDataSelection2,{'name','scientaLensMode','xRayEkinRange_eV','scientaPassEnergy_eV'}))
%%
disp(FileList(tmpDataSelection1,{'name','sample','xRayEkin_eV','scientaPassEnergy_eV','lastModifiedDatestr','sampleTemp_dC',...
'cellPressure_mbar' }))
disp(FileList(tmpDataSelection2,{'name','scientaLensMode','xRayEkinRange_eV','scientaPassEnergy_eV'}))
clearvars tmp*
%%
%
%% Work with data: Modify data in table
%
% There might be bad sweeps (sequence iterations) either with too low
% signal to noise or because some setting was changed during the run. These
% can be removed by directly addressing the data in the images. Same
% procedure, first the data (table row) is filtered, then the image
% modified for the selected data.
%
% *remove one sweep*
%%
%
% tmpDataSelection = contains(FileList.name,'077_C1s')& ...
% (month(FileList.lastModifiedDatenum) == 2) &...
% (year(FileList.lastModifiedDatenum) == 2022);
% FileList(tmpDataSelection,:).image{:}(:,3)=[];
%
% tmpDataSelection = contains(FileList.name,'077_O1s')& ...
% (month(FileList.lastModifiedDatenum) == 2) &...
% (year(FileList.lastModifiedDatenum) == 2022);
% FileList(tmpDataSelection,:).image{:}(:,3)=[];
%
%%
% *remove several sweeps*
%
%%
%
% tmpDataSelection = contains(FileList.name,'059_C1s')& ...
% (month(FileList.lastModifiedDatenum) == 10) &...
% (year(FileList.lastModifiedDatenum) == 2021);
% FileList(tmpDataSelection,:).image{:}(:,5:15)=[];
%%
% *remove all data (complete table rows) outside a specific time window*
%
%%
% tmpTime.start = datenum('30-Apr-2019 02:00:00');
% tmpTime.end = datenum('30-Apr-2019 05:00:00');
% toDelete = Table_FileList.datenum <= tmpTime.start;
% Table_FileList(toDelete,:) = [];
% toDelete = Table_FileList.datenum >= tmpTime.end;
% Table_FileList(toDelete,:) = [];
%%
% *Correct beam line-offset in data*
%
% This will correct 1.6 from the X-ray energies, of particular importance
% for NEXAFS data. One can also do this on selected data.
%%
% beamlineOffset = 1.6;
% FileList.xRayEkin_eV = cellfun(@(x) x+beamlineOffset,FileList.xRayEkin_eV,'UniformOutput',false);
%% Add data (columns) to table
%
% Calculation results for each row can be added to data tables using
% standard Matlab functions. This example illustrates the use of
% anonymous functions, their call for each row using |cellfun|, and
% the generation of additional columns to which (selection of) the data are
% written.
%%
%
% fun1 =@(c) interp1(IzeroAugInCell(:,1),IzeroAugInCell(:,2), c);
% fun2 =@(c) interp1(IzeroAugInCell(:,1),IzeroAugInCell(:,3), c);
% tmpMatch = (month(ListNexafs.lastModifiedDatenum) == 8) &...
% (year(ListNexafs.lastModifiedDatenum) == 2020) |...
% (startsWith(ListNexafs.name, 'sum_Aug'));
% ListNexafs.uhvI0(tmpMatch) = cellfun(fun1, ListNexafs.xRayEkin_eV(tmpMatch) ,'uni' , 0);
% ListNexafs.uhvI0std(tmpMatch) = cellfun(fun2, ListNexafs.xRayEkin_eV(tmpMatch) ,'uni' , 0);
% clearvars tmp* fun*
%% Plot data: XPS images
%
% We use the nappPlot function to plot the images. For this, we specify
% the column of the data table that should be plotted:
% 'tableVarialbe','image' plots the image for all data in FileList that are
% selected by the logical array tmpDataSelection (See _Filtering table_
% above).
%%
%
% nappPlot(FileList,tmpDataSelection,'tableVariable','image');
%
%%
close all
tmpDataSelection = contains(FileList.name,'035_O1s') & FileList.xRayEkinRange_eV(:,1) == 900 ...
& FileList.scientaPassEnergy_eV == 50 ...
& (month(FileList.lastModifiedDatenum) == 2) ...
& (year(FileList.lastModifiedDatenum) == 2022) ...
& (day(FileList.lastModifiedDatenum) >= 27);
nappPlot(FileList,tmpDataSelection,'tableVariable','image');
%% Plot data: XPS and NEXAFS images
%
% This example filters for a XPS file name and a NEXAFS file name and shows
% two things. First, that the XPS file name is not unique and filtering
% thus needs to be combined with extra parameters such as date and second
% how NEXAS and XPS data can be simultaneously passed to the |nappPlot|
% function
%%
% tmpDataSelection = matches(FileList.name,'0067067_O1s_1000eV.ibw') | matches(FileList.name, '0063_20200824_042852_O_K_edge.h5');
% nappPlot(FileList,tmpDataSelection);
%%
tmpDataSelection = matches(FileList.name,'0067067_O1s_1000eV.ibw') | matches(FileList.name, '0063_20200824_042852_O_K_edge.h5');
nappPlot(FileList,tmpDataSelection);
%% Plot data: XPS spectra
%
% We use the nappPlot function to plot the spectra by selecting
% 'spectrum_countsPerSecond' as 'tableVariable'. Further options include
% the binding or kinetic energy scale, and each spectrum in a separate
% window, or all in one window by setting the 'mode'. This works, of
% course, only after the spectrum has been generated using the function
% nappGenerateSpectra.
%%
%
% nappPlot(FileList,tmpDataSelection,'tableVariable','spectrum_countsPerSecond',...
% 'mode','AllInOne','energyScale','kinetic');
%
%%
close all
tmpDataSelection = matches(FileList.sample,'Ice with N2')...
& ~contains(FileList.sample,'(bad data)')...
& contains(FileList.name,'O1s') & FileList.xRayEkinRange_eV(:,1) == 900 ...
& FileList.scientaPassEnergy_eV == 50 ...
& (month(FileList.lastModifiedDatenum) == 2) ...
& (year(FileList.lastModifiedDatenum) == 2022) ...
& (day(FileList.lastModifiedDatenum) >= 27);
FileList = nappGenerateSpectra(FileList,tmpDataSelection);
nappPlot(FileList,tmpDataSelection,'tableVariable','spectrum_countsPerSecond',...
'mode','AllInOne','energyScale','kinetic');
%% Plot data: NEXAFS spectra
%
% We use the same, one-and-only nappPlot function to plot the NEXAFS
% spectra by selecting 'spectrum_counts' as 'tableVariable' and
% 'energyScale' as 'xRay'. Further options include plotting each spectrum
% in a separate window, or all in one window by setting the 'mode'. This
% works, of course, only after the spectrum has been generated using the
% function nappGenerateSpectra.
%%
%
% nappPlot(FileList,tmpDataSelection,'tableVariable','spectrum_counts','energyScale','xRay','mode','OneEach')
%
%%
%
close all
clc
tmpDataSelection = contains(FileList.name, '0063_20200824_042852_O_K_edge');
% Sum Auger-Meitner Spectrum
FileList = nappGenerateSpectra(FileList,'tableSelection',tmpDataSelection,'mode','sum');
% Plot
nappPlot(FileList,tmpDataSelection,'tableVariable','spectrum_counts','energyScale','xRay','mode','OneEach');
%% Plot data: Figure layout
%
% The |nappPlot| function has 3 pre-defined figure layouts optimised for
% the computer screen, for powerpoint presentation or for word (and other
% text) files:
%%
%
% nappPlot(FileList,tmpDataSelection,'tableVariable','spectrum_counts','energyScale','xRay','mode','OneEach','figureMode','screen');
%
%%
close all
clc
tmpDataSelection = contains(FileList.name, '0063_20200824_042852_O_K_edge');
% Sum Auger-Meitner Spectrum
FileList = nappGenerateSpectra(FileList,'tableSelection',tmpDataSelection,'mode','sum');
% Plot
nappPlot(FileList,tmpDataSelection,'tableVariable','spectrum_counts','energyScale','xRay','mode','OneEach','figureMode','screen');
%%
%
% nappPlot(FileList,tmpDataSelection,'tableVariable','spectrum_counts','energyScale','xRay','mode','OneEach','figureMode','word');
%
%%
close all
clc
tmpDataSelection = contains(FileList.name, '0063_20200824_042852_O_K_edge');
% Sum Auger-Meitner Spectrum
FileList = nappGenerateSpectra(FileList,'tableSelection',tmpDataSelection,'mode','sum');
% Plot
nappPlot(FileList,tmpDataSelection,'tableVariable','spectrum_counts','energyScale','xRay','mode','OneEach','figureMode','word');
%%
%
% nappPlot(FileList,tmpDataSelection,'tableVariable','spectrum_counts','energyScale','xRay','mode','OneEach','figureMode','powerpoint');
%
%%
close all
clc
tmpDataSelection = contains(FileList.name, '0063_20200824_042852_O_K_edge');
% Sum Auger-Meitner Spectrum
FileList = nappGenerateSpectra(FileList,'tableSelection',tmpDataSelection,'mode','sum');
% Plot
nappPlot(FileList,tmpDataSelection,'tableVariable','spectrum_counts','energyScale','xRay','mode','OneEach','figureMode','powerpoint');
%% Plot data: Export the Figure (for use in powerpoint)
%
% Either, copy paste the figure, or use this command on the front most
% figure in Matlab:
%%
%
% set(gcf,'InvertHardcopy','on');
% print('NameForFigureFile, '-dpng', '-r220');
%
%% Plot data: Add region labels to survey
%
% Here is an example of how to mark regions of interest in survey plots.
% For this, a survey must be the topmost figure.
%%
% dataObjs = findobj(gcf,'-property','YData');
% tmpxShift = 5; % binding energy shift and mono offset
% tmpxRayEnergy = 900; % of this survey
% tmpyPosition = 0.5E5; % y position of labels, delta to signal height, in axis scale
% tmpyPositionTwo = 0.1E5; % optional, to shift neighouring labels up and dow
% % n
% % Au peaks
% nappAnnotateSurvey(tmpxRayEnergy-57-tmpxShift,tmpyPosition-tmpyPositionTwo,dataObjs(1),'Au5p3/2');
% nappAnnotateSurvey(tmpxRayEnergy-74-tmpxShift,tmpyPosition+tmpyPositionTwo,dataObjs(1),'Au5p5/2');
% nappAnnotateSurvey(tmpxRayEnergy-84-tmpxShift,tmpyPosition,dataObjs(1),'Au4f7/2');
% nappAnnotateSurvey(tmpxRayEnergy-88-tmpxShift,tmpyPosition-tmpyPositionTwo,dataObjs(1),'Au4f5/2');
% nappAnnotateSurvey(tmpxRayEnergy-107-tmpxShift,tmpyPosition,dataObjs(1),'Au5s');
% nappAnnotateSurvey(tmpxRayEnergy-335-tmpxShift,tmpyPosition+tmpyPositionTwo,dataObjs(1),'Au4d1/2');
% nappAnnotateSurvey(tmpxRayEnergy-353-tmpxShift,tmpyPosition,dataObjs(1),'Au4d3/2');
% nappAnnotateSurvey(tmpxRayEnergy-546-tmpxShift,tmpyPosition+tmpyPositionTwo,dataObjs(1),'Au4p3/2');
% nappAnnotateSurvey(tmpxRayEnergy-643-tmpxShift,tmpyPosition,dataObjs(1),'Au4p1/2');
% nappAnnotateSurvey(tmpxRayEnergy-762-tmpxShift,tmpyPosition+tmpyPositionTwo,dataObjs(1),'Au4s');
% nappAnnotateSurvey(tmpxRayEnergy-8-tmpxShift,tmpyPosition,dataObjs(1),'AuVB');
% % usual suspects
% nappAnnotateSurvey(tmpxRayEnergy-285-tmpxShift,tmpyPosition+tmpyPositionTwo,dataObjs(1),'C1s');
% nappAnnotateSurvey(tmpxRayEnergy-534-tmpxShift,tmpyPosition,dataObjs(1),'O1s');
% nappAnnotateSurvey(tmpxRayEnergy-30-tmpxShift,tmpyPosition+tmpyPositionTwo,dataObjs(1),'O2s');
% nappAnnotateSurvey(tmpxRayEnergy-405-tmpxShift,tmpyPosition+tmpyPositionTwo,dataObjs(1),'N1s');
% nappAnnotateSurvey(tmpxRayEnergy-495-tmpxShift,tmpyPosition,dataObjs(1),'Sn3d');
% nappAnnotateSurvey(tmpxRayEnergy-691-tmpxShift,tmpyPosition+tmpyPositionTwo,dataObjs(1),'F1s');
% nappAnnotateSurvey(tmpxRayEnergy-295-tmpxShift,tmpyPosition,dataObjs(1),'K2p');
% nappAnnotateSurvey(tmpxRayEnergy-380-tmpxShift,tmpyPosition+tmpyPositionTwo,dataObjs(1),'K2s');
% nappAnnotateSurvey(tmpxRayEnergy-153-tmpxShift,tmpyPosition,dataObjs(1),'Si2s');
% nappAnnotateSurvey(tmpxRayEnergy-100-tmpxShift,tmpyPosition+tmpyPositionTwo,dataObjs(1),'Si2p');
% nappAnnotateSurvey(tmpxRayEnergy-197-tmpxShift,tmpyPosition,dataObjs(1),'Cl2p');
% nappAnnotateSurvey(tmpxRayEnergy-286-tmpxShift,tmpyPosition-tmpyPositionTwo,dataObjs(1),'Sn3p');
% % Some Auger
% nappAnnotateSurvey(360-tmpxShift,tmpyPosition-tmpyPositionTwo,dataObjs(1),'N KLL');
% nappAnnotateSurvey(500-tmpxShift,tmpyPosition-tmpyPositionTwo,dataObjs(1),'O KLL');
% % tid up
% clearvars tmp*
%%
close all
tmpDataSelection = contains(FileList.name,'007_Survey');
FileList = nappGenerateSpectra(FileList,tmpDataSelection);
nappPlot(FileList,tmpDataSelection,'tableVariable','spectrum_countsPerSecond',...
'mode','AllInOne','energyScale','kinetic');
% add text to Figure
dataObjs = findobj(gcf,'-property','YData');
tmpxShift = 6;
tmpxRayEnergy = 900;
tmpyPosition = 0.5E5;
tmpyPositionTwo = 0.1E5;
% Au peaks
nappAnnotateSurvey(tmpxRayEnergy-57-tmpxShift,tmpyPosition-tmpyPositionTwo,dataObjs(1),'Au5p3/2');
nappAnnotateSurvey(tmpxRayEnergy-74-tmpxShift,tmpyPosition+tmpyPositionTwo,dataObjs(1),'Au5p5/2');
nappAnnotateSurvey(tmpxRayEnergy-84-tmpxShift,tmpyPosition,dataObjs(1),'Au4f7/2');
nappAnnotateSurvey(tmpxRayEnergy-88-tmpxShift,tmpyPosition-tmpyPositionTwo,dataObjs(1),'Au4f5/2');
nappAnnotateSurvey(tmpxRayEnergy-107-tmpxShift,tmpyPosition,dataObjs(1),'Au5s');
nappAnnotateSurvey(tmpxRayEnergy-335-tmpxShift,tmpyPosition+tmpyPositionTwo,dataObjs(1),'Au4d1/2');
nappAnnotateSurvey(tmpxRayEnergy-353-tmpxShift,tmpyPosition,dataObjs(1),'Au4d3/2');
nappAnnotateSurvey(tmpxRayEnergy-546-tmpxShift,tmpyPosition+tmpyPositionTwo,dataObjs(1),'Au4p3/2');
nappAnnotateSurvey(tmpxRayEnergy-643-tmpxShift,tmpyPosition,dataObjs(1),'Au4p1/2');
nappAnnotateSurvey(tmpxRayEnergy-762-tmpxShift,tmpyPosition+tmpyPositionTwo,dataObjs(1),'Au4s');
nappAnnotateSurvey(tmpxRayEnergy-8-tmpxShift,tmpyPosition,dataObjs(1),'AuVB');
% usual suspects
nappAnnotateSurvey(tmpxRayEnergy-285-tmpxShift,tmpyPosition+tmpyPositionTwo,dataObjs(1),'C1s');
nappAnnotateSurvey(tmpxRayEnergy-534-tmpxShift,tmpyPosition,dataObjs(1),'O1s');
nappAnnotateSurvey(tmpxRayEnergy-30-tmpxShift,tmpyPosition+tmpyPositionTwo,dataObjs(1),'O2s');
nappAnnotateSurvey(tmpxRayEnergy-405-tmpxShift,tmpyPosition+tmpyPositionTwo,dataObjs(1),'N1s');
nappAnnotateSurvey(tmpxRayEnergy-495-tmpxShift,tmpyPosition,dataObjs(1),'Sn3d');
nappAnnotateSurvey(tmpxRayEnergy-691-tmpxShift,tmpyPosition+tmpyPositionTwo,dataObjs(1),'F1s');
nappAnnotateSurvey(tmpxRayEnergy-295-tmpxShift,tmpyPosition,dataObjs(1),'K2p');
nappAnnotateSurvey(tmpxRayEnergy-380-tmpxShift,tmpyPosition+tmpyPositionTwo,dataObjs(1),'K2s');
nappAnnotateSurvey(tmpxRayEnergy-153-tmpxShift,tmpyPosition,dataObjs(1),'Si2s');
nappAnnotateSurvey(tmpxRayEnergy-100-tmpxShift,tmpyPosition+tmpyPositionTwo,dataObjs(1),'Si2p');
nappAnnotateSurvey(tmpxRayEnergy-197-tmpxShift,tmpyPosition,dataObjs(1),'Cl2p');
nappAnnotateSurvey(tmpxRayEnergy-286-tmpxShift,tmpyPosition-tmpyPositionTwo,dataObjs(1),'Sn3p');
% Some Auger
nappAnnotateSurvey(360-tmpxShift,tmpyPosition-tmpyPositionTwo,dataObjs(1),'N KLL');
nappAnnotateSurvey(500-tmpxShift,tmpyPosition-tmpyPositionTwo,dataObjs(1),'O KLL');
% tid up
clearvars tmp*
%% Process data: Align sequence iterations in images
%
% To shift and align the kinetic energy of each sequence iteration relative
% to each other, one can use
%
% # nappDetermineShiftXps: calculate the kinetic energy shift of each
% sequence iteration of an image relative to one sequence iteration (first
% is default)
% # nappCopyShift: optionally copy the kinetic energy shift to other data
% # nnappAlignImages: shift each sequence iterations of an image so that
% the peak maxima align.
%%
%
% % compile data
% tmpDataSelection = contains(FileList.name,'67_O1s') ...
% & (month(FileList.lastModifiedDatenum) == 8) ...
% & (year(FileList.lastModifiedDatenum) == 2021);
% % plot images
% nappPlot(FileList,tmpDataSelection,'tableVariable','image');
% % align images
% FileList = nappDetermineShiftXps(FileList,'tableSelection',tmpDataSelection,...
% 'showFigures','off','tableVariable','image');
% FileList = nappAlignImages(FileList,'tableSelection',tmpDataSelection,...
% 'tableVariable','image');
% % plot images
% nappPlot(FileList,tmpDataSelection,'tableVariable','image');
%%
close all
clc
% compile data
tmpDataSelection = contains(FileList.name,'67_O1s') ...
& (month(FileList.lastModifiedDatenum) == 8) ...
& (year(FileList.lastModifiedDatenum) == 2021);
% plot images
nappPlot(FileList,tmpDataSelection,'tableVariable','image');
% align images
FileList = nappDetermineShiftXps(FileList,'tableSelection',tmpDataSelection,...
'showFigures','off','tableVariable','image');
FileList = nappAlignImages(FileList,'tableSelection',tmpDataSelection,...
'tableVariable','image');
% plot images
nappPlot(FileList,tmpDataSelection,'tableVariable','image');
%% Process data: Generate XPS spectra
%
% All sequence iterations of an image are summed or the mean of all
% sequence iterations is calculated. The following command calculates the
% average of all sequence iterations from the filtered files in the
% FileList table. The spectrum based on the mean is saved in the column
% 'spectrum_countsPerSecond'.
%%
%
% FileList = nappGenerateSpectra(FileList,tmpDataSelection);
%
%% Process data: Generate NEXAFS spectra
%
% % All Auger spectra of an image are summed. Options include to sum the
% data with the energy interval of the aquisition, or to use the trapz
% function to normalise to 1 eV data spacing. The NEXAFS spectrua are
% always saved in the column 'spectrum_counts'.
%%
%
% FileList = nappGenerateSpectra(FileList,'tableSelection',tmpDataSelection,'mode','sum');
%
%%
close all
clc
tmpDataSelection = contains(FileList.name, '0063_20200824_042852_O_K_edge');
% Sum Auger-Meitner Spectrum
FileList = nappGenerateSpectra(FileList,'tableSelection',tmpDataSelection,'mode','sum');
% Plot
nappPlot(FileList,tmpDataSelection,'tableVariable','spectrum_counts','energyScale','xRay','mode','OneEach');
%%
%
% FileList = nappGenerateSpectra(FileList,tmpDataSelection);
%
%% Process data: Align XPS spectra to background
%
% To align the spectra to a background the function nappBacktround can
% be used. Options include to compute the mean or a linear regression.
% Here, we calculate the mean between 367 and 370 eV.
%%
%
% FileList = nappBackground(FileList,367,370,'tableSelection',tmpDataSelection,'...
% energyScale','kinetic','mode','mean');
%
%%
close all
clc
tmpDataSelection = matches(FileList.sample,'Ice with N2')...
& ~contains(FileList.sample,'(bad data)')...
& contains(FileList.name,'O1s') & FileList.xRayEkinRange_eV(:,1) == 900 ...
& FileList.scientaPassEnergy_eV == 50 ...
& (month(FileList.lastModifiedDatenum) == 2) ...
& (year(FileList.lastModifiedDatenum) == 2022) ...
& (day(FileList.lastModifiedDatenum) >= 27);
FileList = nappGenerateSpectra(FileList,tmpDataSelection);
FileList = nappBackground(FileList,367,370,'tableSelection',tmpDataSelection,'energyScale','kinetic',...
'mode','mean');
% plot spectra
nappPlot(FileList,tmpDataSelection,'tableVariable','spectrum_countsPerSecond',...
'mode','AllInOne','energyScale','kinetic');
%% Process data: Align NEXAFS spectra to background
%
% To align the spectra to a background the function nappBacktround can
% be used. Options include to compute the mean or a linear regression.
% Here, we calculate the mean between 522 and 525 eV xRay energy.
%%
%
% FileList = nappBackground(FileList,522,525,'tableSelection',tmpDataSelection,...
% 'tableVariable','spectrum_counts','energyScale','xRay','mode','mean');
%
%%
close all
clc
tmpDataSelection = contains(FileList.name, '0063_20200824_042852_O_K_edge');
% Sum Auger-Meitner Spectrum
FileList = nappGenerateSpectra(FileList,'tableSelection',tmpDataSelection,'mode','sum');
% Background
FileList = nappBackground(FileList,522,525,'tableSelection',tmpDataSelection,'tableVariable','spectrum_counts','energyScale','xRay',...
'mode','mean');
% Plot
nappPlot(FileList,tmpDataSelection,'tableVariable','spectrum_counts','energyScale','xRay','mode','OneEach');
%% Process data: Gauss peak fit
%
% Gauss fitting can be used to determine area, width, and position of PE
% peaks. nappFitGaussXps de-convolutes the PE signal using 4 features. The
% fits can be constrained by
%
% * 'widthPosition' (Default): With of all peaks is identical. Position of
% peaks 2-3 is set relative to peak 1.
% * 'position': Position of peaks 2-3 is set relative to peak 1.
% * 'width': all peaks have same width
% * 'unconstrained': Each gauss peak is fitted independent.
% * 'unconstrainedAndWidthPosition': One unconstrained peak #3 (for gas phase
% feature) and 4 peaks constrained in width and/or position
%
%
% The function needs fit parameters as input, such as min and max peak
% area, width, and position; initial values for fitting; and the spectrum
% range.
%
% * spectrum range: define the region of the PE spectrum used for fitting
% (plus and minus from peak 1 position).
% % position of peak 2-4 are relative to peak 1, that of peak 1 absolute
% (either in binding or kinetic energy scale)
% * If you are only interested in less than 4 peaks, choose small dummy
% constrains for those peaks you don't want to fit.
%
%%
% % initial fit parameters
% tmpFitParameters.peakArea = [1E4 5E3 0.1 0.1];
% tmpFitParameters.peakWidth = [2.0 2.0 0.1 0.1];
% tmpFitParameters.peakPos = [363 -1 -2 -3];
% % lower bonds
% tmpFitParameters.peakAreaLowerBond = [1E3 5E3 0.1 0.1];
% tmpFitParameters.peakWidthLowerBond = [2.0 2.0 0.1 0.1];
% tmpFitParameters.peakPosLowerBond = 361;
% % upper bonds
% tmpFitParameters.peakAreaUpperBond = [1E6 10E4 0.1 0.1];
% tmpFitParameters.peakWidthUpperBond = [3.0 2.0 0.1 0.1];
% tmpFitParameters.peakPosUpperBond = 365;
% % spectrum range
% tmpFitParameters.backgroundRange = [5 5];
%
% % „position“ mode
% tmpFitParameters.peakArea = [abs#1 abs#2 abs#3 abs#4];
% tmpFitParameters.peakWidth = [abs#1 abs#2 abs#3 abs#4];
% tmpFitParameters.peakPos = [abs#1 rel#2 rel#3 rel#4];
%
% tmpFitParameters.peakAreaUpperBond = [#1 #2 #3 #4];
% tmpFitParameters.peakWidthUpperBond = [#1 #2 #3 #4];
% tmpFitParameters.peakPosUpperBond = #1;
% tmpFitParameters.peakAreaLowerBond = [#1 #2 #3 #4];
% tmpFitParameters.peakWidthLowerBond = [#1 #2 #3 #4];
% tmpFitParameters.peakPosLowerBond = #1;
%
%
% % „unconstrained“ mode
% tmpFitParameters.peakArea = [abs#1 abs#2 abs#3 abs#4];
% tmpFitParameters.peakWidth = [abs#1 abs#2 abs#3 abs#4];
% tmpFitParameters.peakPos = [abs#1 abs#2 abs#3 abs#4];
%
% tmpFitParameters.peakAreaUpperBond = [#1 #2 #3 #4];
% tmpFitParameters.peakWidthUpperBond = [#1 #2 #3 #4];
% tmpFitParameters.peakPosUpperBond = [#1 #2 #3 #4];
% tmpFitParameters.peakAreaLowerBond = [#1 #2 #3 #4];
% tmpFitParameters.peakWidthLowerBond = [#1 #2 #3 #4];
% tmpFitParameters.peakPosLowerBond = [#1 #2 #3 #4];
%
%
% % „ widthPosition“ mode
% tmpFitParameters.peakArea = [abs#1 abs#2 abs#3 abs#4];
% tmpFitParameters.peakWidth = [abs#1-#4];
% tmpFitParameters.peakPos = [abs#1 rel#2 rel#3 rel#4];
%
% tmpFitParameters.peakAreaUpperBond = [#1 #2 #3 #4];
% tmpFitParameters.peakWidthUpperBond = #1-#4;
% tmpFitParameters.peakPosUpperBond = #1;
% tmpFitParameters.peakAreaLowerBond = [#1 #2 #3 #4];
% tmpFitParameters.peakWidthLowerBond = #1-#4;
% tmpFitParameters.peakPosLowerBond = #1;
%
% % „ width“ mode
% tmpFitParameters.peakArea = [abs#1 abs#2 abs#3 abs#4];
% tmpFitParameters.peakWidth = [abs#1-#4];
% tmpFitParameters.peakPos = [abs#1 abs#2 abs#3 abs#4];
%
% tmpFitParameters.peakAreaUpperBond = [#1 #2 #3 #4];
% tmpFitParameters.peakWidthUpperBond = #1-#4;
% tmpFitParameters.peakPosUpperBond = [#1 #2 #3 #4];
% tmpFitParameters.peakAreaLowerBond = [#1 #2 #3 #4];
% tmpFitParameters.peakWidthLowerBond = #1-#4;
% tmpFitParameters.peakPosLowerBond = [#1 #2 #3 #4];
%
%
% % „ unconstrainedAndWidthPosition" mode (novel: rel distance fit parameter)
% tmpFitParameters.peakArea = [abs#1 abs#2 abs#3 abs#4 abs#5];
% tmpFitParameters.peakWidth = [abs#1,2,4,5 abs#3];
% tmpFitParameters.peakPos = [rel#1 abs#2 abs#3 abs#4 abs#5];
%
% tmpFitParameters.peakAreaUpperBond = [#1 #2 #3 #4 #5];
% tmpFitParameters.peakWidthUpperBond = [#1,2,4,5 #3];
% tmpFitParameters.peakPosUpperBond = [#1 #2 #3 #4 #5];
% tmpFitParameters.peakAreaLowerBond = [#1 #2 #3 #4];
% tmpFitParameters.peakWidthLowerBond = [#1,2,4,5 #3];
% tmpFitParameters.peakPosLowerBond = [#1 #2 #3 #4];
%
%
% FileList = nappFitGaussXps(FileList,tmpDataSelection,tmpFitParameters,'tableSelection',tmpDataSelection,...
% 'energyScale','kinetic','mode','position','showFigures','on');
%%
% % The fit results are written to the data table. Peak position is only
% written to the table if in binding energy mode. Further, results are
% plotted to the command line and fits are shown in graphs:
%%
close all
tmpDataSelection = matches(FileList.sample,'Ice with N2')...
& ~contains(FileList.sample,'(bad data)')...
& contains(FileList.name,'O1s') & FileList.xRayEkinRange_eV(:,1) == 900 ...
& FileList.scientaPassEnergy_eV == 50 ...
& (month(FileList.lastModifiedDatenum) == 2) ...
& (year(FileList.lastModifiedDatenum) == 2022) ...
& (day(FileList.lastModifiedDatenum) >= 27);
FileList = nappBackground(FileList,367,370,'tableSelection',tmpDataSelection,'energyScale','kinetic',...
'mode','mean');
tmpFitParameters.peakArea = [1E4 5E3 0.1 0.1];
tmpFitParameters.peakWidth = [2.0 2.0 0.1 0.1];
tmpFitParameters.peakPos = [363 -1 -2 -3]; % position of peak 2-4 are relative to peak 1
tmpFitParameters.peakAreaLowerBond = [1E3 5E3 0.1 0.1];
tmpFitParameters.peakWidthLowerBond = [2.0 2.0 0.1 0.1];
tmpFitParameters.peakPosLowerBond = 361;
tmpFitParameters.peakAreaUpperBond = [1E6 10E4 0.1 0.1];
tmpFitParameters.peakWidthUpperBond = [3.0 2.0 0.1 0.1];
tmpFitParameters.peakPosUpperBond = 365;
tmpFitParameters.backgroundRange = [5 5];
FileList = nappFitGaussXps(FileList,tmpDataSelection,tmpFitParameters,'tableSelection',tmpDataSelection,...
'energyScale','kinetic','mode','position','showFigures','on');
%% Process data: Norm spectra
%
% To normalise spectra, nappScaleToArea can be used. A typical example is
% to normalise C1s to the O1s peak area to compensate for changes in the
% working distance. The function uses the peakArea table column, thus
% nappFitGaussXps needs to run first. Results are written to the table
% variable spectrum_countsNorm (as the unit is no longer countsPerSecond).
% To normalise C1s to the O1s peak area, select C1s spectra using a logical
% (tmpDataSelection), and choose C1s for regionOld and O1s for regionNew:
%
% * regionOld: C1s (default) or O1s - region that will be normalised
% * regionNew: O1s (default) or C1s - peak area that will be used to normalise
%
%%
%
% FileList = nappScale(FileList,tmpDataSelection,'regionOld','C1s','regionNew','O1s');
% nappPlot(FileList,tmpDataSelection,'tableVariable','spectrum_countsNorm');
%
%%
close all
clc
tmpDataSelection = matches(FileList.sample,'Ice with N2')...
& ~contains(FileList.sample,'(bad data)')...
& contains(FileList.name,'O1s') & FileList.xRayEkinRange_eV(:,1) == 900 ...
& FileList.scientaPassEnergy_eV == 50 ...
& (month(FileList.lastModifiedDatenum) == 2) ...
& (year(FileList.lastModifiedDatenum) == 2022) ...
& (day(FileList.lastModifiedDatenum) >= 27);
% plot spectra
nappPlot(FileList,tmpDataSelection,'tableVariable','spectrum_countsPerSecond',...
'mode','AllInOne','energyScale','kinetic');
% scale to area
FileList = nappScale(FileList,tmpDataSelection,'regionOld','O1s','regionNew','O1s');
FileList = nappBackground(FileList,367,370,'tableSelection',tmpDataSelection,'energyScale','kinetic',...
'mode','mean','tableVariable','spectrum_countsNorm');
% plot spectra
nappPlot(FileList,tmpDataSelection,'tableVariable','spectrum_countsNorm',...
'mode','AllInOne','energyScale','kinetic');
tmpDataSelection = matches(FileList.sample,'Ice with N2')...
& ~contains(FileList.sample,'(bad data)')...
& contains(FileList.name,'C1s') & FileList.xRayEkinRange_eV(:,1) == 900 ...
& FileList.scientaPassEnergy_eV == 50 ...
& (month(FileList.lastModifiedDatenum) == 2) ...
& (year(FileList.lastModifiedDatenum) == 2022) ...
& (day(FileList.lastModifiedDatenum) >= 27);
% Generate spectra
FileList = nappGenerateSpectra(FileList,tmpDataSelection);
% plot spectra
nappPlot(FileList,tmpDataSelection,'tableVariable','spectrum_countsPerSecond',...
'mode','AllInOne','energyScale','kinetic');
% scale to area
FileList = nappScale(FileList,tmpDataSelection,'regionOld','C1s','regionNew','O1s');
FileList = nappBackground(FileList,615,617,'tableSelection',tmpDataSelection,'energyScale','kinetic',...
'mode','mean','tableVariable','spectrum_countsNorm');
% plot spectra
nappPlot(FileList,tmpDataSelection,'tableVariable','spectrum_countsNorm');
%% Process data: Binding energy scale
%
% To calculate the binding energy, you need to
%
% # nappDetermineShiftXps: calculate the kinetic energy shift relative to a reference value
% # nappCopyShift: optionally copy the kinetic energy shift to other data
% # nappBindingEnergyXps: calculate the binding energy based on the kinetic
% energy shift either determined relative to a reference or copied to the
% individual data.
%
% The following example shows how the kinetic energy shift is calculated
% based on selected O1s spectra relative to 535 eV, copied to the C1s data
% with the same file number, and finally the binding energy of the C1s data is
% calculated (based on the observed shift of the O1s of the same sequence
% run) and plotted
%%
%
% close all
% % generate spectra for C1s and O1s
% tmpDataSelection = matches(FileList.sample,'Ice with N2')...
% & ~contains(FileList.sample,'(bad data)')...
% & (contains(FileList.name,'O1s') | contains(FileList.name,'C1s'))...
% & FileList.xRayEkinRange_eV(:,1) == 900 ...
% & FileList.scientaPassEnergy_eV == 50 ...
% & (month(FileList.lastModifiedDatenum) == 2) ...
% & (year(FileList.lastModifiedDatenum) == 2022) ...
% & (day(FileList.lastModifiedDatenum) >= 27);
% FileList = nappGenerateSpectra(FileList,tmpDataSelection);
% FileList = nappBackground(FileList,367,370,'tableSelection',tmpDataSelection,'energyScale','kinetic',...
% 'mode','mean');
% % determine shift of O1s
% tmpDataSelection = matches(FileList.sample,'Ice with N2')...
% & ~contains(FileList.sample,'(bad data)')...
% & contains(FileList.name,'O1s')...
% & FileList.xRayEkinRange_eV(:,1) == 900 ...
% & FileList.scientaPassEnergy_eV == 50 ...
% & (month(FileList.lastModifiedDatenum) == 2) ...
% & (year(FileList.lastModifiedDatenum) == 2022) ...
% & (day(FileList.lastModifiedDatenum) >= 27);
% FileList = nappDetermineShiftXps(FileList,'tableSelection',tmpDataSelection,...
% 'showFigures','off','tableVariable','spectrum_countsPerSecond','binEnReference',533);
% % copy shift from O1s to C1s
% FileList = nappCopyShift(FileList,tmpDataSelection,'energyScale','binding');
% % calculate binding energy of these C1s
% tmpDataSelection = matches(FileList.sample,'Ice with N2')...
% & ~contains(FileList.sample,'(bad data)')...
% & contains(FileList.name,'C1s') & FileList.xRayEkinRange_eV(:,1) == 900 ...
% & FileList.scientaPassEnergy_eV == 50 ...
% & (month(FileList.lastModifiedDatenum) == 2) ...
% & (year(FileList.lastModifiedDatenum) == 2022) ...
% & (day(FileList.lastModifiedDatenum) >= 27);
% FileList = nappBindingEnergyXps(FileList,'tableSelection',tmpDataSelection);
% % plot C1s spectra
% nappPlot(FileList,tmpDataSelection,'tableVariable','spectrum_countsPerSecond',...
% 'mode','AllInOne','energyScale','kinetic');
% nappPlot(FileList,tmpDataSelection,'tableVariable','spectrum_countsPerSecond',...
% 'mode','AllInOne','energyScale','binding');
%%
%
close all
tmpDataSelection = matches(FileList.sample,'Ice with N2')...
& ~contains(FileList.sample,'(bad data)')...
& (contains(FileList.name,'O1s') | contains(FileList.name,'C1s'))...
& FileList.xRayEkinRange_eV(:,1) == 900 ...
& FileList.scientaPassEnergy_eV == 50 ...
& (month(FileList.lastModifiedDatenum) == 2) ...
& (year(FileList.lastModifiedDatenum) == 2022) ...
& (day(FileList.lastModifiedDatenum) >= 27);
FileList = nappGenerateSpectra(FileList,tmpDataSelection);
FileList = nappBackground(FileList,367,370,'tableSelection',tmpDataSelection,'energyScale','kinetic',...
'mode','mean');
% determine shift of O1s
tmpDataSelection = matches(FileList.sample,'Ice with N2')...
& ~contains(FileList.sample,'(bad data)')...
& contains(FileList.name,'O1s')...
& FileList.xRayEkinRange_eV(:,1) == 900 ...
& FileList.scientaPassEnergy_eV == 50 ...
& (month(FileList.lastModifiedDatenum) == 2) ...
& (year(FileList.lastModifiedDatenum) == 2022) ...
& (day(FileList.lastModifiedDatenum) >= 27);
FileList = nappDetermineShiftXps(FileList,'tableSelection',tmpDataSelection,...
'showFigures','off','tableVariable','spectrum_countsPerSecond','binEnReference',533);
% copy shift from O1s to C1s
FileList = nappCopyShift(FileList,tmpDataSelection,'energyScale','binding');
% calculate binding energy of these C1s
tmpDataSelection = matches(FileList.sample,'Ice with N2')...
& ~contains(FileList.sample,'(bad data)')...
& contains(FileList.name,'C1s') & FileList.xRayEkinRange_eV(:,1) == 900 ...
& FileList.scientaPassEnergy_eV == 50 ...
& (month(FileList.lastModifiedDatenum) == 2) ...
& (year(FileList.lastModifiedDatenum) == 2022) ...
& (day(FileList.lastModifiedDatenum) >= 27);
FileList = nappBindingEnergyXps(FileList,'tableSelection',tmpDataSelection);
% plot C1s spectra
nappPlot(FileList,tmpDataSelection,'tableVariable','spectrum_countsPerSecond',...
'mode','AllInOne','energyScale','kinetic');
nappPlot(FileList,tmpDataSelection,'tableVariable','spectrum_countsPerSecond',...
'mode','AllInOne','energyScale','binding');
%% Process data: Combine spectra
%
% To get better statistics (signal-to-noise), repeated measurements can be
% added or averaged into one spectrum. The results are written into a
% matrix with energy in column 1, counts in column2, and standard deviation
% in column 3 (only for mean). So, the nappFunctions can no longer be used
% for this data format.
%%
%
% tmpDataSelection = contains(FileList.name,'C1s')...
% & contains(FileList.sample,'MgO ice AA')...
% & ~endsWith(FileList.sample,'(bad data)')...
% & FileList.sampleTemp_dC >= -26 & FileList.sampleTemp_dC <= -24;
% MgO_C1s_Warm = nappCombineSpectra(FileList,'tableRow',1,...
% 'tableSelection',tmpDataSelection,'tableVariable',...
% 'spectrum_countsPerSecond','EnergyScale','binding','mode','average');
%%
close all
tmpDataSelection = contains(FileList.name,'C1s')...
& contains(FileList.sample,'MgO ice AA')...
& ~endsWith(FileList.sample,'(bad data)')...
& FileList.sampleTemp_dC >= -26 & FileList.sampleTemp_dC <= -24;
FileList = nappGenerateSpectra(FileList,tmpDataSelection);
MgO_C1s_Warm = nappCombineSpectra(FileList,'tableRow',1,...
'tableSelection',tmpDataSelection,'tableVariable',...
'spectrum_countsPerSecond','EnergyScale','kinetic','mode','average');
figure
% axes('Parent',gcf,'XDir','reverse')
hold(gca,'on');
plot(MgO_C1s_Warm(:,1),MgO_C1s_Warm(:,2),'REPLACE_WITH_DASH_DASH','linewidth',2)
title('acetic acid adsorption')
legend({'ice on MgO, -25°C'},...
'location','SouthOutside','Orientation','horizontal')
xlim([704,714]);
xlabel('kinetic energy [eV]')
ylabel('PE [counts per second]')
%%
function [myColorMap, PsiFarbe] = initializeMatlab
%initializeMatlab Sets NappIce specific settings
% Adds Napp files to path and defines file locations for mac, windows,
% and Matlab online (which runs on unix)
% change working directory
path = matlab.desktop.editor.getActiveFilename;
[filepath,~,~] = fileparts(path);
cd(filepath);
% The fitting routines writes quite a lot of feedback and warnings. I shut them off.
warning('off','all')
warning off backtrace
warning off verbose
% Functions and helper files path:
if ismac
% add Napp files to path
addpath('/Users/bartels-rausch/SwitchDrive/PSI_Matlab/Add-Ons');
addpath('/Users/bartels-rausch/SwitchDrive/PSI_Matlab/nappIce');
elseif ispc
% add Napp files to path
addpath('/Users/bartels-rausch/SwitchDrive/PSI_Matlab/Add-Ons');
addpath('/Users/bartels-rausch/SwitchDrive/PSI_Matlab/nappIce');
elseif isunix
% add Napp files to path
addpath('/Users/bartels-rausch/SwitchDrive/PSI_Matlab/Add-Ons');
addpath('/Users/bartels-rausch/SwitchDrive/PSI_Matlab/nappIce');
end
% Color maps
myColorMap.red = colormap(autumn(7));
myColorMap.blue = colormap(winter(7));
% define PSI cooperate identity colours
PsiFarbe.hellgrau = [226 226 226]/255;
PsiFarbe.mittelgrau = [184 184 184]/255;
PsiFarbe.dunkelgrau = [78 78 77]/255;
PsiFarbe.blaugrau = [236 236 243]/255; % This is actually not a PSI colour
PsiFarbe.gelb = [239 200 37]/255;
PsiFarbe.hellorange = [227 164 31]/255;
PsiFarbe.dunkelorange = [207 92 22]/255;
PsiFarbe.hellrot = [164 36 23]/255;
PsiFarbe.dunkelbraun = [114 85 65]/255;
PsiFarbe.hellbraun = [127 119 47]/255;
PsiFarbe.mittelgruen = [135 150 59]/255;
PsiFarbe.hellgruen = [195 214 47]/255;
PsiFarbe.dunkelgruen = [72 130 33]/255;
PsiFarbe.dunkelrot = [104 47 86]/255;
PsiFarbe.dunkelblau = [37 65 108]/255;
PsiFarbe.mittelgruenblau = [61 164 168]/255;
PsiFarbe.hellblau = [58 162 190]/255;
PsiFarbe.mittelblau = [50 118 158]/255;
end
##### SOURCE END #####
--></body></html>