function [theta_vals, S_theta] = computeAngularSpectralDistribution(IMGFFT, kx, ky, k_min, k_max, num_bins, threshold, sigma, windowSize, theta_max)
%% computeAngularSpectralDistribution
% Author:       Karthik
% Date:         2025-09-12
% Version:      1.1
%
% Description:
%   Computes the angular spectral distribution within a specified radial band.
%   Supports custom angular range up to 2π.

    if nargin < 10 || isempty(theta_max)
        theta_max = pi;  % default preserves current behavior
    end

    % Apply threshold to isolate strong peaks
    IMGFFT(IMGFFT < threshold) = 0;

    % Create wavenumber meshgrid
    [KX, KY]         = meshgrid(kx, ky);
    Kmag             = sqrt(KX.^2 + KY.^2);       % radial wavenumber magnitude
    Theta            = atan2(KY, KX);             % range [-pi, pi]

    % Map Theta into [0, 2*pi)
    Theta(Theta < 0) = Theta(Theta < 0) + 2*pi;

     % Restrict to radial band in wavenumber space
    radial_mask      = (Kmag >= k_min) & (Kmag <= k_max);

    % Initialize angular structure factor
    S_theta          = zeros(1, num_bins);
    theta_vals       = linspace(0, theta_max, num_bins);

    % Loop over angular bins
    for i = 1:num_bins
        angle_start  = (i - 1) * theta_max / num_bins;
        angle_end    = i * theta_max / num_bins;
        angle_mask   = (Theta >= angle_start) & (Theta < angle_end);
        bin_mask     = radial_mask & angle_mask;
        fft_angle    = IMGFFT .* bin_mask;
        S_theta(i)   = sum(sum(abs(fft_angle).^2));
    end

    % Optional smoothing
    if exist('sigma', 'var') && ~isempty(sigma)
        % Gaussian smoothing
        half_width   = ceil(3 * sigma);
        x            = -half_width:half_width;
        gauss_kernel = exp(-x.^2 / (2 * sigma^2));
        gauss_kernel = gauss_kernel / sum(gauss_kernel);

        % Circular convolution
        S_theta = conv([S_theta(end - half_width + 1:end), S_theta, S_theta(1:half_width)], ...
                       gauss_kernel, 'same');
        S_theta = S_theta(half_width + 1:end - half_width);
    elseif exist('windowSize', 'var') && ~isempty(windowSize)
        % Moving average smoothing
        pad    = floor(windowSize / 2);
        kernel = ones(1, windowSize) / windowSize;
        S_theta = conv([S_theta(end - pad + 1:end), S_theta, S_theta(1:pad)], kernel, 'same');
        S_theta = S_theta(pad + 1:end - pad);
    end
end