subroutine mx_major_cycle90 (map,uvdata,nu,nv,   &
     &    w_weight,w_v,   &
     &    method,head,   &
     &    clean,beam,resid,nx,ny,nb,   &
     &    wcl,mcl,cct_list,ncct,   &
     &    list, nl, nf, primary, weight,   &
     &    grid, mapu, mapv, mapx, mapy,   &
     &    wfft, cpu0, uvmax, conv)
  use gkernel_interfaces
  use clean_def
  use image_def
  use gbl_message
  use imager_interfaces, except_this=>mx_major_cycle90
  !----------------------------------------------------------------------
  ! @ private-mandatory
  !
  ! IMAGER -- Support for command MX
  !
  !   Major cycle loop according to Cotton-Schwab idea.
  !   Treat only one "plane/channel" at a time. 
  !   Plane is specified by method%iplane
  !----------------------------------------------------------------------
  type (clean_par), intent(inout) :: method !! Clean parameters
  type (uvmap_par), intent(in) :: map       !! UV_MAP parameters
  type (gildas), intent(inout) :: head      !! Image header
  !
  integer, intent(in) :: nu                 !! Visibility size
  integer, intent(in) :: nv                 !! Number of visibilities
  integer, intent(in) :: nb                 !! Number of beams
  real, intent(inout) :: uvdata(nu,nv)      !! Visibilities (iterated residuals)
  real, intent(in) ::  w_weight(nv)         !! Weight array
  real, intent(in) ::  w_v(nv)              !! V values
  real, intent(in) ::  uvmax                !! Max baseline
  !
  integer, intent(in) ::  nx,ny             !! X,Y size
  real, intent(in) ::  mapx(nx),mapy(ny)    !! X,Y coordinates
  real, intent(out) ::  mapu(:),mapv(:)     !! U,V coordinates
  real, intent(inout) ::  grid(nx,ny)       !! Grid correction
  !
  real, intent(inout) ::  clean(nx,ny)      !! Clean image
  real, intent(inout) ::  resid(nx,ny)      !! Residuals
  real, intent(in) ::     beam(nx,ny,nb)    !! Synthesized beams (for all fields)
  integer, intent(in)  ::  nl               !! Search list size
  integer, intent(in)  ::  mcl              !! Maximum number of clean components
  integer, intent(out) ::  ncct             !! Number of clean components / plane
  real, intent(inout)  ::  wfft(*)          !! Work space for FFT
  type (cct_lst), intent(out) :: cct_list   !! Clean components list
  integer, intent(in)  ::  list(nx*ny)      !! List of valid pixels
  !
  integer, intent(in) ::  nf                !! Number of fields
  real, intent(inout) ::  primary(nf,nx,ny) !! Primary beams
  real, intent(inout) ::  weight (nx,ny)    !! Flat field
  !
  type(cct_par), intent(inout) :: wcl(mcl)  !! Work space for Clean Components
  type(gridding), intent(in) :: conv        !! Gridding parameters & coefficients
  !
  ! Constants
  character(len=2), parameter :: rname = 'MX'
  !
  ! Local ---
  real    maxc,minc,maxabs     ! max and min of data, absolute max value
  integer imax,jmax,imin,jmin  ! coordinates of the Max and Min pixels
  real    borne                ! Fraction of initial data
  real    limite               ! Minimal intensity retained
  real    clarkl               ! Clark worry limit
  real flux                    ! Total clean flux density
  integer ncl                  ! Number of selected data points
  logical fini                 ! Stopping criterium 
  logical converge             ! Stop by flux convergence
  integer k, kcl
  character(len=message_length) :: chain
  character(len=32) :: str
  !
  complex, allocatable :: tfgrid(:,:,:)
  complex, allocatable :: ftbeam(:,:)
  !
  real cpu1,cpu0
  integer nn(2),ndim,kz,ier
  !
  integer lx, ly
  !
  ! Code ----
  call imager_tree('MX_MAJOR_CYCLE90',.false.)
  !
  Print *,'GRID Max ',maxval(grid)
  Print *,'BEAM Max ',beam(nx/2+1,ny/2+1,1)
  !
  lx = (uvmax+map%support(1))/map%uvcell(1) + 2
  ly = (uvmax+map%support(2))/map%uvcell(2) + 2
  lx = 2*lx
  ly = 2*ly
  if (ly.gt.ny) then
    write(chain,'(A,A,F8.3)') 'Map cell is too large ',   &
     &      ' Undersampling ratio ',   &
     &      float(ly)/float(ny)
    call map_message(seve%w,rname,chain,seve%w)
    write(chain,*) 'UVMAX ',uvmax,map%support, map%uvcell
    call map_message(seve%w,rname,chain)
  endif
  ly = min(ly,ny)
  lx = min(lx,nx)
  ! !Print *,'MAPU Size ',size(mapu), lx
  call docoor (lx,-map%uvcell(1),mapu)
  call docoor (ly,map%uvcell(2),mapv)
  !
  kz = 1
  allocate (tfgrid(kz+1,lx,ly),ftbeam(nx,ny),stat=ier)
  !
  nn(1) = nx
  nn(2) = ny
  ndim = 2
  call fourt_plan(ftbeam,nn,ndim,-1,1)
  call gag_cpu(cpu0)
  !
  ! Find maximum residual
  call maxlst (resid,nx,ny,list,nl,   &
     &    maxc,imax,jmax,minc,imin,jmin)
  if (method%n_iter.lt.method%p_iter) then
    maxabs=abs(maxc)
  elseif ( abs(maxc).lt.abs(minc) ) then
    maxabs=abs(minc)
  else
    maxabs=abs(maxc)
  endif
  borne= max(method%fres*maxabs,method%ares)
  fini = maxabs.lt.borne
  method%n_iter= 0
  !
  !!Print *,'Weight ',w_weight(1:100)
  !!Print *,'V ',w_v
  !
  ! Major cycle
  k = 0
  flux = 0.0
  do while (.not.fini)
    !
    ! Define minor cycle limit
    k = k+1
    write(chain,100) 'Major cycle ',k,' loop gain ',method%gain
    call map_message(seve%d,rname,chain)
    limite = max(maxabs*method%bgain,0.8*borne)
    clarkl = maxabs*method%bgain
    !
    kcl = mcl
    !
    ! Select points of maximum strength and load them in
    call choice (      &
     &      resid,     &      ! Current residuals
     &      nx,ny,     &      ! image size
     &      list, nl,  &      ! Search list
     &      limite,    &      ! Detection threshold
     &      kcl,       &      ! Maximum number of candidates
     &      wcl,       &      ! Selected candidate components
     &      ncl,       &      ! Selected Number of components
     &      maxabs, method%ngoal)
    !
    if (ncl.gt.0) then
      write(chain,100) 'Selected ',ncl,' points above ',limite
      call map_message(seve%d,rname,chain)
      !
      ! Make minor cycles
      call clark_minor (method,   &
     &        wcl,    &     ! Selected candidate components
     &        ncl,   &         ! Number of candidates
     &        beam,nx,ny,   &  ! Dirty beams and Size
     &        nx,ny,        &  ! Image sizes
     &        method%beam0(1),method%beam0(2),   & ! Beam center
     &        method%patch(1),method%patch(2),   & ! Beam patch
     &        clarkl,limite,   &
     &        converge,   &    !
     &        cct_list,   &    ! Cumulated components
     &        nf, primary, weight, method%trunca,   &
     &        flux,   &        ! Total Flux
     &        method%pflux, next_flux90)
      !
      ! Remove all components by FT : RESID = RESID - BEAM # WCL(*,4)
      !
      call mx_uvsub90 (nx,ny,mapx,mapy,   &
     &        wcl, ncl,   &
     &        nu,nv,uvdata,method%iplane)
      write (chain,101)  'Cleaned ',flux,' Jy with ',   &
     &        method%n_iter,' clean components'
      call map_message(seve%d,rname,chain)
      !
      ! Compute FFTs and loop again
      call gag_cpu(cpu1)
      write(chain,101) 'Start FFT back at ',cpu1-cpu0
      call map_message(seve%d,rname,chain)
      call dofft (nu,nv,     &   ! Size of visibility array
     &        uvdata,        &   ! Visibilities
     &        1,2,           &   ! U, V pointers
     &        method%iplane, &   ! First channel to map
     &        1,lx,ly,       &   ! Cube size
     &        tfgrid,        &   ! FFT cube
     &        mapu,mapv,     &   ! U and V grid coordinates
     &        map%support,   &
     &        map%uvcell,map%taper,   &    ! Gridding parameters
     &        w_weight,      &   ! Weight & Visi arrays
     &        conv%ubias,conv%vbias,conv%ubuff,conv%vbuff,map%ctype)
      !
      ! Make maps with grid correction
      call extracs (2,nx,ny,1,tfgrid,ftbeam,lx,ly)
      call fourt  (ftbeam,nn,ndim,-1,1,wfft)
      call cmtore (ftbeam,resid,nx,ny)
      !
      call docorr (resid,grid,nx*ny)
      call gag_cpu(cpu1)
      write(chain,101) 'Finished gridding again ',cpu1-cpu0
      call map_message(seve%d,rname,chain)
      !
      ! Find new extrema
      call maxlst (resid,nx,ny,list,nl,   &
     &        maxc,imax,jmax,minc,imin,jmin)
      if (method%n_iter.lt.method%p_iter) then
        maxabs=abs(maxc)
      elseif ( abs(maxc).lt.abs(minc) ) then
        maxabs=abs(minc)
      else
        maxabs=abs(maxc)
      endif
      !
      ! Check if converge
      Print *,'MaxAbs ',maxabs,' Borne ',borne, ' Converge ',converge,' Ares ',method%ares
      Print *,'Niter ',method%n_iter,' Max  ',method%m_iter
      fini = (maxabs.le.borne)   &
     &        .or. (method%m_iter.le.method%n_iter)   &
     &        .or. converge
    else
      ! No component found: finish...
      write(chain,101) 'No points selected above ',limite
      call map_message(seve%i,rname,chain)
      fini = .true.
    endif
    !
    converge = fini
    !
    ! Unclear here ...
    call major_plot90 (method,head,   &
     &      converge,method%n_iter,nx,ny,nf,   &
     &      cct_list%cc,clean,resid,weight)
    fini = converge
    !
    ! Get new list
!TEST!    if (.not.fini) then
!TEST!      call re_mask (method,head,nl,error)
!TEST!      nl = method%nlist
!TEST!      list = method%list
!TEST!    endif
  enddo
  ncct = method%n_iter
  !
  ! End
  if (maxabs.le.borne) then
    str = '(minimum flux density)'
  elseif (method%m_iter.le.method%n_iter) then
    str = '(maximum number of components)'
  elseif (method%n_major.le.k) then
    str = '(maximum number of cycles)'
  elseif (converge) then
    str = '(converged)'
  else
    str = '(unknown reason)'
  endif
  write(chain,'(a,i6,a,1pg10.3,a,i5,a)')  'Plane ',method%iplane,': ',flux,' Jy in ',   &
     &    method%n_iter,' clean components '//trim(str)
  call map_message(seve%i,rname,chain)
  !
  if (allocated(tfgrid)) deallocate(tfgrid)
  if (allocated(ftbeam)) deallocate(ftbeam)
  call imager_tree('MX_MAJOR_CYCLE90',.true.)
  !
  100   format (a,i6,a,1pg10.3,a)
  101   format (a,1pg10.3,a,i5,a)
end subroutine mx_major_cycle90
!
subroutine mx_uvsub90 (nx,ny,mapx,mapy,   &
     &    wcl,ncl,nu,nv,visi,ip)
  use clean_def
  !----------------------------------------------------------------------
  ! @ private
  !*
  ! IMAGER --  Support for MX  
  !   Subtract last major cycle components from UV table.
  !   Treats only one channel.
  !!
  !----------------------------------------------------------------------
  integer, intent(in) ::  nx,ny               !! X,Y size
  real, intent(in) ::  mapx(nx),mapy(ny)      !! X,Y coordinates
  integer, intent(in) :: nu                   !! Visibility size
  integer, intent(in) :: nv                   !! Number of visibilities
  integer, intent(in) :: ncl                  !! Number of clean components
  real, intent(inout) :: visi(nu,nv)          !! Visibilities
  integer, intent(in) :: ip                   !! Current "plane/channel"
  type(cct_par), intent(inout) :: wcl(ncl)    !! Clean component values
  !
  ! Local ---
  integer ncomp
  integer ic,iv,ir,ii
  real x,y,phase,rvis,ivis
  !
  ! Code ----
  ir = 5+3*ip  ! Real part
  ii = ir+1    ! Imaginary part
  !
  ! Compress clean component list
  ncomp = 0
  do ic=1,ncl
    if (wcl(ic)%value.ne.0.0) then
      ncomp = ncomp+1
      wcl(ncomp) = wcl(ic)
    endif
  enddo
  !
  ! Remove clean component from UV data set
  do iv = 1,nv
    do ic = 1,ncomp
      x = mapx(wcl(ic)%ix)
      y = mapy(wcl(ic)%iy)
      phase = visi(1,iv)*x+visi(2,iv)*y
      rvis = wcl(ic)%value*cos(phase)
      ivis = wcl(ic)%value*sin(phase)
      visi(ir,iv) = visi(ir,iv) - rvis
      visi(ii,iv) = visi(ii,iv) - ivis
    enddo
  enddo
end subroutine mx_uvsub90
