Bug fixes, exception handling, new measurement analysis scripts.
This commit is contained in:
parent
1a99ff2c2a
commit
5ff4cbbc2d
@ -2,23 +2,20 @@ function results = conductSpectralAnalysis(od_imgs, scan_parameter_values, optio
|
|||||||
|
|
||||||
%% Performs Fourier analysis on a set of optical density (OD) images.
|
%% Performs Fourier analysis on a set of optical density (OD) images.
|
||||||
% Computes radial and angular spectral distributions, optionally plots
|
% Computes radial and angular spectral distributions, optionally plots
|
||||||
% results, saves figures, and can render a video of the analysis.
|
% results, and saves figures.
|
||||||
%
|
%
|
||||||
% Inputs:
|
% Inputs:
|
||||||
% od_imgs - cell array of OD images
|
% od_imgs - cell array of OD images
|
||||||
% scan_parameter_values - array of scan parameter values corresponding to each image
|
% scan_parameter_values - array of scan parameter values corresponding to each image
|
||||||
% OPTIONS -
|
% OPTIONS -
|
||||||
% saveDirectory - directory to save files
|
% saveDirectory - base directory to save results
|
||||||
% savefileName - base filename for saved figures/video
|
|
||||||
% skipMovieRender - skip creating the video of analysis
|
|
||||||
% skipSaveFigures - skip saving plots
|
% skipSaveFigures - skip saving plots
|
||||||
% skipSaveOD - skip saving OD images as .mat
|
|
||||||
% skipPreprocessing - skip preprocessing of images before FFT
|
% skipPreprocessing - skip preprocessing of images before FFT
|
||||||
% skipMasking - skip masking of OD images
|
% skipMasking - skip masking of OD images
|
||||||
% skipIntensityThresholding- skip thresholding of intensity
|
% skipIntensityThresholding- skip thresholding of intensity
|
||||||
% skipBinarization - skip binarization of OD images
|
% skipBinarization - skip binarization of OD images
|
||||||
% skipNormalization - skip normalization when plotting angular spectrum
|
% skipNormalization - skip normalization when plotting angular spectrum
|
||||||
% skipLivePlot = skip live plotting of figures
|
% skipLivePlot - skip live plotting of figures
|
||||||
% pixel_size - physical pixel size of camera sensor (m)
|
% pixel_size - physical pixel size of camera sensor (m)
|
||||||
% magnification - imaging magnification
|
% magnification - imaging magnification
|
||||||
% zoom_size - number of pixels to crop around FFT center
|
% zoom_size - number of pixels to crop around FFT center
|
||||||
@ -31,8 +28,13 @@ function results = conductSpectralAnalysis(od_imgs, scan_parameter_values, optio
|
|||||||
% Radial_WindowSize - window size for smoothing radial spectrum
|
% Radial_WindowSize - window size for smoothing radial spectrum
|
||||||
% scan_parameter - string, type of scan parameter (used in plot text)
|
% scan_parameter - string, type of scan parameter (used in plot text)
|
||||||
% font - font name for plots
|
% font - font name for plots
|
||||||
|
%
|
||||||
|
% Outputs:
|
||||||
|
% results - struct containing spectra and analysis results
|
||||||
|
% Figures (if enabled) are saved into:
|
||||||
|
% [saveDirectory]/Results/SpectralAnalysisSavedFigures/
|
||||||
|
|
||||||
%% Unpack struct arguments
|
%% ===== Unpack struct arguments =====
|
||||||
pixel_size = options.pixel_size;
|
pixel_size = options.pixel_size;
|
||||||
magnification = options.magnification;
|
magnification = options.magnification;
|
||||||
zoom_size = options.zoom_size;
|
zoom_size = options.zoom_size;
|
||||||
@ -51,10 +53,7 @@ function results = conductSpectralAnalysis(od_imgs, scan_parameter_values, optio
|
|||||||
skipIntensityThresholding = options.skipIntensityThresholding;
|
skipIntensityThresholding = options.skipIntensityThresholding;
|
||||||
skipBinarization = options.skipBinarization;
|
skipBinarization = options.skipBinarization;
|
||||||
skipLivePlot = options.skipLivePlot;
|
skipLivePlot = options.skipLivePlot;
|
||||||
skipMovieRender = options.skipMovieRender;
|
|
||||||
skipSaveFigures = options.skipSaveFigures;
|
skipSaveFigures = options.skipSaveFigures;
|
||||||
skipSaveOD = options.skipSaveOD;
|
|
||||||
savefileName = options.savefileName;
|
|
||||||
saveDirectory = options.saveDirectory;
|
saveDirectory = options.saveDirectory;
|
||||||
scan_parameter = options.scan_parameter;
|
scan_parameter = options.scan_parameter;
|
||||||
font = options.font;
|
font = options.font;
|
||||||
@ -70,33 +69,16 @@ function results = conductSpectralAnalysis(od_imgs, scan_parameter_values, optio
|
|||||||
S_k_all = cell(1, N_shots);
|
S_k_all = cell(1, N_shots);
|
||||||
S_k_smoothed_all = cell(1, N_shots);
|
S_k_smoothed_all = cell(1, N_shots);
|
||||||
S_theta_norm_all = cell(1, N_shots);
|
S_theta_norm_all = cell(1, N_shots);
|
||||||
|
PS_all = cell(1, N_shots); % 2D FFT power spectrum |F(kx,ky)|^2
|
||||||
|
|
||||||
|
|
||||||
% Optional save directory override
|
|
||||||
if ~isempty(saveDirectory)
|
|
||||||
savefileName = fullfile(saveDirectory, savefileName);
|
|
||||||
end
|
|
||||||
|
|
||||||
% Prepare video if enabled
|
|
||||||
if ~skipMovieRender
|
|
||||||
videoFile = VideoWriter([savefileName '.mp4'], 'MPEG-4');
|
|
||||||
videoFile.Quality = 100;
|
|
||||||
videoFile.FrameRate = 2;
|
|
||||||
open(videoFile);
|
|
||||||
end
|
|
||||||
|
|
||||||
% Prepare folder to save figures
|
% Prepare folder to save figures
|
||||||
if ~skipSaveFigures
|
if ~skipSaveFigures
|
||||||
saveFolder = [savefileName '_SavedFigures'];
|
saveFolder = fullfile(saveDirectory, "Results", "SpectralAnalysisSavedFigures");
|
||||||
if ~exist(saveFolder, 'dir')
|
if ~exist(saveFolder, 'dir')
|
||||||
mkdir(saveFolder);
|
mkdir(saveFolder);
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
% Initialize lists for power spectra and radial spectra
|
|
||||||
PS_all = cell(1, N_shots); % 2D FFT power spectrum |F(kx,ky)|^2
|
|
||||||
|
|
||||||
|
|
||||||
%% ===== Main loop over images =====
|
%% ===== Main loop over images =====
|
||||||
for k = 1:N_shots
|
for k = 1:N_shots
|
||||||
IMG = od_imgs{k};
|
IMG = od_imgs{k};
|
||||||
@ -253,29 +235,16 @@ function results = conductSpectralAnalysis(od_imgs, scan_parameter_values, optio
|
|||||||
ax.YMinorGrid = 'on';
|
ax.YMinorGrid = 'on';
|
||||||
end
|
end
|
||||||
|
|
||||||
%% ===== Save outputs =====
|
%% ===== Save figures =====
|
||||||
if ~skipMovieRender
|
|
||||||
frame = getframe(gcf);
|
|
||||||
writeVideo(videoFile, frame);
|
|
||||||
end
|
|
||||||
if ~skipSaveFigures
|
if ~skipSaveFigures
|
||||||
fileNamePNG = fullfile(saveFolder, sprintf('fft_analysis_img_%03d.png', k));
|
fileNamePNG = fullfile(saveFolder, sprintf('fft_analysis_img_%03d.png', k));
|
||||||
print(gcf, fileNamePNG, '-dpng', '-r100');
|
print(gcf, fileNamePNG, '-dpng', '-r100');
|
||||||
end
|
elseif ~skipLivePlot
|
||||||
if ~skipSaveOD
|
|
||||||
odDataStruct = struct();
|
|
||||||
odDataStruct.IMG = IMG;
|
|
||||||
odDataStruct.x = x;
|
|
||||||
odDataStruct.y = y;
|
|
||||||
odDataStruct.scan_parameter_value = scan_parameter_values(k);
|
|
||||||
save(fullfile(saveFolder, sprintf('od_image_%03d.mat', k)), '-struct', 'odDataStruct');
|
|
||||||
end
|
|
||||||
if skipMovieRender && skipSaveFigures
|
|
||||||
pause(0.5);
|
pause(0.5);
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
% Package results into struct
|
% Package results into struct
|
||||||
results = struct();
|
results = struct();
|
||||||
results.kx = kx;
|
results.kx = kx;
|
||||||
results.ky = ky;
|
results.ky = ky;
|
||||||
@ -290,7 +259,4 @@ function results = conductSpectralAnalysis(od_imgs, scan_parameter_values, optio
|
|||||||
results.S_theta_norm_all = S_theta_norm_all;
|
results.S_theta_norm_all = S_theta_norm_all;
|
||||||
results.angular_spectral_weight = angular_spectral_weight;
|
results.angular_spectral_weight = angular_spectral_weight;
|
||||||
|
|
||||||
if ~skipMovieRender
|
|
||||||
close(videoFile);
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
@ -31,17 +31,14 @@ function results = performAnalysis(options)
|
|||||||
options.skipBinarization (1,1) logical
|
options.skipBinarization (1,1) logical
|
||||||
options.skipNormalization (1,1) logical
|
options.skipNormalization (1,1) logical
|
||||||
options.skipLivePlot (1,1) logical
|
options.skipLivePlot (1,1) logical
|
||||||
options.skipMovieRender (1,1) logical
|
|
||||||
options.skipSaveFigures (1,1) logical
|
options.skipSaveFigures (1,1) logical
|
||||||
options.skipSaveOD (1,1) logical
|
|
||||||
options.showProgressBar (1,1) logical
|
options.showProgressBar (1,1) logical
|
||||||
options.savefileName (1,:) char
|
options.measurementName (1,:) char
|
||||||
options.folderPath (1,:) char
|
options.folderPath (1,:) char
|
||||||
options.baseDataFolder (1,:) char
|
options.baseDataFolder (1,:) char
|
||||||
options.saveDirectory (1,:) char
|
options.saveDirectory (1,:) char
|
||||||
options.titleString (1,:) char
|
options.titleString (1,:) char
|
||||||
options.font (1,:) char
|
options.font (1,:) char
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
% Collect OD images
|
% Collect OD images
|
||||||
|
@ -68,7 +68,7 @@ function runInteractiveODImageViewer(od_imgs, scan_parameter_values, file_list,
|
|||||||
shortName = [fname, ext];
|
shortName = [fname, ext];
|
||||||
|
|
||||||
% Update figure title with shot + filename
|
% Update figure title with shot + filename
|
||||||
if strcmp(options.scan_parameter, 'rot_mag_fin_pol_angle')
|
if strcmp(options.scan_parameter, 'ps_rot_mag_fin_pol_angle')
|
||||||
hFig.Name = sprintf('Shot %d | %s', idx, shortName);
|
hFig.Name = sprintf('Shot %d | %s', idx, shortName);
|
||||||
txtHandle.String = sprintf('%.1f^\\circ', scan_parameter_values(idx));
|
txtHandle.String = sprintf('%.1f^\\circ', scan_parameter_values(idx));
|
||||||
else
|
else
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
function [ordered_od_imgs, ordered_scan_parameter_values, ordered_file_list] = collectODImages(options)
|
function [od_imgs, scan_parameter_values, file_list] = collectODImages(options)
|
||||||
%% Applies cropping, background subtraction, and optional fringe removal, optional unshuffling on OD image dataset
|
%% Applies cropping, background subtraction, and optional fringe removal, optional unshuffling on OD image dataset
|
||||||
% Automatically reuses in-memory full dataset if available;
|
% Automatically reuses in-memory full dataset if available;
|
||||||
% otherwise, reads and processes raw HDF5 data.
|
% otherwise, reads and processes raw HDF5 data.
|
||||||
@ -17,17 +17,29 @@ function [ordered_od_imgs, ordered_scan_parameter_values, ordered_file_list] = c
|
|||||||
% .scan_reference_values: reference values for unshuffling
|
% .scan_reference_values: reference values for unshuffling
|
||||||
%
|
%
|
||||||
% Outputs:
|
% Outputs:
|
||||||
% ordered_od_imgs : cell array of processed OD images (ordered)
|
% od_imgs : cell array of processed OD images
|
||||||
% ordered_scan_parameter_values: vector of scan parameter values (ordered)
|
% scan_parameter_values: vector of scan parameter values
|
||||||
% ordered_file_list : cell array of file names (ordered)
|
% file_list : cell array of file names
|
||||||
|
|
||||||
% --- Early exit if processed data already exist ---
|
% --- Early exit if processed data already exist AND options match ---
|
||||||
if evalin('base', 'exist(''od_imgs'',''var'') && exist(''scan_parameter_values'',''var'') && exist(''file_list'',''var'')')
|
reuseVarsExist = evalin('base', ...
|
||||||
fprintf('\nReusing processed OD images, scan parameters, and file list from memory.\n');
|
'exist(''od_imgs'',''var'') && exist(''scan_parameter_values'',''var'') && exist(''file_list'',''var'') && exist(''prior_options'',''var'')');
|
||||||
ordered_od_imgs = evalin('base','od_imgs');
|
|
||||||
ordered_scan_parameter_values = evalin('base','scan_parameter_values');
|
if reuseVarsExist
|
||||||
ordered_file_list = evalin('base','file_list');
|
prior_options = evalin('base','prior_options');
|
||||||
return; % ✅ skip rest of the function
|
|
||||||
|
% Define which fields are critical for reuse
|
||||||
|
critical_fields = {'folderPath','cam','angle','ImagingMode','PulseDuration','center','span','fraction','removeFringes','skipUnshuffling','scan_reference_values'};
|
||||||
|
|
||||||
|
if ~haveOptionsChanged(options, prior_options, critical_fields)
|
||||||
|
fprintf('\nReusing processed OD images, scan parameters, and file list from memory (options unchanged).\n');
|
||||||
|
od_imgs = evalin('base','od_imgs');
|
||||||
|
scan_parameter_values = evalin('base','scan_parameter_values');
|
||||||
|
file_list = evalin('base','file_list');
|
||||||
|
return; % ✅ skip rest of the function
|
||||||
|
else
|
||||||
|
fprintf('\nProcessed-data-related options changed. Reprocessing full OD image dataset...\n');
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
% --- Check if the full OD dataset and scan parameters exist in workspace ---
|
% --- Check if the full OD dataset and scan parameters exist in workspace ---
|
||||||
@ -37,12 +49,29 @@ function [ordered_od_imgs, ordered_scan_parameter_values, ordered_file_list] = c
|
|||||||
evalin('base', 'exist(''raw_file_list'', ''var'')');
|
evalin('base', 'exist(''raw_file_list'', ''var'')');
|
||||||
|
|
||||||
if fullDataExists
|
if fullDataExists
|
||||||
% Both required datasets exist, use them directly
|
% Both required datasets exist, check if raw-data options changed
|
||||||
fprintf('\nReusing full OD image dataset and scan parameters from memory.\n');
|
prior_options = evalin('base','prior_options');
|
||||||
full_od_imgs = evalin('base', 'full_od_imgs');
|
|
||||||
full_bkg_imgs = evalin('base', 'full_bkg_imgs');
|
% Define critical fields that affect raw-data computation
|
||||||
raw_scan_parameter_values = evalin('base', 'raw_scan_parameter_values');
|
critical_raw_fields = {'folderPath','cam','angle','ImagingMode','PulseDuration'};
|
||||||
raw_file_list = evalin('base', 'raw_file_list');
|
|
||||||
|
if ~haveOptionsChanged(options, prior_options, critical_raw_fields)
|
||||||
|
fprintf('\nReusing full OD image dataset and scan parameters from memory.\n');
|
||||||
|
full_od_imgs = evalin('base', 'full_od_imgs');
|
||||||
|
full_bkg_imgs = evalin('base', 'full_bkg_imgs');
|
||||||
|
raw_scan_parameter_values = evalin('base', 'raw_scan_parameter_values');
|
||||||
|
raw_file_list = evalin('base', 'raw_file_list');
|
||||||
|
else
|
||||||
|
fprintf('\nRaw-data-related options changed. Recomputing full OD image dataset...\n');
|
||||||
|
[full_od_imgs, full_bkg_imgs, raw_scan_parameter_values, raw_file_list] = Helper.processRawData(options);
|
||||||
|
|
||||||
|
% 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);
|
||||||
|
assignin('base', 'raw_file_list', raw_file_list);
|
||||||
|
fprintf('\nCompleted recomputing OD images. Stored in workspace for reuse.\n');
|
||||||
|
end
|
||||||
else
|
else
|
||||||
% Either dataset is missing, process raw HDF5 files completely
|
% Either dataset is missing, process raw HDF5 files completely
|
||||||
fprintf('\nFull OD image dataset or scan parameters not found in memory.\n');
|
fprintf('\nFull OD image dataset or scan parameters not found in memory.\n');
|
||||||
@ -53,9 +82,9 @@ function [ordered_od_imgs, ordered_scan_parameter_values, ordered_file_list] = c
|
|||||||
assignin('base', 'full_bkg_imgs', full_bkg_imgs);
|
assignin('base', 'full_bkg_imgs', full_bkg_imgs);
|
||||||
assignin('base', 'raw_scan_parameter_values', raw_scan_parameter_values);
|
assignin('base', 'raw_scan_parameter_values', raw_scan_parameter_values);
|
||||||
assignin('base', 'raw_file_list', raw_file_list);
|
assignin('base', 'raw_file_list', raw_file_list);
|
||||||
fprintf('\nCompleted computing OD images. Stored in workspace for reuse.\n');
|
fprintf('\nCompleted computing OD images and will be stored in workspace for reuse.\n');
|
||||||
end
|
end
|
||||||
|
|
||||||
nFiles = size(full_od_imgs, 3);
|
nFiles = size(full_od_imgs, 3);
|
||||||
|
|
||||||
% --- Preallocate arrays for processed images ---
|
% --- Preallocate arrays for processed images ---
|
||||||
@ -64,20 +93,20 @@ function [ordered_od_imgs, ordered_scan_parameter_values, ordered_file_list] = c
|
|||||||
|
|
||||||
% --- Process each image: crop and subtract background ---
|
% --- Process each image: crop and subtract background ---
|
||||||
for k = 1:nFiles
|
for k = 1:nFiles
|
||||||
od_img = full_od_imgs(:,:,k); % original full OD image, never modified
|
full_od_img = full_od_imgs(:,:,k); % original full OD image, never modified
|
||||||
bkg_img = full_bkg_imgs(:,:,k); % original full background image, never modified
|
full_bkg_img = full_bkg_imgs(:,:,k); % original full background image, never modified
|
||||||
if any(isnan(od_img(:)))
|
if any(isnan(full_od_img(:)))
|
||||||
absimages(:,:,k) = nan(options.span(1)+1, options.span(2)+1, 'single');
|
absimages(:,:,k) = nan(options.span(1)+1, options.span(2)+1, 'single');
|
||||||
continue
|
continue
|
||||||
end
|
end
|
||||||
if any(isnan(bkg_img(:)))
|
if any(isnan(full_bkg_img(:)))
|
||||||
refimages(:,:,k) = nan(options.span(1)+1, options.span(2)+1, 'single');
|
refimages(:,:,k) = nan(options.span(1)+1, options.span(2)+1, 'single');
|
||||||
continue
|
continue
|
||||||
end
|
end
|
||||||
|
|
||||||
% Crop image around the region of interest
|
% Crop image around the region of interest
|
||||||
cropped_absimage = Helper.cropODImage(od_img, options.center, options.span);
|
cropped_absimage = Helper.cropODImage(full_od_img, options.center, options.span);
|
||||||
cropped_refimage = Helper.cropODImage(bkg_img, options.center, options.span);
|
cropped_refimage = Helper.cropODImage(full_bkg_img, options.center, options.span);
|
||||||
|
|
||||||
% Subtract background offset based on fraction
|
% Subtract background offset based on fraction
|
||||||
processed_absimage = Helper.subtractBackgroundOffset(cropped_absimage, options.fraction);
|
processed_absimage = Helper.subtractBackgroundOffset(cropped_absimage, options.fraction);
|
||||||
@ -93,10 +122,10 @@ function [ordered_od_imgs, ordered_scan_parameter_values, ordered_file_list] = c
|
|||||||
fprintf('\nApplying fringe removal to processed images...\n');
|
fprintf('\nApplying fringe removal to processed images...\n');
|
||||||
optrefimages = Helper.removeFringesInImage(absimages, refimages);
|
optrefimages = Helper.removeFringesInImage(absimages, refimages);
|
||||||
absimages_fringe_removed = absimages - optrefimages;
|
absimages_fringe_removed = absimages - optrefimages;
|
||||||
processed_od_imgs = arrayfun(@(i) absimages_fringe_removed(:,:,i), 1:nFiles, 'UniformOutput', false);
|
od_imgs = arrayfun(@(i) absimages_fringe_removed(:,:,i), 1:nFiles, 'UniformOutput', false);
|
||||||
fprintf('\nFringe removal completed.\n');
|
fprintf('\nFringe removal completed.\n');
|
||||||
else
|
else
|
||||||
processed_od_imgs = arrayfun(@(i) absimages(:,:,i), 1:nFiles, 'UniformOutput', false);
|
od_imgs = arrayfun(@(i) absimages(:,:,i), 1:nFiles, 'UniformOutput', false);
|
||||||
end
|
end
|
||||||
|
|
||||||
% --- Optional unshuffling based on scan reference values ---
|
% --- Optional unshuffling based on scan reference values ---
|
||||||
@ -108,12 +137,12 @@ function [ordered_od_imgs, ordered_scan_parameter_values, ordered_file_list] = c
|
|||||||
n_reps = n_total / n_values;
|
n_reps = n_total / n_values;
|
||||||
|
|
||||||
ordered_scan_parameter_values = zeros(1, n_total);
|
ordered_scan_parameter_values = zeros(1, n_total);
|
||||||
ordered_od_imgs = cell(1, n_total);
|
ordered_od_imgs = cell(1, n_total);
|
||||||
ordered_file_list = cell(1, n_total);
|
ordered_file_list = cell(1, n_total);
|
||||||
counter = 1;
|
counter = 1;
|
||||||
|
|
||||||
temp_scan_values = raw_scan_parameter_values;
|
temp_scan_values = raw_scan_parameter_values;
|
||||||
temp_od_imgs = processed_od_imgs;
|
temp_od_imgs = od_imgs;
|
||||||
temp_file_list = raw_file_list;
|
temp_file_list = raw_file_list;
|
||||||
|
|
||||||
for rep = 1:n_reps
|
for rep = 1:n_reps
|
||||||
@ -129,18 +158,51 @@ function [ordered_od_imgs, ordered_scan_parameter_values, ordered_file_list] = c
|
|||||||
counter = counter + 1;
|
counter = counter + 1;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
od_imgs = ordered_od_imgs;
|
||||||
|
scan_parameter_values = ordered_scan_parameter_values;
|
||||||
|
file_list = ordered_file_list;
|
||||||
fprintf('\nImage reordering completed.\n');
|
fprintf('\nImage reordering completed.\n');
|
||||||
else
|
else
|
||||||
% No unshuffling: keep original order
|
% No unshuffling: keep original order
|
||||||
ordered_od_imgs = processed_od_imgs;
|
scan_parameter_values = raw_scan_parameter_values;
|
||||||
ordered_scan_parameter_values = raw_scan_parameter_values;
|
file_list = raw_file_list;
|
||||||
ordered_file_list = raw_file_list;
|
|
||||||
end
|
end
|
||||||
|
|
||||||
% --- Save processed dataset for reuse ---
|
% --- Save processed dataset and options for reuse ---
|
||||||
assignin('base', 'od_imgs', ordered_od_imgs);
|
assignin('base', 'od_imgs', od_imgs);
|
||||||
assignin('base', 'scan_parameter_values', ordered_scan_parameter_values);
|
assignin('base', 'scan_parameter_values', scan_parameter_values);
|
||||||
assignin('base', 'file_list', ordered_file_list);
|
assignin('base', 'file_list', file_list);
|
||||||
|
assignin('base', 'prior_options', options);
|
||||||
|
|
||||||
|
% --- Optionally save OD images as figures ---
|
||||||
|
if ~options.skipSaveFigures
|
||||||
|
odFolder = fullfile(saveDirectory, "Results", "ODImages");
|
||||||
|
if ~exist(odFolder, 'dir')
|
||||||
|
mkdir(odFolder);
|
||||||
|
end
|
||||||
|
|
||||||
|
for k = 1:length(od_imgs)
|
||||||
|
img = od_imgs{k};
|
||||||
|
fileName = fullfile(odFolder, sprintf('OD_img_%03d.png', k));
|
||||||
|
imwrite(mat2gray(img), fileName);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
fprintf('\nOD image dataset ready for further analysis.\n');
|
fprintf('\nOD image dataset ready for further analysis.\n');
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
% --- Local helper function to compare options ---
|
||||||
|
function changed = haveOptionsChanged(options, prior_options, critical_fields)
|
||||||
|
changed = false;
|
||||||
|
for f = critical_fields
|
||||||
|
fname = f{1};
|
||||||
|
if isfield(options, fname) && isfield(prior_options, fname)
|
||||||
|
if ~isequal(options.(fname), prior_options.(fname))
|
||||||
|
changed = true; return
|
||||||
|
end
|
||||||
|
elseif xor(isfield(options, fname), isfield(prior_options, fname))
|
||||||
|
changed = true; return
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
@ -25,20 +25,12 @@ function plotAverageSpectra(scan_parameter_values, spectral_analysis_results, va
|
|||||||
addParameter(p, 'FigNum', 1, @(x) isnumeric(x) && isscalar(x));
|
addParameter(p, 'FigNum', 1, @(x) isnumeric(x) && isscalar(x));
|
||||||
addParameter(p, 'ColormapPS', Colormaps.coolwarm(), @(x) isnumeric(x) || ismatrix(x));
|
addParameter(p, 'ColormapPS', Colormaps.coolwarm(), @(x) isnumeric(x) || ismatrix(x));
|
||||||
addParameter(p, 'Font', 'Arial', @ischar);
|
addParameter(p, 'Font', 'Arial', @ischar);
|
||||||
addParameter(p, 'SaveFileName', 'figure.fig', @ischar);
|
addParameter(p, 'SaveFileName', 'avgspectra.fig', @ischar);
|
||||||
addParameter(p, 'SaveDirectory', pwd, @ischar);
|
addParameter(p, 'SaveDirectory', pwd, @ischar);
|
||||||
addParameter(p, 'SkipSaveFigures', false, @islogical);
|
addParameter(p, 'SkipSaveFigures', false, @islogical);
|
||||||
parse(p, varargin{:});
|
parse(p, varargin{:});
|
||||||
opts = p.Results;
|
opts = p.Results;
|
||||||
|
|
||||||
scanParam = opts.ScanParameterName;
|
|
||||||
figNum = opts.FigNum;
|
|
||||||
colormapPS = opts.ColormapPS;
|
|
||||||
fontName = opts.Font;
|
|
||||||
saveFileName = opts.SaveFileName;
|
|
||||||
saveDirectory = opts.SaveDirectory;
|
|
||||||
skipSaveFigures = opts.SkipSaveFigures;
|
|
||||||
|
|
||||||
% --- Unique scan parameters ---
|
% --- Unique scan parameters ---
|
||||||
[uniqueParams, ~, idx] = unique(scan_parameter_values);
|
[uniqueParams, ~, idx] = unique(scan_parameter_values);
|
||||||
nParams = numel(uniqueParams);
|
nParams = numel(uniqueParams);
|
||||||
@ -67,7 +59,7 @@ function plotAverageSpectra(scan_parameter_values, spectral_analysis_results, va
|
|||||||
avgS_theta = avgS_theta / nShots;
|
avgS_theta = avgS_theta / nShots;
|
||||||
|
|
||||||
% ==== Plot ====
|
% ==== Plot ====
|
||||||
fig = figure(figNum); clf;
|
fig = figure(opts.FigNum); clf;
|
||||||
set(fig, 'Color', 'w', 'Position', [400 200 1200 400]);
|
set(fig, 'Color', 'w', 'Position', [400 200 1200 400]);
|
||||||
tLayout = tiledlayout(1,3,'TileSpacing','compact','Padding','compact');
|
tLayout = tiledlayout(1,3,'TileSpacing','compact','Padding','compact');
|
||||||
|
|
||||||
@ -79,14 +71,14 @@ function plotAverageSpectra(scan_parameter_values, spectral_analysis_results, va
|
|||||||
imagesc(kx, ky, log(1 + avgPS));
|
imagesc(kx, ky, log(1 + avgPS));
|
||||||
axis image;
|
axis image;
|
||||||
set(gca, 'FontSize', axisFontSize, 'YDir', 'normal');
|
set(gca, 'FontSize', axisFontSize, 'YDir', 'normal');
|
||||||
xlabel('k_x [\mum^{-1}]','Interpreter','tex','FontSize',axisFontSize,'FontName',fontName);
|
xlabel('k_x [\mum^{-1}]','Interpreter','tex','FontSize',axisFontSize,'FontName',opts.Font);
|
||||||
ylabel('k_y [\mum^{-1}]','Interpreter','tex','FontSize',axisFontSize,'FontName',fontName);
|
ylabel('k_y [\mum^{-1}]','Interpreter','tex','FontSize',axisFontSize,'FontName',opts.Font);
|
||||||
title('Average Power Spectrum','FontSize',titleFontSize,'FontWeight','bold');
|
title('Average Power Spectrum','FontSize',titleFontSize,'FontWeight','bold');
|
||||||
colormap(colormapPS);
|
colormap(opts.ColormapPS);
|
||||||
colorbar;
|
colorbar;
|
||||||
|
|
||||||
% --- Annotate scan parameter ---
|
% --- Annotate scan parameter ---
|
||||||
if strcmp(scanParam,'ps_rot_mag_fin_pol_angle')
|
if strcmp(opts.ScanParameterName,'ps_rot_mag_fin_pol_angle')
|
||||||
txt = sprintf('%.1f^\\circ', currentParam);
|
txt = sprintf('%.1f^\\circ', currentParam);
|
||||||
else
|
else
|
||||||
txt = sprintf('%.2f G', currentParam);
|
txt = sprintf('%.2f G', currentParam);
|
||||||
@ -119,8 +111,8 @@ function plotAverageSpectra(scan_parameter_values, spectral_analysis_results, va
|
|||||||
|
|
||||||
% --- Save figure ---
|
% --- Save figure ---
|
||||||
saveFigure(fig, ...
|
saveFigure(fig, ...
|
||||||
'SaveFileName', saveFileName, ...
|
'SaveFileName', opts.SaveFileName, ...
|
||||||
'SaveDirectory', saveDirectory, ...
|
'SaveDirectory', opts.SaveDirectory, ...
|
||||||
'SkipSaveFigures', skipSaveFigures);
|
'SkipSaveFigures', opts.SkipSaveFigures);
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -10,10 +10,10 @@ dataSources = {
|
|||||||
options = struct();
|
options = struct();
|
||||||
|
|
||||||
% File / paths
|
% File / paths
|
||||||
options.baseDataFolder = '//DyLabNAS/Data';
|
options.baseDataFolder = '//DyLabNAS/Data';
|
||||||
options.savefileName = 'BECToDroplets';
|
options.measurementName = 'BECToDroplets';
|
||||||
scriptFullPath = mfilename('fullpath');
|
scriptFullPath = mfilename('fullpath');
|
||||||
options.saveDirectory = fileparts(scriptFullPath);
|
options.saveDirectory = fileparts(scriptFullPath);
|
||||||
|
|
||||||
% Camera / imaging
|
% Camera / imaging
|
||||||
options.cam = 5;
|
options.cam = 5;
|
||||||
@ -45,7 +45,7 @@ options.zoom_size = 50;
|
|||||||
% Scan parameter
|
% Scan parameter
|
||||||
options.scan_parameter = 'rot_mag_field';
|
options.scan_parameter = 'rot_mag_field';
|
||||||
|
|
||||||
switch options.savefileName
|
switch options.measurementName
|
||||||
case 'BECToDroplets'
|
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.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';
|
options.titleString = 'BEC to Droplets';
|
||||||
|
@ -10,10 +10,10 @@ dataSources = {
|
|||||||
options = struct();
|
options = struct();
|
||||||
|
|
||||||
% File / paths
|
% File / paths
|
||||||
options.baseDataFolder = '//DyLabNAS/Data';
|
options.baseDataFolder = '//DyLabNAS/Data';
|
||||||
options.savefileName = 'BECToDroplets';
|
options.measurementName = 'BECToDroplets';
|
||||||
scriptFullPath = mfilename('fullpath');
|
scriptFullPath = mfilename('fullpath');
|
||||||
options.saveDirectory = fileparts(scriptFullPath);
|
options.saveDirectory = fileparts(scriptFullPath);
|
||||||
|
|
||||||
% Camera / imaging
|
% Camera / imaging
|
||||||
options.cam = 5;
|
options.cam = 5;
|
||||||
@ -45,7 +45,7 @@ options.zoom_size = 50;
|
|||||||
% Scan parameter
|
% Scan parameter
|
||||||
options.scan_parameter = 'rot_mag_field';
|
options.scan_parameter = 'rot_mag_field';
|
||||||
|
|
||||||
switch options.savefileName
|
switch options.measurementName
|
||||||
case 'BECToDroplets'
|
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.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';
|
options.titleString = 'BEC to Droplets';
|
||||||
|
@ -0,0 +1,163 @@
|
|||||||
|
idx = 1;
|
||||||
|
compiled_results = results_all{idx}.results;
|
||||||
|
options.skipSaveFigures = false;
|
||||||
|
|
||||||
|
%% ------------------ 1. Mean ± Std Plots ------------------
|
||||||
|
% Plot Radial Spectral Contrast
|
||||||
|
Plotter.plotMeanWithSE(scan_parameter_values, compiled_results.spectral_analysis_results.radial_spectral_contrast, ...
|
||||||
|
'Title', options.titleString, ...
|
||||||
|
'XLabel', 'B (G)', ...
|
||||||
|
'YLabel', 'Radial Spectral Contrast', ...
|
||||||
|
'FigNum', 1, ...
|
||||||
|
'FontName', options.font, ...
|
||||||
|
'SaveFileName', 'RadialSpectralContrast.fig', ...
|
||||||
|
'SaveDirectory', [options.saveDirectory '/Results'], ...
|
||||||
|
'SkipSaveFigures', options.skipSaveFigures);
|
||||||
|
|
||||||
|
% Plot Angular Spectral Weight
|
||||||
|
Plotter.plotMeanWithSE(scan_parameter_values, compiled_results.spectral_analysis_results.angular_spectral_weight, ...
|
||||||
|
'Title', options.titleString, ...
|
||||||
|
'XLabel', 'B (G)', ...
|
||||||
|
'YLabel', 'Angular Spectral Weight', ...
|
||||||
|
'FigNum', 2, ...
|
||||||
|
'FontName', options.font, ...
|
||||||
|
'SaveFileName', 'AngularSpectralWeight.fig', ...
|
||||||
|
'SaveDirectory', [options.saveDirectory '/Results'], ...
|
||||||
|
'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, ...
|
||||||
|
'Title', options.titleString, ...
|
||||||
|
'XLabel', 'B (G)', ...
|
||||||
|
'YLabel', '$\mathrm{max}[g^{(2)}_{[50,70]}(\delta\theta)]$', ...
|
||||||
|
'FigNum', 3, ...
|
||||||
|
'YLim', [0 1], ...
|
||||||
|
'FontName', options.font, ...
|
||||||
|
'SaveFileName', 'PeakOffsetAngularCorrelation.fig', ...
|
||||||
|
'SaveDirectory', [options.saveDirectory '/Results'], ...
|
||||||
|
'SkipSaveFigures', options.skipSaveFigures);
|
||||||
|
|
||||||
|
%% ------------------ 2. g²(θ) across transition ------------------
|
||||||
|
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, ...
|
||||||
|
'XLabel', '$\delta\theta / \pi$', ...
|
||||||
|
'YLabel', '$g^{(2)}(\delta\theta)$', ...
|
||||||
|
'FigNum', 4, ...
|
||||||
|
'FontName', options.font, ...
|
||||||
|
'SkipSaveFigures', options.skipSaveFigures, ...
|
||||||
|
'SaveFileName', 'G2ThetaAcrossTransition.fig', ...
|
||||||
|
'SaveDirectory', [options.saveDirectory '/Results'], ...
|
||||||
|
'Colormap', @Colormaps.coolwarm);
|
||||||
|
|
||||||
|
%% ------------------ 3. PDF of max g² across transition ------------------
|
||||||
|
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)}]$', ...
|
||||||
|
'FigNum', 5, ...
|
||||||
|
'FontName', options.font, ...
|
||||||
|
'SkipSaveFigures', options.skipSaveFigures, ...
|
||||||
|
'SaveFileName', 'PDF_MaxG2AcrossTransition.fig', ...
|
||||||
|
'SaveDirectory', [options.saveDirectory '/Results'], ...
|
||||||
|
'NumPoints', 200, ...
|
||||||
|
'DataRange', [0 1.5], ...
|
||||||
|
'Colormap', @Colormaps.coolwarm, ...
|
||||||
|
'XLim', [min(options.scan_reference_values) max(options.scan_reference_values)]);
|
||||||
|
|
||||||
|
|
||||||
|
%% ------------------ 4. Cumulants across transition ------------------
|
||||||
|
Plotter.plotCumulants(options.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, ...
|
||||||
|
'FontName', options.font, ...
|
||||||
|
'MarkerSize', 6, ...
|
||||||
|
'LineWidth', 1.5, ...
|
||||||
|
'SkipSaveFigures', options.skipSaveFigures, ...
|
||||||
|
'SaveFileName', 'CumulantOfPeakOffsetAngularCorrelation.fig', ...
|
||||||
|
'SaveDirectory', [options.saveDirectory '/Results']);
|
||||||
|
%{
|
||||||
|
|
||||||
|
%% ------------------ 6. Average of Spectra Plots ------------------
|
||||||
|
|
||||||
|
Plotter.plotAverageSpectra(scan_parameter_values, ...
|
||||||
|
spectral_analysis_results, ...
|
||||||
|
'ScanParameterName', scan_parameter, ...
|
||||||
|
'FigNum', 7, ...
|
||||||
|
'ColormapPS', Colormaps.coolwarm(), ...
|
||||||
|
'Font', 'Bahnschrift', ...
|
||||||
|
'SaveFileName', 'avgSpectra.fig', ...
|
||||||
|
'SaveDirectory', [options.saveDirectory '/Results'], ...
|
||||||
|
'SkipSaveFigures', options.skipSaveFigures);
|
||||||
|
|
||||||
|
%% ------------------ 7. Compare quantities ------------------
|
||||||
|
% Load Droplets → Stripes data
|
||||||
|
Data = load(dtsFile, ...
|
||||||
|
'unique_scan_parameter_values', ...
|
||||||
|
'mean_max_g2_values', ...
|
||||||
|
'std_error_g2_values');
|
||||||
|
dts_scan_parameter_values = Data.unique_scan_parameter_values;
|
||||||
|
dts_mean_mg2 = Data.mean_max_g2_values;
|
||||||
|
dts_stderr_mg2 = Data.std_error_g2_values;
|
||||||
|
|
||||||
|
% Load Stripes → Droplets data
|
||||||
|
Data = load(stdFile, ...
|
||||||
|
'unique_scan_parameter_values', ...
|
||||||
|
'mean_max_g2_values', ...
|
||||||
|
'std_error_g2_values');
|
||||||
|
std_scan_parameter_values = Data.unique_scan_parameter_values;
|
||||||
|
std_mean_mg2 = Data.mean_max_g2_values;
|
||||||
|
std_stderr_mg2 = Data.std_error_g2_values;
|
||||||
|
|
||||||
|
% Prepare cell arrays for multiple datasets
|
||||||
|
scanValsCell = {dts_scan_parameter_values, std_scan_parameter_values};
|
||||||
|
meanValsCell = {dts_mean_mg2, std_mean_mg2};
|
||||||
|
stderrValsCell = {dts_stderr_mg2, std_stderr_mg2};
|
||||||
|
|
||||||
|
% Compare datasets
|
||||||
|
compareMultipleDatasets(scanValsCell, meanValsCell, stderrValsCell, ...
|
||||||
|
'FigNum', 8, ...
|
||||||
|
'FontName', 'Bahnschrift', ...
|
||||||
|
'MarkerSize', 6, ...
|
||||||
|
'LineWidth', 1.5, ...
|
||||||
|
'CapSize', 5, ...
|
||||||
|
'YLim', [0 1], ...
|
||||||
|
'Labels', {'Droplets → Stripes', 'Stripes → Droplets'}, ...
|
||||||
|
'Title', 'AngularCorrelation_Comparison', ...
|
||||||
|
'XLabel', 'B (G)', ...
|
||||||
|
'YLabel', '$\mathrm{max}[g^{(2)}_{[50,70]}(\delta\theta)]$', ...
|
||||||
|
'SkipSaveFigures', options.skipSaveFigures, ...
|
||||||
|
'SaveDirectory', [options.saveDirectory '/Results'], ...
|
||||||
|
'SaveFileName', 'AngularCorrelation_Comparison.fig');
|
||||||
|
|
||||||
|
%% ------------------ 8. Heatmaps ------------------
|
||||||
|
|
||||||
|
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', ...
|
||||||
|
'Colormap', @sky, ...
|
||||||
|
'CLim', [0 1], ...
|
||||||
|
'XLabel', '\alpha (degrees)', ...
|
||||||
|
'YLabel', 'BField (G)', ...
|
||||||
|
'Title', '$\mathrm{max}[g^{(2)}_{[50,70]}(\delta\theta)]$', ...
|
||||||
|
'FigNum', 9, ...
|
||||||
|
'SaveFileName', 'Heatmap_MaxG2.fig', ...
|
||||||
|
'SaveDirectory', options.resultsDir);
|
||||||
|
|
||||||
|
% Heatmap of radial_spectral_contrast
|
||||||
|
Plotter.plotHeatmap(compiled_results, options.scan_groups, BFields, 'radial_spectral_contrast', ...
|
||||||
|
'Colormap', @sky, ...
|
||||||
|
'CLim', [0 0.008], ...
|
||||||
|
'XLabel', '\alpha (degrees)', ...
|
||||||
|
'YLabel', 'BField (G)', ...
|
||||||
|
'Title', 'Radial Spectral Contrast', ...
|
||||||
|
'FigNum', 10, ...
|
||||||
|
'SaveFileName', 'Heatmap_RadialSpectralContrast.fig', ...
|
||||||
|
'SaveDirectory', options.resultsDir);
|
||||||
|
%}
|
116
Data-Analyzer/+Scripts/BECToDropletsToStripes/plotImages.m
Normal file
116
Data-Analyzer/+Scripts/BECToDropletsToStripes/plotImages.m
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
%% ===== BEC-Droplets-Stripes Settings =====
|
||||||
|
|
||||||
|
% Specify data location to run analysis on
|
||||||
|
dataSources = {
|
||||||
|
struct('sequence', 'StructuralPhaseTransition', ...
|
||||||
|
'date', '2025/08/16', ...
|
||||||
|
'runs', [8]) % specify run numbers as a string in "" or just as a numeric value
|
||||||
|
};
|
||||||
|
|
||||||
|
options = struct();
|
||||||
|
|
||||||
|
% File / paths
|
||||||
|
options.baseDataFolder = '//DyLabNAS/Data';
|
||||||
|
options.measurementName = 'DropletsToStripes';
|
||||||
|
scriptFullPath = mfilename('fullpath');
|
||||||
|
options.saveDirectory = fileparts(scriptFullPath);
|
||||||
|
|
||||||
|
% Camera / imaging
|
||||||
|
options.cam = 5;
|
||||||
|
options.angle = 0;
|
||||||
|
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.removeFringes = false;
|
||||||
|
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;
|
||||||
|
|
||||||
|
% Scan parameter
|
||||||
|
options.scan_parameter = 'ps_rot_mag_fin_pol_angle';
|
||||||
|
|
||||||
|
switch options.measurementName
|
||||||
|
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 = false;
|
||||||
|
options.skipUnshuffling = false;
|
||||||
|
options.skipPreprocessing = true;
|
||||||
|
options.skipMasking = true;
|
||||||
|
options.skipIntensityThresholding = true;
|
||||||
|
options.skipBinarization = true;
|
||||||
|
options.skipSaveFigures = false;
|
||||||
|
options.skipLivePlot = false;
|
||||||
|
options.showProgressBar = true;
|
||||||
|
|
||||||
|
% 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);
|
@ -0,0 +1,78 @@
|
|||||||
|
%% ===== BEC-Droplets-Stripes Settings =====
|
||||||
|
|
||||||
|
% Specify data location to run analysis on
|
||||||
|
dataSources = {
|
||||||
|
struct('sequence', 'StructuralPhaseTransition', ...
|
||||||
|
'date', '2025/08/16', ...
|
||||||
|
'runs', [8]) % specify run numbers as a string in "" or just as a numeric value
|
||||||
|
};
|
||||||
|
|
||||||
|
options = struct();
|
||||||
|
|
||||||
|
% File / paths
|
||||||
|
options.baseDataFolder = '//DyLabNAS/Data';
|
||||||
|
options.measurementName = 'DropletsToStripes';
|
||||||
|
scriptFullPath = mfilename('fullpath');
|
||||||
|
options.saveDirectory = fileparts(scriptFullPath);
|
||||||
|
|
||||||
|
% Camera / imaging
|
||||||
|
options.cam = 5;
|
||||||
|
options.angle = 0;
|
||||||
|
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.removeFringes = false;
|
||||||
|
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;
|
||||||
|
|
||||||
|
% Scan parameter
|
||||||
|
options.scan_parameter = 'ps_rot_mag_fin_pol_angle';
|
||||||
|
|
||||||
|
switch options.measurementName
|
||||||
|
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 = false;
|
||||||
|
options.skipUnshuffling = false;
|
||||||
|
options.skipPreprocessing = true;
|
||||||
|
options.skipMasking = true;
|
||||||
|
options.skipIntensityThresholding = true;
|
||||||
|
options.skipBinarization = true;
|
||||||
|
options.skipSaveFigures = false;
|
||||||
|
options.skipLivePlot = false;
|
||||||
|
options.showProgressBar = true;
|
||||||
|
|
||||||
|
% Extras
|
||||||
|
options.font = 'Bahnschrift';
|
||||||
|
|
||||||
|
%% ===== Run Batch Analysis =====
|
||||||
|
results_all = Helper.batchAnalyze(dataSources, options);
|
@ -10,10 +10,10 @@ dataSources = {
|
|||||||
options = struct();
|
options = struct();
|
||||||
|
|
||||||
% File / paths
|
% File / paths
|
||||||
options.baseDataFolder = '//DyLabNAS/Data';
|
options.baseDataFolder = '//DyLabNAS/Data';
|
||||||
options.savefileName = 'BECToDroplets';
|
options.measurementName = 'BECToDroplets';
|
||||||
scriptFullPath = mfilename('fullpath');
|
scriptFullPath ´= mfilename('fullpath');
|
||||||
options.saveDirectory = fileparts(scriptFullPath);
|
options.saveDirectory = fileparts(scriptFullPath);
|
||||||
|
|
||||||
% Camera / imaging
|
% Camera / imaging
|
||||||
options.cam = 5;
|
options.cam = 5;
|
||||||
@ -45,7 +45,7 @@ options.zoom_size = 50;
|
|||||||
% Scan parameter
|
% Scan parameter
|
||||||
options.scan_parameter = 'rot_mag_field';
|
options.scan_parameter = 'rot_mag_field';
|
||||||
|
|
||||||
switch options.savefileName
|
switch options.measurementName
|
||||||
case 'BECToDroplets'
|
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.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';
|
options.titleString = 'BEC to Droplets';
|
||||||
|
@ -10,10 +10,10 @@ dataSources = {
|
|||||||
options = struct();
|
options = struct();
|
||||||
|
|
||||||
% File / paths
|
% File / paths
|
||||||
options.baseDataFolder = '//DyLabNAS/Data';
|
options.baseDataFolder = '//DyLabNAS/Data';
|
||||||
options.savefileName = 'BECToStripes';
|
options.measurementName = 'BECToStripes';
|
||||||
scriptFullPath = mfilename('fullpath');
|
scriptFullPath = mfilename('fullpath');
|
||||||
options.saveDirectory = fileparts(scriptFullPath);
|
options.saveDirectory = fileparts(scriptFullPath);
|
||||||
|
|
||||||
% Camera / imaging
|
% Camera / imaging
|
||||||
options.cam = 5;
|
options.cam = 5;
|
||||||
@ -45,7 +45,7 @@ options.zoom_size = 50;
|
|||||||
% Scan parameter
|
% Scan parameter
|
||||||
options.scan_parameter = 'rot_mag_field';
|
options.scan_parameter = 'rot_mag_field';
|
||||||
|
|
||||||
switch options.savefileName
|
switch options.measurementName
|
||||||
case 'BECToDroplets'
|
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.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';
|
options.titleString = 'BEC to Droplets';
|
||||||
|
Loading…
Reference in New Issue
Block a user