!
subroutine major_sdi (rname,method,head,clean,beam,resid,nx,ny,   &
     &    tfbeam,fcomp,wcl,mcl,ixbeam,iybeam,ixpatch,iypatch,bgain,   &
     &    box, wfft, comp, list, nl, np, primary, weight, &
     &    major_plot )
  use imager_interfaces, except_this=>major_sdi
  use clean_def
  use image_def
  use gbl_message
  use gkernel_interfaces, only : sic_ctrlc
  !----------------------------------------------------------------------
  ! @ private
  !*
  ! IMAGER -- CLEAN  Method SDI  
  ! Major cycle loop according to Steer Dewdney and Ito idea
  !!
  !----------------------------------------------------------------------
  external :: major_plot                        !! Plotting routine
  character(len=*), intent(in) :: rname         !! Caller name
  type (clean_par), intent(inout) :: method     !! Deconvolution method parameterss
  type (gildas), intent(in)  :: head            !! Data header
  integer, intent(in) :: np                     !! Number of fields
  integer, intent(in) :: nx                     !! X size
  integer, intent(in) :: ny                     !! Y size
  integer, intent(in) :: mcl                    !! Maximum number of clean components
  real, intent(inout) :: clean(nx,ny)           !! Clean map
  real, intent(inout) :: resid(nx,ny)           !! Residual map
  real, intent(in) ::    beam(nx,ny,np)         !! Dirty beams (per field)
  real, intent(in) ::    tfbeam(nx,ny,np)       !! FT. of beams
  complex, intent(inout) :: fcomp(nx,ny)        !! FT of component list
  type(cct_par), intent(inout) :: wcl(mcl)      !! Work space for Clean components
  real, intent(in) :: bgain                     !! Maximum sidelobe level
  integer, intent(in) :: ixbeam, iybeam         !! Beam maximum position
  integer, intent(in) :: ixpatch, iypatch       !! Beam patch radius
  integer, intent(in) :: box(4)                 !! Cleaning box
  real, intent(inout) :: wfft(*)                !! Work space for FFT
  integer, intent(inout) :: list(nx*ny)         !! list of searchable pixels
  integer, intent(inout) :: nl                  !! List size
  real, intent(inout) :: comp(nx,ny)            !! Clean components array
  real, intent(in) :: primary(np,nx,ny)         !! Primary beams
  real, intent(in) :: weight (nx,ny)            !! Flat field array
  !
  ! 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 flux                    ! Total clean flux density
  integer ncl                  ! Number of selected data points
  logical fini                 ! Stopping criterium 
  logical converge             ! Stop by flux convergence
  integer k
  real factor                  ! Scaling factor
  character(len=message_length) :: chain
  type (cct_par) :: tcc(1)     ! Dummy argument for Major_PLOT
  real :: sign, cdif
  integer :: dimcum, jiter
  real, allocatable :: oldcum(:)
  !
  ! Code ----
  dimcum = min(8,method%n_major/2)
  allocate (oldcum(dimcum))
  !
  ! Find maximum residual
  call maxlst (resid,nx,ny,list,nl, maxc,imax,jmax,minc,imin,jmin)
  sign = 1
  if (method%n_iter.lt.method%p_iter) then
    maxabs=abs(maxc)
  elseif ( abs(maxc).lt.abs(minc) ) then
    maxabs=abs(minc)
    sign = -1.0    
  else
    maxabs=abs(maxc)
  endif
  oldcum = 0
  !
  borne= max(method%fres*maxabs,method%ares)
  fini = maxabs.lt.borne
  !   method%n_iter= 0      ! Set at Call sequence
  flux = 0.0
  !
  ! Initialize clean components
  comp = 0.0
  !
  ! Major cycle
  !
  converge = .false.
  k = 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*bgain,0.8*borne)
    !
    ! 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
     &      mcl,         &      ! Maximum number of candidates
     &      wcl,         &      ! Selected candidate components
     &      ncl,         &      ! Selected Number of components
     &      maxabs, 0)
    !
    if (ncl.gt.0) then
      write(chain,100) 'Selected ',ncl,' points above ',limite
      call map_message(seve%d,rname,chain)
      !
      ! No minor cycles. Compute scaling factor
      call sdi_normal (    &
     &        fcomp,       &    ! Work space for Component TF
     &        tfbeam,      &    ! Beam TF
     &        nx,ny,       &    ! image size
     &        wcl,         &    ! Selected candidate components
     &        ncl,         &    ! Selected Number of components
     &        wfft,        &    ! FFT work space
     &        factor)
      ! !Print *,'Done NORMAL '
      !
      ! Compute Clean Components
      factor = method%gain*maxabs/factor
      call sdi_scalec (wcl,      &    ! Selected candidate components
     &        ncl,factor,flux,   &
     &        comp, nx, ny)
      ! !Print *,'Done SCALEC '
      method%n_iter = method%n_iter+ncl
      !
      ! Remove all components by FT : RESIDU = RESIDU - BEAM # WCL(*,4)
      call remisajour (    &
     &        clean,       &    ! CLEAN map used as work space
     &        resid,       &    ! Updated residuals
     &        tfbeam,      &    ! Beam TF
     &        fcomp,       &    ! Work space for Component TF
     &        wcl,         &    ! Clean components
     &        ncl,         &    ! Number of Clean Components
     &        nx,ny,       &    ! Map size
     &        wfft,        &    ! FFT work space
     &        np, primary, weight, method%trunca)
      ! !Print *,'Done REMISAJOUR '
      write (chain,101)  'Cleaned ',flux,' Jy with ',   &
     &        method%n_iter,' clean components'
      call map_message(seve%i,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
      !
      if (dimcum.ne.0) then
        jiter = k   ! The Major Loop counter 
        oldcum(mod(jiter,dimcum)+1) = flux
        if (jiter.ge.dimcum) then
          cdif = flux-oldcum(mod(jiter+1,dimcum)+1)
          converge = sign*cdif.lt.0.0
          if (.not.converge) then
            if (abs(cdif/flux).lt.1E-3) converge = .true.
          endif
        endif
      endif
      ! Check if converge
      fini = (maxabs.le.borne)             &
     &        .or. (k.gt.method%n_major)   &
     &        .or. converge
    else
      write(chain,101) 'No point selected above ',limite
      fini = .true.
      call map_message(seve%i,rname,chain)
    endif
    !
    ! Intermediate or final PLOT
    converge = fini
    clean(:,:) = comp               ! Use CLEAN as work space to plot it
    ! !Print *,'Doing MAJOR_PLOT '
    call major_plot (method,head,              &
     &      converge,method%n_iter,nx,ny,np,   &
     &      tcc,clean,resid,weight)
    ! !Print *,'Done MAJOR_PLOT '
    fini = converge
    !
    if (sic_ctrlc()) exit
  enddo
  !
  ! End
  if (maxabs.le.borne) then
    write(chain,100) 'Reached minimum flux density '
  elseif (k.ge.method%n_major) then
    write(chain,100) 'Reached maximum number of cycles'
  elseif (converge) then
    write(chain,100) 'Reached flux convergence'
  else
    write(chain,100) 'End of transcendental causes'
  endif
  call map_message(seve%i,rname,chain)
  !
  ! Store the result
  clean(:,:) = comp
  !
  100   format (a,i0,a,1pg11.4,a)
  101   format (a,1pg11.4,a,i0,a)
end subroutine major_sdi
!
subroutine sdi_normal (fcomp,tfbeam,nx,ny, wcl,ncl,wfft,factor)
  use gkernel_interfaces, only : fourt
  use clean_def
  !----------------------------------------------------------------------
  ! @ private
  !*
  ! IMAGER  --  CLEAN Method SDI  
  ! Subtract last major cycle components from residual map.
  !!
  !----------------------------------------------------------------------
  integer, intent(in) :: nx               !! X size
  integer, intent(in) :: ny               !! Y size
  integer, intent(in) :: ncl              !! Number of clean components
  type(cct_par), intent(in) :: wcl(ncl)   !! Clean components
  real, intent(in) :: tfbeam(nx,ny)       !! FT. of beam
  complex, intent(out) :: fcomp(nx,ny)    !! FT. of clean components
  real, intent(inout) :: wfft(*)          !! Work array
  real, intent(out) :: factor             !! Max of clean
  !
  ! Local ---
  integer i,j,k,ndim,nn(2)
  !
  ! Code ----
  fcomp = 0.0
  do k=1,ncl
    fcomp(wcl(k)%ix,wcl(k)%iy) = cmplx(wcl(k)%influx,0.0)
  enddo
  ndim = 2
  nn(1) = nx
  nn(2) = ny
  call fourt(fcomp,nn,ndim,-1,0,wfft)
  fcomp = fcomp*tfbeam
  call fourt(fcomp,nn,ndim,1,1,wfft)
  factor = abs(real(fcomp(1,1)))
  do j=1,ny
    do i=1,nx
      factor = max(factor,abs(real(fcomp(i,j))))
    enddo
  enddo
end subroutine sdi_normal
!
subroutine sdi_scalec(wcl,ncl,f,s,compon,nx,ny)
  use clean_def
  !----------------------------------------------------------------------
  ! @ private
  !*
  ! IMAGER  -- CLEAN Method SDI  
  ! Subtract last major cycle components from residual map.
  !!
  !----------------------------------------------------------------------
  integer, intent(in) :: nx               !! X size
  integer, intent(in) :: ny               !! Y size
  integer, intent(in) :: ncl              !! Number of clean components
  type(cct_par), intent(inout) :: wcl(ncl)  !! Clean components
  real, intent(in) :: f                   !! Gain factor
  real, intent(inout) :: s                !! Cumulative flux
  real, intent(inout) :: compon(nx,ny)    !! Cumulative clean component
  !
  ! Local ---
  integer i
  !
  ! Code ----
  do i=1,ncl
    wcl(i)%value = wcl(i)%influx*f
    s = s+wcl(i)%value
    compon(wcl(i)%ix,wcl(i)%iy) = compon(wcl(i)%ix,wcl(i)%iy) + wcl(i)%value
  enddo
end subroutine sdi_scalec

