diff --git a/nappIce/HowTo/Bildschirmfoto 2019-05-08 um 09.58.47.png b/nappIce/HowTo/Bildschirmfoto 2019-05-08 um 09.58.47.png deleted file mode 100644 index 3d6e5c1..0000000 Binary files a/nappIce/HowTo/Bildschirmfoto 2019-05-08 um 09.58.47.png and /dev/null differ diff --git a/nappIce/HowTo/Bildschirmfoto 2022-03-23 um 08.19.22.png b/nappIce/HowTo/Bildschirmfoto 2022-03-23 um 08.19.22.png deleted file mode 100644 index 3074d2f..0000000 Binary files a/nappIce/HowTo/Bildschirmfoto 2022-03-23 um 08.19.22.png and /dev/null differ diff --git a/nappIce/HowTo/Bildschirmfoto 2022-03-23 um 11.14.44.png b/nappIce/HowTo/Bildschirmfoto 2022-03-23 um 11.14.44.png deleted file mode 100644 index 1f758f4..0000000 Binary files a/nappIce/HowTo/Bildschirmfoto 2022-03-23 um 11.14.44.png and /dev/null differ diff --git a/nappIce/HowTo/Bildschirmfoto 2022-03-24 um 07.17.54.png b/nappIce/HowTo/Bildschirmfoto 2022-03-24 um 07.17.54.png deleted file mode 100644 index 25c8400..0000000 Binary files a/nappIce/HowTo/Bildschirmfoto 2022-03-24 um 07.17.54.png and /dev/null differ diff --git a/nappIce/HowTo/TMpnappIceHowToData.mat b/nappIce/HowTo/TMpnappIceHowToData.mat deleted file mode 100644 index 0d7c7f2..0000000 Binary files a/nappIce/HowTo/TMpnappIceHowToData.mat and /dev/null differ diff --git a/nappIce/HowTo/html/nappIceHowTo.png b/nappIce/HowTo/html/nappIceHowTo.png deleted file mode 100644 index 716c41d..0000000 Binary files a/nappIce/HowTo/html/nappIceHowTo.png and /dev/null differ diff --git a/nappIce/HowTo/html/nappIceHowTo_01.png b/nappIce/HowTo/html/nappIceHowTo_01.png deleted file mode 100644 index aae7ef9..0000000 Binary files a/nappIce/HowTo/html/nappIceHowTo_01.png and /dev/null differ diff --git a/nappIce/HowTo/html/nappIceHowTo_02.png b/nappIce/HowTo/html/nappIceHowTo_02.png deleted file mode 100644 index 87ddf05..0000000 Binary files a/nappIce/HowTo/html/nappIceHowTo_02.png and /dev/null differ diff --git a/nappIce/HowTo/html/nappIceHowTo_03.png b/nappIce/HowTo/html/nappIceHowTo_03.png deleted file mode 100644 index 7717a0a..0000000 Binary files a/nappIce/HowTo/html/nappIceHowTo_03.png and /dev/null differ diff --git a/nappIce/HowTo/html/nappIceHowTo_04.png b/nappIce/HowTo/html/nappIceHowTo_04.png deleted file mode 100644 index e958e1e..0000000 Binary files a/nappIce/HowTo/html/nappIceHowTo_04.png and /dev/null differ diff --git a/nappIce/HowTo/html/nappIceHowTo_05.png b/nappIce/HowTo/html/nappIceHowTo_05.png deleted file mode 100644 index 0e7fbf7..0000000 Binary files a/nappIce/HowTo/html/nappIceHowTo_05.png and /dev/null differ diff --git a/nappIce/HowTo/html/nappIceHowTo_06.png b/nappIce/HowTo/html/nappIceHowTo_06.png deleted file mode 100644 index 8642173..0000000 Binary files a/nappIce/HowTo/html/nappIceHowTo_06.png and /dev/null differ diff --git a/nappIce/HowTo/html/nappIceHowTo_07.png b/nappIce/HowTo/html/nappIceHowTo_07.png deleted file mode 100644 index 768da42..0000000 Binary files a/nappIce/HowTo/html/nappIceHowTo_07.png and /dev/null differ diff --git a/nappIce/HowTo/html/nappIceHowTo_08.png b/nappIce/HowTo/html/nappIceHowTo_08.png deleted file mode 100644 index b6b9472..0000000 Binary files a/nappIce/HowTo/html/nappIceHowTo_08.png and /dev/null differ diff --git a/nappIce/HowTo/html/nappIceHowTo_09.png b/nappIce/HowTo/html/nappIceHowTo_09.png deleted file mode 100644 index 7fa7f79..0000000 Binary files a/nappIce/HowTo/html/nappIceHowTo_09.png and /dev/null differ diff --git a/nappIce/HowTo/html/nappIceHowTo_10.png b/nappIce/HowTo/html/nappIceHowTo_10.png deleted file mode 100644 index 82d840b..0000000 Binary files a/nappIce/HowTo/html/nappIceHowTo_10.png and /dev/null differ diff --git a/nappIce/HowTo/html/nappIceHowTo_11.png b/nappIce/HowTo/html/nappIceHowTo_11.png deleted file mode 100644 index 082ab08..0000000 Binary files a/nappIce/HowTo/html/nappIceHowTo_11.png and /dev/null differ diff --git a/nappIce/HowTo/html/nappIceHowTo_12.png b/nappIce/HowTo/html/nappIceHowTo_12.png deleted file mode 100644 index 6e3ed23..0000000 Binary files a/nappIce/HowTo/html/nappIceHowTo_12.png and /dev/null differ diff --git a/nappIce/HowTo/html/nappIceHowTo_13.png b/nappIce/HowTo/html/nappIceHowTo_13.png deleted file mode 100644 index 7a72875..0000000 Binary files a/nappIce/HowTo/html/nappIceHowTo_13.png and /dev/null differ diff --git a/nappIce/HowTo/html/nappIceHowTo_14.png b/nappIce/HowTo/html/nappIceHowTo_14.png deleted file mode 100644 index 8b88558..0000000 Binary files a/nappIce/HowTo/html/nappIceHowTo_14.png and /dev/null differ diff --git a/nappIce/HowTo/html/nappIceHowTo_15.png b/nappIce/HowTo/html/nappIceHowTo_15.png deleted file mode 100644 index 27263b5..0000000 Binary files a/nappIce/HowTo/html/nappIceHowTo_15.png and /dev/null differ diff --git a/nappIce/HowTo/html/nappIceHowTo_16.png b/nappIce/HowTo/html/nappIceHowTo_16.png deleted file mode 100644 index 861bbe2..0000000 Binary files a/nappIce/HowTo/html/nappIceHowTo_16.png and /dev/null differ diff --git a/nappIce/HowTo/html/nappIceHowTo_17.png b/nappIce/HowTo/html/nappIceHowTo_17.png deleted file mode 100644 index 68e0d2a..0000000 Binary files a/nappIce/HowTo/html/nappIceHowTo_17.png and /dev/null differ diff --git a/nappIce/HowTo/html/nappIceHowTo_18.png b/nappIce/HowTo/html/nappIceHowTo_18.png deleted file mode 100644 index 8cfc41d..0000000 Binary files a/nappIce/HowTo/html/nappIceHowTo_18.png and /dev/null differ diff --git a/nappIce/HowTo/html/nappIceHowTo_19.png b/nappIce/HowTo/html/nappIceHowTo_19.png deleted file mode 100644 index 3c8faa2..0000000 Binary files a/nappIce/HowTo/html/nappIceHowTo_19.png and /dev/null differ diff --git a/nappIce/HowTo/html/nappIceHowTo_20.png b/nappIce/HowTo/html/nappIceHowTo_20.png deleted file mode 100644 index 0e5a479..0000000 Binary files a/nappIce/HowTo/html/nappIceHowTo_20.png and /dev/null differ diff --git a/nappIce/HowTo/html/nappIceHowTo_21.png b/nappIce/HowTo/html/nappIceHowTo_21.png deleted file mode 100644 index b5bce3f..0000000 Binary files a/nappIce/HowTo/html/nappIceHowTo_21.png and /dev/null differ diff --git a/nappIce/HowTo/html/nappIceHowTo_22.png b/nappIce/HowTo/html/nappIceHowTo_22.png deleted file mode 100644 index 12631d9..0000000 Binary files a/nappIce/HowTo/html/nappIceHowTo_22.png and /dev/null differ diff --git a/nappIce/HowTo/html/nappIceHowTo_23.png b/nappIce/HowTo/html/nappIceHowTo_23.png deleted file mode 100644 index c832e64..0000000 Binary files a/nappIce/HowTo/html/nappIceHowTo_23.png and /dev/null differ diff --git a/nappIce/HowTo/html/nappIceHowTo_24.png b/nappIce/HowTo/html/nappIceHowTo_24.png deleted file mode 100644 index 24904e3..0000000 Binary files a/nappIce/HowTo/html/nappIceHowTo_24.png and /dev/null differ diff --git a/nappIce/HowTo/html/nappIceHowTo_25.png b/nappIce/HowTo/html/nappIceHowTo_25.png deleted file mode 100644 index ec1da90..0000000 Binary files a/nappIce/HowTo/html/nappIceHowTo_25.png and /dev/null differ diff --git a/nappIce/HowTo/html/nappIceHowTo_26.png b/nappIce/HowTo/html/nappIceHowTo_26.png deleted file mode 100644 index 799b940..0000000 Binary files a/nappIce/HowTo/html/nappIceHowTo_26.png and /dev/null differ diff --git a/nappIce/HowTo/nappIceHowTo.m b/nappIce/HowTo/nappIceHowTo.m deleted file mode 100644 index a1e5ed8..0000000 --- a/nappIce/HowTo/nappIceHowTo.m +++ /dev/null @@ -1,1382 +0,0 @@ -%% 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. -% -% -% -% -% -%% 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: -% -% -% -% -%% -% * 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'); -% -% -% -% -% -%% 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. -%% -% -% -% -% -% -%% 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),'--','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 - - diff --git a/nappIce/HowTo/nappIceHowToData.mat b/nappIce/HowTo/nappIceHowToData.mat deleted file mode 100644 index d712101..0000000 Binary files a/nappIce/HowTo/nappIceHowToData.mat and /dev/null differ diff --git a/nappIce/LabView_importData.m b/nappIce/LabView_importData.m deleted file mode 100644 index ce8dab9..0000000 --- a/nappIce/LabView_importData.m +++ /dev/null @@ -1,157 +0,0 @@ -function LabView = LabView_importData(fullFileName,varargin) -% -% LabView_importData reads data log ASCII files stored by LabView into -% a Matlab time series. -% -% LabView = LabView_importData(A) imports file A -% and stores its content as time series in a structure called "LabView". -% -% LabView = LabView_importData(A,LabView) imports file A -% and appends its content as time series to the LabView structure. -% -% -% Example -% LabView = LabView_importData('exmpl.dat',LabView) -% -% Input -% * Napp_chamber_file: Complete and absolute path to the Napp chamber log file. -% * LabView: name of output structure. Always call this'LabView' -% -% Output -% * LabView: time series, the name starting with "ts" -% followed by date and time the recording started. -% -% See also LABVIEW_COMBINE, LABVIEW_PLOT, LABVIEW_CUTDATA -% -%% Data Structure -% -% Data structure before 4.3.2019 -% col 1: Date -% col 2: Time -% col 3: Reservoir "Pressure 1" - Unit "1 water" - mbar -> ts.Data:2 -% col 4: Reservoir "Pressure 2" - Unit "2 other" - mbar -> ts.Data:3 -% col 5: Baratron 1 - cell - 1mbar max - mbar -> ts.Data:4 -% col 6: Baratron 2 - cell - 10mbar max - mbar -> ts.Data:8 -% col 7: Baratron 3 - cell - 0.05mbar max - mbar -> ts.Data:9 -% col 8: Baratron 4 - - mbar -% col 9: Temp.Ice Sample - °C -> ts.Data:1 -% col 10: Temp.Heated Sample -% col 11: none -% col 12: Temp. Reservoir "Cooler 1" - °C -> ts.Data:5 -% col 13: Temp. Reservoir "Cooler 2" - °C -> ts.Data:6 -% col 14: Flow He(cryoholder) - l/min -> ts.Data:7 -% col 15: none -% col 16: none -% -% Data structure after 4.3.2019 -% col 1: Date -% col 2: Time -% col 3: Reservoir "Pressure 1" - Unit "1 water" - mbar -> ts.Data:2 -% col 4: Reservoir "Pressure 2" - Unit "2 other" - mbar -> ts.Data:3 -% col 5: Baratron 1 - cell - 1mbar max - mbar -> ts.Data:4 -% col 6: Baratron 2 - cell - 10mbar max - mbar -> ts.Data:8 -% col 7: Baratron 3 - cell - 0.05mbar max - mbar -> ts.Data:9 -% col 8: Baratron 4 - - mbar -% col 9: Temp.Ice Sample - °C -> ts.Data:1 -% col 10: Temp.Heated Sample -% col 11: Temp. Reservoir "Cooler 1" - °C -> ts.Data:5 -% col 12: Temp. Reservoir "Cooler 2" - °C -> ts.Data:6 -% col 13: Flow He(cryoholder) - l/min -> ts.Data:7 -% col 14: Flow gas 1 -% col 15: Pressure chamber - mbar -% col 16: x-position of cryoholder - mm -> ts.Data:10 -% col 17: y-position of cryoholder - mm -> ts.Data:11 -% col 18: z-position of cryoholder - mm -> ts.Data:12 -% col 19: nothing -% col 20: Temp.Sealing - °C -> ts.Data:13 - - -%% - -% Create an InputParser object -p = inputParser; -% Add inputs to the scheme. -defaultAppendToStructure = 0; -addRequired(p,'fullFileName',@isfile); -addOptional(p,'appendToStructure',defaultAppendToStructure,@isstruct); -% Parse the inputs. -parse(p,fullFileName,varargin{:}) - -%% -% get filedate -[~,name,~] = fileparts(p.Results.fullFileName); -tmp = strsplit(name,'_PC'); -filedate = datenum(tmp{1},'yyyy-mm-dd_HH.MM.SS'); - -clearvars name tmp - -%% -% parse structure to append to - -if isstruct(p.Results.appendToStructure) - LabView = p.Results.appendToStructure; -end -%% -if datenum(filedate) <= datenum('04-Mar-2019 13:30:00') - - fid = fopen(p.Results.fullFileName); - data = textscan(fid, ... - '%s %s %f %f %f %f %f %f %f %f %f %f %f %f %f %f',... - 'HeaderLines',1); % data file has 2 text columns, followed by 14 numeric columns - fclose(fid); - % define time series - LabView.(['ts_' datestr(datenum([char(data{1}{1}), char(data{2}{1})],'dd.mm.yyyyHH:MM:SS'),'YYYYmmdd_HHMM')]) ... - = timeseries([data{9} data{3} data{4} data{5} data{12} ... - data{13} data{14} data{6} data{7}] , ... - datestr(datenum([char(data{1}), char(data{2})],... - 'dd.mm.yyyyHH:MM:SS'),0)); - LabView.(['ts_' datestr(datenum([char(data{1}{1}), char(data{2}{1})],'dd.mm.yyyyHH:MM:SS'),'YYYYmmdd_HHMM')]).Name ... - = 'Readout Napp Chamber raw signal'; - clear fid ans formatOut nans t x - -elseif datenum(filedate) >= datenum('15-Sep-2021 01:00:00') - - fid = fopen(p.Results.fullFileName); - data = textscan(fid, ... - '%s %s %s %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f',... - 'HeaderLines',1); % - - fclose(fid); - % the date formating in the dat file is really messed up. Try to make - % it consitent with MATLAB. The problem is that MATLAB does not - % understand 1 digit month and hours. - % - % - % Split the date in column 1 into year,month,day - newDateSplit = cellfun(@(x) split(char(x),'/'),data{1},'UniformOutput', false); - % Split the time in column 2 into hours, minutes, seconds - newTimeSplit = cellfun(@(x) split(char(x),':'),data{2},'UniformOutput', false); - % combine both with the am/pm string in column 3 to a new datestring - customDateStr = cellfun(@(x,y,z) [datestr(datenum([str2double(x{3}),str2double(x{1}),str2double(x{2}),str2double(y{1}),str2double(y{2}),str2double(y{3})])), ' ', char(z)], newDateSplit,newTimeSplit,data{3}, 'uniformOutput',false) ; - % define time series - LabView.(['ts_' datestr(customDateStr{1},'YYYYmmdd_HHMM')]) ... - = timeseries([data{10} data{4} data{5} data{6} data{12} ... - data{13} data{14} data{7} data{8} data{17} data{18} data{19} data{21}], ... - customDateStr); - LabView.(['ts_' datestr(customDateStr{1},'YYYYmmdd_HHMM')]).Name ... - = 'Readout Napp Chamber raw signal'; - clearvars fid ans formatOut nans t x new* custom* -else - fid = fopen(p.Results.fullFileName); - data = textscan(fid, ... - '%s %s %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f',... - 'HeaderLines',1); % data file has 2 text columns, followed by 16 numeric columns - fclose(fid); - % define time series - - LabView.(['ts_' datestr(datenum([char(data{1}{1}), char(data{2}{1})],'dd.mm.yyyyHH:MM:SS'),'YYYYmmdd_HHMM')]) ... - = timeseries([data{9} data{3} data{4} data{5} data{11} ... - data{12} data{13} data{6} data{7} data{16} data{17} data{18} data{20}] , ... - datestr(datenum([char(data{1}), char(data{2})],... - 'dd.mm.yyyyHH:MM:SS'),0)); - - LabView.(['ts_' datestr(datenum([char(data{1}{1}), char(data{2}{1})],'dd.mm.yyyyHH:MM:SS'),'YYYYmmdd_HHMM')]).Name ... - = 'Readout Napp Chamber raw signal'; - clear fid ans formatOut nans t x -end -end \ No newline at end of file diff --git a/nappIce/Napp_RH_p.m b/nappIce/Napp_RH_p.m deleted file mode 100644 index 540b65a..0000000 --- a/nappIce/Napp_RH_p.m +++ /dev/null @@ -1,38 +0,0 @@ -function relHum = Napp_RH_p(T_current,partial_pressure_water) -%Napp_RH_p calculates the relative humidity for a given -% temperature and water pressure. -% -% With the relative humidity referenced -% to liquid water (RH_w) as opposed to ice (RH_i), the activity of water -% is: activity_w = RH_{water}/100 -% -% -% * Napp_p_RH(T_current,RH) -% * Napp_p_RH([253.15, 263.15, 273.15],[60, 80, 90]) -% * Napp_p_RH(273.15-20,80) -% -% -% *input* -% T_current in K: temperature -% RH in %: relative humidity (RH_{water}) -% -% *output* -% partial pressure of water in mbar - -%% -% -% *water*: -% NIST webbook: Bridgeman and Aldrich, 1964 give parametrisation from 273 -% to 303 K in bar. log10(p) = A - B/ (T+C). -A = 5.40221; -B = 1838.675; -C = -31.737; - -p_w = 10.^(A - B./(T_current+C)) .* 1E3; % mbar -RH = (partial_pressure_water*100)/p_w; -relHum = RH; - -for i = 1:length(T_current) - fprintf('RH of %.0f percent at %.1f K (%.1f dC) and %.2f mbar .\n',RH,T_current,T_current-273.15,partial_pressure_water) -end -end \ No newline at end of file diff --git a/nappIce/Napp_p_RH.m b/nappIce/Napp_p_RH.m deleted file mode 100644 index d9e3378..0000000 --- a/nappIce/Napp_p_RH.m +++ /dev/null @@ -1,34 +0,0 @@ -function Napp_p_RH(T_current,RH) -%Napp_p_RH calculates the partial pressure of water for a given -% temperature and relative humidity. With the relative humidity referenced -% to liquid water (RH_w) as opposed to ice (RH_i), the activity of water -% is: activity_w = RH_{water}/100 -% -% * Napp_p_RH(T_current,RH) -% * Napp_p_RH([253.15, 263.15, 273.15],[60, 80, 90]) -% * Napp_p_RH(273.15-20,80) -% -% -% *input* -% T_current in K: temperature -% RH in %: relative humidity (RH_{water}) -% -% *output* -% partial pressure of water in mbar - -%% -% -% *water*: -% NIST webbook: Bridgeman and Aldrich, 1964 give parametrisation from 273 -% to 303 K in bar. log10(p) = A - B/ (T+C). -A = 5.40221; -B = 1838.675; -C = -31.737; - -p_w = 10.^(A - B./(T_current+C)) .* 1E3; % mbar - - -for i = 1:length(T_current) - fprintf('The partial pressure of water with a RH of %.0f percent at %.1f K (%.1f dC) is %.2f mbar .\n',RH(i),T_current(i),T_current(i)-273.15,p_w(i).*RH(i)./100) -end -end \ No newline at end of file diff --git a/nappIce/Napp_p_ice.m b/nappIce/Napp_p_ice.m deleted file mode 100644 index b1cb7b5..0000000 --- a/nappIce/Napp_p_ice.m +++ /dev/null @@ -1,49 +0,0 @@ -function p = Napp_p_ice(T_current) -%Napp_p_ice(T_current) plots the vapour pressure of ice between 200-270 K -% and marks the vapour pressure of ice at a given temperature. It also -% displays the vapour pressure at a temperature of choice in the command -% window. -% -% * Napp_p_ice(T_current) -% * p = Napp_p_ice([253.15, 263.15, 273.15]) -% -% *input* -% T_current in K: temperature of ice; (format: either single numbers or array) -% -% *output* -% vapour pressure of ice in mbar - -%% Water vapour pressure above the ice and in pure liquid water. - -T = 200:0.2:273; % K, temperature range -% Marti, J., and K. Mauersberger, Geophys. Res.Lett., 20, 363?366, 1993. -% gives parameterization from 169 - 273K in Pa. (log10(p)= A1/T+B) -A_1 = -2663.5; -B_1 = 12.537; -p_i = 10.^(A_1./T + B_1).*1E-5.*1E3; % mbar -p = 10.^(A_1./T_current + B_1).*1E-5.*1E3; % mbar - -% plot -figure( 'Name', 'vapour pressure over ice') -axes1 = axes('Parent',gcf,'XDir','reverse','FontSize',16); -box on -hold on -% relative humidity above ice -plot(p_i,T,'LineWidth',2) -xlim([0 6.5]); -ylim([220 275]); -xticks(0:0.5:6.5) -grid on -grid minor -title('vapour pressure over ice'); - -xlabel('p [mbar]'); -ylabel('temperature [K]'); - -%% write to command line -for i = 1:length(T_current) - plot(10.^(A_1./T_current(i) + B_1).*1E-5.*1E3,T_current(i),'x','MarkerSize',25,'LineWidth',3); - text(10.^(A_1./T_current(i) + B_1).*1E-5.*1E3, T_current(i),[' <- ' num2str(T_current(i))],'FontSize',12); - fprintf('The vapour pressure of ice at %.1f K (%.1f dC) is %.2f mbar \n',T_current(i),T_current(i)-273.15,10.^(A_1./T_current(i) + B_1).*1E-5.*1E3) -end -end \ No newline at end of file diff --git a/nappIce/ToBeAdded/EnsureLength.m b/nappIce/ToBeAdded/EnsureLength.m deleted file mode 100644 index f561e5e..0000000 --- a/nappIce/ToBeAdded/EnsureLength.m +++ /dev/null @@ -1,43 +0,0 @@ -[x1, y1] = prepareCurveData(data1(:,1),data1(:,2)); -[x2, y2] = prepareCurveData(data2(:,1),data2(:,2)); -[x3, y3] = prepareCurveData(data3(:,1),data3(:,2)); - - -% Define equation to fit data -% I use the area Gauss equations here, which I took from the OriginPro -% documentation. https://www.originlab.com/doc/Origin-Help/Gauss-FitFunc -% -% Gauss = area/(width*sqrt(pi/2)) * exp(-2*(x-position)^2/width^2) -% -% where FWHM = width * sqrt(ln(4)) - -% Next, the data will be arranged in a matrix - where all elements need -% to have the same length. Workaround: give both data sets same length. -xLow = [min(x1) min(x2) min(x3)]; -xHigh = [max(x1) max(x2) max(x3)]; -x1start = find(x1 <= min(xHigh),1); -x2start = find(x2 <= min(xHigh),1); -x3start = find(x3 <= min(xHigh),1); -x1end = find(x1 <= max(xLow),1); -x2end = find(x2 <= max(xLow),1); -x3end = find(x3 <= max(xLow),1); -x1 = x1(x1start:x1end); -x2 = x2(x2start:x2end); -x3 = x3(x3start:x3end); -y1 = y1(x1start:x1end); -y2 = y2(x2start:x2end); -y3 = y3(x3start:x3end); - -% if - for any reason - the 3 vectors have different scaling, they might -% end up with different sizes. Here is a workaround -sizeOfX = [size(x1,1) size(x2,1) size(x3,1)]; % find size of each X -if range(sizeOfX) ~= 0 % cut all to shortest range - x1 = x1(1:min(sizeOfX)); - x2 = x2(1:min(sizeOfX)); - x3 = x3(1:min(sizeOfX)); - y1 = y1(1:min(sizeOfX)); - y2 = y2(1:min(sizeOfX)); - y3 = y3(1:min(sizeOfX)); -end -clearvars sizeOfX - diff --git a/nappIce/ToBeAdded/XPS_MeanSeqIterations.m b/nappIce/ToBeAdded/XPS_MeanSeqIterations.m deleted file mode 100644 index 606361a..0000000 --- a/nappIce/ToBeAdded/XPS_MeanSeqIterations.m +++ /dev/null @@ -1,76 +0,0 @@ -function datafile = XPS_MeanSeqIterations(selection_spectra,selection_region, datafile, numberToAverage) -% -% XPS_MeanSeqIterations generates a new data structure by combining and -% averaging a fixed number or sequence interations. This is usefull if for -% example the dwell time was too short to get spectra with a good S/N. -% -% THIS MODIFIES THE RAW DATA in Matlab. -% -% -% XPS = XPS_MeanSeqIterations([346 347],'', XPS); processes -% the first region of spectra 346 and 347. The number of sequence -% iterations to average is determined automatically. -% -% XPS = XPS_MeanSeqIterations([346 347],'', XPS,5); processes -% the first region of spectra 346 and 347. It averages 5 sequence -% iterations. -% -% -% Input -% XPS_background(selection_spectra,selection_region, datafile, hPeaks,excludeBackgroundFit, findPeak,plotFigures) -% * selection_spectra: List of PE spectra to be imported. Numeric list of -% Spectra Number: [25 26] -% * datafile: XPS data structure in workspace. Output from XPS_importData -% function. -% * numberToAverage (optional): Choose how many sequence iterations you -% would like to average. -% -% Output: -% * modified data structure y -% * modified dwellTime meta-data -% * modified sequenceIterations meta-data - -if ~exist('numberToAverage','var') - numberToAverage = 0; -end - - - -for s = 1:length(selection_spectra) - %% Select spectra in data structure - % - - % get list of spectra in data structure - spectraNames = fieldnames(datafile); - % find those that match the spectrum number to be plotted - % (contains gives a list of 0 or 1 for no match and match, resp. and - % find list the rows of matches.) - - - for r = 1:length(selection_region) - - tmp = find(endsWith(spectraNames,[num2str(selection_spectra(s)) char(selection_region(r))])); - if numberToAverage == 0 - % Get the prime factors of the data structure size in the 2nd dimension - % (i.e. number of sequence iterations) - tmp_avnumb = factor(size(datafile.(spectraNames{tmp}).y,2)); - % Use the first prime factor to select number of iterations to - % be averaged. - numberToAverage = tmp_avnumb(1); - end - - % Calculate mean, reshape, and re-size data structure - RM = reshape(datafile.(spectraNames{tmp}).y,... - size(datafile.(spectraNames{tmp}).y,1), numberToAverage, []) ; % Reshape - datafile.(spectraNames{tmp}).y = squeeze(mean(RM,2)) ; - datafile.(spectraNames{tmp}).y_processed = squeeze(mean(RM,2)); - - % update the meta-data - datafile.(spectraNames{tmp}).dwellTime = datafile.(spectraNames{tmp}).dwellTime * numberToAverage; - datafile.(spectraNames{tmp}).sequenceIterations = datafile.(spectraNames{tmp}).sequenceIterations / numberToAverage; - end - -end -disp('*************************************************') -disp('* Voila: XPS_MeanSeqIterations done ! *') -disp('*************************************************') \ No newline at end of file diff --git a/nappIce/addPhotonEnergy.m b/nappIce/addPhotonEnergy.m deleted file mode 100644 index c4fd443..0000000 --- a/nappIce/addPhotonEnergy.m +++ /dev/null @@ -1,22 +0,0 @@ -function FileList = addPhotonEnergy(FileList,fileNumber,notesToAdd,dataMonth,dataYear) -%addPhotonEnergy adds the beam lines photon energy to the data table -% -% FileList = addPhotonEnergy(FileList,[1,8:12,26],1000,2,2022); -% -% Input to this function are -% -% * the name of the data table, -% * the file numbers of the SES scans to which the data should be added -% * the photon energy in eV, -% * the month and the year that the data was acquired - -for ii = 1:length(fileNumber) - tmpMatch = (startsWith(FileList.name, sprintf('%04.0f',fileNumber(ii)))) & ... - (month(FileList.lastModifiedDatenum) == dataMonth) &... - (year(FileList.lastModifiedDatenum) == dataYear) &... - (endsWith(FileList.name, '.ibw')); - - FileList(tmpMatch,:).xRayEkin_eV = num2cell(repmat(notesToAdd,size(FileList.xRayEkin_eV(tmpMatch),1),1)); - FileList(tmpMatch,:).xRayEkinRange_eV = repmat([min(notesToAdd) max(notesToAdd)],size(FileList.xRayEkin_eV(tmpMatch),1),1); -end -end \ No newline at end of file diff --git a/nappIce/addSampleNotes.m b/nappIce/addSampleNotes.m deleted file mode 100644 index 9c069d2..0000000 --- a/nappIce/addSampleNotes.m +++ /dev/null @@ -1,52 +0,0 @@ -function DataTable = addSampleNotes(DataTable,fileNumber,notesToAdd,dataMonth,dataYear,tableSelection) -%addSampleNotes adds a sample description to the data -% -% FileList = addSampleNotes(FileList,44,'Ice with N2 and phenol in Ar (bad data)',2,2022); -% -% Input to this function are -% -% * the name of the data table, -% * the file numbers of the SES scans to which the info should be added -% * a text string describing the sample, -% * the month and the year that the data was aquired -% * optional: 'XPS' or 'NEXAFS' as last input argument to limit to either XPS data or NEXAFS -% data - -% check if "sample" table variable (column) exist, if not add it -existColumn = strcmp('sample',DataTable.Properties.VariableNames); -if ~any(existColumn) - DataTable.sample = cellstr(repmat(' ',size(DataTable,1),1)); -end - -for ii = 1:length(fileNumber) - if ~exist('tableSelection','var') - % select the data - tmpMatch = (startsWith(DataTable.name, sprintf('%04.0f',fileNumber(ii)))) & ... - (month(DataTable.lastModifiedDatenum) == dataMonth) &... - (year(DataTable.lastModifiedDatenum) == dataYear); - else - if matches(tableSelection,'XPS') - % select the data - tmpMatch = (startsWith(DataTable.name, sprintf('%04.0f',fileNumber(ii)))) & ... - (month(DataTable.lastModifiedDatenum) == dataMonth) &... - (year(DataTable.lastModifiedDatenum) == dataYear) &... - (endsWith(DataTable.name, '.ibw')); - elseif matches(tableSelection,'NEXAFS') - % select the data - tmpMatch = (startsWith(DataTable.name, sprintf('%04.0f',fileNumber(ii)))) & ... - (month(DataTable.lastModifiedDatenum) == dataMonth) &... - (year(DataTable.lastModifiedDatenum) == dataYear)&... - (endsWith(DataTable.name, '.h5')); - end - end - % clear existing data (to prevent 2 entries per field) - existColumn = strcmp('sample',DataTable.Properties.VariableNames); - if any(existColumn) - if ~isempty(DataTable(tmpMatch,:).sample) - DataTable(tmpMatch,:).sample = cellstr(repmat(' ',size(DataTable(tmpMatch,:),1),1)); - end - end - DataTable(tmpMatch,:).sample = cellstr(repmat(notesToAdd,size(DataTable(tmpMatch,:),1),1)); -end -end - diff --git a/nappIce/nappAlignImages.m b/nappIce/nappAlignImages.m deleted file mode 100644 index 4af7cc6..0000000 --- a/nappIce/nappAlignImages.m +++ /dev/null @@ -1,78 +0,0 @@ -function DataTable = nappAlignImages(DataTable,varargin) -%nappAlignImages shifts each sequence iteration to align images with a -%drifting kinetic energy of the PE features. -% -% FileList = nappAlignImages(FileList,'tableSelection',tmpDataSelection,... -% 'tableVariable','image'); -% -% -% *input* -% FileList: data table -% tableSelection (optional): logical array to filter data table -% tableVariable: choose to process either imageRoh (default) or image data. -% -% *requirements* -% nappAlignImages shifts each sequence iteration using the data given in -% the table variable kineticEnergyShift. These shifts for each sequence -% iteration need to be determined before running this function. Run -% nappDetermineShiftXps first. -% -% *output* -% The table variable image will be overwritten with the shifted -% image. -% -% See also nappDetermineShiftXps.m - -defaultTableVariable = 'imageRoh'; -expectedTableVariable = {'imageRoh','image'}; -defaultTableSelection = true(size(DataTable,1)); - -% Parse input -p = inputParser; -addRequired(p,'DataTable',@istable); -addParameter(p,'tableSelection',defaultTableSelection,@islogical); -addParameter(p,'tableVariable',defaultTableVariable,... - @(x) any(validatestring(x,expectedTableVariable))); -parse(p,DataTable,varargin{:}); - - -% check input (all elements of input variable need to have non-zero size) -if ~all(cell2mat(cellfun(@size,p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable),'UniformOutput',false)),'all') - disp('The table variable appears to be empty. I quit now') - error('The table variable appears to be empty.') -end - -if matches(p.Results.tableVariable,'imageRoh') - % interpolate image data - for ii = 1:size(p.Results.DataTable(p.Results.tableSelection,:),1) - for ij = 1:size(DataTable(p.Results.tableSelection,:).imageRoh{ii},2) - tmp_1(:,ij)= ... - interp1(DataTable(p.Results.tableSelection,:).scientaEkinRoh_eV{ii}(:)+... - p.Results.DataTable(p.Results.tableSelection,:).kineticEnergyShift{ii}(ij),... - DataTable(p.Results.tableSelection,:).imageRoh{ii}(:,ij),... - DataTable(p.Results.tableSelection,:).scientaEkinRoh_eV{ii}(:)); - - end - DataTable(p.Results.tableSelection,:).image{ii}=tmp_1; - clearvars tmp_1 - - end -else - % interpolate image data - for ii = 1:size(p.Results.DataTable(p.Results.tableSelection,:),1) - for ij = 1:size(p.Results.DataTable(p.Results.tableSelection,:).image{ii},2) - - tmp_1(:,ij)= ... - interp1(p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii}(:)+... - p.Results.DataTable(p.Results.tableSelection,:).kineticEnergyShift{ii}(ij),... - p.Results.DataTable(p.Results.tableSelection,:).image{ii}(:,ij),... - p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii}(:)); - - end - DataTable(p.Results.tableSelection,:).image{ii}=tmp_1; - clearvars tmp_1 - end -end -end - - diff --git a/nappIce/nappAnnotateSurvey.m b/nappIce/nappAnnotateSurvey.m deleted file mode 100644 index 18dca06..0000000 --- a/nappIce/nappAnnotateSurvey.m +++ /dev/null @@ -1,10 +0,0 @@ -function nappAnnotateSurvey(X,Y,dataObjs,labeltext) -% nappAnnotateSurvey adds region labels to a survey in the topmost figure. -ha = annotation('arrow'); % store the arrow information in ha -ha.Parent = gca; % associate the arrow the the current axes -ha.X = [X X]; % the location in data units -tmp.X=find(dataObjs.XData >= X,1); -tmp.Y=dataObjs.YData(tmp.X); -ha.Y = [tmp.Y+Y tmp.Y+(Y/10)]; -text(X,tmp.Y+Y,labeltext,'HorizontalAlignment','center') -end diff --git a/nappIce/nappBackground.m b/nappIce/nappBackground.m deleted file mode 100644 index 77434f6..0000000 --- a/nappIce/nappBackground.m +++ /dev/null @@ -1,187 +0,0 @@ - function DataTable = nappBackground(DataTable,varargin) -%nappBackground determines and subtracts the background from PE or XAS spectra -% -% FileList = nappBackground(FileList,energyStart,energyEnd); -% -% FileList = nappBackground(FileList,368,370,'tableSelection',tmpDataSelection,'energyScale','kinetic',... -% 'mode','mean','showFigures','off'); -% -% -% *input* -% FileList: data table -% energyStart: smallest value of energy range to use for background calculation -% (can also be binding energy) -% energyEnd: largest value of energy energy range to use for background calculation -% (can also be binding energy) -% tableSelection (optional): logical array to filter data table -% tableVariable: choose to process either -% 'spectrum_counts','spectrum_countsPerSecond' (default), or -% 'spectrum_countsNorm'. -% mode: mean(default) subtract the mean of the energy range from -% spectrum; linfit subtract a linear regression through the energy range -% from spectrum -% showFigures, on(default): show fit in figure, off do not show fit in -% figure -% energyScale: kinetic(default): work with kinetic energy scale; binding -% works with binding energy scale. -% -% -% *output* -% The table variable passed to the function as tableVariable -% parameter will be overwritten with the background subtracted spectrum. -% -% The function parameters (mode, energyStart, energyEnd) are written -% to the table as log. - - - -% Define conditions and defaults of input -defaultTableVariable = 'spectrum_countsPerSecond'; -expectedTableVariable = {'spectrum_counts','spectrum_countsPerSecond','spectrum_countsNorm'}; -defaultMode = 'mean'; -expectedMode = {'mean','linfit'}; -defaultTableSelection = true(size(DataTable,1),1); -defaultShowFigures = 'on'; -expectedShowFigures = {'on','off'}; -defaultEnergyScale = 'kinetic'; -expectedEnergyScale = {'kinetic','binding','xRay'}; - -% Parse input -p = inputParser; -addRequired(p,'DataTable',@istable); -addRequired(p,'energyStart',@isnumeric) -addRequired(p,'energyEnd',@isnumeric) -addOptional(p,'tableSelection',defaultTableSelection,@islogical); -addParameter(p,'tableVariable',defaultTableVariable,... - @(x) any(validatestring(x,expectedTableVariable))); -addParameter(p,'mode',defaultMode,... - @(x) any(validatestring(x,expectedMode))); -addParameter(p,'showFigures',defaultShowFigures,... - @(x) any(validatestring(x,expectedShowFigures))); -addParameter(p,'energyScale',defaultEnergyScale,... - @(x) any(validatestring(x,expectedEnergyScale))); -parse(p,DataTable,varargin{:}); - -% check input (all elements of input variable need to have non-zero size) -if ~all(cell2mat(cellfun(@size,p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable),'UniformOutput',false)),'all') - disp('The table variable appears to be empty. I quit now') - error('The table variable appears to be empty.') -end - -% add empty table variables (if they don't exist) -existColumn = strcmp('logBackgroundRange',DataTable.Properties.VariableNames); -if ~any(existColumn) - DataTable.logBackgroundRange = NaN(size(DataTable,1),2); -end -existColumn = strcmp('logBackgroundMode',DataTable.Properties.VariableNames); -if ~any(existColumn) - DataTable.logBackgroundMode = cellstr(repmat(' ',size(p.Results.DataTable,1),1)); -end -existColumn = strcmp('logBackgroundDate',DataTable.Properties.VariableNames); -if ~any(existColumn) - DataTable.logBackgroundDate = cellstr(repmat(' ',size(p.Results.DataTable,1),1)); -end - - -% repeat this for all columns in input. -for ii = 1:size(p.Results.DataTable(p.Results.tableSelection,:),1) - if contains(p.Results.energyScale,'kinetic') - % LINEAR FIT - if contains(p.Results.mode,'linfit') - disp('linfit not yet supported') - % MEAN - else - b_1 = find(p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii} >= p.Results.energyStart,1); - b_2 = find(p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii} >= p.Results.energyEnd,1); - - if b_2 == 1 - b_2=10; - end - - b_mean = mean(p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii}(b_1:b_2),'omitnan'); - tmp(ii,1) = cellfun(@(x) x-b_mean,p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable)(ii),'UniformOutput',false); - - - end - - elseif contains(p.Results.energyScale,'binding') - if contains(p.Results.mode,'linfit') - disp('linfit not yet supported') - % MEAN - else - b_1 = find(p.Results.DataTable(p.Results.tableSelection,:).bindingEnergy_eV{ii} <= p.Results.energyStart,1); - b_2 = find(p.Results.DataTable(p.Results.tableSelection,:).bindingEnergy_eV{ii} <= p.Results.energyEnd,1); - - if b_2 == 1 - b_2=10; - end - - b_mean = mean(p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii}(b_2:b_1),'omitnan'); - tmp(ii,1) = cellfun(@(x) x-b_mean,p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable)(ii),'UniformOutput',false); - - - end - elseif contains(p.Results.energyScale,'xRay') - if contains(p.Results.mode,'linfit') % LINEAR FIT - - % Fit: 'untitled fit 1'. - [xData, yData] = prepareCurveData( p.Results.DataTable(p.Results.tableSelection,:).xRayEkin_eV{ii}, ... - p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii}); - % Set up fittype and options. - ft = fittype( 'poly1' ); - excludedPoints = excludedata( xData, yData, 'domain',[p.Results.energyStart p.Results.energyEnd] ); - fo = fitoptions('Exclude', excludedPoints); - % Fit model to data. - [fitresult, ~] = fit( xData, yData, ft, fo ); - if contains(p.Results.showFigures,'on') - % Plot fit with data. - figure( 'Name', 'fit pre-edge' ); - h = plot( fitresult, xData, yData, excludedPoints ); - xlabel('Photon Energy eV') - ylabel('partial A-M.E.Y.') - grid on - title(p.Results.DataTable(p.Results.tableSelection,:).name{ii},'Interpreter','none') - end - tmp{ii,1} = p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii}-fitresult(p.Results.DataTable(p.Results.tableSelection,:).xRayEkin_eV{ii}); - - elseif contains(p.Results.mode,'mean') % mean - - if p.Results.DataTable(p.Results.tableSelection,:).xRayEkin_eV{ii}(1) < p.Results.DataTable(p.Results.tableSelection,:).xRayEkin_eV{ii}(end) - % prepare Data - - [xData, yData] = prepareCurveData( p.Results.DataTable(p.Results.tableSelection,:).xRayEkin_eV{ii}, ... - p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii}); - % MEAN - b_1 = find(xData >= p.Results.energyStart,1); - b_2 = find(xData >= p.Results.energyEnd,1); - - b_mean = mean(yData(b_1:b_2)); - elseif p.Results.DataTable(p.Results.tableSelection,:).xRayEkin_eV{ii}(1) > p.Results.DataTable(p.Results.tableSelection,:).xRayEkin_eV{ii}(end) - % prepare Data - [xData, yData] = prepareCurveData( p.Results.DataTable(p.Results.tableSelection,:).xRayEkin_eV{ii}, ... - p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii}); - % MEAN - b_1 = find(xData <= p.Results.energyStart,1); - b_2 = find(xData <= p.Results.energyEnd,1); - - b_mean = mean(yData(b_2:b_1)); - else - disp('Warning: Issue with NEXAFS data or energies') - end - - - tmp(ii,1) = cellfun(@(x) x-b_mean,p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable)(ii),'UniformOutput',false); - end - - - end -end - -% fill selected rows -DataTable(p.Results.tableSelection,:).(p.Results.tableVariable) = tmp; -% write log to table -DataTable.logBackgroundMode(p.Results.tableSelection,:) = cellstr(repmat(p.Results.mode,size(p.Results.DataTable(p.Results.tableSelection,:),1),1)); -DataTable.logBackgroundRange(p.Results.tableSelection,:) = repmat([p.Results.energyStart p.Results.energyEnd],size(p.Results.DataTable(p.Results.tableSelection,:),1),1); -DataTable.logBackgroundDate(p.Results.tableSelection,:) = cellstr(repmat(datestr(now),size(p.Results.DataTable(p.Results.tableSelection,:),1),1)); - -end \ No newline at end of file diff --git a/nappIce/nappBackgroundXps.m b/nappIce/nappBackgroundXps.m deleted file mode 100644 index 72d5d46..0000000 --- a/nappIce/nappBackgroundXps.m +++ /dev/null @@ -1,114 +0,0 @@ -function DataTable = nappBackground(DataTable,varargin) -%nappBackground determines and subtracts the background from PE or XAS spectra -% -% FileList = nappBackground(FileList,energyStart,energyEnd); -% -% FileList = nappBackground(FileList,368,370,'tableSelection',tmpDataSelection,'energyScale','kinetic',... -% 'mode','mean','showFigures','off'); -% -% -% *input* -% FileList: data table -% energyStart: smallest value of energy range to use for background calculation -% (can also be binding energy) -% energyEnd: largest value of energy energy range to use for background calculation -% (can also be binding energy) -% tableSelection (optional): logical array to filter data table -% tableVariable: choose to process either -% 'spectrum_counts','spectrum_countsPerSecond' (default), or -% 'spectrum_countsNorm'. -% mode: mean(default) subtract the mean of the energy range from -% spectrum; linfit subtract a linear regression through the energy range -% from spectrum -% showFigures, on(default): show fit in figure, off do not show fit in -% figure -% energyScale: kinetic(default): work with kinetic energy scale; binding -% works with binding energy scale. -% -% -% *output* -% The table variable passed to the function as tableVariable -% parameter will be overwritten with the background subtracted spectrum. -% -% The function parameters (mode, energyStart, energyEnd) are written -% to the table as log. - - - -% Define conditions and defaults of input -defaultTableVariable = 'spectrum_countsPerSecond'; -expectedTableVariable = {'spectrum_counts','spectrum_countsPerSecond','spectrum_countsNorm'}; -defaultMode = 'mean'; -expectedMode = {'mean','linfit'}; -defaultTableSelection = true(size(DataTable,1),1); -defaultShowFigures = 'on'; -expectedShowFigures = {'on','off'}; -defaultEnergyScale = 'kinetic'; -expectedEnergyScale = {'kinetic','binding'}; - -% Parse input -p = inputParser; - addRequired(p,'DataTable',@istable); - addRequired(p,'energyStart',@isnumeric) - addRequired(p,'energyEnd',@isnumeric) - addOptional(p,'tableSelection',defaultTableSelection,@islogical); - addParameter(p,'tableVariable',defaultTableVariable,... - @(x) any(validatestring(x,expectedTableVariable))); - addParameter(p,'mode',defaultMode,... - @(x) any(validatestring(x,expectedMode))); - addParameter(p,'showFigures',defaultShowFigures,... - @(x) any(validatestring(x,expectedShowFigures))); -addParameter(p,'energyScale',defaultEnergyScale,... - @(x) any(validatestring(x,expectedEnergyScale))); -parse(p,DataTable,varargin{:}); - - % check input (all elements of input variable need to have non-zero size) -if ~all(cell2mat(cellfun(@size,p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable),'UniformOutput',false)),'all') - disp('The table variable appears to be empty. I quit now') - error('The table variable appears to be empty.') -end - - % repeat this for all columns in input. -for ii = 1:size(p.Results.DataTable(p.Results.tableSelection,:),1) - if contains(p.Results.energyScale,'kinetic') - % LINEAR FIT - if contains(p.Results.mode,'linfit') - disp('linfit not yet supported') - % MEAN - else - b_1 = find(p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii} >= p.Results.energyStart,1); - b_2 = find(p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii} >= p.Results.energyEnd,1); - - if b_2 == 1 - b_2=10; - end - - b_mean = mean(p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii}(b_1:b_2),'omitnan'); - tmp(ii,1) = cellfun(@(x) x-b_mean,p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable)(ii),'UniformOutput',false); - - - end - - elseif contains(p.Results.energyScale,'binding') - if contains(p.Results.mode,'linfit') - disp('linfit not yet supported') - % MEAN - else - b_1 = find(p.Results.DataTable(p.Results.tableSelection,:).bindingEnergy_eV{ii} <= p.Results.energyStart,1); - b_2 = find(p.Results.DataTable(p.Results.tableSelection,:).bindingEnergy_eV{ii} <= p.Results.energyEnd,1); - - if b_2 == 1 - b_2=10; - end - - b_mean = mean(p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii}(b_2:b_1),'omitnan'); - tmp(ii,1) = cellfun(@(x) x-b_mean,p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable)(ii),'UniformOutput',false); - - - end - end -end -% fill selected rows -DataTable(p.Results.tableSelection,:).(p.Results.tableVariable) = tmp; - -end \ No newline at end of file diff --git a/nappIce/nappBindingEnergyXps.m b/nappIce/nappBindingEnergyXps.m deleted file mode 100644 index de26fe1..0000000 --- a/nappIce/nappBindingEnergyXps.m +++ /dev/null @@ -1,69 +0,0 @@ -function DataTable = nappBindingEnergyXps(DataTable,varargin) -%nappBindingEnergyXps calculates the binding energy scale for spectra based -%on the binding energy shift. -% -% *Requirement* -% Needs table variable bindingEnergyShift as input. Run -% nappDetermineShiftXps.m or nappCopyShift.m first -% -% FileList = nappBindingEnergyXps(FileList,'tableSelection',... -% tmpDataSelection); -% -% -% *input* -% FileList: data table -% tableSelection (optional): logical array to filter data table -% tableVariable: choose to process either -% 'spectrum_counts','spectrum_countsPerSecond' (default) -% -% -% *output* -% new table variable bindingEnergy_eV holding the binding energy for -% the data. -% -% -% See also nappnappAlignImages.m nappBindingEnergyXps nappFitGaussXps.m -% nappCopyShift.m nappDetermineShiftXps.m - -defaultTableVariable = 'spectrum_countsPerSecond'; -expectedTableVariable = {'spectrum_counts','spectrum_countsPerSecond'}; -defaultTableSelection = true(size(DataTable,1),1); - -% Parse input -p = inputParser; -addRequired(p,'DataTable',@istable); -addParameter(p,'tableSelection',defaultTableSelection,@islogical); -addParameter(p,'tableVariable',defaultTableVariable,... - @(x) any(validatestring(x,expectedTableVariable))); -parse(p,DataTable,varargin{:}); - -% check input (all elements of input variable need to have non-zero size) -if ~all(cell2mat(cellfun(@size,p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable),'UniformOutput',false)),'all') - disp('The table variable appears to be empty. I quit now') - error('The table variable appears to be empty.') -end - -% add empty variable to table -existColumn = strcmp('bindingEnergy_eV',DataTable.Properties.VariableNames); -if ~any(existColumn) - DataTable.bindingEnergy_eV = cell(size(DataTable,1),1); -end - -if any(isnan(cell2mat(p.Results.DataTable(p.Results.tableSelection,:).xRayEkin_eV))) - disp('Opps, X-ray energy is empty. Please add manually. Will stop now'); - return -end - - % repeat this for all columns in input. - for ii = 1:size(p.Results.DataTable(p.Results.tableSelection,:),1) - %% - if isnan(p.Results.DataTable(p.Results.tableSelection,:).bindingEnergyShift(ii)) - tmp_2(:,1) = p.Results.DataTable(p.Results.tableSelection,:).xRayEkin_eV{ii} - p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii}; - else - tmp_2(:,1) = p.Results.DataTable(p.Results.tableSelection,:).xRayEkin_eV{ii} - p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii} - p.Results.DataTable(p.Results.tableSelection,:).bindingEnergyShift(ii); - end - tmp_3{ii,1} =tmp_2; - clearvars tmp_2 - end - DataTable.bindingEnergy_eV(p.Results.tableSelection,:) = tmp_3; -end diff --git a/nappIce/nappCombineSpectra.m b/nappIce/nappCombineSpectra.m deleted file mode 100644 index d5b4ed5..0000000 --- a/nappIce/nappCombineSpectra.m +++ /dev/null @@ -1,100 +0,0 @@ -function combinedSpectrum = nappCombineSpectra(DataTable,varargin) -%nappCombineSpectra combines selected PE or NEXAFS spectra into one. Data -%are intrapolated along x-axis. -% -% MgO_C1s_Warm = nappCombineSpectra(FileList,'tableRow',1,... -% 'tableSelection',tmpDataSelection,'tableVariable',... -% 'spectrum_countsNorm','EnergyScale','binding','mode','average'); -% -% *input* -% FileList: data table -% tableSelection (optional): logical array to filter data table -% tableVariable (optional): select source: 'nexafsSpectrum','spectrum_counts','spectrum_countsPerSecond',... -% 'spectrum_countsNorm','nexafsSpectrumPreBackground','nexafsSpectrumPreNorm',... -% 'nexafsSpectrumPreGasPhase','nexafsSpectrumPreI0','nexafsSpectrumPreAdvCarb' -% tableRow (optional): default 1. Defines the row in filtered table (to be -% processed). The x-axis of that data set will be used for interpolation. -% mode: mean (default) averages the spectra; sum adds them, subtract not -% coded yet. -% energyScale (optional): kinetic (default) or binding energy scale; only relevant -% for PE spectra, not for NEXAFS -% -% -% *output* -% a matrix with energy in column 1, counts in column2, and standard -% deviation in column 3 (only for mean). -% - - -expectedTableVariable = {'nexafsSpectrum','spectrum_counts','spectrum_countsPerSecond',... - 'spectrum_countsNorm','nexafsSpectrumPreBackground','nexafsSpectrumPreNorm',... - 'nexafsSpectrumPreGasPhase','nexafsSpectrumPreI0','nexafsSpectrumPreAdvCarb'}; -defaultTableSelection = true(size(DataTable,1)); -defaultTableRow = 1; -defaultMode = 'sum'; -expectedMode = {'sum','average','subtract'}; -defaultEnergyScale = 'kinetic'; -expectedEnergyScale = {'kinetic','binding','xRay'}; - - -% Parse input -p = inputParser; -addRequired(p,'DataTable',@istable); -addParameter(p,'tableSelection',defaultTableSelection,@islogical); -addParameter(p,'tableRow',defaultTableRow,@isnumeric); -addParameter(p,'tableVariable',... - @(x) any(validatestring(x,expectedTableVariable))); -addParameter(p,'mode',defaultMode,... - @(x) any(validatestring(x,expectedMode))); -addParameter(p,'energyScale',defaultEnergyScale,... - @(x) any(validatestring(x,expectedEnergyScale))); - -parse(p,DataTable,varargin{:}); - -% check input (all elements of input variable need to have non-zero size) -if ~all(cell2mat(cellfun(@size,p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable),'UniformOutput',false)),'all') - disp('The table variable appears to be empty. I quit now') - error('The table variable appears to be empty.') -end - -if (contains(p.Results.tableVariable,'counts')) && (contains(p.Results.energyScale,'kinetic')) - tmpX = p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV; -elseif (contains(p.Results.tableVariable,'counts')) && (contains(p.Results.energyScale,'binding')) - tmpX = p.Results.DataTable(p.Results.tableSelection,:).bindingEnergy_eV; -elseif contains(p.Results.tableVariable,'counts') && (contains(p.Results.energyScale,'xRay')) - tmpX = p.Results.DataTable(p.Results.tableSelection,:).xRayEkin_eV; -end - - - if contains(p.Results.energyScale,'binding') - tmpStart = min(cellfun(@(x) x(1), tmpX)); - tmpEnd = max(cellfun(@(x) x(end), tmpX)); - tmpStartIndex = find(tmpX{p.Results.tableRow} <= tmpStart,1); - tmpEndIndex = find(tmpX{p.Results.tableRow} <= tmpEnd,1); - else - tmpStart = max(cellfun(@(x) x(1), tmpX)); - tmpEnd = min(cellfun(@(x) x(end), tmpX)); - tmpStartIndex = find(tmpX{p.Results.tableRow} >= tmpStart,1); - tmpEndIndex = find(tmpX{p.Results.tableRow} >= tmpEnd,1); - end - - xq = tmpX{p.Results.tableRow}(tmpStartIndex:tmpEndIndex); - % repeat this for all columns in input. - for ii = 1:size(p.Results.DataTable(p.Results.tableSelection,:),1) - x = tmpX{ii}; - v = p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii}; - vq(:,ii) = interp1(x,v,xq); - end - - - -combinedSpectrum(:,1) = xq; -if contains(p.Results.mode,'sum') - combinedSpectrum(:,2) = sum(vq,2); -elseif contains(p.Results.mode,'average') - combinedSpectrum(:,2) = mean(vq,2); - combinedSpectrum(:,3) = std(vq,0,2); -elseif contains(p.Results.mode,'subtract') - disp('Not supported yet') % FIXME: subtraction is not implemented yet. -end -end diff --git a/nappIce/nappCopyShift.m b/nappIce/nappCopyShift.m deleted file mode 100644 index 6e586e0..0000000 --- a/nappIce/nappCopyShift.m +++ /dev/null @@ -1,99 +0,0 @@ -function DataTable = nappCopyShift(DataTable,varargin) -%nappBindingEnergyXps calculates the binding energy scale for spectra based -%on the binding energy shift. -% -% For each spectrum with a given file number, the function copies the shift from data of a specified -% region to another region of choice. -% -% *Requirement* -% Needs table variable bindingEnergyShift as input. Run -% nappDetermineShiftXps.m first on selected region. -% -% FileList = nappCopyShift(FileList,tmpDataSelection,'energyScale','binding'); -% -% *input* -% FileList: data table -% tableSelection (optional): logical array to filter data table -% regionOld: O1s (default) or C1s - source of shift data -% regionNew: C1s (default), N1s or O1s - shift data will be copied to this -% region -% energyScale: kinetic (default) or binding: process either the kinetic -% (for images) or the binding energy shift data (for spectra) -% -% *output* -% Table variable bindingEnergy_eV holding the binding energy for -% the data. -% -% See also nappnappAlignImages.m nappBindingEnergyXps nappFitGaussXps.m -% nappCopyShift.m nappDetermineShiftXps.m - -% Define conditions and defaults of input -% Old region must be also selected in tableSelection! it is kind like -% double. -defaultRegionOld = 'O1s'; -expectedRegionOld = {'O1s','C1s','N1s'}; -defaultRegionNew = 'C1s'; -expectedRegionNew = {'O1s','C1s','N1s','Cl2p'}; -defaultTableSelection = true(size(DataTable,1)); -defaultEnergyScale = 'kinetic'; -expectedEnergyScale = {'kinetic','binding'}; - - -% Parse input -p = inputParser; -addRequired(p,'DataTable',@istable); -addOptional(p,'tableSelection',defaultTableSelection,@islogical); -addParameter(p,'regionOld',defaultRegionOld,... - @(x) any(validatestring(x,expectedRegionOld))); -addParameter(p,'regionNew',defaultRegionNew,... - @(x) any(validatestring(x,expectedRegionNew))); -addParameter(p,'energyScale',defaultEnergyScale,... - @(x) any(validatestring(x,expectedEnergyScale))); -parse(p,DataTable,varargin{:}); - -if contains(p.Results.energyScale,'kinetic') - % repeat this for all columns in input. - for ii = 1:size(p.Results.DataTable(p.Results.tableSelection,:),1) - % get name and date - tmpName = replace(p.Results.DataTable(p.Results.tableSelection,:).name{ii}, ... - p.Results.regionOld,p.Results.regionNew); - tmpDate = p.Results.DataTable(p.Results.tableSelection,:).lastModifiedDatenum(ii); - % select spectra - tmpDataSelection = contains(p.Results.DataTable.name,tmpName)... - & ismember(year(p.Results.DataTable.lastModifiedDatenum),year(tmpDate))... - & ismember(month(p.Results.DataTable.lastModifiedDatenum),month(tmpDate))... - & ismember(day(p.Results.DataTable.lastModifiedDatenum),day(tmpDate))... - & ismember(hour(p.Results.DataTable.lastModifiedDatenum),hour(tmpDate))... - & ismember(minute(p.Results.DataTable.lastModifiedDatenum),minute(tmpDate)); - - if ~any(tmpDataSelection) == 1 - disp('There is something wrong with the data time info') - disp(tmpName) - end - % replace the region in the name and copy the data - DataTable.kineticEnergyShift(tmpDataSelection,:) = p.Results.DataTable(p.Results.tableSelection,:).kineticEnergyShift(ii); - end -elseif contains(p.Results.energyScale,'binding') - % repeat this for all columns in input. - for ii = 1:size(p.Results.DataTable(p.Results.tableSelection,:),1) - % get name and date - tmpName = replace(p.Results.DataTable(p.Results.tableSelection,:).name{ii}, ... - p.Results.regionOld,p.Results.regionNew); - tmpDate = p.Results.DataTable(p.Results.tableSelection,:).lastModifiedDatenum(ii); - % select spectra - tmpDataSelection = contains(p.Results.DataTable.name,tmpName)... - & ismember(year(p.Results.DataTable.lastModifiedDatenum),year(tmpDate))... - & ismember(month(p.Results.DataTable.lastModifiedDatenum),month(tmpDate))... - & ismember(day(p.Results.DataTable.lastModifiedDatenum),day(tmpDate))... - & ismember(hour(p.Results.DataTable.lastModifiedDatenum),hour(tmpDate))... - & ismember(minute(p.Results.DataTable.lastModifiedDatenum),minute(tmpDate)); - if ~any(tmpDataSelection) == 1 - disp('There is something wrong with the data time info') - disp(tmpName) - end - % replace the region in the name and copy the data - DataTable.bindingEnergyShift(tmpDataSelection,:) = p.Results.DataTable(p.Results.tableSelection,:).bindingEnergyShift(ii); - end -end - -end \ No newline at end of file diff --git a/nappIce/nappDetermineShiftXps.m b/nappIce/nappDetermineShiftXps.m deleted file mode 100644 index 1d3d1c5..0000000 --- a/nappIce/nappDetermineShiftXps.m +++ /dev/null @@ -1,386 +0,0 @@ -function DataTable = nappDetermineShiftXps(DataTable,varargin) -%nappDetermineShiftXps determines the relative shift of each sequence -%iteration in images or the absolute shift of spectra to a binding energy reference -% -% FileList = nappDetermineShiftXps(FileList,eKinStart,eKinEnd,'tableSelection',tmpDataSelection,... -% 'showFigures','off','tableVariable','spectrum_countsPerSecond','binEnReference',535); -% -% FileList = nappDetermineShiftXps(FileList,'tableSelection',tmpDataSelection,... -% 'showFigures','on','tableVariable','image'); -% -% *input* -% FileList: data table -% eKinStart (optional): smallest value of energy range to use for -% peak fitting. Peak fitting is used to get position of peak -% eKinEnd (optional): largest value of energy energy range to use for -% peak fitting. Peak fitting is used to get position of peak -% tableSelection (optional): logical array to filter data table -% tableVariable: choose to process either -% 'spectrum_counts','spectrum_countsPerSecond' (default), => absolute binding energy shift will be determined or -% ,'image','imageRoh'=> relative kinetic energy shift will be determined. -% binEnReference: Reference BE in eV for spectra energy scale -% kinEnReference: Sequence iteration to which the image should be -% aligned, default is 1. -% minPeakWidth: findpeak parameter, default 0.1 -% minPeakHeight: findpeak parameter, default 0.1 -% movMeanWindow: findpeak parameter, default 1 -% showFigures, on(default): show fit in figure, off do not show fit in figure -% -% -% *output* -% new table variable kineticEnergyShift for images -% new table variable bindingEnergyShift for spectra -% -% -% *ToDo* -% -% FIXME: make use of O1s fit more general => use nappFitGaussXps.m function -% FIXME: Do not use peakfind for image fit => use nappFitGaussXps.m function -% -% -% See also nappnappAlignImages.m nappBindingEnergyXps nappFitGaussXps.m nappCopyShift.m - -defaultKinEnReference = 1; -defaultTableVariable = 'spectrum_countsPerSecond'; -expectedTableVariable = {'spectrum_counts','spectrum_countsPerSecond','image','imageRoh'}; -defaultTableSelection = true(size(DataTable,1)); -defaultMinPeakWidth = 0.1; -defaultMinPeakHeight = 0.1; -defaultMovMeanWindow = 1; -defaultShowFigures = 'off'; -expectedShowFigures = {'on','off'}; - - -%% - -% Parse input -p = inputParser; -addRequired(p,'DataTable',@istable); -addOptional(p,'eKinStart',@isnumeric) -addOptional(p,'eKinEnd',@isnumeric) -addParameter(p,'binEnReference',@isnumeric) -addParameter(p,'kinEnReference',defaultKinEnReference,@isnumeric) -addParameter(p,'tableSelection',defaultTableSelection,@islogical); -addParameter(p,'minPeakWidth',defaultMinPeakWidth,@isnumeric); -addParameter(p,'minPeakHeight',defaultMinPeakHeight,@isnumeric); -addParameter(p,'movMeanWindow',defaultMovMeanWindow ,@isnumeric); -addParameter(p,'tableVariable',defaultTableVariable,... - @(x) any(validatestring(x,expectedTableVariable))); -addParameter(p,'showFigures',defaultShowFigures,... - @(x) any(validatestring(x,expectedShowFigures))); -parse(p,DataTable,varargin{:}); - -% check input (all elements of input variable need to have non-zero size) -if ~all(cell2mat(cellfun(@size,p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable),'UniformOutput',false)),'all') - disp('The table variable appears to be empty. I quit now') - error('The table variable appears to be empty.') -end - -% add empty variable to table -if contains(p.Results.tableVariable,'image') - existColumn = strcmp('kineticEnergyShift',DataTable.Properties.VariableNames); - if ~any(existColumn) - DataTable.kineticEnergyShift = cell(size(DataTable,1),1); - end -else - existColumn = strcmp('bindingEnergyShift',DataTable.Properties.VariableNames); - if ~any(existColumn) - DataTable.bindingEnergyShift = NaN(size(DataTable,1),1); - end -end -%Colors; 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; - -% confirm that X-ray energy is set -if any(isnan(cell2mat(p.Results.DataTable(p.Results.tableSelection,:).xRayEkin_eV))) - disp('Opps, X-ray energy is empty. Please add manually. Will stop now'); - return -end -if matches(p.Results.tableVariable,'image') - % repeat this for all columns in input. - for ii = 1:size(p.Results.DataTable(p.Results.tableSelection,:),1) - %% - try - if isnumeric(p.Results.eKinStart) - start = find(p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii}... - >= p.Results.eKinStart,1); - stop = find(p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii}... - >= p.Results.eKinEnd,1); - else - start = 1; - stop = length(p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii}); - end - catch - warning('There is something wrong with the eKinStart and/or eKinEnd parameters'); - disp('There is something wrong with the eKinStart and/or eKinEnd parameters'); - end - - for ij = 1:size(p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii},2) - [B,x1,y1] = GaussFitOnePeak([p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii}(start:stop)',... - p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii}(start:stop,ij)]); - tmp_1(ij) = p.Results.DataTable(p.Results.tableSelection,:).xRayEkin_eV{ii}-B(3); - % plot result - if matches(p.Results.showFigures,'on') - % define equations to be plotted - Gauss = @(x,Hgt, Pos, Wdt) Hgt./(Wdt.*sqrt(pi/2))*exp(-2.*((x - Pos).^2/Wdt.^2)); - linear = @(x,slp,intrcpt) slp*x+intrcpt; - figure( 'Name', 'Gauss Multi Fit ') - tiledlayout(1,1) - nexttile; - %Define gauss peaks with hight, position, width from fitting results - yData_pk1= Gauss(x1 ,B(1), B(3), B(2)); - yData_pk2= Gauss(x1 ,B(4), B(6), B(5)); - bkgrd = linear(x1,B(7),B(8)); - % plot data - plot(x1,y1,'.') - hold on - % plot fit - h = plot(x1,yData_pk1+yData_pk2+bkgrd); - h.LineWidth=2; - h.Color = PsiFarbe.dunkelblau; - % plot each gauss peak - h = plot(x1,yData_pk1+bkgrd); - h.LineWidth=1.5; - h.Color = PsiFarbe.gelb; - h = plot(x1,yData_pk2+bkgrd); - h.LineWidth=1.5; - h.Color = PsiFarbe.gelb; - - legend OFF - xlabel('Kinetic Energy [eV]'); - ylabel('PE intensity [-]'); - grid on - - % List results in table - - disp('Results'); - disp(' ' ); - disp(cell2table({sprintf('%.1f',B(3)),... - sprintf('%.1f',B(2)*sqrt(log(4))),... - sprintf('%.1f',B(2)),... - sprintf('%7.0f',B(1))},... - 'VariableNames',{'position';'FWHW';'width';'area'},... - 'RowNames',{'pk 1'})); - end - end - %% - - - DataTable(p.Results.tableSelection,:).kineticEnergyShift{ii} = tmp_1-tmp_1(p.Results.kinEnReference); - clearvars tmp_1 - fh = findobj( 'Type', 'Figure', 'Name', 'Gauss Multi Fit '); - close(fh) - fh = findobj( 'Type', 'Figure', 'Name', 'GlobalSearch'); - close(fh) - end -elseif matches(p.Results.tableVariable,'imageRoh') - % repeat this for all columns in input. - for ii = 1:size(p.Results.DataTable(p.Results.tableSelection,:),1) - - %% - try - if isnumeric(p.Results.eKinStart) && isempty(DataTable(p.Results.tableSelection,:).scientaEkinRoh_eV{ii}) - start = find(p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii}... - >= p.Results.eKinStart,1); - stop = find(p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii}... - >= p.Results.eKinEnd,1); - elseif isnumeric(p.Results.eKinStart) && ~isempty(DataTable(p.Results.tableSelection,:).scientaEkinRoh_eV{ii}) - start = find(p.Results.DataTable(p.Results.tableSelection,:).scientaEkinRoh_eV{ii}... - >= p.Results.eKinStart,1); - stop = find(p.Results.DataTable(p.Results.tableSelection,:).scientaEkinRoh_eV{ii}... - >= p.Results.eKinEnd,1); - elseif isempty(DataTable(p.Results.tableSelection,:).scientaEkinRoh_eV{ii}) - start = 1; - stop = length(p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii}); - else - start = 1; - stop = length(DataTable(p.Results.tableSelection,:).scientaEkinRoh_eV{ii}); - end - catch - warning('There is something wrong with the eKinStart and/or eKinEnd parameters'); - disp('There is something wrong with the eKinStart and/or eKinEnd parameters'); - end - for ij = 1:size(p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii},2) - if isempty(DataTable(p.Results.tableSelection,:).scientaEkinRoh_eV{ii}) - [B,x1,y1] = GaussFitOnePeak([p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii}(start:stop)',... - p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii}(start:stop,ij)]); - else - [B,x1,y1] = GaussFitOnePeak([DataTable(p.Results.tableSelection,:).scientaEkinRoh_eV{ii}(start:stop)',... - p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii}(start:stop,ij)]); - end - - tmp_1(ij) = p.Results.DataTable(p.Results.tableSelection,:).xRayEkin_eV{ii}-B(3); - % plot result - if matches(p.Results.showFigures,'on') - % define equations to be plotted - Gauss = @(x,Hgt, Pos, Wdt) Hgt./(Wdt.*sqrt(pi/2))*exp(-2.*((x - Pos).^2/Wdt.^2)); - linear = @(x,slp,intrcpt) slp*x+intrcpt; - figure( 'Name', 'Gauss Multi Fit ') - tiledlayout(1,1) - nexttile; - %Define gauss peaks with hight, position, width from fitting results - yData_pk1= Gauss(x1 ,B(1), B(3), B(2)); - yData_pk2= Gauss(x1 ,B(4), B(6), B(5)); - bkgrd = linear(x1,B(7),B(8)); - % plot data - plot(x1,y1,'.') - hold on - % plot fit - h = plot(x1,yData_pk1+yData_pk2+bkgrd); - h.LineWidth=2; - h.Color = PsiFarbe.dunkelblau; - % plot each gauss peak - h = plot(x1,yData_pk1+bkgrd); - h.LineWidth=1.5; - h.Color = PsiFarbe.gelb; - h = plot(x1,yData_pk2+bkgrd); - h.LineWidth=1.5; - h.Color = PsiFarbe.gelb; - - legend OFF - xlabel('Kinetic Energy [eV]'); - ylabel('PE intensity [-]'); - grid on - - % List results in table - - disp('Results'); - disp(' ' ); - disp(cell2table({sprintf('%.1f',B(3)),... - sprintf('%.1f',B(2)*sqrt(log(4))),... - sprintf('%.1f',B(2)),... - sprintf('%7.0f',B(1))},... - 'VariableNames',{'position';'FWHW';'width';'area'},... - 'RowNames',{'pk 1'})); - end - end - %% - - DataTable(p.Results.tableSelection,:).kineticEnergyShift{ii} = tmp_1-tmp_1(p.Results.kinEnReference); - clearvars tmp_1 - fh = findobj( 'Type', 'Figure', 'Name', 'Gauss Multi Fit '); - close(fh) - fh = findobj( 'Type', 'Figure', 'Name', 'GlobalSearch'); - close(fh) - end -else - % repeat this for all columns in input. - for ii = 1:size(p.Results.DataTable(p.Results.tableSelection,:),1) - %% - try - if isnumeric(p.Results.eKinStart) - start = find(p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii}... - >= p.Results.eKinStart,1); - stop = find(p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii}... - >= p.Results.eKinEnd,1); - else - start = 1; - stop = length(p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii}); - end - catch - warning('There is something wrong with the eKinStart and/or eKinEnd parameters'); - disp('There is something wrong with the eKinStart and/or eKinEnd parameters'); - end - if contains(p.Results.showFigures,'on') - figure - - findpeaks(movmean(p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii}(start:stop),... - p.Results.movMeanWindow),... - p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii}(start:stop),... - 'MinPeakWidth',p.Results.minPeakWidth,'MinPeakHeight',p.Results.minPeakHeight) - end - [pks,locs]=findpeaks(movmean(p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii}(start:stop),... - p.Results.movMeanWindow),... - p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii}(start:stop),... - 'MinPeakWidth',p.Results.minPeakWidth,'MinPeakHeight',p.Results.minPeakHeight); - - %% - - [~,I] = max(pks); - tmp_1(ii,1) = p.Results.DataTable(p.Results.tableSelection,:).xRayEkin_eV{ii}-locs(I)-p.Results.binEnReference; - clearvars tmp_2 - end - - DataTable.bindingEnergyShift(p.Results.tableSelection) = tmp_1; -end - -end -function [B,x1,y1] = GaussFitOnePeak(data1) - - -[x1, y1] = prepareCurveData(data1(:,1),data1(:,2)); - -% make data slimmer so that background makes sense -[~,I] = max(y1); -tmp1 = find(x1>=x1(I)-5,1); -tmp2 = find(x1>=x1(I)+5,1); -if isempty(tmp2) - y1 = y1(tmp1:end); - x1 = x1(tmp1:end); -else - y1 = y1(tmp1:tmp2); - x1 = x1(tmp1:tmp2); -end -[~,I] = max(y1); - -% Define equation to fit data -% I use the area Gauss equations here, which I took from the OriginPro -% documentation. https://www.originlab.com/doc/Origin-Help/Gauss-FitFunc -% -% Gauss = area/(width*sqrt(pi/2)) * exp(-2*(x-position)^2/width^2) -% -% where FWHM = width * sqrt(ln(4)) - -% Data set 1: -yfcn1 = @(b,x)... - b(1)/(b(2)*sqrt(pi/2))*exp(-2.*((x(:,1) - b(3)).^2/b(2).^2)) ... % Gauss peak 1: C-H, Ac- - + b(4)/(b(5)*sqrt(pi/2))*exp(-2.*((x(:,1)- b(6)).^2/b(5).^2))... % Gauss peak 2: C-OOH, Ac- - +b(7).*x(:,1)+b(8); % linear background - -B0 = [80000 1.5 x1(I) ... - 10 1.0 x1(I)-4 ... - 0 0]; - - -% lower bonds -lb = [1000 0.5 x1(I)-1. ... - 10 1.0 x1(I)-5 ... - -Inf -Inf]; - - -% upper bond -ub = [Inf 3 x1(I)+1 ... - 10 1.0 x1(I)-3 ... - Inf Inf]; - - -% Fit equations: Gauss eq. 1 with data -yfcn = @(b,x) yfcn1(b,x); -% We find an optimal fit by minimising the residuals: -fitfcnw = @(b) sum((y1 - yfcn(b,x1)).^2); - -problem = createOptimProblem('fmincon', 'x0',B0, 'lb',lb,'ub',ub, 'objective',fitfcnw); -gs = GlobalSearch('PlotFcns',@gsplotbestf); -B = run(gs,problem); - - - - -end \ No newline at end of file diff --git a/nappIce/nappFileList.m b/nappIce/nappFileList.m deleted file mode 100644 index 7e48225..0000000 --- a/nappIce/nappFileList.m +++ /dev/null @@ -1,1098 +0,0 @@ -function ListFiles = nappFileList(dataPath,varargin) -% nappFileList lists all XAS, PE, and picture data of a specific beam -% time. Analyser and sample settings such as pass energy, lens mode, -% temperature, position, and pressure are added. -% -% -% * listFiles = nappFileList('2019\April_NanoXAS') imports data from beam -% time folder on local computer, generates a new matlab table 'listFiles' -% in the current workspace, and a csv file from data in the -% 'SC_Data/2019/April_NanoXAS' . -% -% * listFiles = nappFileList('2019\April_NanoXAS',listFiles) imports data from beam -% time folder on local computer, adds data to the existing matlab table -% 'listFiles' in the current workspace, and a csv file from data in the -% 'SC_Data/2019/April_NanoXAS' . -% -% Input Arguments -% -% * dataPath, mandatory: year and name of folder that holds the beam time data. -% Text string with format year/name of folder: '2019/April_NanoXAS' -% * DataTable, optional: DataTable to which imported data is added. -% * 'mode','local'; default: imports from local server address -% * 'mode','nappDrive'; imports from napp drive. Needs to be mounted. -% * 'mode','localNew'; imports only new files that have not yet been -% imported. Needs existing data table as input. -% * 'mode','nappDrivePick'; lets user select files in file browser window. Default address is Napp beam time folder. -% * 'mode','localPick'; lets user select files in file browser window. Default address is local beam time folder. -% -% Dependencies -% -% * beam time folder must be located at server/NAPP/SC Data/dataPath. -% dataPath is user input. server needs to be defined at line ~100 of this -% function. -% * XPS data in igor *.ibw format need to be in SES subfolder -% * Photos in *.bmp format need to be in Photos folder -% * NEXAFS data in *.h5 format need to be in NEXAFS subfolder -% * Labview pressure and temperature log need to be in Pressure subfolder. -% * Uses the IgorPro importer for Matlab: -% https://ch.mathworks.com/matlabcentral/fileexchange/42679-igor-pro-file-format-ibw-to-matlab-variable -% * needs at least 1 .*ibw file in the SES subfolder -% -% -% Output -% -% * ListFiles: Matlab table listing XPS, NEXAFS, and photo files with settings -% * YYYYmmm_DataList.csv (2019Apr_DataList.csv): Semicolon separated ASCII -% file for import to Excel in beamtime folder -% -% -% Further info -% -% * Do not run while SES or NEXAFS data are being recorded. Data will be -% lost by SES software. -% * Region iterations are averaged during import -% * counts are normalised to 1s dwell time during import. That is, the -% counts are in cps after import. -% -% -% Matlab Version -% -% * Matlab 2018a or higher -% -% -% See also TABLE IBWread h5read DIR LabView_importData -% -%% -% -% TODO -% -% * FIXME: Add videos and jpg -% -%% Updated -% -% * January 2020, added new h5 file structure and naming convention. -% * March 2021, added possibility to work on local file structure -% * March 2021, added Lens Mode as column (have not tested this for older -% NEXAFS files). -% * April 2021, X-ray kinetic energy and images are now made unique -% * March 2022, input now using varargin -% * March 2022, strict data structure required for local and remote sources - -%% Input -% Define conditions and defaults of input -defaultMode = 'local'; -expectedMode = {'local','nappDrive','localNew','nappDrivePick','localPick'}; -defaultImportLabView = 'on'; -expectedImportLabView = {'on','off'}; -% Parse input -p = inputParser; -addRequired(p,'dataPath'); -addOptional(p,'DataTable',@istable); -addParameter(p,'mode',defaultMode,... - @(x) any(validatestring(x,expectedMode))); -addParameter(p,'importLabView',defaultImportLabView,... - @(x) any(validatestring(x,expectedImportLabView))); -parse(p,dataPath,varargin{:}); -%% Data Paths -% -% Mac and Windows use different notations to address network drives. For -% windows, we use the UNC naming convention. This is a more recent way to -% address mounted drives that does not rely on the use of drive letters. -% The letters might be different for the same drive on different computer. - - -if contains(p.Results.mode,'local') - % Data server address - if ismac - server = '/Users/bartels-rausch/Forschung_Einsam/PSI_SLS/'; - elseif ispc - server = userpath; - end -elseif contains(p.Results.mode,'nappDrive') - % Data server address - if ismac - server = '/Volumes/'; - elseif ispc - server = '\\fs03\'; - end -end -dataPath = fullfile(server,'NAPP','SC Data',dataPath); -% Data Paths to subdirectories for specific files: -dataPath_XPS = fullfile(dataPath, 'SES'); -dataPath_Photo = fullfile(dataPath, 'Photos'); -dataPath_NEXAFS = fullfile(dataPath, 'NEXAFS'); -dataPath_LabView = fullfile(dataPath, 'Pressure'); - -% -if ~isfolder(dataPath_XPS) - warning('There is something wrong with the path. Check for typo and that the drives are mounted') - disp('There is something wrong with the path. Check for typo and that the drives are mounted') - disp('I quit now') - return -end - - -%% Naming Convention -% -% See: MATLAB Programming Style Guidelines, by Richard Johnson -% -% * Variable: mixed case words starting with lower case: credibleThreat, qualityOfLife -% * Variables with a large scope should have meaningful names. Variables -% with a small scope can have short names. -% * A convention on pluralisation should be followed consistently. -% * Named constants (including globals) should be all uppercase using -% underscore to separate words. MAX_ITERATIONS, COLOR_RED -% * Structure names should begin with a capital letter: SegmentData.length -% * The prefix n should be used for variables representing the number of -% objects. A MATLAB-specific addition is the use of m for number of rows -% (based on matrix notation). nFiles, mRows -% * Iterator variables should be named or prefixed with i. for iPosition = -% 1:nPositions, ii, ij, ik.... -% * Functions should have meaningful names written in lower case. -% computetotalwidth(), Avoid compwid(); -% - - - -%% Query beam time folder content -% -% We use MATLAB's 'dir' command which writes the content of a folder into a -% structure with the following fields: -% -% * name -% * folder -% * date -% * bytes -% * isdir -% * datenum -% -% XPS data: Create a structure 'TmpFileList{1}' with all Igor files in the -% directory and its subfolders (1st level). The '\N*' at the beginning is -% important. Otherwise hidden files starting with a . will also be listed. -% Obviously, Igor file names from SES software and h5 file names from Epics -% (NEXAFS) need to start with an N, otherwise change the search term below: -% -% THE ** notation needs a recent version of Matlab, 2014 does not work. - -if endsWith(p.Results.mode,'Pick') - % select files (Xps or Nexafs, ignoring photos) to be imported from data directory - % (data can be taken from any directory; files need to be in same directory) - [filePick,pathPick] = uigetfile({'*.ibw;*.h5'},... - 'Select One or More Files', dataPath,... - 'MultiSelect', 'on'); - % make lists for Nexafs and for XPS - if ischar(filePick) - filePick = {filePick}; - end - filePickXps = filePick(endsWith(filePick,'.ibw')); - filePickNexafs = filePick(endsWith(filePick,'.h5')); - - if isempty(filePickXps) - TmpFileList{1} = dir([dataPath_XPS filesep '**' filesep '*.trallalla']); - else - for ii = 1:size(filePickXps,2) - TmpFileList{1}(ii,1) = dir([pathPick filePickXps{ii}]); - end - end - if isempty(filePickNexafs) - TmpFileList{2} = dir([dataPath_NEXAFS filesep '**' filesep '*.trallalla']); - else - for ii = 1:size(filePickNexafs,2) - TmpFileList{2}(ii,1) = dir([pathPick filePickNexafs{ii}]); - end - end - % make a empty file list for photos, to be consitent with code - TmpFileList{3} = dir([dataPath_Photo filesep '**' filesep '*.trallalla']); -else - - % SES files in IGOR format list all files, then get rid of system files - TmpFileList{1} = dir([dataPath_XPS filesep '**' filesep '*.ibw']); - TmpFileList{1} = TmpFileList{1}(find(~cellfun(@isempty,regexp({TmpFileList{1}.name},'^[a-zA-Z0-9]\w*')))); %#ok - % EPICS files in h5 format list all files, then get rid of system files - TmpFileList{2} = dir([dataPath_NEXAFS filesep '**' filesep '*.h5']); - TmpFileList{2} = TmpFileList{2}(find(~cellfun(@isempty,regexp({TmpFileList{2}.name},'^[a-zA-Z0-9]\w*')))); %#ok - % Photos list all files, then get rid of system files - TmpFileList{3} = dir([dataPath_Photo filesep '**' filesep '*.bmp']); - TmpFileList{3} = TmpFileList{3}(find(~cellfun(@isempty,regexp({TmpFileList{3}.name},'^[a-zA-Z0-9]\w*')))); %#ok - - % The second line of code filters all files that start with Numbers or - % letters. All system files starting with a . or ~ are discarded. - - % only process new files - if (istable(p.Results.DataTable) & matches(p.Results.mode,'localNew')) % do this only if previous list was input to function call - tmpXpsFiles = endsWith(p.Results.DataTable.name,'.ibw'); % get XPS files in current data table - tmpMissingFiles = ~ismember({TmpFileList{1}(:).name},p.Results.DataTable.name(tmpXpsFiles,:)); % find those files that are yet imported - TmpFileList{1} = TmpFileList{1}(tmpMissingFiles); - - tmpNexafsFiles = endsWith(p.Results.DataTable.name,'.h5'); % get XPS files in current data table - tmpMissingFiles = ~ismember({TmpFileList{2}(:).name},p.Results.DataTable.name(tmpNexafsFiles,:)); % find those files that are yet imported - TmpFileList{2} = TmpFileList{2}(tmpMissingFiles); - - tmpPhotoFiles = endsWith(p.Results.DataTable.name,'.bmp'); % get XPS files in current data table - tmpMissingFiles = ~ismember({TmpFileList{3}(:).name},p.Results.DataTable.name(tmpPhotoFiles,:)); % find those files that are yet imported - TmpFileList{3} = TmpFileList{3}(tmpMissingFiles); - - end -end - - - -% get date of last and first .ibw file in folder . -tmp.fileinfo = dir([dataPath_XPS '/*.ibw']); -if isempty(tmp.fileinfo) - warning('There appears to be no file in the SES folder. Add at least one file first.') - disp('There appears to be no file in the SES folder. Add at least one file first.') - disp('I quit now') - return -end - -try - tmp.fileinfo = dir([dataPath_XPS '/*.ibw']); - filedate_first = tmp.fileinfo(1).datenum; - clearvars name tmp -catch - disp('Error getting ibw file date.') -end - -%% Import XPS data to get SES settings -% -% Uses the IgorPro importer for Matlab: -% https://ch.mathworks.com/matlabcentral/fileexchange/42679-igor-pro-file-format-ibw-to-matlab-variable -% -% Normally, Matlab stops when an error occurs. I use 'try' to force Matlab -% to continue even if an error occurs. Matlab will instead print a warning, -% as defined after the 'catch'. Error might occur when single data files -% can't be read. If a warning comes up, check the corresponding data file -% and try to resolve it. I suggest to rename these original data files that -% are damaged, or not complete (because measurement was aborted) to -% "ignore_filename". - -for ii = 1:size(TmpFileList{1},1) % cycle through each XPS file - - - try - PE = IBWread([TmpFileList{1}(ii).folder filesep TmpFileList{1}(ii).name]); % read XPS file - catch - warning('Problem reading the Igor file') - disp('Problem reading the Igor file') - fprintf('Number %.0f: %s \n',ii,[TmpFileList{1}(ii).folder filesep TmpFileList{1}(ii).name]) - end - fclose('all'); - - try - %% Convert SES meta data into variables - % - % Upon import, all meta data are written into _WaveNotes_ variable. - % Here, I select the meta data for each setting and write those - % into individual variables that are then added to the list. - - % Split the WaveNotes text string into individual strings at each line break. - % (This is a work-around. Did not manage to select values with regexp - % function only.) - tmp = regexp(PE.WaveNotes, '\r', 'split'); - % Then, read out the values into variables using a combination of string operations: - - % Start date/time of measurement - PE.creationDate = datevec([char(regexp(tmp{29},'((?<=Date=).*)','match')) ... - ' ' char(regexp(tmp{30},'((?<=Time=).*)','match'))]); - % Pass energy - PE.passEnergy = str2double(char(regexp(tmp{5},'((?<=Pass Energy=).*)','match'))); - % Dwell time (or step time) - PE.dwellTime = str2double(char(regexp(tmp{15},'((?<=Step Time=).*)','match'))); - % Energy step - PE.scientaEkinStep = str2double(char(regexp(tmp{14},'((?<=Energy Step=).*)','match'))); - % Region name - PE.regionName = char(regexp(tmp{3},'((?<=Region Name=).*)','match')); - % Acquisition Mode - PE.acquisitionMode = char(regexp(tmp{9},'((?<=Acquisition Mode=).*)','match')); - - % kinetic energy - for n = 1:size(PE.y,1) - PE.x(n)= PE.x0(1) + (n-1)*PE.dx(1); - end - % lens mode - PE.lensMode = char(regexp(tmp{4},'((?<=Lens Mode=).*)','match')); - % define iterations - if PE.Ndim == 3 - PE.regionIterations = size(PE.y,2); - PE.sequenceIterations = size(PE.y,3); - else - PE.regionIterations = 1; - PE.sequenceIterations = size(PE.y,2); - end - - % average region iterations - if PE.Ndim == 3 - PE.y = squeeze(mean(PE.y,2)); - end - % normalise data to 1ms - PE.y = PE.y .* 1000 ./ PE.dwellTime; - % Pass energy - PE.passEnergy = str2double(char(regexp(tmp{5},'((?<=Pass Energy=).*)','match'))); - catch - warning('Problem reading the PE variable') - disp('Problem reading the PE variable') - fprintf('Number %.0f: %s \n',ii,[TmpFileList{1}(ii).folder filesep TmpFileList{1}(ii).name]) - end - - %% Write SES meta data variables into XPS FileList structure - - try - TmpFileList{1}(ii).creationDate = PE.creationDate; - TmpFileList{1}(ii).image = PE.y; - TmpFileList{1}(ii).spectrum_counts = NaN; - TmpFileList{1}(ii).spectrum_countsPerSecond = NaN; - TmpFileList{1}(ii).xRayEkin_eV = NaN; - TmpFileList{1}(ii).xRayEkinRange_eV = [NaN NaN]; - % SES pass energy - TmpFileList{1}(ii).scientaPassEnergy_eV = PE.passEnergy; % in eV - % SES dwell time - TmpFileList{1}(ii).scientaDwellTime_ms = PE.dwellTime; % in ms - % SES region Name - TmpFileList{1}(ii).regionName = PE.regionName; - TmpFileList{1}(ii).scientaAcquisitionMode = PE.acquisitionMode; - % SES kinetic energy window - TmpFileList{1}(ii).scientaEkinRange_eV = [PE.x(1) PE.x(end)]; - TmpFileList{1}(ii).scientaEkinStep_eV = PE.scientaEkinStep; - TmpFileList{1}(ii).scientaEkin_eV = PE.x; - % Beamline Intensity (I0 during NEXAFS) - TmpFileList{1}(ii).beamlineInt = cell(1); - % SES lens mode - TmpFileList{1}(ii).scientaLensMode = PE.lensMode; - TmpFileList{1}(ii).scientaRegionIterations = PE.regionIterations; - TmpFileList{1}(ii).scientaSequenceIterations = PE.sequenceIterations; - TmpFileList{1}(ii).imageRoh = PE.y; - TmpFileList{1}(ii).spectrum_countsPerSecondRoh = NaN; - TmpFileList{1}(ii).importDate = datestr(now); - try - TmpFileList{1}(ii).analysisDir = file.mFile; - catch - TmpFileList{1}(ii).analysisDir = pwd; - end - catch - warning('Problem with a XPS data file for XPS list') - disp('Problem with a XPS data file for XPS list') - fprintf('Number %.0f: %s \n',ii,[TmpFileList{1}(ii).folder filesep TmpFileList{1}(ii).name]) - fprintf('Number %.0f: %s \n',ii,datestr(TmpFileList{1}(ii).datenum)) - end - -end -disp('*************************************************') -disp('* Voila: Done reading & writing XPS data! *') -disp('*************************************************') - - -%% Read and write NEXAFS meta data -% -% The h5 file is much nicer organised, so we do not need string operations -% to select individual meta data. The data can be directly addressed and -% written into the list structure: - -if datenum(filedate_first) >= datenum('31-Dec-2019 23:59:00') - for ii = 1:size(TmpFileList{2},1) % do this for each list element - - %if ~isempty(h5read([TmpFileList{2}(ii).folder filesep TmpFileList{2}(ii).name],'/scan 1/energy')) - % creation date of file - TmpFileList{2}(ii).creationDate = datevec(NaN); - try - % read data - %if datenum(filedate_first) <= datenum('21-Nov-2020 00:01:00') % Date not exaclty certain. - try - TmpImage= h5read([TmpFileList{2}(ii).folder filesep TmpFileList{2}(ii).name],'/scan 1/spectrum'); - %else - catch - TmpImage = h5read([TmpFileList{2}(ii).folder filesep TmpFileList{2}(ii).name],'/scan 1/scienta spectrum'); - end - % 21.8.20 changed from spectrum to scienta spectrum, later - % switched back to scienta. - - % Spectrum - TmpFileList{2}(ii).spectrum_counts = NaN; - TmpFileList{2}(ii).spectrum_countsPerSecond = NaN; - - % import Photon Energy (cols) - TmpXrayEkin = h5read([TmpFileList{2}(ii).folder filesep TmpFileList{2}(ii).name],'/scan 1/energy'); % X-ray excitation energy; Photon energy in eV - TmpXrayEkin(TmpXrayEkin==0)=[]; - - if isempty(TmpXrayEkin) - TmpFileList{2}(ii).xRayEkinRange_eV = [NaN NaN]; - else - TmpFileList{2}(ii).xRayEkinRange_eV = [TmpXrayEkin(1) TmpXrayEkin(end)]; - end - - % Make unique - [TmpFileList{2}(ii).xRayEkin_eV, ind] = unique(TmpXrayEkin); - TmpFileList{2}(ii).image = TmpImage(:,ind); - - % NEXAFS pass energy - tmp = h5read([TmpFileList{2}(ii).folder filesep TmpFileList{2}(ii).name],'/scan 1/attrs/PassEnergy'); % in eV - TmpFileList{2}(ii).scientaPassEnergy_eV = str2double(tmp(1)); - - - % NEXAFS dwell time - if datenum(filedate_first) >= datenum('1-Feb-2020 23:59:00') - tmp = h5read([TmpFileList{2}(ii).folder filesep TmpFileList{2}(ii).name],'/scan 1/attrs/ScientaStepTime')*1000; % in ms - - else - tmp = h5read([TmpFileList{2}(ii).folder filesep TmpFileList{2}(ii).name],'/scan 1/attrs/StepTime')*1000; % in ms - end - TmpFileList{2}(ii).scientaDwellTime_ms = tmp(1); - % NEXAFS region Name - if TmpFileList{2}(ii).xRayEkinRange_eV(:,1) <= 530 && TmpFileList{2}(ii).xRayEkinRange_eV(:,2) >= 530 - TmpFileList{2}(ii).regionName = 'O K-edge NEXAFS'; - else - TmpFileList{2}(ii).regionName = 'NEXAFS'; - end - - % Acquisition mode - TmpFileList{2}(ii).scientaAcquisitionMode = h5read([TmpFileList{2}(ii).folder filesep TmpFileList{2}(ii).name],'/scan 1/attrs/AcquisitionMode'); - if strcmp(TmpFileList{2}(ii).scientaAcquisitionMode,'Fixed') - % NEXAFS kinetic energy window - fixed mode - tmp = h5read([TmpFileList{2}(ii).folder filesep TmpFileList{2}(ii).name],'/scan 1/attrs/ScientaCenterEnergy'); % in eV - TmpFileList{2}(ii).scientaEkinRange_eV = [tmp(1)-TmpFileList{2}(ii).scientaPassEnergy_eV/20 tmp(1)+TmpFileList{2}(ii).scientaPassEnergy_eV/20]; - TmpFileList{2}(ii).scientaEkinStep_eV = NaN; - TmpFileList{2}(ii).scientaEkin_eV = linspace(TmpFileList{2}(ii).scientaEkinRange_eV(:,1)... - ,TmpFileList{2}(ii).scientaEkinRange_eV(:,2),size(TmpFileList{2}(ii).image,1))'; - else - % NEXAFS kinetic energy window - scan mode - tmp = h5read([TmpFileList{2}(ii).folder filesep TmpFileList{2}(ii).name],'/scan 1/attrs/ScientaLowEnergy'); % in eV - tmp2 = h5read([TmpFileList{2}(ii).folder filesep TmpFileList{2}(ii).name],'/scan 1/attrs/ScientaHighEnergy'); - TmpFileList{2}(ii).scientaEkinRange_eV = [tmp(1) tmp2(1)]; - TmpFileList{2}(ii).scientaEkinStep_eV = h5read([TmpFileList{2}(ii).folder filesep TmpFileList{2}(ii).name],'/scan 1/attrs/StepSize'); - TmpFileList{2}(ii).scientaEkin_eV = [TmpFileList{2}(ii).scientaEkinRange_eV(:,1):TmpFileList{2}(ii).scientaEkinStep_eV(1):TmpFileList{2}(ii).scientaEkinRange_eV(:,2)]'; - end - - % read I_0 - tmp = h5read([TmpFileList{2}(ii).folder filesep TmpFileList{2}(ii).name],'/scan 1/i0'); - TmpFileList{2}(ii).beamlineInt = abs(tmp(ind)); - - % Lens Mode - tmp = h5read([TmpFileList{2}(ii).folder filesep TmpFileList{2}(ii).name],'/scan 1/attrs/LensMode'); - TmpFileList{2}(ii).scientaLensMode = tmp{1}; - clearvars tmp - - TmpFileList{2}(ii).scientaRegionIterations = h5read([TmpFileList{2}(ii).folder filesep TmpFileList{2}(ii).name],'/scan 1/attrs/NumIterations'); - TmpFileList{2}(ii).scientaSequenceIterations = 1; - - catch - warning('Problem with a NEXAFS data file in NEXAFS list') - disp('Problem with a NEXAFS data file in NEXAFS list') - fprintf('Number %.0f: %s \n',ii,[TmpFileList{2}(ii).folder filesep TmpFileList{2}(ii).name]) - fprintf('Number %.0f: %s \n',ii,datestr(TmpFileList{2}(ii).datenum)) - end - - TmpFileList{2}(ii).imageRoh = TmpFileList{2}(ii).image; - TmpFileList{2}(ii).spectrum_countsPerSecondRoh = TmpFileList{2}(ii).spectrum_countsPerSecond; - % log - TmpFileList{2}(ii).importDate = datestr(now); - try - TmpFileList{2}(ii).analysisDir = file.mFile; - catch - TmpFileList{2}(ii).analysisDir = pwd; - end - end - %end -else - for ii = 1:size(TmpFileList{2},1) % do this for each list element - try - % NEXAFS pass energy - tmp = h5read([TmpFileList{2}(ii).folder filesep TmpFileList{2}(ii).name],'/entry/instrument/NDAttributes/PassEnergy'); % in eV - % TODO: Confirm that this assignment is correct. (The number refer to the list number in epics software) - if tmp(1) == 1 - TmpFileList{2}(ii).passEnergy_eV = {[20]}; - elseif tmp(1) == 2 - TmpFileList{2}(ii).passEnergy_eV = {[50]}; - elseif tmp(1) == 3 - TmpFileList{2}(ii).passEnergy_eV = {[100]}; - elseif tmp(1) == 4 - TmpFileList{2}(ii).passEnergy_eV = {[200]}; - end - - % NEXAFS dwell time - if datenum(filedate_first) >= datenum('1-Feb-2020 23:59:00') - tmp = h5read([TmpFileList{2}(ii).folder filesep TmpFileList{2}(ii).name],'/entry/instrument/NDAttributes/ScientaStepTime')*1000; % in ms - - else - tmp = h5read([TmpFileList{2}(ii).folder filesep TmpFileList{2}(ii).name],'/entry/instrument/NDAttributes/StepTime')*1000; % in ms - end - TmpFileList{2}(ii).dwellTime_ms = tmp(1); - % NEXAFS region Name - TmpFileList{2}(ii).regionName = 'NEXAFS'; - % FIXME: Can we differentiate O K-edge, N K-edge, C K-edge based on the h5-file meta data? - - % NEXAFS kinetic energy window - tmp = h5read([TmpFileList{2}(ii).folder filesep TmpFileList{2}(ii).name],'/entry/instrument/NDAttributes/LowEnergy'); % in eV - tmp2 = h5read([TmpFileList{2}(ii).folder filesep TmpFileList{2}(ii).name],'/entry/instrument/NDAttributes/HighEnergy'); - TmpFileList{2}(ii).kinRange_eV = [tmp(1) tmp2(1)]; - - % Lens mode - tmp = h5read([TmpFileList{2}(ii).folder filesep TmpFileList{2}(ii).name],'/entry/instrument/NDAttributes/LensMode'); - TmpFileList{2}(ii).scientaLensMode = tmp{1}; - clearvars tmp - catch - warning('Problem with a NEXAFS data file in NEXAFS list') - disp('Problem with a NEXAFS data file in NEXAFS list') - fprintf('Number %.0f: %s \n',ii,[TmpFileList{2}(ii).folder filesep TmpFileList{2}(ii).name]) - fprintf('Number %.0f: %s \n',ii,datestr(TmpFileList{2}(ii).datenum)) - end - - end -end - -% check for empty entries - -disp('*************************************************') -disp('* Voila: Done reading and writing NEXAFS data! *') -disp('*************************************************') -%% Create Picture List -% -% The file structure needs same number of fields as SES and NEXAFS data. -% Set them to NaN (Not-a-Number). - - -for ii = 1:size(TmpFileList{3},1) % do this for each picture in the list - - - TmpFileList{3}(ii).creationDate = datevec(NaN); - TmpFileList{3}(ii).image = NaN; - TmpFileList{3}(ii).spectrum_counts = NaN; - TmpFileList{3}(ii).spectrum_countsPerSecond = NaN; - TmpFileList{3}(ii).xRayEkin_eV = NaN; - TmpFileList{3}(ii).xRayEkinRange_eV = [NaN NaN]; - TmpFileList{3}(ii).scientaPassEnergy_eV = NaN; - TmpFileList{3}(ii).scientaDwellTime_ms = NaN; - TmpFileList{3}(ii).regionName = ' '; - TmpFileList{3}(ii).scientaAcquisitionMode = ' '; - TmpFileList{3}(ii).scientaEkinRange_eV = [NaN NaN]; - TmpFileList{3}(ii).scientaEkinStep_eV = NaN; - TmpFileList{3}(ii).scientaEkin_eV = NaN; - TmpFileList{3}(ii).beamlineInt = cell(1); - TmpFileList{3}(ii).scientaLensMode = ' '; - TmpFileList{3}(ii).scientaRegionIterations = NaN; - TmpFileList{3}(ii).scientaSequenceIterations = NaN; - TmpFileList{3}(ii).imageRoh = {NaN}; - TmpFileList{3}(ii).spectrum_countsPerSecondRoh = NaN; - TmpFileList{3}(ii).importDate = ' '; - TmpFileList{3}(ii).analysisDir = ' '; - - -end - - -%% Merge lists into one -% - -% get index of non-empty structures -tf =~cellfun(@isempty,TmpFileList); - -% merge the non-empty list structures into one structure -ListFiles = cat(1,TmpFileList{tf}); - -% remove lines with empty images -for ii = 1:size(ListFiles,1) - tmpLogic(ii) = isempty(ListFiles(ii).image); - noncells = tmpLogic; -end -ListFiles(noncells) = []; - -clearvars -except ListFiles server dataPath* p - - -%% - - - -%% Sort by date - -% First, we need to convert into a table, because structures can not be sorted: -ListFiles = struct2table(ListFiles,'AsArray',true); -% Then, we sort the table based on the time (6th column, datenum) -ListFiles = sortrows(ListFiles,6); -% Then, remove un-needed columns -ListFiles = removevars(ListFiles,{'bytes','isdir'}); - -disp('*************************************************') -disp('* Voila: Done creating data list! *') -disp('*************************************************') -%% Import LabView data -% -if matches(p.Results.importLabView,'on') - if isfolder(dataPath_LabView) % verify that this folder exists. - try - % Get list of all files in that folder - TmpFileList = dir([dataPath_LabView filesep '**' filesep '20*.dat']); - - % import LabView data - LabView = LabView_importData(fullfile(TmpFileList(1).folder,TmpFileList(1).name)); % Overwrite LabView data in workspace, if this is the first import - if size(TmpFileList,1) > 1 % for additional data files, add these to the LabView data structure. - for ii = 2:size(TmpFileList,1) - LabView = LabView_importData(fullfile(TmpFileList(ii).folder,TmpFileList(ii).name),LabView); - end - end - catch - warning('Problem with LabView file') - disp('Problem reading LabView file') - end - end - disp('*************************************************') - disp('* Voila: Done reading LabView data! *') - disp('*************************************************') - - clearvars TmpFileList - - try - % combine data and/or rename - LabView = LabView_combine(LabView); - catch - warning('Problem with LabView file') - disp('Problem merging LabView files') - disp('Check number of columns for each file') - end - - %% Extent list with LabView data - - %Query time of each data file and get LabView log for that time. - - for ii = 1:size(ListFiles,1) - - try - - % The time of the data and the logging of LabView are not - % necessarily occurring at precisely the same time. So, here define - % a time range (50 seconds) and get all - % data between these times. - tse1 = tsdata.event('Start',datenum(ListFiles.datenum(ii)),'Datenum'); - tse2 = tsdata.event('End',datenum(ListFiles.datenum(ii)+seconds(50)),'Datenum'); - tmp = gettsbetweenevents(LabView.merge,tse1,tse2); - - if ~isempty(tmp.Data) % only do this if LabView data are not missing (because data logging was off). - - % Cryo-holder set T (Sample holder temperature is in field ts.Data:1) - ListFiles.sampleTemp_dC(ii) = tmp.Data(1,1); % in °C (only get data in first row of tmp) - % Cell pressure - % (TODO: Pick correct Baratron read out: either field: ts.Data 4,8,and 9) - ListFiles.cellPressure_mbar(ii) = tmp.Data(1,4); % in mbar - % vapour pressure over ice: - if ListFiles.cellPressure_mbar(ii) >= 0 - % Marti, J., and K. Mauersberger, Geophys. Res.Lett., 20, 363?366, 1993. - % gives parameterisation from 169 - 273K in Pa. (log10(p)= A1/T+B) - A_1 = -2663.5; - B_1 = 12.537; - ListFiles.iceTemp_dC(ii) = A_1/(log10(ListFiles.cellPressure_mbar(ii)*100)-B_1)-273.15; - else - ListFiles.iceTemp_dC(ii) = NaN; - end - - if datenum(ListFiles.datenum(ii)) >= datenum('04-Mar-2019 13:30:00') % import additional data, logged after 03/2019 - ListFiles.smplX_mm(ii) = tmp.Data(1,10); - ListFiles.smplY_mm(ii) = tmp.Data(1,11); - ListFiles.smplZ_mm(ii) = tmp.Data(1,12); - ListFiles.sealingTemp(ii) = tmp.Data(1,13); - else % if these sub-set of data is not logged, set to NaN - ListFiles.smplX_mm(ii) = NaN; - ListFiles.smplY_mm(ii) = NaN; - ListFiles.smplZ_mm(ii) = NaN; - ListFiles.sealingTemp(ii) = NaN; - end - else % if there are no LabView data stored, set all entries to NaN - ListFiles.sampleTemp_dC(ii) = NaN; - ListFiles.iceTemp_dC(ii) = NaN; - ListFiles.cellPressure_mbar(ii) = NaN; - ListFiles.smplX_mm(ii) = NaN; - ListFiles.smplY_mm(ii) = NaN; - ListFiles.smplZ_mm(ii) = NaN; - ListFiles.sealingTemp(ii) = NaN; - end - clearvars tmp - catch - warning('Problem merging LabView data into data table') - disp('Problem merging LabView data into data table') - %fprintf('Number %.0f: %s \n',ii,[ListFiles.folder(ii) filesep ListFiles.name(ii)]) - %fprintf('Number %.0f: %s \n',ii,datestr(ListFiles.datenum(ii))) - end - end - - disp('*************************************************') - disp('* Voila: Done writing LabView data! *') - disp('*************************************************') -end -%% Make table nicer -% - -if ~iscell(ListFiles.spectrum_countsPerSecond) - ListFiles.spectrum_countsPerSecond = cell(size(ListFiles,1),1); -end -if ~iscell(ListFiles.spectrum_counts) - ListFiles.spectrum_counts = cell(size(ListFiles,1),1); -end -if ~iscell(ListFiles.xRayEkin_eV) - ListFiles.xRayEkin_eV = cell(size(ListFiles,1),1); -end -if ~iscell(ListFiles.scientaEkin_eV) - for ii = 1:size(ListFiles,1) - tmp{ii,:} = ListFiles.scientaEkin_eV(ii,:); - end - ListFiles.scientaEkin_eV = tmp; -end - - - -% rename date fields and delete those fields not needed -[ListFiles.lastModifiedDatestr] = ListFiles.date; -[ListFiles.lastModifiedDatenum] = ListFiles.datenum; -ListFiles = removevars(ListFiles, {'date','datenum'}); - -% Copy Ekin Data -existColumn = strcmp('scientaEkinRoh_eV',ListFiles.Properties.VariableNames); -if any(existColumn) - ListFiles = removevars(ListFiles,'scientaEkinRoh_eV'); -end -existColumn = strcmp('scientaEkinRoh_eV',ListFiles.Properties.VariableNames); -if ~any(existColumn) - % save current ekin data before they are modified - ListFiles.scientaEkinRoh_eV= ListFiles.scientaEkin_eV; -end -if ~iscell(ListFiles.scientaEkinRoh_eV) - for ii = 1:size(ListFiles,1) - tmp{ii,:} = ListFiles.scientaEkinRoh_eV(ii,:); - end - ListFiles.scientaEkinRoh_eV = tmp; -end -% work around for table variables with fitting results having the wrong -% size: -% first delete the old entries - -existColumn = strcmp('peakPosition',ListFiles.Properties.VariableNames); -if any(existColumn) - ListFiles = removevars(ListFiles,'peakPosition'); -end -existColumn = strcmp('peakArea',ListFiles.Properties.VariableNames); -if any(existColumn) - ListFiles = removevars(ListFiles,'peakArea'); -end -existColumn = strcmp('peakFWHM',ListFiles.Properties.VariableNames); -if any(existColumn) - ListFiles = removevars(ListFiles,'peakFWHM'); -end -% then re-create them with right size -% 11/22 change to 5 entries from 4. -existColumn = strcmp('peakPosition',ListFiles.Properties.VariableNames); -if ~any(existColumn) - % save current ekin data before they are modified - ListFiles.peakPosition= NaN(size(ListFiles,1),5); -end -existColumn = strcmp('peakArea',ListFiles.Properties.VariableNames); -if ~any(existColumn) - % save current ekin data before they are modified - ListFiles.peakArea= NaN(size(ListFiles,1),5); -end -existColumn = strcmp('peakFWHM',ListFiles.Properties.VariableNames); -if ~any(existColumn) - % save current ekin data before they are modified - ListFiles.peakFWHM= NaN(size(ListFiles,1),5); -end -existColumn = strcmp('sample',ListFiles.Properties.VariableNames); -if ~any(existColumn) - ListFiles.sample = cellstr(repmat(' ',size(ListFiles,1),1)); -end -% add the imported data to previous list (if passed to function upon call) -if istable(p.Results.DataTable) % do this only if previous list was input to function call - % find table variables that are missing in ListFiles - existColumn = strcmp('sample',p.Results.DataTable.Properties.VariableNames); - if ~any(existColumn) - p.Results.DataTable.sample = cellstr(repmat(' ',size(p.Results.DataTable,1),1)); - end - tmpMissing = ~ismember(p.Results.DataTable.Properties.VariableNames,ListFiles.Properties.VariableNames); - % find all table variables that are cells - tmpCell = cellfun(@(x) iscell(p.Results.DataTable.(x)), p.Results.DataTable.Properties.VariableNames); - % find all table variables that are numbers - tmpNumber = cellfun(@(x) isnumeric(p.Results.DataTable.(x)), p.Results.DataTable.Properties.VariableNames); - % table variabes that hold cells and are missing - tmpCellVariables = p.Results.DataTable.Properties.VariableNames(tmpMissing & tmpCell); - % table variables that hold numbers and are missing - tmpNumberVariables = p.Results.DataTable.Properties.VariableNames(tmpMissing & tmpNumber); - % add empty table variables for missing cell and for number variables - if ~isempty(tmpCellVariables) - for i = 1: size(p.Results.DataTable(:,tmpMissing & tmpCell),2) - ListFiles = addvars(ListFiles,cell(size(ListFiles,1),1),'NewVariableNames',tmpCellVariables{i}); - end - end - if ~isempty(tmpNumberVariables) - for i = 1: size(p.Results.DataTable(:,tmpMissing & tmpNumber),2) - ListFiles = addvars(ListFiles,nan(size(ListFiles,1),1),'NewVariableNames',tmpNumberVariables{i}); - end - end - -% % % sort the tables, if they have not the same order -% tmpCompareTables = cellfun(@isequal, ListFiles.Properties.VariableNames', p.Results.DataTable.Properties.VariableNames'); -% -% if ~all(tmpCompareTables) -% indexDifferenzes = find(ismember(p.Results.DataTable.Properties.VariableNames',ListFiles.Properties.VariableNames(~tmpCompareTables)','rows')); -% nameListFiles =ListFiles.Properties.VariableNames(~tmpCompareTables); -% -% for ii = 1:size(indexDifferenzes,1) -% tmpIndx = find(ismember(p.Results.DataTable.Properties.VariableNames',nameListFiles{ii},'rows')); -% tmpPreviousVarName = p.Results.DataTable.Properties.VariableNames{tmpIndx-1}; -% ListFiles = movevars(ListFiles,nameListFiles{ii},'After',tmpPreviousVarName); -% fprintf("%s comes after %s \n", nameListFiles{ii},tmpPreviousVarName) -% end -% -% end - - - - % merge tables (append imported data to previous table) - ListFiles = [p.Results.DataTable; ListFiles]; - % Then, we sort the table based on the time (datenum) - ListFiles = sortrows(ListFiles,'lastModifiedDatenum'); -end - -%% Export - -ExportList = removevars(ListFiles, {'image', 'spectrum_counts', 'spectrum_countsPerSecond', 'scientaEkin_eV', 'beamlineInt', 'imageRoh', 'scientaEkinRoh_eV', 'xRayEkin_eV'}); -% TODO check windows formatting -try - % write a ;-separated list for export to excel. - writetable(ExportList,fullfile(dataPath,[datestr(ExportList.lastModifiedDatenum(1),'mmmYYYY') '_DataList.csv']),'Delimiter',','); - - if ispc - % and open in Excel; works only on Windows Machines - winopen(fullfile(dataPath,[datestr(ExportList.lastModifiedDatenum(1),'mmmYYYY') '_DataList.csv'])); - end -catch - warning('Problem writing Excel File (*.csv). Make sure it is not open in Excel') -end - - - - -disp('*************************************************') -disp('* Voila: nappFileList.m finished ! *') -disp('*************************************************') - - -end - -function LabView = LabView_importData(fullFileName,varargin) -% -% LabView_importData reads data log ASCII files stored by LabView into -% a Matlab time series. -% -% LabView = LabView_importData(A) imports file A -% and stores its content as time series in a structure called "LabView". -% -% LabView = LabView_importData(A,LabView) imports file A -% and appends its content as time series to the LabView structure. -% -% -% Example -% LabView = LabView_importData('exmpl.dat',LabView) -% -% Input -% * Napp_chamber_file: Complete and absolute path to the Napp chamber log file. -% * LabView: name of output structure. Always call this'LabView' -% -% Output -% * LabView: time series, the name starting with "ts" -% followed by date and time the recording started. -% -% See also LABVIEW_COMBINE, LABVIEW_PLOT, LABVIEW_CUTDATA -% -%% Data Structure -% -% Data structure before 4.3.2019 -% col 1: Date -% col 2: Time -% col 3: Reservoir "Pressure 1" - Unit "1 water" - mbar -> ts.Data:2 -% col 4: Reservoir "Pressure 2" - Unit "2 other" - mbar -> ts.Data:3 -% col 5: Baratron 1 - cell - 1mbar max - mbar -> ts.Data:4 -% col 6: Baratron 2 - cell - 10mbar max - mbar -> ts.Data:8 -% col 7: Baratron 3 - cell - 0.05mbar max - mbar -> ts.Data:9 -% col 8: Baratron 4 - - mbar -% col 9: Temp.Ice Sample - °C -> ts.Data:1 -% col 10: Temp.Heated Sample -% col 11: none -% col 12: Temp. Reservoir "Cooler 1" - °C -> ts.Data:5 -% col 13: Temp. Reservoir "Cooler 2" - °C -> ts.Data:6 -% col 14: Flow He(cryoholder) - l/min -> ts.Data:7 -% col 15: none -% col 16: none -% -% Data structure after 4.3.2019 -% col 1: Date -% col 2: Time -% col 3: Reservoir "Pressure 1" - Unit "1 water" - mbar -> ts.Data:2 -% col 4: Reservoir "Pressure 2" - Unit "2 other" - mbar -> ts.Data:3 -% col 5: Baratron 1 - cell - 1mbar max - mbar -> ts.Data:4 -% col 6: Baratron 2 - cell - 10mbar max - mbar -> ts.Data:8 -% col 7: Baratron 3 - cell - 0.05mbar max - mbar -> ts.Data:9 -% col 8: Baratron 4 - - mbar -% col 9: Temp.Ice Sample - °C -> ts.Data:1 -% col 10: Temp.Heated Sample -% col 11: Temp. Reservoir "Cooler 1" - °C -> ts.Data:5 -% col 12: Temp. Reservoir "Cooler 2" - °C -> ts.Data:6 -% col 13: Flow He(cryoholder) - l/min -> ts.Data:7 -% col 14: Flow gas 1 -% col 15: Pressure chamber - mbar -% col 16: x-position of cryoholder - mm -> ts.Data:10 -% col 17: y-position of cryoholder - mm -> ts.Data:11 -% col 18: z-position of cryoholder - mm -> ts.Data:12 -% col 19: nothing -% col 20: Temp.Sealing - °C -> ts.Data:13 - - -%% - -% Create an InputParser object -p = inputParser; -% Add inputs to the scheme. -defaultAppendToStructure = 0; -addRequired(p,'fullFileName',@isfile); -addOptional(p,'appendToStructure',defaultAppendToStructure,@isstruct); -% Parse the inputs. -parse(p,fullFileName,varargin{:}) - -%% -% get filedate -[~,name,~] = fileparts(p.Results.fullFileName); -tmp = strsplit(name,'_PC'); -filedate = datenum(tmp{1},'yyyy-mm-dd_HH.MM.SS'); - -clearvars name tmp - -%% -% parse structure to append to - -if isstruct(p.Results.appendToStructure) - LabView = p.Results.appendToStructure; -end -%% -if datenum(filedate) <= datenum('04-Mar-2019 13:30:00') - - fid = fopen(p.Results.fullFileName); - data = textscan(fid, ... - '%s %s %f %f %f %f %f %f %f %f %f %f %f %f %f %f',... - 'HeaderLines',1); % data file has 2 text columns, followed by 14 numeric columns - fclose(fid); - % define time series - LabView.(['ts_' datestr(datenum([char(data{1}{1}), char(data{2}{1})],'dd.mm.yyyyHH:MM:SS'),'YYYYmmdd_HHMM')]) ... - = timeseries([data{9} data{3} data{4} data{5} data{12} ... - data{13} data{14} data{6} data{7}] , ... - datestr(datenum([char(data{1}), char(data{2})],... - 'dd.mm.yyyyHH:MM:SS'),0)); - LabView.(['ts_' datestr(datenum([char(data{1}{1}), char(data{2}{1})],'dd.mm.yyyyHH:MM:SS'),'YYYYmmdd_HHMM')]).Name ... - = 'Readout Napp Chamber raw signal'; - clear fid ans formatOut nans t x - -elseif datenum(filedate) >= datenum('15-Sep-2021 01:00:00') && datenum(filedate) <= datenum('01-Apr-2023 01:00:00') - % during this time, date and time were in american format. - fid = fopen(p.Results.fullFileName); - data = textscan(fid, ... - '%s %s %s %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f',... - 'HeaderLines',1); % - - fclose(fid); - % the date formating in the dat file is really messed up. Try to make - % it consitent with MATLAB. The problem is that MATLAB does not - % understand 1 digit month and hours. - % - % - % Split the date in column 1 into year,month,day - newDateSplit = cellfun(@(x) split(char(x),'/'),data{1},'UniformOutput', false); - % Split the time in column 2 into hours, minutes, seconds - newTimeSplit = cellfun(@(x) split(char(x),':'),data{2},'UniformOutput', false); - % combine both with the am/pm string in column 3 to a new datestring - customDateStr = cellfun(@(x,y,z) [datestr(datenum([str2double(x{3}),str2double(x{1}),str2double(x{2}),str2double(y{1}),str2double(y{2}),str2double(y{3})])), ' ', char(z)], newDateSplit,newTimeSplit,data{3}, 'uniformOutput',false) ; - - % define time series - LabView.(['ts_' datestr(customDateStr{1},'YYYYmmdd_HHMM')]) ... - = timeseries([data{10} data{4} data{5} data{6} data{12} ... - data{13} data{14} data{7} data{8} data{17} data{18} data{19} data{21}], ... - customDateStr); - LabView.(['ts_' datestr(customDateStr{1},'YYYYmmdd_HHMM')]).Name ... - = 'Readout Napp Chamber raw signal'; - clearvars fid ans formatOut nans t x new* custom* - - -elseif datenum(filedate) >= datenum('01-Apr-2023 02:00:00') - - fid = fopen(p.Results.fullFileName); - data = textscan(fid, ... - '%s %s %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f',... - 'HeaderLines',1); - % data file has 2 text columns, followed by 18 numeric columns (THE AM - % PM IS MISSING and some changes to the LabView file. Confirm with Luca....) - fclose(fid); - % define time series - - LabView.(['ts_' datestr(datenum([char(data{1}{1}), char(data{2}{1})],'dd.mm.yyyyHH:MM:SS'),'YYYYmmdd_HHMM')]) ... - = timeseries([data{9} data{3} data{4} data{5} data{11} ... - data{12} data{20} data{6} data{7} data{15} data{16} data{17} data{19}] , ... - datestr(datenum([char(data{1}), char(data{2})],... - 'dd.mm.yyyyHH:MM:SS'),0)); - - LabView.(['ts_' datestr(datenum([char(data{1}{1}), char(data{2}{1})],'dd.mm.yyyyHH:MM:SS'),'YYYYmmdd_HHMM')]).Name ... - = 'Readout Napp Chamber raw signal'; - clear fid ans formatOut nans t x - -else - fid = fopen(p.Results.fullFileName); - data = textscan(fid, ... - '%s %s %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f',... - 'HeaderLines',1); % data file has 2 text columns, followed by 14 numeric columns - fclose(fid); - % define time series - - LabView.(['ts_' datestr(datenum([char(data{1}{1}), char(data{2}{1})],'dd.mm.yyyyHH:MM:SS'),'YYYYmmdd_HHMM')]) ... - = timeseries([data{9} data{3} data{4} data{5} data{11} ... - data{12} data{13} data{6} data{7} data{16} data{17} data{18} data{20}] , ... - datestr(datenum([char(data{1}), char(data{2})],... - 'dd.mm.yyyyHH:MM:SS'),0)); - - LabView.(['ts_' datestr(datenum([char(data{1}{1}), char(data{2}{1})],'dd.mm.yyyyHH:MM:SS'),'YYYYmmdd_HHMM')]).Name ... - = 'Readout Napp Chamber raw signal'; - clear fid ans formatOut nans t x -end -end - -function data_structure = LabView_combine(data_structure) -% LabView_combine can be used to merge time series into one. -% -% LabView = LabView_combine(LabView) merges all timeseries in the structure -% LabView into the new timeseries "merge" -% and adds this timeseries to the LabView structure -% -% -% Input -% * data_structure: name of the structure holding the time series -% -% Output -% * data_structure.merge: New time series combining all ts in this structure -% -% See also LABVIEW_IMPORTDATA, LABVIEW_PLOT - -% delete previous merged data -if isfield(data_structure,'merge') - data_structure = rmfield(data_structure, 'merge'); -end - -% sort them chronologically -data_structure = orderfields(data_structure); - -% query list of time series -list_ts = fieldnames(data_structure); - -% and merge all of them into one time series -for ii = 1:length(list_ts) - if ii == 1 - data_structure.merge = data_structure.(list_ts{1}); - else - data_structure.merge = append(data_structure.merge,data_structure.(list_ts{ii})); - end -end - - - - -end diff --git a/nappIce/nappFitGaussXps.m b/nappIce/nappFitGaussXps.m deleted file mode 100644 index 12e9f93..0000000 --- a/nappIce/nappFitGaussXps.m +++ /dev/null @@ -1,522 +0,0 @@ -function DataTable = nappFitGaussXps(DataTable,~,varargin) -%nappFitGaussXps fits PE spectra with up to 4 or 5 Gauss peaks. Different sets -%of constrains can be used. -% -% FileList = -% nappFitGaussXps(FileList,tmpFitParameters,'tableSelection',tmpDataSelection); -% -% *input* -% FileList: data table tmpFitParameters: You can give settings for the 4 -% peaks (5 in some cases), use small (negligible) values if you are -% interested in less than 4 peaks. -% -% % „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 -% 1.5 -% -% % „ 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]; -% -% -% -% tableSelection (optional): logical array to filter data table -% tableVariable (optional): select source: image(default),'imageRoh' -% mode: -% 'unconstrained': Each gauss peak is fitted independent. -% '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 -% 'unconstrainedAndWidthPosition': One unconstrained peak #3 (for gas phase -% feature) and 4 peaks constrained in width and/or position -% energyScale: kinetic (default) or binding -% showFigures: on(default) or off: display Gauss fits in figure. -% -% -% *output* -% table variables peakPosition, peakFWHM, and peakArea with fit -% results for peaks 1-4(5) -% fit results are printed in command window and graph with fits is -% shown. -% - - - -% Define conditions and defaults of input -defaultTableVariable = 'spectrum_countsPerSecond'; -expectedTableVariable = {'spectrum_counts','spectrum_countsPerSecond','spectrum_countsNorm'}; -defaultMode = 'widthPosition'; -expectedMode = {'unconstrained','widthPosition','position','width','unconstrainedAndWidthPosition'}; -defaultTableSelection = true(size(DataTable,1),1); -defaultShowFigures = 'on'; -expectedShowFigures = {'on','off'}; -defaultEnergyScale = 'kinetic'; -expectedEnergyScale = {'kinetic','binding'}; - - -% Parse input -p = inputParser; -addRequired(p,'DataTable',@istable); % TODO: allow combinedSpectrum input. -addRequired(p,'FitParameter',@isstruct); -addOptional(p,'tableSelection',defaultTableSelection,@islogical); -addParameter(p,'tableVariable',defaultTableVariable,... - @(x) any(validatestring(x,expectedTableVariable))); -addParameter(p,'mode',defaultMode,... - @(x) any(validatestring(x,expectedMode))); -addParameter(p,'showFigures',defaultShowFigures,... - @(x) any(validatestring(x,expectedShowFigures))); -addParameter(p,'energyScale',defaultEnergyScale,... - @(x) any(validatestring(x,expectedEnergyScale))); -parse(p,DataTable,varargin{:}); - -if ~all(cell2mat(cellfun(@size,p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable),'UniformOutput',false)),'all') - disp('The table variable appears to be empty. I quit now') - error('The table variable appears to be empty.') -end - -% 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; - -% Define equation to fit data -% I use the area Gauss equations here, which I took from the OriginPro -% documentation. https://www.originlab.com/doc/Origin-Help/Gauss-FitFunc -% -% Gauss = area/(width*sqrt(pi/2)) * exp(-2*(x-position)^2/width^2) -% -% where FWHM = width * sqrt(ln(4)) - - -% fitting equation -if matches(p.Results.mode,'position') - yfcn1 = @(tmpB,x)... - tmpB(1)/(tmpB(2)*sqrt(pi/2))*exp(-2.*((x(:,1) - tmpB(3)).^2/tmpB(2).^2)) ... % Gauss peak 1 - + tmpB(4)/(tmpB(5)*sqrt(pi/2))*exp(-2.*((x(:,1)- (tmpB(3)+p.Results.FitParameter.peakPos(1,2))).^2/tmpB(5).^2))... % Gauss peak 2 - + tmpB(6)/(tmpB(7)*sqrt(pi/2))*exp(-2.*((x(:,1)- (tmpB(3)+p.Results.FitParameter.peakPos(1,3))).^2/tmpB(7).^2))... % Gauss peak 3 - + tmpB(8)/(tmpB(9)*sqrt(pi/2))*exp(-2.*((x(:,1)- (tmpB(3)+p.Results.FitParameter.peakPos(1,4))).^2/tmpB(9).^2))... % Gauss peak 4 - +tmpB(10).*x(:,1)+tmpB(11); % linear background - - % initial value - B0= [p.Results.FitParameter.peakArea(1,1) p.Results.FitParameter.peakWidth(1,1) p.Results.FitParameter.peakPos(1,1)... % Gauss peak 1 - p.Results.FitParameter.peakArea(1,2) p.Results.FitParameter.peakWidth(1,2)... % Gauss peak 2 - p.Results.FitParameter.peakArea(1,3) p.Results.FitParameter.peakWidth(1,3)... % Gauss peak 3 - p.Results.FitParameter.peakArea(1,4) p.Results.FitParameter.peakWidth(1,4)... % Gauss peak 4 - 0 0]; % linear background - % lower bonds - lb = [p.Results.FitParameter.peakAreaLowerBond(1,1) p.Results.FitParameter.peakWidthLowerBond(1,1) p.Results.FitParameter.peakPosLowerBond(1,1) ... % Gauss peak 1 - p.Results.FitParameter.peakAreaLowerBond(1,2) p.Results.FitParameter.peakWidthLowerBond(1,2) ... % Gauss peak 2 - p.Results.FitParameter.peakAreaLowerBond(1,3) p.Results.FitParameter.peakWidthLowerBond(1,3) ... % Gauss peak 3 - p.Results.FitParameter.peakAreaLowerBond(1,4) p.Results.FitParameter.peakWidthLowerBond(1,4) ... % Gauss peak 4 - 0 0]; % linear background - % upper bond - ub = [p.Results.FitParameter.peakAreaUpperBond(1,1) p.Results.FitParameter.peakWidthUpperBond(1,1) p.Results.FitParameter.peakPosUpperBond(1,1) ... % Gauss peak 1 - p.Results.FitParameter.peakAreaUpperBond(1,2) p.Results.FitParameter.peakWidthUpperBond(1,2) ... % Gauss peak 2 - p.Results.FitParameter.peakAreaUpperBond(1,3) p.Results.FitParameter.peakWidthUpperBond(1,3) ... % Gauss peak 3 - p.Results.FitParameter.peakAreaUpperBond(1,4) p.Results.FitParameter.peakWidthUpperBond(1,4) ... % Gauss peak 4 - Inf Inf]; % linear background -elseif matches(p.Results.mode,'unconstrained') - yfcn1 = @(tmpB,x)... - tmpB(1)/(tmpB(2)*sqrt(pi/2))*exp(-2.*((x(:,1) - tmpB(3)).^2/tmpB(2).^2)) ... % Gauss peak 1 - + tmpB(4)/(tmpB(5)*sqrt(pi/2))*exp(-2.*((x(:,1)- tmpB(6)).^2/tmpB(5).^2))... % Gauss peak 2 - + tmpB(7)/(tmpB(8)*sqrt(pi/2))*exp(-2.*((x(:,1)- tmpB(9)).^2/tmpB(8).^2))... % Gauss peak 3 - + tmpB(10)/(tmpB(11)*sqrt(pi/2))*exp(-2.*((x(:,1)- tmpB(12)).^2/tmpB(11).^2))... % Gauss peak 4 - +tmpB(13).*x(:,1)+tmpB(14); % linear background - - % initial value - B0= [p.Results.FitParameter.peakArea(1,1) p.Results.FitParameter.peakWidth(1,1) p.Results.FitParameter.peakPos(1,1)... % Gauss peak 1 - p.Results.FitParameter.peakArea(1,2) p.Results.FitParameter.peakWidth(1,2) p.Results.FitParameter.peakPos(1,2)... % Gauss peak 2 - p.Results.FitParameter.peakArea(1,3) p.Results.FitParameter.peakWidth(1,3) p.Results.FitParameter.peakPos(1,3)... % Gauss peak 3 - p.Results.FitParameter.peakArea(1,4) p.Results.FitParameter.peakWidth(1,4) p.Results.FitParameter.peakPos(1,4)... % Gauss peak 4 - 0 0]; % linear background - % lower bonds - lb = [p.Results.FitParameter.peakAreaLowerBond(1,1) p.Results.FitParameter.peakWidthLowerBond(1,1) p.Results.FitParameter.peakPosLowerBond(1,1) ... % Gauss peak 1 - p.Results.FitParameter.peakAreaLowerBond(1,2) p.Results.FitParameter.peakWidthLowerBond(1,2) p.Results.FitParameter.peakPosLowerBond(1,2)... % Gauss peak 2 - p.Results.FitParameter.peakAreaLowerBond(1,3) p.Results.FitParameter.peakWidthLowerBond(1,3) p.Results.FitParameter.peakPosLowerBond(1,3)... % Gauss peak 3 - p.Results.FitParameter.peakAreaLowerBond(1,4) p.Results.FitParameter.peakWidthLowerBond(1,4) p.Results.FitParameter.peakPosLowerBond(1,4)... % Gauss peak 4 - 0 0]; % linear background - % upper bond - ub = [p.Results.FitParameter.peakAreaUpperBond(1,1) p.Results.FitParameter.peakWidthUpperBond(1,1) p.Results.FitParameter.peakPosUpperBond(1,1) ... % Gauss peak 1 - p.Results.FitParameter.peakAreaUpperBond(1,2) p.Results.FitParameter.peakWidthUpperBond(1,2) p.Results.FitParameter.peakPosUpperBond(1,2)... % Gauss peak 2 - p.Results.FitParameter.peakAreaUpperBond(1,3) p.Results.FitParameter.peakWidthUpperBond(1,3) p.Results.FitParameter.peakPosUpperBond(1,3)... % Gauss peak 3 - p.Results.FitParameter.peakAreaUpperBond(1,4) p.Results.FitParameter.peakWidthUpperBond(1,4) p.Results.FitParameter.peakPosUpperBond(1,4)... % Gauss peak 4 - Inf Inf]; % linear background -elseif matches(p.Results.mode,'widthPosition') - yfcn1 = @(tmpB,x)... - tmpB(1)/(tmpB(2)*sqrt(pi/2))*exp(-2.*((x(:,1) - tmpB(3)).^2/tmpB(2).^2)) ... % Gauss peak 1 - + tmpB(4)/(tmpB(2)*sqrt(pi/2))*exp(-2.*((x(:,1)- (tmpB(3)+p.Results.FitParameter.peakPos(1,2))).^2/tmpB(2).^2))... % Gauss peak 2 - + tmpB(5)/(tmpB(2)*sqrt(pi/2))*exp(-2.*((x(:,1)- (tmpB(3)+p.Results.FitParameter.peakPos(1,3))).^2/tmpB(2).^2))... % Gauss peak 3 - + tmpB(6)/(tmpB(2)*sqrt(pi/2))*exp(-2.*((x(:,1)- (tmpB(3)+p.Results.FitParameter.peakPos(1,4))).^2/tmpB(2).^2))... % Gauss peak 4 - +tmpB(7).*x(:,1)+tmpB(8); % linear background - - % initial value - B0= [p.Results.FitParameter.peakArea(1,1) p.Results.FitParameter.peakWidth(1,1) p.Results.FitParameter.peakPos(1,1)... % Gauss peak 1 - p.Results.FitParameter.peakArea(1,2) ... % Gauss peak 2 - p.Results.FitParameter.peakArea(1,3) ... % Gauss peak 3 - p.Results.FitParameter.peakArea(1,4)... % Gauss peak 4 - 0 0]; % linear background - % lower bonds - lb = [p.Results.FitParameter.peakAreaLowerBond(1,1) p.Results.FitParameter.peakWidthLowerBond(1,1) p.Results.FitParameter.peakPosLowerBond(1,1) ... % Gauss peak 1 - p.Results.FitParameter.peakAreaLowerBond(1,2) ... % Gauss peak 2 - p.Results.FitParameter.peakAreaLowerBond(1,3) ... % Gauss peak 3 - p.Results.FitParameter.peakAreaLowerBond(1,4) ... % Gauss peak 4 - 0 0]; % linear background - % upper bond - ub = [p.Results.FitParameter.peakAreaUpperBond(1,1) p.Results.FitParameter.peakWidthUpperBond(1,1) p.Results.FitParameter.peakPosUpperBond(1,1) ... % Gauss peak 1 - p.Results.FitParameter.peakAreaUpperBond(1,2) ... % Gauss peak 2 - p.Results.FitParameter.peakAreaUpperBond(1,3) ... % Gauss peak 3 - p.Results.FitParameter.peakAreaUpperBond(1,4) ... % Gauss peak 4 - Inf Inf]; % linear background -elseif matches(p.Results.mode,'width') - yfcn1 = @(tmpB,x)... - tmpB(1)/(tmpB(2)*sqrt(pi/2))*exp(-2.*((x(:,1) - tmpB(3)).^2/tmpB(2).^2)) ... % Gauss peak 1 - + tmpB(4)/(tmpB(2)*sqrt(pi/2))*exp(-2.*((x(:,1)- tmpB(5)).^2/tmpB(2).^2))... % Gauss peak 2 - + tmpB(6)/(tmpB(2)*sqrt(pi/2))*exp(-2.*((x(:,1)- tmpB(7)).^2/tmpB(2).^2))... % Gauss peak 3 - + tmpB(8)/(tmpB(2)*sqrt(pi/2))*exp(-2.*((x(:,1)- tmpB(9)).^2/tmpB(2).^2))... % Gauss peak 4 - +tmpB(10).*x(:,1)+tmpB(11); % linear background - - % initial value - B0= [p.Results.FitParameter.peakArea(1,1) p.Results.FitParameter.peakWidth(1,1) p.Results.FitParameter.peakPos(1,1)... % Gauss peak 1 - p.Results.FitParameter.peakArea(1,2) p.Results.FitParameter.peakPos(1,2)... % Gauss peak 2 - p.Results.FitParameter.peakArea(1,3) p.Results.FitParameter.peakPos(1,3)... % Gauss peak 3 - p.Results.FitParameter.peakArea(1,4) p.Results.FitParameter.peakPos(1,4)... % Gauss peak 4 - 0 0]; % linear background - % lower bonds - lb = [p.Results.FitParameter.peakAreaLowerBond(1,1) p.Results.FitParameter.peakWidthLowerBond(1,1) p.Results.FitParameter.peakPosLowerBond(1,1) ... % Gauss peak 1 - p.Results.FitParameter.peakAreaLowerBond(1,2) p.Results.FitParameter.peakWidthLowerBond(1,2) ... % Gauss peak 2 - p.Results.FitParameter.peakAreaLowerBond(1,3) p.Results.FitParameter.peakWidthLowerBond(1,3) ... % Gauss peak 3 - p.Results.FitParameter.peakAreaLowerBond(1,4) p.Results.FitParameter.peakWidthLowerBond(1,4) ... % Gauss peak 4 - 0 0]; % linear background - % upper bond - ub = [p.Results.FitParameter.peakAreaUpperBond(1,1) p.Results.FitParameter.peakWidthUpperBond(1,1) p.Results.FitParameter.peakPosUpperBond(1,1) ... % Gauss peak 1 - p.Results.FitParameter.peakAreaUpperBond(1,2) p.Results.FitParameter.peakWidthUpperBond(1,2) ... % Gauss peak 2 - p.Results.FitParameter.peakAreaUpperBond(1,3) p.Results.FitParameter.peakWidthUpperBond(1,3) ... % Gauss peak 3 - p.Results.FitParameter.peakAreaUpperBond(1,4) p.Results.FitParameter.peakWidthUpperBond(1,4) ... % Gauss peak 4 - Inf Inf]; % linear background - -elseif matches(p.Results.mode,'unconstrainedAndWidthPosition') % Novum, also the distance between peaks is a fit parameter. [Gauss = area/(width*sqrt(pi/2)) * exp(-2*(x-position)^2/width^2)] - yfcn1 = @(tmpB,x)... - tmpB(1)/(tmpB(2)*sqrt(pi/2))*exp(-2.*((x(:,1) - (tmpB(3)+tmpB(14))).^2/tmpB(2).^2)) ... % Gauss peak 1: width and position - + tmpB(4)/(tmpB(2)*sqrt(pi/2))*exp(-2.*((x(:,1) - tmpB(3)).^2/tmpB(2).^2))... % Gauss peak 2: width and position - + tmpB(5)/(tmpB(6)*sqrt(pi/2))*exp(-2.*((x(:,1) - tmpB(7)).^2/tmpB(6).^2))... % Gauss peak 3: unconstrained - + tmpB(8)/(tmpB(2)*sqrt(pi/2))*exp(-2.*((x(:,1) - tmpB(9)).^2/tmpB(2).^2))... % Gauss peak 4: width - + tmpB(10)/(tmpB(2)*sqrt(pi/2))*exp(-2.*((x(:,1)- tmpB(11)).^2/tmpB(2).^2))... % Gauss peak 5: width - + tmpB(12).*x(:,1)+tmpB(13); % linear background - - % initial value - B0= [p.Results.FitParameter.peakArea(1,1) p.Results.FitParameter.peakWidth(1,1) p.Results.FitParameter.peakPos(1,2)... % Gauss peak 1 - p.Results.FitParameter.peakArea(1,2) ... % Gauss peak 2 - p.Results.FitParameter.peakArea(1,3) p.Results.FitParameter.peakWidth(1,2) p.Results.FitParameter.peakPos(1,3)... % Gauss peak 3 - p.Results.FitParameter.peakArea(1,4) p.Results.FitParameter.peakPos(1,4)... % Gauss peak 4 - p.Results.FitParameter.peakArea(1,5) p.Results.FitParameter.peakPos(1,5)... % Gauss peak 5 - 0 0 ... % linear background - p.Results.FitParameter.peakPos(1,1)]; - % lower bonds - lb = [p.Results.FitParameter.peakAreaLowerBond(1,1) p.Results.FitParameter.peakWidthLowerBond(1,1) p.Results.FitParameter.peakPosLowerBond(1,2) ... % Gauss peak 1 - p.Results.FitParameter.peakAreaLowerBond(1,2) ... % Gauss peak 2 - p.Results.FitParameter.peakAreaLowerBond(1,3) p.Results.FitParameter.peakWidthLowerBond(1,2) p.Results.FitParameter.peakPosLowerBond(1,3) ... % Gauss peak 3 - p.Results.FitParameter.peakAreaLowerBond(1,4) p.Results.FitParameter.peakPosLowerBond(1,4) ... - p.Results.FitParameter.peakAreaLowerBond(1,5) p.Results.FitParameter.peakPosLowerBond(1,5) ...% Gauss peak 4 - 0 0 ... % linear background - p.Results.FitParameter.peakPosLowerBond(1,1)]; - - % upper bond - ub = [p.Results.FitParameter.peakAreaUpperBond(1,1) p.Results.FitParameter.peakWidthUpperBond(1,1) p.Results.FitParameter.peakPosUpperBond(1,2) ... % Gauss peak 1 - p.Results.FitParameter.peakAreaUpperBond(1,2) ... % Gauss peak 2 - p.Results.FitParameter.peakAreaUpperBond(1,3) p.Results.FitParameter.peakWidthUpperBond(1,2) p.Results.FitParameter.peakPosUpperBond(1,3) ... % Gauss peak 3 - p.Results.FitParameter.peakAreaUpperBond(1,4) p.Results.FitParameter.peakPosUpperBond(1,4) ... - p.Results.FitParameter.peakAreaUpperBond(1,5) p.Results.FitParameter.peakPosUpperBond(1,5) ... % Gauss peak 4 - Inf Inf ... % linear background - p.Results.FitParameter.peakPosUpperBond(1,1)]; % shift upper bond -end - -for ii = 1:size(p.Results.DataTable(p.Results.tableSelection,:),1) - if contains(p.Results.energyScale,'kinetic') - [x1, y1] = prepareCurveData(p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii},... - p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii}); - % make data slimmer so that background fit improved - if p.Results.FitParameter.peakPos(1,1) >= 10 - tmp1 = find(x1>=p.Results.FitParameter.peakPos(1,1)-p.Results.FitParameter.backgroundRange(1,1),1); - tmp2 = find(x1>=p.Results.FitParameter.peakPos(1,1)+p.Results.FitParameter.backgroundRange(1,2),1); - else - tmp1 = find(x1>=p.Results.FitParameter.peakPos(1,2)-p.Results.FitParameter.backgroundRange(1,1),1); - tmp2 = find(x1>=p.Results.FitParameter.peakPos(1,2)+p.Results.FitParameter.backgroundRange(1,2),1); - end - if isempty(tmp2) - y1 = y1(tmp1:end); - x1 = x1(tmp1:end); - else - y1 = y1(tmp1:tmp2); - x1 = x1(tmp1:tmp2); - end - % Fit equations: Gauss eq. 1 with data - yfcn = @(tmpB,x) yfcn1(tmpB,x); - % We find an optimal fit by minimising the residuals: - fitfcnw = @(tmpB) sum((y1 - yfcn(tmpB,x1)).^2); - problem = createOptimProblem('fmincon', 'x0',B0, 'lb',lb,'ub',ub, 'objective',fitfcnw); - gs = GlobalSearch('PlotFcns',@gsplotbestf); - tmpB = run(gs,problem); - elseif contains(p.Results.energyScale,'binding') - [x1, y1] = prepareCurveData(p.Results.DataTable(p.Results.tableSelection,:).bindingEnergy_eV{ii},... - p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii}); - % make data slimmer so that background fit improves - if p.Results.FitParameter.peakPos(1,1) >= 10 - tmp2 = find(x1<=p.Results.FitParameter.peakPos(1,1)-p.Results.FitParameter.backgroundRange(1,1),1); - tmp1 = find(x1<=p.Results.FitParameter.peakPos(1,1)+p.Results.FitParameter.backgroundRange(1,2),1); - else - tmp2 = find(x1<=p.Results.FitParameter.peakPos(1,2)-p.Results.FitParameter.backgroundRange(1,1),1); - tmp1 = find(x1<=p.Results.FitParameter.peakPos(1,2)+p.Results.FitParameter.backgroundRange(1,2),1); - end - if isempty(tmp2) - y1 = y1(tmp1:end); - x1 = x1(tmp1:end); - else - y1 = y1(tmp1:tmp2); - x1 = x1(tmp1:tmp2); - end - % Fit equations: Gauss eq. 1 with data - yfcn = @(tmpB,x) yfcn1(tmpB,x); - % We find an optimal fit by minimising the residuals: - fitfcnw = @(tmpB) sum((y1 - yfcn(tmpB,x1)).^2); - problem = createOptimProblem('fmincon', 'x0',B0, 'lb',lb,'ub',ub, 'objective',fitfcnw); - gs = GlobalSearch('PlotFcns',@gsplotbestf); - tmpB = run(gs,problem); - end - % compile results into variable B with same dimension for all - % fit-types (Area Width Position): - if matches(p.Results.mode,'position') - B = [tmpB(1) tmpB(2) tmpB(3)... - tmpB(4) tmpB(5) tmpB(3)+p.Results.FitParameter.peakPos(1,2) ... - tmpB(6) tmpB(7) tmpB(3)+p.Results.FitParameter.peakPos(1,3)... - tmpB(8) tmpB(9) tmpB(3)+p.Results.FitParameter.peakPos(1,4)... - tmpB(10) tmpB(11)... - NaN NaN NaN]; - elseif matches(p.Results.mode,'unconstrained') - B = [tmpB(1) tmpB(2) tmpB(3)... - tmpB(4) tmpB(5) tmpB(6) ... - tmpB(7) tmpB(8) tmpB(9) ... - tmpB(10) tmpB(11) tmpB(12) ... - tmpB(13) tmpB(14)... - NaN NaN NaN]; - elseif matches(p.Results.mode,'widthPosition') - B = [tmpB(1) tmpB(2) tmpB(3)... - tmpB(4) tmpB(2) tmpB(3)+p.Results.FitParameter.peakPos(1,2)... - tmpB(5) tmpB(2) tmpB(3)+p.Results.FitParameter.peakPos(1,3)... - tmpB(6) tmpB(2) tmpB(3)+p.Results.FitParameter.peakPos(1,4)... - tmpB(7) tmpB(8)... - NaN NaN NaN]; - elseif matches(p.Results.mode,'width') - B = [tmpB(1) tmpB(2) tmpB(3)... - tmpB(4) tmpB(2) tmpB(5)... - tmpB(6) tmpB(2) tmpB(8)... - tmpB(9) tmpB(2) tmpB(10)... - tmpB(11) tmpB(12)... - NaN NaN NaN]; - elseif matches(p.Results.mode,'unconstrainedAndWidthPosition') - B = [tmpB(1) tmpB(2) tmpB(3)+tmpB(14)... - tmpB(4) tmpB(2) tmpB(3)... - tmpB(5) tmpB(6) tmpB(7)... - tmpB(8) tmpB(2) tmpB(9)... - tmpB(12) tmpB(13) ... - tmpB(10) tmpB(2) tmpB(11)]; - end - - % print out result table and result plots based on B. Because B has the - % same structure for all fit types, the same code for printing and - % plotting can be used for all fit types. - - if matches(p.Results.showFigures,'on') - % Display results in table - disp(' ' ); - disp(' ' ); - disp('Fit results') - disp(p.Results.DataTable(p.Results.tableSelection,:).name{ii}); - disp(' ' ); - disp(cell2table({sprintf('%.1f',B(3)),... - sprintf('%.1f',B(2)*sqrt(log(4))),... - sprintf('%.1f',B(2)),... - sprintf('%7.0f',B(1));... - sprintf('%.1f',B(6)),... - sprintf('%.1f',B(5)*sqrt(log(4))),... - sprintf('%.1f',B(5)),... - sprintf('%7.0f',B(4));... - sprintf('%.1f',B(9)),... - sprintf('%.1f',B(8)*sqrt(log(4))),... - sprintf('%.1f',B(8)),... - sprintf('%7.0f',B(7));... - sprintf('%.1f',B(12)),... - sprintf('%.1f',B(11)*sqrt(log(4))),... - sprintf('%.1f',B(11)),... - sprintf('%7.0f',B(10)); ... - sprintf('%.1f',B(17)),... - sprintf('%.1f',B(16)*sqrt(log(4))),... - sprintf('%.1f',B(16)),... - sprintf('%7.0f',B(15))},... - 'VariableNames',{'position';'FWHW';'width';'area'},... - 'RowNames',{'peak1','peak2','peak3','peak4','peak5'})); % 'RowNames',{'peak1','peak2','peak3','peak4','peak5'})); - - % plot result - % eliminate NaN in B - B(isnan(B))=0.01; - % define equations to be plotted - Gauss = @(x, A, Pos, Wdt) A./(Wdt.*sqrt(pi/2))*exp(-2.*((x - Pos).^2/Wdt.^2)); - linear = @(x,slp,intrcpt) slp*x+intrcpt; - figure( 'Name', 'Gauss Multi Fit ') - tiledlayout(1,1) - ax(1) = nexttile; - % define high-resolution x for plotting - if x1(1)<= x1(end) - xGaussPlot = x1(1):0.01:x1(end); - else - xGaussPlot = x1(1):-0.01:x1(end); - end - - %Define gauss peaks - yData_pk1= Gauss(xGaussPlot ,B(1), B(3), B(2)); - yData_pk2= Gauss(xGaussPlot ,B(4), B(6), B(5)); - yData_pk3= Gauss(xGaussPlot ,B(7), B(9), B(8)); - yData_pk4= Gauss(xGaussPlot ,B(10), B(12), B(11)); - yData_pk5= Gauss(xGaussPlot ,B(15), B(17), B(16)); - bkgrd = linear(xGaussPlot,B(13),B(14)); - % plot data - plot(x1,y1,'.') - hold on - % plot fit - h = plot(xGaussPlot,yData_pk1+yData_pk2+yData_pk3+yData_pk4+yData_pk5+bkgrd); - h.LineWidth=2; - h.Color = PsiFarbe.dunkelblau; - % plot each gauss peak - h = plot(xGaussPlot,yData_pk1+bkgrd); - h.LineWidth=1.5; - h.Color = PsiFarbe.gelb; - h = plot(xGaussPlot,yData_pk2+bkgrd); - h.LineWidth=1.5; - h.Color = PsiFarbe.gelb; - h = plot(xGaussPlot,yData_pk3+bkgrd); - h.LineWidth=1.5; - h.Color = PsiFarbe.gelb; - h = plot(xGaussPlot,yData_pk4+bkgrd); - h.LineWidth=1.5; - h.Color = PsiFarbe.gelb; - h = plot(xGaussPlot,yData_pk5+bkgrd); - h.LineWidth=1.5; - h.Color = PsiFarbe.gelb; - plot(xGaussPlot, bkgrd); - set(ax(1),'Xdir','reverse'); - legend OFF - xlabel('Binding Energy [eV]'); - ylabel('PE intensity [-]'); - grid on - end - % Write results to List, we need all fitting results - resultsPeakPos(ii,:) = [B(3), B(6), B(9), B(12), B(16)] ; %#ok<*AGROW> - resultsPeakFWHW(ii,:) = [B(2).*sqrt(log(4)), B(5).*sqrt(log(4)), B(8).*sqrt(log(4)), B(11).*sqrt(log(4)), B(17).*sqrt(log(4))] ; - resultsPeakArea(ii,:) = [B(1), B(4), B(7), B(10) B(15)] ; - % resultsBkgrd(ii,:) = [B(13), B(14)] ; -end - - -% write results to data table -try - existColumn = strcmp('peakPosition',p.Results.DataTable.Properties.VariableNames); - if ~any(existColumn) - DataTable.peakPosition = NaN(size(p.Results.DataTable,1),size(resultsPeakPos,2)); - end - existColumn = strcmp('peakArea',p.Results.DataTable.Properties.VariableNames); - if ~any(existColumn) - DataTable.peakArea = NaN(size(p.Results.DataTable,1),size(resultsPeakArea,2)); - end - existColumn = strcmp('peakFWHM',p.Results.DataTable.Properties.VariableNames); - if ~any(existColumn) - DataTable.peakFWHM = NaN(size(p.Results.DataTable,1),size(resultsPeakFWHW,2)); - end - %if contains(p.Results.energyScale,'binding') - DataTable(p.Results.tableSelection,:).peakPosition = resultsPeakPos(:,:); - %end - DataTable(p.Results.tableSelection,:).peakFWHM = resultsPeakFWHW(:,:); - DataTable(p.Results.tableSelection,:).peakArea = resultsPeakArea(:,:); -catch - disp('Could not write results to table. Writing only 4 entries') - existColumn = strcmp('peakPosition',p.Results.DataTable.Properties.VariableNames); - if ~any(existColumn) - DataTable.peakPosition = NaN(size(p.Results.DataTable,1),size(resultsPeakPos,2)); - end - existColumn = strcmp('peakArea',p.Results.DataTable.Properties.VariableNames); - if ~any(existColumn) - DataTable.peakArea = NaN(size(p.Results.DataTable,1),size(resultsPeakArea,2)); - end - existColumn = strcmp('peakFWHM',p.Results.DataTable.Properties.VariableNames); - if ~any(existColumn) - DataTable.peakFWHM = NaN(size(p.Results.DataTable,1),size(resultsPeakFWHW,2)); - end - %if contains(p.Results.energyScale,'binding') - DataTable(p.Results.tableSelection,:).peakPosition = resultsPeakPos(:,1:4); - %end - DataTable(p.Results.tableSelection,:).peakFWHM = resultsPeakFWHW(:,1:4); - DataTable(p.Results.tableSelection,:).peakArea = resultsPeakArea(:,1:4); -end - - -end \ No newline at end of file diff --git a/nappIce/nappGenerateSpectra.m b/nappIce/nappGenerateSpectra.m deleted file mode 100644 index 0bf923f..0000000 --- a/nappIce/nappGenerateSpectra.m +++ /dev/null @@ -1,126 +0,0 @@ -function DataTable = nappGenerateSpectra(DataTable,varargin) -%nappGenerateSpectra reduces the dimension of images to generate spectra -% -% nappGenerateSpectra(FileList,tmpDataSelection) -% -% *input* -% FileList: data table -% tableSelection (optional): logical array to filter data table -% tableVariable (optional): select source: image(default),'imageRoh' -% mode: mean (default) averages the sequence iterations; sum adds them -% -% *output* -% with mode mean the spectrum will be saved in the table variable spectrum_countsPerSecond -% with mode sum the spectrum will be saved in the table variable spectrum_counts -% -% FIXME: spectrum_counts is not implemented yet. - -% Define conditions and defaults of input -defaultTableVariable = 'image'; -expectedTableVariable = {'image','imageRoh'}; -defaultMode = 'mean'; -expectedMode = {'mean','sum','trapz'}; -defaultEkinStart = 0; -defaultEkinEnd = 0; -defaultTableSelection = true(size(DataTable,1)); - -% Parse input -p = inputParser; -addRequired(p,'DataTable',@istable); -addOptional(p,'tableSelection',defaultTableSelection,@islogical); -addParameter(p,'tableVariable',defaultTableVariable,... - @(x) any(validatestring(x,expectedTableVariable))); -addParameter(p,'mode',defaultMode,... - @(x) any(validatestring(x,expectedMode))); -addParameter(p,'iterationRange',[0:0]); -addParameter(p,'eKinStart',defaultEkinStart,@isnumeric) -addParameter(p,'eKinEnd',defaultEkinEnd,@isnumeric) -parse(p,DataTable,varargin{:}); - -% add empty variable to table -existColumn = strcmp('spectrum_countsPerSecond',p.Results.DataTable.Properties.VariableNames); -if ~any(existColumn) - DataTable.spectrum_countsPerSecond = cell(size(p.Results.DataTable,1),1); -end -existColumn = strcmp('spectrum_counts',p.Results.DataTable.Properties.VariableNames); -if ~any(existColumn) - DataTable.spectrum_counts = cell(size(p.Results.DataTable,1),1); -end -existColumn = strcmp('logGenerateRange',p.Results.DataTable.Properties.VariableNames); -if ~any(existColumn) - DataTable.logGenerateRange = NaN(size(p.Results.DataTable,1),2); -end -existColumn = strcmp('logGenerateDate',p.Results.DataTable.Properties.VariableNames); -if ~any(existColumn) - DataTable.logGenerateDate = cellstr(repmat(' ',size(p.Results.DataTable,1),1)); -end -existColumn = strcmp('logGenerateMode',p.Results.DataTable.Properties.VariableNames); -if ~any(existColumn) - DataTable.logGenerateDate = cellstr(repmat(' ',size(p.Results.DataTable,1),1)); -end - -% check input (all elements of input variable need to have non-zero size) -if ~all(cell2mat(cellfun(@size,p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable),'UniformOutput',false)),'all') - disp('The table variable appears to be empty. I quit now') - error('The table variable appears to be empty.') -end - -% create empty variables -tmp_3 = cell(size(p.Results.DataTable(p.Results.tableSelection,:),1),1); -tmp_6 = cell(size(p.Results.DataTable(p.Results.tableSelection,:),1),1); -tmp_4 = NaN(size(p.Results.DataTable(p.Results.tableSelection,:),1),1); -tmp_5 = NaN(size(p.Results.DataTable(p.Results.tableSelection,:),1),1); -% repeat this for all columns in input. -for ii = 1:size(p.Results.DataTable(p.Results.tableSelection,:),1) - if endsWith(p.Results.DataTable(p.Results.tableSelection,:).name{ii},'h5') % let's do NEXAFS first. - % Get index of EkinStart and EkinEnd - if (p.Results.eKinStart) == 0 - tmp_1 = 1; - else - tmp_1 = find(p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii} >= p.Results.eKinStart,1); - end - if (p.Results.eKinEnd) == 0 - tmp_2 = length(p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii}); - else - tmp_2 = find(p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii} >= p.Results.eKinEnd,1); - end - - if contains(p.Results.mode,'trapz') - tmp_3(ii,1)= {trapz(p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii}(tmp_1:tmp_2),... - p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii}(tmp_1:tmp_2,:))'}; - elseif (contains(p.Results.mode,'sum') | contains(p.Results.mode,'mean')) - - tmp_3(ii,1) = {sum(p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii}(tmp_1:tmp_2,:),1)'}; %#ok<*AGROW> - end - % log - tmp_4(ii,1) = p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii}(tmp_1); - tmp_5(ii,1) = p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii}(tmp_2); - elseif endsWith(p.Results.DataTable(p.Results.tableSelection,:).name{ii},'ibw') % then do Igorfiles - if p.Results.iterationRange(1) == 0 - startRange = 1; - endRange = size(p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii},2); - else - startRange = p.Results.iterationRange(1); - endRange = p.Results.iterationRange(2); - end - - if (contains(p.Results.mode,'mean') | contains(p.Results.mode,'trapz')) - tmp_6(ii,1)= {mean(p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii}(:,startRange:endRange),2)}; - elseif contains(p.Results.mode,'sum') - tmp_3(ii,1) = {sum(p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii}(:,startRange:endRange),2)}; %#ok<*AGROW> - end - % log - tmp_4(ii,1) = startRange; - tmp_5(ii,1) = endRange; - end -end - -% write results to table - DataTable.spectrum_counts(p.Results.tableSelection) = tmp_3; - DataTable.spectrum_countsPerSecond(p.Results.tableSelection) = tmp_6; -% write log to table - DataTable.logGenerateMode(p.Results.tableSelection,:) = cellstr(repmat(p.Results.mode,size(p.Results.DataTable(p.Results.tableSelection,:),1),1)); - DataTable.logGenerateRange(p.Results.tableSelection,:) = [tmp_4 tmp_5]; - DataTable.logGenerateDate(p.Results.tableSelection,:) = cellstr(repmat(datestr(now),size(p.Results.DataTable(p.Results.tableSelection,:),1),1)); - -end \ No newline at end of file diff --git a/nappIce/nappImage.m b/nappIce/nappImage.m deleted file mode 100644 index 6f35383..0000000 --- a/nappIce/nappImage.m +++ /dev/null @@ -1,58 +0,0 @@ - function nappImage(DataTable,varargin) - % - % h_img = Napp_plotImage(StructArrayData) plots an image of the - % NEXAFS data set in the NEXAFS data structure. - % - % Output: an image figure, with a handle. The handle is important to - % select these images for XPS removal - -% Define conditions and defaults of input -defaultTableVariable = {'image'}; -expectedTableVariable = {'image','imageRoh'}; -defaultTableSelection = true(size(DataTable,1)); - - -% Parse input -p = inputParser; - addRequired(p,'DataTable',@istable); - addOptional(p,'tableSelection',defaultTableSelection,@islogical); - addParameter(p,'tableVariable',defaultTableVariable,... - @(x) any(validatestring(x,expectedTableVariable))); -parse(p,DataTable,varargin{:}); - -% check input (all elements of input variable need to have non-zero size) -if ~all(cell2mat(cellfun(@size,p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable),'UniformOutput',false)),'all') - disp('The table variable appears to be empty. I quit now') - error('The table variable appears to be empty.') -end - - for ii = 1:size(p.Results.DataTable(p.Results.tableSelection,:),1) - figure('Name',p.Results.DataTable(p.Results.tableSelection,:).name{ii}); - - % Create axes - hold(gca,'on'); - % Try to plot image with x and y - try - image(p.Results.DataTable(p.Results.tableSelection,:).xRayEkin_eV{ii},p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii},... - p.Results.DataTable.(p.Results.DataFieldname){ii},'Parent',gca,'CDataMapping','scaled'); - axis(gca,'ij'); - set(gca,'Layer','top'); - xlim([p.Results.DataTable(p.Results.tableSelection,:).xRayEkin_eV{ii}(1) p.Results.DataTable(p.Results.tableSelection,:).xRayEkin_eV{ii}(end)]); - ylim([p.Results.DataTable(p.Results.tableSelection,:).scientaEkinMin_eV(ii) p.Results.DataTable(p.Results.tableSelection,:).scientaEkinMax_eV(ii)]); - xlabel('Photon energy [eV]') - ylabel('Auger energy [eV]') - % if this does not work, plot without scaling (just with row and column numbers) - catch - image(p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii},'Parent',gca,'CDataMapping','scaled'); - axis(gca,'ij'); - set(gca,'Layer','top'); - ylim([1 size(p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii},1)]); - xlim([1 size(p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii},2)]); - xlabel('# Photon energy, column number') - ylabel('# Auger energy, column number') - end - - box(gca,'on'); - title(p.Results.DataTable(p.Results.tableSelection,:).name{ii},'Interpreter','none') - end - end \ No newline at end of file diff --git a/nappIce/nappPlot.m b/nappIce/nappPlot.m deleted file mode 100644 index 8535955..0000000 --- a/nappIce/nappPlot.m +++ /dev/null @@ -1,551 +0,0 @@ -function hdl = nappPlot(DataTable,varargin) -%nappPlot is the one-and-only function to plot PE spectra and images. -% -% nappPlotXps(FileList,tmpDataSelection) -% -% *input* -% FileList: data table -% tableSelection (optional): logical array to filter data table -% tableVariable (optional): select what to plot: image(default),'imageRoh','spectrum_countsPerSecond','spectrum_counts','spectrum_countsNorm' -% energyScale: kinetic (default) or binding, energy scale to be used for -% plots. -% mode: AllInOne (default) all spectra are plotted in one figure, images -% are plotted in one figure each; OneEach: all spectra are plotted in one -% figure each; iterations: each spectrum is plotted in one figure each -% showing the individual sequence iterations. -% plotStep, default 1: Specify the i-th iterations that should be -% plotted. -% -% -% *output* -% just a figure, with handle. -%% TODO -% -% TODO: Add averaging in image and in iteration plot -% TODO: Make code nicer (NEXAFS plotting) - -% Define conditions and defaults of input -defaultTableVariable = 'image'; -expectedTableVariable = {'image','imageRoh','spectrum_countsPerSecond','spectrum_counts','spectrum_countsNorm'}; -defaultMode = 'AllInOne'; -expectedMode = {'AllInOne','OneEach','iterations'}; -defaultFigureMode = 'screen'; -expectedFigureMode = {'screen','powerpoint','word'}; -defaultEnergyScale = 'kinetic'; -expectedEnergyScale = {'kinetic','binding','xRay'}; -defaultTableSelection = true(size(DataTable,1),1); -defaultPlotStep = 1; - -% Parse input -p = inputParser; -addRequired(p,'DataTable',@istable); -addOptional(p,'tableSelection',defaultTableSelection,@islogical); -addParameter(p,'tableVariable',defaultTableVariable,... - @(x) any(validatestring(x,expectedTableVariable))); -addParameter(p,'mode',defaultMode,... - @(x) any(validatestring(x,expectedMode))); -addParameter(p,'figureMode',defaultFigureMode,... - @(x) any(validatestring(x,expectedFigureMode))); -addParameter(p,'energyScale',defaultEnergyScale,... - @(x) any(validatestring(x,expectedEnergyScale))); -addParameter(p,'plotStep',defaultPlotStep); -parse(p,DataTable,varargin{:}); - -if ~all(cell2mat(cellfun(@size,p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable),'UniformOutput',false)),'all') - disp('The table variable appears to be empty. I quit now') - error('The table variable appears to be empty.') -end - - -% make figure, with options for output. -if contains(p.Results.figureMode ,'screen') % standard - alw = get(groot,'DefaultAxesLineWidth'); - fsz = get(groot,'DefaultAxesFontSize'); - lw = 2; %get(groot,'DefaultLineLineWidth'); - fnt = get(groot,'DefaultAxesFontName'); - loc = 'northeastoutside'; - unt = 'pixels'; - pos = [20 100 800 500]; - -elseif contains(p.Results.figureMode,'powerpoint') - alw = 2; - fsz = 26; - lw = 4; - fnt = 'Helvetica Neue'; - loc = 'northeastoutside'; - unt = 'pixels'; - pos = [300 200 1280 720]; - -elseif contains(p.Results.figureMode,'word') - alw = 0.75; - fsz = 10; - lw = 0.5; - fnt = 'Helvetica Neue'; - loc = 'southoutside'; - unt = 'centimeters'; - pos = [8 10 8 10]; - -end - - - - - -if matches(p.Results.tableVariable,'image') - for ii = 1:size(p.Results.DataTable(p.Results.tableSelection,:),1) - if endsWith(p.Results.DataTable(p.Results.tableSelection,:).name{ii},'h5') % let's do NEXAFS first. - hdl = figure('Name',p.Results.DataTable(p.Results.tableSelection,:).name{ii},'units', unt,'Position',pos); - - % Create axes - hold(gca,'on'); - % Try to plot image with x and y - try - % interpolate, to have equal x spacing for image plot - Xq = p.Results.DataTable(p.Results.tableSelection,:).xRayEkin_eV{ii}(1):0.1:p.Results.DataTable(p.Results.tableSelection,:).xRayEkin_eV{ii}(end); - Vq = interp2(p.Results.DataTable(p.Results.tableSelection,:).xRayEkin_eV{ii},p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii},... - p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii},Xq,p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii}); - image(Xq,p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii},... - Vq,'Parent',gca,'CDataMapping','scaled'); - axis(gca,'ij'); - set(gca,'Layer','top'); - xlim([p.Results.DataTable(p.Results.tableSelection,:).xRayEkin_eV{ii}(1) p.Results.DataTable(p.Results.tableSelection,:).xRayEkin_eV{ii}(end)]); - ylim([p.Results.DataTable(p.Results.tableSelection,:).scientaEkinRange_eV(ii,1) p.Results.DataTable(p.Results.tableSelection,:).scientaEkinRange_eV(ii,2)]); - hXLabel = xlabel('Photon energy [eV]'); - hYLabel = ylabel('Auger energy [eV]'); - % if this does not work, plot without scaling (just with row and column numbers) - catch - image(p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii},'Parent',gca,'CDataMapping','scaled'); - axis(gca,'ij'); - set(gca,'Layer','top'); - ylim([1 size(p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii},1)]); - xlim([1 size(p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii},2)]); - hXLabel = xlabel('# Photon energy, column number'); - hYLabel = ylabel('# Auger energy, column number'); - end - - box(gca,'on'); - if ~matches(p.Results.figureMode,'word') - title(p.Results.DataTable(p.Results.tableSelection,:).name{ii},'Interpreter','none') - end - set( gca, ... - 'FontName' , fnt,'FontSize' , fsz ); - set([hXLabel, hYLabel], ... - 'FontName' , fnt); - set([hXLabel, hYLabel] , ... - 'FontSize' , 1.2*fsz ); - - set(gca, ... - 'Box' , 'off' , ... - 'TickDir' , 'out' , ... - 'TickLength' , [.02 .02] , ... - 'XMinorTick' , 'on' , ... - 'YMinorTick' , 'off' , ... - 'XGrid' , 'on' , ... - 'XColor' , [0 0 0], ... - 'YColor' , [0 0 0], ... - 'LineWidth' , alw ); - elseif endsWith(p.Results.DataTable(p.Results.tableSelection,:).name{ii},'ibw') - - if contains(p.Results.energyScale,'kinetic') - hdl = figure('Name',p.Results.DataTable(p.Results.tableSelection,:).name{ii},'units', unt,'Position',pos); - - % Create axes - hold(gca,'on'); - image(p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii},... - 1:length(1:size(p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii},2)),... - p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii}',... - 'Parent',gca,'CDataMapping','scaled'); - axis(gca,'ij'); - set(gca,'Layer','top'); - ylim([1 size(p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii},2)]); - xlim([p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii}(1) p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii}(end)]); - hXLabel = xlabel('Electron energy [eV]'); - hYLabel = ylabel('Sequence iteration'); - elseif contains(p.Results.energyScale,'binding') - hdl = figure('Name',p.Results.DataTable(p.Results.tableSelection,:).name{ii},'units', unt,'Position',pos); - - % Create axes - hold(gca,'on'); - image(p.Results.DataTable(p.Results.tableSelection,:).bindingEnergy_eV{ii},... - 1:length(1:size(p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii},2)),... - p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii}',... - 'Parent',gca,'CDataMapping','scaled'); - axis(gca,'ij'); - set(gca,'Layer','top'); - ylim([1 size(p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii},2)]); - % xlim([p.Results.DataTable(p.Results.tableSelection,:).bindingEnergy_eV(ii,1) p.Results.DataTable(p.Results.tableSelection,:).bindingEnergy_eV(ii,2)]); - hXLabel = xlabel('Binding energy [eV]'); - hYLabel = ylabel('Sequence iteration'); - end - box(gca,'on'); - existColumn = strcmp('sample',p.Results.DataTable.Properties.VariableNames); - if ~matches(p.Results.figureMode,'word') - if ~any(existColumn) - title([{p.Results.DataTable(p.Results.tableSelection,:).name{ii} p.Results.DataTable(p.Results.tableSelection,:).lastModifiedDatestr{ii}}],'Interpreter','none') - else - title([{p.Results.DataTable(p.Results.tableSelection,:).name{ii} p.Results.DataTable(p.Results.tableSelection,:).sample{ii} p.Results.DataTable(p.Results.tableSelection,:).lastModifiedDatestr{ii}}] ,'Interpreter','none') - end - end - set( gca, ... - 'FontName' , fnt,'FontSize' , fsz ); - set([hXLabel, hYLabel], ... - 'FontName' , fnt); - set([hXLabel, hYLabel] , ... - 'FontSize' , 1.2*fsz ); - - set(gca, ... - 'Box' , 'off' , ... - 'TickDir' , 'out' , ... - 'TickLength' , [.02 .02] , ... - 'XMinorTick' , 'on' , ... - 'YMinorTick' , 'off' , ... - 'XGrid' , 'on' , ... - 'XColor' , [0 0 0], ... - 'YColor' , [0 0 0], ... - 'LineWidth' , alw ); - end - end -end -if matches(p.Results.tableVariable,'imageRoh') - for ii = 1:size(p.Results.DataTable(p.Results.tableSelection,:),1) - if endsWith(p.Results.DataTable(p.Results.tableSelection,:).name{ii},'h5') % let's do NEXAFS first. - hdl = figure('Name',p.Results.DataTable(p.Results.tableSelection,:).name{ii},'units', unt,'Position',pos); - - % Create axes - hold(gca,'on'); - % Try to plot image with x and y - try - image(p.Results.DataTable(p.Results.tableSelection,:).xRayEkin_eV{ii},p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii},... - p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii},'Parent',gca,'CDataMapping','scaled'); - axis(gca,'ij'); - set(gca,'Layer','top'); - xlim([p.Results.DataTable(p.Results.tableSelection,:).xRayEkin_eV{ii}(1) p.Results.DataTable(p.Results.tableSelection,:).xRayEkin_eV{ii}(end)]); - ylim([p.Results.DataTable(p.Results.tableSelection,:).scientaEkinRange_eV(ii,1) p.Results.DataTable(p.Results.tableSelection,:).scientaEkinRange_eV(ii,2)]); - hXLabel = xlabel('Photon energy [eV]'); - hYLabel = ylabel('Auger energy [eV]'); - % if this does not work, plot without scaling (just with row and column numbers) - catch - image(p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii},'Parent',gca,'CDataMapping','scaled'); - axis(gca,'ij'); - set(gca,'Layer','top'); - ylim([1 size(p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii},1)]); - xlim([1 size(p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii},2)]); - hXLabel = xlabel('# Photon energy, column number'); - hYLabel = ylabel('# Auger energy, column number'); - end - - box(gca,'on'); - set( gca, ... - 'FontName' , fnt,'FontSize' , fsz ); - set([hXLabel, hYLabel], ... - 'FontName' , fnt); - set([hXLabel, hYLabel] , ... - 'FontSize' , 1.2*fsz ); - - set(gca, ... - 'Box' , 'off' , ... - 'TickDir' , 'out' , ... - 'TickLength' , [.02 .02] , ... - 'XMinorTick' , 'on' , ... - 'YMinorTick' , 'off' , ... - 'XGrid' , 'on' , ... - 'XColor' , [0 0 0], ... - 'YColor' , [0 0 0], ... - 'LineWidth' , alw ); - elseif endsWith(p.Results.DataTable(p.Results.tableSelection,:).name{ii},'ibw') - - if contains(p.Results.energyScale,'kinetic') - hdl = figure('Name',p.Results.DataTable(p.Results.tableSelection,:).name{ii},'units', unt,'Position',pos); - - % Create axes - hold(gca,'on'); - existColumn = strcmp('scientaEkinRoh_eV',DataTable.Properties.VariableNames); - if any(existColumn) - image(p.Results.DataTable(p.Results.tableSelection,:).scientaEkinRoh_eV{ii},... - 1:length(1:size(p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii},2)),... - p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii}',... - 'Parent',gca,'CDataMapping','scaled'); - xlim([p.Results.DataTable(p.Results.tableSelection,:).scientaEkinRoh_eV{ii}(1) p.Results.DataTable(p.Results.tableSelection,:).scientaEkinRoh_eV{ii}(end)]); - - else - image(p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii},... - 1:length(1:size(p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii},2)),... - p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii}',... - 'Parent',gca,'CDataMapping','scaled'); - xlim([p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii}(1) p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii}(end)]); - - end - axis(gca,'ij'); - set(gca,'Layer','top'); - ylim([1 size(p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii},2)]); - hXLabel = xlabel('Electron energy [eV]'); - hYLabel = ylabel('Sequence iteration'); - elseif contains(p.Results.energyScale,'binding') - hdl = figure('Name',p.Results.DataTable(p.Results.tableSelection,:).name{ii},'units', unt,'Position',pos); - - % Create axes - hold(gca,'on'); - image(p.Results.DataTable(p.Results.tableSelection,:).bindingEnergy_eV{ii},... - 1:length(1:size(p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii},2)),... - p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii}',... - 'Parent',gca,'CDataMapping','scaled'); - axis(gca,'ij'); - set(gca,'Layer','top'); - ylim([1 size(p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii},2)]); - % xlim([p.Results.DataTable(p.Results.tableSelection,:).bindingEnergy_eV(ii,1) p.Results.DataTable(p.Results.tableSelection,:).bindingEnergy_eV(ii,2)]); - hXLabel = xlabel('Binding energy [eV]'); - hYLabel = ylabel('Sequence iteration'); - - end - box(gca,'on'); - - existColumn = strcmp('sample',p.Results.DataTable.Properties.VariableNames); - if ~matches(p.Results.figureMode,'word') - if ~any(existColumn) - title([{p.Results.DataTable(p.Results.tableSelection,:).name{ii} p.Results.DataTable(p.Results.tableSelection,:).lastModifiedDatestr{ii}}],'Interpreter','none') - else - title([{p.Results.DataTable(p.Results.tableSelection,:).name{ii} p.Results.DataTable(p.Results.tableSelection,:).sample{ii} p.Results.DataTable(p.Results.tableSelection,:).lastModifiedDatestr{ii}}] ,'Interpreter','none') - end - end - set( gca, ... - 'FontName' , fnt,'FontSize' , fsz ); - set([hXLabel, hYLabel], ... - 'FontName' , fnt); - set([hXLabel, hYLabel] , ... - 'FontSize' , 1.2*fsz ); - - set(gca, ... - 'Box' , 'off' , ... - 'TickDir' , 'out' , ... - 'TickLength' , [.02 .02] , ... - 'XMinorTick' , 'on' , ... - 'YMinorTick' , 'off' , ... - 'XGrid' , 'on' , ... - 'XColor' , [0 0 0], ... - 'YColor' , [0 0 0], ... - 'LineWidth' , alw ); - end - end -end - - -if contains(p.Results.tableVariable,'spectrum') - if contains(p.Results.mode,'OneEach') - for ii = 1:size(p.Results.DataTable(p.Results.tableSelection,:),1) - hdl = figure('Name',p.Results.DataTable(p.Results.tableSelection,:).name{ii},'units', unt,'Position',pos); - - % Create axes - hold(gca,'on'); - if (contains(p.Results.energyScale,'kinetic') & endsWith(p.Results.DataTable(p.Results.tableSelection,:).name{ii},'ibw')) - hplot = plot(p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii},... - p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii}'); - hplot.LineWidth = lw; - hXLabel = xlabel('Electron kinetic energy [eV]'); - xlim([p.Results.DataTable(p.Results.tableSelection,:).scientaEkinRange_eV(ii,1) p.Results.DataTable(p.Results.tableSelection,:).scientaEkinRange_eV(ii,2)]); - - elseif (contains(p.Results.energyScale,'binding') & endsWith(p.Results.DataTable(p.Results.tableSelection,:).name{ii},'ibw')) - hplot = plot(p.Results.DataTable(p.Results.tableSelection,:).bindingEnergy_eV{ii},... - p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii}'); - hplot.LineWidth = lw; - hXLabel= xlabel('Binding energy [eV]'); - xlim([min(p.Results.DataTable(p.Results.tableSelection,:).bindingEnergy{ii}) max(p.Results.DataTable(p.Results.tableSelection,:).bindingEnergy_eV{ii})]); - - elseif (contains(p.Results.energyScale,'xRay') | endsWith(p.Results.DataTable(p.Results.tableSelection,:).name{ii},'h5')) - hplot = plot(p.Results.DataTable(p.Results.tableSelection,:).xRayEkin_eV{ii},... - p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii}); - hplot.LineWidth = lw; - hXLabel = xlabel('Photon Energy eV'); - xlim([p.Results.DataTable(p.Results.tableSelection,:).xRayEkinRange_eV(ii,1) p.Results.DataTable(p.Results.tableSelection,:).xRayEkinRange_eV(ii,2)]); - - end - if contains(p.Results.tableVariable,'Norm') - hYLabel = ylabel('Counts [arb. unit]'); - elseif contains(p.Results.energyScale,'xRay') - hYLabel = ylabel('partial A-M.E.Y.'); - else - hYLabel = ylabel('Counts per second'); - end - - - box(gca,'on'); - existColumn = strcmp('sample',p.Results.DataTable.Properties.VariableNames); - if ~matches(p.Results.figureMode,'word') - if ~any(existColumn) - title([{p.Results.DataTable(p.Results.tableSelection,:).name{ii} p.Results.DataTable(p.Results.tableSelection,:).lastModifiedDatestr{ii}}],'Interpreter','none') - else - title([{p.Results.DataTable(p.Results.tableSelection,:).name{ii} p.Results.DataTable(p.Results.tableSelection,:).sample{ii} p.Results.DataTable(p.Results.tableSelection,:).lastModifiedDatestr{ii}}] ,'Interpreter','none') - end - end - - set( gca, ... - 'FontName' , fnt,'FontSize' , fsz ); - set([hXLabel, hYLabel], ... - 'FontName' , fnt); - set([hXLabel, hYLabel] , ... - 'FontSize' , 1.2*fsz ); - - set(gca, ... - 'Box' , 'off' , ... - 'TickDir' , 'out' , ... - 'TickLength' , [.02 .02] , ... - 'XMinorTick' , 'on' , ... - 'YMinorTick' , 'off' , ... - 'XGrid' , 'on' , ... - 'XColor' , [0 0 0], ... - 'YColor' , [0 0 0], ... - 'LineWidth' , alw ); - - end - end - - if contains(p.Results.mode,'AllInOne') - % generate colormap - - hdl = figure('Name','AllInOneSpectrum','units', unt,'Position',pos); - if size(p.Results.DataTable(p.Results.tableSelection,:),1) >= 7 - tmp_color = colormap(parula(size(p.Results.DataTable(p.Results.tableSelection,:),1))); - else - tmp_color = colormap(lines(size(p.Results.DataTable(p.Results.tableSelection,:),1))); - end - if contains(p.Results.energyScale,'kinetic') - % axes('Parent',gcf,'XDir','reverse') - hold(gca,'on'); - for ii = 1:size(p.Results.DataTable(p.Results.tableSelection,:),1) - if endsWith(p.Results.DataTable(p.Results.tableSelection,:).name{ii},'ibw') - hplot = plot(p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii},... - p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii}','DisplayName',p.Results.DataTable(p.Results.tableSelection,:).name{ii},'Color',tmp_color(ii,:)); - hplot.LineWidth = lw; - end - end - hXLabel = xlabel('Electron kinetic energy [eV]'); - elseif contains(p.Results.energyScale,'binding') - axes('Parent',gcf,'XDir','reverse') - hold(gca,'on'); - - for ii = 1:size(p.Results.DataTable(p.Results.tableSelection,:),1) - if endsWith(p.Results.DataTable(p.Results.tableSelection,:).name{ii},'ibw') - hplot = plot(p.Results.DataTable(p.Results.tableSelection,:).bindingEnergy_eV{ii},... - p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii}','DisplayName',p.Results.DataTable(p.Results.tableSelection,:).name{ii},'Color',tmp_color(ii,:)); - hplot.LineWidth = lw; - end - end - hXLabel= xlabel('Binding energy [eV]'); - elseif contains(p.Results.energyScale,'xRay') - hold(gca,'on'); - for ii = 1:size(p.Results.DataTable(p.Results.tableSelection,:),1) - if endsWith(p.Results.DataTable(p.Results.tableSelection,:).name{ii},'h5') - hplot = plot(p.Results.DataTable(p.Results.tableSelection,:).xRayEkin_eV{ii},... - p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii},... - 'DisplayName',p.Results.DataTable(p.Results.tableSelection,:).name{ii},'Color',tmp_color(ii,:)); - hplot.LineWidth = lw; - end - end - hXLabel = xlabel('Photon Energy eV'); - end - if contains(p.Results.tableVariable,'Norm') - hYLabel = ylabel('Counts [arb. unit]'); - elseif contains(p.Results.energyScale,'xRay') - hYLabel = ylabel('partial A-M.E.Y.'); - else - hYLabel = ylabel('Counts per second'); - end - - - box(gca,'on'); - if ~matches(p.Results.figureMode,'word') - title('PE Spectra','Interpreter','none') - hlegend = legend(p.Results.DataTable(p.Results.tableSelection,:).name{:}); - hlegend.FontSize = fsz; - hlegend.Interpreter = 'none'; - hlegend.Location = loc; - set(legend, 'Interpreter','none') - end - set( gca, ... - 'FontName' , fnt,'FontSize' , fsz ); - set([hXLabel, hYLabel], ... - 'FontName' , fnt); - set([hXLabel, hYLabel] , ... - 'FontSize' , 1.2*fsz ); - - set(gca, ... - 'Box' , 'off' , ... - 'TickDir' , 'out' , ... - 'TickLength' , [.02 .02] , ... - 'XMinorTick' , 'on' , ... - 'YMinorTick' , 'off' , ... - 'XGrid' , 'on' , ... - 'XColor' , [0 0 0], ... - 'YColor' , [0 0 0], ... - 'LineWidth' , alw ); - - - - end - - -end -if contains(p.Results.mode,'iterations') - % generate colormap - - for ii = 1:size(p.Results.DataTable(p.Results.tableSelection,:),1) - if endsWith(p.Results.DataTable(p.Results.tableSelection,:).name{ii},'ibw') - - hdl = figure('Name',p.Results.DataTable(p.Results.tableSelection,:).name{ii},'units', unt,'Position',pos); - if size(p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii},2) >= 7 - tmp_color = colormap(parula(size(p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii},2))); - else - tmp_color = colormap(lines(size(p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii},2))); - end - - % Create axes - hold(gca,'on'); - - if contains(p.Results.energyScale,'kinetic') - for ij = 1:p.Results.plotStep:size(p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii},2) - hplot= plot(p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii}',... - p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii}(:,ij),'Color',tmp_color(ij,:)); - hplot.LineWidth = lw; - hold on - end - xlabel('Electron kinetic energy [eV]') - elseif contains(p.Results.energyScale,'binding') - for ij = 1:p.Results.plotStep:size(p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii},2) - hplot = plot(p.Results.DataTable(p.Results.tableSelection,:).bindingEnergy_eV{ii}',... - p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii}(:,ij),'Color',tmp_color(ii,:)); - hplot.LineWidth = lw; - end - hXLabel = xlabel('Binding energy [eV]'); - end - if contains(p.Results.tableVariable,'Norm') - hYLabel = ylabel('Counts [arb. unit]'); - else - hYLabel = ylabel('Counts per second'); - end - - - box(gca,'on'); - if ~matches(p.Results.figureMode,'word') - title([{p.Results.DataTable(p.Results.tableSelection,:).name{ii} p.Results.DataTable(p.Results.tableSelection,:).sample{ii} p.Results.DataTable(p.Results.tableSelection,:).lastModifiedDatestr{ii}}] ,'Interpreter','none') - end - set( gca, ... - 'FontName' , fnt,'FontSize' , fsz ); - set([hXLabel, hYLabel], ... - 'FontName' , fnt); - set([hXLabel, hYLabel] , ... - 'FontSize' , 1.2*fsz ); - - set(gca, ... - 'Box' , 'off' , ... - 'TickDir' , 'out' , ... - 'TickLength' , [.02 .02] , ... - 'XMinorTick' , 'on' , ... - 'YMinorTick' , 'off' , ... - 'XGrid' , 'on' , ... - 'XColor' , [0 0 0], ... - 'YColor' , [0 0 0], ... - 'LineWidth' , alw ); - end - end -end -end - diff --git a/nappIce/nappScale.m b/nappIce/nappScale.m deleted file mode 100644 index fc81083..0000000 --- a/nappIce/nappScale.m +++ /dev/null @@ -1,193 +0,0 @@ -function DataTable = nappScale(DataTable,varargin) -%nappScale can be used to normalise XPS spectra to the peak area. The peak -%of the same region or of a different region with identical SES file -%number can be used for XPS data. NEXAFS spectra can be normed to their -%area or to the intensity at an energy range of choice. -% -% FileList = nappScale(FileList,tmpDataSelection,'regionOld','C1s','regionNew','O1s'); -% -% *input* -% FileList: data table -% tableSelection (optional): logical array to filter data table. These -% spectra will be normalised. -% regionOld: C1s (default) or O1s, N1s - region spectra that will be -% normalised. Needs to be identical to the table selection (filter). -% regionNew: O1s (default) or C1s, N1s - peak area that will be used to normalise -% peakNumber: Number of the feature that should be used for fitting -% (nappFitGaussXps gives results for 4 features, default is 1) -% -% The region in tableSelection and regionOld MUST be identical. -% -% -% *output* -% table variable spectrum_countsNorm - -% Define conditions and defaults of input -defaultTableVariable = 'spectrum_countsPerSecond'; -expectedTableVariable = {'spectrum_counts','spectrum_countsPerSecond','spectrum_countsNorm'}; -defaultMode = 'area'; -expectedMode = {'intensity','area'}; -defaultRegionOld = 'C1s'; -expectedRegionOld = {'O1s','C1s','N1s','Cl2p'}; -defaultRegionNew = 'O1s'; -expectedRegionNew = {'O1s','C1s','N1s'}; -defaultPeakNumber = 1; -defaultTableSelection = true(size(DataTable,1)); - - -% Parse input -p = inputParser; -addRequired(p,'DataTable',@istable); -addOptional(p,'tableSelection',defaultTableSelection,@islogical); -addOptional(p,'energyStart',@isnumeric) -addOptional(p,'energyEnd',@isnumeric) -addParameter(p,'tableVariable',defaultTableVariable,... - @(x) any(validatestring(x,expectedTableVariable))); -addParameter(p,'regionOld',defaultRegionOld,... - @(x) any(validatestring(x,expectedRegionOld))); -addParameter(p,'regionNew',defaultRegionNew,... - @(x) any(validatestring(x,expectedRegionNew))); -addParameter(p,'peakNumber',defaultPeakNumber); -addParameter(p,'mode',defaultMode,... - @(x) any(validatestring(x,expectedMode))); -parse(p,DataTable,varargin{:}); - -% add empty variable to table -existColumn = strcmp('spectrum_countsNorm',DataTable.Properties.VariableNames); -if ~any(existColumn) - DataTable.spectrum_countsNorm = cell(size(DataTable,1),1); -end - -existColumn = strcmp('logScaleRange',DataTable.Properties.VariableNames); -if ~any(existColumn) - DataTable.logBackgroundRange = NaN(size(DataTable,1),2); -end -existColumn = strcmp('logScaleMode',DataTable.Properties.VariableNames); -if ~any(existColumn) - DataTable.logBackgroundMode = cellstr(repmat(' ',size(p.Results.DataTable,1),1)); -end -existColumn = strcmp('logScaleDate',DataTable.Properties.VariableNames); -if ~any(existColumn) - DataTable.logBackgroundDate = cellstr(repmat(' ',size(p.Results.DataTable,1),1)); -end - -% check input (all elements of input variable need to have non-zero size) -if ~all(cell2mat(cellfun(@size,p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable),'UniformOutput',false)),'all') - disp('The table variable appears to be empty. I quit now') - error('The table variable appears to be empty.') -end - - -% repeat this for all columns in input. -for ii = 1:size(p.Results.DataTable(p.Results.tableSelection,:),1) - if endsWith(p.Results.DataTable(p.Results.tableSelection,:).name{ii},'ibw') - % get name and date of input file and replace old region with new - % region. This will be the files where the peak area is taken from. - tmpName = replace(p.Results.DataTable(p.Results.tableSelection,:).name{ii}, ... - p.Results.regionOld,p.Results.regionNew); - tmpDate = p.Results.DataTable(p.Results.tableSelection,:).lastModifiedDatenum(ii); - % select spectra based on the new names and dates of original file - tmpDataSelection = contains(p.Results.DataTable.name,tmpName)... - & ismember(year(p.Results.DataTable.lastModifiedDatenum),year(tmpDate))... - & ismember(month(p.Results.DataTable.lastModifiedDatenum),month(tmpDate))... - & ismember(day(p.Results.DataTable.lastModifiedDatenum),day(tmpDate))... - & ismember(hour(p.Results.DataTable.lastModifiedDatenum),hour(tmpDate))... - & ismember(minute(p.Results.DataTable.lastModifiedDatenum),minute(tmpDate)); - % check peak area - existColumn = strcmp('peakArea',DataTable.Properties.VariableNames); - if any(existColumn) - if isnan(DataTable( tmpDataSelection,:).peakArea(p.Results.peakNumber)) - disp('The peak area appears to be empty. I quit now') - disp(DataTable( tmpDataSelection,:).name{ii}) - error('The peak area appears to be empty.') - end - else - disp('The data table appear to have not peak area column. I quit now') - error('No peak area column') - end - % do the norming - if contains(p.Results.mode,'area') - DataTable(p.Results.tableSelection,:).spectrum_countsNorm{ii} = ... - DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii}... - ./ DataTable( tmpDataSelection,:).peakArea(p.Results.peakNumber); - elseif contains(p.Results.mode,'intensity') - disp('Intensity mode not yet programmed for XPS data') - end - - elseif endsWith(p.Results.DataTable(p.Results.tableSelection,:).name{ii},'h5') - % if ~exist(p.Results.energyStart) | ~exist(p.Results.energyEnd) - % disp('The energy region used for normalisation appears to be empty. I quit now') - % error('The energy region used to normalise appears to be empty.') - % end - if contains(p.Results.mode,'intensity') - if p.Results.DataTable(p.Results.tableSelection,:).xRayEkin_eV{ii}(1)... - < p.Results.DataTable(p.Results.tableSelection,:).xRayEkin_eV{ii}(end) - % prepare Data - [xData, yData] = prepareCurveData(p.Results.DataTable(p.Results.tableSelection,:).xRayEkin_eV{ii}... - , p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii}); - % MEAN - b_1 = find(xData >= p.Results.energyStart,1); - b_2 = find(xData >= p.Results.energyEnd,1); - - b_mean = mean(yData(b_1:b_2)); - elseif p.Results.DataTable(p.Results.tableSelection,:).xRayEkin_eV{ii}(1)... - > p.Results.DataTable(p.Results.tableSelection,:).xRayEkin_eV{ii}(end) - % prepare Data - [xData, yData] = prepareCurveData( p.Results.DataTable(p.Results.tableSelection,:).xRayEkin_eV{ii}... - , p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii}); - % MEAN - b_1 = find(xData <= p.Results.energyStart,1); - b_2 = find(xData <= p.Results.energyEnd,1); - - b_mean = mean(yData(b_2:b_1)); - else - disp('Warning: Issue with NEXAFS_col_scaling') - end - - tmp_3(:,1) = p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii}... - ./b_mean; - - DataTable(p.Results.tableSelection,:).spectrum_countsNorm{ii} = tmp_3; - clearvars tmp_3 - elseif contains(p.Results.mode,'area') - if p.Results.DataTable(p.Results.tableSelection,:).xRayEkin_eV{ii}(1)... - < p.Results.DataTable(p.Results.tableSelection,:).xRayEkin_eV{ii}(end) - % prepare Data - [xData, yData] = prepareCurveData( p.Results.DataTable(p.Results.tableSelection,:).xRayEkin_eV{ii}... - , p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii}); - % Area - b_1 = find(xData >= p.Results.energyStart,1); - b_2 = find(xData >= p.Results.energyEnd,1); - - b_area = trapz(xData(b_1:b_2),yData(b_1:b_2)); - elseif p.Results.DataTable(p.Results.tableSelection,:).xRayEkin_eV{ii}(1)... - > p.Results.DataTable(p.Results.tableSelection,:).xRayEkin_eV{ii}(end) - % prepare Data - [xData, yData] = prepareCurveData( p.Results.DataTable(p.Results.tableSelection,:).xRayEkin_eV{ii}... - , p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii}); - % MEAN - b_1 = find(xData <= p.Results.energyStart,1); - b_2 = find(xData <= p.Results.energyEnd,1); - - b_area = trapz(xData(b_2:b_1),yData(b_2:b_1)); - else - disp('Warning: Issue with NEXAFS_col_scaling') - end - - tmp_3(:,1) = p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii}... - ./b_area; - - DataTable(p.Results.tableSelection,:).spectrum_countsNorm{ii} = tmp_3; - clearvars tmp_3 - - end - end -end -% write log to table -DataTable.logScaleMode(p.Results.tableSelection,:) = cellstr(repmat(p.Results.mode,size(p.Results.DataTable(p.Results.tableSelection,:),1),1)); -if endsWith(p.Results.DataTable(p.Results.tableSelection,:).name{ii},'h5') - DataTable.logScaleRange(p.Results.tableSelection,:) = repmat([p.Results.energyStart p.Results.energyEnd],size(p.Results.DataTable(p.Results.tableSelection,:),1),1); -end -DataTable.logScaleDate(p.Results.tableSelection,:) = cellstr(repmat(datestr(now),size(p.Results.DataTable(p.Results.tableSelection,:),1),1)); - -end \ No newline at end of file