440 lines
18 KiB
Matlab
440 lines
18 KiB
Matlab
%% --- User chooses which dataset to load ---
|
|
datasetIdx = 1; % <-- change this to 1, 2, 3, ...
|
|
datasetName = sprintf('Dataset_%d', datasetIdx);
|
|
|
|
% --- Base directory selection ---
|
|
useLocalBaseDir = true; % <-- set true to use script location, false to use manual path
|
|
|
|
if useLocalBaseDir
|
|
% Use folder where this script is located
|
|
thisScriptPath = mfilename('fullpath');
|
|
[thisScriptDir, ~, ~] = fileparts(thisScriptPath);
|
|
baseDir = fullfile(thisScriptDir, 'Results');
|
|
else
|
|
% Use manually specified folder
|
|
baseDir = 'E:\Results - Experiment\202508\BECToDropletsToStripes\';
|
|
end
|
|
|
|
% --- Build paths ---
|
|
dataFile = fullfile(baseDir, 'SavedData', [datasetName '.mat']);
|
|
figSaveDir = fullfile(baseDir, 'SavedFigures', datasetName);
|
|
|
|
% --- Load dataset ---
|
|
data = load(dataFile);
|
|
|
|
% --- Ensure figure folder exists ---
|
|
if ~exist(figSaveDir, 'dir')
|
|
mkdir(figSaveDir);
|
|
end
|
|
|
|
% --- Access dataset struct dynamically ---
|
|
datasetStruct = data.(datasetName);
|
|
compiled_results = datasetStruct.results;
|
|
scan_parameter_values = datasetStruct.scan_parameter_values;
|
|
scan_reference_values = datasetStruct.scan_reference_values;
|
|
|
|
% --- Load options used during analysis ---
|
|
options = datasetStruct.options;
|
|
options.font = 'Bahnschrift'; % override if needed
|
|
options.skipSaveFigures = false; % override if needed
|
|
|
|
%% ------------------ 1. Mean ± Std Plots ------------------
|
|
% Plot Radial Spectral Contrast
|
|
Plotter.plotMeanWithSE(scan_parameter_values, compiled_results.spectral_analysis_results.radial_spectral_contrast, ...
|
|
'Title', options.titleString, ...
|
|
'XLabel', 'B (G)', ...
|
|
'YLabel', 'Radial Spectral Contrast', ...
|
|
'FigNum', 1, ...
|
|
'FontName', options.font, ...
|
|
'SaveFileName', 'RadialSpectralContrast.fig', ...
|
|
'SaveDirectory', figSaveDir, ... % save figures inside dataset-specific folder
|
|
'SkipSaveFigures', options.skipSaveFigures);
|
|
|
|
% Plot Angular Spectral Weight
|
|
Plotter.plotMeanWithSE(scan_parameter_values, compiled_results.spectral_analysis_results.angular_spectral_weight, ...
|
|
'Title', options.titleString, ...
|
|
'XLabel', 'B (G)', ...
|
|
'YLabel', 'Angular Spectral Weight', ...
|
|
'FigNum', 2, ...
|
|
'FontName', options.font, ...
|
|
'SaveFileName', 'AngularSpectralWeight.fig', ...
|
|
'SaveDirectory', figSaveDir, ...
|
|
'SkipSaveFigures', options.skipSaveFigures);
|
|
|
|
% Plot Peak Offset Angular Correlation
|
|
Plotter.plotMeanWithSE(scan_parameter_values, compiled_results.custom_g_results.max_g2_all_per_scan_parameter_value, ...
|
|
'Title', options.titleString, ...
|
|
'XLabel', 'B (G)', ...
|
|
'YLabel', '$\mathrm{max}[g^{(2)}_{[50,70]}(\delta\theta)]$', ...
|
|
'FigNum', 3, ...
|
|
'YLim', [0 1], ...
|
|
'FontName', options.font, ...
|
|
'SaveFileName', 'PeakOffsetAngularCorrelation.fig', ...
|
|
'SaveDirectory', figSaveDir, ...
|
|
'SkipSaveFigures', options.skipSaveFigures);
|
|
|
|
%% ------------------ 2. g²(θ) across transition ------------------
|
|
Plotter.plotG2MeanCurves(compiled_results.full_g2_results.g2_mean, ...
|
|
compiled_results.full_g2_results.g2_error, ...
|
|
compiled_results.full_g2_results.theta_values, ...
|
|
scan_reference_values, ...
|
|
options.scanParameterUnits, ...
|
|
'Title', options.titleString, ...
|
|
'XLabel', '$\delta\theta / \pi$', ...
|
|
'YLabel', '$g^{(2)}(\delta\theta)$', ...
|
|
'FigNum', 4, ...
|
|
'FontName', options.font, ...
|
|
'SkipSaveFigures', options.skipSaveFigures, ...
|
|
'SaveFileName', 'G2ThetaAcrossTransition.fig', ...
|
|
'SaveDirectory', figSaveDir, ...
|
|
'Colormap', @Colormaps.coolwarm);
|
|
|
|
%% ------------------ 3. Features of g²(θ) across transition ------------------
|
|
|
|
g2_analysis_results = Analyzer.analyzeAutocorrelation(compiled_results.full_g2_results);
|
|
|
|
Plotter.plotG2Curves(compiled_results.full_g2_results, ...
|
|
'Title', options.titleString, ...
|
|
'XLabel', '\delta\theta / \pi', ...
|
|
'YLabel', 'g^{(2)}(\delta\theta)', ...
|
|
'HighlightEvery', 10, ... % highlight every 10th repetition
|
|
'FontName', options.font, ...
|
|
'FigNum', 5, ...
|
|
'TileTitlePrefix', '\alpha', ... % user-defined tile prefix
|
|
'TileTitleSuffix', '^\circ', ... % user-defined suffix (e.g., Gauss symbol)...
|
|
'SkipSaveFigures', options.skipSaveFigures, ...
|
|
'SaveFileName', 'G2Curves.fig', ...
|
|
'SaveDirectory', figSaveDir);
|
|
|
|
Plotter.plotG2PDF(compiled_results.full_g2_results, pi/2, ...
|
|
'Title', options.titleString, ...
|
|
'XLabel', '\alpha (degrees)', ...
|
|
'YLabel', 'g^{(2)}(\delta\theta)', ...
|
|
'FontName', options.font, ...
|
|
'FontSize', 16, ...
|
|
'FigNum', 6, ...
|
|
'SkipSaveFigures', options.skipSaveFigures, ...
|
|
'SaveFileName', 'G2PDF_pi6.fig', ...
|
|
'SaveDirectory', figSaveDir, ...
|
|
'NumberOfBins', 20, ...
|
|
'NormalizeHistogram', true, ...
|
|
'DataRange', [0 1.0], ...
|
|
'Colormap', @Colormaps.coolwarm, ...
|
|
'ColorScale', 'log', ...
|
|
'XLim', [min(scan_reference_values) max(scan_reference_values)]);
|
|
|
|
Plotter.plotG2Features(g2_analysis_results, ...
|
|
'Title', options.titleString, ...
|
|
'XLabel', '\alpha (degrees)', ...
|
|
'FontName', options.font, ...
|
|
'FigNum', 7, ...
|
|
'SkipSaveFigures', options.skipSaveFigures, ...
|
|
'SaveFileName', 'G2Features.fig', ...
|
|
'SaveDirectory', figSaveDir);
|
|
|
|
Plotter.plotG2Cumulants(g2_analysis_results, ...
|
|
'Title', options.titleString, ...
|
|
'XLabel', '\alpha (degrees)', ...
|
|
'FontName', options.font, ...
|
|
'FigNum', 8, ...
|
|
'SkipSaveFigures', options.skipSaveFigures, ...
|
|
'SaveFileName', 'G2Cumulants.fig', ...
|
|
'SaveDirectory', figSaveDir);
|
|
|
|
%% ------------------ 4. PDF of max g² across transition ------------------
|
|
Plotter.plotPDF(compiled_results.custom_g_results.max_g2_all_per_scan_parameter_value, ...
|
|
scan_reference_values, ...
|
|
'Title', options.titleString, ...
|
|
'XLabel', 'B (G)', ...
|
|
'YLabel', '$\mathrm{max}[g^{(2)}_{[50,70]}(\delta\theta)]$', ...
|
|
'FigNum', 9, ...
|
|
'FontName', options.font, ...
|
|
'SkipSaveFigures', options.skipSaveFigures, ...
|
|
'SaveFileName', 'PDF_MaxG2AcrossTransition.fig', ...
|
|
'SaveDirectory', figSaveDir, ...
|
|
'NumberOfBins', 20, ...
|
|
'NormalizeHistogram', true, ...
|
|
'DataRange', [0 1.5], ...
|
|
'Colormap', @Colormaps.coolwarm, ...
|
|
'XLim', [min(scan_reference_values) max(scan_reference_values)]);
|
|
|
|
|
|
%% ------------------ 5. Cumulants across transition ------------------
|
|
Plotter.plotCumulants(scan_reference_values, ...
|
|
{compiled_results.custom_g_results.mean_max_g2, compiled_results.custom_g_results.var_max_g2, compiled_results.custom_g_results.skew_max_g2_angle, compiled_results.custom_g_results.fourth_order_cumulant_max_g2}, ...
|
|
'Title', 'Cumulants of Peak Offset Angular Correlation', ...
|
|
'XLabel', '\alpha (degrees)', ...
|
|
'FigNum', 10, ...
|
|
'FontName', options.font, ...
|
|
'SkipSaveFigures', options.skipSaveFigures, ...
|
|
'SaveFileName', 'CumulantOfPeakOffsetAngularCorrelation.fig', ...
|
|
'SaveDirectory', figSaveDir);
|
|
|
|
%% ------------------ 6. PCA ------------------
|
|
Plotter.plotSinglePCAResults(compiled_results.pca_results, scan_parameter_values, scan_reference_values, ...
|
|
'FigNumRange', [11,12,13,14,15,16], ...
|
|
'XLabel', '\alpha (degrees)', ...
|
|
'FontName', options.font, ...
|
|
'SkipSaveFigures', options.skipSaveFigures, ...
|
|
'SaveDirectory', figSaveDir);
|
|
|
|
|
|
Plotter.plotMultiplePCAResults(compiled_results.pca_results, scan_parameter_values, scan_reference_values, ...
|
|
'MaxPCToPlot', 2, ...
|
|
'XLabel', '\alpha (degrees)', ...
|
|
'FigNumRange', [17,18,19], ...
|
|
'FontName', options.font, ...
|
|
'SkipSaveFigures', options.skipSaveFigures, ...
|
|
'SaveDirectory', figSaveDir);
|
|
|
|
%% ------------------ 7. Plot of all Angular Spectral Distribution Curves ------------------
|
|
Plotter.plotSpectralCurves( ...
|
|
results_all{1}.results.spectral_analysis_results.S_theta_norm_all, ...
|
|
results_all{1}.results.spectral_analysis_results.theta_vals/pi, ... % correct θ values
|
|
results_all{1}.scan_reference_values, ... % correct scan params
|
|
'Title', options.titleString, ...
|
|
'XLabel', '\theta / \pi', ...
|
|
'YLabel', 'S(\theta)', ...
|
|
'HighlightEvery', 10, ... % highlight every 10th repetition
|
|
'FontName', options.font, ...
|
|
'FigNum', 20, ...
|
|
'TileTitlePrefix', '\alpha', ... % user-defined tile prefix
|
|
'TileTitleSuffix', '^\circ', ... % user-defined suffix (e.g., degrees symbol)
|
|
'SkipSaveFigures', options.skipSaveFigures, ...
|
|
'SaveFileName', 'SpectralCurves.fig', ...
|
|
'SaveDirectory', figSaveDir);
|
|
|
|
%% ------------------ 8. Plot of all Angular Spectral Distribution Curves shifted ------------------
|
|
results = Plotter.plotSpectralCurvesRecentered( ...
|
|
results_all{1}.results.spectral_analysis_results.S_theta_norm_all, ...
|
|
results_all{1}.results.spectral_analysis_results.theta_vals/pi, ... % correct θ values
|
|
results_all{1}.scan_reference_values, ... % correct scan params
|
|
'Title', options.titleString, ...
|
|
'XLabel', '\theta / \pi', ...
|
|
'YLabel', 'S(\theta)', ...
|
|
'HighlightEvery', 10, ... % highlight every 10th repetition
|
|
'FontName', options.font, ...
|
|
'FigNum', 21, ...
|
|
'TileTitlePrefix', '\alpha', ... % user-defined tile prefix
|
|
'TileTitleSuffix', '^\circ', ... % user-defined suffix (e.g., degrees symbol)
|
|
'SkipSaveFigures', options.skipSaveFigures, ...
|
|
'SaveFileName', 'SpectralCurves.fig', ...
|
|
'SaveDirectory', figSaveDir);
|
|
%% ------------------ 9. Plot cumulants from shifted Angular Spectral Distribution Curves ------------------
|
|
Plotter.plotSpectralDistributionCumulants(results, ...
|
|
'Title', options.titleString, ...
|
|
'XLabel', '\alpha (degrees)', ...
|
|
'FontName', options.font, ...
|
|
'FontSize', 14, ...
|
|
'FigNum', 22, ...
|
|
'SkipSaveFigures', false, ...
|
|
'SaveFileName', 'SpectralCumulants.fig');
|
|
|
|
%% ------------------ 10. Fit shifted Angular Spectral Distribution Curves ------------------
|
|
fitResults = Analyzer.fitTwoGaussianCurves(...
|
|
results_all{1}.results.spectral_analysis_results.S_theta_norm_all, ...
|
|
results_all{1}.results.spectral_analysis_results.theta_vals, ...
|
|
'MaxTheta', pi/2, ...
|
|
'DeviationLimit', 1.00);
|
|
|
|
%% ------------------ 11. Plot fit parameters - position ------------------
|
|
Plotter.plotFitParameterPDF(fitResults, results_all{1}.scan_reference_values, 'mu2', ...
|
|
'Title', options.titleString, ...
|
|
'XLabel', '\alpha (degrees)', ...
|
|
'YLabel', 'Secondary peak position (\theta, rad)', ...
|
|
'FontName', options.font, ...
|
|
'FontSize', 16, ...
|
|
'FigNum', 23, ...
|
|
'SkipSaveFigures', options.skipSaveFigures, ...
|
|
'SaveFileName', 'SecondaryPeakPositionPDF.fig', ...
|
|
'PlotType', 'histogram', ...
|
|
'NumberOfBins', 20, ...
|
|
'NormalizeHistogram', true, ...
|
|
'Colormap', @Colormaps.coolwarm, ...
|
|
'XLim', [min(results_all{1}.scan_reference_values), max(results_all{1}.scan_reference_values)]);
|
|
|
|
%% ------------------ 12. Plot fit parameters - width ------------------
|
|
Plotter.plotFitParameterPDF(fitResults, results_all{1}.scan_reference_values, 'sigma2', ...
|
|
'Title', options.titleString, ...
|
|
'XLabel', '\alpha (degrees)', ...
|
|
'YLabel', 'Secondary peak width (\sigma, rad)', ...
|
|
'FontName', options.font, ...
|
|
'FontSize', 16, ...
|
|
'FigNum', 24, ...
|
|
'SkipSaveFigures', options.skipSaveFigures, ...
|
|
'SaveFileName', 'SecondaryPeakWidthPDF.fig', ...
|
|
'PlotType', 'histogram', ...
|
|
'NumberOfBins', 20, ...
|
|
'NormalizeHistogram', true, ...
|
|
'Colormap', @Colormaps.coolwarm, ...
|
|
'XLim', [min(results_all{1}.scan_reference_values), max(results_all{1}.scan_reference_values)]);
|
|
|
|
%% ------------------ 13. Plot fit parameters of mean shifted Angular Spectral Distribution Curves ------------------
|
|
S_theta_all = results_all{1}.results.spectral_analysis_results.S_theta_norm_all;
|
|
theta_vals = results_all{1}.results.spectral_analysis_results.theta_vals;
|
|
scanValues = results_all{1}.scan_reference_values;
|
|
|
|
N_params = numel(scanValues);
|
|
N_total = numel(S_theta_all);
|
|
N_reps = N_total / N_params;
|
|
|
|
theta_min = deg2rad(0);
|
|
theta_max = deg2rad(90);
|
|
|
|
% --- Shift curves so first peak is at start ---
|
|
S_theta_all_shifted = cell(size(S_theta_all));
|
|
for k = 1:N_total
|
|
curve = S_theta_all{k};
|
|
idx_range = find(theta_vals >= theta_min & theta_vals <= theta_max);
|
|
if isempty(idx_range)
|
|
[~, peak_idx] = max(curve);
|
|
else
|
|
[~, local_max_idx] = max(curve(idx_range));
|
|
peak_idx = idx_range(local_max_idx);
|
|
end
|
|
S_theta_all_shifted{k} = curve(peak_idx:end);
|
|
end
|
|
|
|
% --- Pad shorter curves with NaN to match lengths ---
|
|
Npoints_shifted = max(cellfun(@numel, S_theta_all_shifted));
|
|
for k = 1:N_total
|
|
len = numel(S_theta_all_shifted{k});
|
|
if len < Npoints_shifted
|
|
S_theta_all_shifted{k} = [S_theta_all_shifted{k}, nan(1, Npoints_shifted-len)];
|
|
end
|
|
end
|
|
|
|
% --- Compute mean curves per scan parameter ---
|
|
meanCurves = cell(1, N_params);
|
|
for i = 1:N_params
|
|
curves = zeros(N_reps, Npoints_shifted);
|
|
for r = 1:N_reps
|
|
idx = (r-1)*N_params + i; % interleaved indexing
|
|
curves(r,:) = S_theta_all_shifted{idx};
|
|
end
|
|
meanCurves{i} = nanmean(curves,1); % mean over repetitions
|
|
end
|
|
|
|
% --- Fit two-Gaussian model to mean curves ---
|
|
fitResultsMean = Analyzer.fitTwoGaussianCurves(meanCurves, theta_vals(1:Npoints_shifted)-theta_vals(1), ...
|
|
'MaxTheta', pi/2, ...
|
|
'DeviationLimit', 1.0);
|
|
|
|
% --- Scatter plot of secondary peak position (mu2) vs scan parameter ---
|
|
mu2_vals = nan(1, N_params);
|
|
sigma2_vals = nan(1, N_params);
|
|
|
|
for i = 1:N_params
|
|
if fitResultsMean(i).isValid
|
|
mu2_vals(i) = fitResultsMean(i).pFit(4); % secondary peak position
|
|
sigma2_vals(i) = fitResultsMean(i).pFit(5); % secondary peak width
|
|
end
|
|
end
|
|
|
|
% Secondary peak position
|
|
plotSecondaryPeakScatter(fitResultsMean, results_all{1}.scan_reference_values, 'mu2', ...
|
|
'Title', options.titleString, ...
|
|
'XLabel', '\alpha (degrees)', ...
|
|
'YLabel', 'Secondary peak position (\theta, rad)', ...
|
|
'FigNum', 23, ...
|
|
'FontName', options.font, ...
|
|
'FontSize', 16, ...
|
|
'SkipSaveFigures', options.skipSaveFigures, ...
|
|
'SaveFileName', 'SecondaryPeakPositionScatter.fig');
|
|
|
|
% Secondary peak width
|
|
plotSecondaryPeakScatter(fitResultsMean, results_all{1}.scan_reference_values, 'sigma2', ...
|
|
'Title', options.titleString, ...
|
|
'XLabel', '\alpha (degrees)', ...
|
|
'YLabel', 'Secondary peak width (\sigma, rad)', ...
|
|
'FigNum', 24, ...
|
|
'FontName', options.font, ...
|
|
'FontSize', 16, ...
|
|
'SkipSaveFigures', options.skipSaveFigures, ...
|
|
'SaveFileName', 'SecondaryPeakWidthScatter.fig');
|
|
|
|
|
|
function plotSecondaryPeakScatter(fitResultsMean, scanValues, parameterName, varargin)
|
|
%% plotSecondaryPeakScatter
|
|
% Author: Karthik
|
|
% Date: 2025-10-06
|
|
% Version: 1.0
|
|
%
|
|
% Description:
|
|
% Scatter plot of secondary peak fit parameters (mu2 or sigma2) vs scan parameter
|
|
% in the same style as plotMeanWithSE.
|
|
|
|
% --- Parse optional inputs ---
|
|
p = inputParser;
|
|
addParameter(p, 'Title', '', @(x) ischar(x) || isstring(x));
|
|
addParameter(p, 'XLabel', '', @(x) ischar(x) || isstring(x));
|
|
addParameter(p, 'YLabel', '', @(x) ischar(x) || isstring(x));
|
|
addParameter(p, 'FigNum', [], @(x) isempty(x) || isscalar(x));
|
|
addParameter(p, 'FontName', 'Arial', @ischar);
|
|
addParameter(p, 'FontSize', 14, @isnumeric);
|
|
addParameter(p, 'YLim', [], @(x) isempty(x) || isnumeric(x));
|
|
addParameter(p, 'SkipSaveFigures', false, @islogical);
|
|
addParameter(p, 'SaveFileName', 'secondary_peak_scatter.fig', @ischar);
|
|
addParameter(p, 'SaveDirectory', pwd, @ischar);
|
|
parse(p, varargin{:});
|
|
opts = p.Results;
|
|
|
|
% --- Extract parameter values ---
|
|
N_params = numel(fitResultsMean);
|
|
paramVals = nan(1, N_params);
|
|
for i = 1:N_params
|
|
if fitResultsMean(i).isValid
|
|
switch parameterName
|
|
case 'mu2'
|
|
paramVals(i) = fitResultsMean(i).pFit(4);
|
|
case 'sigma2'
|
|
paramVals(i) = fitResultsMean(i).pFit(5);
|
|
otherwise
|
|
error('Unknown parameter name: %s', parameterName);
|
|
end
|
|
end
|
|
end
|
|
|
|
% --- Prepare figure ---
|
|
if isempty(opts.FigNum)
|
|
fig = figure;
|
|
else
|
|
fig = figure(opts.FigNum);
|
|
clf(fig);
|
|
end
|
|
set(fig, 'Color', 'w', 'Position', [100 100 950 750]);
|
|
|
|
% --- Plot as mean ± SE style (SE=0 here) ---
|
|
errorbar(scanValues, paramVals, zeros(size(paramVals)), 'o--', ...
|
|
'LineWidth', 1.8, 'MarkerSize', 6, 'CapSize', 5);
|
|
|
|
% --- Axis formatting ---
|
|
set(gca, 'FontName', opts.FontName, 'FontSize', opts.FontSize);
|
|
if ~isempty(opts.YLim)
|
|
ylim(opts.YLim);
|
|
end
|
|
xlabel(opts.XLabel, 'Interpreter', 'tex', 'FontName', opts.FontName, 'FontSize', opts.FontSize);
|
|
ylabel(opts.YLabel, 'Interpreter', 'tex', 'FontName', opts.FontName, 'FontSize', opts.FontSize);
|
|
title(opts.Title, 'FontName', opts.FontName, 'FontSize', opts.FontSize + 2, 'FontWeight', 'bold');
|
|
grid on;
|
|
|
|
% --- Save figure ---
|
|
if ~opts.SkipSaveFigures
|
|
if ~exist(opts.SaveDirectory, 'dir'), mkdir(opts.SaveDirectory); end
|
|
savefig(fig, fullfile(opts.SaveDirectory, opts.SaveFileName));
|
|
end
|
|
end
|
|
|
|
%{
|
|
%% ------------------ 14. Average of Spectra Plots ------------------
|
|
|
|
Plotter.plotAverageSpectra(scan_parameter_values, ...
|
|
spectral_analysis_results, ...
|
|
'ScanParameterName', scan_parameter, ...
|
|
'FigNum', 25, ...
|
|
'ColormapPS', Colormaps.coolwarm(), ...
|
|
'Font', 'Bahnschrift', ...
|
|
'SaveFileName', 'avgSpectra.fig', ...
|
|
'SaveDirectory', figSaveDir, ...
|
|
'SkipSaveFigures', options.skipSaveFigures);
|
|
%} |