subroutine uv_linear_comm(line,comm,error)
  use clean_def
  use clean_arrays
  use clean_beams
  use gbl_message
  use gkernel_interfaces
  use imager_interfaces, except_this => uv_linear_comm
  !-----------------------------------------------------------
  ! @ private
  ! IMAGER -- Support for command  
  !   UV_LINEARIZE   [/FILE FileIn FileOut]
  !
  !     Linearize random frequency axis by  
  !     - ordering the frequencies  
  !     - filling the holes by empty (zero weight) channels
  !   as much as possible, i.e. if and only if  
  !     - spacing tolerance between "adjacent" frequencies is
  !       smaller than specified threshold  
  !     - gaps are not too large either
  !!
  !-----------------------------------------------------------
  character(len=*), intent(in) :: comm    !! Command name
  character(len=*), intent(inout) :: line !! Command line
  logical, intent(inout) :: error         !! Error flag
  !
  ! Constants
  character(len=*), parameter :: rname='UV_LINEARIZE'
  integer, parameter :: o_file=1
  real(kind=8) :: btole=1.D-3 !! Strictly speaking it 
  !! should be dependent on the number of channels
  !
  ! Local ---
  type(gildas) :: uvout
  real, pointer :: duv_previous(:,:), duv_next(:,:)
  real(kind=8), allocatable :: the_freqs(:)
  integer, allocatable :: indx(:), itmp(:), acount(:), pixels(:), filled(:)
  real, allocatable :: rdiff(:)
  real(kind=8), allocatable :: adiff(:)
  integer :: nfreq, ier, i, j, jdiff, mdiff, npix
  integer :: iv,ic, kfi,kla, jfi,jla
  real :: bzero, bdiff
  integer :: nu,nv
  logical :: err
  !
  ! Code ----
  call sic_r8(line,0,1,btole,.false.,error)
  !
  if (sic_present(o_file,0)) then
    call map_message(seve%e,rname,'Option /FILE not yet implemented')
    error = .true.
    return
  endif
  !
  ! Only in memory work so far
  if (huv_current%loca%size.eq.0) then
    call map_message(seve%e,rname,'No UV data')
    error = .true.
    return
  endif
  if (huv_current%gil%nfreq.eq.0) then
    call map_message(seve%i,rname,'UV data is already linear',seve%w)
    return
  endif
  !
  nfreq = huv_current%gil%nfreq
  allocate(the_freqs(nfreq),indx(nfreq),itmp(nfreq), &
    & adiff(nfreq),acount(nfreq),stat=ier)
  !
  the_freqs(:) = huv_current%gil%freqs(:)
  call gr8_trie(the_freqs,indx,nfreq,error)
  !
  ! Count the differences
  adiff(1) = the_freqs(2)-the_freqs(1)
  mdiff = 1
  acount(1) = 1
  bzero = adiff(1)
  !
  do i=2,nfreq-1
    bdiff = the_freqs(i+1)-the_freqs(i)
    jdiff = 0
    do j=1,mdiff
      if (abs(bdiff-adiff(j)).le.bzero*btole) then
        jdiff = j
        exit
      endif
    enddo
    if (jdiff.eq.0) then
      Print *,'Found new spacing at I ',i,the_freqs(i),the_freqs(i+1)
      jdiff = mdiff+1
      adiff(jdiff) = bdiff
      acount(jdiff) = 1
      mdiff = jdiff
    else
      acount(jdiff) = acount(jdiff)+1
    endif
  enddo
  !
  if (mdiff.gt.1) then
    call map_message(seve%w,rname,'More than one Frequency range')
    allocate (rdiff(mdiff))
    Print *,'Range      Spacing     Occurence  Ratio '
    do j=1,mdiff
      rdiff(j) = adiff(j)/adiff(1)
      Print *,j,adiff(j),acount(j),rdiff(j)
      if (abs(nint(rdiff(j))-rdiff(j)).gt.btole) error = .true.
    enddo
    if (error) then
      call map_message(seve%e,rname,'Input frequency axis is not sufficiently regular')
      return
    endif
  endif
  !
  ! Now define the axis
  npix = ceiling((the_freqs(nfreq)-the_freqs(1))/adiff(1)+1.0)
  !
  if (npix.gt.huv_current%gil%nchan*2) then
    call map_message(seve%e,rname,'Linearization would create too many  or too large gaps')
    error = .true.
    return
  endif
  !
  allocate(pixels(npix),filled(nfreq),stat=ier)
  do i=1,npix
    pixels(i) = (i-1)*adiff(1)+the_freqs(1)
  enddo
  !
  do i=1,nfreq
    j = nint((huv_current%gil%freqs(i)-the_freqs(1))/adiff(1) + 1d0)
    filled(i) = j
    if (j.gt.npix) then
      Print *,'Rounding error J ',j,' > NPIX ',npix
      Print *,'   Please enter a number to continue'
      read(5,*) iv
    endif 
    if (i.gt.1) then
      if (j.eq.filled(i-1)) then
        Print *,'Duplicate entry j ',j,' at I ',i,huv_current%gil%freqs(i),adiff(1)
        Print *,'Entry I-1 ',i-1,huv_current%gil%freqs(i-1),filled(i-1), (& 
          & huv_current%gil%freqs(i)-the_freqs(1))/adiff(1) + 1d0
        print *,filled(1:i)
        Print *,'   Please enter a number to continue'
        read(5,*) iv
      endif
    endif
  enddo
  !
  ! Get a new UV data set
  call gildas_null(uvout,type='UVT')
  call gdf_copy_header(huv_current,uvout,error)
  uvout%gil%nfreq = 0
  !
  ! Prepare appropriate array...
  nu = huv_current%gil%dim(1)+(npix-nfreq)*3  ! No Stokes anyway...
  nv = huv_current%gil%nvisi
  uvout%gil%dim(1) = nu
  uvout%gil%dim(2) = nv 
  uvout%gil%convert(:,1) = [1.d0,the_freqs(1),dble(adiff(1))]
  uvout%gil%nchan = npix
  uvout%gil%freq = (npix/2-1)*uvout%gil%convert(3,1)+uvout%gil%convert(2,1)
  uvout%gil%convert(1,1) = npix/2
  uvout%gil%convert(2,1) = uvout%gil%freq
  call gdf_uv_shift_columns(huv_current,uvout)
  call gdf_setuv(uvout,error)
  !
  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
  !
  do iv=1,nv
    duv_next(1:7,iv) = duv_previous(1:7,iv)
    do ic=1,nfreq
      kfi = 5+3*ic
      kla = kfi+2
      jfi = 5+3*filled(ic)
      jla = jfi+2
      duv_next(jfi:jla,iv) = duv_previous(kfi:kla,iv)
    enddo
  enddo  
  !
  ! Set header back
  call gdf_copy_header(uvout,huv_current,error)
  !
  ! Reset proper pointers
  call uv_clean_buffers (duv_previous, duv_next,error)
  if (error) return
  !
  ! Delete variables that may have been affected
  !
  ! Channel range is no longer meaningful
  nbeam_ranges = -1
  call sic_delvariable ('BEAM_RANGES',.false.,err)
  if (sic_varexist('UVS')) call sic_delvariable('UVS',.false.,err)
  !
  ! Indicate UV data has changed, and weight must be computed
  call uv_new_data(weight=.true., resample=.true.)  
end subroutine uv_linear_comm
