%% BeamTime2016PhoenixIceNapp % add ../Functions to path (works on Windows and macOS) funcDir = fullfile(fileparts(mfilename('fullpath')), '..', 'Functions'); funcDir = char(java.io.File(funcDir).getCanonicalPath); % resolves .. and symlinks cross-platform if isfolder(funcDir) addpath(funcDir); else warning('Functions directory not found: %s', funcDir); end clearvars close all clc %% Import and Generate Spectra % @DEP_IN: BeamTime2016PhoenixIceNapp FileList = nappFileList('BeamTime2016PhoenixIceNapp','mode','local'); FileList = nappGenerateSpectra(FileList); %% Add photon energy and sample type idxSpotChange1 = find(matches(FileList.name,"PHOENIX0207207.ibw")); idxSpotChange2 = find(matches(FileList.name,"PHOENIX0225225.ibw")); idxSpotChange3 = find(matches(FileList.name,"PHOENIX0229229.ibw")); idxSpotChange4 = find(matches(FileList.name,"PHOENIX0235235.ibw")); idxSpotChange5 = find(matches(FileList.name,"PHOENIX0235235.ibw")); idxSpotChange6 = find(matches(FileList.name,"PHOENIX0238238.ibw")); isIBW = endsWith(FileList.name,'.ibw'); k = find(isIBW); for ii = 1:length(k) FileList(k(ii),:).xRayEkin_eV{:} = 2200; end for ii = 1:idxSpotChange1 FileList(ii,:).sample{:} = 'NaCl; H2O gas, Spot#1 (0/0/6)'; end for ii = idxSpotChange1+1:idxSpotChange2 FileList(ii,:).sample{:} = 'NaCl; H2O gas, Spot#2 (0/0.6/6)'; end for ii = idxSpotChange2+1:idxSpotChange3 FileList(ii,:).sample{:} = 'NaCl; H2O gas, Spot#3 (-1/0.6/6.6)'; end for ii = idxSpotChange3+1:idxSpotChange4 FileList(ii,:).sample{:} = 'NaCl; H2O gas, Spot#4 (0/0.6/6.1)'; end for ii = idxSpotChange4+1:idxSpotChange5 FileList(ii,:).sample{:} = 'NaCl; H2O gas, Spot#5 (0.5/1.7/5.8)'; end for ii = idxSpotChange5+1:idxSpotChange6 FileList(ii,:).sample{:} = 'NaCl; H2O gas, Spot#6 (0/0.9/6)'; end for ii = idxSpotChange6+1:308 FileList(ii,:).sample{:} = 'NaCl; H2O gas, Spot#6 (-1/0.4/6.4)'; end %% Add meta-data (keywords) propNames = ["campaignName","campaignLocation","campaignInstrument","projectName","contact","sourceDirectory","startDate","endDate","dataLevel","publicationDoi", "funding", "contactORCID", "publicationDataDoi", "rawDataDoi", "team"]; try FileList = addprop(FileList, propNames, repmat("table",1,numel(propNames))); catch % properties already exist from a previous run -- fine, just update values below end FileList.Properties.CustomProperties.campaignName = "Beamtime Phoenix Spring 2016"; FileList.Properties.CustomProperties.campaignLocation = "SLS/Phoenix"; FileList.Properties.CustomProperties.campaignInstrument = "NappEndstation"; FileList.Properties.CustomProperties.projectName = "NappIce"; FileList.Properties.CustomProperties.contact = "thorsten.bartels-rausch@psi.ch"; FileList.Properties.CustomProperties.contactORCID = "0000-0002-7548-2572"; FileList.Properties.CustomProperties.team = "Thorsten Bartels-Rausch, Xiangrui Kong, Fabrizio Orlando, Luca Artiglia, Astrid Waldner,Thomas Huthwelker,Markus Ammann"; FileList.Properties.CustomProperties.sourceDirectory = FileList.folder{1}; FileList.Properties.CustomProperties.startDate = FileList(1,:).lastModifiedDatestr{:}; FileList.Properties.CustomProperties.endDate = FileList(end,:).lastModifiedDatestr{:}; FileList.Properties.CustomProperties.dataLevel = 0; FileList.Properties.CustomProperties.publicationDoi = "10.5194/tc-15-2001-2021"; FileList.Properties.CustomProperties.publicationDataDoi = "10.16904/envidat.164"; FileList.Properties.CustomProperties.rawDataDoi = " "; FileList.Properties.CustomProperties.funding = "SNF 149629"; % Adds human-readable column descriptions and units to the standard table % properties Properties.VariableDescriptions / Properties.VariableUnits meta.name = struct('desc','File name of the imported data or photo file.', 'unit',''); meta.folder = struct('desc','Full path to the folder containing the file.', 'unit',''); meta.creationDate = struct('desc','Acquisition timestamp: from instrument metadata for XPS/NEXAFS files, or OS file creation time for photos. Stored as a datevec [Y M D H MI S].', 'unit',''); meta.lastModifiedDatenum = struct('desc','OS file modification time, as a MATLAB datenum.', 'unit',''); meta.lastModifiedDatestr = struct('desc','OS file modification time, as a formatted date string.', 'unit',''); meta.image = struct('desc','2D spectral map (kinetic energy vs. iteration/scan), normalized to counts per second.', 'unit','counts/s'); meta.imageRoh = struct('desc','Raw copy of the 2D spectral map.', 'unit','counts/s'); meta.xRayEkin_eV = struct('desc','X-ray excitation (photon) energy: the scan axis for NEXAFS, or the single excitation energy used for an XPS region.', 'unit','eV'); meta.xRayEkinRange_eV = struct('desc','[min max] range of the X-ray excitation energy scan.', 'unit','eV'); meta.scientaPassEnergy_eV = struct('desc','Analyzer pass energy setting.', 'unit','eV'); meta.scientaDwellTime_ms = struct('desc','Aquisition (step) time per data point.', 'unit','ms'); meta.regionName = struct('desc','Name of the measured region, e.g. an XPS core level (''C1s''), a survey scan, or a NEXAFS edge.', 'unit',''); meta.scientaAcquisitionMode = struct('desc','Analyzer acquisition mode: ''Swept'' (scanning) or ''Fixed'' (fixed energy window).', 'unit',''); meta.scientaEkinRange_eV = struct('desc','[min max] kinetic energy range of the analyzer scan.', 'unit','eV'); meta.scientaEkinStep_eV = struct('desc','Kinetic energy step size between data points.', 'unit','eV'); meta.scientaEkin_eV = struct('desc','The kinetic energy axis of the spectrum.', 'unit','eV'); meta.scientaEkinRoh_eV = struct('desc','Raw copy of the kinetic energy axis of the spectrum, kept alongside scientaEkin_eV in case later processing modifies the data.', 'unit','eV'); meta.beamlineInt = struct('desc','Beamline (incident photon) intensity, I0, used to normalize NEXAFS signal.', 'unit','a.u.'); meta.scientaLensMode = struct('desc','Analyzer lens transmission mode.', 'unit',''); meta.scientaAnalyzerSlit = struct('desc','Analyzer entrance slit setting.', 'unit',''); meta.scientaWorkfunction_eV = struct('desc','Analyzer work function used in the kinetic-to-binding-energy conversion.', 'unit','eV'); meta.scientaRegionIterations = struct('desc','Number of repeated scans within one region measurement, averaged together during import.', 'unit',''); meta.scientaSequenceIterations = struct('desc','Number of sequence repeats.', 'unit',''); meta.importDate = struct('desc','Timestamp of when this row was generated by nappFileList.', 'unit',''); meta.analysisDir = struct('desc','Working directory (or calling script''s folder) at the time of import.', 'unit',''); meta.sample = struct('desc','Sample name or description, from the SpecsLab comment field (.xy files) or set later from the lab journal.', 'unit',''); meta.sampleTemp_dC = struct('desc','Sample (cryo-holder) temperature, from the LabView log.', 'unit','degC'); meta.cellPressure_mbar = struct('desc','Sample cell pressure, from the LabView Baratron log.', 'unit','mbar'); meta.iceTemp_dC = struct('desc','Ice equilibrium temperature, derived from cellPressure_mbar via the Marti & Mauersberger (1993) vapour-pressure parameterization.', 'unit','degC'); meta.smplX_mm = struct('desc','Sample holder X position.', 'unit','mm'); meta.smplY_mm = struct('desc','Sample holder Y position.', 'unit','mm'); meta.smplZ_mm = struct('desc','Sample holder Z position.', 'unit','mm'); meta.sealingTemp = struct('desc','Sealing temperature, from the LabView log.', 'unit','degC'); meta.originalFileName = struct('desc','Original file name before a multi-region Specs .xy file was split into one row per region.', 'unit',''); % added by generate spectra meta.spectrum_countsPerSecond = struct('desc','1D spectrum for .ibw/.xy rows in ''mean''/''trapz'' mode: the mean (or trapz) of the image data -- already counts/s, since nappFileList normalizes by dwell time before storing image. Not populated for .h5/NEXAFS rows (their result goes to spectrum_counts instead).', 'unit','counts/s'); meta.spectrum_counts = struct('desc','1D spectrum: for .h5/NEXAFS rows, the sum or trapezoidal integral of the image over the selected kinetic-energy range (not time-normalized), for any mode; for .ibw/.xy rows, only populated when mode=''sum'' (sum over the selected iteration range).', 'unit','counts'); meta.logNappGenerateSpectraRange = struct('desc','[start end] range used to generate the spectrum: kinetic-energy limits for .h5 rows, or iteration indices for .ibw/.xy rows.', 'unit','eV (h5) or index (ibw/xy)'); meta.logNappGenerateSpectraDate = struct('desc','Logs when the spectrum was generated', 'unit',''); meta.logNappGenerateSpectraMode = struct('desc','Reduction mode used to generate the spectrum for this row (''mean'', ''sum'', ''trapz'', or ''AugerMeitnerMean'').', 'unit',''); meta.logNappGenerateSpectraCaller = struct('desc','File path of the script or function that called nappGenerateSpectra, for provenance.', 'unit',''); varNames = FileList.Properties.VariableNames; descriptions = repmat({''}, 1, numel(varNames)); units = repmat({''}, 1, numel(varNames)); for k = 1:numel(varNames) if isfield(meta, varNames{k}) descriptions{k} = meta.(varNames{k}).desc; units{k} = meta.(varNames{k}).unit; end end FileList.Properties.VariableDescriptions = descriptions; FileList.Properties.VariableUnits = units; %% Tidy up FileList = removevars(FileList,{'smplX_mm','smplY_mm','smplZ_mm','scientaAnalyzerSlit','scientaWorkfunction_eV','sealingTemp'}); FileList.comment = repmat({''}, height(FileList), 1); clearvars -except FileList %% Export and Save ExportList = removevars(FileList, {'image', 'scientaEkin_eV', 'beamlineInt', 'imageRoh', 'scientaEkinRoh_eV', 'xRayEkin_eV', 'spectrum_countsPerSecond', 'spectrum_counts' }); % @DEP_OUT: Apr2016_DataTable.csv writetable(ExportList,fullfile([datestr(ExportList.lastModifiedDatenum(1),'mmmYYYY') '_DataList.csv']),'Delimiter',','); % write to command line whos('FileList'); % basic size/type info disp('--- Table Properties ---') disp(FileList.Properties) % show table properties (Description, UserData, VariableDescriptions, etc.) disp('--- Summary of Table ---') summary(FileList) % concise summary of variables and types %% clearvars -except FileList % @DEP_OUT: Apr2016_DataTable.mat save("Apr2016_DataTable.mat") % @DEP_OUT: Apr2016_DataTable.h5 nappExportH5(FileList, "Apr2016_DataTable.h5");