subroutine uv_spectral_frequency_sel(frequency, width, unit, channels, error)
  use gkernel_interfaces
  use mapping_interfaces, except_this=>uv_spectral_frequency_sel
  use gbl_message
  use uv_buffers
  !--------------------------------------------------------
  ! @ private
  !
  ! Mapping
  ! returns spectral channels based on a frequency and width given as input
  !--------------------------------------------------------
  real(kind=8), intent(in)      :: frequency
  real(kind=4), intent(in)      :: width
  character(len=10), intent(in) :: unit
  integer(kind=4), intent(out)  :: channels(2)
  logical, intent(inout)        :: error
  !
  real(kind=4)                  :: locwidth ! Local variable to manipulate width
  !
  select case(unit)
  case ('CHANNEL')
     locwidth = 0.5*width*abs(huv%gil%fres)
  case ('VELOCITY')
     locwidth = 0.5*width*abs(huv%gil%fres/huv%gil%vres)
  case ('FREQUENCY')
     locwidth = 0.5*width ! Otherwise locwidth is non initialized
  end select
  if (huv%gil%fres.gt.0) then
     ! +1 to assure the correct number of output channels.
     channels(1) = (frequency-huv%gil%freq-locwidth)/huv%gil%fres + huv%gil%ref(1)+1
     channels(2) = (frequency-huv%gil%freq+locwidth)/huv%gil%fres + huv%gil%ref(1)
  else
     channels(1) = (frequency-huv%gil%freq+locwidth)/huv%gil%fres + huv%gil%ref(1)+1
     channels(2) = (frequency-huv%gil%freq-locwidth)/huv%gil%fres + huv%gil%ref(1)
  endif
end subroutine uv_spectral_frequency_sel
!
subroutine uv_spectral_velocity_sel(velocity, width, unit, channels, error)
  use gkernel_interfaces
  use mapping_interfaces, except_this=>uv_spectral_velocity_sel
  use gbl_message
  use uv_buffers
  !--------------------------------------------------------
  ! @ private
  !
  ! Mapping
  ! returns spectral channels based on a velocity and width given as input
  !--------------------------------------------------------
  real(kind=8), intent(in)      :: velocity
  real(kind=4), intent(in)      :: width
  character(len=10), intent(in) :: unit
  integer(kind=4), intent(out)  :: channels(2)
  logical, intent(inout)        :: error
  !
  real(kind=4)                  :: locwidth ! Local variable to manipulate width
  !
  locwidth = 0.5*width ! This makes sure we don't need a case for velocity
  select case(unit)
  case ('CHANNEL')
     locwidth = locwidth*abs(huv%gil%vres)
  case ('FREQUENCY')
     locwidth = width*abs(huv%gil%vres/huv%gil%fres)
  end select
  if (huv%gil%vres.gt.0) then
     ! +1 to assure the correct number of output channels.
     channels(1) = (velocity-huv%gil%voff-locwidth)/huv%gil%vres + huv%gil%ref(1)+1
     channels(2) = (velocity-huv%gil%voff+locwidth)/huv%gil%vres + huv%gil%ref(1)
  else
     channels(1) = (velocity-huv%gil%voff+locwidth)/huv%gil%vres + huv%gil%ref(1)+1
     channels(2) = (velocity-huv%gil%voff-locwidth)/huv%gil%vres + huv%gil%ref(1)
  endif
end subroutine uv_spectral_velocity_sel
!
subroutine uv_spectral_range_sel(range,unit,channels, error)
  use gkernel_interfaces
  use mapping_interfaces, except_this=>uv_spectral_range_sel
  use gbl_message
  use uv_buffers
  !--------------------------------------------------------
  ! @ private
  !
  ! Mapping
  ! returns spectral channels based on a range at a known unit
  !--------------------------------------------------------
  real(kind=4), intent(in)      :: range(2)
  character(len=10), intent(in) :: unit
  integer(kind=4), intent(out)  :: channels(2)
  logical, intent(inout)        :: error
  !
  integer           :: dummy            ! dummy integer for one off operations
  !
  select case(unit)
  case ('CHANNEL')
     channels = nint(range)
  case ('VELOCITY')
     channels = (range - huv%gil%voff) / huv%gil%vres + huv%gil%ref(huv%gil%faxi)
  case ('FREQUENCY')
     channels = (range - huv%gil%freq) / huv%gil%fres + huv%gil%ref(huv%gil%faxi)
  end select
  if (channels(1).gt.channels(2)) then
     dummy = channels(2)
     channels(2) = channels(1)
     channels(1) = dummy
  endif
end subroutine uv_spectral_range_sel
!
subroutine uv_spectral_getcols(channel,columns)
  use image_def, only: index_length
  use uv_buffers
  use mapping_interfaces, except_this=>uv_spectral_getcols
  !--------------------------------------------------------
  ! @ private
  !
  ! Mapping
  ! returns real, imaginary and weight columns for a given channel
  ! Returns -1 for all columns if channel outside table
  !--------------------------------------------------------
  integer(kind=index_length),intent(in)  :: channel
  integer(kind=index_length),intent(out) :: columns(3)
  !
  if (channel.gt.huv%gil%nchan.or.channel.lt.1) then
     columns = -1
     return
  endif
  columns(1) = huv%gil%nlead+(channel-1)*huv%gil%natom+1
  columns(2) = columns(1)+1
  columns(3) = columns(1)+2
end subroutine uv_spectral_getcols
!
subroutine uv_spectral_flag(channel,error)
  use image_def, only: index_length,size_length
  use uv_buffers
  use mapping_interfaces, except_this=>uv_spectral_flag
  !--------------------------------------------------------
  ! @ private
  !
  ! Mapping
  ! Flags a UV channel i.e. makes its weight negative.
  ! Returns error if channel is outside UV table range.
  !--------------------------------------------------------
  integer(kind=index_length),intent(in)  :: channel
  logical,intent(inout)                  :: error
  !
  integer(kind=index_length) :: cols(3)        ! UV Columns for channel
  integer(kind=size_length)  :: nvisi          ! Number of visibilities
  integer(kind=index_length) :: ivisi          ! visibility index
  integer(kind=index_length) :: weicol         ! weight column
  !
  ! Verify That we are inside the table
  call uv_spectral_getcols(channel,cols)
  if (cols(1).eq.-1) then
     error = .true.
     return
  endif
  !
  ! Actual work
  nvisi = huv%gil%nvisi
  weicol = cols(3)
  do ivisi=1, nvisi
     if (duv(weicol,ivisi).gt.0)then
        duv(weicol,ivisi) = -duv(weicol,ivisi)
     endif
  enddo
end subroutine uv_spectral_flag
!
subroutine uv_spectral_zero(channel,error)
  use image_def, only: index_length
  use uv_buffers
  use mapping_interfaces, except_this=>uv_spectral_zero
  !--------------------------------------------------------
  ! @ private
  !
  ! Mapping
  ! zeros a UV channel
  ! Returns error if channel is outside UV table range.
  !--------------------------------------------------------
  integer(kind=index_length),intent(in)  :: channel
  logical,intent(inout)                  :: error
  !
  integer(kind=index_length) :: cols(3)        ! UV Columns for channel
  integer(kind=index_length) :: icol           ! Column index
  !
  ! Verify That we are inside the table
  call uv_spectral_getcols(channel,cols)
  if (cols(1).eq.-1) then
     error = .true.
     return
  endif
  ! Work
  do icol=cols(1), cols(3)
     duv(icol,:) = 0.0
  end do
end subroutine uv_spectral_zero
