Calculations/Data-Analyzer/+Analyzer/recenterSpectralCurves.m

89 lines
2.9 KiB
Matlab

function results = recenterSpectralCurves(S_theta_all, theta_vals, scan_reference_values, varargin)
%% recenterSpectralCurves
% Author: Karthik
% Date: 2025-10-09
% Version: 1.0
%
% Description:
% Recenters each curve so its first peak is at zero (no wrap-around),
% pads shorter curves with NaN, and computes mean and SEM for each
% scan parameter. Returns a struct ready for plotting.
%
% Inputs:
% S_theta_all - 1x(N_reps*N_params) cell array of curves
% theta_vals - vector of theta values (radians)
% scan_reference_values - vector of unique scan parameters
%
% Optional name-value pairs:
% 'SearchRange' - [deg_min deg_max] range for first-peak search (default: [0 90])
%
% Output struct fields:
% results.curves
% results.x_values
% results.curves_mean
% results.curves_error
% results.scan_parameter_values
% --- Parse optional inputs ---
p = inputParser;
addParameter(p, 'SearchRange', [0 pi/2], @(x) isnumeric(x) && numel(x)==2);
parse(p, varargin{:});
opts = p.Results;
% --- Setup ---
N_params = numel(scan_reference_values);
Ntotal = numel(S_theta_all);
Nreps = Ntotal / N_params;
theta_min = opts.SearchRange(1);
theta_max = opts.SearchRange(2);
% --- Shift each curve so its first peak is at zero ---
S_theta_all_shifted = cell(size(S_theta_all));
for k = 1:Ntotal
curve = S_theta_all{k};
idx_range = find(theta_vals >= theta_min & theta_vals <= theta_max);
if isempty(idx_range)
[~, peak_idx] = max(curve);
else
[~, local_max_idx] = max(curve(idx_range));
peak_idx = idx_range(local_max_idx);
end
% From first peak onward
S_theta_all_shifted{k} = curve(peak_idx:end);
end
% --- Pad shorter curves with NaN ---
Npoints_shifted = max(cellfun(@numel, S_theta_all_shifted));
for k = 1:Ntotal
len = numel(S_theta_all_shifted{k});
if len < Npoints_shifted
S_theta_all_shifted{k} = [S_theta_all_shifted{k}, nan(1, Npoints_shifted - len)];
end
end
% --- Compute mean and SEM ---
curves_all = cell(1, N_params);
curves_mean = cell(1, N_params);
curves_err = cell(1, N_params);
for i = 1:N_params
curves = zeros(Nreps, Npoints_shifted);
for r = 1:Nreps
idx = (r-1)*N_params + i; % interleaved indexing
curves(r,:) = S_theta_all_shifted{idx};
end
curves_all{i} = curves;
curves_mean{i} = nanmean(curves,1);
curves_err{i} = nanstd(curves,0,1)/sqrt(Nreps);
end
% --- Construct results struct ---
results.curves = curves_all;
results.x_values = theta_vals(1:Npoints_shifted) - theta_vals(1); % shift start to zero
results.curves_mean = curves_mean;
results.curves_error = curves_err;
results.scan_reference_values = scan_reference_values;
end