Latest scripts - new analysis routines, more bugfixes, aesthetic changes.

This commit is contained in:
Karthik 2025-09-03 21:29:08 +02:00
parent b7f38c16a0
commit 9b4412f1a2
24 changed files with 766 additions and 168 deletions

View File

@ -0,0 +1,139 @@
function results = analyzeAutocorrelation(autocorrresults)
%% Computes features from g2(theta) curves and aggregates results.
% Assumes theta_values are given in radians.
feature_list = table();
per_group = cell(numel(autocorrresults.scan_parameter_values),1);
% --- Loop over groups ---
for i = 1:numel(autocorrresults.scan_parameter_values)
curves = autocorrresults.g2_curves{i};
thetas = autocorrresults.theta_values;
group_tbl = table();
for j = 1:size(curves,1)
g2curve = curves(j,:);
feats = extractFeatures(thetas, g2curve);
group_tbl = [group_tbl; feats]; %#ok<AGROW>
feature_list = [feature_list; feats]; %#ok<AGROW>
end
per_group{i} = group_tbl;
end
%% Compute group summaries (mean & SEM of features)
summary_table = table();
N_params = numel(autocorrresults.scan_parameter_values);
for i = 1:N_params
FT = per_group{i};
% Scalars
vars = {'A2','A4','A6','S2','Q4','H6','Contrast','NumberOfPeaks','MaxProm','MaxHeight'};
% --- Handle spacing ---
spacing_means = cellfun(@mean, FT.Spacing, 'UniformOutput', false);
spacing_stds = cellfun(@std, FT.Spacing, 'UniformOutput', false);
FT.SpacingMean = cell2mat(spacing_means);
FT.SpacingStd = cell2mat(spacing_stds);
% --- Handle widths ---
width_means = cellfun(@mean, FT.Widths, 'UniformOutput', false);
width_stds = cellfun(@std, FT.Widths, 'UniformOutput', false);
FT.WidthsMean = cell2mat(width_means);
FT.WidthsStd = cell2mat(width_stds);
vars = [vars, {'SpacingMean','SpacingStd','WidthsMean','WidthsStd'}];
% Group averages
meanVals = varfun(@mean, FT, 'InputVariables', vars);
semVals = varfun(@(x) std(x,0,1,'omitnan')/sqrt(size(FT,1)), ...
FT, 'InputVariables', vars);
row = table(autocorrresults.scan_parameter_values(i), ...
'VariableNames', {'scanParamVal'});
summary_table = [summary_table; [row meanVals semVals]]; %#ok<AGROW>
end
%% --- Compute cumulants from full distribution of curves ---
N_theta = numel(autocorrresults.theta_values);
g2_cums = cell(N_params,1);
for i = 1:N_params
curves = autocorrresults.g2_curves{i}; % [N_reps × N_theta]
cumul_mat = zeros(N_theta,4); % θ × first 4 cumulants
for th = 1:N_theta
g2vals = curves(:,th); % all repetitions at this theta
cumul_mat(th,:) = Calculator.computeCumulants(g2vals,4);
end
g2_cums{i} = cumul_mat;
end
%% Package results
results = struct();
results.features_all = feature_list; % all repetitions pooled
results.features_group = per_group; % per scan parameter
results.summaries = summary_table; % group-level stats
results.g2_cumulants = g2_cums; % cumulants from full distribution
results.theta_values = autocorrresults.theta_values;
end
function features = extractFeatures(thetas, g2curve)
%% --- Step 1: Restrict theta to [0, π] ---
mask = (thetas >= 0 & thetas <= pi);
thetasWithinPi = thetas(mask);
g2WithinPi = g2curve(mask);
%% --- Step 2: DC removal ---
g2cWithinPi = g2WithinPi - mean(g2WithinPi);
%% --- Step 3: Fourier projections (n=2,4,6) ---
nlist = [2 4 6];
An = zeros(size(nlist));
for k = 1:numel(nlist)
n = nlist(k);
An(k) = abs(mean(g2cWithinPi .* exp(-1i*n*thetasWithinPi)));
end
%% --- Step 3b: Symmetry fractions ---
totalAmp = sum(An);
if totalAmp > 0
S2 = An(1)/totalAmp;
Q4 = An(2)/totalAmp;
H6 = An(3)/totalAmp;
else
S2 = 0; Q4 = 0; H6 = 0;
end
%% --- Step 4: RMS fluctuation (contrast) ---
RMSval = sqrt(mean(g2cWithinPi.^2));
%% --- Step 5: Peak finding with dynamic threshold ---
alpha = 0.25;
dynamicProm = alpha * range(g2WithinPi);
minDist = round(numel(thetasWithinPi)/12);
[pks,locs,w,prom] = findpeaks(g2WithinPi, ...
'MinPeakProminence', dynamicProm, ...
'MinPeakDistance', minDist);
peakAngles = thetasWithinPi(locs);
%% --- Step 6: Spacing calculation (wrap within π) ---
if numel(peakAngles) > 1
d = diff([peakAngles, peakAngles(1)+pi]);
else
d = NaN;
end
%% --- Step 7: Safely handle empty peaks ---
if isempty(prom), MaxProm = NaN; else, MaxProm = max(prom(:),[],'omitnan'); end
if isempty(pks), MaxHeight = NaN; else, MaxHeight = max(pks(:),[],'omitnan'); end
%% --- Step 8: Package as one row table ---
features = table( ...
An(1), An(2), An(3), RMSval, numel(pks), ...
MaxProm, MaxHeight, ...
{d(:)'}, {w(:)'}, ...
S2, Q4, H6, ...
'VariableNames', {'A2','A4','A6','Contrast','NumberOfPeaks','MaxProm','MaxHeight','Spacing','Widths','S2','Q4','H6'});
end

View File

@ -1,9 +1,8 @@
function results = extractAutocorrelation(theta_values, angular_spectral_distribution, scan_parameter_values, N_shots, N_angular_bins)
%% Extract g² (autocorrelation) from experimental images
% Computes angular autocorrelation g² for a set of experimental images.
% Uses conductSpectralAnalysis to compute S(θ) and θ-values, then groups
% images by scan parameter and computes normalized autocorrelations.
% Returns both all repetition curves and their mean + error for each scan parameter.
% ===== Convert spectral distributions to matrix =====
delta_nkr_all = zeros(N_shots, N_angular_bins);
for k = 1:N_shots
@ -14,36 +13,45 @@ function results = extractAutocorrelation(theta_values, angular_spectral_distrib
[unique_scan_parameter_values, ~, idx] = unique(scan_parameter_values);
N_params = length(unique_scan_parameter_values);
% ===== Preallocate output arrays =====
g2_all = zeros(N_params, N_angular_bins);
g2_error_all = zeros(N_params, N_angular_bins);
% ===== Preallocate outputs =====
g2_curves = cell(1, N_params); % each cell: [N_reps × N_angular_bins]
g2_mean = zeros(N_params, N_angular_bins);
g2_error = zeros(N_params, N_angular_bins);
% ===== Compute g²(θ) for each scan parameter group =====
for i = 1:N_params
group_idx = find(idx == i);
group_data = delta_nkr_all(group_idx, :);
N_reps = length(group_idx);
for dtheta = 0:N_angular_bins-1
temp = zeros(length(group_idx), 1);
g2_matrix = zeros(N_reps, N_angular_bins);
for j = 1:length(group_idx)
profile = group_data(j, :);
profile_shifted = circshift(profile, -dtheta, 2);
for j = 1:N_reps
profile = group_data(j, :);
for dtheta = 0:N_angular_bins-1
profile_shifted = circshift(profile, -dtheta, 2);
num = mean(profile .* profile_shifted);
denom = mean(profile.^2);
temp(j) = num / denom;
g2_matrix(j, dtheta+1) = num / denom;
end
g2_all(i, dtheta+1) = mean(temp, 'omitnan');
g2_error_all(i, dtheta+1) = std(temp, 'omitnan') / sqrt(length(group_idx));
end
% Store per-repetition curves
g2_curves{i} = g2_matrix;
% Compute mean and standard error
g2_mean(i,:) = mean(g2_matrix, 1, 'omitnan');
g2_error(i,:) = std(g2_matrix, 0, 1, 'omitnan') ./ sqrt(N_reps);
end
% ===== Package results =====
results = struct();
results.g2_all = g2_all;
results.g2_error_all = g2_error_all;
results.theta_values = theta_values;
end
results.g2_curves = g2_curves; % raw [N_reps × N_angular_bins] per group
results.g2_mean = g2_mean; % mean per group
results.g2_error = g2_error; % standard error per group
results.theta_values = theta_values;
results.scan_parameter_values = unique_scan_parameter_values;
end

View File

@ -55,26 +55,26 @@ function [results, scan_parameter_values] = performAnalysis(options)
% Conduct spectral analysis
fprintf('\n[INFO] Initiating spectral analysis...\n');
spectral_analysis_results = Analyzer.conductSpectralAnalysis(od_imgs, scan_parameter_values, options);
spectral_analysis_results = Analyzer.conductSpectralAnalysis(od_imgs, scan_parameter_values, options);
N_shots = length(od_imgs);
N_shots = length(od_imgs);
% Extract angular correlations
full_g2_results = Analyzer.extractAutocorrelation(...
spectral_analysis_results.theta_vals, ...
spectral_analysis_results.angular_spectral_distribution, ...
scan_parameter_values, N_shots, options.N_angular_bins);
full_g2_results = Analyzer.extractAutocorrelation(...
spectral_analysis_results.theta_vals, ...
spectral_analysis_results.angular_spectral_distribution, ...
scan_parameter_values, N_shots, options.N_angular_bins);
custom_g_results = Analyzer.extractCustomCorrelation(...
spectral_analysis_results.angular_spectral_distribution, ...
scan_parameter_values, N_shots, options.N_angular_bins);
custom_g_results = Analyzer.extractCustomCorrelation(...
spectral_analysis_results.angular_spectral_distribution, ...
scan_parameter_values, N_shots, options.N_angular_bins);
fprintf('\n[INFO] Spectral analysis complete!\n');
% Conduct PCA
fprintf('\n[INFO] Initiating Principal Component Analysis...\n');
pca_results = Analyzer.conductPCA(od_imgs);
pca_results = Analyzer.conductPCA(od_imgs);
fprintf('\n[INFO] Principal Component Analysis complete!\n');
@ -82,8 +82,8 @@ function [results, scan_parameter_values] = performAnalysis(options)
% Package results into struct
results = struct();
results.spectral_analysis_results = spectral_analysis_results;
results.full_g2_results = full_g2_results;
results.custom_g_results = custom_g_results;
results.pca_results = pca_results;
results.spectral_analysis_results = spectral_analysis_results;
results.full_g2_results = full_g2_results;
results.custom_g_results = custom_g_results;
results.pca_results = pca_results;
end

View File

@ -119,7 +119,7 @@ function [od_imgs, scan_parameter_values, file_list] = collectODImages(options)
% If user forces recompute -> recompute from selected raw path
if isfield(options,'skipFullODImagesFolderUse') && options.skipFullODImagesFolderUse
[full_od_imgs, full_bkg_imgs, raw_scan_parameter_values, raw_file_list, raw_scan_parameter_names, options.scan_reference_values] = recomputeODImages(options, selPath);
[full_od_imgs, full_bkg_imgs, raw_scan_parameter_values, raw_file_list, raw_scan_parameter_names, scan_reference_values] = recomputeODImages(options, selPath);
if ~options.SAVE_TO_WORKSPACE
% --- Determine parent folder for FullODImages ---
if isfield(options, 'FullODImagesFolder') && ...
@ -162,7 +162,7 @@ function [od_imgs, scan_parameter_values, file_list] = collectODImages(options)
% If no matching full-OD folder found, recompute from the selected raw path
if ~found
fprintf('\n[INFO] Forcing recompute from raw data as no matching full OD images subfolder found (Use skipFullODImagesFolderUse=true to skip directly to computing from raw data).\n');
[full_od_imgs, full_bkg_imgs, raw_scan_parameter_values, raw_file_list, raw_scan_parameter_names, options.scan_reference_values] = recomputeODImages(options, selPath);
[full_od_imgs, full_bkg_imgs, raw_scan_parameter_values, raw_file_list, raw_scan_parameter_names, scan_reference_values] = recomputeODImages(options, selPath);
if ~options.SAVE_TO_WORKSPACE
% --- Determine parent folder for FullODImages ---
if isfield(options, 'FullODImagesFolder') && ...
@ -186,7 +186,7 @@ function [od_imgs, scan_parameter_values, file_list] = collectODImages(options)
else
% --- No selected path: either force recompute or search among fullodimage_folders ---
if isfield(options,'skipFullODImagesFolderUse') && options.skipFullODImagesFolderUse
[full_od_imgs, full_bkg_imgs, raw_scan_parameter_values, raw_file_list, raw_scan_parameter_names, options.scan_reference_values] = recomputeODImages(options, options.baseDataFolder);
[full_od_imgs, full_bkg_imgs, raw_scan_parameter_values, raw_file_list, raw_scan_parameter_names, scan_reference_values] = recomputeODImages(options, options.baseDataFolder);
if ~options.SAVE_TO_WORKSPACE
% --- Determine parent folder for FullODImages ---
if isfield(options, 'FullODImagesFolder') && ...
@ -234,7 +234,7 @@ function [od_imgs, scan_parameter_values, file_list] = collectODImages(options)
elseif isfolder(full_od_image_parent_folder) && useFullODFolders
fprintf('\n[INFO] No matching full OD images subfolder found. Will recompute from raw data.\n');
end
[full_od_imgs, full_bkg_imgs, raw_scan_parameter_values, raw_file_list, raw_scan_parameter_names, options.scan_reference_values] = recomputeODImages(options, options.baseDataFolder);
[full_od_imgs, full_bkg_imgs, raw_scan_parameter_values, raw_file_list, raw_scan_parameter_names, scan_reference_values] = recomputeODImages(options, options.baseDataFolder);
if ~options.SAVE_TO_WORKSPACE
% --- Determine parent folder for FullODImages ---
if isfield(options, 'FullODImagesFolder') && ...
@ -360,11 +360,11 @@ function [od_imgs, scan_parameter_values, file_list] = collectODImages(options)
end
if isvector(scan_reference_values)
[scan_reference_values, ~] = sort(scan_reference_values, sort_order);
[scan_reference_values, ~] = sort(scan_reference_values, sort_order);
else
scan_reference_values = sortrows(scan_reference_values, sort_order);
scan_reference_values = sortrows(scan_reference_values, sort_order);
end
% --- Reorder images according to scan reference values ---
n_reps = n_total / n_values;
tol = 1e-6; % tolerance for floating-point comparisons
@ -426,18 +426,19 @@ function [od_imgs, scan_parameter_values, file_list] = collectODImages(options)
% Decide single vs multiple parameter output
if numel(unique_names) == 1
options.scan_parameter = unique_names{1}; % single char array
scan_parameter_names = options.scan_parameter;
scan_parameter_names = unique_names{1}; % single char array
else
options.scan_parameter = unique_names; % cell array of char arrays
scan_parameter_names = options.scan_parameter;
scan_parameter_names = unique_names; % cell array of char arrays
end
else
scan_parameter_names = options.scan_parameter;
end
% --- Save processed dataset and options to workspace ---
assignin('base', 'od_imgs', od_imgs);
assignin('base', 'scan_parameter_names', scan_parameter_names);
assignin('base', 'scan_parameter_values', scan_parameter_values);
assignin('base', 'scan_reference_values', scan_reference_values);
assignin('base', 'file_list', file_list);
assignin('base', 'prior_options', options);

View File

@ -81,7 +81,7 @@ function plotCumulants(scan_vals, cumulant_data, varargin)
% --- Super title ---
if ~isempty(opts.Title)
sgtitle(opts.Title, 'FontWeight', 'bold', 'FontSize', titleFontSize, 'Interpreter', 'latex');
sgtitle(opts.Title, 'FontName', opts.FontName, 'FontWeight', 'bold', 'FontSize', titleFontSize);
end
% --- Save figure ---

View File

@ -1,4 +1,4 @@
function plotG2(g2_all, g2_error_all, theta_values, scan_parameter_values, scan_parameter, varargin)
function plotG2(g2_all, g2_error_all, theta_values, scan_parameter_values, scan_parameter_units, varargin)
%% plotG2: Plots g2 angular correlations with optional parameters
%
% Usage:
@ -24,6 +24,19 @@ function plotG2(g2_all, g2_error_all, theta_values, scan_parameter_values, scan_
opts = p.Results;
nParams = size(g2_all, 1);
% Determine unit suffix and interpreter
switch lower(scan_parameter_units)
case {'degrees', 'deg', '°'}
unitSuffix = '^\circ'; % LaTeX degree symbol
txtInterpreter = 'tex';
case {'gauss', 'g'}
unitSuffix = ' G';
txtInterpreter = 'none';
otherwise
unitSuffix = '';
txtInterpreter = 'none';
end
% --- Create figure ---
if isempty(opts.FigNum)
@ -37,28 +50,22 @@ function plotG2(g2_all, g2_error_all, theta_values, scan_parameter_values, scan_
% --- Colormap ---
cmap = opts.Colormap(nParams);
% --- Plot data with errorbars ---
legend_entries = cell(nParams, 1);
for i = 1:nParams
errorbar(theta_values/pi, g2_all(i,:), g2_error_all(i,:), ...
'o', 'Color', cmap(i,:), 'MarkerSize', 4, 'MarkerFaceColor', cmap(i,:), 'CapSize', 4);
switch scan_parameter
case 'ps_rot_mag_fin_pol_angle'
legend_entries{i} = sprintf('$\\alpha = %g^\\circ$', scan_parameter_values(i));
case 'rot_mag_field'
legend_entries{i} = sprintf('B = %.2f G', scan_parameter_values(i));
otherwise
legend_entries{i} = sprintf('%g', scan_parameter_values(i));
end
% Update overlay text with scan parameter + unit
legend_entries{i} = sprintf('%.2f%s', scan_parameter_values(i), unitSuffix);
end
% --- Formatting ---
xlabel(opts.XLabel, 'Interpreter', 'latex', 'FontName', opts.FontName, 'FontSize', opts.FontSize);
ylabel(opts.YLabel, 'Interpreter', 'latex', 'FontName', opts.FontName, 'FontSize', opts.FontSize);
title(opts.Title, 'Interpreter', 'latex', 'FontName', opts.FontName, 'FontSize', opts.FontSize + 2);
legend(legend_entries, 'Interpreter', 'latex', 'Location', 'bestoutside');
title(opts.Title, 'FontName', opts.FontName, 'FontName', opts.FontName, 'FontSize', opts.FontSize + 2);
legend(legend_entries, 'Interpreter', txtInterpreter, 'Location', 'bestoutside');
set(gca, 'FontName', opts.FontName, 'FontSize', opts.FontSize);
ylim(opts.YLim);
grid on;

View File

@ -0,0 +1,71 @@
function plotG2Cumulants(results, varargin)
%% plotG2Cumulants: Plot first four cumulants of g²(θ) vs scan parameter
% --- Parse name-value pairs ---
p = inputParser;
addParameter(p, 'Title', 'g² Cumulants', @(x) ischar(x) || isstring(x));
addParameter(p, 'XLabel', 'Scan Parameter', @(x) ischar(x) || isstring(x));
addParameter(p, 'FontName', 'Arial', @ischar);
addParameter(p, 'FontSize', 14, @isnumeric);
addParameter(p, 'FigNum', [], @(x) isempty(x) || (isnumeric(x) && isscalar(x)));
addParameter(p, 'SkipSaveFigures', false, @islogical);
addParameter(p, 'SaveFileName', 'G2Cumulants.fig', @ischar);
addParameter(p, 'SaveDirectory', pwd, @ischar);
parse(p, varargin{:});
opts = p.Results;
% --- Extract cumulant data from full distribution ---
N_params = numel(results.g2_cumulants);
N_theta = size(results.g2_cumulants{1},1);
xvals = results.summaries.scanParamVal;
kappa = zeros(N_theta, N_params, 4); % θ × scan × cumulant
for i = 1:N_params
cumul_mat = results.g2_cumulants{i}; % [N_theta × 4]
kappa(:,i,:) = cumul_mat;
end
% --- Select specific theta indices: 0, pi/6, pi/3, pi/2, 2*pi/3, pi ---
thetaVals = results.theta_values; % assume radians
desiredTheta = [pi/12 pi/6 pi/3 pi/2 2*pi/3 5*pi/6];
[~, thIdx] = arrayfun(@(t) min(abs(thetaVals - t)), desiredTheta);
% --- Legend labels ---
thetaLabels = {'\pi/12','\pi/6','\pi/3','\pi/2','2\pi/3','5\pi/6'};
% --- Colormap (sky) ---
cmap = Colormaps.coolwarm(numel(thIdx));
% --- Create figure ---
if isempty(opts.FigNum), fig = figure; else, fig = figure(opts.FigNum); end
clf(fig);
set(fig,'Color','w','Position',[100 100 950 750]);
t = tiledlayout(2,2,'TileSpacing','Compact','Padding','Compact');
title(t, opts.Title, 'FontName', opts.FontName, 'FontSize', opts.FontSize+4);
cumulLabels = {'\kappa_1','\kappa_2','\kappa_3','\kappa_4'};
cumulTitles = {'Mean','Variance','Skewness','Binder Cumulant'};
for k = 1:4
ax = nexttile; hold(ax,'on');
for idx = 1:numel(thIdx)
th = thIdx(idx);
plot(ax, xvals, squeeze(kappa(th,:,k)), '-o', ...
'Color', cmap(idx,:), 'LineWidth', 2, 'MarkerSize', 8, 'MarkerFaceColor', cmap(idx,:));
end
ylabel(ax, cumulLabels{k}, 'FontName', opts.FontName, 'FontSize', opts.FontSize);
xlabel(ax, opts.XLabel, 'FontName', opts.FontName, 'FontSize', opts.FontSize);
title(ax, cumulTitles{k}, 'FontName', opts.FontName, 'FontSize', opts.FontSize+2);
grid(ax,'on'); set(ax,'FontName',opts.FontName,'FontSize',opts.FontSize);
% --- Add legend ---
legend(ax, thetaLabels, 'Location', 'best', 'FontSize', opts.FontSize-2);
end
% --- Save figure ---
if ~opts.SkipSaveFigures
if ~exist(opts.SaveDirectory,'dir'), mkdir(opts.SaveDirectory); end
savefig(fig, fullfile(opts.SaveDirectory, opts.SaveFileName));
end
end

View File

@ -0,0 +1,94 @@
function plotG2Curves(results, varargin)
%% plotG2Curves: Plot raw g²(θ) curves with mean, SEM, and highlights
%
% Usage:
% plotG2Curves(results, ...
% 'Title','g² Curves','XLabel','\theta / \pi','YLabel','g^2(\theta)', ...
% 'FontName','Arial','FontSize',14,'FigNum',1,'TileTitlePrefix','Control Parameter', ...
% 'TileTitleSuffix','°','HighlightEvery',10,'SkipSaveFigures',false, ...
% 'SaveFileName','G2Curves.fig','SaveDirectory','results');
%
% Inputs:
% results - struct with fields:
% g2_curves - cell array of [N_reps × Nθ] matrices
% theta_values - vector of theta values (radians)
% g2_mean - [N_params × Nθ] mean
% g2_error - [N_params × Nθ] SEM
% scan_parameter_values- vector of scan parameters
% --- Parse name-value pairs ---
p = inputParser;
addParameter(p, 'Title', 'g² Curves', @(x) ischar(x) || isstring(x));
addParameter(p, 'XLabel', '\theta / \pi', @(x) ischar(x) || isstring(x));
addParameter(p, 'YLabel', 'g^2(\theta)', @(x) ischar(x) || isstring(x));
addParameter(p, 'FontName', 'Arial', @ischar);
addParameter(p, 'FontSize', 14, @isnumeric);
addParameter(p, 'FigNum', [], @(x) isempty(x) || (isnumeric(x) && isscalar(x)));
addParameter(p, 'SkipSaveFigures', false, @islogical);
addParameter(p, 'SaveFileName', 'G2Curves.fig', @ischar);
addParameter(p, 'SaveDirectory', pwd, @ischar);
addParameter(p, 'TileTitlePrefix', 'Control Parameter', @(x) ischar(x) || isstring(x));
addParameter(p, 'TileTitleSuffix', '', @(x) ischar(x) || isstring(x)); % NEW
addParameter(p, 'HighlightEvery', 10, @(x) isnumeric(x) && isscalar(x) && x>=1);
parse(p, varargin{:});
opts = p.Results;
% --- Extract data ---
N_params = numel(results.g2_curves);
theta = results.theta_values / pi;
g2_mean = results.g2_mean;
g2_err = results.g2_error;
Nhighlight = opts.HighlightEvery;
% --- Create figure ---
if isempty(opts.FigNum), fig = figure; else, fig = figure(opts.FigNum); end
clf(fig);
set(fig,'Color','w','Position',[100 100 1000 800]);
t = tiledlayout('TileSpacing','compact','Padding','compact');
title(t, opts.Title, 'FontName', opts.FontName, 'FontSize', opts.FontSize+2);
% --- Loop over scan parameters ---
for i = 1:N_params
ax = nexttile; hold(ax,'on');
G = results.g2_curves{i}; % [N_reps × Nθ]
% --- Plot all repetitions in light grey ---
plot(ax, theta, G', 'Color', [0.7 0.7 0.7, 0.5]);
% --- Highlight every Nth curve ---
idx = Nhighlight:Nhighlight:size(G,1);
for j = idx
plot(ax, theta, G(j,:), 'Color', [0.3 0.3 0.3, 1], 'LineWidth', 1.5);
end
% --- Mean + SEM shading ---
mu = g2_mean(i,:);
se = g2_err(i,:);
fill(ax, [theta fliplr(theta)], [mu-se fliplr(mu+se)], ...
[0.2 0.4 0.8], 'FaceAlpha',0.2, 'EdgeColor','none');
% --- Mean curve ---
plot(ax, theta, mu, 'b-', 'LineWidth', 2);
% --- Vertical reference lines at pi/3 and 2pi/3 ---
xlines = [1/3 2/3];
for xl = xlines
xline(ax, xl, 'k--', 'LineWidth', 1.5, 'Alpha', 0.5);
end
% --- Axes formatting ---
grid(ax,'on');
xlabel(ax, opts.XLabel, 'FontName', opts.FontName, 'FontSize', opts.FontSize);
ylabel(ax, opts.YLabel, 'FontName', opts.FontName, 'FontSize', opts.FontSize);
title(ax, sprintf('%s=%.3g%s', opts.TileTitlePrefix, results.scan_parameter_values(i), opts.TileTitleSuffix), ...
'FontName', opts.FontName, 'FontSize', opts.FontSize);
set(ax, 'FontName', opts.FontName, 'FontSize', opts.FontSize);
end
% --- Save figure ---
if ~opts.SkipSaveFigures
if ~exist(opts.SaveDirectory,'dir'), mkdir(opts.SaveDirectory); end
savefig(fig, fullfile(opts.SaveDirectory, opts.SaveFileName));
end
end

View File

@ -0,0 +1,82 @@
function plotG2Features(results, varargin)
%% plotG2Features: Plot Fourier amplitudes, contrast, and symmetry fractions
%
% Usage:
% plotG2Features(results, 'Title','Analysis Results','XLabel','Scan Parameter', ...)
% --- Parse name-value pairs ---
p = inputParser;
addParameter(p, 'Title', 'Analysis Results', @(x) ischar(x) || isstring(x));
addParameter(p, 'XLabel', 'Scan Parameter', @(x) ischar(x) || isstring(x));
addParameter(p, 'FontName', 'Arial', @ischar);
addParameter(p, 'FontSize', 14, @isnumeric);
addParameter(p, 'FigNum', [], @(x) isempty(x) || (isnumeric(x) && isscalar(x)));
addParameter(p, 'SkipSaveFigures', false, @islogical);
addParameter(p, 'SaveFileName', 'AllFeatures.fig', @ischar);
addParameter(p, 'SaveDirectory', pwd, @ischar);
parse(p, varargin{:});
opts = p.Results;
T = results.summaries;
x = T.scanParamVal;
% --- Extract Fourier amplitudes, contrast, symmetry fractions ---
A2m = T.mean_A2; A2e = T.Fun_A2;
A4m = T.mean_A4; A4e = T.Fun_A4;
A6m = T.mean_A6; A6e = T.Fun_A6;
Nrm = T.mean_Contrast; Nrme = T.Fun_Contrast;
S2m = T.mean_S2; S2e = T.Fun_S2;
Q4m = T.mean_Q4; Q4e = T.Fun_Q4;
H6m = T.mean_H6; H6e = T.Fun_H6;
% --- Color palette: same color for each symmetry type ---
colors = [...
0.8500 0.3250 0.0980; % Stripe (red/orange) -> A2/S2
0.0000 0.4470 0.7410; % Square (blue) -> A4/Q4
0.4660 0.6740 0.1880]; % Hexatic (green) -> A6/H6
% --- Create figure ---
if isempty(opts.FigNum), fig = figure; else, fig = figure(opts.FigNum); end
clf(fig);
set(fig,'Color','w','Position',[100 100 950 900]);
t = tiledlayout(3,1,'TileSpacing','Compact','Padding','Compact');
t = tiledlayout(3,1,'TileSpacing','Compact','Padding','Compact');
% --- Top tile ---
ax1 = nexttile; hold on;
errorbar(x, A2m, A2e,'-o','LineWidth',1.5,'Color',colors(1,:),'MarkerFaceColor',colors(1,:));
errorbar(x, A4m, A4e,'-s','LineWidth',1.5,'Color',colors(2,:),'MarkerFaceColor',colors(2,:));
errorbar(x, A6m, A6e,'-^','LineWidth',1.5,'Color',colors(3,:),'MarkerFaceColor',colors(3,:));
ylabel(ax1,'Amplitude','FontName',opts.FontName,'FontSize',opts.FontSize);
title(ax1,'Harmonic Amplitudes','FontName',opts.FontName,'FontSize',opts.FontSize+2);
legend(ax1,'|A2|','|A4|','|A6|','Location','best'); grid(ax1,'on');
set(ax1,'FontName',opts.FontName,'FontSize',opts.FontSize);
% --- Middle tile ---
ax2 = nexttile; hold on;
errorbar(x, S2m, S2e,'-o','LineWidth',1.5,'Color',colors(1,:),'MarkerFaceColor',colors(1,:));
errorbar(x, Q4m, Q4e,'-s','LineWidth',1.5,'Color',colors(2,:),'MarkerFaceColor',colors(2,:));
errorbar(x, H6m, H6e,'-^','LineWidth',1.5,'Color',colors(3,:),'MarkerFaceColor',colors(3,:));
ylabel(ax2,'Symmetry Fraction','FontName',opts.FontName,'FontSize',opts.FontSize);
ylim(ax2,[0 1]); grid(ax2,'on');
title(ax2,'Symmetry Fractions','FontName',opts.FontName,'FontSize',opts.FontSize+2);
legend(ax2,'S2','Q4','H6','Location','best');
set(ax2,'FontName',opts.FontName,'FontSize',opts.FontSize);
% --- Bottom tile ---
ax3 = nexttile; hold on;
errorbar(x, Nrm, Nrme,'-d','LineWidth',1.5,'Color',[0.6 0.2 0.8],'MarkerFaceColor',[0.6 0.2 0.8]);
ylabel(ax3,'Contrast (RMS)','FontName',opts.FontName,'FontSize',opts.FontSize);
title(ax3,'g^2 Curve Contrast','FontName',opts.FontName,'FontSize',opts.FontSize+2);
grid(ax3,'on'); set(ax3,'FontName',opts.FontName,'FontSize',opts.FontSize);
% --- Global x-label ---
xlabel(t,opts.XLabel,'FontName',opts.FontName,'FontSize',opts.FontSize);
%% --- Save figure ---
if ~opts.SkipSaveFigures
if ~exist(opts.SaveDirectory,'dir'), mkdir(opts.SaveDirectory); end
savefig(fig, fullfile(opts.SaveDirectory, opts.SaveFileName));
end
end

View File

@ -28,7 +28,11 @@ function plotMeanWithSE(scan_values, data_values, varargin)
mean_vals = zeros(size(unique_vals));
stderr_vals = zeros(size(unique_vals));
for i = 1:length(unique_vals)
group = data_values(idx == i);
if iscell(data_values)
group = data_values{idx == i};
else
group = data_values(idx == i);
end
if iscell(group)
groupVals = [group{:}];
else
@ -58,7 +62,7 @@ function plotMeanWithSE(scan_values, data_values, varargin)
end
xlabel(opts.XLabel, 'Interpreter', 'latex', 'FontName', opts.FontName, 'FontSize', opts.FontSize);
ylabel(opts.YLabel, 'Interpreter', 'latex', 'FontName', opts.FontName, 'FontSize', opts.FontSize);
title(opts.Title, 'Interpreter', 'latex', 'FontSize', opts.FontSize + 2, 'FontWeight', 'bold');
title(opts.Title, 'FontName', opts.FontName, 'FontSize', opts.FontSize + 2, 'FontWeight', 'bold');
grid on;
% --- Save figure ---

View File

@ -50,6 +50,7 @@ function plotPCAResults(pcaResults, scan_parameter_values, scan_reference_values
imagesc(pc1_image); axis image off; colormap(opts.Colormap()); colorbar;
title(sprintf('First Principal Component (PC1) Image - Explains %.2f%% Variance', explained(1)), ...
'FontName', opts.FontName, 'FontSize', opts.FontSize + 2);
set(gca, 'FontName', opts.FontName, 'FontSize', opts.FontSize);
if ~opts.SkipSaveFigures
Plotter.saveFigure(fig, 'SaveFileName', 'PC1_Image.fig', 'SaveDirectory', opts.SaveDirectory);
end
@ -70,7 +71,7 @@ function plotPCAResults(pcaResults, scan_parameter_values, scan_reference_values
ylabel('PC1 Score', 'FontName', opts.FontName, 'FontSize', opts.FontSize);
title('Evolution of PC1 Scores', 'FontName', opts.FontName, 'FontSize', opts.FontSize + 2);
grid on;
set(gca,'XDir','reverse'); % Ensure decreasing scan_reference_values go left-to-right
set(gca, 'FontName', opts.FontName, 'FontSize', opts.FontSize);
if ~opts.SkipSaveFigures
Plotter.saveFigure(fig, 'SaveFileName', 'PC1_Scatter.fig', 'SaveDirectory', opts.SaveDirectory);
end
@ -100,12 +101,13 @@ function plotPCAResults(pcaResults, scan_parameter_values, scan_reference_values
plot(xi, f, 'Color', colors(g,:), 'LineWidth', 2);
yl = ylim;
plot([median(data) median(data)], yl, 'k--', 'LineWidth', 1);
xlabel('PC1 Score');
ylabel('Probability');
title(sprintf('Control = %g', unique_scan_param_vals(g)));
xlabel('PC1 Score', 'FontName', opts.FontName, 'FontSize', opts.FontSize);
ylabel('Probability', 'FontName', opts.FontName, 'FontSize', opts.FontSize);
title(sprintf('Control = %g', unique_scan_param_vals(g)), 'FontName', opts.FontName, 'FontSize', opts.FontSize);
grid on;
end
sgtitle('PC1 Score Distributions');
sgtitle('PC1 Score Distributions', 'FontName', opts.FontName, 'FontSize', opts.FontSize + 2);
set(gca, 'FontName', opts.FontName, 'FontSize', opts.FontSize);
if ~opts.SkipSaveFigures
Plotter.saveFigure(fig, 'SaveFileName', 'PC1_Distributions.fig', 'SaveDirectory', opts.SaveDirectory);
end
@ -134,7 +136,7 @@ function plotPCAResults(pcaResults, scan_parameter_values, scan_reference_values
ylabel('PC1 Score', 'FontName', opts.FontName, 'FontSize', opts.FontSize);
title('PC1 Score Boxplots by Group', 'FontName', opts.FontName, 'FontSize', opts.FontSize + 2);
grid on;
set(gca, 'FontName', opts.FontName, 'FontSize', opts.FontSize);
if ~opts.SkipSaveFigures
Plotter.saveFigure(fig, 'SaveFileName', 'PC1_Boxplot.fig', 'SaveDirectory', opts.SaveDirectory);
end
@ -155,7 +157,7 @@ function plotPCAResults(pcaResults, scan_parameter_values, scan_reference_values
ylabel('Mean PC1 Score ± SEM', 'FontName', opts.FontName, 'FontSize', opts.FontSize);
title('Mean ± SEM of PC1 Scores', 'FontName', opts.FontName, 'FontSize', opts.FontSize + 2);
grid on;
set(gca,'XDir','reverse'); % consistent ordering
set(gca, 'FontName', opts.FontName, 'FontSize', opts.FontSize);
if ~opts.SkipSaveFigures
Plotter.saveFigure(fig, 'SaveFileName', 'PC1_MeanSEM.fig', 'SaveDirectory', opts.SaveDirectory);
end
@ -177,7 +179,7 @@ function plotPCAResults(pcaResults, scan_parameter_values, scan_reference_values
ylabel('\kappa (\times 10^5)', 'FontName', opts.FontName, 'FontSize', opts.FontSize);
title('Binder Cumulant of PC1 Scores', 'FontName', opts.FontName, 'FontSize', opts.FontSize + 2);
grid on;
set(gca,'XDir','reverse'); % consistent ordering
set(gca, 'FontName', opts.FontName, 'FontSize', opts.FontSize);
if ~opts.SkipSaveFigures
Plotter.saveFigure(fig, 'SaveFileName', 'PC1_BinderCumulant.fig', 'SaveDirectory', opts.SaveDirectory);
end

View File

@ -93,16 +93,16 @@ function plotPDF(dataCell, referenceValues, varargin)
set(gca, 'YDir', 'normal', 'FontName', opts.FontName, 'FontSize', opts.FontSize);
xlabel(opts.XLabel, 'Interpreter', 'latex', 'FontSize', opts.FontSize, 'FontName', opts.FontName);
ylabel(opts.YLabel, 'Interpreter', 'latex', 'FontSize', opts.FontSize, 'FontName', opts.FontName);
title(opts.Title, 'Interpreter', 'latex', 'FontSize', opts.FontSize + 2, 'FontWeight', 'bold');
title(opts.Title, 'FontName', opts.FontName, 'FontSize', opts.FontSize + 2, 'FontWeight', 'bold');
colormap(feval(opts.Colormap));
c = colorbar;
if strcmpi(opts.PlotType,'kde')
ylabel(c, 'PDF', 'Interpreter', 'latex', 'FontSize', opts.FontSize);
ylabel(c, 'PDF', 'FontName', opts.FontName, 'FontSize', opts.FontSize);
else
if opts.NormalizeHistogram
ylabel(c, 'Probability Density', 'Interpreter', 'latex', 'FontSize', opts.FontSize);
ylabel(c, 'Probability Density', 'FontName', opts.FontName, 'FontSize', opts.FontSize);
else
ylabel(c, 'Counts', 'Interpreter', 'latex', 'FontSize', opts.FontSize);
ylabel(c, 'Counts', 'FontName', opts.FontName, 'FontSize', opts.FontSize);
end
end

View File

@ -18,7 +18,7 @@ scan_parameter_values = datasetStruct.scan_parameter_values;
% Load the original options used during analysis
options = datasetStruct.options; % exact options used for this dataset
options.font = 'Bahnscrift'; % override if needed
options.font = 'Bahnschrift'; % override if needed
options.skipSaveFigures = false; % override if needed
%% ------------------ Create dataset-specific figure folder ------------------
@ -51,7 +51,7 @@ Plotter.plotMeanWithSE(scan_parameter_values, compiled_results.spectral_analysis
'SkipSaveFigures', options.skipSaveFigures);
% Plot Peak Offset Angular Correlation
Plotter.plotMeanWithSE(options.scan_reference_values, compiled_results.custom_g_results.max_g2_all_per_scan_parameter_value, ...
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)]$', ...
@ -63,11 +63,11 @@ Plotter.plotMeanWithSE(options.scan_reference_values, compiled_results.custom_g_
'SkipSaveFigures', options.skipSaveFigures);
%% ------------------ 2. g²(θ) across transition ------------------
Plotter.plotG2(compiled_results.full_g2_results.g2_all, ...
compiled_results.full_g2_results.g2_error_all, ...
Plotter.plotG2(compiled_results.full_g2_results.g2_mean, ...
compiled_results.full_g2_results.g2_error, ...
compiled_results.full_g2_results.theta_values, ...
options.scan_reference_values, ...
'rot_mag_field', ...
scan_reference_values, ...
options.scanParameterUnits, ...
'Title', options.titleString, ...
'XLabel', '$\delta\theta / \pi$', ...
'YLabel', '$g^{(2)}(\delta\theta)$', ...
@ -77,14 +77,51 @@ Plotter.plotG2(compiled_results.full_g2_results.g2_all, ...
'SaveFileName', 'G2ThetaAcrossTransition.fig', ...
'SaveDirectory', figSaveDir, ...
'Colormap', @Colormaps.coolwarm);
%% ------------------ 3. Feature extraction of g²(θ) across transition ------------------
%% ------------------ 3. PDF of max g² across transition ------------------
Plotter.plotG2Curves(compiled_results.full_g2_results, ...
'Title', options.titleString, ...
'XLabel', '\theta / \pi', ...
'YLabel', 'g^{(2)}(\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);
%
g2_analysis_results = Analyzer.analyzeAutocorrelation(compiled_results.full_g2_results);
%
Plotter.plotG2Features(g2_analysis_results, ...
'Title', options.titleString, ...
'XLabel', '\alpha (deg)', ...
'FontName', options.font, ...
'FigNum', 6, ...
'SkipSaveFigures', options.skipSaveFigures, ...
'SaveFileName', 'G2Features.fig', ...
'SaveDirectory', figSaveDir);
%
Plotter.plotG2Cumulants(g2_analysis_results, ...
'Title', options.titleString, ...
'XLabel', '\alpha (deg)', ...
'FontName', options.font, ...
'FigNum', 7, ...
'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, ...
options.scan_reference_values, ...
scan_reference_values, ...
'Title', options.titleString, ...
'XLabel', 'B (G)', ...
'YLabel', '$\mathrm{max}[g^{(2)}]$', ...
'FigNum', 5, ...
'FigNum', 8, ...
'FontName', options.font, ...
'SkipSaveFigures', options.skipSaveFigures, ...
'SaveFileName', 'PDF_MaxG2AcrossTransition.fig', ...
@ -93,15 +130,15 @@ Plotter.plotPDF(compiled_results.custom_g_results.max_g2_all_per_scan_parameter_
'NormalizeHistogram', true, ...
'DataRange', [0 1.5], ...
'Colormap', @Colormaps.coolwarm, ...
'XLim', [min(options.scan_reference_values) max(options.scan_reference_values)]);
'XLim', [min(scan_reference_values) max(scan_reference_values)]);
%% ------------------ 4. Cumulants across transition ------------------
Plotter.plotCumulants(options.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', 'B (G)', ...
'FigNum', 6, ...
'FigNum', 9, ...
'FontName', options.font, ...
'MarkerSize', 6, ...
'LineWidth', 1.5, ...
@ -109,13 +146,15 @@ Plotter.plotCumulants(options.scan_reference_values, ...
'SaveFileName', 'CumulantOfPeakOffsetAngularCorrelation.fig', ...
'SaveDirectory', figSaveDir);
%% ------------------ 5. PCA ------------------
Plotter.plotPCAResults(compiled_results.pca_results, scan_parameter_values, options.scan_reference_values, ...
'FigNumRange', [7,8,9,10,11,12], ...
%% ------------------ 6. PCA ------------------
Plotter.plotPCAResults(compiled_results.pca_results, scan_parameter_values, scan_reference_values, ...
'FigNumRange', [10,11,12,13,14,15], ...
'FontName', options.font, ...
'SkipSaveFigures', options.skipSaveFigures, ...
'SaveDirectory', figSaveDir);
%%
%{
@ -176,7 +215,7 @@ compareMultipleDatasets(scanValsCell, meanValsCell, stderrValsCell, ...
BFields = [2.35, 2.15, 2.0, 1.85, 1.7, 1.55, 1.4, 1.35];
% Heatmap of mean_max_g2_values
Plotter.plotHeatmap(compiled_results, options.scan_groups, BFields, 'mean_max_g2_values', ...
Plotter.plotHeatmap(compiled_results, scan_reference_values, BFields, 'mean_max_g2_values', ...
'Colormap', @sky, ...
'CLim', [0 1], ...
'XLabel', '\alpha (degrees)', ...
@ -184,10 +223,10 @@ Plotter.plotHeatmap(compiled_results, options.scan_groups, BFields, 'mean_max_g2
'Title', '$\mathrm{max}[g^{(2)}_{[50,70]}(\delta\theta)]$', ...
'FigNum', 9, ...
'SaveFileName', 'Heatmap_MaxG2.fig', ...
'SaveDirectory', options.resultsDir);
'SaveDirectory', options.saveDirectory);
% Heatmap of radial_spectral_contrast
Plotter.plotHeatmap(compiled_results, options.scan_groups, BFields, 'radial_spectral_contrast', ...
Plotter.plotHeatmap(compiled_results, scan_reference_values, BFields, 'radial_spectral_contrast', ...
'Colormap', @sky, ...
'CLim', [0 0.008], ...
'XLabel', '\alpha (degrees)', ...
@ -195,5 +234,5 @@ Plotter.plotHeatmap(compiled_results, options.scan_groups, BFields, 'radial_spec
'Title', 'Radial Spectral Contrast', ...
'FigNum', 10, ...
'SaveFileName', 'Heatmap_RadialSpectralContrast.fig', ...
'SaveDirectory', options.resultsDir);
'SaveDirectory', options.saveDirectory);
%}

View File

@ -63,18 +63,22 @@ options.showProgressBar = true;
options.font = 'Bahnschrift';
switch options.measurementName
case 'BECToDroplets'
options.scan_parameter = 'rot_mag_field';
options.flipSortOrder = true;
options.scanParameterUnits = 'gauss';
options.titleString = 'BEC to Droplets';
case 'BECToStripes'
options.scan_parameter = 'rot_mag_field';
options.flipSortOrder = true;
options.scanParameterUnits = 'gauss';
options.titleString = 'BEC to Stripes';
case 'DropletsToStripes'
options.scan_parameter = 'ps_rot_mag_field';
options.flipSortOrder = true;
options.scanParameterUnits = 'degrees';
options.titleString = 'Droplets to Stripes';
case 'StripesToDroplets'
options.scan_parameter = 'ps_rot_mag_field';
options.flipSortOrder = false;
options.scanParameterUnits = 'degrees';
options.titleString = 'Stripes to Droplets';
@ -82,7 +86,7 @@ end
%% ===== Collect Images and Launch Viewer =====
[options.selectedPath, options.folderPath] = Helper.selectDataSourcePath(dataSources, options);
[options.selectedPath, options.folderPath] = Helper.selectDataSourcePath(dataSources, options);
[od_imgs, scan_parameter_values, file_list] = Helper.collectODImages(options);

View File

@ -3,15 +3,15 @@
% Specify data location to run analysis on
dataSources = {
struct('sequence', 'StructuralPhaseTransition', ...
'date', '2025/08/13', ...
'runs', [62]) % specify run numbers as a string in "" or just as a numeric value
'date', '2025/07/25', ...
'runs', [25]) % specify run numbers as a string in "" or just as a numeric value
};
options = struct();
% File paths
options.baseDataFolder = '//DyLabNAS/Data';
options.FullODImagesFolder = 'F:/Data - Experiment/FullODImages/202508';
options.FullODImagesFolder = 'E:/Data - Experiment/FullODImages/202507';
options.measurementName = 'BECToDroplets';
scriptFullPath = mfilename('fullpath');
options.saveDirectory = fileparts(scriptFullPath);
@ -63,18 +63,22 @@ options.showProgressBar = true;
options.font = 'Bahnschrift';
switch options.measurementName
case 'BECToDroplets'
options.scan_parameter = 'rot_mag_field';
options.flipSortOrder = true;
options.scanParameterUnits = 'gauss';
options.titleString = 'BEC to Droplets';
case 'BECToStripes'
options.scan_parameter = 'rot_mag_field';
options.flipSortOrder = true;
options.scanParameterUnits = 'gauss';
options.titleString = 'BEC to Stripes';
case 'DropletsToStripes'
options.scan_parameter = 'ps_rot_mag_field';
options.flipSortOrder = true;
options.scanParameterUnits = 'degrees';
options.titleString = 'Droplets to Stripes';
case 'StripesToDroplets'
options.scan_parameter = 'ps_rot_mag_field';
options.flipSortOrder = false;
options.scanParameterUnits = 'degrees';
options.titleString = 'Stripes to Droplets';

View File

@ -1,5 +1,5 @@
% --- User chooses which dataset to load ---
datasetIdx = 6; % <-- change this to 1, 2, 3, ...
datasetIdx = 1; % <-- change this to 1, 2, 3, ...
datasetName = sprintf('Dataset_%d', datasetIdx);
% Detect the folder where this script is located and set that as the Base Directory
@ -18,7 +18,7 @@ scan_parameter_values = datasetStruct.scan_parameter_values;
% Load the original options used during analysis
options = datasetStruct.options; % exact options used for this dataset
options.font = 'Bahnscrift'; % override if needed
options.font = 'Bahnschrift'; % override if needed
options.skipSaveFigures = false; % override if needed
%% ------------------ Create dataset-specific figure folder ------------------
@ -51,7 +51,7 @@ Plotter.plotMeanWithSE(scan_parameter_values, compiled_results.spectral_analysis
'SkipSaveFigures', options.skipSaveFigures);
% Plot Peak Offset Angular Correlation
Plotter.plotMeanWithSE(options.scan_reference_values, compiled_results.custom_g_results.max_g2_all_per_scan_parameter_value, ...
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)]$', ...
@ -63,11 +63,11 @@ Plotter.plotMeanWithSE(options.scan_reference_values, compiled_results.custom_g_
'SkipSaveFigures', options.skipSaveFigures);
%% ------------------ 2. g²(θ) across transition ------------------
Plotter.plotG2(compiled_results.full_g2_results.g2_all, ...
compiled_results.full_g2_results.g2_error_all, ...
Plotter.plotG2(compiled_results.full_g2_results.g2_mean, ...
compiled_results.full_g2_results.g2_error, ...
compiled_results.full_g2_results.theta_values, ...
options.scan_reference_values, ...
'rot_mag_field', ...
scan_reference_values, ...
options.scanParameterUnits, ...
'Title', options.titleString, ...
'XLabel', '$\delta\theta / \pi$', ...
'YLabel', '$g^{(2)}(\delta\theta)$', ...
@ -77,14 +77,51 @@ Plotter.plotG2(compiled_results.full_g2_results.g2_all, ...
'SaveFileName', 'G2ThetaAcrossTransition.fig', ...
'SaveDirectory', figSaveDir, ...
'Colormap', @Colormaps.coolwarm);
%% ------------------ 3. Feature extraction of g²(θ) across transition ------------------
%% ------------------ 3. PDF of max g² across transition ------------------
Plotter.plotG2Curves(compiled_results.full_g2_results, ...
'Title', options.titleString, ...
'XLabel', '\theta / \pi', ...
'YLabel', 'g^{(2)}(\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);
%
g2_analysis_results = Analyzer.analyzeAutocorrelation(compiled_results.full_g2_results);
%
Plotter.plotG2Features(g2_analysis_results, ...
'Title', options.titleString, ...
'XLabel', '\alpha (deg)', ...
'FontName', options.font, ...
'FigNum', 6, ...
'SkipSaveFigures', options.skipSaveFigures, ...
'SaveFileName', 'G2Features.fig', ...
'SaveDirectory', figSaveDir);
%
Plotter.plotG2Cumulants(g2_analysis_results, ...
'Title', options.titleString, ...
'XLabel', '\alpha (deg)', ...
'FontName', options.font, ...
'FigNum', 7, ...
'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, ...
options.scan_reference_values, ...
scan_reference_values, ...
'Title', options.titleString, ...
'XLabel', 'B (G)', ...
'YLabel', '$\mathrm{max}[g^{(2)}]$', ...
'FigNum', 5, ...
'FigNum', 8, ...
'FontName', options.font, ...
'SkipSaveFigures', options.skipSaveFigures, ...
'SaveFileName', 'PDF_MaxG2AcrossTransition.fig', ...
@ -93,14 +130,15 @@ Plotter.plotPDF(compiled_results.custom_g_results.max_g2_all_per_scan_parameter_
'NormalizeHistogram', true, ...
'DataRange', [0 1.5], ...
'Colormap', @Colormaps.coolwarm, ...
'XLim', [min(options.scan_reference_values) max(options.scan_reference_values)]);
'XLim', [min(scan_reference_values) max(scan_reference_values)]);
%% ------------------ 4. Cumulants across transition ------------------
Plotter.plotCumulants(options.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', 'B (G)', ...
'FigNum', 6, ...
'FigNum', 9, ...
'FontName', options.font, ...
'MarkerSize', 6, ...
'LineWidth', 1.5, ...
@ -108,13 +146,16 @@ Plotter.plotCumulants(options.scan_reference_values, ...
'SaveFileName', 'CumulantOfPeakOffsetAngularCorrelation.fig', ...
'SaveDirectory', figSaveDir);
%% ------------------ 5. PCA ------------------
Plotter.plotPCAResults(compiled_results.pca_results, scan_parameter_values, options.scan_reference_values, ...
'FigNumRange', [7,8,9,10,11,12], ...
%% ------------------ 6. PCA ------------------
Plotter.plotPCAResults(compiled_results.pca_results, scan_parameter_values, scan_reference_values, ...
'FigNumRange', [10,11,12,13,14,15], ...
'FontName', options.font, ...
'SkipSaveFigures', options.skipSaveFigures, ...
'SaveDirectory', figSaveDir);
%%
%{
%% ------------------ 6. Average of Spectra Plots ------------------
@ -174,7 +215,7 @@ compareMultipleDatasets(scanValsCell, meanValsCell, stderrValsCell, ...
BFields = [2.35, 2.15, 2.0, 1.85, 1.7, 1.55, 1.4, 1.35];
% Heatmap of mean_max_g2_values
Plotter.plotHeatmap(compiled_results, options.scan_groups, BFields, 'mean_max_g2_values', ...
Plotter.plotHeatmap(compiled_results, scan_reference_values, BFields, 'mean_max_g2_values', ...
'Colormap', @sky, ...
'CLim', [0 1], ...
'XLabel', '\alpha (degrees)', ...
@ -182,10 +223,10 @@ Plotter.plotHeatmap(compiled_results, options.scan_groups, BFields, 'mean_max_g2
'Title', '$\mathrm{max}[g^{(2)}_{[50,70]}(\delta\theta)]$', ...
'FigNum', 9, ...
'SaveFileName', 'Heatmap_MaxG2.fig', ...
'SaveDirectory', options.resultsDir);
'SaveDirectory', options.saveDirectory);
% Heatmap of radial_spectral_contrast
Plotter.plotHeatmap(compiled_results, options.scan_groups, BFields, 'radial_spectral_contrast', ...
Plotter.plotHeatmap(compiled_results, scan_reference_values, BFields, 'radial_spectral_contrast', ...
'Colormap', @sky, ...
'CLim', [0 0.008], ...
'XLabel', '\alpha (degrees)', ...
@ -193,5 +234,5 @@ Plotter.plotHeatmap(compiled_results, options.scan_groups, BFields, 'radial_spec
'Title', 'Radial Spectral Contrast', ...
'FigNum', 10, ...
'SaveFileName', 'Heatmap_RadialSpectralContrast.fig', ...
'SaveDirectory', options.resultsDir);
'SaveDirectory', options.saveDirectory);
%}

View File

@ -11,7 +11,7 @@ options = struct();
% File paths
options.baseDataFolder = '//DyLabNAS/Data';
options.FullODImagesFolder = 'F:/Data - Experiment/FullODImages/202508';
options.FullODImagesFolder = 'D:/Data - Experiment/FullODImages/202508';
options.measurementName = 'DropletsToStripes';
scriptFullPath = mfilename('fullpath');
options.saveDirectory = fileparts(scriptFullPath);
@ -63,18 +63,22 @@ options.showProgressBar = true;
options.font = 'Bahnschrift';
switch options.measurementName
case 'BECToDroplets'
options.scan_parameter = 'rot_mag_field';
options.flipSortOrder = true;
options.scanParameterUnits = 'gauss';
options.titleString = 'BEC to Droplets';
case 'BECToStripes'
options.scan_parameter = 'rot_mag_field';
options.flipSortOrder = true;
options.scanParameterUnits = 'gauss';
options.titleString = 'BEC to Stripes';
case 'DropletsToStripes'
options.scan_parameter = 'ps_rot_mag_field';
options.flipSortOrder = true;
options.scanParameterUnits = 'degrees';
options.titleString = 'Droplets to Stripes';
case 'StripesToDroplets'
options.scan_parameter = 'ps_rot_mag_field';
options.flipSortOrder = false;
options.scanParameterUnits = 'degrees';
options.titleString = 'Stripes to Droplets';
@ -82,7 +86,7 @@ end
%% ===== Collect Images and Launch Viewer =====
[options.selectedPath, options.folderPath] = Helper.selectDataSourcePath(dataSources, options);
[options.selectedPath, options.folderPath] = Helper.selectDataSourcePath(dataSources, options);
[od_imgs, scan_parameter_values, file_list] = Helper.collectODImages(options);

View File

@ -11,7 +11,7 @@ options = struct();
% File paths
options.baseDataFolder = '//DyLabNAS/Data';
options.FullODImagesFolder = 'F:/Data - Experiment/FullODImages/202508';
options.FullODImagesFolder = 'E:/Data - Experiment/FullODImages/202508';
options.measurementName = 'DropletsToStripes';
scriptFullPath = mfilename('fullpath');
options.saveDirectory = fileparts(scriptFullPath);
@ -63,23 +63,26 @@ options.showProgressBar = true;
options.font = 'Bahnschrift';
switch options.measurementName
case 'BECToDroplets'
options.scan_parameter = 'rot_mag_field';
options.flipSortOrder = true;
options.scanParameterUnits = 'gauss';
options.titleString = 'BEC to Droplets';
case 'BECToStripes'
options.scan_parameter = 'rot_mag_field';
options.flipSortOrder = true;
options.scanParameterUnits = 'gauss';
options.titleString = 'BEC to Stripes';
case 'DropletsToStripes'
options.scan_parameter = 'ps_rot_mag_field';
options.flipSortOrder = true;
options.scanParameterUnits = 'degrees';
options.titleString = 'Droplets to Stripes';
case 'StripesToDroplets'
options.scan_parameter = 'ps_rot_mag_field';
options.flipSortOrder = false;
options.scanParameterUnits = 'degrees';
options.titleString = 'Stripes to Droplets';
end
%% ===== Run Batch Analysis =====
results_all = Helper.batchAnalyze(dataSources, options);

View File

@ -18,7 +18,7 @@ scan_parameter_values = datasetStruct.scan_parameter_values;
% Load the original options used during analysis
options = datasetStruct.options; % exact options used for this dataset
options.font = 'Bahnscrift'; % override if needed
options.font = 'Bahnschrift'; % override if needed
options.skipSaveFigures = false; % override if needed
%% ------------------ Create dataset-specific figure folder ------------------
@ -51,7 +51,7 @@ Plotter.plotMeanWithSE(scan_parameter_values, compiled_results.spectral_analysis
'SkipSaveFigures', options.skipSaveFigures);
% Plot Peak Offset Angular Correlation
Plotter.plotMeanWithSE(options.scan_reference_values, compiled_results.custom_g_results.max_g2_all_per_scan_parameter_value, ...
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)]$', ...
@ -63,11 +63,11 @@ Plotter.plotMeanWithSE(options.scan_reference_values, compiled_results.custom_g_
'SkipSaveFigures', options.skipSaveFigures);
%% ------------------ 2. g²(θ) across transition ------------------
Plotter.plotG2(compiled_results.full_g2_results.g2_all, ...
compiled_results.full_g2_results.g2_error_all, ...
Plotter.plotG2(compiled_results.full_g2_results.g2_mean, ...
compiled_results.full_g2_results.g2_error, ...
compiled_results.full_g2_results.theta_values, ...
options.scan_reference_values, ...
'rot_mag_field', ...
scan_reference_values, ...
options.scanParameterUnits, ...
'Title', options.titleString, ...
'XLabel', '$\delta\theta / \pi$', ...
'YLabel', '$g^{(2)}(\delta\theta)$', ...
@ -77,14 +77,51 @@ Plotter.plotG2(compiled_results.full_g2_results.g2_all, ...
'SaveFileName', 'G2ThetaAcrossTransition.fig', ...
'SaveDirectory', figSaveDir, ...
'Colormap', @Colormaps.coolwarm);
%% ------------------ 3. Feature extraction of g²(θ) across transition ------------------
%% ------------------ 3. PDF of max g² across transition ------------------
Plotter.plotG2Curves(compiled_results.full_g2_results, ...
'Title', options.titleString, ...
'XLabel', '\theta / \pi', ...
'YLabel', 'g^{(2)}(\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);
%
g2_analysis_results = Analyzer.analyzeAutocorrelation(compiled_results.full_g2_results);
%
Plotter.plotG2Features(g2_analysis_results, ...
'Title', options.titleString, ...
'XLabel', '\alpha (deg)', ...
'FontName', options.font, ...
'FigNum', 6, ...
'SkipSaveFigures', options.skipSaveFigures, ...
'SaveFileName', 'G2Features.fig', ...
'SaveDirectory', figSaveDir);
%
Plotter.plotG2Cumulants(g2_analysis_results, ...
'Title', options.titleString, ...
'XLabel', '\alpha (deg)', ...
'FontName', options.font, ...
'FigNum', 7, ...
'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, ...
options.scan_reference_values, ...
scan_reference_values, ...
'Title', options.titleString, ...
'XLabel', 'B (G)', ...
'YLabel', '$\mathrm{max}[g^{(2)}]$', ...
'FigNum', 5, ...
'FigNum', 8, ...
'FontName', options.font, ...
'SkipSaveFigures', options.skipSaveFigures, ...
'SaveFileName', 'PDF_MaxG2AcrossTransition.fig', ...
@ -93,15 +130,15 @@ Plotter.plotPDF(compiled_results.custom_g_results.max_g2_all_per_scan_parameter_
'NormalizeHistogram', true, ...
'DataRange', [0 1.5], ...
'Colormap', @Colormaps.coolwarm, ...
'XLim', [min(options.scan_reference_values) max(options.scan_reference_values)]);
'XLim', [min(scan_reference_values) max(scan_reference_values)]);
%% ------------------ 4. Cumulants across transition ------------------
Plotter.plotCumulants(options.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', 'B (G)', ...
'FigNum', 6, ...
'FigNum', 9, ...
'FontName', options.font, ...
'MarkerSize', 6, ...
'LineWidth', 1.5, ...
@ -109,13 +146,16 @@ Plotter.plotCumulants(options.scan_reference_values, ...
'SaveFileName', 'CumulantOfPeakOffsetAngularCorrelation.fig', ...
'SaveDirectory', figSaveDir);
%% ------------------ 5. PCA ------------------
Plotter.plotPCAResults(compiled_results.pca_results, scan_parameter_values, options.scan_reference_values, ...
'FigNumRange', [7,8,9,10,11,12], ...
%% ------------------ 6. PCA ------------------
Plotter.plotPCAResults(compiled_results.pca_results, scan_parameter_values, scan_reference_values, ...
'FigNumRange', [10,11,12,13,14,15], ...
'FontName', options.font, ...
'SkipSaveFigures', options.skipSaveFigures, ...
'SaveDirectory', figSaveDir);
%%
%{
%% ------------------ 6. Average of Spectra Plots ------------------
@ -175,7 +215,7 @@ compareMultipleDatasets(scanValsCell, meanValsCell, stderrValsCell, ...
BFields = [2.35, 2.15, 2.0, 1.85, 1.7, 1.55, 1.4, 1.35];
% Heatmap of mean_max_g2_values
Plotter.plotHeatmap(compiled_results, options.scan_groups, BFields, 'mean_max_g2_values', ...
Plotter.plotHeatmap(compiled_results, scan_reference_values, BFields, 'mean_max_g2_values', ...
'Colormap', @sky, ...
'CLim', [0 1], ...
'XLabel', '\alpha (degrees)', ...
@ -183,10 +223,10 @@ Plotter.plotHeatmap(compiled_results, options.scan_groups, BFields, 'mean_max_g2
'Title', '$\mathrm{max}[g^{(2)}_{[50,70]}(\delta\theta)]$', ...
'FigNum', 9, ...
'SaveFileName', 'Heatmap_MaxG2.fig', ...
'SaveDirectory', options.resultsDir);
'SaveDirectory', options.saveDirectory);
% Heatmap of radial_spectral_contrast
Plotter.plotHeatmap(compiled_results, options.scan_groups, BFields, 'radial_spectral_contrast', ...
Plotter.plotHeatmap(compiled_results, scan_reference_values, BFields, 'radial_spectral_contrast', ...
'Colormap', @sky, ...
'CLim', [0 0.008], ...
'XLabel', '\alpha (degrees)', ...
@ -194,5 +234,5 @@ Plotter.plotHeatmap(compiled_results, options.scan_groups, BFields, 'radial_spec
'Title', 'Radial Spectral Contrast', ...
'FigNum', 10, ...
'SaveFileName', 'Heatmap_RadialSpectralContrast.fig', ...
'SaveDirectory', options.resultsDir);
'SaveDirectory', options.saveDirectory);
%}

View File

@ -63,18 +63,22 @@ options.showProgressBar = true;
options.font = 'Bahnschrift';
switch options.measurementName
case 'BECToDroplets'
options.scan_parameter = 'rot_mag_field';
options.flipSortOrder = true;
options.scanParameterUnits = 'gauss';
options.titleString = 'BEC to Droplets';
case 'BECToStripes'
options.scan_parameter = 'rot_mag_field';
options.flipSortOrder = true;
options.scanParameterUnits = 'gauss';
options.titleString = 'BEC to Stripes';
case 'DropletsToStripes'
options.scan_parameter = 'ps_rot_mag_field';
options.flipSortOrder = true;
options.scanParameterUnits = 'degrees';
options.titleString = 'Droplets to Stripes';
case 'StripesToDroplets'
options.scan_parameter = 'ps_rot_mag_field';
options.flipSortOrder = false;
options.scanParameterUnits = 'degrees';
options.titleString = 'Stripes to Droplets';
@ -82,7 +86,7 @@ end
%% ===== Collect Images and Launch Viewer =====
[options.selectedPath, options.folderPath] = Helper.selectDataSourcePath(dataSources, options);
[options.selectedPath, options.folderPath] = Helper.selectDataSourcePath(dataSources, options);
[od_imgs, scan_parameter_values, file_list] = Helper.collectODImages(options);

View File

@ -3,15 +3,15 @@
% Specify data location to run analysis on
dataSources = {
struct('sequence', 'StructuralPhaseTransition', ...
'date', '2025/08/15', ...
'runs', [3]) % specify run numbers as a string in "" or just as a numeric value
'date', '2025/07/26', ...
'runs', [8]) % specify run numbers as a string in "" or just as a numeric value
};
options = struct();
% File paths
options.baseDataFolder = '//DyLabNAS/Data';
options.FullODImagesFolder = 'F:/Data - Experiment/FullODImages/202508';
options.FullODImagesFolder = 'E:/Data - Experiment/FullODImages/202507';
options.measurementName = 'BECToStripes';
scriptFullPath = mfilename('fullpath');
options.saveDirectory = fileparts(scriptFullPath);
@ -23,7 +23,7 @@ options.center = [1420, 2050];
options.span = [200, 200];
options.fraction = [0.1, 0.1];
options.pixel_size = 5.86e-6; % in meters
options.magnification = 24.6;
options.magnification = 23.94;
options.ImagingMode = 'HighIntensity';
options.PulseDuration = 5e-6; % in s
@ -52,7 +52,7 @@ options.skipMasking = true;
options.skipIntensityThresholding = true;
options.skipBinarization = true;
options.skipFullODImagesFolderUse = false;
options.skipFullODImagesFolderUse = true;
options.skipSaveData = false;
options.skipSaveFigures = true;
options.skipSaveProcessedOD = true;
@ -63,18 +63,22 @@ options.showProgressBar = true;
options.font = 'Bahnschrift';
switch options.measurementName
case 'BECToDroplets'
options.scan_parameter = 'rot_mag_field';
options.flipSortOrder = true;
options.scanParameterUnits = 'gauss';
options.titleString = 'BEC to Droplets';
case 'BECToStripes'
options.scan_parameter = 'rot_mag_field';
options.flipSortOrder = true;
options.scanParameterUnits = 'gauss';
options.titleString = 'BEC to Stripes';
case 'DropletsToStripes'
options.scan_parameter = 'ps_rot_mag_field';
options.flipSortOrder = true;
options.scanParameterUnits = 'degrees';
options.titleString = 'Droplets to Stripes';
case 'StripesToDroplets'
options.scan_parameter = 'ps_rot_mag_field';
options.flipSortOrder = false;
options.scanParameterUnits = 'degrees';
options.titleString = 'Stripes to Droplets';

View File

@ -18,7 +18,7 @@ scan_parameter_values = datasetStruct.scan_parameter_values;
% Load the original options used during analysis
options = datasetStruct.options; % exact options used for this dataset
options.font = 'Bahnscrift'; % override if needed
options.font = 'Bahnschrift'; % override if needed
options.skipSaveFigures = false; % override if needed
%% ------------------ Create dataset-specific figure folder ------------------
@ -51,7 +51,7 @@ Plotter.plotMeanWithSE(scan_parameter_values, compiled_results.spectral_analysis
'SkipSaveFigures', options.skipSaveFigures);
% Plot Peak Offset Angular Correlation
Plotter.plotMeanWithSE(options.scan_reference_values, compiled_results.custom_g_results.max_g2_all_per_scan_parameter_value, ...
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)]$', ...
@ -63,11 +63,11 @@ Plotter.plotMeanWithSE(options.scan_reference_values, compiled_results.custom_g_
'SkipSaveFigures', options.skipSaveFigures);
%% ------------------ 2. g²(θ) across transition ------------------
Plotter.plotG2(compiled_results.full_g2_results.g2_all, ...
compiled_results.full_g2_results.g2_error_all, ...
Plotter.plotG2(compiled_results.full_g2_results.g2_mean, ...
compiled_results.full_g2_results.g2_error, ...
compiled_results.full_g2_results.theta_values, ...
options.scan_reference_values, ...
'rot_mag_field', ...
scan_reference_values, ...
options.scanParameterUnits, ...
'Title', options.titleString, ...
'XLabel', '$\delta\theta / \pi$', ...
'YLabel', '$g^{(2)}(\delta\theta)$', ...
@ -77,14 +77,51 @@ Plotter.plotG2(compiled_results.full_g2_results.g2_all, ...
'SaveFileName', 'G2ThetaAcrossTransition.fig', ...
'SaveDirectory', figSaveDir, ...
'Colormap', @Colormaps.coolwarm);
%% ------------------ 3. Feature extraction of g²(θ) across transition ------------------
%% ------------------ 3. PDF of max g² across transition ------------------
Plotter.plotG2Curves(compiled_results.full_g2_results, ...
'Title', options.titleString, ...
'XLabel', '\theta / \pi', ...
'YLabel', 'g^{(2)}(\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);
%
g2_analysis_results = Analyzer.analyzeAutocorrelation(compiled_results.full_g2_results);
%
Plotter.plotG2Features(g2_analysis_results, ...
'Title', options.titleString, ...
'XLabel', '\alpha (deg)', ...
'FontName', options.font, ...
'FigNum', 6, ...
'SkipSaveFigures', options.skipSaveFigures, ...
'SaveFileName', 'G2Features.fig', ...
'SaveDirectory', figSaveDir);
%
Plotter.plotG2Cumulants(g2_analysis_results, ...
'Title', options.titleString, ...
'XLabel', '\alpha (deg)', ...
'FontName', options.font, ...
'FigNum', 7, ...
'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, ...
options.scan_reference_values, ...
scan_reference_values, ...
'Title', options.titleString, ...
'XLabel', 'B (G)', ...
'YLabel', '$\mathrm{max}[g^{(2)}]$', ...
'FigNum', 5, ...
'FigNum', 8, ...
'FontName', options.font, ...
'SkipSaveFigures', options.skipSaveFigures, ...
'SaveFileName', 'PDF_MaxG2AcrossTransition.fig', ...
@ -93,15 +130,15 @@ Plotter.plotPDF(compiled_results.custom_g_results.max_g2_all_per_scan_parameter_
'NormalizeHistogram', true, ...
'DataRange', [0 1.5], ...
'Colormap', @Colormaps.coolwarm, ...
'XLim', [min(options.scan_reference_values) max(options.scan_reference_values)]);
'XLim', [min(scan_reference_values) max(scan_reference_values)]);
%% ------------------ 4. Cumulants across transition ------------------
Plotter.plotCumulants(options.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', 'B (G)', ...
'FigNum', 6, ...
'FigNum', 9, ...
'FontName', options.font, ...
'MarkerSize', 6, ...
'LineWidth', 1.5, ...
@ -109,13 +146,16 @@ Plotter.plotCumulants(options.scan_reference_values, ...
'SaveFileName', 'CumulantOfPeakOffsetAngularCorrelation.fig', ...
'SaveDirectory', figSaveDir);
%% ------------------ 5. PCA ------------------
Plotter.plotPCAResults(compiled_results.pca_results, scan_parameter_values, options.scan_reference_values, ...
'FigNumRange', [7,8,9,10,11,12], ...
%% ------------------ 6. PCA ------------------
Plotter.plotPCAResults(compiled_results.pca_results, scan_parameter_values, scan_reference_values, ...
'FigNumRange', [10,11,12,13,14,15], ...
'FontName', options.font, ...
'SkipSaveFigures', options.skipSaveFigures, ...
'SaveDirectory', figSaveDir);
%%
%{
%% ------------------ 6. Average of Spectra Plots ------------------
@ -175,7 +215,7 @@ compareMultipleDatasets(scanValsCell, meanValsCell, stderrValsCell, ...
BFields = [2.35, 2.15, 2.0, 1.85, 1.7, 1.55, 1.4, 1.35];
% Heatmap of mean_max_g2_values
Plotter.plotHeatmap(compiled_results, options.scan_groups, BFields, 'mean_max_g2_values', ...
Plotter.plotHeatmap(compiled_results, scan_reference_values, BFields, 'mean_max_g2_values', ...
'Colormap', @sky, ...
'CLim', [0 1], ...
'XLabel', '\alpha (degrees)', ...
@ -183,10 +223,10 @@ Plotter.plotHeatmap(compiled_results, options.scan_groups, BFields, 'mean_max_g2
'Title', '$\mathrm{max}[g^{(2)}_{[50,70]}(\delta\theta)]$', ...
'FigNum', 9, ...
'SaveFileName', 'Heatmap_MaxG2.fig', ...
'SaveDirectory', options.resultsDir);
'SaveDirectory', options.saveDirectory);
% Heatmap of radial_spectral_contrast
Plotter.plotHeatmap(compiled_results, options.scan_groups, BFields, 'radial_spectral_contrast', ...
Plotter.plotHeatmap(compiled_results, scan_reference_values, BFields, 'radial_spectral_contrast', ...
'Colormap', @sky, ...
'CLim', [0 0.008], ...
'XLabel', '\alpha (degrees)', ...
@ -194,5 +234,5 @@ Plotter.plotHeatmap(compiled_results, options.scan_groups, BFields, 'radial_spec
'Title', 'Radial Spectral Contrast', ...
'FigNum', 10, ...
'SaveFileName', 'Heatmap_RadialSpectralContrast.fig', ...
'SaveDirectory', options.resultsDir);
'SaveDirectory', options.saveDirectory);
%}

View File

@ -63,18 +63,22 @@ options.showProgressBar = true;
options.font = 'Bahnschrift';
switch options.measurementName
case 'BECToDroplets'
options.scan_parameter = 'rot_mag_field';
options.flipSortOrder = true;
options.scanParameterUnits = 'gauss';
options.titleString = 'BEC to Droplets';
case 'BECToStripes'
options.scan_parameter = 'rot_mag_field';
options.flipSortOrder = true;
options.scanParameterUnits = 'gauss';
options.titleString = 'BEC to Stripes';
case 'DropletsToStripes'
options.scan_parameter = 'ps_rot_mag_field';
options.flipSortOrder = true;
options.scanParameterUnits = 'degrees';
options.titleString = 'Droplets to Stripes';
case 'StripesToDroplets'
options.scan_parameter = 'ps_rot_mag_field';
options.flipSortOrder = false;
options.scanParameterUnits = 'degrees';
options.titleString = 'Stripes to Droplets';

View File

@ -11,7 +11,7 @@ options = struct();
% File paths
options.baseDataFolder = '//DyLabNAS/Data';
options.FullODImagesFolder = 'F:/Data - Experiment/FullODImages/202508';
options.FullODImagesFolder = 'E:/Data - Experiment/FullODImages/202508';
options.measurementName = 'StripesToDroplets';
scriptFullPath = mfilename('fullpath');
options.saveDirectory = fileparts(scriptFullPath);
@ -63,24 +63,27 @@ options.showProgressBar = true;
options.font = 'Bahnschrift';
switch options.measurementName
case 'BECToDroplets'
options.scan_parameter = 'rot_mag_field';
options.flipSortOrder = true;
options.scanParameterUnits = 'gauss';
options.titleString = 'BEC to Droplets';
case 'BECToStripes'
options.scan_parameter = 'rot_mag_field';
options.flipSortOrder = true;
options.scanParameterUnits = 'gauss';
options.titleString = 'BEC to Stripes';
case 'DropletsToStripes'
options.scan_parameter = 'ps_rot_mag_field';
options.flipSortOrder = true;
options.scanParameterUnits = 'degrees';
options.titleString = 'Droplets to Stripes';
case 'StripesToDroplets'
options.scan_parameter = 'ps_rot_mag_field';
options.flipSortOrder = false;
options.scanParameterUnits = 'degrees';
options.titleString = 'Stripes to Droplets';
end
%% ===== Run Batch Analysis =====
results_all = Helper.batchAnalyze(dataSources, options);