%--------------------------------------------------------------------------
% function [zc] = FT_zernike_map_convolution(map,n_max,results_filename)
% 
% A function for Matlab which performs a convolution between a mirror map
% given in the specified map structure and Zernike polynomials up to the
% polynomials with n = n_max.
%
% map:              Mirror map of surface heights in the standard map
%                   structure
% nmax:             The maximum value of n for the Zernike polynomials.
%                   Convolutions are performed between the map and all
%                   polynomials with n<=n_max
% results_filename: Filename for the results file, storing the amplitudes 
%                   of the Zernike polynomials which convolute with the map
%                   and the residual map with all the convoluted
%                   polynomials removed.
%                   0: don't save results
%
% zc:               Structure containing array of amplitudes and zernike
%                   indices of the convolution. 
%
% Part of the Simtools package, http://www.gwoptics.org/simtools
% Charlotte Bond    28.01.10
%--------------------------------------------------------------------------
%

function [zc] = FT_zernike_map_convolution(map,nmax,results_filename)

    % Recenter for best convolution results
    map=FT_recenter_mirror_map(map);

    % Initiate Zernike coefficients structure
    zc = FT_init_zernike_coefficients(nmax);
    
    % Only use points defined as inside the map
    [rows,cols]=size(map.data);
    idx=map.notnan;

    % Find the maximum radius of the map
    r=(FT_find_map_radius(map));

    map_out=map;

    % Calculate number of polynomials to be convoluted
	no_polys = (nmax+1)*(nmax+2)/2;
	nrun=1;
    elapsed_time=0;
    
    % Perform a convolution with each Zernike polynomial, from n=n_start to 
    % n=nmax.
    for n=0:nmax
        
        % Zernike polynomials for all possible values of m for specific values
        % of n
        for m=-n:2:n
            tic;
			elapsed_time = FT_print_progress(elapsed_time,nrun,no_polys,0);
            % Calculate the surface heights for the Zernike polynomial
            Z=FT_zernike_polynomial_for_grid(cols,rows,map.x0,map.y0,r,r,n,m);
        
            %-------------------------Convolution------------------------------
            c=sum(sum(Z(idx).*conj(map.data(idx))));
            cn=sum(sum((Z(idx).*conj(Z(idx)))));
            c=c/cn;
            %------------------------------------------------------------------
        
            % Update zc with Zernike amplitude
            zc = FT_update_zernike_coefficient(zc,n,m,c);
            map_out=FT_remove_zernike_polynomial_from_map(map_out,n,m,c);
        
			nrun=nrun+1;
        
		end

    end

    if results_filename~=0
        % Save amplitudes and the resultant map
        save(results_filename,'zc','map_out');
    end

end

