!
subroutine getuv_conversion(uvout,nc,convert)
  use gildas_def
  use image_def
  use phys_const
  !---------------------------------------------------------------------
  ! @ public
  !*
  ! IMAGER -- Utility routine for Velocity resampling
  !
  !   Derive the frequency axis corresponding to a specified
  !   Velocity sampling.
  !!
  !---------------------------------------------------------------------
  type (gildas), intent(inout) :: uvout   !! Output UV table header
  integer, intent(in) :: nc               !! Number of desired channels
  real(8), intent(inout) :: convert(3)    !! Velocity conversion formula
  !
  ! Local ---
  real(8) :: n_iref
  !
  ! Convert(3) is initially on a Velocity Scale.
  ! Code ----
  !
  ! Compute the Reference pixel at which VOFF will occur
  ! in this new sampling, to preserve the VOFF / FREQ / IREF 
  ! correspondance
  !      voff = (n_iref - convert(1))*convert(3) + convert(2)
  n_iref = (uvout%gil%voff - convert(2)) / convert(3) + convert(1)
  !
  convert(1) = n_iref
  convert(2) = uvout%gil%voff
  uvout%gil%vres = convert(3)
  uvout%gil%fres = - uvout%gil%vres * 1d3 / clight * uvout%gil%freq
  uvout%gil%ref(1) = convert(1)
  uvout%gil%val(1) = uvout%gil%freq  ! This is already the case
  uvout%gil%inc(1) = uvout%gil%fres  
  uvout%gil%nchan = nc
  !
  uvout%gil%nchan = nc
  uvout%gil%dim(1) = uvout%gil%nlead+uvout%gil%ntrail + uvout%gil%natom*nc
end subroutine getuv_conversion
!
subroutine resample_uv (uvint,uvout,uvint_data,uvout_data,nv,nt,filtered)
  use image_def
  !------------------------------------------------------------------------
  ! @ public
  !*
  ! IMAGER --   Support for commands UV_RESAMPLE and UV_MERGE
  !
  !   Resample (in memory) a UV data set
  !------------------------------------------------------------------------
  type (gildas), intent(in) :: uvint  !! Input UV header
  type (gildas), intent(in) :: uvout  !! Output UV header
  real(4), intent(in) :: uvint_data(uvint%gil%dim(1),uvint%gil%dim(2))
  real(4), intent(out) :: uvout_data(uvout%gil%dim(1),uvout%gil%dim(2))
  integer(kind=index_length), intent(in) :: nv  !! Actual number of visibilities
  integer, intent(in) :: nt           !! Number of trailing informations
  integer, intent(in), optional :: filtered(:)  !! Filtered channels
  !
  ! Local
  integer(kind=index_length) :: iv
  real(4), allocatable :: uvtmp(:)
  integer :: nin, nou, k, kk
  real(8) :: xref,xval,xinc
  real(8) :: yref,yval,yinc
  logical :: ok
  !
  xref = uvout%gil%ref(1)
  yref = uvint%gil%ref(1)
  xval =   uvout%gil%voff
  xinc =   uvout%gil%vres
  yval =   uvint%gil%voff
  yinc =   uvint%gil%vres
  !
  nou = uvout%gil%dim(1)
  nin = uvint%gil%dim(1)
  !
  ok = .false. !TEST! present(filtered)
  if (ok) then
    Print *,'Filtered ',filtered
    allocate(uvtmp(uvint%gil%dim(1)))
    !$OMP PARALLEL &
    !$OMP    & SHARED(uvout_data,uvint_data, uvout, uvint, filtered) &
    !$OMP    & SHARED(xinc,xref,xval, yinc,yref,yval, nv,nt,nou,nin) & 
    !$OMP    & PRIVATE(iv, uvtmp, k, kk)
    !$OMP DO SCHEDULE(STATIC)
    do iv = 1,nv  						  
      uvtmp(:) = uvint_data(:,iv)
      uvout_data(1:7,iv) = uvtmp(1:7)
      do k=1,uvint%gil%nchan
        kk = 7+3*k
        uvtmp(kk) = filtered(k)*uvtmp(kk)
      enddo
      call interpolate_uv (uvout_data(8:,iv), uvout%gil%nchan, xinc,xref,xval, &
          uvtmp(8:),uvint%gil%nchan,yinc,yref,yval)
      if (nt.ne.0) then
        uvout_data(nou-nt+1:nou,iv) = uvtmp(nin-nt+1:nin)
      endif
    enddo
    !$OMP END DO
    !$OMP END PARALLEL
  else
    !$OMP PARALLEL &
    !$OMP    & SHARED(uvout_data,uvint_data, uvout, uvint) &
    !$OMP    & SHARED(xinc,xref,xval, yinc,yref,yval, nv,nt,nou,nin) & 
    !$OMP    & PRIVATE(iv)
    !$OMP DO SCHEDULE(STATIC)
    do iv = 1,nv  						  
      uvout_data(1:7,iv) = uvint_data(1:7,iv)
      call interpolate_uv (uvout_data(8:,iv), uvout%gil%nchan, xinc,xref,xval, &
          uvint_data(8:,iv),uvint%gil%nchan,yinc,yref,yval)
      if (nt.ne.0) then
        uvout_data(nou-nt+1:nou,iv) = uvint_data(nin-nt+1:nin,iv)
      endif
    enddo
    !$OMP END DO
    !$OMP END PARALLEL
  endif
end subroutine resample_uv
!
subroutine interpolate_uv(x,xdim,xinc,xref,xval, y,ydim,yinc,yref,yval)
  !-----------------------------------------------------------------------
  ! @ no-interface
  !*
  ! IMAGER   Support for UV_RESAMPLE and UV_MERGE
  !
  ! Performs the linear interpolation/integration for visibilities
  !
  ! 1) if actual interpolation (XINC <= YINC)  
  !     this is a 2-point linear interpolation formula.
  !     the data is untouched if the resolution is unchanged and the shift
  !     is an integer number of channels.
  !
  ! 2) if not (XINC > YINC)  
  !     boxcar convolution (width xinc-yinc) followed by linear interpolation
  !!
  !-----------------------------------------------------------------------------
  integer, intent(in) :: ydim             !! Input axis size
  integer, intent(in) :: xdim             !! Output axis size
  real(8), intent(in) :: yref,yval,yinc   !! Input conversion formula
  real(8), intent(in) :: xref,xval,xinc   !! Output conversion formula
  real(4), intent(in) :: y(3,xdim)        !! Input values
  real(4), intent(out) :: x(3,ydim)       !! Output values
  !
  ! Local ---
  integer :: i,imax,imin, j
  real(8) :: pix, val, expand
  real(4) :: scale, ww
  !
  ! Code ----
  expand = abs(xinc/yinc)
  do i = 1, xdim
    !
    ! Compute interval
    val = xval + (i-xref)*xinc
    pix = (val-yval)/yinc + yref
    if (expand.gt.1.) then
      imin = int(pix-expand/2d0+0.5d0)
      imax = int(pix+expand/2d0+0.5d0)
      if (imin.gt.ydim .or. imax.lt.1) cycle
      if (imin.lt.1) then
        imin = 1
        ww = 1.0  ! the whole channel is in...
      else
        ww = imin-(pix-expand/2d0-0.5d0)
      endif
      x(1:3,i) = y(1:3,imin)*ww
      scale = ww
      !
      if (imax.gt.ydim) then
        imax = ydim
        ww = 1.0
      else
        ww = pix+expand/2d0+0.5d0-imax
      endif
      x(1:3,i) = x(1:3,i) + y(1:3,imax)*ww
      scale = scale + ww
      !
      do j=imin+1, imax-1
        x(1:3,i) = x(1:3,i) + y(1:3,j)
        scale = scale+1.
      enddo
      ! Normalize
      !!            w(i) = scale/expand  ! This is the fraction of channel covered
      x(1:2,i) = x(1:2,i)/scale
    else
      imin = int(pix)
      imax = imin+1
      if ((imin.lt.1).or.(imax.gt.ydim)) then
        x(1:3,i) = 0.
      else
        x(1:3,i) = y(1:3,imin)*(imin+1-pix) + y(1:3,imin+1)*(pix-imin)
      endif
      ! Re-scale the weight
      x(3,i) = x(3,i)*expand
    endif
  enddo
end subroutine interpolate_uv
!
subroutine interpolate_axis(xdim,xinc,xref,xval, ydim,yinc,yref,yval, &
  & jmin,jmax,wmin,wmax)
  !-----------------------------------------------------------------------
  ! @ public
  !*
  ! IMAGER   Support for UV_RESAMPLE and UV_MERGE
  !
  ! Performs the linear interpolation/integration for visibilities
  !
  ! 1) if actual interpolation (XINC <= YINC)  
  !     this is a 2-point linear interpolation formula.
  !     the data is untouched if the resolution is unchanged and the shift
  !     is an integer number of channels.
  !
  ! 2) if not (XINC > YINC)  
  !     boxcar convolution (width xinc-yinc) followed by linear interpolation
  !!
  !-----------------------------------------------------------------------------
  integer, intent(in) :: ydim             !! Input axis size
  integer, intent(in) :: xdim             !! Output axis size
  real(8), intent(in) :: yref,yval,yinc   !! Input conversion formula
  real(8), intent(in) :: xref,xval,xinc   !! Output conversion formula
  integer, intent(out) :: jmin(xdim)      !! Min pixel in current output one
  integer, intent(out) :: jmax(xdim)      !! Max pixel in current output one
  real, intent(out) :: wmin(xdim)         !! Weight of jmin()
  real, intent(out) :: wmax(xdim)         !! Weight of jmax()
  !
  ! Local ---
  integer :: i,j,imin,imax
  real(8) :: pix, val, expand
  real(4) :: scale, ww
  integer :: wall
  !
  ! Code ----
  expand = abs(xinc/yinc)
  !Print *,'Expand  ',expand
  !Print *,'Channel    Wleft    middle     Right     Imin     Imax ' 
  do i = 1, xdim
    !
    ! Compute interval
    val = xval + (i-xref)*xinc
    pix = (val-yval)/yinc + yref
    if (expand.gt.1.) then
      imin = int(pix-expand/2d0+0.5d0)
      imax = int(pix+expand/2d0+0.5d0)
      if (imin.gt.ydim .or. imax.lt.1) cycle
      if (imin.lt.1) then
        imin = 1
        ww = 1.0  ! the whole channel is in...
      else
        ww = imin-(pix-expand/2d0-0.5d0)
      endif
      wmin(i) = ww
      !
      if (imax.gt.ydim) then
        imax = ydim
        ww = 1.0
      else
        ww = pix+expand/2d0+0.5d0-imax
      endif
      wmax(i) = ww
      scale = scale + ww
      !
      wall = imax-imin-1
      do j=imin+1, imax-1
        scale = scale+1.
      enddo
    else
      imin = int(pix)
      imax = imin+1
      wall = 0
      if ((imin.lt.1).or.(imax.gt.ydim)) then
        wmin(i) = 0
        wmax(i) = 0
      else
        wmin(i) = imin+1-pix
        wmax(i) = pix-imin
      endif
    endif
    jmin(i) = imin
    jmax(i) = imax
    !Print *,i,wmin(i),wall,wmax(i),jmin(i),jmax(i) !', Expand ',expand 
  enddo
end subroutine interpolate_axis
!
subroutine average_uv (out,nx,nv,inp,ny,nc,num,nt)
  !------------------------------------------------------------------------
  ! @ public
  !
  ! MAPPING
  !   Support for tasks UV_AVERAGE    -- Unused by IMAGER
  !   Average (in memory) a series of channels of a UV data set
  !------------------------------------------------------------------------
  integer, intent(in) :: num        ! Number of selected channels
  integer, intent(in) :: nx         ! Output Visibility size
  integer, intent(in) :: nv         ! Number of visibilities
  real, intent(out) :: out(nx,nv)   ! Output Visibilities
  integer, intent(in) :: ny         ! Input visibility size
  real, intent(in) :: inp(ny,nv)    ! Input visibilities
  integer, intent(in) :: nc(num)    ! Selected Channels, first & last pairs
  integer, intent(in) :: nt         ! Number of trailing informations
  ! Local
  integer :: j,k,kk,l
  real :: a,b,c
  !
  do j=1,nv
    out(1:7,j) = inp(1:7,j)
    a = 0.0
    b = 0.0
    c = 0.0
    do l=2,num,2
      do k=nc(l-1),nc(l)
        kk = 7+3*k
        if (inp(kk,j).gt.0) then
          a = a+inp(kk-2,j)*inp(kk,j)
          b = b+inp(kk-1,j)*inp(kk,j)
          c = c+inp(kk  ,j)
        endif
      enddo
    enddo
    if (c.ne.0.0) then
      out(8,j) =a/c
      out(9,j) =b/c
      out(10,j)=c              ! time*band
    else
      out(8,j) =0.0
      out(9,j) =0.0
      out(10,j)=0.0
    endif
    !
    if (nt.ne.0) then
      out(nx-nt+1:nx,j) = inp(ny-nt+1:ny,j)
    endif
  enddo
end subroutine average_uv
!
subroutine compress_uv(out,nx,nv,mx,inp,ny,nc,nt, filtered)
  !------------------------------------------------------------------------
  ! @ public
  !
  ! IMAGER
  !   Support for command UV_COMPRESS
  !   Compress (in memory) by NC channels a UV data set
  !------------------------------------------------------------------------
  integer, intent(in) :: nx         ! Output Visibility size
  integer, intent(in) :: nv         ! Number of visibilities
  integer, intent(in) :: mx         ! Number of Output Channels
  real, intent(out) :: out(nx,nv)   ! Output Visibilities
  integer, intent(in) :: ny         ! Input visibility size
  real, intent(in) :: inp(ny,nv)    ! Input visibilities
  integer, intent(in) :: nc         ! Number of Channels to average
  integer, intent(in) :: nt         ! Number of trailing informations
  integer, intent(in), optional :: filtered(:) 
  ! Local
  integer :: i,j,k,kk,ifi,mc
  real :: a,b,c
  integer, allocatable :: filtre(:)
  !
  ! Code
  if (present(filtered)) then
    mc = size(filtered)
    allocate(filtre(mc)) 
    filtre(:) = filtered
  else
    allocate(filtre(nc))
    filtre = 1
  endif
  !$OMP PARALLEL &
  !$OMP    & SHARED(out,inp, nx,nv,mx,ny,nc,nt, filtered)  &
  !$OMP    & PRIVATE(j,ifi,a,b,c,k,kk)
  !$OMP DO SCHEDULE(STATIC)
  do j=1,nv
    out(1:7,j) = inp(1:7,j)
    ifi = 1
    do i=1,mx
      a = 0.
      b = 0.
      c = 0.
      do k=ifi,ifi+nc-1
        kk = 7+3*k
        if (kk.gt.ny-nt) exit   ! Avoid overflow
        if ((inp(kk,j).gt.0).and.(filtre(k).gt.0)) then
          a = a+inp(kk-2,j)*inp(kk,j)
          b = b+inp(kk-1,j)*inp(kk,j)
          c = c+inp(kk  ,j)
        endif
      enddo
      ifi = ifi+nc
      kk = 7+3*i
      if (c.ne.0) then
        out(kk-2,j) = a/c
        out(kk-1,j) = b/c
        out(kk  ,j) = c         ! time*band
      else
        out(kk-2,j) = 0.
        out(kk-1,j) = 0.
        out(kk  ,j) = 0.
      endif
    enddo
    !
    if (nt.ne.0) then
      out(nx-nt+1:nx,j) = inp(ny-nt+1:ny,j)
    endif
  enddo
  !$OMP END DO
  !$OMP END PARALLEL    
end subroutine compress_uv
