subroutine uv_resample_comm(line,comm,error)
  use gbl_message
  use gkernel_types
  use gkernel_interfaces
  use imager_interfaces, except_this=>uv_resample_comm
  !---------------------------------------------------------------------
  ! @ private
  !
  ! IMAGER
  !   Resample in velocity UV Tables or compress them
  !   Support for commands
  !     UV_RESAMPLE NC [Ref Val Inc] [/FILE FileIn FileOut] [/LIKE Mold]
  !     UV_COMPRESS NC [/CONTINUUM] [/FILE FileIn FileOut] 
  !     UV_HANNING     [/FILE FileIn FileOut]
  !     UV_SMOOTH   NC [/ASYMMETRIC] [/FILE FileIn FileOut] 
  !---------------------------------------------------------------------
  character(len=*), intent(in) :: line  ! Command line
  character(len=*), intent(in) :: comm  ! Calling command
  logical, intent(out) :: error         ! Error flag
  !
  integer, parameter :: o_asym=1
  integer :: o_file
  !
  logical :: asym
  character(len=filename_length) :: in_file, ou_file
  character(len=120) :: mess
  integer :: n
  type(gildas) :: hiuv, houv
  integer :: nblock
  integer :: nu, nv, ni, nt, nchan, nc, ier
  integer(kind=index_length)  :: ib           ! Blocked visibility counter
  integer(kind=index_length)  :: mvisi        ! Number of blocked visibilities
  integer(kind=index_length)  :: nvisi        ! Number of visibilities
  !
  ! Option numbering depends on Command name
  if ((comm.eq.'UV_COMPRESS').or.(comm.eq.'UV_SMOOTH')) then
    o_file = 2
  else
    o_file = 1
  endif
  !
  if (.not.sic_present(o_file,0)) then
    call uv_resample_mem(line,comm,error)
  else
    !
    call sic_ch(line,o_file,1,in_file,n,.true.,error)
    if (error) return
    call sic_ch(line,o_file,2,ou_file,n,.true.,error)
    if (error) return
    !
    call gildas_null(hiuv,type='UVT')
    call gildas_null(houv,type='UVT')
    !
    call sic_parse_file(in_file,' ','.uvt',hiuv%file)
    call gdf_read_header(hiuv,error)
    if (error) return
    !
    call gdf_copy_header(hiuv,houv,error)
    !!Print *,'Input ',hiuv%gil%dim(1:2), hiuv%gil%ntrail
    call sic_parse_file(ou_file,' ','.uvt',houv%file)
    !
    call uv_resample_args(line,comm,hiuv,houv,error)
    if (error) return
    call gdf_create_image(houv,error)
    if (error) return
    !
    asym = sic_present(o_asym,0)
    !
    ! Set the Blocking Factor
    nblock = space_nitems('SPACE_IMAGER',hiuv,1)
    mvisi = nblock
    !
    allocate(hiuv%r2d(hiuv%gil%dim(1),mvisi),houv%r2d(houv%gil%dim(1),mvisi),stat=ier)
    if (ier.ne.0) then
      call map_message(seve%e,comm,'Memory allocation error')
      error = .true.
      return
    endif
    !
    !! Print *,'Trailings ',hiuv%gil%ntrail, houv%gil%ntrail
    !
    do ib=1,hiuv%gil%dim(2),mvisi
      !
      ! Read the data
      write(mess,*) ib,' / ',hiuv%gil%dim(2),mvisi
      call map_message(seve%i,comm,mess)
      hiuv%blc(2) = ib
      hiuv%trc(2) = min(hiuv%gil%dim(2),ib-1+mvisi)
      nvisi = hiuv%trc(2)-hiuv%blc(2)+1
      call gdf_read_data(hiuv,hiuv%r2d,error)
      if (error) return
      !
      ni = hiuv%gil%dim(1)
      nu = houv%gil%dim(1)
      nv = nvisi  ! Not houv%gil%dim(2)
      nt = houv%gil%ntrail
      nc = nint(real(hiuv%gil%nchan)/real(houv%gil%nchan))  ! Compression factor
      nchan = houv%gil%nchan
      !
      ! Now resample
      if (comm.eq.'UV_RESAMPLE') then
        call resample_uv (hiuv,houv,hiuv%r2d,houv%r2d,nvisi,nt)
      else if (comm.eq.'UV_COMPRESS') then
        call compress_uv (houv%r2d,nu,nv,nchan,hiuv%r2d,ni,nc,nt) 
      else if (comm.eq.'UV_HANNING') then
        call hanning_uv (houv%r2d,nu,nvisi,nchan,hiuv%r2d,ni,nt)
      else if (comm.eq.'UV_SMOOTH') then
        call smooth_uv (houv%r2d,nu,nvisi,nchan,hiuv%r2d,nc,nt,asym)
      endif
      !
      ! Check channel boundaries, to flag the incomplete ones
      call uvflag_edges(hiuv,houv,nu,nv,houv%r2d)
      !
      ! Write in place
      houv%blc = hiuv%blc
      houv%trc = hiuv%trc
      call gdf_write_data (houv,houv%r2d,error)
      if (error) return
    enddo
    !
    deallocate(hiuv%r2d,houv%r2d)  
    call gdf_close_image(hiuv,error)
    call gdf_close_image(houv,error)
    if (error) return
    !
    call map_message(seve%i,comm,'Created '//trim(houv%file))
    !        
  endif
end subroutine uv_resample_comm
!
subroutine uv_resample_args(line,comm,hiuv,houv,error)
  use gkernel_types
  use gkernel_interfaces
  use gbl_message
  use clean_def
  use clean_default
  use clean_types
  use imager_interfaces, except_this=>uv_resample_args
  !---------------------------------------------------------------------
  ! @ private
  !
  ! IMAGER
  !   Resample in velocity UV Tables or compress them
  !   Support for commands
  !     UV_RESAMPLE NC [Ref Val Inc] [/FILE FileIn FileOut] [/LIKE Mold]
  !     UV_COMPRESS [NC] [/CONTINUUM] [/FILE FileIn FileOut] 
  !     UV_HANNING     [/FILE FileIn FileOut]
  !     UV_SMOOTH   NC [/ASYMMETRIC] [/FILE FileIn FileOut]
  !
  !   Decode the arguments and fill the output header accordingly
  !---------------------------------------------------------------------
  character(len=*), intent(in) :: line  ! Command line
  character(len=*), intent(in) :: comm  ! Calling command
  logical, intent(out) :: error         ! Error flag
  type(gildas), intent(inout) :: hiuv
  type(gildas), intent(inout) :: houv
  !
  integer, parameter :: o_cont_comp=2
  integer, parameter :: o_cont_file=1
  integer, parameter :: o_like=2
  integer, parameter :: o_asym=1
  !
  type(gildas) :: hmold
  character(len=4) :: arg(4)
  real(8) :: convert(3), velo
  real(8) :: freqs
  real(4) :: velos
  integer :: nc, na, i
  logical :: do_mod
  character(len=128) :: mess
  character(len=filename_length) :: moldfile
  !
  if (hiuv%gil%nstokes.gt.1) then
    call map_message(seve%e,comm,'Only single polarization data supported')
    error = .true.
    return
  endif
  !
  select case (comm)
  case ('UV_RESAMPLE')
    nc = 0
    !
    if (sic_present(o_like,0)) then
      call gdf_copy_header(hiuv,houv,error)
      !
      call sic_ch(line,o_like,1,moldfile,nc,.true.,error)
      if (error) return
      call gildas_null(hmold,'UVT')
      call sic_parse_file(moldfile,' ','.uvt',hmold%file)
      call gdf_read_header(hmold,error)
      if (error) then
        call map_message(seve%e,comm,'Cannot open '//trim(hmold%file))
        return
      endif
      !
      ! Check that the Reference Frequencies and Velocities are the same also...
      ! use the MODIFY method if needed to guarantee this is the case
      do_mod = .false.
      if (hmold%gil%freq .ne. houv%gil%freq) then
        write(mess,*) 'Different Frequencies Mold:',hmold%gil%freq,', Data: ',houv%gil%freq
        call map_message(seve%i,comm,mess)
      endif
      freqs = houv%gil%freq
      if (hmold%gil%voff .ne. houv%gil%voff) then
        write(mess,*) 'Different Velocities Mold:',hmold%gil%voff,', Data: ',houv%gil%voff
        call map_message(seve%w,comm,mess)
        do_mod = .true.
      endif
      velos = hmold%gil%voff  ! Will be done by the resampling
      if (do_mod) then
        call gdf_modify(houv,velos,freqs,error=error)
        if (error) return
      endif
      !
      nc = hmold%gil%nchan
      convert(1) = hmold%gil%ref(1)
      convert(2) = hmold%gil%voff
      convert(3) = hmold%gil%vres
    else
      !    SIC__CH would complain if argument is too long, SIC_KE is silent
      call sic_ke(line,0,1,arg(1),na,.true.,error)
      error = .false.
      if (arg(1).ne.'*') call sic_i4(line,0,1,nc,.true.,error)
      if (error) return
      !
      ! Set default resampling in Velocity
      convert(1) = hiuv%gil%ref(1)
      convert(2) = hiuv%gil%voff
      convert(3) = hiuv%gil%vres
      ! Get new one
      do i=2,sic_narg(0)
        call sic_ke(line,0,i,arg(i),na,.false.,error)
        error = .false.
        if (arg(i).ne.'*') call sic_r8(line,0,i,convert(i-1),.false.,error)
        if (error) return
      enddo
      !
      ! Fill missing arguments
      if (nc.eq.0) then
        nc = nint(abs(hiuv%gil%nchan*hiuv%gil%vres/convert(3)))
        if (arg(2).eq.'*') then
          ! Keep the middle channel in the middle
          velo = (0.5d0*hiuv%gil%nchan-hiuv%gil%ref(1))*hiuv%gil%vres + hiuv%gil%voff
          convert(1) = 0.5d0*nc - (velo-convert(2))/convert(3)
        endif
      endif
    endif
    !
    ! NC Ref Val Inc
    write(mess,'(A,I0,X,3(F12.3))') 'Resampling to ',nc,convert(1:3)
    call map_message(seve%i,comm,mess)
    !
    ! First shift the Reference Velocity Frame to the new sampling
    freqs = houv%gil%freq
    velos = convert(2)
    call gdf_modify(houv,velos,freqs,error=error)
    !
    ! Then get the proper conversion formula
    call getuv_conversion(houv,nc,convert)
    !
  case ('UV_COMPRESS') 
    call sub_cont_average(line,comm,hiuv,houv,nc,error)
    if (error) return
  case ('UV_HANNING')
    ! Drop the edge channels
    houv%gil%ref(1) = houv%gil%ref(1)-1 ! -1, not +1 
    houv%gil%nchan = houv%gil%nchan-2
  case ('UV_SMOOTH') 
    call sic_i4(line,0,1,nc,.true.,error)
    if (error) return
    if (sic_present(o_asym,0)) then
    ! Shift the reference pixel if NC is even ?
      if (mod(nc,2).eq.0) houv%gil%ref(1) = houv%gil%ref(1)+0.5
    endif
  case default
    call map_message(seve%e,comm,'Unrecognized choice '//comm)
    error = .true.
    return
  end select
  !
  ! Work with complete structure
  houv%gil%dim(1) = 3*houv%gil%nchan + 7 + houv%gil%ntrail ! and nothing more ...
  if (houv%gil%ntrail.ne.0) then
    do i=1,code_uvt_last
      if (houv%gil%column_pointer(i).gt.houv%gil%lcol)  &
        houv%gil%column_pointer(i) =  houv%gil%column_pointer(i) + houv%gil%dim(1) - hiuv%gil%dim(1)
    enddo
  endif
end subroutine uv_resample_args
!
subroutine uv_resample_mem(line,comm,error)
  use gkernel_interfaces
  use imager_interfaces, except_this=>uv_resample_mem
  use gkernel_types
  use clean_def
  use clean_beams
  use clean_arrays
  use clean_types
  use gbl_message
  !---------------------------------------------------------------------
  ! @ private
  !
  ! IMAGER
  !   Resample in velocity the UV Table or compress it
  !   Support for commands
  !     UV_RESAMPLE NC [Ref Val Inc] 
  !     UV_COMPRESS [NC] [/CONTINUUM]
  !     UV_HANNING 
  !     UV_SMOOTH NC    
  !---------------------------------------------------------------------
  character(len=*), intent(in) :: line  ! Command line
  character(len=*), intent(in) :: comm  ! Calling command
  logical, intent(out) :: error         ! Error flag
  !
  integer, parameter :: o_cont_comp=1
  integer, parameter :: o_like=2
  integer, parameter :: o_asym=1
  !
  type(sic_descriptor_t) :: desc
  real, pointer :: duv_previous(:,:), duv_next(:,:)
  character(len=4) :: arg(4)
  character(len=128) :: mess
  real(8) :: convert(3), velo
  integer :: nt, nc, nv, nchan, na, narg
  type (gildas) :: uvout
  integer :: nu, ni, i
  logical :: err, found, asym
  integer(kind=index_length)  :: nvisi        ! Number of visibilities
  !
  ! Code
  if (huv%loca%size.eq.0) then
    call map_message(seve%e,comm,'No UV data loaded')
    error = .true.
    return
  endif
  if (huv%gil%nstokes.gt.1) then
    call map_message(seve%e,comm,'Only single polarization data supported')
    error = .true.
    return
  endif
  !
  ! Channel range is no longer meaningful
  nbeam_ranges = -1
  call sic_delvariable ('BEAM_RANGES',.false.,error)
  !
  error = .false.
  ! No argument: get back to the original UV data
  narg = sic_narg(0)
  if (narg.eq.0) then
    if (comm.eq.'UV_HANNING') then
      continue
    else if (comm.eq.'UV_COMPRESS'.and.sic_present(o_cont_comp,0)) then
      continue
    else if (comm.eq.'UV_RESAMPLE'.and.sic_present(o_like,0)) then
      call map_message(seve%e,comm,'/LIKE option not yet implemented in this context')
      error = .true.
      return
    else
      call sic_delvariable('UV',.false.,error)
      call uv_reset_buffer(comm)
      call map_uvgildas('UV',huv,error,duv)
      do_weig = .true.
      return
    endif
  endif
  !
  ! Compute the Frequency Conversion from the Velocity Conversion
  call gildas_null(uvout, type = 'UVT')
  call gdf_copy_header(huv,uvout,error)
  !
  if (comm.eq.'UV_RESAMPLE') then
    nc = 0
    !    SIC__CH would complain if argument is too long, SIC_KE is silent
    call sic_ke(line,0,1,arg(1),na,.true.,error)
    error = .false.
    if (arg(1).ne.'*') call sic_i4(line,0,1,nc,.true.,error)
    if (error) return
    !
    ! Set default resampling in Velocity
    convert(1) = huv%gil%ref(1)
    convert(2) = huv%gil%voff
    convert(3) = huv%gil%vres
    ! Get new one
    do i=2,sic_narg(0)
      call sic_ke(line,0,i,arg(i),na,.false.,error)
      error = .false.
      if (arg(i).ne.'*') call sic_r8(line,0,i,convert(i-1),.false.,error)
      if (error) return
    enddo
    !
    ! Fill missing arguments
    if (nc.eq.0) then
      nc = nint(abs(huv%gil%nchan*huv%gil%vres/convert(3)))
      if (arg(2).eq.'*') then
        ! Keep the middle channel in the middle
        velo = (0.5d0*huv%gil%nchan-huv%gil%ref(1))*huv%gil%vres + huv%gil%voff
        convert(1) = 0.5d0*nc - (velo-convert(2))/convert(3)
      endif
    endif
    !
    call getuv_conversion(uvout,nc,convert)
    !
    ! NC Ref Val Inc
    write(mess,'(A,I0,X,3(F12.3))') 'Resampling to ',nc,convert(1:3)
    call map_message(seve%i,comm,mess) 
    !
  else if (comm.eq.'UV_COMPRESS') then
    huv%r2d => duv
    call sub_cont_average(line,comm,huv,uvout,nc,error)
    if (error) return
  else if (comm.eq.'UV_HANNING') then
    ! Drop the edge channels
    uvout%gil%ref(1) = uvout%gil%ref(1)-1
    uvout%gil%nchan = uvout%gil%nchan-2
    continue
  else if (comm.eq.'UV_SMOOTH') then
    call sic_i4(line,0,1,nc,.true.,error)
    if (error) return
    huv%r2d => duv
    asym = sic_present(o_asym,0)
    if (asym) then
      ! Shift the reference pixel if NC is even 
      if (mod(nc,2).eq.0) uvout%gil%ref(1) = uvout%gil%ref(1)+0.5
    endif
  else
    call map_message(seve%e,comm,'Unrecognized choice '//comm)
    error = .true.
    return
  endif
  !
  ! Work with complete structure
  uvout%gil%dim(1) = 3*uvout%gil%nchan + 7 + uvout%gil%ntrail ! and nothing more ...
  if (uvout%gil%ntrail.ne.0) then
    do i=1,code_uvt_last
      if (uvout%gil%column_pointer(i).gt.uvout%gil%lcol) uvout%gil%column_pointer(i) =  &
        & uvout%gil%column_pointer(i) + uvout%gil%dim(1) - huv%gil%dim(1)
    enddo
  endif
  !
  ni = huv%gil%dim(1)
  nu = uvout%gil%dim(1)
  nv = uvout%gil%dim(2)
  nvisi = uvout%gil%nvisi
  nt = uvout%gil%ntrail
  nchan = uvout%gil%nchan
  !
  ! Prepare appropriate array...
  nullify (duv_previous, duv_next)
  call uv_find_buffers (comm,nu,nv,duv_previous, duv_next,error)
  if (error) then
    call map_message(seve%e,comm,'Cannot set buffer pointers')
    return
  endif
  !
  ! Now resample
  if (comm.eq.'UV_RESAMPLE') then
    nvisi = huv%gil%nvisi
    call resample_uv (huv,uvout,duv_previous,duv_next,nvisi,nt)
  else if (comm.eq.'UV_COMPRESS') then
    call compress_uv (duv_next,nu,nv,nchan,duv_previous,ni,nc,nt)
  else if (comm.eq.'UV_HANNING') then
    call hanning_uv (duv_next,nu,nvisi,nchan,duv_previous,ni,nt)
  else if (comm.eq.'UV_SMOOTH') then
    call smooth_uv (duv_next,nu,nvisi,nchan,duv_previous,nc,nt,asym)
  endif
  !
  ! Check channel boundaries, to flag the incomplete ones
  call uvflag_edges(huv,uvout,nu,nv,duv_next)
  !
  ! Set header back
  call gdf_copy_header(uvout,huv,error)
  !
  ! Reset proper pointers
  call uv_clean_buffers (duv_previous, duv_next,error)
  if (error) return
  !
  ! Indicate UV data has changed, and weight must be computed
  !
  ! Delete variables that may have been affected
  err = .false.
  call sic_descriptor('UVS',desc,found)  
  if (found) call sic_delvariable('UVS',.false.,err)
  call uv_new_data(weight=.true.)
end subroutine uv_resample_mem
!
subroutine hanning_uv (duvout, nu, nv, nchan, duvin, ni, ntrail) 
  use gildas_def
  !---------------------------------------------------------------------
  ! @ private
  !
  ! IMAGER
  !   Support for command
  !     UV_HANNING     
  !   This is equivalent to UV_SMOOTH 2
  !---------------------------------------------------------------------
  integer, intent(in) :: nu           ! Ouput Visibility size
  integer(kind=index_length), intent(in) :: nv           ! Number of visibilities
  integer, intent(in) :: nchan        ! Number of ouput channels
  integer, intent(in) :: ntrail       ! Trailing columns
  integer, intent(in) :: ni           ! Input Visibility size
  real, intent(in) :: duvin(ni,nv)    ! Input visibilities
  real, intent(out) :: duvout(nu,nv)  ! Output visibilities
  ! Local
  integer :: nlead
  integer :: i,j,k,kk
  real :: a,b,c,w(3),r
  data w/0.5,1.0,0.5/
  !
  nlead = 7
  !
  duvout = 0
  !
  do j=1,nv
    duvout (1:nlead,j) =  duvin (1:nlead,j)  
    do i=1,nchan
      a = 0
      b = 0
      c = 0
      do k=1,3
        kk = nlead+3*(i+k-1)  ! i=1, k=1, ==> kk=10
        if (duvin(kk,j).ne.0) then
          r = duvin(kk,j)*w(k)
          a = a+duvin(kk-2,j)*r
          b = b+duvin(kk-1,j)*r
          c = c+r
        endif
      enddo
      kk = nlead+3*i-2  ! i=1 ==> kk=8
      if (c.ne.0) then
        duvout(kk,j) = a/c
        duvout(kk+1,j) = b/c
        duvout(kk+2,j) = c         ! time*band
      else
        duvout(kk,j) = 0
        duvout(kk+1,j) = 0
        duvout(kk+2,j) = 0
      endif
    enddo
    if (ntrail.gt.0) then
      duvout(nu-ntrail+1:nu,j) = duvin(ni-ntrail+1:ni,j)
    endif
  enddo
end subroutine hanning_uv
!
subroutine smooth_uv (duvout, nu, nv, nchan, duvin, mc, ntrail, asym) 
  use gildas_def
  !---------------------------------------------------------------------
  ! @ private
  !
  ! IMAGER
  !   Support for command
  !     UV_SMOOTH  Nc [/ASYMMETRIC]
  !---------------------------------------------------------------------
  integer, intent(in) :: nu           ! Ouput Visibility size
  integer(kind=index_length), intent(in) :: nv  ! Number of visibilities
  integer, intent(in) :: nchan        ! Number of channels
  integer, intent(in) :: ntrail       ! Trailing columns
  integer, intent(in) :: mc           ! Smoothing factor
  real, intent(in) :: duvin(nu,nv)    ! Input visibilities
  real, intent(out) :: duvout(nu,nv)  ! Output visibilities
  logical, intent(in) :: asym         ! Asymmetric smoothing ?
  ! Local
  integer :: nlead, nc
  integer :: i,j,k,kk
  integer :: ic,jm,jp,kc,lc
  integer, allocatable :: im(:),ip(:)
  real :: a,b,c,r
  logical :: odd
  !
  nlead = 7
  !
  kc = mc
  nc = kc/2
  odd = mod(kc,2).ne.0 
  kc = 2*nc+1
  allocate(im(nchan),ip(nchan))
  !
  ! Define method 
  do ic=1,nchan
    if (asym) then
      lc = (mc-1)/2
      jm = max(1,ic-lc)
      jp = min(nchan,ic+mc-lc-1)
    else
      ! We must ensure that the smoothing is symmetric, as we want to preserve the
      ! spectral sampling of the initial data.
      !
      ! This is a symmetric smoothing, but limited at edges by available data.
      jm = ic-nc
      jp = ic+kc-nc-1
      if (jm.lt.1) then
        lc = ic-1
        jm = 1
        jp = ic+lc
      else if (jp.gt.nchan) then
        lc = nchan-ic
        jm = ic-lc
        jp = ic+lc
      endif
    endif
    !
    im(ic) = jm
    ip(ic) = jp
  enddo
  !
  duvout = 0
  !
  ! Compress each visibility
  do j=1,nv
    duvout (1:nlead,j) =  duvin (1:nlead,j)  
    do ic=1,nchan
      a = 0
      b = 0
      c = 0
      if (asym.or.odd) then
        do k=im(ic),ip(ic)
          kk = nlead+3*k  ! k=1, ==> kk=10
          if (duvin(kk,j).gt.0) then
            r = duvin(kk,j)
            a = a+duvin(kk-2,j)*r
            b = b+duvin(kk-1,j)*r
            c = c+r
          endif
        enddo
      else
        do k=im(ic),ip(ic)
          kk = nlead+3*k  ! k=1, ==> kk=10
          if (duvin(kk,j).gt.0) then
            r = duvin(kk,j)
            if ((k.eq.im(ic)).or.(k.eq.ip(ic))) r = r/2
            a = a+duvin(kk-2,j)*r
            b = b+duvin(kk-1,j)*r
            c = c+r
          endif
        enddo
      endif
      !
      kk = nlead+3*ic-2  ! i=1 ==> kk=8
      if (c.ne.0) then
        duvout(kk,j) = a/c
        duvout(kk+1,j) = b/c
        duvout(kk+2,j) = c         ! time*band
      else
        duvout(kk,j) = 0
        duvout(kk+1,j) = 0
        duvout(kk+2,j) = 0
      endif
    enddo
    if (ntrail.gt.0) then
      duvout(nu-ntrail+1:nu,j) = duvin(nu-ntrail+1:nu,j)
    endif
  enddo
end subroutine smooth_uv
!
subroutine sub_cont_average(line,comm,hiuv,houv,nc,error)
  use image_def
  use clean_default
  use gbl_message
  use gkernel_interfaces
  use imager_interfaces, except_this => sub_cont_average
  !---------------------------------------------------------------------
  ! @ private
  !   
  ! IMAGER
  !   Support for command
  !     UV_COMPRESS [NC] [/CONTINUUM]  
  ! Derive the compression factor NC and set the output Header
  ! properly
  !---------------------------------------------------------------------
  character(len=*), intent(in) :: line  ! Command line
  character(len=*), intent(in) :: comm  ! Command name
  type(gildas), intent(inout) :: hiuv   ! Original UV data
  type(gildas), intent(inout) :: houv   ! Resampled UV data header
  integer, intent(out) :: nc            ! Compression factor
  logical, intent(out) :: error
  !
  real(kind=8), parameter :: pi=3.14159265358979323846d0
  real(kind=8), parameter :: f_to_k = 2.d0*pi/299792458.d-6
  !
  character(len=80) :: mess
  real :: uvmax, uvmin
  integer :: msize, narg
  type (uvmap_par) :: map
  real(8) :: freq
  !  
  error = .false.
  narg = sic_narg(0)
  if (narg.gt.0) then
    call sic_i4(line,0,1,nc,.true.,error)
    if (error) return
  else
    msize = maxval(default_map%size)
    if (msize.eq.0) then
      map = default_map
      freq = gdf_uv_frequency(hiuv)
      call uvgmax (hiuv,hiuv%r2d,uvmax,uvmin)
      ! Now transform UVMAX in kiloWavelength (including 2 pi factor)
      uvmax = uvmax*freq*f_to_k
      uvmin = uvmin*freq*f_to_k
      error = .false.
      call map_parameters(comm,map,hiuv,freq,uvmax,uvmin,error)
      if (error) return
      msize = maxval(map%size)
    endif
    nc = 0
    call t_channel_sampling (comm,hiuv,nc,msize)  
  endif
  !
  if (nc.lt.1) then
    write(mess,'(A,I6,A)') 'Invalid Averaging number ',nc
    call map_message(seve%e,comm,mess)
    error = .true.
    return
  endif
  if (nc.gt.hiuv%gil%nchan) nc = hiuv%gil%nchan
  write(mess,'(A,I6,A)') 'Averaging by chunks of ',nc,' channels'
  call map_message(seve%i,comm,mess)
  !
  ! Set header
  houv%gil%inc(1) = houv%gil%inc(1)*nc
  houv%gil%ref(1) = (2.0d0*houv%gil%ref(1)+nc-1.0)/(2*nc)
  houv%gil%vres = nc*houv%gil%vres
  houv%gil%fres = nc*houv%gil%fres
  ! Change the number of channels
  houv%gil%nchan = houv%gil%nchan/nc
  if (narg.gt.0) return
  !
  ! Round up in case of /CONTINUUM option, to avoid losing sensitivity
  if (houv%gil%nchan*nc.ne.hiuv%gil%nchan) houv%gil%nchan = houv%gil%nchan+1
end subroutine sub_cont_average
!
subroutine uvflag_edges(huvin, huvout, nu, nv, duv)  
  use image_def
  !---------------------------------------------------------------------
  ! @ private
  !
  ! IMAGER
  !   Support routine for UV Resampling: flag edge channels if not
  !   fully covered in the operation
  !---------------------------------------------------------------------
  type(gildas), intent(in) :: huvin
  type(gildas), intent(in) :: huvout
  integer, intent(in) :: nu, nv
  real, intent(inout) :: duv(nu,nv) 
  !
  integer :: ic,jc,imin,imax
  real :: vmin, vmax
  !
  if (huvin%gil%vres.gt.0) then
    vmin = (0.5-huvin%gil%ref(1))*huvin%gil%vres + huvin%gil%voff
    vmax = (huvin%gil%nchan-0.5-huvin%gil%ref(1))*huvin%gil%vres + huvin%gil%voff
  else
    vmin = (huvin%gil%nchan-0.5-huvin%gil%ref(1))*huvin%gil%vres + huvin%gil%voff
    vmax = (0.5-huvin%gil%ref(1))*huvin%gil%vres + huvin%gil%voff
  endif
  !
  if (huvout%gil%vres.gt.0) then
    imin = (vmin-huvout%gil%voff)/huvout%gil%vres + huvout%gil%ref(1)
    imax = (vmax-huvout%gil%voff)/huvout%gil%vres + huvout%gil%ref(1)
  else
    imin = (vmax-huvout%gil%voff)/huvout%gil%vres + huvout%gil%ref(1)
    imax = (vmin-huvout%gil%voff)/huvout%gil%vres + huvout%gil%ref(1)
  endif
  !
  if (imin.gt.0) then
    do ic=1,imin
      jc = 7+3*ic
      duv(jc,:) = 0.
    enddo
  endif
  if (imax.lt.huvout%gil%nchan) then
    do ic=imax,huvout%gil%nchan
      jc = 7+3*ic
      duv(jc,:) = 0.
    enddo
  endif
end subroutine uvflag_edges
