!
subroutine one_beam (rname,map,huv,hbeam,hdirty,   &
     &    nx,ny,nu,nv,uvdata,   &
     &    w_mapu, w_mapv, w_grid, w_weight, w_v, do_weig,    &
     &    wcol,mcol,wfft,sblock,cpu0,error,uvmax)
  use gkernel_interfaces
  use imager_interfaces, except_this=>one_beam
  use clean_def
  use image_def
  use gbl_message
  use clean_default
  !------------------------------------------------------------------------
  ! @ private
  !
  ! MAPPING
  !   Compute a map from a CLIC UV Sorted Table
  !   by Gridding and Fast Fourier Transform, with
  !   one single beam for all channels.
  !
  ! Input :
  ! a precessed UV table, sorted in V, ordered in
  ! (U,V,W,D,T,iant,jant,nchan(real,imag,weig))
  ! Output :
  ! a beam image
  ! a VLM cube
  ! Work space :
  ! a  VLM complex Fourier cube (first V value is for beam)
  !------------------------------------------------------------------------
  character(len=*), intent(in) :: rname   ! Calling Task name
  type (uvmap_par), intent(inout) :: map  ! Mapping parameters
  type (gildas), intent(inout) :: huv     ! UV data set
  type (gildas), intent(inout) :: hbeam   ! Dirty beam data set
  type (gildas), intent(inout) :: hdirty  ! Dirty image data set
  integer, intent(in) :: nx   ! X size
  integer, intent(in) :: ny   ! Y size
  integer, intent(in) :: nu   ! Size of a visibilities
  integer, intent(in) :: nv   ! Number of visibilities
  real, intent(inout) :: uvdata(nu,nv)
  real, intent(inout) :: w_mapu(nx)      ! U grid coordinates
  real, intent(inout) :: w_mapv(ny)      ! V grid coordinates
  real, intent(inout) :: w_grid(nx,ny)   ! Gridding space
  real, intent(inout) :: w_weight(nv)    ! Weight of visibilities
  real, intent(inout) :: w_v(nv)         ! V values
  logical, intent(inout) :: do_weig
  !
  real, intent(inout) :: wfft(*)     ! Work space
  real, intent(inout) :: cpu0        ! CPU
  real, intent(inout) :: uvmax       ! Maximum baseline
  integer, intent(inout) :: sblock   ! Blocking factor
  integer, intent(inout) :: wcol     ! Weight channel
  integer, intent(inout) :: mcol(2)  ! First and last channel
  logical, intent(inout) :: error
  !
  if (omp_single_beam.eq.0) then
    Print *,'Calling SERIAL one_beam'
    call one_beam_serial (rname,map,huv,hbeam,hdirty,   &
     &    nx,ny,nu,nv,uvdata,   &
     &    w_mapu, w_mapv, w_grid, w_weight, w_v, do_weig,    &
     &    wcol,mcol,wfft,sblock,cpu0,error,uvmax)
  else
    Print *,'Calling PARALLEL one_beam'
    call one_beam_para (rname,map,huv,hbeam,hdirty,   &
     &    nx,ny,nu,nv,uvdata,   &
     &    w_mapu, w_mapv, w_grid, w_weight, w_v, do_weig,    &
     &    wcol,mcol,wfft,sblock,cpu0,error,uvmax)
  endif
end subroutine one_beam
!
subroutine check_order(visi,np,nv,sorted)
  !----------------------------------------------------------
  ! @ private
  !
  ! MAPPING
  !   Check if visibilites are sorted.
  !   Chksuv does a similar job, but using V values and an index.
  !----------------------------------------------------------
  integer, intent(in) :: np       ! Size of a visibility
  integer, intent(in) :: nv       ! Number of visibilities
  real, intent(in) :: visi(np,nv) ! Visibilities
  logical, intent(out) :: sorted
  !
  real vmax
  integer iv
  !
  vmax = visi(2,1)
  do iv=1,nv
    if (visi(2,iv).lt.vmax) then
      sorted = .false.
      return
    endif
    vmax = visi(2,iv)
  enddo
  sorted = .true.
end subroutine check_order
!
subroutine cct_prepare(line,nc,a_method,task,error)
  use gkernel_interfaces
  use imager_interfaces, only : get_i4list_fromsic, get_r4list_fromsic, map_message
  use clean_def
  use clean_arrays
  use clean_types
  use clean_default
  use gbl_message
  !---------------------------------------------------
  ! @ private
  !
  ! MAPPING
  !   Prepare the Clean Component Table
  !---------------------------------------------------
  character(len=*), intent(in) :: line      ! Command line
  integer, intent(in) :: nc                 ! Number of channels
  type(clean_par), intent(in) :: a_method   ! Input method
  character(len=*), intent(in) :: task      ! Caller name
  logical, intent(out) :: error  !
  ! Local
  integer(kind=4) :: ier,x_iter
  integer, parameter :: opt_iter=4
  integer, parameter :: opt_ares=5
  !
  error = .false.
  x_iter = a_method%m_iter
  !
  ! Use up to nc = hdirty%gil%dim(3)
  if (sic_present(opt_iter,0)) then
    niter_listsize = hdirty%gil%dim(3)
    Print *,'Allocating per plane NITER ',niter_listsize
    if (allocated(niter_list)) deallocate(niter_list)
    allocate(niter_list(niter_listsize),stat=ier)
    call get_i4list_fromsic(task,line,opt_iter,niter_listsize, &
      & niter_list,error)
    if (error) return
    ! 
    x_iter = maxval(niter_list)
  endif
  !
  if (sic_present(opt_ares,0)) then
    ares_listsize = hdirty%gil%dim(3)
    Print *,'Allocating per plane ARES ',ares_listsize
    if (allocated(ares_list)) deallocate(ares_list)
    allocate(ares_list(ares_listsize),stat=ier)
    call get_r4list_fromsic(task,line,opt_ares,ares_listsize, &
      & ares_list,error)
    if (error) return
  endif
  !
  if (a_method%method.eq.'MULTI') x_iter = a_method%ninflate*x_iter
  !print *,'CCT-Prepare, Method ',method%method,m_iter,x_iter
  !print *,'CCT-Prepare, FIRST ',a_method%first,' LAST ',a_method%last
  call sic_delvariable('CCT',.false.,error)
  if (error)  error = .false.  ! Not an error if no such variable
  !
  x_iter = max(1,x_iter)
  call reallocate_cct(3,nc,x_iter,dcct,error)
  if (error)  return
  dcct(:,a_method%first:a_method%last,:) = 0.  ! Nullify the channels to be used
  !
  ! Define the image header
  call gildas_null(hcct)
  call gdf_copy_header (hdirty,hcct,error)
  hcct%gil%ndim = 3
  hcct%char%unit = 'Jy'
  !
  hcct%gil%dim(1) = 3
  ! Keep the same axis description
  hcct%gil%xaxi = 1
  !
  hcct%gil%convert(:,2) = hdirty%gil%convert(:,3)
  hcct%gil%convert(:,3) = hdirty%gil%convert(:,2)
  hcct%gil%dim(2) = hdirty%gil%dim(3)
  hcct%char%code(2) = hdirty%char%code(3)
  hcct%gil%faxi = 2
  hcct%gil%dim(3) = x_iter
  hcct%char%code(3) = 'COMPONENT'
  hcct%gil%yaxi = 3
  hcct%loca%size = 3*hcct%gil%dim(2)*hcct%gil%dim(3)
  !
  ! Initialize BLCs...
  hcct%blc = 0
  hcct%trc = 0
  !
contains
  subroutine reallocate_cct(n1,n2,n3,array,error)
    use gbl_message
    use imager_interfaces, only : map_message
    !-------------------------------------------------------------------
    ! (re)allocate the CCT allocatable array.
    ! If only the last dimension is enlarged, the previous contents are
    ! kept. Otherwise, the data is initialized to 0.
    !-------------------------------------------------------------------
    integer(kind=4),           intent(in)    :: n1,n2,n3      ! New dimensions
    real(kind=4), allocatable, intent(inout) :: array(:,:,:)  !
    logical,                   intent(inout) :: error         !
    ! Local
    character(len=message_length) :: mess
    logical :: keep
    integer(kind=4) :: ier,oldn1,oldn2,oldn3
    real(kind=4), allocatable :: tmp(:,:,:)
    !
    if (n1.le.0 .or. n2.le.0 .or. n3.le.0) then
      write(mess,'(A,3(I0,A))')  &
        'CCT size can not be zero nor negative (got n1 x n2 x n3 = ',  &
        n1,'x',n2,'x',n3,')'
      call map_message(seve%e,task,mess)
      error = .true.
      return
    endif
    !
    keep = .false.
    if (allocated(array)) then
      oldn1 = ubound(array,1)
      oldn2 = ubound(array,2)
      oldn3 = ubound(array,3)
      if (oldn1.eq.n1 .and.  &  ! Strict equality
          oldn2.eq.n2 .and.  &  ! Strict equality
          oldn3.ge.n3) then     ! Greater or equal
        write(mess,'(a,i0,a,i0,a,i0)')  &
          'Re-using current CCT table of size ',oldn1,' x ',oldn2,' x ',oldn3
        call map_message(seve%i,task,mess)
        return
      endif
      !
      write(mess,'(a,i0,a,i0,a,i0,a)')  &
        'Current CCT table has size ',oldn1,' x ',oldn2,' x ',oldn3,', increasing'
      call map_message(seve%i,task,mess)
      if (oldn1.eq.n1 .and.  &  ! Strict equality
          oldn2.eq.n2) then     ! Strict equality
        ! The 2 first dimensions are not modified, only the third is enlarged.
        ! Data will be kept.
        keep = .true.
        call move_alloc(from=array,to=tmp)
        ! 'array' is now deallocated
      else
        deallocate(array)
      endif
    endif
    !
    ! Allocation
    allocate(array(n1,n2,n3),stat=ier)
    if (failed_allocate(task,'ARRAY',ier,error))  return
    write(mess,'(a,i0,a,i0,a,i0)')  &
      'Allocated new CCT table of size ',n1,' x ',n2,' x ',n3
    call map_message(seve%i,task,mess)
    !
    ! Back copy
    if (keep) then
      array(:,:,1:oldn3) = tmp(:,:,1:oldn3)
      array(:,:,oldn3+1:n3) = 0.
      deallocate(tmp)
    else
      array(:,:,:) = 0.
    endif
    !
  end subroutine reallocate_cct
  !
end subroutine cct_prepare
!
subroutine get_i4list_fromsic(rname,line,opt,nf,list,error)
  use gkernel_interfaces
  use gkernel_types
  use gbl_message
  use gbl_format
  use imager_interfaces, only : map_message
  !
  ! @ public-mandatory
  !
  ! Return in the allocatable array the content of the 1-D
  ! SIC variable given as argument of Option # opt.
  ! Return the size of the array in NF
  ! If NF is non zero on entry, the size must match and the
  ! array is pre-allocated.
  !
  character(len=*), intent(in) :: rname
  character(len=*), intent(in) :: line
  integer, intent(in) :: opt
  integer, intent(inout) :: nf
  integer, allocatable, intent(inout) :: list(:)
  logical, intent(out) :: error
  !
  character(len=64) :: listname
  logical :: found
  integer(kind=address_length) :: jpd
  type(sic_descriptor_t) :: desc
  integer :: na, ier
  integer, save :: memory(2)
  !
  call sic_ch(line,opt,1,listname,na,.true.,error)
  if (error) return
  call sic_descriptor(listname,desc,found)
  if (.not.found) then
    call sic_i4(line,opt,1,na,.true.,error)
    if (error) then
      call map_message(seve%e,rname,'Variable '//trim(listname)//' does not exists.')
      return 
    endif
    if (nf.eq.0) then
      nf = 1
      allocate(list(nf),stat=ier)
    else if (nf.ne.1) then
      call map_message(seve%e,rname,'Number of elements mismatch in List')
      error = .true.
    else if (.not.allocated(list)) then
      call map_message(seve%e,rname,'List is not allocated')
      error = .true.
    endif
    if (error) return
    list(1:nf) = na
    return
  else if (desc%type.ne.fmt_i4) then
    call map_message(seve%e,rname,'Variable '//trim(listname)//' must be Integer ')
    error = .true.
    return
  endif
  if (desc%ndim.ne.1) then
    call map_message(seve%e,rname,'Variable '//trim(listname)//' must have rank 1')
    error = .true.
    return
  endif
  if (nf.eq.0) then
    nf = desc%dims(1)
    allocate(list(nf),stat=ier)
  else if (nf.ne.desc%dims(1)) then
    call map_message(seve%e,rname,'Number of elements mismatch in List')
    error = .true.
  else if (.not.allocated(list)) then
    call map_message(seve%e,rname,'List is not allocated')
    error = .true.
  endif
  if (error) return
  !
  jpd = gag_pointer(desc%addr,memory)
  call i4toi4(memory(jpd),list,nf)
end subroutine get_i4list_fromsic
!
subroutine get_r4list_fromsic(rname,line,opt,nf,list,error)
  use gkernel_interfaces
  use gkernel_types
  use gbl_message
  use gbl_format
  use imager_interfaces, only : map_message
  !
  ! @ public-mandatory
  !
  ! Return in the allocatable array the content of the 1-D
  ! SIC variable given as argument of Option # opt.
  ! Return the size of the array in NF
  ! If NF is non zero on entry, the size must match and the
  ! array is pre-allocated.
  !
  character(len=*), intent(in) :: rname
  character(len=*), intent(in) :: line
  integer, intent(in) :: opt
  integer, intent(inout) :: nf
  real, allocatable, intent(inout) :: list(:)
  logical, intent(out) :: error
  !
  character(len=64) :: listname
  logical :: found
  integer(kind=address_length) :: jpd
  type(sic_descriptor_t) :: desc
  integer :: na, ier
  integer, save :: memory(2)
  !
  call sic_ch(line,opt,1,listname,na,.true.,error)
  if (error) return
  call sic_descriptor(listname,desc,found)
  if (.not.found) then
    call sic_i4(line,opt,1,na,.true.,error)
    if (error) then
      call map_message(seve%e,rname,'Variable '//trim(listname)//' does not exists.')
      return 
    endif
    if (nf.eq.0) then
      nf = 1
      allocate(list(nf),stat=ier)
    else if (nf.ne.1) then
      call map_message(seve%e,rname,'Number of elements mismatch in List')
      error = .true.
    else if (.not.allocated(list)) then
      call map_message(seve%e,rname,'List is not allocated')
      error = .true.
    endif
    if (error) return
    list(1:nf) = na
    return
  else if (desc%type.ne.fmt_i4) then
    call map_message(seve%e,rname,'Variable '//trim(listname)//' must be Integer ')
    error = .true.
    return
  endif
  if (desc%ndim.ne.1) then
    call map_message(seve%e,rname,'Variable '//trim(listname)//' must have rank 1')
    error = .true.
    return
  endif
  if (nf.eq.0) then
    nf = desc%dims(1)
    allocate(list(nf),stat=ier)
  else if (nf.ne.desc%dims(1)) then
    call map_message(seve%e,rname,'Number of elements mismatch in List')
    error = .true.
  else if (.not.allocated(list)) then
    call map_message(seve%e,rname,'List is not allocated')
    error = .true.
  endif
  if (error) return
  !
  jpd = gag_pointer(desc%addr,memory)
  call r4tor4(memory(jpd),list,nf)
end subroutine get_r4list_fromsic

