!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
subroutine wifisyn_ift_kern(nift,kern,error)
  use gbl_message
  use phys_const
  use wifisyn_interfaces, except_this=>wifisyn_ift_kern
  use wifisyn_gridding_types
  !---------------------------------------------------------------------
  ! @ private
  ! Compute the inverse Fourier transform of the gridding function
  ! on the full image support (i.e. much larger number of pixels than the
  ! initial definition). The result is centered on kern%ft%n/2+1.
  ! I guess that kern%ft%n must be even (not checked...).
  !---------------------------------------------------------------------
  integer,           intent(in)    :: nift
  type(kernel_1d_t), intent(inout) :: kern
  logical,           intent(inout) :: error
  !
  real :: kw,ku
  integer :: iu,ix,mx
  character(len=*), parameter :: rname='GRIDDING/IFT/KERN'
  !
  call wifisyn_message(seve%t,rname,'Welcome')
  !
  call wifisyn_reallocate_real_1d('Kernel IFT',nift,kern%ft,error)
  if (error) return
  !
  mx = nift/2+1
  kw = pi / mx / kern%fac
  kern%ft%val = 0.0
  do iu=1,kern%fn%n
     if (kern%fn%val(iu).ne.0.0) then
        ku = kw*(float(iu)-kern%zero)
        do ix=1,nift
           kern%ft%val(ix) = kern%ft%val(ix) + kern%fn%val(iu) * cos(ku*float(ix-mx))
        enddo
     endif
  enddo
end subroutine wifisyn_ift_kern
!
subroutine wifisyn_ift_shift_and_plunge(ic,cube,image)
  use gbl_message
  use wifisyn_interfaces, except_this=>wifisyn_ift_shift_and_plunge
  use wifisyn_array_types
  !---------------------------------------------------------------------
  ! @ private
  ! Extract a Fourier plane from the FFT cube
  !---------------------------------------------------------------------
  integer,            intent(in)    :: ic
  type(complex_3d_t), intent(in)    :: cube
  type(complex_2d_t), intent(inout) :: image
  !
  integer :: ix,imx,iy,imy
  integer :: jx,jmx,jy,jmy
  character(len=*), parameter :: rname='IFT/SHIFT+PLUNGE'
  !
  call wifisyn_message(seve%t,rname,'Welcome')
  !
  imx = cube%nx/2
  imy = cube%ny/2
  jmx = image%nx/2
  jmy = image%ny/2
  !
  ! Initialization
  image%val = (0.0,0.0)
  ! Negative y spatial frequencies
  do iy=1,imy
     jy = iy+jmy-imy
     ! Negative x spatial frequencies
     do ix=1,imx
        jx = ix+jmx-imx
        image%val(jx+jmx,jy+jmy) = cube%val(ic,ix,iy)
     enddo
     ! Positive x spatial frequencies
     do ix=1,imx
        image%val(ix,jy+jmy) = cube%val(ic,ix+imx,iy)
     enddo
  enddo
  !
  ! Positive y spatial frequencies
  do iy=1,imy
     ! Negative x spatial frequencies
     do ix=1,imx
        jx = ix+jmx-imx
        image%val(jx+jmx,iy) = cube%val(ic,ix,iy+imy)
     enddo
     ! Positive x spatial frequencies
     do ix=1,imx
        image%val(ix,iy) = cube%val(ic,ix+imx,iy+imy)
     enddo
  enddo
end subroutine wifisyn_ift_shift_and_plunge
!
subroutine wifisyn_ift_shift_and_real(ic,image,cube)
  use gbl_message
  use image_def
  use wifisyn_interfaces, except_this=>wifisyn_ift_shift_and_real
  use wifisyn_array_types
  !---------------------------------------------------------------------
  ! @ private
  ! Extract real image from an IFT image with appropriate recentering
  !---------------------------------------------------------------------
  integer,            intent(in)    :: ic
  type(complex_2d_t), intent(in)    :: image
  type(gildas),       intent(inout) :: cube
  !
  integer :: ix,mx
  integer :: iy,my
  character(len=*), parameter :: rname='IFT/SHIFT+REAL'
  !
  call wifisyn_message(seve%t,rname,'Welcome')
  !
  mx = image%nx/2
  my = image%ny/2
  !
  do iy=1,my
     do ix=1,mx
        cube%r3d(ix+mx,iy+my,ic) = real(image%val(ix,iy))
     enddo
     do ix=1,mx
        cube%r3d(ix,iy+my,ic) = real(image%val(ix+mx,iy))
     enddo
  enddo
  do iy=1,my
     do ix=1,mx
        cube%r3d(ix+mx,iy,ic) = real(image%val(ix,iy+my))
     enddo
     do ix=1,mx
        cube%r3d(ix,iy,ic) = real(image%val(ix+mx,iy+my))
     enddo
  enddo
end subroutine wifisyn_ift_shift_and_real
!
subroutine wifisyn_ift_compute_grid_correction(beam,ukern,vkern,corr,error)
  use gbl_message
  use image_def
  use wifisyn_interfaces, except_this=>wifisyn_ift_compute_grid_correction
  use wifisyn_array_types
  use wifisyn_gridding_types
  !---------------------------------------------------------------------
  ! @ private
  ! Compute grid correction array, with normalisation of beam to 1.0
  ! at maximum pixel
  !---------------------------------------------------------------------
  type(gildas),      intent(in)    :: beam  ! Beam before normalization
  type(kernel_1d_t), intent(in)    :: ukern ! U gridding kernel
  type(kernel_1d_t), intent(in)    :: vkern ! V gridding kernel
  type(real_2d_t),   intent(inout) :: corr  ! Beam-normalized 2D grid correction
  logical,           intent(inout) :: error
  !
  real :: norm
  integer :: ix,nx
  integer :: iy,ny
  character(len=*), parameter :: rname='IFT/COMPUTE/GRID/CORR'
  !
  call wifisyn_message(seve%t,rname,'Welcome')
  !
  nx = ukern%ft%n
  ny = vkern%ft%n
  !
  norm = ukern%ft%val(nx/2+1)*vkern%ft%val(ny/2+1)/beam%r3d(nx/2+1,ny/2+1,1)
  do iy=1,ny
    do ix=1,nx
      corr%val(ix,iy) = norm/(ukern%ft%val(ix)*vkern%ft%val(iy))
    enddo
  enddo
end subroutine wifisyn_ift_compute_grid_correction
!
subroutine wifisyn_ift_apply_grid_correction(win,corr,cube,error)
  use gbl_message
  use image_def
  use wifisyn_interfaces, except_this=>wifisyn_ift_apply_grid_correction
  use wifisyn_array_types
  use wifisyn_gridding_types
  !---------------------------------------------------------------------
  ! @ private
  ! Apply gridding kernel correction to map
  !---------------------------------------------------------------------
  type(window_t),  intent(in)    :: win
  type(real_2d_t), intent(in)    :: corr
  type(gildas),    intent(inout) :: cube
  logical,         intent(inout) :: error
  !
  integer :: ix,iy,ic
  character(len=*), parameter :: rname='IFT/APPLY/GRID/CORR'
  !
  call wifisyn_message(seve%t,rname,'Welcome')
  !
  do ic=win%first,win%last
     do iy=1,cube%gil%dim(2)
        do ix=1,cube%gil%dim(1)
           cube%r3d(ix,iy,ic) = cube%r3d(ix,iy,ic)*corr%val(ix,iy)
        enddo ! ix
     enddo ! iy
  enddo ! ic
  !
end subroutine wifisyn_ift_apply_grid_correction
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
