New plotting routines
This commit is contained in:
parent
ffa50e2525
commit
5fd39e31f4
@ -43,26 +43,29 @@ function plotAndCompareG2Cumulants(results1, results2, varargin)
|
|||||||
% --- Legend labels for θ ---
|
% --- Legend labels for θ ---
|
||||||
thetaLabels = arrayfun(@(t) sprintf('\\pi/%g', round(pi/t)), opts.DesiredTheta, 'UniformOutput', false);
|
thetaLabels = arrayfun(@(t) sprintf('\\pi/%g', round(pi/t)), opts.DesiredTheta, 'UniformOutput', false);
|
||||||
|
|
||||||
% --- Marker per θ ---
|
|
||||||
markerList = {'o','s','^','d','v','>','<','p','h'}; % more markers if needed
|
|
||||||
Ntheta = numel(thIdx);
|
|
||||||
markers = markerList(mod(0:Ntheta-1, numel(markerList))+1); % cycle if Ntheta > markerList
|
|
||||||
|
|
||||||
% --- Line styles for datasets ---
|
% --- Line styles for datasets ---
|
||||||
lineStyles = {'-', '--'}; % solid for dataset1, dashed for dataset2
|
lineStyles = {'-', '--'}; % solid for dataset1, dashed for dataset2
|
||||||
|
|
||||||
% --- Colors per θ (generalized, using only ends of coolwarm) ---
|
% --- Colors per θ ---
|
||||||
|
%{
|
||||||
cmapFull = Colormaps.coolwarm(256);
|
cmapFull = Colormaps.coolwarm(256);
|
||||||
Ntheta = numel(thIdx);
|
Ntheta = numel(thIdx);
|
||||||
|
startColor = cmapFull(1,:);
|
||||||
% pick start and end colors
|
endColor = cmapFull(end,:);
|
||||||
startColor = cmapFull(1, :); % deep blue
|
|
||||||
endColor = cmapFull(end, :); % deep red
|
|
||||||
|
|
||||||
% interpolate RGB linearly between start and end for Ntheta points
|
|
||||||
thetaColors = [linspace(startColor(1), endColor(1), Ntheta)', ...
|
thetaColors = [linspace(startColor(1), endColor(1), Ntheta)', ...
|
||||||
linspace(startColor(2), endColor(2), Ntheta)', ...
|
linspace(startColor(2), endColor(2), Ntheta)', ...
|
||||||
linspace(startColor(3), endColor(3), Ntheta)'];
|
linspace(startColor(3), endColor(3), Ntheta)'];
|
||||||
|
%}
|
||||||
|
cmapFull = Colormaps.coolwarm(256);
|
||||||
|
Ntheta = numel(thIdx);
|
||||||
|
% Split into two halves: blue side (1:128), red side (129:256)
|
||||||
|
blueSide = cmapFull(1:100, :); % cut before gray
|
||||||
|
redSide = cmapFull(157:end, :); % cut after gray
|
||||||
|
% Concatenate to avoid center
|
||||||
|
cmapTrimmed = [blueSide; redSide];
|
||||||
|
% Now sample evenly from this trimmed colormap
|
||||||
|
indices = round(linspace(1, size(cmapTrimmed,1), Ntheta));
|
||||||
|
thetaColors = cmapTrimmed(indices, :);
|
||||||
|
|
||||||
|
|
||||||
% --- Create figure ---
|
% --- Create figure ---
|
||||||
@ -85,7 +88,7 @@ function plotAndCompareG2Cumulants(results1, results2, varargin)
|
|||||||
% Dataset 1 -> solid line + marker
|
% Dataset 1 -> solid line + marker
|
||||||
plot(ax, x1, squeeze(kappa1(th,:,k)), ...
|
plot(ax, x1, squeeze(kappa1(th,:,k)), ...
|
||||||
'LineStyle', lineStyles{1}, 'Color', c, ...
|
'LineStyle', lineStyles{1}, 'Color', c, ...
|
||||||
'LineWidth', 2, 'Marker', 'o', 'MarkerSize', 7, ...
|
'LineWidth', 2, 'Marker', 'o', 'MarkerSize', 7, ... % markerList = {'o','s','^','d','v','>','<','p','h'}; % more markers if needed
|
||||||
'MarkerFaceColor', c);
|
'MarkerFaceColor', c);
|
||||||
|
|
||||||
% Dataset 2 -> dashed line + marker
|
% Dataset 2 -> dashed line + marker
|
||||||
|
|||||||
135
Data-Analyzer/+Plotter/plotAndCompareG2Mean.m
Normal file
135
Data-Analyzer/+Plotter/plotAndCompareG2Mean.m
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
function plotAndCompareG2Mean(results1, results2, varargin)
|
||||||
|
%% plotAndCompareG2Mean: Compare first cumulant (mean) of g²(θ) for two datasets
|
||||||
|
% results1, results2 : g2_analysis_results objects
|
||||||
|
%
|
||||||
|
% Dataset 1 = Solid line
|
||||||
|
% Dataset 2 = Dashed line
|
||||||
|
% Marker shape encodes θ value (consistent across datasets)
|
||||||
|
% Dataset colors are distinct
|
||||||
|
%
|
||||||
|
% Plots mean ± standard deviation of g² values at the desired θ
|
||||||
|
|
||||||
|
% --- Parse name-value pairs ---
|
||||||
|
p = inputParser;
|
||||||
|
addParameter(p, 'Title', 'Mean Comparison', @(x) ischar(x) || isstring(x));
|
||||||
|
addParameter(p, 'XLabel', 'Scan Parameter', @(x) ischar(x) || isstring(x));
|
||||||
|
addParameter(p, 'YLabel', 'Mean (\kappa_1)', @(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', 'G2MeanComparison.fig', @ischar);
|
||||||
|
addParameter(p, 'SaveDirectory', pwd, @ischar);
|
||||||
|
addParameter(p, 'DesiredTheta', [pi/12 pi/6 pi/3 pi/2 2*pi/3 5*pi/6], @(x) isnumeric(x) && isvector(x));
|
||||||
|
parse(p, varargin{:});
|
||||||
|
opts = p.Results;
|
||||||
|
|
||||||
|
% --- Helper to extract mean, STD, and SEM at desired θ ---
|
||||||
|
function [xvals, yMean, yStd, ySEM, thIdx] = extractData(results)
|
||||||
|
xvals = results.scan_parameter_values(:); % [N_params × 1]
|
||||||
|
N_params = numel(xvals);
|
||||||
|
thetaVals = results.theta_values; % all θ
|
||||||
|
desiredTheta = opts.DesiredTheta;
|
||||||
|
[~, thIdx] = arrayfun(@(t) min(abs(thetaVals - t)), desiredTheta);
|
||||||
|
Ndesired = numel(desiredTheta);
|
||||||
|
|
||||||
|
yMean = zeros(N_params, Ndesired); % [scan × θ]
|
||||||
|
yStd = zeros(N_params, Ndesired);
|
||||||
|
ySEM = zeros(N_params, Ndesired);
|
||||||
|
|
||||||
|
for i = 1:N_params
|
||||||
|
G = results.g2_curves{i}; % [N_reps × N_theta] for this scan parameter
|
||||||
|
for j = 1:Ndesired
|
||||||
|
th = thIdx(j);
|
||||||
|
data = G(:, th); % all reps for this θ at this scan param
|
||||||
|
yMean(i,j) = mean(data); % mean across reps
|
||||||
|
yStd(i,j) = std(data,0,1); % std across reps
|
||||||
|
ySEM(i,j) = std(data,0,1)/sqrt(numel(data)); % SEM
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
% --- Extract data for both datasets ---
|
||||||
|
[x1, yMean1, yStd1, ySEM1, thIdx] = extractData(results1);
|
||||||
|
[x2, yMean2, yStd2, ySEM2, ~] = extractData(results2);
|
||||||
|
|
||||||
|
% --- Legend labels for θ ---
|
||||||
|
thetaLabels = arrayfun(@(t) sprintf('\\pi/%g', round(pi/t)), opts.DesiredTheta, 'UniformOutput', false);
|
||||||
|
|
||||||
|
|
||||||
|
% --- Line styles for datasets ---
|
||||||
|
lineStyles = {'-', '--'}; % solid for dataset1, dashed for dataset2
|
||||||
|
|
||||||
|
% --- Colors per θ ---
|
||||||
|
%{
|
||||||
|
cmapFull = Colormaps.coolwarm(256);
|
||||||
|
Ntheta = numel(thIdx);
|
||||||
|
startColor = cmapFull(1,:);
|
||||||
|
endColor = cmapFull(end,:);
|
||||||
|
thetaColors = [linspace(startColor(1), endColor(1), Ntheta)', ...
|
||||||
|
linspace(startColor(2), endColor(2), Ntheta)', ...
|
||||||
|
linspace(startColor(3), endColor(3), Ntheta)'];
|
||||||
|
%}
|
||||||
|
cmapFull = Colormaps.coolwarm(256);
|
||||||
|
Ntheta = numel(thIdx);
|
||||||
|
% Split into two halves: blue side (1:128), red side (129:256)
|
||||||
|
blueSide = cmapFull(1:100, :); % cut before gray
|
||||||
|
redSide = cmapFull(157:end, :); % cut after gray
|
||||||
|
% Concatenate to avoid center
|
||||||
|
cmapTrimmed = [blueSide; redSide];
|
||||||
|
% Now sample evenly from this trimmed colormap
|
||||||
|
indices = round(linspace(1, size(cmapTrimmed,1), Ntheta));
|
||||||
|
thetaColors = cmapTrimmed(indices, :);
|
||||||
|
|
||||||
|
% --- 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]);
|
||||||
|
|
||||||
|
ax = axes(fig); hold(ax,'on'); 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, opts.Title, 'FontName', opts.FontName, 'FontSize', opts.FontSize+2);
|
||||||
|
|
||||||
|
% --- Plot each θ with SEM ---
|
||||||
|
for idx = 1:Ntheta
|
||||||
|
c = thetaColors(idx,:);
|
||||||
|
|
||||||
|
% Dataset 1 -> solid line + marker + SEM
|
||||||
|
errorbar(ax, x1, yMean1(:,idx), ySEM1(:,idx), 'LineStyle', lineStyles{1}, ...
|
||||||
|
'Color', c, 'LineWidth', 2, 'Marker', 'o', 'MarkerSize', 7, 'MarkerFaceColor', c);
|
||||||
|
|
||||||
|
% Dataset 2 -> dashed line + marker + SEM
|
||||||
|
errorbar(ax, x2, yMean2(:,idx), ySEM2(:,idx), 'LineStyle', lineStyles{2}, ...
|
||||||
|
'Color', c, 'LineWidth', 2, 'Marker', 's', 'MarkerSize', 7, 'MarkerFaceColor', c);
|
||||||
|
end
|
||||||
|
|
||||||
|
% --- Line-only legend for θ ---
|
||||||
|
thetaHandles = gobjects(Ntheta,1);
|
||||||
|
for m = 1:Ntheta
|
||||||
|
thetaHandles(m) = plot(ax, NaN, NaN, 'LineStyle','-', 'Color',thetaColors(m,:), ...
|
||||||
|
'LineWidth',6, 'Marker','none');
|
||||||
|
end
|
||||||
|
legend(ax, thetaHandles, thetaLabels, 'Location','northeast', 'FontSize', opts.FontSize-2);
|
||||||
|
|
||||||
|
% --- Dataset legend (solid/dashed + marker) ABOVE AXES ---
|
||||||
|
axLegend = axes(fig,'Position',[0.65 0.65 0.25 0.15],'Visible','off');
|
||||||
|
hold(axLegend,'on');
|
||||||
|
|
||||||
|
d1 = plot(axLegend, NaN, NaN, 'LineStyle',lineStyles{1}, ...
|
||||||
|
'Color','k', 'Marker','none', 'LineWidth',2);
|
||||||
|
d2 = plot(axLegend, NaN, NaN, 'LineStyle',lineStyles{2}, ...
|
||||||
|
'Color','k', 'Marker','none', 'LineWidth',2);
|
||||||
|
|
||||||
|
legend(axLegend,[d1 d2],{'D -> S','S -> D'}, ...
|
||||||
|
'FontName', opts.FontName, 'FontSize', opts.FontSize+2, ...
|
||||||
|
'Orientation','vertical', 'Box','off');
|
||||||
|
|
||||||
|
|
||||||
|
% --- Save figure ---
|
||||||
|
if ~opts.SkipSaveFigures
|
||||||
|
if ~exist(opts.SaveDirectory,'dir'), mkdir(opts.SaveDirectory); end
|
||||||
|
savefig(fig, fullfile(opts.SaveDirectory, opts.SaveFileName));
|
||||||
|
end
|
||||||
|
end
|
||||||
121
Data-Analyzer/+Plotter/plotG2CurvesMultiParam.m
Normal file
121
Data-Analyzer/+Plotter/plotG2CurvesMultiParam.m
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
function plotG2CurvesMultiParam(results, scan_parameter_values, scan_reference_values, param1ValuesToPlot, param2ValuesToPlot, varargin)
|
||||||
|
%% plotG2CurvesMultiParam: Plot g²(θ) curves for selected param1 and param2 values in a phase diagram
|
||||||
|
%
|
||||||
|
% Usage:
|
||||||
|
% plotG2CurvesMultiParam(results, scan_parameter_values, scan_reference_values, ...
|
||||||
|
% param1ValuesToPlot, param2ValuesToPlot, ...
|
||||||
|
% 'Title','g² Curves','FontName','Arial','FontSize',14,'FigNum',1, ...
|
||||||
|
% 'Param1Name','BField','Param2Name','Alpha', ...
|
||||||
|
% 'HighlightEvery',10,'SkipSaveFigures',false, ...
|
||||||
|
% 'SaveFileName','G2CurvesPhaseDiagram.fig','SaveDirectory','results');
|
||||||
|
|
||||||
|
% --- Parse name-value pairs ---
|
||||||
|
p = inputParser;
|
||||||
|
addParameter(p, 'Title', 'g² Curves', @(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, 'Param1Name', 'Param1', @(x) ischar(x) || isstring(x));
|
||||||
|
addParameter(p, 'Param2Name', 'Param2', @(x) ischar(x) || isstring(x));
|
||||||
|
addParameter(p, 'HighlightEvery', 10, @(x) isnumeric(x) && isscalar(x) && x>=1);
|
||||||
|
addParameter(p, 'SkipSaveFigures', false, @islogical);
|
||||||
|
addParameter(p, 'SaveFileName', 'G2CurvesPhaseDiagram.fig', @ischar);
|
||||||
|
addParameter(p, 'SaveDirectory', pwd, @ischar);
|
||||||
|
parse(p, varargin{:});
|
||||||
|
opts = p.Results;
|
||||||
|
|
||||||
|
% --- Convert reference/parameter values to numeric arrays ---
|
||||||
|
scanRefArray = cell2mat(scan_reference_values(:)); % nParams × 2
|
||||||
|
scanParamArray = cell2mat(scan_parameter_values(:)); % nTotal × 2
|
||||||
|
|
||||||
|
% --- Select subset based on param1ValuesToPlot and param2ValuesToPlot ---
|
||||||
|
keepIdx = ismembertol(scanRefArray(:,1), param1ValuesToPlot, 1e-6) & ...
|
||||||
|
ismembertol(scanRefArray(:,2), param2ValuesToPlot, 1e-6);
|
||||||
|
scan_reference_values_plot = scan_reference_values(keepIdx);
|
||||||
|
nParamsPlot = numel(scan_reference_values_plot);
|
||||||
|
|
||||||
|
% --- Warn about missing values ---
|
||||||
|
existingP1 = param1ValuesToPlot(ismembertol(param1ValuesToPlot, unique(scanRefArray(:,1)), 1e-6));
|
||||||
|
missingP1 = setdiff(param1ValuesToPlot, existingP1);
|
||||||
|
existingP2 = param2ValuesToPlot(ismembertol(param2ValuesToPlot, unique(scanRefArray(:,2)), 1e-6));
|
||||||
|
missingP2 = setdiff(param2ValuesToPlot, existingP2);
|
||||||
|
if ~isempty(missingP1)
|
||||||
|
warning('The following %s values were not found: %s', opts.Param1Name, num2str(missingP1));
|
||||||
|
end
|
||||||
|
if ~isempty(missingP2)
|
||||||
|
warning('The following %s values were not found: %s', opts.Param2Name, num2str(missingP2));
|
||||||
|
end
|
||||||
|
|
||||||
|
param1Plot = sort(existingP1, 'descend');
|
||||||
|
param2Plot = sort(existingP2);
|
||||||
|
|
||||||
|
% --- Extract theta values ---
|
||||||
|
theta = results.theta_values / pi;
|
||||||
|
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 1200 800]);
|
||||||
|
t = tiledlayout(numel(param1Plot), numel(param2Plot), 'TileSpacing','compact','Padding','compact');
|
||||||
|
title(t, opts.Title, 'FontName', opts.FontName, 'FontSize', opts.FontSize+2);
|
||||||
|
|
||||||
|
% --- Loop over selected param1/param2 values ---
|
||||||
|
for r = 1:numel(param1Plot)
|
||||||
|
P1 = param1Plot(r);
|
||||||
|
for c = 1:numel(param2Plot)
|
||||||
|
P2 = param2Plot(c);
|
||||||
|
|
||||||
|
ax = nexttile((r-1)*numel(param2Plot) + c); hold(ax,'on');
|
||||||
|
|
||||||
|
% Find index of this (param1, param2)
|
||||||
|
k = find(cellfun(@(v) all(abs(v - [P1 P2]) < 1e-6), scan_reference_values_plot), 1);
|
||||||
|
if isempty(k), continue; end
|
||||||
|
|
||||||
|
% Extract g² curves for this pair
|
||||||
|
G = results.g2_curves{k}; % [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 repetition ---
|
||||||
|
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 = mean(G,1,'omitnan');
|
||||||
|
se = std(G,0,1,'omitnan')/sqrt(size(G,1));
|
||||||
|
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, '\theta / \pi', 'FontName', opts.FontName, 'FontSize', opts.FontSize);
|
||||||
|
ylabel(ax, 'g^2(\theta)', 'FontName', opts.FontName, 'FontSize', opts.FontSize);
|
||||||
|
title(ax, sprintf('%s=%.3g, %s=%.1f', opts.Param1Name, P1, opts.Param2Name, P2), ...
|
||||||
|
'FontName', opts.FontName, 'FontSize', opts.FontSize);
|
||||||
|
set(ax, 'FontName', opts.FontName, 'FontSize', opts.FontSize);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
% --- Save figure ---
|
||||||
|
if ~opts.SkipSaveFigures
|
||||||
|
if ~exist(opts.SaveDirectory,'dir'), mkdir(opts.SaveDirectory); end
|
||||||
|
savefig(fig, fullfile(opts.SaveDirectory, opts.SaveFileName));
|
||||||
|
end
|
||||||
|
end
|
||||||
118
Data-Analyzer/+Plotter/plotG2MeanHeatmap.m
Normal file
118
Data-Analyzer/+Plotter/plotG2MeanHeatmap.m
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
function plotG2MeanHeatmap(results, theta_query, scan_parameter_values, scan_reference_values, varargin)
|
||||||
|
%% plotG2MeanHeatmap: Plots a heatmap of mean g² values at a specified theta across the phase diagram
|
||||||
|
%
|
||||||
|
% Usage:
|
||||||
|
% plotG2MeanHeatmap(results, pi/6, scan_parameter_values, scan_reference_values, ...
|
||||||
|
% 'FigNum', 1, 'Colormap', @jet, 'CLim', [], 'ColorScale', 'linear', ...
|
||||||
|
% 'XLabel', '\alpha (degrees)', 'YLabel', 'BField (G)', ...
|
||||||
|
% 'Title', 'Mean g²', 'SaveFileName', 'g2MeanHeatmap.fig', ...
|
||||||
|
% 'SaveDirectory', 'results', 'SkipSaveFigures', false);
|
||||||
|
|
||||||
|
% --- Parse optional inputs ---
|
||||||
|
p = inputParser;
|
||||||
|
addParameter(p, 'FigNum', []);
|
||||||
|
addParameter(p, 'Colormap', @jet);
|
||||||
|
addParameter(p, 'CLim', []);
|
||||||
|
addParameter(p, 'ColorScale', 'linear', @(x) any(validatestring(x,{'linear','log'})));
|
||||||
|
addParameter(p, 'XLabel', '\alpha (degrees)');
|
||||||
|
addParameter(p, 'YLabel', 'BField (G)');
|
||||||
|
addParameter(p, 'Title', 'Mean g²');
|
||||||
|
addParameter(p, 'FontName', 'Arial');
|
||||||
|
addParameter(p, 'FontSize', 14);
|
||||||
|
addParameter(p, 'SkipSaveFigures', false, @islogical);
|
||||||
|
addParameter(p, 'SaveFileName', 'g2MeanHeatmap.fig', @ischar);
|
||||||
|
addParameter(p, 'SaveDirectory', pwd, @ischar);
|
||||||
|
parse(p, varargin{:});
|
||||||
|
opts = p.Results;
|
||||||
|
|
||||||
|
% --- Extract data at requested theta ---
|
||||||
|
theta_vals = results.theta_values;
|
||||||
|
[~, idx_theta] = min(abs(theta_vals - theta_query)); % closest index
|
||||||
|
N_total = numel(results.g2_curves);
|
||||||
|
dataCell = cell(N_total,1);
|
||||||
|
for i = 1:N_total
|
||||||
|
G = results.g2_curves{i}; % [N_reps × Nθ]
|
||||||
|
dataCell{i} = G(:, idx_theta); % all repetitions at chosen theta
|
||||||
|
end
|
||||||
|
|
||||||
|
% --- Convert reference/parameter values to numeric arrays ---
|
||||||
|
scanRefArray = cell2mat(scan_reference_values(:)); % nParams × 2
|
||||||
|
scanParamArray = cell2mat(scan_parameter_values(:)); % nTotal × 2
|
||||||
|
|
||||||
|
BFields = sort(unique(scanRefArray(:,1)), 'ascend'); % rows
|
||||||
|
alphas = sort(unique(scanRefArray(:,2)), 'ascend'); % cols
|
||||||
|
|
||||||
|
nB = numel(BFields);
|
||||||
|
nA = numel(alphas);
|
||||||
|
|
||||||
|
% --- Preallocate data matrix ---
|
||||||
|
data_matrix = NaN(nB, nA);
|
||||||
|
|
||||||
|
% --- Fill matrix by looping over unique parameter pairs ---
|
||||||
|
for k = 1:size(scanRefArray,1)
|
||||||
|
B = scanRefArray(k,1);
|
||||||
|
alpha = scanRefArray(k,2);
|
||||||
|
|
||||||
|
row = find(ismembertol(BFields, B, 1e-6));
|
||||||
|
col = find(ismembertol(alphas, alpha, 1e-6));
|
||||||
|
if isempty(row) || isempty(col), continue; end
|
||||||
|
|
||||||
|
repIdx = find(ismembertol(scanParamArray, [B alpha], 1e-6, 'ByRows', true));
|
||||||
|
if isempty(repIdx), continue; end
|
||||||
|
|
||||||
|
% Extract mean g² across repetitions
|
||||||
|
vals = cellfun(@(x) mean(x, 'omitnan'), dataCell(repIdx));
|
||||||
|
data_matrix(row,col) = mean(vals, 'omitnan');
|
||||||
|
end
|
||||||
|
|
||||||
|
% --- 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]);
|
||||||
|
|
||||||
|
% --- Plot heatmap ---
|
||||||
|
imagesc(alphas, BFields, data_matrix);
|
||||||
|
|
||||||
|
set(gca, ...
|
||||||
|
'FontName', opts.FontName, ...
|
||||||
|
'FontSize', opts.FontSize, ...
|
||||||
|
'YDir', 'normal', ...
|
||||||
|
'ColorScale', opts.ColorScale); % linear or log
|
||||||
|
|
||||||
|
% --- Labels and title ---
|
||||||
|
xlabel(opts.XLabel, 'Interpreter', 'tex', 'FontName', opts.FontName, 'FontSize', opts.FontSize);
|
||||||
|
ylabel(opts.YLabel, 'Interpreter', 'tex', 'FontName', opts.FontName, 'FontSize', opts.FontSize);
|
||||||
|
|
||||||
|
% --- Compute fraction of pi ---
|
||||||
|
theta_factor = theta_query / pi; % e.g., pi/6 -> 1/6
|
||||||
|
|
||||||
|
% --- Format as string ---
|
||||||
|
if abs(round(1/theta_factor) - 1/theta_factor) < 1e-6 % e.g., 1/6
|
||||||
|
theta_str = sprintf('\\pi/%d', round(1/theta_factor));
|
||||||
|
elseif abs(theta_factor - round(theta_factor)) < 1e-6 % e.g., pi or 2*pi
|
||||||
|
theta_str = sprintf('%d\\pi', round(theta_factor));
|
||||||
|
else
|
||||||
|
theta_str = sprintf('%.3g \\pi', theta_factor); % fallback numeric
|
||||||
|
end
|
||||||
|
|
||||||
|
% --- Set title ---
|
||||||
|
title(sprintf('%s | Mean g^{(2)}(\\delta\\theta) at \\delta\\theta = %s', opts.Title, theta_str), ...
|
||||||
|
'FontName', opts.FontName, 'FontSize', opts.FontSize + 2, 'FontWeight', 'bold');
|
||||||
|
|
||||||
|
% --- Colorbar ---
|
||||||
|
colormap(feval(opts.Colormap));
|
||||||
|
if ~isempty(opts.CLim)
|
||||||
|
caxis(opts.CLim);
|
||||||
|
end
|
||||||
|
c = colorbar;
|
||||||
|
|
||||||
|
% --- Save figure ---
|
||||||
|
if ~opts.SkipSaveFigures
|
||||||
|
if ~exist(opts.SaveDirectory,'dir'), mkdir(opts.SaveDirectory); end
|
||||||
|
savefig(fig, fullfile(opts.SaveDirectory, opts.SaveFileName));
|
||||||
|
end
|
||||||
|
end
|
||||||
@ -118,7 +118,7 @@ function plotG2PDF(results, theta_query, varargin)
|
|||||||
end
|
end
|
||||||
|
|
||||||
% --- Set title ---
|
% --- Set title ---
|
||||||
title(sprintf('%s | g^{(2)}(\\delta\\theta) at \\theta = %s', opts.Title, theta_str), ...
|
title(sprintf('%s | g^{(2)}(\\delta\\theta) at \\delta\\theta = %s', opts.Title, theta_str), ...
|
||||||
'FontName', opts.FontName, 'FontSize', opts.FontSize + 2, 'FontWeight', 'bold');
|
'FontName', opts.FontName, 'FontSize', opts.FontSize + 2, 'FontWeight', 'bold');
|
||||||
|
|
||||||
colormap(feval(opts.Colormap));
|
colormap(feval(opts.Colormap));
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
function plotHeatmap(results_all, x_values, y_values, fieldName, varargin)
|
function plotHeatmap(results, scan_parameter_values, scan_reference_values, fieldName, varargin)
|
||||||
%% plotHeatmap: Plots a heatmap for a field in a struct array.
|
%% plotHeatmap: Plots a heatmap for a field in a struct array.
|
||||||
%
|
%
|
||||||
% Usage:
|
% Usage:
|
||||||
% plotHeatmap(results_all, x_values, y_values, fieldName, ...
|
% plotHeatmap(results, scan_parameter_values, scan_reference_values, 'energy', ...
|
||||||
% 'FigNum', 1, 'Colormap', parula, 'CLim', [0 1], ...
|
% 'FigNum', 1, 'Colormap', parula, 'CLim', [0 1], ...
|
||||||
|
% 'ColorScale', 'log', ...
|
||||||
% 'XLabel', '\alpha (degrees)', 'YLabel', 'BField (G)', ...
|
% 'XLabel', '\alpha (degrees)', 'YLabel', 'BField (G)', ...
|
||||||
% 'Title', 'My Title', 'SaveFileName', 'heatmap.fig', ...
|
% 'Title', 'My Title', 'SaveFileName', 'heatmap.fig', ...
|
||||||
% 'SaveDirectory', 'results', 'SkipSaveFigures', false);
|
% 'SaveDirectory', 'results', 'SkipSaveFigures', false);
|
||||||
@ -13,6 +14,7 @@ function plotHeatmap(results_all, x_values, y_values, fieldName, varargin)
|
|||||||
addParameter(p, 'FigNum', []);
|
addParameter(p, 'FigNum', []);
|
||||||
addParameter(p, 'Colormap', parula);
|
addParameter(p, 'Colormap', parula);
|
||||||
addParameter(p, 'CLim', []);
|
addParameter(p, 'CLim', []);
|
||||||
|
addParameter(p, 'ColorScale', 'linear', @(x) any(validatestring(x,{'linear','log'}))); % NEW
|
||||||
addParameter(p, 'XLabel', '\alpha (degrees)');
|
addParameter(p, 'XLabel', '\alpha (degrees)');
|
||||||
addParameter(p, 'YLabel', 'BField (G)');
|
addParameter(p, 'YLabel', 'BField (G)');
|
||||||
addParameter(p, 'Title', fieldName);
|
addParameter(p, 'Title', fieldName);
|
||||||
@ -24,17 +26,32 @@ function plotHeatmap(results_all, x_values, y_values, fieldName, varargin)
|
|||||||
parse(p, varargin{:});
|
parse(p, varargin{:});
|
||||||
opts = p.Results;
|
opts = p.Results;
|
||||||
|
|
||||||
N_y = length(results_all);
|
% --- Convert reference/parameter values to numeric arrays ---
|
||||||
N_x = length(x_values);
|
scanRefArray = cell2mat(scan_reference_values(:)); % nParams × 2
|
||||||
|
scanParamArray = cell2mat(scan_parameter_values(:)); % nTotal × 2
|
||||||
|
|
||||||
|
BFields = sort(unique(scanRefArray(:,1)), 'ascend'); % rows
|
||||||
|
alphas = sort(unique(scanRefArray(:,2)), 'ascend'); % cols
|
||||||
|
nB = numel(BFields);
|
||||||
|
nA = numel(alphas);
|
||||||
|
|
||||||
% --- Preallocate data matrix ---
|
% --- Preallocate data matrix ---
|
||||||
data_matrix = NaN(N_y, N_x);
|
data_matrix = NaN(nB, nA);
|
||||||
for i = 1:N_y
|
|
||||||
if isfield(results_all(i), fieldName)
|
% --- Fill matrix by looping over unique parameter pairs ---
|
||||||
data_matrix(i, :) = results_all(i).(fieldName);
|
for k = 1:size(scanRefArray,1)
|
||||||
else
|
B = scanRefArray(k,1);
|
||||||
warning('Field "%s" does not exist in results_all(%d). Filling with NaN.', fieldName, i);
|
alpha = scanRefArray(k,2);
|
||||||
end
|
|
||||||
|
row = find(ismembertol(BFields, B, 1e-6));
|
||||||
|
col = find(ismembertol(alphas, alpha, 1e-6));
|
||||||
|
if isempty(row) || isempty(col), continue; end
|
||||||
|
|
||||||
|
repIdx = find(ismembertol(scanParamArray, [B alpha], 1e-6, 'ByRows', true));
|
||||||
|
if isempty(repIdx), continue; end
|
||||||
|
|
||||||
|
vals = results.(fieldName)(repIdx);
|
||||||
|
data_matrix(row,col) = mean(vals, 'omitnan');
|
||||||
end
|
end
|
||||||
|
|
||||||
% --- Create figure ---
|
% --- Create figure ---
|
||||||
@ -44,20 +61,24 @@ function plotHeatmap(results_all, x_values, y_values, fieldName, varargin)
|
|||||||
fig = figure(opts.FigNum);
|
fig = figure(opts.FigNum);
|
||||||
end
|
end
|
||||||
clf(fig);
|
clf(fig);
|
||||||
set(fig, 'Color', 'w', 'Position', [50 50 950 750]);
|
set(fig, 'Color', 'w', 'Position', [100 100 950 750]);
|
||||||
|
|
||||||
% --- Plot heatmap ---
|
% --- Plot heatmap ---
|
||||||
imagesc(x_values, y_values, data_matrix);
|
imagesc(alphas, BFields, data_matrix);
|
||||||
colormap(opts.Colormap);
|
colormap(feval(opts.Colormap));
|
||||||
if ~isempty(opts.CLim)
|
if ~isempty(opts.CLim)
|
||||||
caxis(opts.CLim);
|
caxis(opts.CLim);
|
||||||
end
|
end
|
||||||
set(gca, 'FontName', opts.FontName, 'FontSize', opts.FontSize, 'YDir', 'normal');
|
set(gca, ...
|
||||||
|
'FontName', opts.FontName, ...
|
||||||
|
'FontSize', opts.FontSize, ...
|
||||||
|
'YDir', 'normal', ...
|
||||||
|
'ColorScale', opts.ColorScale); % <-- linear or log
|
||||||
|
|
||||||
% --- Labels and title ---
|
% --- Labels and title ---
|
||||||
xlabel(opts.XLabel, 'Interpreter', 'tex', 'FontName', opts.FontName, 'FontSize', opts.FontSize);
|
xlabel(opts.XLabel, 'Interpreter', 'tex', 'FontName', opts.FontName, 'FontSize', opts.FontSize);
|
||||||
ylabel(opts.YLabel, 'Interpreter', 'tex', 'FontName', opts.FontName, 'FontSize', opts.FontSize);
|
ylabel(opts.YLabel, 'Interpreter', 'tex', 'FontName', opts.FontName, 'FontSize', opts.FontSize);
|
||||||
title(opts.Title, 'Interpreter', 'latex', 'FontSize', opts.FontSize + 2, 'FontWeight', 'bold');
|
title(opts.Title, 'Interpreter', 'latex', 'FontName', opts.FontName, 'FontSize', opts.FontSize + 2, 'FontWeight', 'bold');
|
||||||
colorbar;
|
colorbar;
|
||||||
|
|
||||||
% --- Save figure ---
|
% --- Save figure ---
|
||||||
@ -65,5 +86,4 @@ function plotHeatmap(results_all, x_values, y_values, fieldName, varargin)
|
|||||||
'SaveFileName', opts.SaveFileName, ...
|
'SaveFileName', opts.SaveFileName, ...
|
||||||
'SaveDirectory', opts.SaveDirectory, ...
|
'SaveDirectory', opts.SaveDirectory, ...
|
||||||
'SkipSaveFigures', opts.SkipSaveFigures);
|
'SkipSaveFigures', opts.SkipSaveFigures);
|
||||||
|
|
||||||
end
|
end
|
||||||
@ -100,9 +100,9 @@ function plotPDF(dataCell, referenceValues, varargin)
|
|||||||
ylabel(c, 'PDF', 'FontName', opts.FontName, 'FontSize', opts.FontSize);
|
ylabel(c, 'PDF', 'FontName', opts.FontName, 'FontSize', opts.FontSize);
|
||||||
else
|
else
|
||||||
if opts.NormalizeHistogram
|
if opts.NormalizeHistogram
|
||||||
ylabel(c, 'Probability Density', 'FontName', opts.FontName, 'FontSize', opts.FontSize);
|
ylabel(c, 'Probability Density', 'Rotation', -90, 'FontName', opts.FontName, 'FontSize', opts.FontSize);
|
||||||
else
|
else
|
||||||
ylabel(c, 'Counts', 'FontName', opts.FontName, 'FontSize', opts.FontSize);
|
ylabel(c, 'Counts', 'FontName', 'Rotation', -90, opts.FontName, 'FontSize', opts.FontSize);
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
%% --- User chooses which dataset to load ---
|
%% --- 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);
|
datasetName = sprintf('Dataset_%d', datasetIdx);
|
||||||
|
|
||||||
% --- Base directory selection ---
|
% --- Base directory selection ---
|
||||||
|
|||||||
@ -91,9 +91,6 @@ end
|
|||||||
[od_imgs, scan_parameter_values, scan_reference_values, ~] = Helper.collectODImages(options);
|
[od_imgs, scan_parameter_values, scan_reference_values, ~] = Helper.collectODImages(options);
|
||||||
|
|
||||||
% === Plot raw images ===
|
% === Plot raw images ===
|
||||||
n_total = numel(scan_parameter_values);
|
|
||||||
nParams = numel(scan_reference_values);
|
|
||||||
nReps = n_total/nParams;
|
|
||||||
|
|
||||||
% Select every 10th repetition
|
% Select every 10th repetition
|
||||||
selected_reps = [1, 10, 20, 30, 40, 50];
|
selected_reps = [1, 10, 20, 30, 40, 50];
|
||||||
|
|||||||
@ -1,32 +1,99 @@
|
|||||||
BFieldRange = [2.45 2.44 2.43 2.42 2.40 2.39 2.38 2.37 2.36 2.35 2.34 2.32 2.30 2.28 2.25 2.20 2.15 2.10 2.05 2.00 1.95 1.90 1.85 1.80];
|
%% --- User chooses which dataset to load ---
|
||||||
AlphaRange = [180 175 170 168 166 164 162 160 158 156 154 152 150 145 140];
|
datasetIdx = 1; % <-- change this to 1, 2, 3, ...
|
||||||
|
datasetName = sprintf('Dataset_%d', datasetIdx);
|
||||||
|
|
||||||
% Z must be 15x24 to match y-by-x
|
% --- Base directory selection ---
|
||||||
Z = zeros([numel(BFieldRange), numel(AlphaRange)]);... % your data
|
useLocalBaseDir = false; % <-- set true to use script location, false to use manual path
|
||||||
|
|
||||||
[X,Y] = meshgrid(x, y);
|
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\';
|
||||||
|
baseDir = 'C:\Users\Karthik-OfficePC\Documents\GitRepositories\Calculations\Data-Analyzer\+Scripts\PhaseDiagram\Results';
|
||||||
|
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
|
||||||
|
|
||||||
%% ------------------ Plot Heatmaps ------------------
|
%% ------------------ Plot Heatmaps ------------------
|
||||||
|
|
||||||
% Heatmap of radial_spectral_contrast
|
% Heatmap of radial_spectral_contrast
|
||||||
Plotter.plotHeatmap(compiled_results, scan_reference_values, BFields, 'radial_spectral_contrast', ...
|
Plotter.plotHeatmap(compiled_results.spectral_analysis_results, scan_parameter_values, scan_reference_values, 'radial_spectral_contrast', ...
|
||||||
'Colormap', @sky, ...
|
'Colormap', @Colormaps.coolwarm, ...
|
||||||
'CLim', [0 0.008], ...
|
'ColorScale', 'log', ...
|
||||||
'XLabel', '\alpha (degrees)', ...
|
'XLabel', '\alpha (degrees)', ...
|
||||||
'YLabel', 'BField (G)', ...
|
'YLabel', 'BField (G)', ...
|
||||||
'Title', 'Radial Spectral Contrast', ...
|
'Title', 'Radial Spectral Contrast', ...
|
||||||
'FigNum', 10, ...
|
'FontName', options.font, ...
|
||||||
|
'FigNum', 9, ...
|
||||||
'SaveFileName', 'Heatmap_RadialSpectralContrast.fig', ...
|
'SaveFileName', 'Heatmap_RadialSpectralContrast.fig', ...
|
||||||
'SaveDirectory', options.saveDirectory);
|
'SaveDirectory', options.saveDirectory);
|
||||||
|
|
||||||
% Heatmap of mean_max_g2_values
|
%% Heatmap of mean_max_g2_values
|
||||||
Plotter.plotHeatmap(compiled_results, scan_reference_values, BFields, 'mean_max_g2_values', ...
|
Plotter.plotHeatmap(compiled_results.custom_g_results, scan_parameter_values, scan_reference_values, 'mean_max_g2', ...
|
||||||
'Colormap', @sky, ...
|
'Colormap', @Colormaps.coolwarm, ...
|
||||||
'CLim', [0 1], ...
|
'ColorScale', 'linear', ...
|
||||||
'XLabel', '\alpha (degrees)', ...
|
'XLabel', '\alpha (degrees)', ...
|
||||||
'YLabel', 'BField (G)', ...
|
'YLabel', 'BField (G)', ...
|
||||||
'Title', '$\mathrm{max}[g^{(2)}_{[50,70]}(\delta\theta)]$', ...
|
'Title', '$\mathrm{max}[g^{(2)}_{[50,70]}(\delta\theta)]$', ...
|
||||||
'FigNum', 9, ...
|
'FontName', options.font, ...
|
||||||
|
'FigNum', 10, ...
|
||||||
'SaveFileName', 'Heatmap_MaxG2.fig', ...
|
'SaveFileName', 'Heatmap_MaxG2.fig', ...
|
||||||
'SaveDirectory', options.saveDirectory);
|
'SaveDirectory', options.saveDirectory);
|
||||||
|
|
||||||
|
%% Heatmap of mean g2 values as specific theta
|
||||||
|
|
||||||
|
Plotter.plotG2MeanHeatmap(compiled_results.full_g2_results, pi/2, ...
|
||||||
|
scan_parameter_values, scan_reference_values, ...
|
||||||
|
'Colormap', @Colormaps.coolwarm, ...
|
||||||
|
'CLim', [0 1.0], ...
|
||||||
|
'ColorScale', 'log', ...
|
||||||
|
'XLabel', '\alpha (degrees)', ...
|
||||||
|
'YLabel', 'BField (G)', ...
|
||||||
|
'Title', options.titleString, ...
|
||||||
|
'FontName', options.font, ...
|
||||||
|
'FigNum', 11, ...
|
||||||
|
'SaveFileName', 'Heatmap_MeanG2.fig', ...
|
||||||
|
'SaveDirectory', options.saveDirectory);
|
||||||
|
|
||||||
|
%% G2 curves across phase diagram
|
||||||
|
|
||||||
|
Plotter.plotG2CurvesMultiParam(compiled_results.full_g2_results, ...
|
||||||
|
scan_parameter_values, scan_reference_values, ...
|
||||||
|
[2.45, 2.35, 2.32, 2.28], ...
|
||||||
|
[0, 10, 20, 30, 40], ...
|
||||||
|
'FigNum', 12, ...
|
||||||
|
'FontName', options.font, ...
|
||||||
|
'FontSize', 14, ...
|
||||||
|
'Title', options.titleString, ...
|
||||||
|
'Param1Name', 'B', ...
|
||||||
|
'Param2Name', '\alpha', ...
|
||||||
|
'HighlightEvery', 5, ...
|
||||||
|
'SkipSaveFigures', false, ...
|
||||||
|
'SaveFileName', 'G2Curves_PhaseDiagram.fig', ...
|
||||||
|
'SaveDirectory', options.saveDirectory);
|
||||||
|
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
dataSources = {
|
dataSources = {
|
||||||
struct('sequence', 'StructuralPhaseTransition', ...
|
struct('sequence', 'StructuralPhaseTransition', ...
|
||||||
'date', '2025/08/20', ...
|
'date', '2025/08/20', ...
|
||||||
'runs', [2]) % specify run numbers as a string in "" or just as a numeric value
|
'runs', [1]) % specify run numbers as a string in "" or just as a numeric value
|
||||||
};
|
};
|
||||||
|
|
||||||
options = struct();
|
options = struct();
|
||||||
@ -56,7 +56,7 @@ options.skipFullODImagesFolderUse = false;
|
|||||||
options.skipSaveData = false;
|
options.skipSaveData = false;
|
||||||
options.skipSaveFigures = true;
|
options.skipSaveFigures = true;
|
||||||
options.skipSaveProcessedOD = true;
|
options.skipSaveProcessedOD = true;
|
||||||
options.skipLivePlot = true;
|
options.skipLivePlot = false;
|
||||||
options.showProgressBar = true;
|
options.showProgressBar = true;
|
||||||
|
|
||||||
% Extras
|
% Extras
|
||||||
|
|||||||
215
Data-Analyzer/+Scripts/PhaseDiagram/plotODImageGrid.m
Normal file
215
Data-Analyzer/+Scripts/PhaseDiagram/plotODImageGrid.m
Normal file
@ -0,0 +1,215 @@
|
|||||||
|
%% ===== BEC-Droplets-Stripes Settings =====
|
||||||
|
|
||||||
|
% Specify data location to run analysis on
|
||||||
|
dataSources = {
|
||||||
|
struct('sequence', 'StructuralPhaseTransition', ...
|
||||||
|
'date', '2025/08/20', ...
|
||||||
|
'runs', [1]) % specify run numbers as a string in "" or just as a numeric value
|
||||||
|
};
|
||||||
|
|
||||||
|
options = struct();
|
||||||
|
|
||||||
|
% File paths
|
||||||
|
options.baseDataFolder = '//DyLabNAS/Data';
|
||||||
|
options.FullODImagesFolder = 'E:/Data - Experiment/FullODImages/202508';
|
||||||
|
options.measurementName = 'DropletsToStripes';
|
||||||
|
scriptFullPath = mfilename('fullpath');
|
||||||
|
options.saveDirectory = fileparts(scriptFullPath);
|
||||||
|
|
||||||
|
% Camera / imaging settings
|
||||||
|
options.cam = 4; % 1 - ODT_1_Axis_Camera; 2 - ODT_2_Axis_Camera; 3 - Horizontal_Axis_Camera;, 4 - Vertical_Axis_Camera;
|
||||||
|
options.angle = 0; % angle by which image will be rotated
|
||||||
|
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.ImagingMode = 'HighIntensity';
|
||||||
|
options.PulseDuration = 5e-6; % in s
|
||||||
|
|
||||||
|
% Fourier analysis settings
|
||||||
|
options.theta_min = deg2rad(0);
|
||||||
|
options.theta_max = deg2rad(180);
|
||||||
|
options.N_radial_bins = 500;
|
||||||
|
options.Radial_Sigma = 2;
|
||||||
|
options.Radial_WindowSize = 5; % odd number
|
||||||
|
|
||||||
|
options.k_min = 1.2771; % μm⁻¹
|
||||||
|
options.k_max = 2.5541; % μm⁻¹
|
||||||
|
options.N_angular_bins = 180;
|
||||||
|
options.Angular_Threshold = 75;
|
||||||
|
options.Angular_Sigma = 2;
|
||||||
|
options.Angular_WindowSize = 5;
|
||||||
|
options.zoom_size = 50;
|
||||||
|
|
||||||
|
% Flags
|
||||||
|
options.skipUnshuffling = false;
|
||||||
|
options.skipNormalization = false;
|
||||||
|
|
||||||
|
options.skipFringeRemoval = true;
|
||||||
|
options.skipPreprocessing = true;
|
||||||
|
options.skipMasking = true;
|
||||||
|
options.skipIntensityThresholding = true;
|
||||||
|
options.skipBinarization = true;
|
||||||
|
|
||||||
|
options.skipFullODImagesFolderUse = false;
|
||||||
|
options.skipSaveData = false;
|
||||||
|
options.skipSaveFigures = true;
|
||||||
|
options.skipSaveProcessedOD = true;
|
||||||
|
options.skipLivePlot = false;
|
||||||
|
options.showProgressBar = true;
|
||||||
|
|
||||||
|
% Extras
|
||||||
|
options.font = 'Bahnschrift';
|
||||||
|
switch options.measurementName
|
||||||
|
case 'DropletsToStripes'
|
||||||
|
options.ignore_scan_parameter = {'ps_rot_mag_field'}; % Parameter to IGNORE from these - rot_mag_field, ps_rot_mag_field, ps_rot_mag_fin_pol_angle
|
||||||
|
options.flipSortOrder = true;
|
||||||
|
options.scanParameterUnits = {'gauss','degrees'};
|
||||||
|
options.titleString = 'Droplets to Stripes';
|
||||||
|
case 'StripesToDroplets'
|
||||||
|
options.ignore_scan_parameter = {'ps_rot_mag_field'}; % Parameter to IGNORE from these - rot_mag_field, ps_rot_mag_field, ps_rot_mag_fin_pol_angle
|
||||||
|
options.flipSortOrder = false;
|
||||||
|
options.scanParameterUnits = {'gauss','degrees'};
|
||||||
|
options.titleString = 'Stripes to Droplets';
|
||||||
|
end
|
||||||
|
|
||||||
|
%% ===== Collect Images and Launch Viewer =====
|
||||||
|
|
||||||
|
[options.selectedPath, options.folderPath] = Helper.selectDataSourcePath(dataSources, options);
|
||||||
|
|
||||||
|
[od_imgs, scan_parameter_values, scan_reference_values, ~] = Helper.collectODImages(options);
|
||||||
|
|
||||||
|
%% === Plot raw images ===
|
||||||
|
|
||||||
|
% === User selection of BFields and alpha values ===
|
||||||
|
BFieldsToPlot = [2.45, 2.4, 2.35, 2.34, 2.32, 2.3, 2.28]; % [2.45, 2.44, 2.43, 2.42, 2.4, 2.39, 2.38, 2.37, 2.36, 2.35, 2.34, 2.32, 2.3, 2.28, 2.25, 2.2, 2.15, 2.1, 2.05, 2.0, 1.95, 1.90, 1.85, 1.8] G
|
||||||
|
alphasToPlot = [0, 5, 10, 20, 30, 40]; % [0, 5, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 35, 40] degrees
|
||||||
|
|
||||||
|
% --- Convert scan_reference_values (cell array of 1x2) into Nx2 array ---
|
||||||
|
scanRefArray = cell2mat(scan_reference_values(:)); % Nx2
|
||||||
|
scanParamArray = cell2mat(scan_parameter_values(:)); % Nx2
|
||||||
|
|
||||||
|
BFieldVals = scanRefArray(:,1);
|
||||||
|
alphaVals = scanRefArray(:,2);
|
||||||
|
|
||||||
|
% --- Select subset of scan_reference_values to plot ---
|
||||||
|
keepIdx = ismembertol(BFieldVals, BFieldsToPlot, 1e-6) & ...
|
||||||
|
ismembertol(alphaVals, alphasToPlot, 1e-6);
|
||||||
|
|
||||||
|
scan_reference_values_plot = scan_reference_values(keepIdx);
|
||||||
|
nParamsPlot = numel(scan_reference_values_plot);
|
||||||
|
|
||||||
|
% --- Warn about missing values ---
|
||||||
|
existingB = BFieldsToPlot(ismembertol(BFieldsToPlot, unique(BFieldVals), 1e-6));
|
||||||
|
missingB = setdiff(BFieldsToPlot, existingB);
|
||||||
|
|
||||||
|
existingA = alphasToPlot(ismembertol(alphasToPlot, unique(alphaVals), 1e-6));
|
||||||
|
missingA = setdiff(alphasToPlot, existingA);
|
||||||
|
|
||||||
|
if ~isempty(missingB)
|
||||||
|
warning('The following BFields were not found: %s', num2str(missingB));
|
||||||
|
end
|
||||||
|
if ~isempty(missingA)
|
||||||
|
warning('The following alpha values were not found: %s', num2str(missingA));
|
||||||
|
end
|
||||||
|
|
||||||
|
BFieldsPlot = existingB;
|
||||||
|
alphasPlot = existingA;
|
||||||
|
|
||||||
|
% --- Collect all repetitions for each kept parameter ---
|
||||||
|
od_imgs_grouped = cell(nParamsPlot, 1);
|
||||||
|
|
||||||
|
for k = 1:nParamsPlot
|
||||||
|
paramVal = scan_reference_values_plot{k}; % 1x2 vector [BField, alpha]
|
||||||
|
|
||||||
|
% Find all repetitions matching this parameter pair (BField, alpha)
|
||||||
|
repIdx = find(ismembertol(scanParamArray, paramVal, 1e-6, 'ByRows', true));
|
||||||
|
|
||||||
|
% Store images + parameter values
|
||||||
|
od_imgs_grouped{k} = od_imgs(repIdx);
|
||||||
|
end
|
||||||
|
|
||||||
|
% === Plot OD images as a phase diagram ===
|
||||||
|
% Unique values for axes
|
||||||
|
BFieldsPlot = sort(unique(cellfun(@(c) c(1), scan_reference_values_plot)), 'descend'); % y-axis
|
||||||
|
alphasPlot = sort(unique(cellfun(@(c) c(2), scan_reference_values_plot))); % x-axis
|
||||||
|
|
||||||
|
nB = numel(BFieldsPlot);
|
||||||
|
nA = numel(alphasPlot);
|
||||||
|
|
||||||
|
repToPlot = 1; % which repetition to show
|
||||||
|
|
||||||
|
% Create figure
|
||||||
|
figure(300); clf;
|
||||||
|
set(gcf, 'Position', [100 100 950 750]);
|
||||||
|
t = tiledlayout(nB, nA, 'TileSpacing', 'compact', 'Padding', 'compact');
|
||||||
|
|
||||||
|
font = 'Bahnschrift';
|
||||||
|
allAxes = gobjects(nB, nA);
|
||||||
|
|
||||||
|
% Loop over rows (BFields) and columns (alphas)
|
||||||
|
for r = 1:nB
|
||||||
|
B = BFieldsPlot(r);
|
||||||
|
for c = 1:nA
|
||||||
|
alpha = alphasPlot(c);
|
||||||
|
|
||||||
|
ax = nexttile((r-1)*nA + c);
|
||||||
|
allAxes(r,c) = ax;
|
||||||
|
|
||||||
|
% Find the index k corresponding to this (BField, alpha) pair
|
||||||
|
k = find(cellfun(@(v) all(abs(v - [B alpha]) < 1e-6), scan_reference_values_plot), 1);
|
||||||
|
|
||||||
|
if ~isempty(k)
|
||||||
|
img = od_imgs_grouped{k}{repToPlot};
|
||||||
|
imagesc(ax, img);
|
||||||
|
else
|
||||||
|
% If missing, leave blank
|
||||||
|
axis(ax, 'off');
|
||||||
|
continue
|
||||||
|
end
|
||||||
|
|
||||||
|
set(ax, 'YDir', 'normal');
|
||||||
|
axis(ax, 'image');
|
||||||
|
ax.DataAspectRatioMode = 'manual';
|
||||||
|
ax.PlotBoxAspectRatioMode = 'auto';
|
||||||
|
ax.XTick = [];
|
||||||
|
ax.YTick = [];
|
||||||
|
colormap(ax, Colormaps.inferno());
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
% Shared colorbar
|
||||||
|
cb = colorbar('Location', 'eastoutside');
|
||||||
|
ylabel(cb, 'Optical Density');
|
||||||
|
cb.Layout.Tile = 'east';
|
||||||
|
cb.FontName = font;
|
||||||
|
cb.FontSize = 18;
|
||||||
|
cb.Label.FontSize = 20;
|
||||||
|
cb.Label.Rotation = -90;
|
||||||
|
cb.Label.VerticalAlignment = 'bottom';
|
||||||
|
cb.Label.HorizontalAlignment = 'center';
|
||||||
|
cb.Direction = 'normal';
|
||||||
|
|
||||||
|
% Label alpha values along bottom
|
||||||
|
for c = 1:nA
|
||||||
|
ax = allAxes(end, c);
|
||||||
|
ax.XTick = size(img,2)/2;
|
||||||
|
ax.XTickLabel = sprintf('%.0f°', alphasPlot(c));
|
||||||
|
ax.XTickLabelRotation = 45;
|
||||||
|
ax.FontName = font;
|
||||||
|
ax.FontSize = 16;
|
||||||
|
end
|
||||||
|
|
||||||
|
% Label BFields along left
|
||||||
|
for r = 1:nB
|
||||||
|
ax = allAxes(r, 1);
|
||||||
|
ax.YTick = size(img,1)/2;
|
||||||
|
ax.YTickLabel = sprintf('%.2f G', BFieldsPlot(r));
|
||||||
|
ax.FontName = font;
|
||||||
|
ax.FontSize = 16;
|
||||||
|
end
|
||||||
|
|
||||||
|
% Figure title
|
||||||
|
title(t, sprintf('%s', options.titleString), ...
|
||||||
|
'FontSize', 24, 'FontName', font, 'FontWeight', 'bold');
|
||||||
Loading…
x
Reference in New Issue
Block a user