From 5761d3b0fe7bb4f9cd70c422e4ac02d605fbd3e3 Mon Sep 17 00:00:00 2001 From: Karthik Chandrashekara Date: Thu, 16 Oct 2025 19:06:38 +0200 Subject: [PATCH] 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). --- ...ssianCurvesToAngularSpectralDistribution.m | 38 +-- ...ussianCurvesToRadialSpectralDistribution.m | 18 +- .../runInteractiveASDTwoGaussianFitGUI.m | 228 ++++++++++++++++++ .../runInteractiveRSDTwoGaussianFitGUI.m | 219 +++++++++++++++++ .../runAngularSpectralDistributionAnalysis.m | 67 +---- .../runRadialSpectralDistributionAnalysis.m | 70 +----- .../runAngularSpectralDistributionAnalysis.m | 69 +----- .../runRadialSpectralDistributionAnalysis.m | 72 +----- .../runAngularSpectralDistributionAnalysis.m | 67 +---- .../runRadialSpectralDistributionAnalysis.m | 70 +----- .../runAngularSpectralDistributionAnalysis.m | 67 +---- .../runRadialSpectralDistributionAnalysis.m | 70 +----- 12 files changed, 496 insertions(+), 559 deletions(-) create mode 100644 Data-Analyzer/+Analyzer/runInteractiveASDTwoGaussianFitGUI.m create mode 100644 Data-Analyzer/+Analyzer/runInteractiveRSDTwoGaussianFitGUI.m diff --git a/Data-Analyzer/+Analyzer/fitTwoGaussianCurvesToAngularSpectralDistribution.m b/Data-Analyzer/+Analyzer/fitTwoGaussianCurvesToAngularSpectralDistribution.m index 5428b1b..890b4ec 100644 --- a/Data-Analyzer/+Analyzer/fitTwoGaussianCurvesToAngularSpectralDistribution.m +++ b/Data-Analyzer/+Analyzer/fitTwoGaussianCurvesToAngularSpectralDistribution.m @@ -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(); diff --git a/Data-Analyzer/+Analyzer/fitTwoGaussianCurvesToRadialSpectralDistribution.m b/Data-Analyzer/+Analyzer/fitTwoGaussianCurvesToRadialSpectralDistribution.m index 1ee4417..c826ab8 100644 --- a/Data-Analyzer/+Analyzer/fitTwoGaussianCurvesToRadialSpectralDistribution.m +++ b/Data-Analyzer/+Analyzer/fitTwoGaussianCurvesToRadialSpectralDistribution.m @@ -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); diff --git a/Data-Analyzer/+Analyzer/runInteractiveASDTwoGaussianFitGUI.m b/Data-Analyzer/+Analyzer/runInteractiveASDTwoGaussianFitGUI.m new file mode 100644 index 0000000..572c6c0 --- /dev/null +++ b/Data-Analyzer/+Analyzer/runInteractiveASDTwoGaussianFitGUI.m @@ -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 diff --git a/Data-Analyzer/+Analyzer/runInteractiveRSDTwoGaussianFitGUI.m b/Data-Analyzer/+Analyzer/runInteractiveRSDTwoGaussianFitGUI.m new file mode 100644 index 0000000..16dfdee --- /dev/null +++ b/Data-Analyzer/+Analyzer/runInteractiveRSDTwoGaussianFitGUI.m @@ -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 currentIdx1, currentIdx=currentIdx-1; set(hSlider,'Value',currentIdx); updatePlot(); end + end + end + +end diff --git a/Data-Analyzer/+Scripts/BECToDroplets/runAngularSpectralDistributionAnalysis.m b/Data-Analyzer/+Scripts/BECToDroplets/runAngularSpectralDistributionAnalysis.m index 70174a7..f7ac16e 100644 --- a/Data-Analyzer/+Scripts/BECToDroplets/runAngularSpectralDistributionAnalysis.m +++ b/Data-Analyzer/+Scripts/BECToDroplets/runAngularSpectralDistributionAnalysis.m @@ -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', ... diff --git a/Data-Analyzer/+Scripts/BECToDroplets/runRadialSpectralDistributionAnalysis.m b/Data-Analyzer/+Scripts/BECToDroplets/runRadialSpectralDistributionAnalysis.m index f43dc7a..3b6b3e2 100644 --- a/Data-Analyzer/+Scripts/BECToDroplets/runRadialSpectralDistributionAnalysis.m +++ b/Data-Analyzer/+Scripts/BECToDroplets/runRadialSpectralDistributionAnalysis.m @@ -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, ... diff --git a/Data-Analyzer/+Scripts/BECToDropletsToStripes/runAngularSpectralDistributionAnalysis.m b/Data-Analyzer/+Scripts/BECToDropletsToStripes/runAngularSpectralDistributionAnalysis.m index 9212b2e..87fce66 100644 --- a/Data-Analyzer/+Scripts/BECToDropletsToStripes/runAngularSpectralDistributionAnalysis.m +++ b/Data-Analyzer/+Scripts/BECToDropletsToStripes/runAngularSpectralDistributionAnalysis.m @@ -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', ... diff --git a/Data-Analyzer/+Scripts/BECToDropletsToStripes/runRadialSpectralDistributionAnalysis.m b/Data-Analyzer/+Scripts/BECToDropletsToStripes/runRadialSpectralDistributionAnalysis.m index 0101717..dba3929 100644 --- a/Data-Analyzer/+Scripts/BECToDropletsToStripes/runRadialSpectralDistributionAnalysis.m +++ b/Data-Analyzer/+Scripts/BECToDropletsToStripes/runRadialSpectralDistributionAnalysis.m @@ -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', ... diff --git a/Data-Analyzer/+Scripts/BECToStripes/runAngularSpectralDistributionAnalysis.m b/Data-Analyzer/+Scripts/BECToStripes/runAngularSpectralDistributionAnalysis.m index c7d899a..d888fcc 100644 --- a/Data-Analyzer/+Scripts/BECToStripes/runAngularSpectralDistributionAnalysis.m +++ b/Data-Analyzer/+Scripts/BECToStripes/runAngularSpectralDistributionAnalysis.m @@ -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', ... diff --git a/Data-Analyzer/+Scripts/BECToStripes/runRadialSpectralDistributionAnalysis.m b/Data-Analyzer/+Scripts/BECToStripes/runRadialSpectralDistributionAnalysis.m index 8eb46c1..09bd476 100644 --- a/Data-Analyzer/+Scripts/BECToStripes/runRadialSpectralDistributionAnalysis.m +++ b/Data-Analyzer/+Scripts/BECToStripes/runRadialSpectralDistributionAnalysis.m @@ -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, ... diff --git a/Data-Analyzer/+Scripts/BECToStripesToDroplets/runAngularSpectralDistributionAnalysis.m b/Data-Analyzer/+Scripts/BECToStripesToDroplets/runAngularSpectralDistributionAnalysis.m index 85d81ba..97ad443 100644 --- a/Data-Analyzer/+Scripts/BECToStripesToDroplets/runAngularSpectralDistributionAnalysis.m +++ b/Data-Analyzer/+Scripts/BECToStripesToDroplets/runAngularSpectralDistributionAnalysis.m @@ -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', ... diff --git a/Data-Analyzer/+Scripts/BECToStripesToDroplets/runRadialSpectralDistributionAnalysis.m b/Data-Analyzer/+Scripts/BECToStripesToDroplets/runRadialSpectralDistributionAnalysis.m index 023ef11..406417f 100644 --- a/Data-Analyzer/+Scripts/BECToStripesToDroplets/runRadialSpectralDistributionAnalysis.m +++ b/Data-Analyzer/+Scripts/BECToStripesToDroplets/runRadialSpectralDistributionAnalysis.m @@ -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, ...