subroutine mx_major_cycle90 (map,uvdata,nu,nv,   &
     &    w_weight,w_v,   &
     &    method,head,   &
     &    clean,beam,resid,nx,ny,nb,   &
     &    wcl,mcl,tcc,ncct,   &
     &    list, nl, nf, primary, weight,   &
     &    grid, mapu, mapv, mapx, mapy,   &
     &    wfft, cpu0, uvmax)
  use gkernel_interfaces
  use clean_def
  use image_def
  use gbl_message
  use imager_interfaces, except_this=>mx_major_cycle90
  !----------------------------------------------------------------------
  ! @ private
  !
  ! IMAGER
  !   Support for MX
  !   Major cycle loop according to B.Clark idea
  !   Treat only one "plane/channel" at a time
  !   Plane is specified by method%iplane
  !----------------------------------------------------------------------
  type (clean_par), intent(inout) :: method
  type (uvmap_par), intent(in) :: map
  type (gildas), intent(inout) :: head
  !
  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(in) ::  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

  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_par), intent(out) :: tcc(method%m_iter) ! Clean components array
  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 array for Clean Components
  !
  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, allocatable :: my_resid(:,:)
  !
  real cpu1,cpu0
  integer nn(2),ndim,kz,ier
  ! Some leftover globals...
  real ubias,vbias,ubuff(4096),vbuff(4096)
  common /conv/ ubias,vbias,ubuff,vbuff
  integer lx, ly
  character(len=2) :: rname = 'MX'
  !
  call imager_tree('MX_MAJOR_CYCLE90 in mx_cycle.f90')
  !
  !!Print *,'Number of fields ',nf,'  Number of Beams ',nb
  !
  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,3)
    write(chain,*) 'UVMAX ',uvmax,map%support, map%uvcell
    call map_message(seve%w,rname,chain)
  endif
  ly = min(ly,ny)
  lx = min(lx,nx)
  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),my_resid(nx,ny),stat=ier)
  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 minor_cycle90 (method,   &
     &        wcl,    &     ! Selected candidate components
     &        ncl,   &         ! Number of candidates
     &        beam,nx,ny,   &  ! Dirty beams and Size
     &        method%beam0(1),method%beam0(2),   & ! Beam center
     &        method%patch(1),method%patch(2),   & ! Beam patch
     &        clarkl,limite,   &
     &        converge,   &    !
     &        tcc,   &         ! 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,w_v,   &    ! Weight & Visi arrays
     &        ubias,vbias,ubuff,vbuff,map%ctype)
      !
      ! Make maps with grid correction
      call extracs (1+1,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 cmtore (ftbeam,my_resid,nx,ny)
   !! Print *,'RESID 1',my_resid(:,ny/2)
   !! call docorr (my_resid,grid,nx*ny)
   !! Print *,'RESID 2',my_resid(:,ny/2)
   !! resid = my_resid
      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
      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,   &
     &      tcc,clean,resid,weight)
    fini = converge
    !
    ! Get new list
!!!    if (.not.fini) then
!!!      call re_mask (method,head,nl,error)
!!!      nl = method%nlist
!!!      list = method%list
!!!    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)
  !
  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
  !
  ! MAPPING
  !   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 comp. value
  !
  integer ncomp
  integer ic,iv,ir,ii
  real x,y,phase,rvis,ivis
  !
  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
