Replaced plotting of raw and fit curves for the radial and angular spectral distributions with an interactive viewer (Still will put back the plotting function for direct saving to file).
This commit is contained in:
parent
5faf433329
commit
5761d3b0fe
@ -171,15 +171,17 @@ function [fitResults, rawCurves] = fitTwoGaussianCurvesToAngularSpectralDistribu
|
||||
thetaFine = linspace(0, opts.MaxTheta, 500);
|
||||
yFit = 1.0*exp(-0.5*((thetaFine - pCanonical(2))/max(pCanonical(3),1e-6)).^2) + ...
|
||||
pCanonical(4)*exp(-0.5*((thetaFine - pCanonical(5))/max(pCanonical(6),1e-6)).^2);
|
||||
|
||||
fitResults(k).pFit = pCanonical;
|
||||
fitResults(k).thetaFit = theta;
|
||||
fitResults(k).xFit = x;
|
||||
fitResults(k).thetaFine = thetaFine;
|
||||
fitResults(k).yFit = yFit;
|
||||
fitResults(k).isValid = true;
|
||||
fitResults(k).fitMaxTheta = fitMaxTheta;
|
||||
continue; % success → next curve
|
||||
|
||||
if ~isnan(pCanonical)
|
||||
fitResults(k).pFit = pCanonical;
|
||||
fitResults(k).thetaFit = theta;
|
||||
fitResults(k).xFit = x;
|
||||
fitResults(k).thetaFine = thetaFine;
|
||||
fitResults(k).yFit = yFit;
|
||||
fitResults(k).isValid = true;
|
||||
fitResults(k).fitMaxTheta = fitMaxTheta;
|
||||
continue; % success → next curve
|
||||
end
|
||||
catch
|
||||
warning('Curve %d constrained fit failed, switching to generic fit.', k);
|
||||
end
|
||||
@ -209,14 +211,16 @@ function [fitResults, rawCurves] = fitTwoGaussianCurvesToAngularSpectralDistribu
|
||||
fitMaxTheta = max(pFree(5), pFree(2));
|
||||
thetaFine = linspace(0, opts.MaxTheta, 500);
|
||||
yFit = twoGaussFree(pFree, thetaFine);
|
||||
|
||||
fitResults(k).pFit = pFree;
|
||||
fitResults(k).thetaFit = theta;
|
||||
fitResults(k).xFit = x;
|
||||
fitResults(k).thetaFine = thetaFine;
|
||||
fitResults(k).yFit = yFit;
|
||||
fitResults(k).isValid = true;
|
||||
fitResults(k).fitMaxTheta = fitMaxTheta;
|
||||
|
||||
if ~isnan(pFree)
|
||||
fitResults(k).pFit = pFree;
|
||||
fitResults(k).thetaFit = theta;
|
||||
fitResults(k).xFit = x;
|
||||
fitResults(k).thetaFine = thetaFine;
|
||||
fitResults(k).yFit = yFit;
|
||||
fitResults(k).isValid = true;
|
||||
fitResults(k).fitMaxTheta = fitMaxTheta;
|
||||
end
|
||||
catch
|
||||
warning('Curve %d: generic two-Gaussian fit failed.', k);
|
||||
fitResults(k) = fillNaNStruct();
|
||||
|
@ -103,14 +103,16 @@ function [fitResults, rawCurves] = fitTwoGaussianCurvesToRadialSpectralDistribut
|
||||
fitMaxKRho = max(pFit(5), pFit(2));
|
||||
kFine = linspace(min(kVals), max(kVals), 500);
|
||||
yFit = twoGauss(pFit, kFine);
|
||||
|
||||
fitResults(k).pFit = pFit;
|
||||
fitResults(k).kFit = kVals;
|
||||
fitResults(k).xFit = x;
|
||||
fitResults(k).kFine = kFine;
|
||||
fitResults(k).yFit = yFit;
|
||||
fitResults(k).isValid = true;
|
||||
fitResults(k).fitMaxKRho = fitMaxKRho;
|
||||
|
||||
if ~isnan(pFit)
|
||||
fitResults(k).pFit = pFit;
|
||||
fitResults(k).kFit = kVals;
|
||||
fitResults(k).xFit = x;
|
||||
fitResults(k).kFine = kFine;
|
||||
fitResults(k).yFit = yFit;
|
||||
fitResults(k).isValid = true;
|
||||
fitResults(k).fitMaxKRho = fitMaxKRho;
|
||||
end
|
||||
|
||||
catch
|
||||
warning('Curve %d fit failed completely.', k);
|
||||
|
228
Data-Analyzer/+Analyzer/runInteractiveASDTwoGaussianFitGUI.m
Normal file
228
Data-Analyzer/+Analyzer/runInteractiveASDTwoGaussianFitGUI.m
Normal file
@ -0,0 +1,228 @@
|
||||
function runInteractiveASDTwoGaussianFitGUI(spectral_analysis_results)
|
||||
%% runInteractiveASDTwoGaussianFitGUI
|
||||
% Author: Karthik
|
||||
% Date: 2025-10-16
|
||||
% Version: 1.0
|
||||
%
|
||||
% Description:
|
||||
% Interactive viewer for raw angular spectral distributions.
|
||||
% Lets user browse through individual curves and refit two-Gaussian models
|
||||
% live as threshold parameters are adjusted.
|
||||
%
|
||||
% Controls:
|
||||
% - Slider or ←/→ keys to browse curves
|
||||
% - Editable boxes for thresholds (Residual, Position, Amplitude, MaxTheta)
|
||||
% - "Re-fit" button triggers recomputation
|
||||
%
|
||||
% Dependencies:
|
||||
% Requires Analyzer.fitTwoGaussianCurvesToAngularSpectralDistribution.m
|
||||
|
||||
%% --- Initialization ---
|
||||
rawCurves.x = spectral_analysis_results.S_theta_norm_all;
|
||||
rawCurves.theta = spectral_analysis_results.theta_vals;
|
||||
|
||||
% Handle input organization
|
||||
if iscell(rawCurves.x)
|
||||
Ncurves = numel(rawCurves.x);
|
||||
else
|
||||
Ncurves = size(rawCurves.x, 1);
|
||||
tmp = arrayfun(@(i) struct('x', rawCurves.x(i, :), 'theta', rawCurves.theta(:)'), 1:Ncurves);
|
||||
rawCurves = tmp(:);
|
||||
end
|
||||
|
||||
% Default fit parameters
|
||||
params.MaxTheta = pi/2;
|
||||
params.ResidualThreshold = 0.15;
|
||||
params.PositionThreshold = pi/15;
|
||||
params.AmplitudeThreshold = 0.15;
|
||||
|
||||
currentIdx = 1;
|
||||
|
||||
%% --- Create figure ---
|
||||
hFig = findobj('Type','figure','Tag','InteractiveTwoGaussianFit');
|
||||
if isempty(hFig)
|
||||
hFig = figure('Name','Angular Spectra Fit Viewer',...
|
||||
'NumberTitle','off',...
|
||||
'Position',[100 100 1250 800],...
|
||||
'Color','w',...
|
||||
'KeyPressFcn',@keyPressCallback,...
|
||||
'Tag','InteractiveTwoGaussianFit');
|
||||
else
|
||||
figure(hFig); clf(hFig);
|
||||
end
|
||||
|
||||
%% --- Axes for plot ---
|
||||
hAx = axes('Parent',hFig,'Position',[0.08 0.1 0.55 0.8]);
|
||||
grid(hAx,'on'); box(hAx,'on');
|
||||
xlabel(hAx,'\theta (rad)','FontSize',12);
|
||||
ylabel(hAx,'Normalized amplitude','FontSize',12);
|
||||
|
||||
%% --- Slider for curve index ---
|
||||
hSlider = uicontrol('Style','slider','Min',1,'Max',Ncurves,'Value',1,...
|
||||
'SliderStep',[1/(Ncurves-1), 10/(Ncurves-1)],...
|
||||
'Units','normalized','Position',[0.1 0.02 0.5 0.03],...
|
||||
'Callback',@(~,~) updatePlot());
|
||||
|
||||
%% --- Parameter definitions ---
|
||||
paramNames = {'MaxTheta','ResidualThreshold','PositionThreshold','AmplitudeThreshold'};
|
||||
paramLabels = {'Max Theta (rad)', 'Residual Threshold', 'Position Threshold (rad)', 'Amplitude Threshold'};
|
||||
paramDescs = {'Upper limit for fitting range',...
|
||||
'Maximum mean residual for valid fits',...
|
||||
'Minimum peak separation required',...
|
||||
'Minimum amplitude ratio threshold'};
|
||||
|
||||
nParams = numel(paramNames);
|
||||
hEdit = gobjects(nParams,1);
|
||||
baseY = 0.88;
|
||||
|
||||
%% --- Create parameter controls ---
|
||||
for i = 1:nParams
|
||||
yPos = baseY - 0.12*(i-1);
|
||||
|
||||
% Label
|
||||
uicontrol('Style','text','Units','normalized',...
|
||||
'Position',[0.68 yPos 0.25 0.04],...
|
||||
'String',paramLabels{i},...
|
||||
'HorizontalAlignment','left',...
|
||||
'FontSize',10,'FontWeight','bold',...
|
||||
'BackgroundColor','w');
|
||||
|
||||
% Edit box
|
||||
hEdit(i) = uicontrol('Style','edit','Units','normalized',...
|
||||
'Position',[0.9 yPos 0.07 0.045],...
|
||||
'String',num2str(params.(paramNames{i}), '%.4f'),...
|
||||
'Callback',@(src,~) applyParams());
|
||||
|
||||
% Description
|
||||
uicontrol('Style','text','Units','normalized',...
|
||||
'Position',[0.68 yPos - 0.04 0.35 0.03],...
|
||||
'String',paramDescs{i},...
|
||||
'HorizontalAlignment','left',...
|
||||
'FontSize',8,'ForegroundColor',[0.4 0.4 0.4],...
|
||||
'BackgroundColor','w');
|
||||
end
|
||||
|
||||
%% --- Apply button ---
|
||||
uicontrol('Style','pushbutton','Units','normalized',...
|
||||
'Position',[0.70 0.35 0.25 0.06],...
|
||||
'String','Re-fit All Curves',...
|
||||
'FontSize',14,'FontWeight','bold',...
|
||||
'BackgroundColor',[0.2 0.6 1],...
|
||||
'ForegroundColor','w',...
|
||||
'Callback',@(~,~) refitAll());
|
||||
|
||||
%% --- Fit info text boxes ---
|
||||
infoLabels = {'Fit validity:', 'Peak positions (rad):', 'Amplitudes:'};
|
||||
hInfoText = gobjects(numel(infoLabels),1);
|
||||
for i = 1:numel(infoLabels)
|
||||
yText = 0.22 - 0.07*(i-1);
|
||||
uicontrol('Style','text','Units','normalized',...
|
||||
'Position',[0.68 yText 0.25 0.05],...
|
||||
'String',infoLabels{i},...
|
||||
'FontSize',10,'FontWeight','bold',...
|
||||
'HorizontalAlignment','left',...
|
||||
'BackgroundColor','w');
|
||||
hInfoText(i) = uicontrol('Style','text','Units','normalized',...
|
||||
'Position',[0.88 yText 0.1 0.05],...
|
||||
'String','-','FontSize',10,...
|
||||
'HorizontalAlignment','left',...
|
||||
'BackgroundColor','w');
|
||||
end
|
||||
|
||||
%% --- Compute initial fits ---
|
||||
[fitResults, rawData] = Analyzer.fitTwoGaussianCurvesToAngularSpectralDistribution(...
|
||||
spectral_analysis_results.S_theta_norm_all,...
|
||||
spectral_analysis_results.theta_vals,...
|
||||
'MaxTheta', params.MaxTheta,...
|
||||
'ResidualThreshold', params.ResidualThreshold,...
|
||||
'PositionThreshold', params.PositionThreshold,...
|
||||
'AmplitudeThreshold', params.AmplitudeThreshold);
|
||||
|
||||
%% --- Initial plot ---
|
||||
updatePlot();
|
||||
|
||||
%% --- Nested functions ---
|
||||
|
||||
function applyParams()
|
||||
% Update parameters from GUI fields
|
||||
for j = 1:nParams
|
||||
val = str2double(hEdit(j).String);
|
||||
if ~isnan(val)
|
||||
params.(paramNames{j}) = val;
|
||||
end
|
||||
end
|
||||
refitAll();
|
||||
end
|
||||
|
||||
function refitAll()
|
||||
% Recompute all fits
|
||||
drawnow;
|
||||
[fitResults, rawData] = Analyzer.fitTwoGaussianCurvesToAngularSpectralDistribution(...
|
||||
spectral_analysis_results.S_theta_norm_all,...
|
||||
spectral_analysis_results.theta_vals,...
|
||||
'MaxTheta', params.MaxTheta,...
|
||||
'ResidualThreshold', params.ResidualThreshold,...
|
||||
'PositionThreshold', params.PositionThreshold,...
|
||||
'AmplitudeThreshold', params.AmplitudeThreshold);
|
||||
updatePlot();
|
||||
end
|
||||
|
||||
function updatePlot()
|
||||
idx = round(get(hSlider,'Value'));
|
||||
currentIdx = idx;
|
||||
|
||||
cla(hAx);
|
||||
hold(hAx,'on');
|
||||
raw = rawData(idx);
|
||||
plot(hAx, raw.theta, raw.x, 'k.-', 'LineWidth', 1, 'DisplayName', 'Raw Data');
|
||||
|
||||
if idx <= numel(fitResults)
|
||||
fit = fitResults(idx);
|
||||
if isfield(fit,'isValid') && ~isempty(fit.isValid) && fit.isValid
|
||||
plot(hAx, fit.thetaFine, fit.yFit, 'r-', 'LineWidth', 1.5, 'DisplayName', 'Two-Gaussian Fit');
|
||||
|
||||
% Extract parameters from pFit vector if available
|
||||
if isfield(fit,'pFit') && numel(fit.pFit) >= 6
|
||||
A1 = fit.pFit(1); mu1 = fit.pFit(2);
|
||||
A2 = fit.pFit(4); mu2 = fit.pFit(5);
|
||||
hInfoText(1).String = 'Valid';
|
||||
hInfoText(1).ForegroundColor = [0 0.5 0];
|
||||
hInfoText(2).String = sprintf('[%.3f, %.3f]', mu1, mu2);
|
||||
hInfoText(3).String = sprintf('[%.2f, %.2f]', A1, A2);
|
||||
else
|
||||
hInfoText(1).String = 'Valid';
|
||||
hInfoText(1).ForegroundColor = [0 0.5 0];
|
||||
hInfoText(2).String = '-';
|
||||
hInfoText(3).String = '-';
|
||||
end
|
||||
else
|
||||
hInfoText(1).String = 'Invalid';
|
||||
hInfoText(1).ForegroundColor = [0.7 0 0];
|
||||
hInfoText(2).String = '-';
|
||||
hInfoText(3).String = '-';
|
||||
end
|
||||
end
|
||||
|
||||
title(hAx,sprintf('Curve %d / %d', idx, Ncurves),'FontSize',16);
|
||||
legend(hAx,'Location','northeast','FontSize',14);
|
||||
hold(hAx,'off');
|
||||
drawnow;
|
||||
end
|
||||
|
||||
function keyPressCallback(event)
|
||||
switch event.Key
|
||||
case 'rightarrow'
|
||||
if currentIdx < Ncurves
|
||||
currentIdx = currentIdx + 1;
|
||||
set(hSlider,'Value',currentIdx);
|
||||
updatePlot();
|
||||
end
|
||||
case 'leftarrow'
|
||||
if currentIdx > 1
|
||||
currentIdx = currentIdx - 1;
|
||||
set(hSlider,'Value',currentIdx);
|
||||
updatePlot();
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
219
Data-Analyzer/+Analyzer/runInteractiveRSDTwoGaussianFitGUI.m
Normal file
219
Data-Analyzer/+Analyzer/runInteractiveRSDTwoGaussianFitGUI.m
Normal file
@ -0,0 +1,219 @@
|
||||
function runInteractiveRSDTwoGaussianFitGUI(spectral_analysis_results)
|
||||
%% runInteractiveRSDTwoGaussianFitGUI
|
||||
% Author: Karthik
|
||||
% Date: 2025-10-16
|
||||
% Version: 1.0
|
||||
%
|
||||
% Description:
|
||||
% Interactive viewer for raw radial spectral distributions.
|
||||
% Lets user browse through individual curves and refit two-Gaussian models
|
||||
% live as threshold parameters are adjusted.
|
||||
%
|
||||
% Controls:
|
||||
% - Slider or ←/→ keys to browse curves
|
||||
% - Editable boxes for thresholds (Residual, Position, Amplitude, KRhoRange, AmplitudeRange)
|
||||
% - "Re-fit Current Curve" button triggers recomputation
|
||||
%
|
||||
% Dependencies:
|
||||
% Requires Analyzer.fitTwoGaussianCurvesToRadialSpectralDistribution.m
|
||||
|
||||
%% --- Initialization ---
|
||||
rawCurves.x = spectral_analysis_results.S_k_all;
|
||||
rawCurves.k = spectral_analysis_results.k_rho_vals;
|
||||
|
||||
% Handle input organization
|
||||
if iscell(rawCurves.x)
|
||||
Ncurves = numel(rawCurves.x);
|
||||
else
|
||||
Ncurves = size(rawCurves.x, 1);
|
||||
tmp = arrayfun(@(i) struct('x', rawCurves.x(i,:), 'k', rawCurves.k(:)'), 1:Ncurves);
|
||||
rawCurves = tmp(:);
|
||||
end
|
||||
|
||||
% Default fit parameters
|
||||
params.KRhoRange = [0, 3];
|
||||
params.AmplitudeRange = [0, 0.5];
|
||||
params.ResidualThreshold = 0.15;
|
||||
params.PositionThreshold = 0.5;
|
||||
params.AmplitudeThreshold = 0.015;
|
||||
|
||||
currentIdx = 1;
|
||||
|
||||
%% --- Create figure ---
|
||||
hFig = findobj('Type','figure','Tag','InteractiveTwoGaussianRSD');
|
||||
if isempty(hFig)
|
||||
hFig = figure('Name','Radial Spectra Fit Viewer',...
|
||||
'NumberTitle','off',...
|
||||
'Position',[100 100 1250 800],...
|
||||
'Color','w',...
|
||||
'KeyPressFcn',@keyPressCallback,...
|
||||
'Tag','InteractiveTwoGaussianRSD');
|
||||
else
|
||||
figure(hFig); clf(hFig);
|
||||
end
|
||||
|
||||
%% --- Axes for plot ---
|
||||
hAx = axes('Parent',hFig,'Position',[0.08 0.1 0.55 0.8]);
|
||||
grid(hAx,'on'); box(hAx,'on');
|
||||
xlabel(hAx,'k_\rho','FontSize',12);
|
||||
ylabel(hAx,'Normalized amplitude','FontSize',12);
|
||||
|
||||
%% --- Slider for curve index ---
|
||||
hSlider = uicontrol('Style','slider','Min',1,'Max',Ncurves,'Value',1,...
|
||||
'SliderStep',[1/(Ncurves-1), 10/(Ncurves-1)],...
|
||||
'Units','normalized','Position',[0.1 0.02 0.5 0.03],...
|
||||
'Callback',@(~,~) updatePlot());
|
||||
|
||||
%% --- Parameter definitions ---
|
||||
paramNames = {'KRhoRange','AmplitudeRange','ResidualThreshold','PositionThreshold','AmplitudeThreshold'};
|
||||
paramLabels = {'KRho range [min,max]','Amplitude range [min,max]','Residual Threshold','Position Threshold','Amplitude Threshold'};
|
||||
paramDescs = {'Truncate k_\rho range for fitting',...
|
||||
'Truncate amplitudes below/above values',...
|
||||
'Maximum mean residual for valid fits',...
|
||||
'Minimum separation between peaks',...
|
||||
'Minimum amplitude ratio threshold'};
|
||||
|
||||
nParams = numel(paramNames);
|
||||
hEdit = gobjects(nParams,1);
|
||||
baseY = 0.88;
|
||||
|
||||
%% --- Create parameter controls ---
|
||||
for i = 1:nParams
|
||||
yPos = baseY - 0.12*(i-1);
|
||||
|
||||
% Label
|
||||
uicontrol('Style','text','Units','normalized',...
|
||||
'Position',[0.68 yPos 0.25 0.04],...
|
||||
'String',paramLabels{i},...
|
||||
'HorizontalAlignment','left',...
|
||||
'FontSize',10,'FontWeight','bold',...
|
||||
'BackgroundColor','w');
|
||||
|
||||
% Edit box
|
||||
hEdit(i) = uicontrol('Style','edit','Units','normalized',...
|
||||
'Position',[0.9 yPos 0.07 0.045],...
|
||||
'String',num2str(params.(paramNames{i}), '%.4f'),...
|
||||
'Callback',@(src,~) applyParams());
|
||||
|
||||
% Description
|
||||
uicontrol('Style','text','Units','normalized',...
|
||||
'Position',[0.68 yPos - 0.04 0.35 0.03],...
|
||||
'String',paramDescs{i},...
|
||||
'HorizontalAlignment','left','FontSize',8,'ForegroundColor',[0.4 0.4 0.4],...
|
||||
'BackgroundColor','w');
|
||||
end
|
||||
|
||||
%% --- Re-fit button ---
|
||||
uicontrol('Style','pushbutton','Units','normalized',...
|
||||
'Position',[0.700 0.295 0.25 0.06],...
|
||||
'String','Re-fit All Curves',...
|
||||
'FontSize',14,'FontWeight','bold',...
|
||||
'BackgroundColor',[0.2 0.6 1],...
|
||||
'ForegroundColor','w',...
|
||||
'Callback',@(~,~) refitAll());
|
||||
|
||||
%% --- Fit info text boxes ---
|
||||
infoLabels = {'Fit validity:','Peak positions:','Amplitudes:'};
|
||||
hInfoText = gobjects(numel(infoLabels),1);
|
||||
for i = 1:numel(infoLabels)
|
||||
yText = 0.22 - 0.07*(i-1);
|
||||
uicontrol('Style','text','Units','normalized',...
|
||||
'Position',[0.68 yText 0.25 0.05],...
|
||||
'String',infoLabels{i},...
|
||||
'FontSize',10,'FontWeight','bold',...
|
||||
'HorizontalAlignment','left',...
|
||||
'BackgroundColor','w');
|
||||
hInfoText(i) = uicontrol('Style','text','Units','normalized',...
|
||||
'Position',[0.88 yText 0.1 0.05],...
|
||||
'String','-','FontSize',10,...
|
||||
'HorizontalAlignment','left',...
|
||||
'BackgroundColor','w');
|
||||
end
|
||||
|
||||
%% --- Compute initial fits ---
|
||||
[fitResults, rawData] = Analyzer.fitTwoGaussianCurvesToRadialSpectralDistribution(...
|
||||
spectral_analysis_results.S_k_all,...
|
||||
spectral_analysis_results.k_rho_vals,...
|
||||
'KRhoRange', params.KRhoRange,...
|
||||
'AmplitudeRange', params.AmplitudeRange,...
|
||||
'ResidualThreshold', params.ResidualThreshold,...
|
||||
'PositionThreshold', params.PositionThreshold,...
|
||||
'AmplitudeThreshold', params.AmplitudeThreshold);
|
||||
|
||||
%% --- Initial plot ---
|
||||
updatePlot();
|
||||
|
||||
%% --- Nested functions ---
|
||||
|
||||
function applyParams()
|
||||
% Update parameters from GUI fields
|
||||
for j = 1:nParams
|
||||
val = str2double(hEdit(j).String);
|
||||
if ~isnan(val)
|
||||
params.(paramNames{j}) = val;
|
||||
end
|
||||
end
|
||||
refitAll();
|
||||
end
|
||||
|
||||
function refitAll()
|
||||
% Recompute all fits for the entire radial dataset
|
||||
drawnow;
|
||||
[fitResults, rawData] = Analyzer.fitTwoGaussianCurvesToRadialSpectralDistribution(...
|
||||
spectral_analysis_results.S_k_all, ...
|
||||
spectral_analysis_results.k_rho_vals, ...
|
||||
'KRhoRange', params.KRhoRange, ...
|
||||
'AmplitudeRange', params.AmplitudeRange, ...
|
||||
'ResidualThreshold', params.ResidualThreshold, ...
|
||||
'PositionThreshold', params.PositionThreshold, ...
|
||||
'AmplitudeThreshold', params.AmplitudeThreshold);
|
||||
updatePlot();
|
||||
end
|
||||
|
||||
function updatePlot()
|
||||
% Display raw curve and two-Gaussian fit
|
||||
idx = round(get(hSlider,'Value'));
|
||||
currentIdx = idx;
|
||||
|
||||
cla(hAx); hold(hAx,'on');
|
||||
|
||||
raw = rawData(idx);
|
||||
plot(hAx, raw.k, raw.x, 'k.-','LineWidth',1,'DisplayName','Raw Data');
|
||||
|
||||
fit = fitResults(idx);
|
||||
if isfield(fit,'isValid') && ~isempty(fit.isValid) && fit.isValid && ...
|
||||
isfield(fit,'kFine') && isfield(fit,'yFit') && ~isempty(fit.kFine)
|
||||
plot(hAx, fit.kFine, fit.yFit, 'r-','LineWidth',1.5,'DisplayName','Two-Gaussian Fit');
|
||||
|
||||
if isfield(fit,'pFit') && numel(fit.pFit)>=6
|
||||
A1=fit.pFit(1); mu1=fit.pFit(2);
|
||||
A2=fit.pFit(4); mu2=fit.pFit(5);
|
||||
hInfoText(1).String='Valid'; hInfoText(1).ForegroundColor=[0 0.5 0];
|
||||
hInfoText(2).String=sprintf('[%.3f, %.3f]',mu1,mu2);
|
||||
hInfoText(3).String=sprintf('[%.3f, %.3f]',A1,A2);
|
||||
else
|
||||
hInfoText(1).String='Valid'; hInfoText(1).ForegroundColor=[0 0.5 0];
|
||||
hInfoText(2).String='-'; hInfoText(3).String='-';
|
||||
end
|
||||
else
|
||||
hInfoText(1).String='Invalid'; hInfoText(1).ForegroundColor=[0.7 0 0];
|
||||
hInfoText(2).String='-'; hInfoText(3).String='-';
|
||||
end
|
||||
|
||||
xlabel(hAx,'k_\rho'); ylabel(hAx,'Normalized amplitude');
|
||||
title(hAx,sprintf('Curve %d / %d',idx,Ncurves),'FontSize',16);
|
||||
legend(hAx,'Location','northeast','FontSize',14);
|
||||
hold(hAx,'off'); drawnow;
|
||||
end
|
||||
|
||||
function keyPressCallback(event)
|
||||
% Navigate curves via arrow keys
|
||||
switch event.Key
|
||||
case 'rightarrow'
|
||||
if currentIdx<Ncurves, currentIdx=currentIdx+1; set(hSlider,'Value',currentIdx); updatePlot(); end
|
||||
case 'leftarrow'
|
||||
if currentIdx>1, currentIdx=currentIdx-1; set(hSlider,'Value',currentIdx); updatePlot(); end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
@ -167,71 +167,8 @@ Plotter.plotSpectralDistributionCumulants(results, ...
|
||||
'PositionThreshold', pi/15, ...
|
||||
'AmplitudeThreshold', 0.15);
|
||||
|
||||
%{
|
||||
% --- Function call ---
|
||||
plotTwoGaussianFitsOnRaw(fitResults, rawCurves, 8, 12); % 8×12 subplots per page
|
||||
|
||||
% --- Function definition ---
|
||||
function plotTwoGaussianFitsOnRaw(fitResults, rawCurves, nRows, nCols)
|
||||
% plotTwoGaussianFitsOnRaw - Plots raw curves and overlays valid two-Gaussian fits.
|
||||
%
|
||||
% Inputs:
|
||||
% fitResults - struct array from fitTwoGaussianCurvesToAngularSpectralDistribution (may contain fits)
|
||||
% rawCurves - struct array with fields:
|
||||
% .x - raw curve
|
||||
% .theta - corresponding theta values
|
||||
% nRows - number of subplot rows per page (default: 4)
|
||||
% nCols - number of subplot columns per page (default: 6)
|
||||
|
||||
if nargin < 3, nRows = 4; end
|
||||
if nargin < 4, nCols = 6; end
|
||||
|
||||
Ncurves = numel(rawCurves);
|
||||
plotsPerPage = nRows * nCols;
|
||||
pageNum = 1;
|
||||
|
||||
for k = 1:Ncurves
|
||||
% --- New figure/page if needed ---
|
||||
if mod(k-1, plotsPerPage) == 0
|
||||
figure('Name', sprintf('Curves Page %d', pageNum), ...
|
||||
'NumberTitle', 'off', 'Color', 'w');
|
||||
pageNum = pageNum + 1;
|
||||
end
|
||||
|
||||
% --- Select subplot ---
|
||||
subplot(nRows, nCols, mod(k-1, plotsPerPage)+1);
|
||||
hold on; grid on; box on;
|
||||
|
||||
% --- Plot raw curve ---
|
||||
xRaw = rawCurves(k).x;
|
||||
thetaRaw = rawCurves(k).theta;
|
||||
if ~isempty(xRaw) && ~isempty(thetaRaw) && all(isfinite(xRaw))
|
||||
plot(thetaRaw, xRaw, 'k.-', 'LineWidth', 1, 'DisplayName', 'Raw data');
|
||||
end
|
||||
|
||||
% --- Overlay fit if valid ---
|
||||
if k <= numel(fitResults)
|
||||
fit = fitResults(k);
|
||||
if isfield(fit, 'isValid') && fit.isValid ...
|
||||
&& ~isempty(fit.yFit) && ~isempty(fit.thetaFine)
|
||||
plot(fit.thetaFine, fit.yFit, 'r-', 'LineWidth', 1.2, 'DisplayName', 'Two-Gaussian fit');
|
||||
end
|
||||
end
|
||||
|
||||
% --- Formatting ---
|
||||
xlabel('\theta (rad)');
|
||||
ylabel('Normalized amplitude');
|
||||
title(sprintf('Curve %d', k), 'FontSize', 10);
|
||||
|
||||
% --- Legend once per page ---
|
||||
if mod(k-1, plotsPerPage) == 0
|
||||
legend('Location', 'best', 'FontSize', 8);
|
||||
end
|
||||
|
||||
hold off;
|
||||
end
|
||||
end
|
||||
%}
|
||||
%% ------------------ Interactive Fit Viewer ------------------
|
||||
Analyzer.runInteractiveASDTwoGaussianFitGUI(spectral_analysis_results);
|
||||
|
||||
%% ------------------ 5. Plot fit parameters - amplitude ------------------
|
||||
Plotter.plotFitParameterPDF(fitResults, scan_reference_values, 'A2', ...
|
||||
|
@ -121,76 +121,10 @@ Plotter.plotSpectralCurves( ...
|
||||
'ResidualThreshold', 0.15, ... % maximum allowed residual
|
||||
'PositionThreshold', 0.5, ... % minimum separation between peaks
|
||||
'AmplitudeThreshold', 0.015); % minimum secondary peak fraction
|
||||
%%
|
||||
%{
|
||||
% --- Function call ---
|
||||
plotTwoGaussianFitsOnRaw(fitResults, rawCurves, 8, 12); % 8×12 subplots per page
|
||||
|
||||
% --- Function definition ---
|
||||
function plotTwoGaussianFitsOnRaw(fitResults, rawCurves, nRows, nCols)
|
||||
%% plotTwoGaussianFitsOnRaw
|
||||
% Plots raw radial spectral curves with their two-Gaussian fits.
|
||||
%
|
||||
% Inputs:
|
||||
% fitResults - struct array from fitTwoGaussianCurvesToRadialSpectralDistribution
|
||||
% rawCurves - struct array with fields:
|
||||
% .x - raw normalized amplitudes
|
||||
% .k - corresponding k_rho values
|
||||
% nRows - number of subplot rows per page (default: 8)
|
||||
% nCols - number of subplot columns per page (default: 12)
|
||||
%% ------------------ Interactive Fit Viewer ------------------
|
||||
Analyzer.runInteractiveRSDTwoGaussianFitGUI(spectral_analysis_results);
|
||||
|
||||
if nargin < 3, nRows = 8; end
|
||||
if nargin < 4, nCols = 12; end
|
||||
|
||||
Ncurves = numel(rawCurves);
|
||||
plotsPerPage = nRows * nCols;
|
||||
pageNum = 1;
|
||||
|
||||
for k = 1:Ncurves
|
||||
% --- Create new figure page if needed ---
|
||||
if mod(k-1, plotsPerPage) == 0
|
||||
figure('Name', sprintf('Radial Spectra Page %d', pageNum), ...
|
||||
'NumberTitle', 'off', 'Color', 'w', ...
|
||||
'Position', [50 50 1600 900]);
|
||||
pageNum = pageNum + 1;
|
||||
end
|
||||
|
||||
% --- Subplot selection ---
|
||||
subplot(nRows, nCols, mod(k-1, plotsPerPage) + 1);
|
||||
hold on; grid on; box on;
|
||||
|
||||
% --- Plot raw curve ---
|
||||
if isfield(rawCurves, 'x') && isfield(rawCurves, 'k') && ...
|
||||
~isempty(rawCurves(k).x) && all(isfinite(rawCurves(k).x))
|
||||
plot(rawCurves(k).k, rawCurves(k).x, 'k.-', ...
|
||||
'LineWidth', 1, 'DisplayName', 'Raw data');
|
||||
end
|
||||
|
||||
% --- Overlay fit if valid ---
|
||||
if k <= numel(fitResults)
|
||||
fit = fitResults(k);
|
||||
if isfield(fit, 'isValid') && fit.isValid && ...
|
||||
isfield(fit, 'kFine') && isfield(fit, 'yFit') && ...
|
||||
~isempty(fit.kFine) && all(isfinite(fit.yFit))
|
||||
plot(fit.kFine, fit.yFit, 'r-', ...
|
||||
'LineWidth', 1.2, 'DisplayName', 'Two-Gaussian fit');
|
||||
end
|
||||
end
|
||||
|
||||
% --- Labels and title ---
|
||||
xlabel('k_\rho', 'FontSize', 10);
|
||||
ylabel('Normalized amplitude', 'FontSize', 10);
|
||||
title(sprintf('Curve %d', k), 'FontSize', 9, 'Interpreter', 'none');
|
||||
|
||||
% --- Legend on first subplot of each page ---
|
||||
if mod(k-1, plotsPerPage) == 0
|
||||
legend('Location', 'best', 'FontSize', 8);
|
||||
end
|
||||
|
||||
hold off;
|
||||
end
|
||||
end
|
||||
%}
|
||||
%% ------------------ 3. Plot fit parameters - amplitude ------------------
|
||||
Plotter.plotFitParameterPDF(fitResults, scan_reference_values, 'A2', ...
|
||||
'Title', options.titleString, ...
|
||||
|
@ -154,7 +154,7 @@ Plotter.plotSpectralDistributionCumulants(results, ...
|
||||
'FontName', options.font, ...
|
||||
'FontSize', 14, ...
|
||||
'FigNum', 3, ...
|
||||
'SkipSaveFigures', false, ...
|
||||
'SkipSaveFigures', options.skipSaveFigures, ...
|
||||
'SaveFileName', 'SpectralCumulants.fig', ...
|
||||
'SaveDirectory', options.saveDirectory);
|
||||
|
||||
@ -167,71 +167,8 @@ Plotter.plotSpectralDistributionCumulants(results, ...
|
||||
'PositionThreshold', pi/15, ...
|
||||
'AmplitudeThreshold', 0.15);
|
||||
|
||||
%{
|
||||
% --- Function call ---
|
||||
plotTwoGaussianFitsOnRaw(fitResults, rawCurves, 8, 12); % 8×12 subplots per page
|
||||
|
||||
% --- Function definition ---
|
||||
function plotTwoGaussianFitsOnRaw(fitResults, rawCurves, nRows, nCols)
|
||||
% plotTwoGaussianFitsOnRaw - Plots raw curves and overlays valid two-Gaussian fits.
|
||||
%
|
||||
% Inputs:
|
||||
% fitResults - struct array from fitTwoGaussianCurvesToAngularSpectralDistribution (may contain fits)
|
||||
% rawCurves - struct array with fields:
|
||||
% .x - raw curve
|
||||
% .theta - corresponding theta values
|
||||
% nRows - number of subplot rows per page (default: 4)
|
||||
% nCols - number of subplot columns per page (default: 6)
|
||||
|
||||
if nargin < 3, nRows = 4; end
|
||||
if nargin < 4, nCols = 6; end
|
||||
|
||||
Ncurves = numel(rawCurves);
|
||||
plotsPerPage = nRows * nCols;
|
||||
pageNum = 1;
|
||||
|
||||
for k = 1:Ncurves
|
||||
% --- New figure/page if needed ---
|
||||
if mod(k-1, plotsPerPage) == 0
|
||||
figure('Name', sprintf('Curves Page %d', pageNum), ...
|
||||
'NumberTitle', 'off', 'Color', 'w');
|
||||
pageNum = pageNum + 1;
|
||||
end
|
||||
|
||||
% --- Select subplot ---
|
||||
subplot(nRows, nCols, mod(k-1, plotsPerPage)+1);
|
||||
hold on; grid on; box on;
|
||||
|
||||
% --- Plot raw curve ---
|
||||
xRaw = rawCurves(k).x;
|
||||
thetaRaw = rawCurves(k).theta;
|
||||
if ~isempty(xRaw) && ~isempty(thetaRaw) && all(isfinite(xRaw))
|
||||
plot(thetaRaw, xRaw, 'k.-', 'LineWidth', 1, 'DisplayName', 'Raw data');
|
||||
end
|
||||
|
||||
% --- Overlay fit if valid ---
|
||||
if k <= numel(fitResults)
|
||||
fit = fitResults(k);
|
||||
if isfield(fit, 'isValid') && fit.isValid ...
|
||||
&& ~isempty(fit.yFit) && ~isempty(fit.thetaFine)
|
||||
plot(fit.thetaFine, fit.yFit, 'r-', 'LineWidth', 1.2, 'DisplayName', 'Two-Gaussian fit');
|
||||
end
|
||||
end
|
||||
|
||||
% --- Formatting ---
|
||||
xlabel('\theta (rad)');
|
||||
ylabel('Normalized amplitude');
|
||||
title(sprintf('Curve %d', k), 'FontSize', 10);
|
||||
|
||||
% --- Legend once per page ---
|
||||
if mod(k-1, plotsPerPage) == 0
|
||||
legend('Location', 'best', 'FontSize', 8);
|
||||
end
|
||||
|
||||
hold off;
|
||||
end
|
||||
end
|
||||
%}
|
||||
%% ------------------ Interactive Fit Viewer ------------------
|
||||
Analyzer.runInteractiveASDTwoGaussianFitGUI(spectral_analysis_results);
|
||||
|
||||
%% ------------------ 5. Plot fit parameters - amplitude ------------------
|
||||
Plotter.plotFitParameterPDF(fitResults, scan_reference_values, 'A2', ...
|
||||
|
@ -121,76 +121,10 @@ Plotter.plotSpectralCurves( ...
|
||||
'ResidualThreshold', 0.15, ... % maximum allowed residual
|
||||
'PositionThreshold', 0.5, ... % minimum separation between peaks
|
||||
'AmplitudeThreshold', 0.015); % minimum secondary peak fraction
|
||||
%%
|
||||
%{
|
||||
% --- Function call ---
|
||||
plotTwoGaussianFitsOnRaw(fitResults, rawCurves, 8, 12); % 8×12 subplots per page
|
||||
|
||||
% --- Function definition ---
|
||||
function plotTwoGaussianFitsOnRaw(fitResults, rawCurves, nRows, nCols)
|
||||
%% plotTwoGaussianFitsOnRaw
|
||||
% Plots raw radial spectral curves with their two-Gaussian fits.
|
||||
%
|
||||
% Inputs:
|
||||
% fitResults - struct array from fitTwoGaussianCurvesToRadialSpectralDistribution
|
||||
% rawCurves - struct array with fields:
|
||||
% .x - raw normalized amplitudes
|
||||
% .k - corresponding k_rho values
|
||||
% nRows - number of subplot rows per page (default: 8)
|
||||
% nCols - number of subplot columns per page (default: 12)
|
||||
%% ------------------ Interactive Fit Viewer ------------------
|
||||
Analyzer.runInteractiveRSDTwoGaussianFitGUI(spectral_analysis_results);
|
||||
|
||||
if nargin < 3, nRows = 8; end
|
||||
if nargin < 4, nCols = 12; end
|
||||
|
||||
Ncurves = numel(rawCurves);
|
||||
plotsPerPage = nRows * nCols;
|
||||
pageNum = 1;
|
||||
|
||||
for k = 1:Ncurves
|
||||
% --- Create new figure page if needed ---
|
||||
if mod(k-1, plotsPerPage) == 0
|
||||
figure('Name', sprintf('Radial Spectra Page %d', pageNum), ...
|
||||
'NumberTitle', 'off', 'Color', 'w', ...
|
||||
'Position', [50 50 1600 900]);
|
||||
pageNum = pageNum + 1;
|
||||
end
|
||||
|
||||
% --- Subplot selection ---
|
||||
subplot(nRows, nCols, mod(k-1, plotsPerPage) + 1);
|
||||
hold on; grid on; box on;
|
||||
|
||||
% --- Plot raw curve ---
|
||||
if isfield(rawCurves, 'x') && isfield(rawCurves, 'k') && ...
|
||||
~isempty(rawCurves(k).x) && all(isfinite(rawCurves(k).x))
|
||||
plot(rawCurves(k).k, rawCurves(k).x, 'k.-', ...
|
||||
'LineWidth', 1, 'DisplayName', 'Raw data');
|
||||
end
|
||||
|
||||
% --- Overlay fit if valid ---
|
||||
if k <= numel(fitResults)
|
||||
fit = fitResults(k);
|
||||
if isfield(fit, 'isValid') && fit.isValid && ...
|
||||
isfield(fit, 'kFine') && isfield(fit, 'yFit') && ...
|
||||
~isempty(fit.kFine) && all(isfinite(fit.yFit))
|
||||
plot(fit.kFine, fit.yFit, 'r-', ...
|
||||
'LineWidth', 1.2, 'DisplayName', 'Two-Gaussian fit');
|
||||
end
|
||||
end
|
||||
|
||||
% --- Labels and title ---
|
||||
xlabel('k_\rho', 'FontSize', 10);
|
||||
ylabel('Normalized amplitude', 'FontSize', 10);
|
||||
title(sprintf('Curve %d', k), 'FontSize', 9, 'Interpreter', 'none');
|
||||
|
||||
% --- Legend on first subplot of each page ---
|
||||
if mod(k-1, plotsPerPage) == 0
|
||||
legend('Location', 'best', 'FontSize', 8);
|
||||
end
|
||||
|
||||
hold off;
|
||||
end
|
||||
end
|
||||
%}
|
||||
%% ------------------ 3. Plot fit parameters - amplitude ------------------
|
||||
Plotter.plotFitParameterPDF(fitResults, scan_reference_values, 'A2', ...
|
||||
'Title', options.titleString, ...
|
||||
@ -207,7 +141,7 @@ Plotter.plotFitParameterPDF(fitResults, scan_reference_values, 'A2', ...
|
||||
'NormalizeHistogram', true, ...
|
||||
'Colormap', @Colormaps.coolwarm, ...
|
||||
'XLim', [min(scan_reference_values), max(scan_reference_values)], ...
|
||||
'YLim', [0, 0.06]);
|
||||
'YLim', [0, 0.025]);
|
||||
|
||||
%% ------------------ 4. Plot fit parameters - position ------------------
|
||||
Plotter.plotFitParameterPDF(fitResults, scan_reference_values, 'mu2', ...
|
||||
|
@ -167,71 +167,8 @@ Plotter.plotSpectralDistributionCumulants(results, ...
|
||||
'PositionThreshold', pi/15, ...
|
||||
'AmplitudeThreshold', 0.15);
|
||||
|
||||
%{
|
||||
% --- Function call ---
|
||||
plotTwoGaussianFitsOnRaw(fitResults, rawCurves, 8, 12); % 8×12 subplots per page
|
||||
|
||||
% --- Function definition ---
|
||||
function plotTwoGaussianFitsOnRaw(fitResults, rawCurves, nRows, nCols)
|
||||
% plotTwoGaussianFitsOnRaw - Plots raw curves and overlays valid two-Gaussian fits.
|
||||
%
|
||||
% Inputs:
|
||||
% fitResults - struct array from fitTwoGaussianCurvesToAngularSpectralDistribution (may contain fits)
|
||||
% rawCurves - struct array with fields:
|
||||
% .x - raw curve
|
||||
% .theta - corresponding theta values
|
||||
% nRows - number of subplot rows per page (default: 4)
|
||||
% nCols - number of subplot columns per page (default: 6)
|
||||
|
||||
if nargin < 3, nRows = 4; end
|
||||
if nargin < 4, nCols = 6; end
|
||||
|
||||
Ncurves = numel(rawCurves);
|
||||
plotsPerPage = nRows * nCols;
|
||||
pageNum = 1;
|
||||
|
||||
for k = 1:Ncurves
|
||||
% --- New figure/page if needed ---
|
||||
if mod(k-1, plotsPerPage) == 0
|
||||
figure('Name', sprintf('Curves Page %d', pageNum), ...
|
||||
'NumberTitle', 'off', 'Color', 'w');
|
||||
pageNum = pageNum + 1;
|
||||
end
|
||||
|
||||
% --- Select subplot ---
|
||||
subplot(nRows, nCols, mod(k-1, plotsPerPage)+1);
|
||||
hold on; grid on; box on;
|
||||
|
||||
% --- Plot raw curve ---
|
||||
xRaw = rawCurves(k).x;
|
||||
thetaRaw = rawCurves(k).theta;
|
||||
if ~isempty(xRaw) && ~isempty(thetaRaw) && all(isfinite(xRaw))
|
||||
plot(thetaRaw, xRaw, 'k.-', 'LineWidth', 1, 'DisplayName', 'Raw data');
|
||||
end
|
||||
|
||||
% --- Overlay fit if valid ---
|
||||
if k <= numel(fitResults)
|
||||
fit = fitResults(k);
|
||||
if isfield(fit, 'isValid') && fit.isValid ...
|
||||
&& ~isempty(fit.yFit) && ~isempty(fit.thetaFine)
|
||||
plot(fit.thetaFine, fit.yFit, 'r-', 'LineWidth', 1.2, 'DisplayName', 'Two-Gaussian fit');
|
||||
end
|
||||
end
|
||||
|
||||
% --- Formatting ---
|
||||
xlabel('\theta (rad)');
|
||||
ylabel('Normalized amplitude');
|
||||
title(sprintf('Curve %d', k), 'FontSize', 10);
|
||||
|
||||
% --- Legend once per page ---
|
||||
if mod(k-1, plotsPerPage) == 0
|
||||
legend('Location', 'best', 'FontSize', 8);
|
||||
end
|
||||
|
||||
hold off;
|
||||
end
|
||||
end
|
||||
%}
|
||||
%% ------------------ Interactive Fit Viewer ------------------
|
||||
Analyzer.runInteractiveASDTwoGaussianFitGUI(spectral_analysis_results);
|
||||
|
||||
%% ------------------ 5. Plot fit parameters - amplitude ------------------
|
||||
Plotter.plotFitParameterPDF(fitResults, scan_reference_values, 'A2', ...
|
||||
|
@ -121,76 +121,10 @@ Plotter.plotSpectralCurves( ...
|
||||
'ResidualThreshold', 0.15, ... % maximum allowed residual
|
||||
'PositionThreshold', 0.5, ... % minimum separation between peaks
|
||||
'AmplitudeThreshold', 0.015); % minimum secondary peak fraction
|
||||
%%
|
||||
%{
|
||||
% --- Function call ---
|
||||
plotTwoGaussianFitsOnRaw(fitResults, rawCurves, 8, 12); % 8×12 subplots per page
|
||||
|
||||
% --- Function definition ---
|
||||
function plotTwoGaussianFitsOnRaw(fitResults, rawCurves, nRows, nCols)
|
||||
%% plotTwoGaussianFitsOnRaw
|
||||
% Plots raw radial spectral curves with their two-Gaussian fits.
|
||||
%
|
||||
% Inputs:
|
||||
% fitResults - struct array from fitTwoGaussianCurvesToRadialSpectralDistribution
|
||||
% rawCurves - struct array with fields:
|
||||
% .x - raw normalized amplitudes
|
||||
% .k - corresponding k_rho values
|
||||
% nRows - number of subplot rows per page (default: 8)
|
||||
% nCols - number of subplot columns per page (default: 12)
|
||||
%% ------------------ Interactive Fit Viewer ------------------
|
||||
Analyzer.runInteractiveRSDTwoGaussianFitGUI(spectral_analysis_results);
|
||||
|
||||
if nargin < 3, nRows = 8; end
|
||||
if nargin < 4, nCols = 12; end
|
||||
|
||||
Ncurves = numel(rawCurves);
|
||||
plotsPerPage = nRows * nCols;
|
||||
pageNum = 1;
|
||||
|
||||
for k = 1:Ncurves
|
||||
% --- Create new figure page if needed ---
|
||||
if mod(k-1, plotsPerPage) == 0
|
||||
figure('Name', sprintf('Radial Spectra Page %d', pageNum), ...
|
||||
'NumberTitle', 'off', 'Color', 'w', ...
|
||||
'Position', [50 50 1600 900]);
|
||||
pageNum = pageNum + 1;
|
||||
end
|
||||
|
||||
% --- Subplot selection ---
|
||||
subplot(nRows, nCols, mod(k-1, plotsPerPage) + 1);
|
||||
hold on; grid on; box on;
|
||||
|
||||
% --- Plot raw curve ---
|
||||
if isfield(rawCurves, 'x') && isfield(rawCurves, 'k') && ...
|
||||
~isempty(rawCurves(k).x) && all(isfinite(rawCurves(k).x))
|
||||
plot(rawCurves(k).k, rawCurves(k).x, 'k.-', ...
|
||||
'LineWidth', 1, 'DisplayName', 'Raw data');
|
||||
end
|
||||
|
||||
% --- Overlay fit if valid ---
|
||||
if k <= numel(fitResults)
|
||||
fit = fitResults(k);
|
||||
if isfield(fit, 'isValid') && fit.isValid && ...
|
||||
isfield(fit, 'kFine') && isfield(fit, 'yFit') && ...
|
||||
~isempty(fit.kFine) && all(isfinite(fit.yFit))
|
||||
plot(fit.kFine, fit.yFit, 'r-', ...
|
||||
'LineWidth', 1.2, 'DisplayName', 'Two-Gaussian fit');
|
||||
end
|
||||
end
|
||||
|
||||
% --- Labels and title ---
|
||||
xlabel('k_\rho', 'FontSize', 10);
|
||||
ylabel('Normalized amplitude', 'FontSize', 10);
|
||||
title(sprintf('Curve %d', k), 'FontSize', 9, 'Interpreter', 'none');
|
||||
|
||||
% --- Legend on first subplot of each page ---
|
||||
if mod(k-1, plotsPerPage) == 0
|
||||
legend('Location', 'best', 'FontSize', 8);
|
||||
end
|
||||
|
||||
hold off;
|
||||
end
|
||||
end
|
||||
%}
|
||||
%% ------------------ 3. Plot fit parameters - amplitude ------------------
|
||||
Plotter.plotFitParameterPDF(fitResults, scan_reference_values, 'A2', ...
|
||||
'Title', options.titleString, ...
|
||||
|
@ -167,71 +167,8 @@ Plotter.plotSpectralDistributionCumulants(results, ...
|
||||
'PositionThreshold', pi/15, ...
|
||||
'AmplitudeThreshold', 0.15);
|
||||
|
||||
%{
|
||||
% --- Function call ---
|
||||
plotTwoGaussianFitsOnRaw(fitResults, rawCurves, 8, 12); % 8×12 subplots per page
|
||||
|
||||
% --- Function definition ---
|
||||
function plotTwoGaussianFitsOnRaw(fitResults, rawCurves, nRows, nCols)
|
||||
% plotTwoGaussianFitsOnRaw - Plots raw curves and overlays valid two-Gaussian fits.
|
||||
%
|
||||
% Inputs:
|
||||
% fitResults - struct array from fitTwoGaussianCurvesToAngularSpectralDistribution (may contain fits)
|
||||
% rawCurves - struct array with fields:
|
||||
% .x - raw curve
|
||||
% .theta - corresponding theta values
|
||||
% nRows - number of subplot rows per page (default: 4)
|
||||
% nCols - number of subplot columns per page (default: 6)
|
||||
|
||||
if nargin < 3, nRows = 4; end
|
||||
if nargin < 4, nCols = 6; end
|
||||
|
||||
Ncurves = numel(rawCurves);
|
||||
plotsPerPage = nRows * nCols;
|
||||
pageNum = 1;
|
||||
|
||||
for k = 1:Ncurves
|
||||
% --- New figure/page if needed ---
|
||||
if mod(k-1, plotsPerPage) == 0
|
||||
figure('Name', sprintf('Curves Page %d', pageNum), ...
|
||||
'NumberTitle', 'off', 'Color', 'w');
|
||||
pageNum = pageNum + 1;
|
||||
end
|
||||
|
||||
% --- Select subplot ---
|
||||
subplot(nRows, nCols, mod(k-1, plotsPerPage)+1);
|
||||
hold on; grid on; box on;
|
||||
|
||||
% --- Plot raw curve ---
|
||||
xRaw = rawCurves(k).x;
|
||||
thetaRaw = rawCurves(k).theta;
|
||||
if ~isempty(xRaw) && ~isempty(thetaRaw) && all(isfinite(xRaw))
|
||||
plot(thetaRaw, xRaw, 'k.-', 'LineWidth', 1, 'DisplayName', 'Raw data');
|
||||
end
|
||||
|
||||
% --- Overlay fit if valid ---
|
||||
if k <= numel(fitResults)
|
||||
fit = fitResults(k);
|
||||
if isfield(fit, 'isValid') && fit.isValid ...
|
||||
&& ~isempty(fit.yFit) && ~isempty(fit.thetaFine)
|
||||
plot(fit.thetaFine, fit.yFit, 'r-', 'LineWidth', 1.2, 'DisplayName', 'Two-Gaussian fit');
|
||||
end
|
||||
end
|
||||
|
||||
% --- Formatting ---
|
||||
xlabel('\theta (rad)');
|
||||
ylabel('Normalized amplitude');
|
||||
title(sprintf('Curve %d', k), 'FontSize', 10);
|
||||
|
||||
% --- Legend once per page ---
|
||||
if mod(k-1, plotsPerPage) == 0
|
||||
legend('Location', 'best', 'FontSize', 8);
|
||||
end
|
||||
|
||||
hold off;
|
||||
end
|
||||
end
|
||||
%}
|
||||
%% ------------------ Interactive Fit Viewer ------------------
|
||||
Analyzer.runInteractiveASDTwoGaussianFitGUI(spectral_analysis_results);
|
||||
|
||||
%% ------------------ 5. Plot fit parameters - amplitude ------------------
|
||||
Plotter.plotFitParameterPDF(fitResults, scan_reference_values, 'A2', ...
|
||||
|
@ -121,76 +121,10 @@ Plotter.plotSpectralCurves( ...
|
||||
'ResidualThreshold', 0.15, ... % maximum allowed residual
|
||||
'PositionThreshold', 0.5, ... % minimum separation between peaks
|
||||
'AmplitudeThreshold', 0.015); % minimum secondary peak fraction
|
||||
%%
|
||||
%{
|
||||
% --- Function call ---
|
||||
plotTwoGaussianFitsOnRaw(fitResults, rawCurves, 8, 12); % 8×12 subplots per page
|
||||
|
||||
% --- Function definition ---
|
||||
function plotTwoGaussianFitsOnRaw(fitResults, rawCurves, nRows, nCols)
|
||||
%% plotTwoGaussianFitsOnRaw
|
||||
% Plots raw radial spectral curves with their two-Gaussian fits.
|
||||
%
|
||||
% Inputs:
|
||||
% fitResults - struct array from fitTwoGaussianCurvesToRadialSpectralDistribution
|
||||
% rawCurves - struct array with fields:
|
||||
% .x - raw normalized amplitudes
|
||||
% .k - corresponding k_rho values
|
||||
% nRows - number of subplot rows per page (default: 8)
|
||||
% nCols - number of subplot columns per page (default: 12)
|
||||
%% ------------------ Interactive Fit Viewer ------------------
|
||||
Analyzer.runInteractiveRSDTwoGaussianFitGUI(spectral_analysis_results);
|
||||
|
||||
if nargin < 3, nRows = 8; end
|
||||
if nargin < 4, nCols = 12; end
|
||||
|
||||
Ncurves = numel(rawCurves);
|
||||
plotsPerPage = nRows * nCols;
|
||||
pageNum = 1;
|
||||
|
||||
for k = 1:Ncurves
|
||||
% --- Create new figure page if needed ---
|
||||
if mod(k-1, plotsPerPage) == 0
|
||||
figure('Name', sprintf('Radial Spectra Page %d', pageNum), ...
|
||||
'NumberTitle', 'off', 'Color', 'w', ...
|
||||
'Position', [50 50 1600 900]);
|
||||
pageNum = pageNum + 1;
|
||||
end
|
||||
|
||||
% --- Subplot selection ---
|
||||
subplot(nRows, nCols, mod(k-1, plotsPerPage) + 1);
|
||||
hold on; grid on; box on;
|
||||
|
||||
% --- Plot raw curve ---
|
||||
if isfield(rawCurves, 'x') && isfield(rawCurves, 'k') && ...
|
||||
~isempty(rawCurves(k).x) && all(isfinite(rawCurves(k).x))
|
||||
plot(rawCurves(k).k, rawCurves(k).x, 'k.-', ...
|
||||
'LineWidth', 1, 'DisplayName', 'Raw data');
|
||||
end
|
||||
|
||||
% --- Overlay fit if valid ---
|
||||
if k <= numel(fitResults)
|
||||
fit = fitResults(k);
|
||||
if isfield(fit, 'isValid') && fit.isValid && ...
|
||||
isfield(fit, 'kFine') && isfield(fit, 'yFit') && ...
|
||||
~isempty(fit.kFine) && all(isfinite(fit.yFit))
|
||||
plot(fit.kFine, fit.yFit, 'r-', ...
|
||||
'LineWidth', 1.2, 'DisplayName', 'Two-Gaussian fit');
|
||||
end
|
||||
end
|
||||
|
||||
% --- Labels and title ---
|
||||
xlabel('k_\rho', 'FontSize', 10);
|
||||
ylabel('Normalized amplitude', 'FontSize', 10);
|
||||
title(sprintf('Curve %d', k), 'FontSize', 9, 'Interpreter', 'none');
|
||||
|
||||
% --- Legend on first subplot of each page ---
|
||||
if mod(k-1, plotsPerPage) == 0
|
||||
legend('Location', 'best', 'FontSize', 8);
|
||||
end
|
||||
|
||||
hold off;
|
||||
end
|
||||
end
|
||||
%}
|
||||
%% ------------------ 3. Plot fit parameters - amplitude ------------------
|
||||
Plotter.plotFitParameterPDF(fitResults, scan_reference_values, 'A2', ...
|
||||
'Title', options.titleString, ...
|
||||
|
Loading…
Reference in New Issue
Block a user