Code covered by the BSD License  

Highlights from
STXM data analysis script collection - STACKLab

image thumbnail
from STXM data analysis script collection - STACKLab by Tobias Henn
STXM data analysis script collection with stack exploration GUI tool STACKLab

Scomplete=CombineStacks(S1,S2)
function Scomplete=CombineStacks(S1,S2)
%function Scombined=CombineStacks(S1,S2)
%
%Function used to automatically align and combine two stacks recorded over 
%the same image region at different X-ray absorption edges.
%One image from the 1st 10th of each stack are used to align the stacks. Image shifts
%for alignment are calculated using Manuel Guizar's dftregistration script*).
%T.R. Henn April 2009
%
%*)
% Manuel Guizar-Sicairos, Samuel T. Thurman, and James R. Fienup, 
% "Efficient subpixel image registration algorithms," Opt. Lett. 33, 
% 156-158 (2008).
%
%Inputs
%------
%S1             aligned and OD converted standard stack structure array 
%               recorded at lower X-ray energies
%S2             aligned and OD converted standard stack structure array
%               recorded at lower X-ray energies
%
%
%Outputs
%-------
%Scomplete      comined Stack structure array
%


Scomplete=S1;
spectr1=S1.spectr;
spectr2=S2.spectr;

[s1y,s1x,s1eV]=size(S1.spectr);
[s2y,s2x,s2eV]=size(S2.spectr);

xresolution=S1.Xvalue/s1x;      % Will be used to calculate new Scomplete.Xvalue etc...
yresolution=S1.Yvalue/s1y;

comby=min(s1y,s2y);
combx=min(s1x,s2x);

floatshifts=dftregistration(fft2(S1.spectr(1:comby,1:combx,ceil(s1eV*1/10))),fft2(S2.spectr(1:comby,1:combx,ceil(s2eV*1/10))),100);        %Calculate Stack shift

intshifts=fix(floatshifts);
fracshifts=floatshifts-intshifts;

for k=1:s2eV            %Shift 2nd Stack images
    
    spectr2(:,:,k)=FTMatrixShift(spectr2(:,:,k),-fracshifts(3),-fracshifts(4));
    
end

%Remove circulated pixel lines
if floatshifts(3) > 0           
    
    spectr2(1,:,:)=[];
    
elseif floatshifts(3) < 0
    
    spectr2(s2y,:,:)=[];
    
end

if floatshifts(4) > 0 
    
    spectr2(:,1,:)=[];
    
elseif floatshifts(4) < 0
    
    spectr2(:,s2x,:)=[];
    
end;

[s2y,s2x,s2eV]=size(spectr2);

%Shift Matrix Construction
if s1y+abs(intshifts(3)) > s2y
    
    ysm=s1y+abs(intshifts(3));
    
elseif s1y+abs(intshifts(3)) <= s2y
    
    ysm = s2y;
    
end

if s1x+abs(intshifts(4)) > s2x
    
    xsm=s1x+abs(intshifts(4));
    
elseif s1x+abs(intshifts(4)) <= s2x
    
    xsm = s2x;
    
end

ShiftMatrix=zeros(ysm,xsm,s1eV+s2eV);

% Calculation of shift borders for transfer of S1 and S2 into Shift Matrix

if intshifts(3) < 0
    
    S1ystart=abs(intshifts(3))+1;
    S2ystart=1;
    S1ystop=S1ystart+s1y-1;
    S2ystop=S2ystart+s2y-1;
    
elseif intshifts(3) == 0
    
    S1ystart=1;
    S2ystart=1;    
    S1ystop=S1ystart+s1y-1;
    S2ystop=S2ystart+s2y-1;
    
elseif intshifts(3) > 0
    
    S1ystart=1;
    S2ystart=abs(intshifts(3))+1;
    S1ystop=S1ystart+s1y-1;    
    S2ystop=S2ystart+s2y-1;
    
end

if intshifts(4) < 0
    
    S1xstart=abs(intshifts(4))+1;
    S2xstart=1;
    S1xstop=S1xstart+s1x-1;
    S2xstop=S2xstart+s2x-1;
    
elseif intshifts(4) == 0
    
    S1xstart=1;
    S2xstart=1;    
    S1xstop=S1xstart+s1x-1;
    S2xstop=S2xstart+s2x-1;
    
elseif intshifts(4) > 0
    
    S1xstart=1;
    S2xstart=abs(intshifts(4))+1;
    S1xstop=S1xstart+s1x-1;    
    S2xstop=S2xstart+s2x-1;
    
end

% Transfer of S1 and S2 into Shift Matrix

ShiftMatrix(S1ystart:S1ystop,S1xstart:S1xstop,1:s1eV)=spectr1(:,:,:);
ShiftMatrix(S2ystart:S2ystop,S2xstart:S2xstop,(s1eV+1):(s1eV+s2eV))=spectr2(:,:,:);

% Energy data reconstruction for combined Stack
eVenergy=zeros((s1eV+s2eV),1);                        
eVenergy(1:s1eV)=S1.eVenergy;
eVenergy((s1eV+1):(s1eV+s2eV))=S2.eVenergy;
Scomplete.eVenergy=eVenergy;

% Izero data reconstruction for combined Stack
izero=zeros((s1eV+s2eV),2);                        
izero(1:s1eV,:)=S1.Izero;
izero((s1eV+1):(s1eV+s2eV),:)=S2.Izero;
Scomplete.Izero=izero;

%Calculate overlapping pixel region
cutymin=max(S1ystart,S2ystart);
cutymax=min(S1ystop,S2ystop);
cutxmin=max(S1xstart,S2xstart);
cutxmax=min(S1xstop,S2xstop);


Scomplete.spectr=ShiftMatrix(cutymin:cutymax,cutxmin:cutxmax,:);

S.Xvalue=size(Scomplete.spectr,2)*xresolution;
S.Yvalue=size(Scomplete.spectr,1)*yresolution;

return

Contact us at files@mathworks.com