subroutine pdbi_spectral(line,error)
  use gkernel_interfaces
  use gbl_message
  use ast_line
  use ast_astro
  !---------------------------------------------------------------------
  ! @ private
  ! PDBI internal routine, support for command
  !	SPECTRAL iunit bandwidth frequency /NARROW i
  !---------------------------------------------------------------------
  character(len=*):: line           !
  logical :: error                  !
  ! Local
  logical :: bad, update
  integer(kind=4) :: iunit, iband, ii, bandmode, nc, nk
  real(kind=4) :: flo3, x4, y4, rf
  real(kind=8) :: xu, yu
  character(len=1) :: code
  character(len=13) :: rname
  data rname /'PDBI_SPECTRAL'/
  character(len=3) :: bmode(4), arg, arg2
  data bmode /'LSB','USB','SSB','DSB'/
  ! ---------------------------------------------------------------------------
  !
  ! NARROW entries must have been defined
  !
  if (.not.narrow_def) then
     call astro_message(seve%e,rname,'NARROW entries not defined')
     error = .true.
     return
  endif
  !
  ! Unit
  !
  call sic_i4 (line,0,1,iunit,.true.,error)
  if (error) return
  if (iunit.lt.1 .or. iunit.gt.8) then
    call astro_message(seve%e,rname,'Invalid correlator unit number ')
    error = .true.
    return
  endif
  !
  ! SPECTRAL i OFF
  !
  if (sic_present(0,2)) then
     call sic_ke(line,0,2,arg,nc,.true.,error)
     if ((arg.eq.'OFF').or.(arg.eq.'off')) then
        unit_def(iunit) = .false.
        call pdbi_plot_line(error)
        return
     endif
  endif
  !
  ! Defaults
  !
  if (unit_def(iunit)) then
     iband = unit_band(iunit)
     flo3 = unit_cent(iunit)
     ii = unit_wind(iunit)
  else
     iband = 80
  endif
  !
  ! Bandwidth
  !
  if (sic_present(0,2)) then
     call sic_i4(line,0,2,iband,.true.,error)
     if (error) return
     if (iband.ne.20 .and. iband.ne.40 .and. iband.ne.80 .and. iband.ne.160   &
          .and. iband.ne.320) then
        call astro_message(seve%e,rname,'Invalid bandwidth ')
        error = .true.
        return
     endif
  endif
  !
  ! Center frequency & narrow entry
  !
  if (sic_present(0,3)) then
     !
     ! From the command line
     !
     if (sic_present(1,0)) then
	!
	! option /NARROW
	!
     	call sic_r4(line,0,3,flo3,.true.,error)
     	if (error) return
       	if (flo3.lt.100 .or. flo3.gt.1100) then
           call astro_message(seve%e,rname,'Invalid center frequency ')
           error = .true.
           return
        endif
        !      IF (FLO3.LT.(IFLIM(1)+IBAND/2) .OR.
        !     &     FLO3.GT.(IFLIM(2)-IBAND(2))) THEN
        !         CALL GAGOUT('W-LINE/SPECTRAL,  Center freq. too close
        !     &        from edge of receiver band')
        !      ENDIF
        flo3 = 0.625*nint(flo3/0.625)
        !
        ! Correlator entry
        !
        call sic_i4(line,1,1,ii,.true.,error)
        if (error) return
        if ((ii.ne.1).and.(ii.ne.2)) then
           call astro_message(seve%e,'SPECTRAL','Unknown correlator entry')
           error = .true.
           return
        endif
	!
     elseif (sic_present(4,0)) then
	!
	! Option /RF
	!
     	call sic_r4(line,0,3,rf,.true.,error)
	call if3fromrf(flo3,ii,rf,error)
	if (error) then
	   call astro_message(seve%e,'SPECTRAL','RF frequency not observed')
	   return
        endif
	!
     else
	!
	! Need /NARROW or /RF
	!
        call astro_message(seve%e,rname,'/NARROW or /RF options mandatory')
        error = .true.
        return
     endif
     !
  else
     !
     ! Interactive definition with the cursor
     !
     ! plot_mode must be 2
     !
     if (plot_mode.ne.2) then
        plot_mode = 2
        call pdbi_plot_def(error)
        if (error) return
        call pdbi_plot_line(error)
     endif
     call gr_exec1('LIMITS 100 1100 0 5')  !  force IF3 limits
     !
     ! Update spectral plot, to have selected unit in dash
     !
     call gt_clear_segment('SPECTRAL',.false.,error)
     call pdbi_plot_spectral(1,iunit)
     call pdbi_plot_spectral(2,iunit)
     call gr_exec1('PEN 0')
     !
     ! Loop on cursor output
     !
     code = ' '
     call astro_message(seve%i,rname,'Interactive definition of the spectral unit')
     call astro_message(seve%r,rname,'    Left click to define position / narrow input')
     call astro_message(seve%r,rname,'    + to increase bandwidth')
     call astro_message(seve%r,rname,'    - to decrease bandwidth')
     call astro_message(seve%r,rname,'    > to shift position by 5 MHz (increase IF)')
     call astro_message(seve%r,rname,'    < to shift position by 5 MHz (decrease IF)')
     call astro_message(seve%r,rname,'    E to exit')
     !
     do while (code.ne.'E')
        !
        update = .false.
        call gr_curs (xu, yu, x4, y4, code)
        !
        if (code.eq.'^') then
           !
           ! Left click : define central frequency & narrow entry
           !
           update = .true.
           if ((xu.gt.(100+iband/2)).and.(xu.lt.(1100-iband/2))) then
              flo3 = xu
           else
              call astro_message(seve%e,rname,'Spectral window must fit in the IF band')
              update = .false.
           endif
           !
           ! Narrow entry
           !
           if ((yu.ge.0).and.(yu.le.5)) then
              ii = 2
           elseif ((yu.ge.7.75).and.(yu.le.12.75)) then
              ii = 1
           else
              call astro_message(seve%e,rname,'Please select one of the NARROW entries')
              update = .false.
           endif
        else
	   !
	   ! Too lazy to use SHIFT
           !
	   if (code.eq.'=') code = '+'
	   if (code.eq.',') code = '<'
	   if (code.eq.'.') code = '>'
           !
           ! Move/expand unit
           !
           if ((code.eq.'+').and.(iband.ne.320)) iband = iband*2
           if ((code.eq.'-').and.(iband.ne.20)) iband = iband/2
           if (code.eq.'<') flo3 = flo3-5
           if (code.eq.'>') flo3 = flo3+5
           update = .true.
           if ((code.ne.'+').and.(code.ne.'-').and.(code.ne.'<') &
                .and.(code.ne.'>')) update = .false.
        endif
        !
        ! Update plot
        !
        if (update) then
           plot_mode = 2
           unit_def(iunit) = .true.
           unit_band(iunit) = iband     ! width
           unit_cent(iunit) = flo3      ! center IF
           unit_wind(iunit) = ii        ! correlator input
           !
	   call gt_clear_segment('SPECTRAL',.false.,error)
           call pdbi_plot_spectral(1,iunit)
           call pdbi_plot_spectral(2,iunit)
           call gr_exec1('PEN 0')
        endif
     enddo
  endif
  !
  ! /BAND option
  !
  bandmode = 1                 ! Default is LSB
  if (iband.eq.320) bandmode = 4   ! DSB for 320 MHz bands
  if (sic_present(2,0)) then
    call sic_ke(line,2,1,arg,nc,.true.,error)
    call sic_ambigs(rname,arg,arg2,nk,bmode,4,error)
    if (error) then
      call astro_message(seve%e,'SPECTRAL', 'Unknown /BAND mode')
      return
    endif
    bad = .false.
    bad = ((iband.eq.20).or.(iband.eq.40)).and.(nk.gt.3)
    bad = bad.or.((iband.eq.320).and.(nk.lt.4))
    if (bad) then
      call astro_message(seve%e,'SPECTRAL','Incompatible unit width and '//  &
      'SSB/DSB mode')
      error = .true.
      return
    endif
    bandmode = nk
  endif
  !
  ! Store values
  !
  unit_def(iunit) = .true.
  unit_band(iunit) = iband     ! width
  unit_cent(iunit) = flo3      ! center IF
  unit_wind(iunit) = ii        ! correlator input
  unit_bmode(iunit) = bandmode ! ssb/dsb mode
  !
  ! Now do the plot
  !
  plot_mode = 2
  call pdbi_plot_line(error)
  !
  1010 format('  Unit ',i1,i4,f8.2,' on entry ',i1)
  1020 format('  Unit ',i1,' OFF')
end subroutine pdbi_spectral
!
! -------------------------------------------------------------------------
!
subroutine pdbi_plot_spectral(window,specialunit)
  use ast_line
  !---------------------------------------------------------------------
  ! @ private
  !---------------------------------------------------------------------
  integer(kind=4) :: window         !
  integer(kind=4) :: specialunit    !
  ! Local
  integer(kind=4) :: i, j, iband
  real(kind=4) :: x(8),y(8), flo3, z(8), edge
  logical :: error
  data z/0.0,2.0,2.0,0.0,2.5,2.0,2.0,0.0/
  !
  if (window.eq.1) then
     call gr_exec1('PEN 1 /DASH 1')
     call gr_exec1('SET BOX 4 29 11.5 17')
  else
     call gr_exec1('PEN 3 /DASH 1')
     call gr_exec1('SET BOX 4 29 3 8.5')
  endif
  !
  do i=1,nunit
    !
    ! Spectral band must have been defined AND connected to
    ! the correct correlator input = 'window'
    !
    if (unit_def(i).and.(window.eq.unit_wind(i))) then
      !
      iband = unit_band(i)
      flo3 =  unit_cent(i)
      !
      ! Box size depends on unit
      !
      do j=1,8
        y(j) = (1.0+0.05*(i-1))*z(j)
      enddo
      !
      ! Special unit in dash
      !
      if (i.eq.specialunit) then
         call gr_exec1('PEN /DASH 3')
      endif
      call gr_segm('SPECTRAL',error)
      !
      ! Consider a 5% loss at the filter's edge
      ! Draw a vertical line at the band center (Gibbs) if necessary, ie if
      ! the unit is in DSB mode (only possible on 80, 160, 320 MHz units)
      !
      edge = iband*0.05
      if (unit_bmode(i).eq.4) then
        x(1) = flo3+0.5*iband
        x(2) = flo3+0.5*iband-1.0*edge
        x(3) = flo3
        x(4) = flo3
        x(5) = flo3
        x(6) = flo3
        x(7) = flo3-0.5*iband+1.0*edge
        x(8) = flo3-0.5*iband
        call gr4_connect(8,x,y,0.0,-1.0)
        ! write(chain,100) x(5),y(5)+0.5,i
        ! call gr_exec1(chain)
      else
        x(1) = flo3+0.5*iband
        x(2) = flo3+0.5*iband-1.0*edge
        x(3) = flo3-0.5*iband+1.0*edge
        x(4) = flo3-0.5*iband
        call gr4_connect(4,x,y,0.0,-1.0)
      endif
      call gr_segm_close(error)
      call gr_exec1('PEN /DASH 1')
    endif
  enddo
  !
  100 format('DRAW TEXT ',f10.2, f10.2, i2, ' /USER')
end subroutine pdbi_plot_spectral
!
! ---------------------------------------------------------------------------
!
subroutine find_rffreq(i,f)
  use gbl_message
  use ast_line
  use ast_astro
  !---------------------------------------------------------------------
  ! @ private
  ! PDBI internal routine
  !       Find sky frequency associated to the center of subband i
  !---------------------------------------------------------------------
  integer(kind=4), intent(in) :: i  !
  real(kind=8), intent(out) :: f    !
  ! Local
  real(kind=8) :: bandwidth, center, ifmin, ifmax, tmp
  integer(kind=4) :: inp
  real(kind=8) :: f1, f2
  real(kind=4) :: qlim(2,4)
  data qlim/4200,5200,5000,6000,6000,7000,6800,7800/
  ! ---------------------------------------------------------------------------
  !
  ! Narrow input
  !
  inp = unit_wind(i)
  !
  ! First IF limits
  !
  ifmin = qlim(1,narrow_input(inp))
  ifmax = qlim(2,narrow_input(inp))
  bandwidth = abs(ifmax-ifmin)/1000.
  center = ifmin+(ifmax-ifmin)/2.
  !
  ! RF axis
  !
  if (sky.eq.1) then           ! USB
    f1 = (flo1+center)/1000.d0/fshift-bandwidth/2.
    f2 = f1+bandwidth
  else                         ! LSB
    f1 = (flo1-center)/1000.d0/fshift+bandwidth/2.
    f2 = f1-bandwidth
  endif
  ! IF in Q2 and Q4 is flipped wrt the RF frequency
  if ((narrow_input(inp).eq.2).or.(narrow_input(inp).eq.4)) then
    tmp = f1
    f1 = f2
    f2 = tmp
  endif
  !
  ! Compute rest frequency at center of subband i
  ! F1 corresponds to IF=100, F2 to IF=1100. But depending on LSB/USB
  ! tuning and on selected quarter, F1 can be > or < F2.
  !
  if (f1.lt.f2) then
    f = f1*1000 + (unit_cent(i) - 100)
  else
    f = f1*1000 - (unit_cent(i) - 100)
  endif
  !
end subroutine find_rffreq
!
subroutine if3fromrf(if3,narrow,rf,error)
  use ast_line
  !---------------------------------------------------------------------
  ! @ private
  ! Compute IF3 from RF
  !---------------------------------------------------------------------
  real(kind=4), intent(out) :: if3        !
  integer(kind=4), intent(out) :: narrow  !
  real(kind=4), intent(in) :: rf          !
  logical, intent(out) :: error           !
  ! Local
  real(kind=4) :: if1
  integer(kind=4) :: quarter, i, goodquarter
  logical :: foundentry
  real(kind=4) :: qlim(2,4)
  data qlim/4200,5200,5000,6000,6000,7000,6800,7800/
  !
  ! First IF (in MHz)
  if1 = (rf*1000.-flo1)/sky
  !
  ! Find good quarter
  do i = 1,4
    if (if1.gt.qlim(1,i) .and. if1.lt.qlim(2,i)) goodquarter = i
  enddo
  !
  ! Special case for the Q1/Q2 and Q3/Q$ overlap
  if (if1.gt.5000 .and. if1.lt.5200 .and. (narrow_input(1)*narrow_input(2)).eq.2) then
     if (if1.lt.5100) goodquarter = 1
     if (if1.ge.5100) goodquarter = 2
  endif
  if (if1.gt.6800 .and. if1.lt.7000 .and. (narrow_input(1)*narrow_input(2)).eq.12) then
     if (if1.le.6800) goodquarter = 3
     if (if1.gt.6800) goodquarter = 4
  endif
  !
  ! Correlator entry?
  foundentry = .false.
  do i = 1,2 ! loop on correlator entries
     if (narrow_input(i).eq.goodquarter) then
	!
	narrow = i 		   ! corr entry 1-2
	quarter = narrow_input(i)  ! quarter 1-4
	!
	! Compute IF3
	if (quarter.eq.2 .or. quarter.eq.4) then
     	   if3 = 1100 - (if1-qlim(1,quarter))
        else
           if3 = 100 + (if1-qlim(1,quarter))
        endif
	!
	foundentry = .true.
     endif
  enddo
  !
  error = .not.foundentry
end subroutine if3fromrf
