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.power_spectra       = fft_imgs;
    results.theta_vals          = theta_vals;
    results.S_theta_all         = S_theta_all;
    results.S_theta_norm_all    = S_theta_norm_all;
end
