Files
nappMATLAB-toolbox/beamtime/ADRESSTools_vEos/MATools_IceLine_VNS/SumScanXC.m
T
2023-08-10 09:19:49 +02:00

65 lines
2.8 KiB
Matlab

function [DataXC,OffsE]=SumScanXC(Energy,Data,maxLagE,Win)
% [DataXC,OffsE] = SumScanXC(Energy,Data,maxLagE[,WinE]) summs up the separate scan frames from 3D
% array Data with energy offsets calculated by cross-correlation within the lag interval % +-maxLagE.
% The cross-correlation energy window is Win (default 80% of Energy) and angular window is fixed to
% default 90%. The returned offsets OffsE are discrete on energy grid without interpolation.
% Note: The cross-correlation algorithm subtracts linear background fixed at the end points of the
% energy window. For better accuracy choose the window ends at valleys between the spectral peaks
% and not far above EF.
% Ver. 17.06.2017
disp('- Correlating scans')
% check input
if size(Data,3)<2; DataXC=Data; OffsE=0; return; end
% parameters
nE=length(Energy); dE=mean(diff(Energy)); nA=size(Data,2); nS=size(Data,3);
maxLag=round(maxLagE/dE); Lag=-1*maxLag:maxLag;
% XC-window
% - default window of 80% in energy and 90% in angle
EWin=(1+round(0.1*nE)):round(0.9*nE);
AWin=(1+round(0.05*nA)):round(0.95*nA); nAWin=length(AWin);
% - energy window
if nargin>3;
Win=sort(Win);
EWin=round([max(1,interp1(Energy,1:nE,Win(1))):min(nE,interp1(Energy,1:nE,Win(2)))]);
end
nEWin=length(EWin);
% data window
DWin=Data(EWin(1):EWin(end),AWin(1):AWin(end),:);
X=repmat(1:nAWin,nEWin,1); Y=repmat((1:nEWin)',1,nAWin);
% figure; surf(X,Y,DWin(:,:,1),'edgecolor','none');
% suppress the window edge effects by 1D linear fit of the edge values
% - window edge values averaged over 3 end points
D1=sum(DWin(1:3,:,:),1)/3; D2=sum(DWin(end-2:end,:,:),1)/3;
for iS=1:nS
D1S=D1(1,:,iS); D2S=D2(1,:,iS);
Bkg=repmat(D1S,nEWin,1)+repmat((D2S-D1S)./(Y(end,:)-Y(1,:)),nEWin,1).*Y;
% figure; surf(X,Y,Bkg,'edgecolor','none');
DWin(:,:,iS)=DWin(:,:,iS)-Bkg;
% figure; surf(X,Y,DWin(:,:,iS),'edgecolor','none');
end
% padded reference
Ref=DWin(:,:,1); RPad=[zeros(maxLag,nAWin);Ref;zeros(maxLag,nAWin)];
% cycle over scans
OffsE=0; DataXC=Data(:,:,1)/nS;
for iS=2:nS
% - cycle over lags
XC=[]; for lag=Lag
DPad=[zeros(maxLag+lag,nAWin);DWin(:,:,iS);zeros(maxLag-lag,nAWin)];
xc=sum(sum(RPad.*DPad));
%/(size(Ref,1)-abs(lag)); % Note: Unbiased correlation may fail for flat-topped functions like y=x^2 (see TestXC.m)
XC=[XC xc];
end
% figure; plot(dE*Lag,XC);
% - offset at maximal correlation
[~,indMax]=max(XC); offs=Lag(indMax); offsE=offs*dE; OffsE=[OffsE; offsE];
disp(['Scan = ' num2str(iS) ': Offset = ' num2str(offsE)])
% - appending/truncation of the correlated images
% Note: negative arguments of ones(n,m) return empty array
Data(:,:,iS)=[NaN*ones(offs,nA); ...
Data(max(1,1-offs):min(nE,nE-offs),:,iS); ...
NaN*ones(-1*offs,nA)];
% - summation normalized by nS
DataXC=DataXC+Data(:,:,iS)/nS;
end