function results = extractFullAngularSpectralDistribution(od_imgs, options) %% extractFullAngularSpectralDistribution % Author: Karthik % Date: 2025-10-09 % Version: 1.0 % % Description: % Computes the angular spectral distribution S(θ) from OD images, % extending θ from 0 → 2π using the computeAngularSpectralDistribution function. % % Inputs: % od_imgs - cell array of OD images % options - struct containing relevant parameters: % pixel_size, magnification, zoom_size, % k_min, k_max, N_angular_bins, % Angular_Threshold, Angular_Sigma % % Outputs: % results - struct containing θ values and angular spectra % % Notes: % This function is a minimal variant of conductSpectralAnalysis, % stopping right after angular spectral extraction. %% ===== Unpack options ===== pixel_size = options.pixel_size; magnification = options.magnification; zoom_size = options.zoom_size; k_min = options.k_min; k_max = options.k_max; N_angular_bins = options.N_angular_bins; Angular_Threshold = options.Angular_Threshold; Angular_Sigma = options.Angular_Sigma; skipPreprocessing = options.skipPreprocessing; skipMasking = options.skipMasking; skipIntensityThresholding = options.skipIntensityThresholding; skipBinarization = options.skipBinarization; %% ===== Initialization ===== N_shots = length(od_imgs); fft_imgs = cell(1, N_shots); S_theta_all = cell(1, N_shots); S_theta_norm_all = cell(1, N_shots); theta_vals = []; %% ===== Main loop ===== for k = 1:N_shots IMG = od_imgs{k}; % Skip empty or low-intensity images if ~(max(IMG(:)) > 1) IMGFFT = NaN(size(IMG)); else % Compute FFT (with same preprocessing pipeline) [IMGFFT, ~] = Calculator.computeFourierTransform(IMG, ... skipPreprocessing, skipMasking, skipIntensityThresholding, skipBinarization); end % Image dimensions [Ny, Nx] = size(IMG); dx = pixel_size / magnification; dy = dx; % Reciprocal-space sampling dvx = 1 / (Nx * dx); dvy = 1 / (Ny * dy); vx = (-floor(Nx/2):ceil(Nx/2)-1) * dvx; vy = (-floor(Ny/2):ceil(Ny/2)-1) * dvy; % Convert to wavenumber axes [µm⁻¹] kx_full = 2 * pi * vx * 1E-6; ky_full = 2 * pi * vy * 1E-6; % Crop FFT and wavenumber axes around center mid_x = floor(Nx/2); mid_y = floor(Ny/2); fft_imgs{k} = IMGFFT(mid_y-zoom_size:mid_y+zoom_size, mid_x-zoom_size:mid_x+zoom_size); kx = kx_full(mid_x - zoom_size : mid_x + zoom_size); ky = ky_full(mid_y - zoom_size : mid_y + zoom_size); % ===== Compute angular spectrum (0 → 2π) ===== [theta_vals, S_theta] = Calculator.computeAngularSpectralDistribution( ... fft_imgs{k}, kx, ky, k_min, k_max, N_angular_bins, ... Angular_Threshold, Angular_Sigma, [], 2*pi); % Normalize angular spectrum and compute weight S_theta_norm = S_theta / max(S_theta); % Store results S_theta_all{k} = S_theta; S_theta_norm_all{k} = S_theta_norm; end %% ===== Package results ===== results = struct(); results.theta_vals = theta_vals; results.S_theta_all = S_theta_all; results.S_theta_norm_all = S_theta_norm_all; end