function hdl = nappPlot(DataTable,varargin) %NAPPLOT Plot photoelectron spectra and NEXAFS images from a data table. % hdl = NAPPLOT(DataTable) creates figures for all rows in DataTable % using the default visualization options and returns the handle(s) to % the generated figure(s). % % hdl = NAPPLOT(DataTable, tableSelection) restricts plotting to rows for % which tableSelection is true. The length of tableSelection must % match the height of DataTable. % % hdl = NAPPLOT(DataTable, tableSelection, Name, Value) additionally % customizes the data source, energy axis, layout mode, and figure % formatting using Name-Value arguments. % % NAPPLOT is a general-purpose visualization routine for spectroscopy % experiments that can display: % - NEXAFS images (h5) % - time-resolved XPS/Auger maps (ibw) % - 1D spectra from previously generated table variables % - interactive NEXAFS + Auger-Meitner views % % Required input % -------------- % DataTable % Table that contains spectroscopy data and metadata. % Depending on the chosen tableVariable and energyScale, the % following variables are typically used: % - name : file name (string/char), used to % distinguish '.h5', '.ibw', '.xy' % - image : processed 2D image (cell of numeric) % - imageRoh : raw 2D image (cell of numeric) % - spectrum_counts : 1D spectrum (in arbitrary counts % - spectrum_countsPerSecond % : 1D spectrum (normalized to counts per second) % - spectrum_countsNorm : 1D normalized spectrum % - scientaEkin_eV : kinetic energy axis (cell of numeric) % - bindingEnergy_eV : binding energy axis (cell of numeric) % - xRayEkin_eV : photon energy axis (cell of numeric) % - scientaEkinRange_eV : [emin emax] for plotting % - xRayEkinRange_eV : [emin emax] for plotting % - lastModifiedDatestr : acquisition or file time stamp % - sample : (optional) sample name for titles % % Optional positional input % ------------------------- % tableSelection % Logical vector selecting rows of DataTable to plot. % Default: all rows true % % Name-Value arguments % -------------------- % 'tableVariable' % Name of the variable in DataTable to plot. % Type : char or string % Values : 'image' (default) % 'imageRoh' % 'spectrum_countsPerSecond' % 'spectrum_counts' % 'spectrum_countsNorm' % % 'energyScale' % Energy axis used for plotting % Type : char or string % Values : 'kinetic' (default) - use scientaEkin_eV % 'binding' - use bindingEnergy_eV % 'xRay' - use xRayEkin_eV % 'sweeps' - use column/iteration index % % 'mode' % Layout and plotting mode % Type : char or string % Values : 'AllInOne' (default) % - Plot all selected 1D spectra in a single axes % (overlaid). % 'OneEach' % - One figure per single spectrum or image. % 'iterations' % - Plot multiple iterations from a 2D stack in different % colors to show time/sequence evolution. % 'AugerMeitner' % - Extract and plot Auger-Meitner spectra at specified % photon energies for NEXAFS maps ('.h5'). % 'interactive' % - Interactive layout for NEXAFS images with linked % Auger-Meitner and NEXAFS line cuts controlled by % mouse / data cursor callbacks. % % 'figureMode' % Overall figure formatting, size, and font presets. % Type : char or string % Values : 'screen' (default) % - Standard display window in pixels, moderate fonts. % 'powerpoint' % - Larger window and fonts optimized for slides. % 'word' % - Compact figure in centimeters for documents. % % 'plotStep' % Step size in iteration index for 'iterations' mode. % Type : positive numeric scalar % Default: 1 (plot every iteration) % % 'AugerMeitnerEnergies' % Photon energies (in eV) for 'AugerMeitner' mode % At each value, the function extracts one column from the image and % plots the corresponding Auger-Meitner electron spectrum. % Type : numeric vector % % Output % ------ % hdl % Handle or array of handles to the generated figure(s) % For 'AllInOne' this is a single figure. For 'OneEach', % 'iterations', 'AugerMeitner', and 'interactive', hdl may contain % one handle per processed row. % % Notes % ----- % - The function checks that the chosen tableVariable is non-empty for % all selected rows and throws an error otherwise. % - File type is inferred from the 'name' variable to distinguish h5, % ibw, and xy-type data % - Axis labels, limits, and titles are adapted automatically based on % energyScale, tableVariable, and available metadata (sample name, % time stamp) % - In 'interactive' mode, datacursor and mouse motion callbacks update % linked line plots for Auger-Meitner and NEXAFS traces. %% 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','AugerMeitner','interactive'}; defaultFigureMode = 'screen'; expectedFigureMode = {'screen','powerpoint','word'}; defaultEnergyScale = 'kinetic'; expectedEnergyScale = {'kinetic','binding','xRay','sweeps'}; 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); addParameter(p,'AugerMeitnerEnergies',@isnumeric) 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.mode,'AugerMeitner') for ii = 1:size(p.Results.DataTable(p.Results.tableSelection,:),1) if endsWith(p.Results.DataTable(p.Results.tableSelection,:).name{ii},'h5') hdl = figure('Name',p.Results.DataTable(p.Results.tableSelection,:).name{ii},'units', unt,'Position',pos); if size(p.Results.AugerMeitnerEnergies) >= 7 tmp_color = colormap(parula(size(p.Results.AugerMeitnerEnergies,2))); else tmp_color = colormap(lines(size(p.Results.AugerMeitnerEnergies,2))); end % Create axes hold(gca,'on'); for ij = 1:size(p.Results.AugerMeitnerEnergies,2) % find x-ray energy in data tmpXrayEnergy = find(p.Results.DataTable(p.Results.tableSelection,:).xRayEkin_eV{ii} >= p.Results.AugerMeitnerEnergies(ij),1); hplot= plot( p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii}, ... p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii}(:,tmpXrayEnergy)); hplot.LineWidth = lw; hold on end xlabel('Auger-Meitner electron energy [eV]') hYLabel = ylabel('Counts per dwell time'); legend(string(p.Results.AugerMeitnerEnergies)) end end end if matches(p.Results.tableVariable,'image') && matches(p.Results.mode,'interactive') 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',[20 100 1000 800]); tld = tiledlayout(2,2); tld.TileSpacing = 'compact'; tld.Padding = 'compact'; % image ax1= nexttile; img_handle = image(p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii},'Parent',ax1,'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'); box(gca,'on'); set( gca, ... 'FontName' , fnt,'FontSize' , fsz ); set([hXLabel, hYLabel], ... 'FontName' , fnt); set([hXLabel, hYLabel] , ... 'FontSize' , 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 ); hdl.Pointer = 'crosshair'; ij= 1; ik=1; % Auger-Meitner ax2 = nexttile; hplot= plot(p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii}(:,ij), p.Results.DataTable(p.Results.tableSelection,:).scientaEkin_eV{ii}); hplot.LineWidth = lw; hold on ylabel('A-M e energy [eV]') xlabel('Counts per dwell time'); ax2.YDir = 'reverse'; box(ax2,'on'); set( ax2, ... 'FontName' , fnt,'FontSize' , fsz ); set([hXLabel, hYLabel], ... 'FontName' , fnt); set([hXLabel, hYLabel] , ... 'FontSize' , fsz ); set(ax2, ... 'Box' , 'off' , ... 'TickDir' , 'out' , ... 'TickLength' , [.02 .02] , ... 'XMinorTick' , 'on' , ... 'YMinorTick' , 'off' , ... 'XGrid' , 'on' , ... 'XColor' , [0 0 0], ... 'YColor' , [0 0 0], ... 'LineWidth' , alw ); % NEXAFS ax3 = nexttile; hplot2= plot( p.Results.DataTable(p.Results.tableSelection,:).xRayEkin_eV{ii}, ... p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii}(ik,:)); hplot2.LineWidth = lw; hold on xlabel('xray energy [eV]') hYLabel = ylabel('Counts per dwell time'); box(ax3,'on'); set( ax3, ... 'FontName' , fnt,'FontSize' , fsz ); set([hXLabel, hYLabel], ... 'FontName' , fnt); set([hXLabel, hYLabel] , ... 'FontSize' , fsz ); set(ax3, ... 'Box' , 'off' , ... 'TickDir' , 'out' , ... 'TickLength' , [.02 .02] , ... 'XMinorTick' , 'on' , ... 'YMinorTick' , 'off' , ... 'XGrid' , 'on' , ... 'XColor' , [0 0 0], ... 'YColor' , [0 0 0], ... 'LineWidth' , alw ); if ~matches(p.Results.figureMode,'word') title(tld,p.Results.DataTable(p.Results.tableSelection,:).name{ii},'Interpreter','none') end % % NOW set up datacursor - after all axes are created dcm = datacursormode(hdl); set(dcm, 'UpdateFcn', {@updatePlots, p.Results, ii, ax2, ax3, hplot, hplot2}); set(dcm, 'Enable', 'on'); set(dcm, 'SnapToDataVertex', 'off'); % Allows smooth mouse tracking set(dcm, 'DisplayStyle', 'window'); % or 'datatip' for tooltip style % Enable continuous update on mouse move set(hdl, 'WindowButtonMotionFcn', {@mouseMoveFcn, dcm, p.Results, ii, ax2, ax3, hplot, hplot2, ax1}); end end end if matches(p.Results.tableVariable,'image') && ~matches(p.Results.mode,'AugerMeitner') && ~matches(p.Results.mode,'interactive') 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'); if matches(p.Results.energyScale,'sweep') 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'); else % 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 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') || endsWith(p.Results.DataTable(p.Results.tableSelection,:).name{ii},'xy') 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'); if size(p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii},2) >= 2 ylim([1 size(p.Results.DataTable(p.Results.tableSelection,:).(p.Results.tableVariable){ii},2)]); end 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') || endsWith(p.Results.DataTable(p.Results.tableSelection,:).name{ii},'xy') 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') || endsWith(p.Results.DataTable(p.Results.tableSelection,:).name{ii},'xy'))) 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')|| endsWith(p.Results.DataTable(p.Results.tableSelection,:).name{ii},'xy'))) 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_eV{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 try 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') catch title([{p.Results.DataTable(p.Results.tableSelection,:).name{ii} p.Results.DataTable(p.Results.tableSelection,:).sample{ii}}] ,'Interpreter','none') end 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') || endsWith(p.Results.DataTable(p.Results.tableSelection,:).name{ii},'xy')) 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') || endsWith(p.Results.DataTable(p.Results.tableSelection,:).name{ii},'xy')) 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') || endsWith(p.Results.DataTable(p.Results.tableSelection,:).name{ii},'xy') 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') %axes('Parent',gcf,'XDir','reverse') 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 % Nested callback function % function txt = updatePlots(~, event_obj, pResults, ii, ax2, ax3, hplot2, hplot3) % pos = get(event_obj, 'Position'); % ij = round(pos(1)); % ik = round(pos(2)); % % set(hplot2, 'XData', pResults.DataTable(pResults.tableSelection,:).(pResults.tableVariable){ii}(:,ij)); % title(ax2, sprintf('Auger-Meitner (X index = %d)', ij)); % % set(hplot3, 'YData', pResults.DataTable(pResults.tableSelection,:).(pResults.tableVariable){ii}(ik,:)); % title(ax3, sprintf('NEXAFS (Y index = %d)', ik)); % % % Create custom datatip text showing coordinates % txt = {sprintf('X index: %d', ij), ... % sprintf('Y index: %d', ik), ... % sprintf('Intensity: %.2f', dataMatrix(ik, ij))}; % end function mouseMoveFcn(~, ~, dcm, pResults, ii, ax2, ax3, hplot2, hplot3, ax1) % Check if mouse is over the image axes if gca == ax1 % Get current mouse position cp = get(ax1, 'CurrentPoint'); ij = round(cp(1, 1)); % X index ik = round(cp(1, 2)); % Y index % Get the data matrix dataMatrix = pResults.DataTable(pResults.tableSelection,:).(pResults.tableVariable){ii}; % Ensure indices are within bounds [nRows, nCols] = size(dataMatrix); if ij >= 1 && ij <= nCols && ik >= 1 && ik <= nRows % Update plots set(hplot2, 'XData', dataMatrix(:, ij)); title(ax2, sprintf('Auger-Meitner (X index = %d)', ij)); set(hplot3, 'YData', dataMatrix(ik, :)); title(ax3, sprintf('NEXAFS (Y index = %d)', ik)); end end end % Datatip callback - shows info function txt = updatePlots(~, event_obj, pResults, ii, ax2, ax3, hplot2, hplot3) try pos = get(event_obj, 'Position'); ij = round(pos(1)); ik = round(pos(2)); dataMatrix = pResults.DataTable(pResults.tableSelection,:).(pResults.tableVariable){ii}; [nRows, nCols] = size(dataMatrix); ij = max(1, min(ij, nCols)); ik = max(1, min(ik, nRows)); txt = {sprintf('X: %d', ij), ... sprintf('Y: %d', ik), ... sprintf('Intensity: %.2f', dataMatrix(ik, ij))}; catch pos = get(event_obj, 'Position'); txt = {sprintf('X: %.1f', pos(1)), ... sprintf('Y: %.1f', pos(2))}; end end end