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=index_length) :: ivisi
  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
  weicol = cols(3)
  do ivisi=1,huv%gil%nvisi
     duv(weicol,ivisi) = sign(duv(weicol,ivisi),-1.0)
  enddo
end subroutine uv_spectral_flag
!
subroutine uv_spectral_flag_by_antenna(channel,antlist,nantlist,error)
  use image_def
  use uv_buffers
  use mapping_interfaces, except_this=>uv_spectral_flag_by_antenna
  !--------------------------------------------------------
  ! @ private
  ! Flags a UV channel for the given list of antennnas.
  ! Returns error if channel is outside UV table range.
  !--------------------------------------------------------
  integer(kind=index_length), intent(in)    :: channel
  integer(kind=4),            intent(in)    :: antlist(:)
  integer(kind=4),            intent(in)    :: nantlist
  logical,                    intent(inout) :: error
  !
  integer(kind=index_length) :: cols(3)  ! UV Columns for channel
  integer(kind=index_length) :: ivisi,kant,weicol
  integer(kind=index_length) :: col_anti,col_antj
  integer(kind=4) :: iant,jant
  !
  ! Verify that we are inside the table
  call uv_spectral_getcols(channel,cols)
  if (cols(1).eq.-1) then
     error = .true.
     return
  endif
  weicol = cols(3)
  col_anti = huv%gil%column_pointer(code_uvt_anti)
  col_antj = huv%gil%column_pointer(code_uvt_antj)
  !
  ! Work
  do ivisi=1,huv%gil%nvisi
     iant = duv(col_anti,ivisi)
     jant = duv(col_antj,ivisi)
     do kant=1,nantlist
         if (antlist(kant).eq.iant .or. antlist(kant).eq.jant) then
            duv(weicol,ivisi) = sign(duv(weicol,ivisi),-1.0)
            exit
         endif
     enddo
  enddo
end subroutine uv_spectral_flag_by_antenna
!
subroutine uv_spectral_flag_by_baseline(channel,baselist,nbaselist,error)
  use image_def
  use uv_buffers
  use mapping_interfaces, except_this=>uv_spectral_flag_by_baseline
  !--------------------------------------------------------
  ! @ private
  ! Flags a UV channel for the given list of baselines.
  ! Returns error if channel is outside UV table range.
  !--------------------------------------------------------
  integer(kind=index_length), intent(in)    :: channel
  integer(kind=4),            intent(in)    :: baselist(:,:)
  integer(kind=4),            intent(in)    :: nbaselist
  logical,                    intent(inout) :: error
  !
  integer(kind=index_length) :: cols(3)  ! UV Columns for channel
  integer(kind=index_length) :: ivisi,ibase,weicol
  integer(kind=index_length) :: col_anti,col_antj
  integer(kind=4) :: iant,jant
  !
  ! Verify that we are inside the table
  call uv_spectral_getcols(channel,cols)
  if (cols(1).eq.-1) then
     error = .true.
     return
  endif
  weicol = cols(3)
  col_anti = huv%gil%column_pointer(code_uvt_anti)
  col_antj = huv%gil%column_pointer(code_uvt_antj)
  !
  ! Work
  do ivisi=1,huv%gil%nvisi
     iant = duv(col_anti,ivisi)
     jant = duv(col_antj,ivisi)
     do ibase=1,nbaselist
        if ((baselist(1,ibase).eq.iant .and. baselist(2,ibase).eq.jant) .or.  &
            (baselist(1,ibase).eq.jant .and. baselist(2,ibase).eq.iant)) then
           duv(weicol,ivisi) = sign(duv(weicol,ivisi),-1.0)
           exit
        endif
     enddo
  enddo
end subroutine uv_spectral_flag_by_baseline
!
subroutine uv_spectral_zero(channel,error)
  use image_def, only: index_length
  use uv_buffers
  use mapping_interfaces, except_this=>uv_spectral_zero
  !--------------------------------------------------------
  ! @ private
  ! Zeroes 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) :: ivisi,icol
  !
  ! 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 ivisi=1,huv%gil%nvisi
     do icol=cols(1),cols(3)
        duv(icol,ivisi) = 0.0
     enddo
  enddo
end subroutine uv_spectral_zero
!
subroutine uv_spectral_zero_by_antenna(channel,antlist,nantlist,error)
  use image_def
  use uv_buffers
  use mapping_interfaces, except_this=>uv_spectral_zero_by_antenna
  !--------------------------------------------------------
  ! @ private
  ! Zeroes a UV channel for the given list of antennnas.
  ! Returns error if channel is outside UV table range.
  !--------------------------------------------------------
  integer(kind=index_length), intent(in)    :: channel
  integer(kind=4),            intent(in)    :: antlist(:)
  integer(kind=4),            intent(in)    :: nantlist
  logical,                    intent(inout) :: error
  !
  integer(kind=index_length) :: cols(3)  ! UV Columns for channel
  integer(kind=index_length) :: ivisi,kant,icol
  integer(kind=index_length) :: col_anti,col_antj
  integer(kind=4) :: iant,jant
  !
  ! Verify that we are inside the table
  call uv_spectral_getcols(channel,cols)
  if (cols(1).eq.-1) then
     error = .true.
     return
  endif
  col_anti = huv%gil%column_pointer(code_uvt_anti)
  col_antj = huv%gil%column_pointer(code_uvt_antj)
  !
  ! Work
  do ivisi=1,huv%gil%nvisi
     iant = duv(col_anti,ivisi)
     jant = duv(col_antj,ivisi)
     do kant=1,nantlist
         if (antlist(kant).eq.iant .or. antlist(kant).eq.jant) then
            do icol=cols(1),cols(3)
               duv(icol,ivisi) = 0.0
            enddo
            exit
         endif
     enddo
  enddo
end subroutine uv_spectral_zero_by_antenna
!
subroutine uv_spectral_zero_by_baseline(channel,baselist,nbaselist,error)
  use image_def
  use uv_buffers
  use mapping_interfaces, except_this=>uv_spectral_zero_by_baseline
  !--------------------------------------------------------
  ! @ private
  ! Zeroes a UV channel for the given list of baselines.
  ! Returns error if channel is outside UV table range.
  !--------------------------------------------------------
  integer(kind=index_length), intent(in)    :: channel
  integer(kind=4),            intent(in)    :: baselist(:,:)
  integer(kind=4),            intent(in)    :: nbaselist
  logical,                    intent(inout) :: error
  !
  integer(kind=index_length) :: cols(3)  ! UV Columns for channel
  integer(kind=index_length) :: ivisi,ibase,icol
  integer(kind=index_length) :: col_anti,col_antj
  integer(kind=4) :: iant,jant
  !
  ! Verify that we are inside the table
  call uv_spectral_getcols(channel,cols)
  if (cols(1).eq.-1) then
     error = .true.
     return
  endif
  col_anti = huv%gil%column_pointer(code_uvt_anti)
  col_antj = huv%gil%column_pointer(code_uvt_antj)
  !
  ! Work
  do ivisi=1,huv%gil%nvisi
     iant = duv(col_anti,ivisi)
     jant = duv(col_antj,ivisi)
     do ibase=1,nbaselist
        if ((baselist(1,ibase).eq.iant .and. baselist(2,ibase).eq.jant) .or.  &
            (baselist(1,ibase).eq.jant .and. baselist(2,ibase).eq.iant)) then
           do icol=cols(1),cols(3)
              duv(icol,ivisi) = 0.0
           enddo
           exit
        endif
     enddo
  enddo
end subroutine uv_spectral_zero_by_baseline
