subroutine uv_model_comm(line,error)
  use gildas_def
  use gbl_message
  use gkernel_interfaces
  use clean_default
  use clean_arrays
  use imager_interfaces, except_this => uv_model_comm
  !---------------------------------------------------------------------
  ! @ private
  !*
  ! IMAGER -- Support routine for command  
  !     MODEL [Args] [/MINVAL Value [Unit]] [/OUTPUT]  
  !           [/MODE CCT|UV_FIT|IMAGE|SELF [Frequency]]
  !
  ! Dispatch to adequate routine as specified by /MODE option to   
  !  - Compute the UV_MODEL data set from the current CCT table  
  ! or  
  !  - Compute the UV_MODEL data set from the current UV_FIT results  
  ! or  
  !  - Compute the UV_MODEL data set from the specified IMAGE variable
  !
  !   If no /MODE option is specified, the operation depends on whether 
  ! CLEAN or UV_FIT was executed last.
  !
  !   The /OUTPUT option is dummy, being present only for compatibility
  ! with the UV_RESIDUAL command
  !!
  !---------------------------------------------------------------------
  character(len=*), intent(inout) :: line       !! Command line
  logical, intent(inout) :: error               !! Logical Error flag
  !
  ! Constants
  character(len=*), parameter :: rname='MODEL'
  integer, parameter :: o_minval=1 ! 
  integer, parameter :: o_output=2 ! Must be 2 ...
  integer, parameter :: o_mode=3  
  integer, parameter :: mmode=5
  character(len=12) vocs(mmode)
  data vocs/'CCT','COMPONENT','IMAGE','UV_FIT','SELF'/ 
  !
  ! Local ---
  integer :: imode
  character(len=12) argu,cmode
  logical :: OLD=.TRUE.
  !
  call sic_get_logi('MODEL_OLD',old,error)
  error = .false.
  !
  ! Code ----
  if (sic_present(o_mode,0)) then
    call sic_ke(line,o_mode,1,argu,imode,.true.,error)
    if (error) return
    call sic_ambigs(rname,argu,cmode,imode,vocs,mmode,error)
    if (error) return
  else
    cmode = last_resid ! CCT or UV_FIT
  endif
  call sic_delvariable('UV_MODEL',.false.,error)
  !
  error = .false.
  !
  uv_model_updated = .true.
  select case (cmode)
  case ('UV_FIT')    
    call uvfit_residual_model(line,'MODEL',1,error)
    return
  case ('CCT','COMPONENT')
    huv_current%r2d => duv
    if (OLD) then
      call cct_fast_uvmodel(line,huv_current,error)
    else
      call cct_new_uvmodel(line,huv_current,error)
    endif
  case ('SELF')
    if (themap%nfields.le.1) then
      ! Single field case...
      if (OLD) then
        if (hself_calib%gil%nchan.gt.1) then
          hself_calib%r2d => duvcalib
          call cct_fast_uvmodel(line,hself_calib,error)
        else
          hself_self%r2d => duvself
          call cct_fast_uvmodel(line,hself_self,error)
        endif
      else
        if (hself_calib%gil%nchan.gt.1) then
          hself_calib%r2d => duvcalib
          call map_message(seve%w,rname,'Using ctt_new_uvmodel with Line data',seve%e)
          call cct_new_uvmodel(line,hself_calib,error)
        else
          hself_self%r2d => duvself
          call map_message(seve%w,rname,'Using ctt_new_uvmodel with Continuum',seve%e)
          call cct_new_uvmodel(line,hself_self,error)
        endif
      endif
    else
      if (hself_calib%gil%nchan.gt.1) then
        hself_calib%r2d => duvcalib
        call map_message(seve%w,rname,'New MODEL for Mosaic Self-Calibration -- Not yet Finished ....',seve%e)
        call map_message(seve%w,rname,'Using cct_new_uvmodel ',seve%e)
        call cct_new_uvmodel(line,hself_calib,error)
      else
        hself_self%r2d => duvself
        call map_message(seve%w,rname,'Using self_uvmodel ',seve%e)
        call self_uvmodel(line,hself_self,error)
      endif
    endif
      !
  case default
    !!Print *,'Mode IMAGE '
    call map_uvmodel(line,error)
  end select
  if (error) return
  !
  huv_model%loca%size = huv_model%gil%dim(1)*huv_model%gil%dim(2)
  huv_model%r2d => duvm
  call sic_mapgildas('UV_MODEL',huv_model,error,huv_model%r2d)
  !
end subroutine uv_model_comm
!<FF>
subroutine map_uvmodel(line,error)
  use gildas_def
  use gbl_message
  use gkernel_interfaces
  use clean_arrays
  use iso_c_binding
  use imager_interfaces, except_this => map_uvmodel
  !---------------------------------------------------------------------
  ! @ private
  !*
  ! IMAGER -- Parsing routine for command  
  !     MODEL ImageName [/MINVAL Value [Unit]] /MODE IMAGE [Frequency]
  !
  ! Compute the UV_MODEL data set from the specified image.
  ! Parsing only to call the effective routine. 
  !
  !!
  !---------------------------------------------------------------------
  character(len=*), intent(in) :: line      !! Command line
  logical, intent(inout) :: error           !! Logical Error flag
  !
  ! Constants
  character(len=*), parameter :: rname='MODEL'
  real(kind=8), parameter :: pi=3.14159265358979323846d0
  integer, parameter :: o_minval=1 ! 
  integer, parameter :: o_output=2 ! Must be 2 ...
  integer, parameter :: o_mode=3   
  ! 
  ! Local ---
  real :: fmin ! Minimum flux
  real(8) :: freq ! Effective frequency - to be checked !!!
  character(len=filename_length) :: namex
  type(gildas) :: hmap
  real, allocatable, target :: dmap(:,:,:)
  integer :: nf,mx,my, nc, ier
  logical :: is_image, is_clean, rdonly, large
  type(c_ptr) :: cptr
  real, pointer :: rptr(:,:,:)
  real :: cpu0
  !
  ! Code ----
  large = sic_present(0,2) ! Test
  !
  if (.not.associated(duv)) then
    call map_message(seve%e,rname,'No UV data (DUV is not associated)') 
    error = .true.
    return
  endif
  !
  error = .false.
  call gag_cpu(cpu0)
  !
  ! Input data is the current UV Data  huv & duv
  !
  ! Input MAP is specified as first argument, or defaults to CLEAN
  call gildas_null(hmap)
  if (sic_present(0,1)) then
    call sic_ch(line,0,1,namex,nc,.true.,error)
    if (error) return
    is_clean = .false.
    is_image = .false.    ! Allow SIC variable or GILDAS Data file
    call sub_readhead (rname,namex,hmap,is_image,error,rdonly,fmt_r4)
  else
    ! Use the CLEAN image so far for a test...
    if (hclean%loca%size.eq.0) then
      call map_message(seve%w,rname,'No CLEAN image')
      error = .true.
      return
    endif
    call gdf_copy_header(hclean,hmap,error)
    is_clean = .true.
  endif
  !
  ! There must be some match of the Velocity axis (not the frequency axis)
  ! This match may imply a change of number of channels, i.e.
  ! we should be able to define the intersection of the two velocity
  ! axis.  For the time being, just assume they are identical,
  ! or take the Image axis if the UV data is just 1 channel.
  if (huv_current%gil%nchan.ne.1) then
    if (hmap%gil%dim(3).ne.huv_current%gil%nchan) then
      call map_message(seve%w,rname,'Velocity axis mis-match, using UV coverage only')
    endif
  endif
  nf = hmap%gil%dim(3) ! In all cases
  mx = hmap%gil%dim(1)
  my = hmap%gil%dim(2)
  !
  ! Then do the job as in the CCT case, except for the Scale factor...
  allocate (dmap(mx,my,nf),stat=ier)
  if (ier.ne.0) then
    call map_message(seve%e,rname,'MAP Allocation error')
    error = .true.
    return
  endif
  !
  ! We need a copy because we ignore edges
  if (is_clean) then
    !TEST!Print *,'Using CLEAN'
    dmap(:,:,:) = dclean 
  else if (is_image) then
    !TEST!Print *,'Using an IMAGE '
    call adtoad(hmap%loca%addr,cptr,1)
    call c_f_pointer(cptr,rptr,hmap%gil%dim(1:3))
    dmap(:,:,:) = rptr
  else
    !TEST!Print *,'Reading a data file'
    call gdf_read_data(hmap,dmap,error)
    if (error) return
    call gdf_close_image(hmap,error)
  endif
  !
  ! Retrieve minimum value and Frequency
  call mod_min_image (line,hmap,huv_current,freq,fmin,error)
  if (error) return
  !
  if (fmin.gt.0) then
    where (abs(dmap).lt.fmin)  dmap = 0.
  endif
  !
  ! Now call the Sub-routine
  call map_fast_uvmodel(huv_current,duv,huv_model,duvm,hmap,dmap,themap,freq,error)
  deallocate(dmap)
  !
end subroutine map_uvmodel
!<FF>
subroutine map_fast_uvmodel(huvl,duvl,huvm,duvm,hmap,dmap,map,freq,error)
  use image_def
  use gbl_message
  use gkernel_interfaces
  use clean_def
  use iso_c_binding
  use imager_interfaces, except_this => map_fast_uvmodel
  !---------------------------------------------------------------------
  ! @ private
  !*
  ! IMAGER -- Support routine for command  
  !     MODEL ImageName [/MINVAL Value [Unit]] /MODE IMAGE [Frequency]
  !
  ! Compute the UV_MODEL data set from the specified image. 
  ! Uses an intermediate FFT with further interpolation for 
  !    better speed than UV_CCT. Also works for Mosaic Self Calibration
  !!
  !---------------------------------------------------------------------
  type(gildas), intent(in) :: huvl  !! Input UV Header
  type(gildas), intent(inout) :: huvm  !! Output Model UV Header
  real, intent(in) :: duvl(:,:)     !! Input UV data (used for UV and Frequency coverage)
  real, intent(out), allocatable :: duvm(:,:) !! Output UV data
  type(gildas), intent(in) :: hmap  !! Input Map Header
  real, intent(inout), target :: dmap(:,:,:)  !! Input dat cube
  type(uvmap_par), intent(inout) :: map       !! Imaging parameters
  real(8), intent(in) :: freq                 !! Effective frequency
  logical, intent(inout) :: error             !! Logical Error flag
  !
  ! Constants
  character(len=*), parameter :: rname='MODEL'
  real(kind=8), parameter :: pi=3.14159265358979323846d0
  integer, parameter :: o_minval=1 ! 
  integer, parameter :: o_output=2 ! Must be 2 ...
  integer, parameter :: o_mode=3   
  ! Local ---
  character(len=132) :: mess
  logical :: large
  complex, allocatable :: fft(:,:,:)
  real, allocatable :: work(:)
  integer :: if,it,nc,nx,ny,mx,my,nt,nv,mt,mv, ier, ix,iy
  real :: cpu0, cpu1
  real :: factor
  real(8) :: xinc, yinc, area, jyperk
  character(len=8) :: cunit
  real(8) :: vres
  real :: lambda, pixel_area
  real, pointer :: dlocal(:,:,:)
  integer :: ifuv, iluv, nfield, iv, ic
  ! I have an issue with IDcol
  integer :: idcol, jdcol
  integer :: ioff, joff, xoff, yoff
  logical :: doprint
  ! Radial profile
  integer :: nr, ntel
  real :: bsize(10)
  real(8), allocatable :: profile(:,:,:) ! Radial profile
  !
  ! Code ----
  large = sic_present(0,2) ! Test
  !
  idcol = huvl%gil%column_pointer(code_uvt_id)
  !
  ! Code
  error = .false.
  call gag_cpu(cpu0)
  !
  nc = hmap%gil%dim(3) ! In all cases
  mx = hmap%gil%dim(1)
  my = hmap%gil%dim(2)
  !
  ! Then do the job as in the CCT case, except for the Scale factor...
  !
  ! Define observing frequency
  vres = hmap%gil%vres
  xinc = hmap%gil%inc(1)
  yinc = hmap%gil%inc(2)
  !
  ! Replace Blanking by 0
  if (hmap%gil%eval.ge.0) then
    do ic=1,nc
      do iy=1,my
        do ix=1,mx
          if (abs(dmap(ix,iy,ic)-hmap%gil%bval).le.hmap%gil%eval) then
            dmap(ix,iy,ic) = 0
          endif
        enddo
      enddo
    enddo
  endif
  !
  ! Prepare the UV output
  call gildas_null(huvm, type = 'UVT')
  !
  ! Do we want the same frequency layout as the UV data or that of the TEMPLATE (MAP or CLEAN COMPONENT) ? 
  ! The UV data specifies the appropriate UV coverage, 
  ! but the MAP specifies the Spectroscopy by default
  !
  ! Analysis of the /MODE option yields the choice
  call gdf_copy_header(huvl,huvm,error) 
  !
  write(mess,'(A,I0,A,I0)') 'Channels: in UV data ',huvl%gil%nchan,' ; in Model cube ',hmap%gil%dim(3)
  call map_message(seve%i,rname,mess,seve%w)
  huvm%gil%nchan = nc ! Reset number of channels
  !
  if (huvl%gil%nchan.eq.huvm%gil%nchan) then
    call map_message(seve%i,rname,'Number of channels match between UV data and Model')
  else if (huvl%gil%nchan.eq.1) then
    call map_message(seve%i,rname,'Extending UV data to number of channels in Model')
    ! Push the extra column by the difference in the Channel number
    do ic=1,code_uvt_last
      if (huvm%gil%column_pointer(ic).gt.10) then
        huvm%gil%column_pointer(ic) = huvm%gil%column_pointer(ic) + 3*(huvm%gil%nchan-1)
      endif
    enddo
    huvm%gil%dim(1) = huvl%gil%dim(1)+3*(huvm%gil%nchan-1)
  else
    write(mess,'(A,I0,A,I0)') 'Mismatch Channels UV data ',huvl%gil%nchan,' - Model cube ',huvm%gil%nchan
    call map_message(seve%e,rname,mess)
    error = .true.
    return
  endif
  !
  ! Avoid edges by default - Do not even bother to check for a mask
  ! or whatever - It is needed to avoid aliasing in any case
  do ic=1,nc
    dmap(1:(mx/8),:,ic) = 0
    dmap((7*mx)/8:mx,:,ic) = 0
    dmap(:,1:(my/8),ic) = 0
    dmap(:,(7*my)/8:my,ic) = 0
  enddo
  !
  ! Define the image size
  call mod_fft_size(large,mx,my,nx,ny)
  call gag_cpu(cpu1)
  !
  ! Get Virtual Memory & compute the FFT
  allocate (fft(nx,ny,nc),work(2*max(nx,ny)),stat=ier)
  if (ier.ne.0) then
    call map_message(seve%e,rname,'FFT space allocation error')
    error = .true.
    return
  endif
  !
  ! Loop over fields if needed
  nfield = abs(map%nfields) 
  if (nfield.gt.1) then
    if (huvl%gil%column_pointer(code_uvt_id).eq.0) then
      call map_message(seve%e,rname,'MODEL does not work for Mosaics that have no POINTING Table')
      call map_message(seve%i,rname,'Use the MOSAIC command before')
      error = .true.
      return
    endif
  else
    nfield = 1
  endif
  !
  ioff = code_uvt_xoff
  joff = code_uvt_yoff
  xoff = huvm%gil%column_pointer(ioff)
  yoff = huvm%gil%column_pointer(joff)
  !
  if ((idcol.ne.0).and.((xoff.eq.0).or.(yoff.eq.0))) then
    xoff = huvm%gil%column_pointer(code_uvt_loff)
    yoff = huvm%gil%column_pointer(code_uvt_moff)
    if ((xoff.eq.0).or.(yoff.eq.0)) then
      jdcol = huvm%gil%column_pointer(code_uvt_id)
      huvm%gil%column_pointer(code_uvt_id) = 0
      huvm%gil%column_size(code_uvt_id) = 0
      if (jdcol.lt.huvm%gil%dim(1)) then
        huvm%gil%column_pointer(ioff)= jdcol
        huvm%gil%column_pointer(joff)= jdcol+1
      else if (jdcol.eq.huvm%gil%dim(1)) then
        huvm%gil%dim(1) = huvm%gil%dim(1)+1
        huvm%gil%column_pointer(ioff)= huvm%gil%dim(1)-1
        huvm%gil%column_pointer(joff)= huvm%gil%dim(1)
      else
        huvm%gil%dim(1) = huvm%gil%dim(1)+2
        huvm%gil%column_pointer(ioff)= huvm%gil%dim(1)-1
        huvm%gil%column_pointer(joff)= huvm%gil%dim(1)
      endif
    else
      huvm%gil%column_pointer(code_uvt_xoff) = huvm%gil%column_pointer(code_uvt_loff)
      huvm%gil%column_pointer(code_uvt_loff) = 0
      huvm%gil%column_size(code_uvt_loff) = 0
      huvm%gil%column_pointer(code_uvt_yoff) = huvm%gil%column_pointer(code_uvt_moff)
      huvm%gil%column_pointer(code_uvt_moff) = 0
      huvm%gil%column_size(code_uvt_moff) = 0
    endif
    huvm%gil%column_size(ioff) = 1
    huvm%gil%column_size(joff) = 1
    xoff = huvm%gil%column_pointer(ioff)
    yoff = huvm%gil%column_pointer(joff)
  endif
  !
  if (allocated(duvm)) deallocate(duvm)
  allocate (duvm(huvm%gil%dim(1),huvm%gil%dim(2)),stat=ier)
  if (ier.ne.0) then
    call map_message(seve%e,rname,'UV Model allocation error')
    error = .true.
    return
  endif
  nt = huvm%gil%dim(1)
  nv = huvm%gil%dim(2)
  mt = huvl%gil%dim(1)
  mv = huvl%gil%nvisi
  !
  huvm%gil%ref(1)  = hmap%gil%ref(3)
  huvm%gil%val(1)  = freq
  !
  ! Set the velocity resolution
  huvm%gil%vres = vres
  huvm%gil%fres = -vres*freq/299792.458d0  ! Velocity in km/s
  huvm%gil%inc(1)  = huvm%gil%fres 
  !
  huvm%gil%freq = freq
  huvm%char%line = hmap%char%line 
  huvm%gil%voff = hmap%gil%voff
  !
  ! Set the number of channels
  huvm%gil%nchan = nc
  huvm%gil%convert(:,1) = hmap%gil%convert(:,3)
  !
  write(mess,'(A,I0,A,I0)') 'Channels UV coverage ',huvl%gil%nchan,' - in Model cube ',huvm%gil%nchan
  call map_message(seve%w,rname,mess)
  !
  ! Unit is according to Image characteristics
  !
  cunit = hmap%char%unit
  call sic_upper(cunit)
  jyperk = 1.0
  if (cunit.eq.'JY/BEAM') then
    ! Get the scale factor of the input data. We want
    ! a model image in K for the rest of the job.
    area = pi*hmap%gil%majo*hmap%gil%mino/4/log(2.0)
    if (area.ne.0) then
      jyperk = 2*1.38e3*area/(299792458d0/freq*1d-6)**2
    else
      call map_message(seve%w,rname,'No beam size, using arbitrary units')
    endif
  else if (cunit.eq.'JY/PIXEL') then
    area = abs(hmap%gil%inc(1)*hmap%gil%inc(2))
    jyperk = 2*1.38e3*area/(299792458d0/freq*1d-6)**2
  else if (cunit.eq.'K') then
    jyperk = 1.0
  endif
  !
  ! Define scaling factor from Brightness to Flux (2 k B^2 / l^2)
  lambda = 299792.458e3/(freq*1e6) ! in meter
  ! 1.38E3 is the Boltzmann constant times 10^26 to give result in Jy
  pixel_area = abs(xinc*yinc)   ! in radian
  factor = 2*1.38e3/lambda**2*pixel_area
  !
  factor = factor/jyperk  
  !
  if (nfield.gt.1) then
    allocate (dlocal(mx,my,nc),stat=ier)
  endif
  !
  ! Cannot save Memory by Splitting into UV data copy first
  !   and 
  ! Model computation next, except for Single field
  bsize = 0
  ntel = huvl%gil%nteles
  if (nfield.gt.1) then
    call primary_radial(' ',bsize,hmap,nr,ntel,profile,error)
    if (error) return
  endif
  !
  doprint = real(mv)*real(nc).GE.5E7
  iluv = 0  
  do if=1,nfield      ! This is purely SEQUENTIAL, as the ifuv / iluv pointers are incremented
    if (nfield.eq.1) then
      dlocal => dmap
      ifuv = 1
      iluv = nv
      ! At this stage, we just copy the DAPs and the weights.
      if (huvl%gil%nchan.eq.huvm%gil%nchan) then
        if (doprint) call map_message(seve%i,rname,'Copying Visibilities')
        duvm(1:nt,1:nv) = duvl(1:nt,1:nv)
      else if (huvl%gil%nchan.eq.1) then
        if (doprint) call map_message(seve%i,rname,'Copying Leading columns and Weights')
        do iv=1,mv
          duvm(1:7,iv) = duvl(1:7,iv)
          do ic=1,huvm%gil%nchan
            duvm(7+3*ic,iv) = duvl(10,iv)
          enddo
        enddo
      endif
    else
      !
      ! Compute and apply Primary beam attenuation
      it = huvl%mos%fields(if)%jteles
      call apply_primary_single(dlocal,dmap,dble(huvl%mos%fields(if)%opoint(1)), &
        dble(huvl%mos%fields(if)%opoint(2)),hmap,nr,profile(:,:,it),error)
      !
      ! Copy appropriate UV data 
      ifuv = iluv+1      
      do iv=1,mv
        if (duvl(idcol,iv).eq.if) then
          iluv = iluv+1
          if (huvl%gil%nchan.eq.huvm%gil%nchan) then
            duvm(1:nt,iluv) = duvl(1:nt,iv)
          else if (huvl%gil%nchan.eq.1) then
            duvm(1:nt,iluv) = 0
            duvm(1:7,iluv) = duvl(1:7,iv)
            do ic=1,huvm%gil%nchan
              duvm(7+3*ic,iluv) = duvl(10,iv)
            enddo
          endif
          duvm(xoff,iluv) = huvl%mos%fields(if)%opoint(1)
          duvm(yoff,iluv) = huvl%mos%fields(if)%opoint(2)
        endif
      enddo
      nv = iluv-ifuv+1
      if (nv.ne.huvl%mos%fields(if)%nvisi) then
        write(mess,'(A,I0,A,I0,A,I0)') 'Mismatch UV data for field ',if, &
          & ' expected ',huvl%mos%fields(if)%nvisi,' got ',nv
        call map_message(seve%e,rname,mess)
      endif  
    endif
    !
    ! See UV_RESTORE also for this code
    if (doprint) call map_message(seve%i,rname,'Setting FFT for all channels')
    if (nx.eq.mx .and. ny.eq.my) then
      fft(:,:,:) = cmplx(dlocal,0.0)
    else
      fft = 0.
      do ic = 1,nc
        call plunge_real (dlocal(:,:,ic),mx,my,fft(:,:,ic),nx,ny)
      enddo
    endif
    !
    ! Compute the FFT
    if (doprint) call map_message(seve%i,rname,'Computing FFTs')
    call do_fft(nx,ny,nc,fft,work)
    call gag_cpu(cpu1)
    !
    ! Now compute the model
    if (doprint) call map_message(seve%i,rname,'Extracting Model Visibilities')
    !Print *,'Field ',if,'  IFUV ',ifuv,' ILUV ',iluv
    call do_uvmodel(duvm(:,ifuv:iluv), nt, nv, fft,nx,ny,nc,freq,xinc,yinc,factor)
    error = .false.
    call gag_cpu(cpu1) 
    !
  enddo
  !
  ! Free data cube
  if (associated(dlocal,dmap)) then
    nullify(dlocal)
  else
    deallocate(dlocal)
  endif
  !Print *,'Finish map_fast_uvmodel (T/F) ? '
  !read(5,*) error
  if (.not.error) return
  !
  huvm%file = 'model.uvt'
  call gdf_write_image(huvm,duvm,error)
  call map_message(seve%e,rname,'Map_Fast_uvmodel error. Saved on "model.uvt"')
  error = .true.
  !
end subroutine map_fast_uvmodel
!<FF>
subroutine cct_fast_uvmodel(line,huvl,error)
  use gildas_def
  use gbl_message
  use gkernel_interfaces
  use clean_arrays
  use imager_interfaces, except_this => cct_fast_uvmodel
  !---------------------------------------------------------------------
  ! @ private
  !*
  ! IMAGER --  Support routine for command  
  !     MODEL [MaxIter] [/MINVAL Value [Unit]] [/MODE CCT [Frequency]]
  !
  ! Compute the MODEL UV data set from the current CCT table
  !
  !     Uses an intermediate FFT with further interpolation for
  !     better speed than UV_CCT
  !!
  !---------------------------------------------------------------------
  character(len=*), intent(in) :: line      !! Command line
  type(gildas), intent(in) :: huvl          !! Input UV data
  logical, intent(inout) :: error           !! Error flag
  !
  ! Constants
  character(len=*), parameter :: rname='MODEL'
  real(kind=8), parameter :: pi=3.14159265358979323846d0
  integer, parameter :: o_minval=1 ! 
  integer, parameter :: o_output=2 ! Must be 2 ...
  integer, parameter :: o_mode=3   
  ! Local ---
  integer :: nclean ! Number of clean components retained
  logical :: large
  complex, allocatable :: fft(:,:,:)
  real, allocatable :: dmap(:,:,:)
  real, allocatable :: work(:)
  integer :: if,nf,nx,ny,mx,my,nt,nv,mt, ier
  real :: cpu0, cpu1
  real :: factor
  real(8) :: xinc, yinc, freq, vres
  character(len=80) :: mess
  !
  ! Code ----
  nclean = 0
  call sic_i4(line,0,1,nclean,.false.,error)
  if (error) return
  large = sic_present(0,2) ! Test
  !
  if (.not.associated(huvl%r2d)) then
    call map_message(seve%e,rname,'Input UV pointer is not associated') 
    error = .true.
    return
  endif
  ! Code
  error = .false.
  call gag_cpu(cpu0)
  !
  ! Input data is the current UV Data  huv & duv
  !
  ! Input CCT is the current CCT Data (it should match the UV data)
  !
  ! Compact it into an image
  ! This depends on the CCT type, and is done in a subroutine
  !    First, define the sampling and image size 
  call cct_def_image (hcct,mx,my,nf,xinc,yinc,error)
  if (error) return
  !
  if (nf.ne.1) then
    if (nf.ne.huvl%gil%nchan) then
      write(mess,'(A,I0,A,I0)') 'Velocity channels mis-match, CCT ',nf,' UV_DATA ',huvl%gil%nchan
      call map_message(seve%e,rname,mess)
      error = .true.
      return
    endif
  endif
  !
  !    Then do the job
  allocate (dmap(mx,my,nf),stat=ier)
  if (ier.ne.0) then
    call map_message(seve%e,rname,'MAP Allocation error')
    error = .true.
    return
  endif
  call cct_set_image (hcct,dcct,mx,my,nclean,xinc,yinc,nf,dmap,error)
  !
  ! Do we want the same velocity layout as the UV data or that of the MAP? 
  ! The UV data specifies the appropriate UV coverage, 
  ! but the MAP specifies the Spectroscopy 
  call gildas_null(huv_model, type = 'UVT')
  call gdf_copy_header(huvl,huv_model,error) ! Will work in all cases
  !
  ! Define the image size
  call mod_fft_size(large,mx,my,nx,ny)
  call gag_cpu(cpu1)
  !
  ! Get Virtual Memory & compute the FFT
  allocate (fft(nx,ny,nf),stat=ier)
  if (ier.ne.0) then
    call map_message(seve%e,rname,'FFT space allocation error')
    error = .true.
    return
  endif
  !
  ! See UV_RESTORE also for this code
  if (nx.eq.mx .and. ny.eq.my) then
    fft(:,:,:) = cmplx(dmap,0.0)
  else
    do if = 1,nf
      call plunge_real (dmap(:,:,if),mx,my,fft(:,:,if),nx,ny)
    enddo
  endif
  ! Free map
  deallocate (dmap,stat=ier)
  allocate (work(2*max(nx,ny)),stat=ier)
  if (ier.ne.0) then
    call map_message(seve%e,rname,'FFT work allocation error')
    error = .true.
    return
  endif
  !
  ! Compute the FFT
  call do_fft(nx,ny,nf,fft,work)
  call gag_cpu(cpu1)
  !
  freq = gdf_uv_frequency(huv_model)
  !
  huv_model%gil%dim(1) = 7+3*nf
  huv_model%gil%ref(1)  = hcct%gil%ref(hcct%gil%faxi)
  huv_model%gil%val(1)  = freq
  !
  ! Set the velocity resolution
  vres = hcct%gil%vres
  huv_model%gil%vres = vres
  huv_model%gil%fres = -vres*freq/299792.458d0  ! Velocity in km/s
  huv_model%gil%inc(1)  = huv_model%gil%fres 
  !
  huv_model%gil%freq = freq
  huv_model%char%line = hcct%char%line 
  huv_model%gil%voff = hcct%gil%voff
  !
  ! Set the number of channels
  huv_model%gil%nchan = nf
  huv_model%gil%convert(:,1) = hcct%gil%convert(:,hcct%gil%faxi)
  ! 
  ! Define scaling factor to Flux: we are in Jy, so this is simple
  factor = 1.0
  !
  if (allocated(duvm)) deallocate(duvm)
  allocate (duvm(huv_model%gil%dim(1),huv_model%gil%dim(2)),stat=ier)
  if (ier.ne.0) then
    call map_message(seve%e,rname,'UV Model allocation error')
    error = .true.
    return
  endif
  nt = huv_model%gil%dim(1)
  nv = huv_model%gil%dim(2)
  mt = huvl%gil%dim(1)
  !
  ! At this stage, copy the DAPs and Weights
  call copyuv (nt,nv,duvm,mt,huvl%r2d)
  !
  ! Now compute the model
  call do_uvmodel(duvm, nt, nv, fft,nx,ny,nf,freq,xinc,yinc,factor)
  !
  call gag_cpu(cpu1)
  error = .false.
end subroutine cct_fast_uvmodel
!<FF>
subroutine mod_min_image(line,hmap,huvl,freq,fmin,error)
  use gkernel_types
  use gkernel_interfaces
  use gbl_message
  use imager_interfaces, only : map_message
  !---------------------------------------------------------------------
  ! @ private-mandatory
  !*
  ! IMAGER -- Support routine for command MODEL  
  !
  !   Define output frequency and truncate the data range if needed
  !!
  !---------------------------------------------------------------------
  character(len=*), intent(in) :: line    !! Command line
  type(gildas), intent(in) :: hmap        !! Header of input data set
  type(gildas), intent(in) :: huvl        !! Header of input UV set
  real(8), intent(inout) :: freq          !! Frequency of output    
  real(4), intent(out) :: fmin            !! Minimum significant flux
  logical, intent(inout) :: error         !! Logical error flag
  !
  ! Constants
  integer, parameter :: o_minval=1        ! /MINVAL option
  integer, parameter :: o_mode=3          ! /MODE option
  real(kind=8), parameter :: pi=3.14159265358979323846d0
  character(len=*), parameter :: rname='MODEL'
  character(len=12), parameter :: cimage='IMAGE       '
  character(len=12), parameter :: cuv   ='UV_DATA     '
  !
  ! Local ---
  integer :: narg, nc
  real :: area, jyperk
  character(len=64) :: chain
  !
  ! Code ----
  !
  ! Override output frequency if needed
  freq = hmap%gil%freq+hmap%gil%fres*((hmap%gil%dim(3)+1)*0.5-hmap%gil%ref(3))
  if (sic_present(o_mode,2)) then
    call sic_ke(line,o_mode,2,chain,nc,.true.,error)
    nc = min(nc,12)
    if (chain(1:nc).eq.cimage(1:nc)) then
      continue
    else if (chain(1:nc).eq.cuv(1:nc)) then
      freq = gdf_uv_frequency(huvl)
    else
      call sic_r8(line,o_mode,2,freq,.false.,error)
      if (error) return
    endif
  endif
  write(chain,'(A,F14.6,A)') 'Frequency ',freq,' MHz'
  call map_message(seve%i,rname,chain)
  !
  narg = sic_narg(o_minval)  ! /MINVAL option
  if (narg.le.0) return
  !
  fmin = 0.
  call sic_r4(line,o_minval,1,fmin,.true.,error)
  if (error) return
  !
  if (narg.gt.1) then
    call sic_ch(line,o_minval,2,chain,nc,.true.,error)
    if (error) return
    if (chain(1:nc).eq.'sigma') then
      fmin = fmin * max(hmap%gil%noise,hmap%gil%rms)
    elseif (chain(1:nc).eq.'mJy') then
      fmin = 1e-3*fmin
    elseif (chain(1:nc).eq.'K') then
      if (hmap%gil%majo.ne.0) then
        area = pi*hmap%gil%majo*hmap%gil%mino/4/log(2.0)
        jyperk = 2*1.38e3*area/(299792458d0/freq*1d-6)**2
        fmin = fmin * jyperk 
      else
        call map_message(seve%e,rname,'Unit K unsupported in this context')
        error = .true.
        return
      endif      
    elseif (chain(1:nc).eq.'Jy') then
      fmin = fmin
    else
      call map_message(seve%e,rname,'Unrecognized unit '//chain(1:nc))
      error = .true.
      return
    endif
  endif
end subroutine mod_min_image
!<FF>
subroutine do_uvmodel (visi,nt,nv,a,nx,ny,nf,   &
     &    freq,xinc,yinc,factor)
  !$ use omp_lib
  use gbl_message
  use imager_interfaces, only : map_message
  !---------------------------------------------------------------------
  ! @ public
  !*
  ! IMAGER -- Support for command MODEL    
  ! Compute the MODEL UV data set from the current CCT table
  !
  !     Uses an intermediate FFT with further interpolation for
  !     better speed than UV_CCT
  ! CAUTION  
  !     Frequency (and hence Lambda/D) is assumed constant 
  !!
  !---------------------------------------------------------------------
  integer, intent(in) :: nt                       !! Size of visibility
  integer, intent(in) :: nv                       !! Number of visibilities
  real, intent(inout) :: visi(nt,nv)              !! Visibilities
  integer, intent(in) :: nx                       !! X Size of image
  integer, intent(in) :: ny                       !! Y Size of image
  integer, intent(in) :: nf                       !! Number of frequencies
  complex, intent(in) :: a(nx,ny,nf)              !! Clean Component Image
  real(8), intent(in) :: freq                     !! Reference frequency
  real(8), intent(in) :: xinc                     !! X Pixel increment
  real(8), intent(in) :: yinc                     !! Y Pixel increment
  real, intent(in) :: factor                      !! Flux scale factor
  !
  real(kind=8), parameter :: clight=299792458d0
  ! Local ---
  real(kind=8) :: kwx,kwy,stepx,stepy,lambda,xr,yr
  complex(kind=8) :: aplus,amoin,azero,afin
  integer :: i,if,ia,ja
  integer(kind=8) :: icount
  logical :: inside
  character(len=80) :: chain
  !
  ! Code ----
  lambda = clight/(freq*1d6)
  stepx = 1.d0/(nx*xinc)*lambda
  stepy = 1.d0/(ny*yinc)*lambda
  !
  ! Loop on visibility
  icount = 0
  !$OMP PARALLEL DEFAULT(none) &
  !$OMP SHARED(visi,nv,nt, a,nx,ny,nf, stepx,stepy,lambda, factor) &
  !$OMP PRIVATE(i,kwx,kwy,ia,ja,xr,yr,inside,if,azero,aplus,amoin,afin) &
  !$OMP REDUCTION(+:icount)
  !$OMP DO
  do i = 1, nv
    kwx =  visi(1,i) / stepx + dble(nx/2 + 1)
    kwy =  visi(2,i) / stepy + dble(ny/2 + 1)
    ia = int(kwx)
    ja = int(kwy)
    inside = (ia.gt.1 .and. ia.lt.nx) .and.   &
        &      (ja.gt.1 .and. ja.lt.ny)
    if (inside) then
      xr = kwx - ia
      yr = kwy - ja
      do if=1,nf
        !
        ! Interpolate (X or Y first, does not matter in this case)
        aplus = ( (a(ia+1,ja+1,if)+a(ia-1,ja+1,if)   &
            &          - 2.d0*a(ia,ja+1,if) )*xr   &
            &          + a(ia+1,ja+1,if)-a(ia-1,ja+1,if) )*xr*0.5d0   &
            &          + a(ia,ja+1,if)
        azero = ( (a(ia+1,ja,if)+a(ia-1,ja,if)   &
            &          - 2.d0*a(ia,ja,if) )*xr   &
            &          + a(ia+1,ja,if)-a(ia-1,ja,if) )*xr*0.5d0   &
            &          + a(ia,ja,if)
        amoin = ( (a(ia+1,ja-1,if)+a(ia-1,ja-1,if)   &
            &          - 2.d0*a(ia,ja-1,if) )*xr   &
            &          + a(ia+1,ja-1,if)-a(ia-1,ja-1,if) )*xr*0.5d0   &
            &          + a(ia,ja-1,if)
        ! Then Y (or X)
        afin = ( (aplus+amoin-2.d0*azero)   &
            &          *yr + aplus-amoin )*yr*0.5d0 + azero
        !
        visi(5+3*if,i) =  real(afin)*factor
        ! There was a - sign in the precedent version
        visi(6+3*if,i) =  imag(afin)*factor
      enddo
    else
      icount = icount+1
    endif
  enddo
  !$OMP END DO
  !$OMP END PARALLEL
  if (icount.ne.0) then
    write(chain,'(A,I0,A,I0,A)') 'Input model insufficiently spatially sampled: lost ', &
      & icount,' / ',nv, ' Visibilities'
    call map_message(seve%w,'CCT_UVMODEL',chain)
  endif
end subroutine do_uvmodel
!<FF>
subroutine do_fft (nx,ny,nf,fft,work)
  !$ use omp_lib
  use imager_interfaces, only : recent
  !! IMAGER -- Compute a Cube from its FFT
  !
  integer, intent(in)  :: nx                       !! X size
  integer, intent(in)  :: ny                       !! Y size
  integer, intent(in)  :: nf                       !! Z size
  complex, intent(inout) :: fft(nx,ny,nf)          !! FFT cube
  real, intent(inout)  :: work(2*max(nx,ny))       !! Work space
  !
  ! Local ---
  integer :: if,dim(2), ier, ithread
  real, allocatable :: lwork(:)
  !
  ! Code ----
  dim(1) = nx
  dim(2) = ny
  ! Loop on channels
  !$OMP PARALLEL DEFAULT(none) &
  !$OMP & SHARED(dim,nx,ny,nf,fft) &
  !$OMP & PRIVATE(if, ier, lwork, ithread)
  allocate(lwork(2*max(nx,ny)),stat=ier)
  !$ ithread = omp_get_thread_num()+1
  !$OMP DO
  do if = 1, nf
    !!Print *,'Starting channel ',if,' Thread ',ithread
    call fourt(fft(:,:,if),dim,2,1,1,lwork)
    call recent(nx,ny,fft(:,:,if))
  enddo
  !$OMP END DO
  !$OMP END PARALLEL
end subroutine do_fft
!<FF>
subroutine copyuv (nco,nv,out,nci,in)
  !---------------------------------------------------------------------
  ! @ public
  !
  !! IMAGER --  Copy structure of UV data, but not the (Real,Imag) columns
  !---------------------------------------------------------------------
  integer, intent(in)  :: nco                      !! Size of output visi.
  integer, intent(in)  :: nv                       !! Number of visibilities
  real, intent(out)  :: out(nco,nv)                !! Output Visibilities
  integer, intent(in) :: nci                       !! Size of input visi.
  real, intent(in)  :: in(nci,nv)                  !! Input visibilities
  !
  ! Local ---
  integer :: i,j
  !
  ! Code ----
  ! This does not handle extra columns
  do i=1,nv
    out(1:7,i) = in(1:7,i)
    do j=8,nco,3
      out(j,i) = 0
      out(j+1,i) = 0
      out(j+2,i) = in(10,i)
    enddo
  enddo
end subroutine copyuv
!
subroutine cct_def_image (hima,mx,my,nf,xinc,yinc,error)
  use image_def
  use imager_interfaces, only : map_message
  use gbl_message
  !---------------------------------------------------------------------
  ! @ private
  !
  !! IMAGER -- Define Image size from CCT information.  
  !! Supports both layouts of CCT tables.
  !---------------------------------------------------------------------
  type (gildas), intent(in) :: hima   !! Input CCT Table
  integer, intent(out) :: mx,my,nf    !! Ouput data cube size
  real(8), intent(out) :: xinc,yinc   !! Pixel size
  logical, intent(out) :: error       !! Error flag
  !
  error = .false.
  if (hima%char%code(3).eq.'COMPONENT') then
    call map_message(seve%i,'UV_FCCT','Clean Components from IMAGER')
    nf = hima%gil%dim(2)  ! Number of channels
    mx = (hima%gil%ref(1)-1)*2
    xinc = hima%gil%inc(1)
    my = (hima%gil%ref(3)-1)*2
    yinc = hima%gil%inc(3)
  else
    call map_message(seve%w,'UV_FCCT','Clean Components from old CLEAN Task')
    nf = hima%gil%dim(3)
    mx = (hima%gil%ref(1)-1)*2
    xinc = hima%gil%inc(1)
    my = (hima%gil%ref(2)-1)*2
    yinc = hima%gil%inc(2)
  endif
end subroutine cct_def_image
!
subroutine cct_set_image (hcct,clean,mx,my,mc,xinc,yinc,nf,image,error)
  use image_def
  use gbl_message
  use imager_interfaces, only : map_message
  !---------------------------------------------------------------------
  ! @ private
  !
  !! IMAGER -- Fill an Image from the list of Clean Components 
  !---------------------------------------------------------------------
  type (gildas), intent(in) :: hcct          !! CCT Table header
  real clean(hcct%gil%dim(1),hcct%gil%dim(2),hcct%gil%dim(3))  !! CCT Table
  integer, intent(in) :: mx,my,nf         !! Output data cube size
  integer, intent(in) :: mc               !! Max component number
  real(8), intent(in) :: xinc,yinc        !! Pixel size
  real, intent(out) :: image(mx,my,nf)    !! Output data
  logical, intent(out) :: error           !! Logical Error flag
  !
  ! Local ---
  integer :: lc,nc,kc,ic,jf,ix,iy
  character(len=80) :: mess
  !
  ! Code ----
  image = 0
  if (hcct%char%code(3).eq.'COMPONENT') then
    lc = hcct%gil%dim(1)
    nc = hcct%gil%dim(2)  ! Number of channels
    if (nc.ne.nf) then
      write(mess,*) 'Channel mismatch ',nc,nf
      call map_message(seve%e,'MODEL',mess)
      error = .true.
      return
    endif
    if (mc.eq.0) then
      kc = hcct%gil%dim(3)  ! Number of components
    else
      kc = min(mc,hcct%gil%dim(3))
    endif
    !
    do jf = 1,nf
      do ic = 1,kc
        if (clean(3,jf,ic).ne.0) then
          ix = nint(clean(1,jf,ic)/xinc)+mx/2+1
          iy = nint(clean(2,jf,ic)/yinc)+my/2+1
          image(ix,iy,jf) = image(ix,iy,jf) + clean(3,jf,ic)
        else
          exit ! No more components for this channel
        endif
      enddo
    enddo
  else
    lc = hcct%gil%dim(1)
    if (mc.eq.0) then
      kc = hcct%gil%dim(2)  ! Number of components
    else
      kc = min(mc,hcct%gil%dim(2))
    endif
    nc = hcct%gil%dim(3)
    if (nc.ne.nf) then
      write(mess,*) 'Channel mismatch ',nc,nf
      call map_message(seve%e,'MODEL',mess)
      error = .true.
      return
    endif
    do jf = 1,nf
      do ic = 1,kc
        if (clean(1,ic,jf).ne.0) then
          ix = nint(clean(2,ic,jf))
          iy = nint(clean(3,ic,jf))
          image(ix,iy,jf) = image(ix,iy,jf) + clean(1,ic,jf)
        else
          exit ! No more components for this channel
        endif
      enddo
    enddo
  endif
end subroutine cct_set_image
!
subroutine mod_fft_size(large,mx,my,nx,ny)
  !---------------------------------------------------------------------
  ! @ private
  !*
  ! IMAGER -- Support for MODEL  
  !   Define the intermediate FFT size - Make it square by default
  !!
  !---------------------------------------------------------------------
  logical, intent(in) :: large      !! Should size be enlarged ?
  integer, intent(in) :: mx,my      !! Input map size
  integer, intent(out) :: nx,ny     !! Output fft size
  !
  ! Local ---
  integer :: kxy, mxy
  real :: rxy
  !
  ! Code ----
  mxy = max(mx,my)
  rxy = log(float(mxy))/log(2.0)
  kxy = nint(rxy)
  if (kxy.lt.rxy) kxy = kxy+1
  nx = 2**kxy
  if (large) nx = max(mxy,min(4*nx,4096))
  ny = nx
end subroutine mod_fft_size
!!
subroutine apply_primary_single(dmap,dsky,offx,offy,hsky,nr,profile,error)
  use gkernel_interfaces
  use imager_interfaces, except_this=>apply_primary_single
  use image_def
  use gbl_message
  !---------------------------------------------------------------------
  ! @ private-mandatory
  !*
  ! IMAGER -- Support for command MODEL [BeamSize]  
  ! Compute and Applies primary beam for a single field
  !!
  !---------------------------------------------------------------------
  real, intent(out) :: dmap(:,:,:)  !! Attenuated Image
  real, intent(in) :: dsky(:,:,:)   !! True sky distribution
  real(8), intent(in) :: offx       !! X pointing offset (radians)
  real(8), intent(in) :: offy       !! Y pointing offset (radians)
  type(gildas), intent(in) :: hsky  !! Sky Header
  integer, intent(in) :: nr         !! Number of radial points for beam profile
  real(8), intent(in) :: profile(:,:)   !! Radial beam profile ((radii, values)
  logical, intent(out) :: error     !! Logical error flag
  !
  ! Constants
  character(len=*), parameter :: rname='PRIMARY'
  real(8), parameter :: pi=3.14159265358979323846d0
  integer, parameter :: o_trunc=1
  !
  ! Local ---
  integer :: ir,ix,iy
  real(8) :: ioffx, ioffy, dr, r, x, y
  real(4) :: factor
  !
  ! Code ----
  ioffx = offx/hsky%gil%inc(1)
  ioffy = offy/hsky%gil%inc(2)
  dr = profile(2,1) - profile(1,1) ! Increment
  !
  do iy=1,hsky%gil%dim(2)
    y = (iy-hsky%gil%ref(2)-ioffy)*hsky%gil%inc(2) + hsky%gil%val(2)
    do ix=1,hsky%gil%dim(1)
      x = (ix-hsky%gil%ref(1)-ioffx)*hsky%gil%inc(1) + hsky%gil%val(1)
      r = sqrt(x**2+y**2)
      !
      ! Locate by interpolation
      ir = int(r/dr)+1
      if (ir.lt.nr) then
        factor = ((profile(ir+1,1)-r)*profile(ir,2) + (r-profile(ir,1))*profile(ir+1,2) ) /dr
        dmap(ix,iy,:) = dsky(ix,iy,:) * factor
      else
        dmap(ix,iy,:) = 0.
      endif
    enddo
  enddo
  !
end subroutine apply_primary_single
!
subroutine self_uvmodel(line,huvl,error)
  use gildas_def
  use gbl_message
  use gkernel_interfaces
  use clean_arrays
  use imager_interfaces, except_this => self_uvmodel
  !---------------------------------------------------------------------
  ! @ private
  !*
  ! IMAGER --  Support routine for command  
  !     MODEL [MaxIter] [/MINVAL Value [Unit]] /MODE SELF CCT 
  !
  ! Compute the MODEL UV data set from the current CCT table
  ! for Self-Calibration
  !
  !     Uses an intermediate FFT with further interpolation for
  !     better speed than UV_CCT
  !!
  !---------------------------------------------------------------------
  character(len=*), intent(in) :: line      !! Command line
  type(gildas), intent(in) :: huvl          !! Input UV data
  logical, intent(inout) :: error           !! Error flag
  !
  ! Constants
  character(len=*), parameter :: rname='MODEL'
  real(kind=8), parameter :: pi=3.14159265358979323846d0
  integer, parameter :: o_minval=1 ! 
  integer, parameter :: o_output=2 ! Must be 2 ...
  integer, parameter :: o_mode=3   
  !
  ! Local ---
  integer :: nclean ! Number of clean components retained
  logical :: large
  real, allocatable :: dmap(:,:,:)
  integer :: nf,mx,my, ier
  real :: cpu0
  real(8) :: xinc, yinc, freq
  !
  ! Code ----
  nclean = 0
  call sic_i4(line,0,1,nclean,.false.,error)
  if (error) return
  large = sic_present(0,2) ! Test
  !
  if (.not.associated(huvl%r2d)) then
    call map_message(seve%e,rname,'Input UV pointer is not associated') 
    error = .true.
    return
  endif
  ! Code
  error = .false.
  call gag_cpu(cpu0)
  !
  ! Input data is passed as argument through HUVL and its data
  ! is defined by its HUVL%R2D pointer
  ! 
  ! This is in general HUV and DUV
  !
  ! Input CCT is the current CCT Data (it should match the UV data)
  !
  ! Compact it into an image
  ! This depends on the CCT type, and is done in a subroutine
  !    First, define the sampling and image size 
  !
  call cct_def_image (hcct,mx,my,nf,xinc,yinc,error)
  if (error) return
  !Print *,'XINC ',xinc,hsky%gil%inc(1)
  !Print *,'YINC ',yinc,hsky%gil%inc(2)
  !Print *,'CCT size ',mx,my
  !Print *,'SKY size ',hsky%gil%dim(1:2)
  !read(5,*) mx,my
  !
  if (nf.ne.1) then
    if (nf.ne.huvl%gil%nchan) then
      Print *,'CCT channels ',nf,'  UVDATA chanels ',huvl%gil%nchan
      call map_message(seve%w,rname,'Velocity axis mis-match')
      error = .true.
      return
    endif
  endif
  !
  !    Then do the job
  allocate (dmap(mx,my,nf),stat=ier)
  if (ier.ne.0) then
    call map_message(seve%e,rname,'MAP Allocation error')
    error = .true.
    return
  endif
  call cct_set_image (hcct,dcct,mx,my,nclean,xinc,yinc,nf,dmap,error)
  !
  !Print *,'--------------------------'
  !Print *,' Before map_fast_uvmodel '
  !Print *,' ' 
  ! call gdf_print_header(huvl)
  freq = gdf_uv_frequency(huvl)  
  call map_fast_uvmodel(huvl,huvl%r2d,huv_model,duvm,hsky,dmap,themap,freq,error)
end subroutine self_uvmodel


subroutine cct_new_uvmodel(line,huvl,error)
  use gildas_def
  use gbl_message
  use gkernel_interfaces
  use clean_arrays
  use imager_interfaces, except_this => cct_new_uvmodel
  !---------------------------------------------------------------------
  ! @ private
  !*
  ! IMAGER --  Support routine for command  
  !     MODEL [MaxIter] [/MINVAL Value [Unit]] [/MODE CCT [Frequency]]
  !
  ! Compute the MODEL UV data set from the current CCT table
  !
  !     Uses an intermediate FFT with further interpolation for
  !     better speed than UV_CCT
  !!
  !---------------------------------------------------------------------
  character(len=*), intent(inout) :: line   !! Command line
  type(gildas), intent(in) :: huvl          !! Input UV data
  logical, intent(inout) :: error           !! Error flag
  !
  ! Constants
  character(len=*), parameter :: rname='MODEL'
  real(kind=8), parameter :: pi=3.14159265358979323846d0
  integer, parameter :: o_minval=1 ! 
  integer, parameter :: o_output=2 ! Must be 2 ...
  integer, parameter :: o_mode=3   
  logical, parameter :: subtract=.false.
  ! Local ---
  integer :: nclean ! Number of clean components retained
  integer :: ier, iarg
  real :: cpu0
  logical :: do_clean, do_resi
  !
  ! Code ----
  nclean = 0
  call sic_i4(line,0,1,nclean,.false.,error)
  if (error) return
  !
  if (.not.associated(huvl%r2d)) then
    call map_message(seve%e,rname,'Input UV pointer is not associated') 
    error = .true.
    return
  endif
  ! Code
  error = .false.
  call gag_cpu(cpu0)
  !
  error = .false.
  if (themap%nfields.ne.0) then
    call map_message(seve%w,rname,'UV data is a Mosaic - UNDER TESTS !!!')
! Unclear - which mosaic is to be shited ???  Why does not depend on HUVL
!    call uv_shift_mosaic(line,rname,error)
!    if (error) return
  endif
  !
  call sic_delvariable('UV_MODEL',.false.,error)
  !
  if (allocated(duvm)) deallocate(duvm)
  call gildas_null(huv_model,type='UVT')
  call gdf_copy_header(huvl,huv_model,error)
  allocate (duvm(huv_model%gil%dim(1),huv_model%gil%dim(2)),stat=ier)
  if (ier.ne.0) then
    call map_message(seve%e,rname,'UV Model allocation error')
!    call gdf_copy_header(htmp,huvl,error)  ! Save SG  Why ?
    error = .true.
    return
  endif
  !
  ! Do the job. 
  do_clean = .false. 
  do_resi = .true.
  !
  ! Buffer choice will depend on the MODEL option
  Print *,'HUVL ',associated(huvl%r2d)
  Print *,'DUVM ',allocated(duvm) 
  Print *,'Calling SUB_UV_RESIDUAL with HUV_MODEL and DUVM'
  call sub_uv_residual(rname,line,iarg,huv_model,huvl%r2d,duvm, &
    &   do_clean,do_resi,subtract,error)
  huv_model%r2d => duvm
end subroutine cct_new_uvmodel
