subroutine mx_local_clean(hu,hb,hr,hc,hcct,grid,mapx,mapy,work,sblock, cpu0)
  use gildas_def
  use image_def
  use gkernel_interfaces
  use cct_types
  use mx_parameters
  use clean_beam_tool, only: find_sidelobe
  use minmax_tool, only: maxmap
  !---------------------------------------------------------------------
  ! GILDAS: CLEAN Internal routine
  ! Implementation of MX CLEAN deconvolution algorithm.
  !---------------------------------------------------------------------
  type(gildas), intent(in) :: hu    ! UV Data  Header
  type(gildas), intent(in) :: hb    ! Beam     Header
  type(gildas), intent(in) :: hr    ! Residual Header
  type(gildas), intent(in) :: hcct  ! Clean Component Table Header
  type(gildas), intent(in) :: hc    ! Clean    Header
  real :: grid(hb%gil%dim(1),hb%gil%dim(2))     ! Gridding correction
  real :: mapx(hb%gil%dim(1))                   ! X coordinates
  real :: mapy(hb%gil%dim(2))                   ! Y coordinates
  real :: work(*)                   ! FFT Work array
  integer :: sblock                 ! Blocking factor
  real :: cpu0                      ! Starting CPU
  ! Local
  integer :: i, j, box(4), ix_min,iy_min, nx,ny,nz, nclean, k, ier
  complex, allocatable :: p_work(:,:)
  real, allocatable :: p_ux(:), p_vy(:)
  integer, allocatable :: p_iter(:)
  type (cct_par), allocatable :: p_comp(:)
  real :: xinc, yinc
  !
  nx = hr%gil%dim(1)
  ny = hr%gil%dim(2)
  !
  ! Get some memory
  nclean = (c_trc(1)-c_blc(1)+1) * (c_trc(2)-c_blc(2)+1)
  allocate (p_work(nx,ny), p_comp(nclean), p_ux(nx), p_vy(ny), stat=ier)
  !
  call mx_loadxy (hu,hr,p_ux,nx,p_vy,ny,mcol)
  !
  box(1) = 1
  box(2) = 1
  box(3) = nx
  box(4) = ny
  !
  ! Prepare beam parameters
  call maxmap (hb%r2d,nx,ny,box,   &
     &    beam_max,ix_beam,iy_beam,beam_min,ix_min,iy_min)
  write(6,1000) 'I-MX_CLEAN,  Beam maximum ',beam_max,   &
     &    ' at ',ix_beam,iy_beam
  write(6,1000) 'I-MX_CLEAN,  Beam minimum ',beam_min,   &
     &    ' at ',ix_min,iy_min
  call find_sidelobe (hb%r2d,nx,ny,   &
     &    ix_beam,iy_beam,ix_patch,iy_patch,beam_gain)
  write(6,1000) 'I-MX_CLEAN,  Maximum sidelobe is ',beam_gain
  !
  box(1) = c_blc(1)
  box(2) = c_blc(2)
  box(3) = c_trc(1)
  box(4) = c_trc(2)
  xinc = hc%gil%inc(1)
  yinc = hc%gil%inc(2)
  !
  ! Find components
  nz = hc%gil%dim(4)*hc%gil%dim(3)
  allocate (p_iter(nz), stat=ier)
  call mx_major (hu,   &
     &    hb%r2d, hr%r3d, nx,ny, nz,   &
     &    p_work, p_comp, nclean,   &
     &    box, max_iter, hcct%r3d, p_iter,   &
     &    grid,  mapx, mapy, p_ux, p_vy,  &
     &    work, map_tf, sblock, cpu0)
  !
  ! Add clean components to clean map
  k = 0
  do j=1,hc%gil%dim(4)
    do i=1,hc%gil%dim(3)
      k = k+1
      write(6,1001) 'I-CLARK,  Restoring plane ',i,j
      call mx_make_clean (   &
     &        hc%r3d(:,:,k),nx,ny,   &
     &        p_work,   &
     &        major_axis,minor_axis,pos_angle,   &
     &        xinc,yinc,hcct%r3d(:,:,k), p_iter(k), &
     &        work, hr%r3d(:,:,k) )
    enddo
  enddo
  !
  1001  format(a,i5,i5)
  1000  format(a,1pg11.4,a,i6,i6)
end subroutine mx_local_clean
!
subroutine mx_make_clean (clean,nx,ny,ft,bmaj,bmin,pa,   &
     &    xinc,yinc,compon,nc,work,resi)
  use gkernel_interfaces
  use mapping_gaussian_tool
  !---------------------------------------------------------------------
  ! GILDAS: CLEAN   Internal routine
  ! Convolve source list into residual map using the Fourier method.
  !---------------------------------------------------------------------
  integer :: nx                     !
  integer :: ny                     !
  real :: clean(nx,ny)              !
  complex :: ft(nx,ny)              !
  real :: bmaj                      !
  real :: bmin                      !
  real :: pa                        !
  real :: xinc                      !
  real :: yinc                      !
  integer :: nc                     !
  real :: compon(3,nc)              !
  real :: work(*)                   !
  real :: resi(nx,ny)               !
  ! Local
  real(8), parameter :: pi=3.141592653589793d0
  real :: fact
  integer :: i, j, ic, ndim, dim(2)
  !
  clean = resi
  if (nc.eq.0) return
  !
  ft = 0.0
  !
  ! Convolve source list into residual map ---
  do ic=1,nc
    i = nint(compon(2,ic))
    j = nint(compon(3,ic))
    ft(i,j) = ft(i,j) + compon(1,ic)
  enddo
  !
  ndim = 2
  dim(1) = nx
  dim(2) = ny
  call fourt(ft,dim,ndim,-1,0,work)
  !
  ! Beam Area = PI * BMAJ * BMIN / (4 * LOG(2) ) for flux density
  ! normalisation
  fact = bmaj*bmin*pi/(4.0*log(2.0))/abs(xinc*yinc)/(nx*ny)
  call mulgau(ft,nx,ny,bmaj,bmin,pa,fact,xinc,yinc)
  call fourt (ft,dim,ndim,1,1,work)
  ! Add Residual and Clean image
  clean = clean + real(ft)
end subroutine mx_make_clean
!
subroutine mx_loadxy (x,y,mapux,nx,mapvy,ny,mcol)
  use gkernel_interfaces, only : gdf_uv_frequency
  use gildas_def
  use image_def
  type(gildas) :: x,y               !
  integer :: nx                     !
  real :: mapux(nx)                 !
  integer :: ny                     !
  real :: mapvy(ny)                 !
  integer :: mcol(2)                !
  !
  ! Local
  integer :: i
  real(8) :: pidsur                  ! 2*pi*D/Lambda
  real(8) :: freq, dcol
  real(8), parameter :: pi=3.14159265358979323846d0
  real(8), parameter :: f_to_k = 2.d0*pi/299792458.d-6
  !
  dcol = (mcol(1)+mcol(2))*0.5d0
  freq = gdf_uv_frequency(x,dcol)
  pidsur = f_to_k * freq
  !
  do i=1,nx
    mapux(i) = pidsur*((i-y%gil%ref(1))*y%gil%inc(1)+y%gil%val(1))
  enddo
  do i=1,ny
    mapvy(i) = pidsur*((i-y%gil%ref(2))*y%gil%inc(2)+y%gil%val(2))
  enddo
end subroutine mx_loadxy
