110 lines
4.3 KiB
Matlab
110 lines
4.3 KiB
Matlab
function results = extractCustomCorrelation(angular_spectral_distribution, scan_parameter_values, N_shots, N_angular_bins)
|
||
%% extractCustomCorrelation
|
||
% Author: Karthik
|
||
% Date: 2025-09-12
|
||
% Version: 1.0
|
||
%
|
||
% Description:
|
||
% Extracts correlation of a single (highest) peak with possible secondary peak (50-70°)
|
||
% Computes correlations and cumulants grouped by unique scan parameter.
|
||
%
|
||
% Notes:
|
||
% Optional notes, references.
|
||
|
||
% ===== Convert spectral distributions to matrix =====
|
||
delta_nkr_all = zeros(N_shots, N_angular_bins);
|
||
for k = 1:N_shots
|
||
delta_nkr_all(k, :) = angular_spectral_distribution{k};
|
||
end
|
||
|
||
% ===== Determine unique scan parameter values =====
|
||
if isnumeric(scan_parameter_values) && isvector(scan_parameter_values)
|
||
[unique_scan_parameter_values, ~, idx] = unique(scan_parameter_values(:), 'stable');
|
||
elseif iscell(scan_parameter_values)
|
||
params = cell2mat(scan_parameter_values);
|
||
[unique_scan_parameter_values, ~, idx] = unique(params, 'rows', 'stable');
|
||
else
|
||
error('Unsupported format for scan_parameter_values.');
|
||
end
|
||
|
||
N_unique = size(unique_scan_parameter_values, 1);
|
||
|
||
% ===== Angular settings =====
|
||
angle_range = 180;
|
||
angle_per_bin = angle_range / N_angular_bins;
|
||
max_peak_bin = round(180 / angle_per_bin);
|
||
window_size = 10;
|
||
angle_threshold = 100;
|
||
|
||
% ===== Preallocate result arrays based on unique values =====
|
||
mean_max_g2_values = zeros(1, N_unique);
|
||
skew_max_g2_angle_values = zeros(1, N_unique);
|
||
var_max_g2_values = zeros(1, N_unique);
|
||
fourth_order_cumulant_max_g2_angle_values = zeros(1, N_unique);
|
||
max_g2_all_per_scan_parameter_value = cell(1, N_unique);
|
||
std_error_g2_values = zeros(1, N_unique);
|
||
|
||
% ===== Compute correlations and cumulants per unique parameter =====
|
||
for i = 1:N_unique
|
||
group_idx = find(idx == i); % all repetitions for this unique value
|
||
group_data = delta_nkr_all(group_idx, :);
|
||
N_reps = size(group_data, 1);
|
||
|
||
g2_values = zeros(1, N_reps);
|
||
|
||
for j = 1:N_reps
|
||
profile = group_data(j, :);
|
||
|
||
% Find highest peak in 0–180° range
|
||
restricted_profile = profile(1:max_peak_bin);
|
||
[~, peak_idx_rel] = max(restricted_profile);
|
||
peak_idx = peak_idx_rel;
|
||
peak_angle = (peak_idx - 1) * angle_per_bin;
|
||
|
||
% Determine offsets for secondary peak correlation
|
||
if peak_angle < angle_threshold
|
||
offsets = round(50 / angle_per_bin) : round(70 / angle_per_bin);
|
||
else
|
||
offsets = -round(70 / angle_per_bin) : -round(50 / angle_per_bin);
|
||
end
|
||
|
||
ref_window = mod((peak_idx - window_size):(peak_idx + window_size) - 1, N_angular_bins) + 1;
|
||
ref = profile(ref_window);
|
||
|
||
correlations = zeros(size(offsets));
|
||
for k_off = 1:length(offsets)
|
||
shifted_idx = mod(peak_idx + offsets(k_off) - 1, N_angular_bins) + 1;
|
||
sec_window = mod((shifted_idx - window_size):(shifted_idx + window_size) - 1, N_angular_bins) + 1;
|
||
sec = profile(sec_window);
|
||
correlations(k_off) = mean(ref .* sec) / mean(ref.^2);
|
||
end
|
||
|
||
[max_corr, ~] = max(correlations);
|
||
g2_values(j) = max_corr;
|
||
end
|
||
|
||
% Store all repetitions for this unique parameter
|
||
max_g2_all_per_scan_parameter_value{i} = g2_values;
|
||
|
||
% Compute cumulants
|
||
kappa = Calculator.computeCumulants(g2_values(:), 4);
|
||
|
||
mean_max_g2_values(i) = kappa(1);
|
||
var_max_g2_values(i) = kappa(2);
|
||
skew_max_g2_angle_values(i) = kappa(3);
|
||
fourth_order_cumulant_max_g2_angle_values(i) = kappa(4);
|
||
|
||
N_eff = sum(~isnan(g2_values));
|
||
std_error_g2_values(i) = sqrt(kappa(2)) / sqrt(N_eff);
|
||
end
|
||
|
||
% ===== Package results into struct =====
|
||
results = struct();
|
||
results.mean_max_g2 = mean_max_g2_values;
|
||
results.var_max_g2 = var_max_g2_values;
|
||
results.skew_max_g2_angle = skew_max_g2_angle_values;
|
||
results.fourth_order_cumulant_max_g2 = fourth_order_cumulant_max_g2_angle_values;
|
||
results.std_error_g2 = std_error_g2_values;
|
||
results.max_g2_all_per_scan_parameter_value = max_g2_all_per_scan_parameter_value;
|
||
results.scan_parameter_values = unique_scan_parameter_values;
|
||
end |