Modifications in batch analysis script to take sequence name, date and run number, to reuse data saved in workspace and enhancements to image viewer.

This commit is contained in:
Karthik 2025-08-18 16:03:25 +02:00
parent f52666d929
commit 1f7526c594
4 changed files with 101 additions and 45 deletions

View File

@ -9,7 +9,7 @@ function results_all = batchAnalyze(dataSources, options)
options.baseDataFolder = '//DyLabNAS/Data';
end
results_all = struct([]); % one element per folder
results_all = {}; % one element per folder
for i = 1:numel(dataSources)
ds = dataSources{i};
@ -63,7 +63,7 @@ function results_all = batchAnalyze(dataSources, options)
result.results = analysisResults;
% Append to output
results_all(end+1,1) = result;
results_all{end+1,1} = result;
catch ME
warning("Error processing %s/%s/%s: %s", ...

View File

@ -20,6 +20,15 @@ function [ordered_od_imgs, ordered_scan_parameter_values, ordered_file_list] = c
% ordered_od_imgs : cell array of processed OD images (ordered)
% ordered_scan_parameter_values: vector of scan parameter values (ordered)
% ordered_file_list : cell array of file names (ordered)
% --- Early exit if processed data already exist ---
if evalin('base', 'exist(''od_imgs'',''var'') && exist(''scan_parameter_values'',''var'') && exist(''file_list'',''var'')')
fprintf('\nReusing processed OD images, scan parameters, and file list from memory.\n');
ordered_od_imgs = evalin('base','od_imgs');
ordered_scan_parameter_values = evalin('base','scan_parameter_values');
ordered_file_list = evalin('base','file_list');
return; % skip rest of the function
end
% --- Check if the full OD dataset and scan parameters exist in workspace ---
fullDataExists = evalin('base', 'exist(''full_od_imgs'', ''var'')') && ...
@ -39,7 +48,7 @@ function [ordered_od_imgs, ordered_scan_parameter_values, ordered_file_list] = c
fprintf('\nFull OD image dataset or scan parameters not found in memory.\n');
[full_od_imgs, full_bkg_imgs, raw_scan_parameter_values, raw_file_list] = Helper.processRawData(options);
% Optionally save the full dataset into workspace for future reuse
% Save raw full dataset for reuse
assignin('base', 'full_od_imgs', full_od_imgs);
assignin('base', 'full_bkg_imgs', full_bkg_imgs);
assignin('base', 'raw_scan_parameter_values', raw_scan_parameter_values);
@ -103,9 +112,9 @@ function [ordered_od_imgs, ordered_scan_parameter_values, ordered_file_list] = c
ordered_file_list = cell(1, n_total);
counter = 1;
temp_scan_values = raw_scan_parameter_values; % copy for indexing
temp_scan_values = raw_scan_parameter_values;
temp_od_imgs = processed_od_imgs;
temp_file_list = raw_file_list; % copy original file paths for reordering
temp_file_list = raw_file_list;
for rep = 1:n_reps
for val = options.scan_reference_values
@ -113,25 +122,25 @@ function [ordered_od_imgs, ordered_scan_parameter_values, ordered_file_list] = c
if isempty(idx), continue; end
ordered_scan_parameter_values(counter) = temp_scan_values(idx);
ordered_od_imgs{counter} = temp_od_imgs{idx};
ordered_file_list{counter} = temp_file_list{idx}; % reorder file list
temp_scan_values(idx) = NaN; % mark as used
ordered_file_list{counter} = temp_file_list{idx};
temp_scan_values(idx) = NaN;
temp_od_imgs{idx} = [];
temp_file_list{idx} = [];
counter = counter + 1;
end
end
fprintf('\nImage reordering completed.\n');
else
% No unshuffling: keep original order
ordered_od_imgs = processed_od_imgs;
ordered_scan_parameter_values = raw_scan_parameter_values;
ordered_file_list = raw_file_list;
ordered_file_list = raw_file_list;
end
% Optionally save the full dataset into workspace for future reuse
% --- Save processed dataset for reuse ---
assignin('base', 'od_imgs', ordered_od_imgs);
assignin('base', 'scan_parameter_values', ordered_scan_parameter_values);
assignin('base', 'file_list', ordered_file_list);
fprintf('\nOD image dataset ready for further analysis.\n');
end

View File

@ -1,6 +1,10 @@
idx = 1;
compiled_results = results_all{idx}.results;
options.skipSaveFigures = false;
%% ------------------ 1. Mean ± Std Plots ------------------
% Plot Radial Spectral Contrast
Plotter.plotMeanWithSE(scan_parameter_values, results_all.spectral_analysis_results.radial_spectral_contrast, ...
Plotter.plotMeanWithSE(scan_parameter_values, compiled_results.spectral_analysis_results.radial_spectral_contrast, ...
'Title', options.titleString, ...
'XLabel', 'B (G)', ...
'YLabel', 'Radial Spectral Contrast', ...
@ -11,7 +15,7 @@ Plotter.plotMeanWithSE(scan_parameter_values, results_all.spectral_analysis_resu
'SkipSaveFigures', options.skipSaveFigures);
% Plot Angular Spectral Weight
Plotter.plotMeanWithSE(scan_parameter_values, results_all.spectral_analysis_results.angular_spectral_weight, ...
Plotter.plotMeanWithSE(scan_parameter_values, compiled_results.spectral_analysis_results.angular_spectral_weight, ...
'Title', options.titleString, ...
'XLabel', 'B (G)', ...
'YLabel', 'Angular Spectral Weight', ...
@ -22,7 +26,7 @@ Plotter.plotMeanWithSE(scan_parameter_values, results_all.spectral_analysis_resu
'SkipSaveFigures', options.skipSaveFigures);
% Plot Peak Offset Angular Correlation
Plotter.plotMeanWithSE(options.scan_reference_values, results_all.custom_g_results.max_g2_all_per_scan_parameter_value, ...
Plotter.plotMeanWithSE(options.scan_reference_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)]$', ...
@ -34,9 +38,9 @@ Plotter.plotMeanWithSE(options.scan_reference_values, results_all.custom_g_resul
'SkipSaveFigures', options.skipSaveFigures);
%% ------------------ 2. g²(θ) across transition ------------------
Plotter.plotG2(results_all.full_g2_results.g2_all, ...
results_all.full_g2_results.g2_error_all, ...
results_all.full_g2_results.theta_values, ...
Plotter.plotG2(compiled_results.full_g2_results.g2_all, ...
compiled_results.full_g2_results.g2_error_all, ...
compiled_results.full_g2_results.theta_values, ...
options.scan_reference_values, ...
'rot_mag_field', ...
'Title', options.titleString, ...
@ -50,7 +54,7 @@ Plotter.plotG2(results_all.full_g2_results.g2_all, ...
'Colormap', @Colormaps.coolwarm);
%% ------------------ 3. PDF of max g² across transition ------------------
Plotter.plotPDF(results_all.custom_g_results.max_g2_all_per_scan_parameter_value, options.scan_reference_values, ...
Plotter.plotPDF(compiled_results.custom_g_results.max_g2_all_per_scan_parameter_value, options.scan_reference_values, ...
'Title', options.titleString, ...
'XLabel', 'B (G)', ...
'YLabel', '$\mathrm{max}[g^{(2)}]$', ...
@ -67,7 +71,7 @@ Plotter.plotPDF(results_all.custom_g_results.max_g2_all_per_scan_parameter_value
%% ------------------ 4. Cumulants across transition ------------------
Plotter.plotCumulants(options.scan_reference_values, ...
{results_all.custom_g_results.mean_max_g2, results_all.custom_g_results.var_max_g2, results_all.custom_g_results.skew_max_g2_angle, results_all.custom_g_results.fourth_order_cumulant_max_g2}, ...
{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, ...
@ -136,7 +140,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(results_all, options.scan_groups, BFields, 'mean_max_g2_values', ...
Plotter.plotHeatmap(compiled_results, options.scan_groups, BFields, 'mean_max_g2_values', ...
'Colormap', @sky, ...
'CLim', [0 1], ...
'XLabel', '\alpha (degrees)', ...
@ -147,7 +151,7 @@ Plotter.plotHeatmap(results_all, options.scan_groups, BFields, 'mean_max_g2_valu
'SaveDirectory', options.resultsDir);
% Heatmap of radial_spectral_contrast
Plotter.plotHeatmap(results_all, options.scan_groups, BFields, 'radial_spectral_contrast', ...
Plotter.plotHeatmap(compiled_results, options.scan_groups, BFields, 'radial_spectral_contrast', ...
'Colormap', @sky, ...
'CLim', [0 0.008], ...
'XLabel', '\alpha (degrees)', ...

View File

@ -1,10 +1,19 @@
%% ===== BEC-Droplets Settings =====
% 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
};
options = struct();
% File / paths
options.folderPath = "//DyLabNAS/Data/StructuralPhaseTransition/2025/08/13/0062";
options.baseDataFolder = '//DyLabNAS/Data';
options.savefileName = 'BECToDroplets';
options.saveDirectory = "Z:/Users/Karthik/Data-Analyzer/+Scripts";
scriptFullPath = mfilename('fullpath');
options.saveDirectory = fileparts(scriptFullPath);
% Camera / imaging
options.cam = 5;
@ -19,41 +28,40 @@ options.ImagingMode = 'HighIntensity';
options.PulseDuration = 5e-6; % in s
% Fourier analysis settings
% Radial Spectral Distribution
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 for centered moving avg
options.Radial_WindowSize = 5; % odd number
% Angular Spectral Distribution
options.k_min = 1.2771; % in μm¹
options.k_max = 2.5541; % in μm¹
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; % zoomed-in region around center
options.zoom_size = 50;
% Scan parameter
options.scan_parameter = 'rot_mag_field';
if strcmp(options.savefileName, 'BECToDroplets')
options.scan_reference_values = [2.40, 2.39, 2.38, 2.37, 2.35, 2.34, 2.32, 2.30, 2.28, 2.26, 2.24, 2.22, 2.2, 2.15, 2.10, 2.05, 2, 1.95, 1.90, 1.85, 1.8];
options.titleString = 'BEC to Droplets';
elseif strcmp(options.savefileName, 'BECToStripes')
options.scan_reference_values = [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.10, 2.0, 1.90, 1.8];
options.titleString = 'BEC to Stripes';
elseif strcmp(options.savefileName, 'DropletsToStripes')
options.scan_reference_values = [0, 5, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 35, 40];
options.titleString = 'Droplets to Stripes';
elseif strcmp(options.savefileName, 'StripesToDroplets')
options.scan_reference_values = fliplr([0, 5, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 35, 40]);
options.titleString = 'Stripes to Droplets';
switch options.savefileName
case 'BECToDroplets'
options.scan_reference_values = [2.40, 2.39, 2.38, 2.37, 2.35, 2.34, 2.32, 2.30, 2.28, 2.26, 2.24, 2.22, 2.2, 2.15, 2.10, 2.05, 2, 1.95, 1.90, 1.85, 1.8];
options.titleString = 'BEC to Droplets';
case 'BECToStripes'
options.scan_reference_values = [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.10, 2.0, 1.90, 1.8];
options.titleString = 'BEC to Stripes';
case 'DropletsToStripes'
options.scan_reference_values = [0, 5, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 35, 40];
options.titleString = 'Droplets to Stripes';
case 'StripesToDroplets'
options.scan_reference_values = fliplr([0, 5, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 35, 40]);
options.titleString = 'Stripes to Droplets';
end
% Flags
options.skipNormalization = true;
options.skipNormalization = false;
options.skipUnshuffling = false;
options.skipPreprocessing = true;
options.skipMasking = true;
@ -62,14 +70,49 @@ options.skipBinarization = true;
options.skipMovieRender = true;
options.skipSaveFigures = true;
options.skipSaveOD = true;
options.skipLivePlot = false;
options.skipLivePlot = false;
options.showProgressBar = true;
% Optional extras
% Extras
options.font = 'Bahnschrift';
%%
%% ===== Build Paths from Data Sources =====
allPaths = {}; % initialize
for i = 1:length(dataSources)
ds = dataSources{i};
% Split the date string into year/month/day
dateParts = strsplit(ds.date, '/');
for run = ds.runs
runStr = sprintf('%04d', run); % 4-digit run number
fullPath = fullfile(options.baseDataFolder, ds.sequence, dateParts{:}, runStr);
if isfolder(fullPath) % only include valid directories
allPaths{end+1} = fullPath;
else
warning('Path does not exist: %s', fullPath);
end
end
end
% Let user select a single path
set(0,'DefaultUicontrolFontSize',10); % increase default font size
[selectedIndex, tf] = listdlg('PromptString','Select a path to analyze:', ...
'SelectionMode','single', ...
'ListString', allPaths, ...
'ListSize',[400, 300]); % width x height in pixels
if tf
options.folderPath = allPaths{selectedIndex}; % store in options
fprintf('Path set to selection: %s\n', options.folderPath);
else
error('No path selected. Aborting.');
end
%% ===== Collect Images and Launch Viewer =====
[od_imgs, scan_parameter_values, file_list] = Helper.collectODImages(options);
%%
Analyzer.runInteractiveODImageViewer(od_imgs, scan_parameter_values, file_list, options);