function results = extractFullRadialSpectralDistribution(od_imgs, options)
%% extractFullRadialSpectralDistribution
% Author:       Karthik
% Date:         2025-10-15
% Version:      1.0
%
% Description:
%   Computes the radial spectral distribution S(k) from OD images
%
% Inputs:
%   od_imgs   - cell array of OD images
%   options   - struct containing relevant parameters:
%                 pixel_size, magnification, zoom_size,
%                 theta_min, theta_max, N_radial_bins, Radial_WindowSize
%
% Outputs:
%   results   - struct containing k_rho values and radial spectra
%
% Notes:
%   This function is a minimal variant of conductSpectralAnalysis,
%   stopping right after radial spectral dsitribution extraction.

    %% ===== Unpack options =====
    pixel_size        = options.pixel_size;
    magnification     = options.magnification;
    zoom_size         = options.zoom_size;
    theta_min         = options.theta_min;
    theta_max         = options.theta_max;
    N_radial_bins      = options.N_radial_bins;
    radial_window_size = options.Radial_WindowSize;
    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_k_all           = cell(1, N_shots);
    S_k_smoothed_all  = cell(1, N_shots);
    k_rho_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 radial spectrum =====
        [k_rho_vals, S_k]           = Calculator.computeRadialSpectralDistribution(...
            fft_imgs{k}, kx, ky, theta_min, theta_max, N_radial_bins);
        
        % Smooth radial spectrum
        S_k_smoothed                = movmean(S_k, radial_window_size);

        % Store results
        S_k_all{k}                  = S_k;
        S_k_smoothed_all{k}         = S_k_smoothed;
    end

    %% ===== Package results =====
    results = struct();
    results.k_rho_vals          = k_rho_vals;
    results.S_k_all             = S_k_all;
    results.S_k_smoothed_all    = S_k_smoothed_all;
end
