function [Transf] = setupSpaceRadial(~,Params,morder)

    Params.Lr   = 0.5*min(Params.Lx,Params.Ly);
    Params.Nr   = max(Params.Nx,Params.Ny);
    
    Zmax        = 0.5*Params.Lz;
    Rmax        = Params.Lr;
    Nz          = Params.Nz;
    Nr          = Params.Nr;
    
    if(nargin==2)
        morder=0; %only do Bessel J0
    end
    
    % Fourier grids
    z    = linspace(-Zmax,Zmax,Nz+1);
    z    = z(1:end-1);
    dz   = z(2)-z(1);
    Kmax = Nz*2*pi/(4*Zmax);
    kz   = linspace(-Kmax,Kmax,Nz+1);
    kz   = kz(1:end-1);
    
    % Hankel grids and transform 
    H    = hankelmatrix(morder,Rmax,Nr);
    r    = H.r(:);
    kr   = H.kr(:);
    T    = diag(H.J/H.kmax)*H.T*diag(Rmax./H.J)*dz*(2*pi);
    Tinv = diag(H.J./Rmax)*H.T'*diag(H.kmax./H.J)/dz/(2*pi);
    wr   = H.wr;
    wk   = H.wk;
    % H.T'*diag(H.J/H.vmax)*H.T*diag(Rmax./H.J)
    
    [Transf.R,Transf.Z]=ndgrid(r,z);
    [Transf.KR,Transf.KZ]=ndgrid(kr,kz);
    Transf.T=T;
    Transf.Tinv=Tinv;
    Transf.r=r;
    Transf.kr=kr;
    Transf.z=z;
    Transf.kz=kz;
    Transf.wr=wr;
    Transf.wk=wk;
    Transf.Rmax=Rmax;
    Transf.Zmax=Zmax;
    Transf.dz=z(2)-z(1);
    Transf.dkz=kz(2)-kz(1);
    
function s_HT = hankelmatrix(order,rmax,Nr,eps_roots)
%HANKEL_MATRIX: Generates data to use for Hankel Transforms
%
%	s_HT = hankel_matrix(order, rmax, Nr, eps_roots)
%
%	s_HT	=	Structure containing data to use for the pQDHT
%	order	=	Transform order
%	rmax	=	Radial extent of transform
%	Nr		=	Number of sample points
%	eps_roots	=	Error in estimation of roots of Bessel function (optional)
%
%	s_HT:
%		order, rmax, Nr =	As above
%		J_roots		=	Roots of the pth order Bessel fn.
%		J_roots_N1	=	(N+1)th root
%		r			=	Radial co-ordinate vector
%		v			=	frequency co-ordinate vector
%		kr			=	Radial wave number co-ordinate vector
%		vmax		=	Limiting frequency
%					=	roots_N1 / (2*pi*rmax)
%		S			=	rmax * 2*pi*vmax (S product)
%		T			=	Transform matrix
%		J			=	Scaling vector
%					=	J_(order+1){roots}
%
%	The algorithm used is that from:
%		"Computation of quasi-discrete Hankel transforms of the integer
%		order for propagating optical wave fields"
%		Manuel Guizar-Sicairos and Julio C. Guitierrez-Vega
%		J. Opt. Soc. Am. A 21(1) 53-58 (2004)
%
%	The algorithm also calls the function:
%	zn = bessel_zeros(1, p, Nr+1, 1e-6),
%	where p and N are defined above, to calculate the roots of the bessel
%	function. This algorithm is taken from:
%  		"An Algorithm with ALGOL 60 Program for the Computation of the
%  		zeros of the Ordinary Bessel Functions and those of their
%  		Derivatives".
%  		N. M. Temme
%  		Journal of Computational Physics, 32, 270-279 (1979)
%
%	Example: Propagation of radial field
%
%		% Note the use of matrix and element products / divisions
%		H = hankel_matrix(0, 1e-3, 512);
%		DR0 = 50e-6;
%		Ur0 = exp(-(H.r/DR0).^2);
%		Ukr0 = H.T * (Ur0./H.J);
%		k0 = 2*pi/800e-9;
%		kz = realsqrt((k0^2 - H.kr.^2).*(k0>H.kr));
%		z = (-5e-3:1e-5:5e-3);
%		Ukrz = (Ukr0*ones(1,length(z))).*exp(i*kz*z);
%		Urz = (H.T * Ukrz) .* (H.J * ones(1,length(z)));
%
%	See also bessel_zeros, besselj

if (~exist('eps_roots', 'var')||isemtpy(eps_roots))
    s_HT.eps_roots = 1e-6;
else
    s_HT.eps_roots = eps_roots;
end

s_HT.order = order;
s_HT.rmax = rmax;
s_HT.Nr = Nr;

%	Calculate N+1 roots:
J_roots = bessel_zeros(1, s_HT.order, s_HT.Nr+1, s_HT.eps_roots);
s_HT.J_roots = J_roots(1:end-1);
s_HT.J_roots_N1 = J_roots(end);

%	Calculate co-ordinate vectors
s_HT.r = s_HT.J_roots * s_HT.rmax / s_HT.J_roots_N1;
s_HT.v = s_HT.J_roots / (2*pi * s_HT.rmax);
s_HT.kr = 2*pi * s_HT.v;
s_HT.kmax = s_HT.J_roots_N1 / (s_HT.rmax);
s_HT.vmax = s_HT.J_roots_N1 / (2*pi * s_HT.rmax);
s_HT.S = s_HT.J_roots_N1;

%	Calculate hankel matrix and vectors
%	I use (p=order) and (p1=order+1)
Jp = besselj(s_HT.order, (s_HT.J_roots) * (s_HT.J_roots.') / s_HT.S);
Jp1 = abs(besselj(s_HT.order+1, s_HT.J_roots));
s_HT.T = 2*Jp./(Jp1 * (Jp1.') * s_HT.S);
s_HT.J = Jp1;
s_HT.wr=2./((s_HT.kmax)^2*abs(Jp1).^2);
s_HT.wk=2./((s_HT.rmax)^2*abs(Jp1).^2);

return

function z = bessel_zeros(d,a,n,e)
%BESSEL_ZEROS: Finds the first n zeros of a bessel function
%
%	z = bessel_zeros(d, a, n, e)
%
%	z	=	zeros of the bessel function
%	d	=	Bessel function type:
%			1:	Ja
%			2:	Ya
%			3:	Ja'
%			4:	Ya'
%	a	=	Bessel order (a>=0)
%	n	=	Number of zeros to find
%	e	=	Relative error in root
%
%	This function uses the routine described in:
%		"An Algorithm with ALGOL 60 Program for the Computation of the
%		zeros of the Ordinary Bessel Functions and those of their
%		Derivatives".
%		N. M. Temme
%		Journal of Computational Physics, 32, 270-279 (1979)

z = zeros(n, 1);
aa = a^2;
mu = 4*aa;
mu2 = mu^2;
mu3 = mu^3;
mu4 = mu^4;

if (d<3)
    p = 7*mu - 31;
    p0 = mu - 1;
    if ((1+p)==p)
	    p1 = 0;
	    q1 = 0;
    else
	    p1 = 4*(253*mu2 - 3722*mu+17869)*p0/(15*p);
	    q1 = 1.6*(83*mu2 - 982*mu + 3779)/p;
    end
else
    p = 7*mu2 + 82*mu - 9;
    p0 = mu + 3;
    if ((p+1)==1)
	    p1 = 0;
	    q1 = 0;
    else
	    p1 = (4048*mu4 + 131264*mu3 - 221984*mu2 - 417600*mu + 1012176)/(60*p);
	    q1 = 1.6*(83*mu3 + 2075*mu2 - 3039*mu + 3537)/p;
    end
end

if (d==1)|(d==4)
    t = .25;
else
    t = .75;
end
tt = 4*t;

if (d<3)
    pp1 = 5/48;
    qq1 = -5/36;
else
    pp1 = -7/48;
    qq1 = 35/288;
end

y = .375*pi;
if (a>=3)
    bb = a^(-2/3);
else
    bb = 1;
end
a1 = 3*a - 8;
% psi = (.5*a + .25)*pi;

for s=1:n
    if ((a==0)&(s==1)&(d==3))
	    x = 0;
	    j = 0;
    else
	    if (s>=a1)
		    b = (s + .5*a - t)*pi;
		    c = .015625/(b^2);
		    x = b - .125*(p0 - p1*c)/(b*(1 - q1*c));
	    else
		    if (s==1)
			    switch (d)
				    case (1)
					    x = -2.33811;
				    case (2)
					    x = -1.17371;
				    case (3)
					    x = -1.01879;
				    otherwise
					    x = -2.29444;
			    end
		    else
			    x = y*(4*s - tt);
			    v = x^(-2);
			    x = -x^(2/3) * (1 + v*(pp1 + qq1*v));
		    end
		    u = x*bb;
		    v = fi(2/3 * (-u)^1.5);
		    w = 1/cos(v);
		    xx = 1 - w^2;
		    c = sqrt(u/xx);
		    if (d<3)
			    x = w*(a + c*(-5/u - c*(6 - 10/xx))/(48*a*u));
		    else
			    x = w*(a + c*(7/u + c*(18 - 14/xx))/(48*a*u));
		    end
	    end
	    j = 0;
	    
while ((j==0)|((j<5)&(abs(w/x)>e)))
		    xx = x^2;
		    x4 = x^4;
		    a2 = aa - xx;
		    r0 = bessr(d, a, x);
		    j = j+1;
		    if (d<3)
			    u = r0;
			    w = 6*x*(2*a + 1);
			    p = (1 - 4*a2)/w;
			    q = (4*(xx-mu) - 2 - 12*a)/w;
		    else
			    u = -xx*r0/a2;
			    v = 2*x*a2/(3*(aa+xx));
			    w = 64*a2^3;
			    q = 2*v*(1 + mu2 + 32*mu*xx + 48*x4)/w;
			    p = v*(1 + (40*mu*xx + 48*x4 - mu2)/w);
		    end
		    w = u*(1 + p*r0)/(1 + q*r0);
		    x = x+w;
	    end
	    z(s) = x;
    end
end

function FI = fi(y)
    c1 = 1.570796;
    if (~y)
	    FI = 0;
    elseif (y>1e5)
	    FI = c1;
    else
	    if (y<1)
		    p = (3*y)^(1/3);
		    pp = p^2;
		    p = p*(1 + pp*(pp*(27 - 2*pp) - 210)/1575);
	    else
		    p = 1/(y + c1);
		    pp = p^2;
		    p = c1 - p*(1 + pp*(2310 + pp*(3003 + pp*(4818 + pp*(8591 + pp*16328))))/3465);
	    end
	    pp = (y+p)^2;
	    r = (p - atan(p+y))/pp;
	    FI = p - (1+pp)*r*(1 + r/(p+y));
    end
return

function Jr = bessr(d,a,x)
    switch (d)
	    case (1)
		    Jr = besselj(a, x)./besselj(a+1, x);
	    case (2)
		    Jr = bessely(a, x)./bessely(a+1, x);
	    case (3)
		    Jr = a./x - besselj(a+1, x)./besselj(a, x);
	    otherwise
		    Jr = a./x - bessely(a+1, x)./bessely(a, x);
    end
return