function [img1_aligned, img2_aligned, delta_all] = fun_align_img(img1,img2,asize,pix)

%   [resolution] = aligned_FSC(file1,file2,params)
%
% Receives two filenames with path for ptychography reconstructions and a
% structure with parameters. The routine reads the reconstructions, matches
% the linear phase between them, registers the images, and returns the
% resolution estimates based on first and last crossing of the FSC with the
% threshold.
%
% References relevant to this code:
% For using this FSC code with ptychography: J. Vila-Comamala, et al., "Characterization of high-resolution diffractive X-ray optics by ptychographic coherent diffractive imaging," Opt. Express 19, 21333-21344 (2011).
% For subpixel alignment: M. Guizar-Sicairos, et al., "Efficient subpixel image registration algorithms," Opt. Lett. 33, 156 (2008).
% For matching of phase ramp by approximate least squared error:  M. Guizar-Sicairos, et al., "Phase tomography from x-ray coherent diffractive imaging projections," Opt. Express 19, 21345-21357 (2011).
%
% Outputs:
%
% resolution    A two element variable that contains the resolution
%               obtained from first and last crossing of the FSC curve with
%               the threshold curve.
%
% Inputs:
%
% file1     Filename with path of reconstruction 1
% file2     Filename with path of reconstruction 2
% params    Structure with parameters as described below
%
%  params.flipped_images    Flip one input image horizontally (= true or false).
%                           Useful when comparing 0 and 180 degree projections 
%                           in tomography (default = false).
%  params.crop      = '';       for using the default half size of the probe
%                   = 'manual'  for using GUI to select region. This will display the range, e.g. {600:800, 600:800}     
%                   = {600:800, 600:800} for custom vertical and horizontal cropping, respectively
%  params.GUIguess  To click for an initial alignment guess, if used it ignores 
%                   the values of params.guessx and params.guessy (default
%                   = false)
%  params.guessx
%  params.guessy        An intial guess for x and y alignment (default = [])
%  params.remove_ramp   Try to remove linear phase from whole image before initial 
%                       alignment (default = true)
%  params.image_prop    = 'complex' 
%                       = 'phasor' (phase with unit amplitude, default) 
%                       = 'phase'  (Note: phase should not be used if there is phase wrapping)
%  params.taper         = 20 (default)   Pixels to taper images - Increase until the FSC does not change anymore
%  params.plotting      Display plots (default = false)
%  params.dispfsc       Display FSC plot (default = true)
%  params.SNRt          SNR for FSC threshold curve   
%                       SNRt = 0.2071 for 1/2 bit threshold for resolution of the average of the 2 images
%                       SNRt = 0.5    for 1   bit threshold for resolution of each individual image (default)
%  params.thickring     Thickness of Fourier domain ring for FSC in pixels (default = 1)
%  params.freq_thr      To ignore the crossings before freq_thr for determining resolution (default 0.02)
%  params.out_fn        Filename of output of jpeg for FSC

%*-----------------------------------------------------------------------*
%|                                                                       |
%|  Except where otherwise noted, this work is licensed under a          |
%|  Creative Commons Attribution-NonCommercial-ShareAlike 4.0            |
%|  International (CC BY-NC-SA 4.0) license.                             |
%|                                                                       |
%|  Copyright (c) 2017 by Paul Scherrer Institute (http://www.psi.ch)    |
%|                                                                       |
%|      Authors: CXS group
%|                                                                       |
%*-----------------------------------------------------------------------*
%
% You may use this code with the following provisions:
%
% If this code, or subfunctions or parts of it, is used for research in a 
%   publication or if it is fully or partially rewritten for another 
%   computing language the authors and institution should be acknowledged 
%   in written form and additionally you should cite the references relevant
%   to this code.
%
% A publication that focuses on describing features, or parameters, that
%    are already existing in the code should be first discussed with the
%    authors.
%   
% This code and subroutines are part of a continuous development, they 
%    are provided “as they are” without guarantees or liability on part
%    of PSI or the authors. It is the user responsibility to ensure its 
%    proper use and the correctness of the results.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Checks and defaults %%%
flag_imread = 1;

GUIguess = false;
plotting = false;
crop = '';
guessx = [];
guessy = [];
remove_ramp = false;

image_prop = 'complex';
taper = 20;
dispfsc = true;
SNRt = 0.5;
thickring = 5;
freq_thr = 0.02;

%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
img1_orig = img1;
img2_orig = img2;


screensize = get( 0, 'Screensize' ); 
% Show phase images (not cropped)%
if plotting
    figure(2)
    set(gcf,'Outerposition',[1 screensize(4)-550 500 500])    %[left, bottom, width, height
    if ~flag_imread
        imagesc(angle(img1));
    else
        imagesc(img1);
    end
    axis xy equal tight
    colormap bone
    if ~flag_imread 
        aux = angle(img1); %angle(img1(round(asize(1)/2):end-round(asize(1)/2),round(asize(2)/2):end-round(asize(2)/2)));
    else
        aux = img1;
    end
    caxis([min(aux(:)) max(aux(:))]); colorbar
    title(file{1},'interpreter','none')
    figure(3)
    if ~flag_imread
        imagesc(angle(img2));
    else
        imagesc(img2);
    end
    axis xy equal tight
    colormap bone
    if ~flag_imread 
        aux = angle(img2); %angle(img2(round(asize(1)/2):end-round(asize(1)/2),round(asize(2)/2):end-round(asize(2)/2)));
    else
        aux = img2;  
    end
    caxis([min(aux(:)) max(aux(:))]); colorbar
    title(file{2},'interpreter','none')
    set(gcf,'Outerposition',[500 screensize(4)-550 500 500])    %[left, bottom, width, height
end

% Crop images - default is half the size of the probe on each side plus
% whatever needed to make them of equal size
minsize1 = min(size(img1,1),size(img2,1));
minsize2 = min(size(img1,2),size(img2,2));
if isempty(crop)
    crop = {round(asize(1)/2):minsize1-round(asize(1)/2), ...
        round(asize(2)/2):minsize2-round(asize(1)/2)};
elseif strcmpi(crop, 'manual')
    figure()
    imagesc(angle(img1))
    colormap bone 
    axis image xy 
    title('Select compared region')
    rect = round(getrect);
    crop = {rect(2)+(1:rect(4)),rect(1)+(1:rect(3))};
    disp('===========================')
    fprintf('Selected region: {%i:%i,%i:%i}\n',rect(2), rect(2)+rect(4), rect(1), rect(1)+rect(3));
    disp('===========================')
    pause(1)
end
img1 = img1(crop{:});
img2 = img2(crop{:});


if GUIguess
    figure(2)
    disp(['Click on a feature on figure 2'])
    [xin yin] = ginput(1);
    figure(3)
    disp(['Click on a feature on figure 3'])
    [xin2 yin2] = ginput(1);
    guessx = round(xin-xin2);
    guessy = round(yin-yin2);
end

if ~isempty(guessx)
    switch sign(guessx)
        case 1
            img1 = img1(:,1+guessx:end);
            img2 = img2(:,1:end-guessx);
        case -1
            img1 = img1(:,1:end+guessx);
            img2 = img2(:,1-guessx:end);
    end
end
if ~isempty(guessy)
    switch sign(guessy)
        case 1
            img1 = img1(1+guessy:end,:);
            img2 = img2(1:end-guessy,:);
        case -1
            img1 = img1(1:end+guessy,:);
            img2 = img2(1-guessy:end,:);
    end
end

% Remove ramp 
if remove_ramp
    disp('Removing ramp for initial alignment')
    img1 = remove_linearphase_v2(img1,ones(size(img1)),100);
    img2 = remove_linearphase_v2(img2,ones(size(img2)),100);
end
    
if plotting
    figure(4)
    set(gcf,'Outerposition',[1 1 500 476])    %[left, bottom, width, height
    if ~flag_imread
        imagesc(angle(img1));
    else
        imagesc(img1); 
    end
    axis xy equal tight
    colormap bone; colorbar
    title(file{1},'interpreter','none')
    figure(5)
    if ~flag_imread
        imagesc(angle(img2));
    else
        imagesc(img2);
    end
    axis xy equal tight
    colormap bone; colorbar
    title(file{2},'interpreter','none')
    set(gcf,'Outerposition',[500 1 500 476])    %[left, bottom, width, height
end

%%% Initial alignment %%%
fprintf('\nInitial alignment\n')  
if ~flag_imread
    switch lower(image_prop)
        case  'complex'
            imgalign1 = img1;
            imgalign2 = img2;
            disp('Registering complex valued images')
        case 'phasor'
            imgalign1 = ones(size(img1)).*exp(1i*angle(img1));
            imgalign2 = ones(size(img1)).*exp(1i*angle(img2));
            disp('Registering phasor of complex valued images')
        case 'phase'
            imgalign1 = angle(img1);
            imgalign2 = angle(img2);
            disp('Registering phase of complex valued images')
    end
else
    imgalign1 = img1;
    imgalign2 = img2; 
end

upsamp = 100;
displ = 1;
W = 1;
x1 = [];%[1:150];
x2 = x1;
y1 = [];%[1:238];
y2 = y1;
% imgalign2 = shiftpp2(imgalign2,10,-10); % To test range adjustment
[subim1, subim2, delta, deltafine, regionsout] = registersubimages_2(imgalign1,imgalign2, x1, y1, x2, y2, upsamp, displ,1);

%%% Fine alignment (second round) %%%

% Remove ramp for fine alignment
disp('Removing ramp for fine alignment')
%%% A patch for deltafine large
if max(regionsout.y2+round(delta(1)))>size(img2,1)
    warning('First subpixel registration refinement found large values')
    regionsout.y2 = [min(regionsout.y2):size(img2,1)-round(delta(1))];
    regionsout.y1 = regionsout.y2;
end
if max(regionsout.x2+round(delta(2)))>size(img2,2)
    warning('First subpixel registration refinement found large values')
    regionsout.x2 = [min(regionsout.x2):size(img2,2)-round(delta(2))];
    regionsout.x1 = regionsout.x2;
end
%%%
subimg1 = img1(regionsout.y1,regionsout.x1);
subimg2 = img2(regionsout.y2+round(delta(1)),regionsout.x2+round(delta(2)));
if ~flag_imread
    subimg1 = remove_linearphase_v2(subimg1,ones(size(subimg1)),100);
    subimg2 = remove_linearphase_v2(subimg2,ones(size(subimg2)),100);
end

if ~flag_imread
    switch lower(image_prop)
        case  'complex'
            subimgalign1 = subimg1;
            subimgalign2 = subimg2;
            disp('Registering complex valued images')
        case 'phasor'
            subimgalign1 = ones(size(subimg1)).*exp(1i*angle(subimg1));
            subimgalign2 = ones(size(subimg1)).*exp(1i*angle(subimg2));
            disp('Registering phasor of complex valued images')
        case 'phase'
            subimgalign1 = angle(subimg1);
            subimgalign2 = angle(subimg2);
            disp('Registering phase of complex valued images')
    end
else
   subimgalign1 = subimg1;
   subimgalign2 = subimg2; 
end

% Fine alignment %
disp(sprintf('\nFine alignment'))
[subim1, subim2, delta2, deltafine2, regionsout] = registersubimages_2(subimgalign1,subimgalign2, x1, y1, x2, y2, upsamp, displ,1);

%%% Tapering %%%
filterx = fract_hanning_pad(size(subim1,2),size(subim1,2),size(subim1,2)-2*taper);
filterx = fftshift(filterx(1,:));
filterx = repmat(filterx,[size(subim1,1) 1]);
filtery = fract_hanning_pad(size(subim1,1),size(subim1,1),size(subim1,1)-2*taper);
filtery = fftshift(filtery(:,1));
filtery = repmat(filtery,[1 size(subim1,2)]);
filterxy = filterx.*filtery;

% Taper subimages %
subim1 = subim1.*filterxy;% + (1-filterxy).*mean(subim1(:));
subim2 = subim2.*filterxy;% + (1-filterxy).*mean(subim2(:));

if plotting
    figure(4)
    set(gcf,'Outerposition',[1 1 500 476])    %[left, bottom, width, height
    if strcmpi(image_prop,'phase') || flag_imread
        imagesc(subim1);
    else
        imagesc(angle(subim1));
    end
    axis xy equal tight
    colormap bone; colorbar
    title(file{1},'interpreter','none')
    figure(5)
    if strcmpi(image_prop,'phase') || flag_imread
        imagesc(real(subim2));
    else
        imagesc(angle(subim2));
    end
    axis xy equal tight
    colormap bone; colorbar
    title(file{2},'interpreter','none')
    set(gcf,'Outerposition',[500 1 500 476])    %[left, bottom, width, height
end
%% Computing the FSC
param.st_title = sprintf('taper %d',taper);
param.pixel_size = pix; 

[resolution FSC T freq] = fourier_shell_corr_3D_2(subim1,subim2, param);

if 0
    img1_aligned = img1_orig;
    img1_aligned(asize(1)/2:asize(1)/2+size(subim1,1)-1, asize(2)/2:asize(2)/2+size(subim1,2)-1) = subim1;

    img2_aligned = img2_orig;
    img2_aligned(asize(1)/2:asize(1)/2+size(subim2,1)-1, asize(2)/2:asize(2)/2+size(subim2,2)-1) = subim2;
else
    img1_aligned = subim1;
    img2_aligned = subim2;
end

delta_all = round(delta) + delta2;

return
