subroutine line_auto(line,error)
  use gbl_message
  use gkernel_interfaces
  use ast_astro
  !---------------------------------------------------------------------
  ! @ private
  !---------------------------------------------------------------------
  character(len=*):: line           !
  logical :: error                  !
  ! Local
  integer(kind=4) :: ier, sky, lck, harm, mult, i1, i2, ic, mline, nline
  integer(kind=4) :: ncont, lch, nc, i, mrec, isb, iend, isky(2), nb(2), j, nok, irec
  integer(kind=4) :: mspec, nspec, k, if1, if2, k1, k2, j1, j2, score, mcont
  integer(kind=4) :: scoremax, ibf, ibf2, band(5)
  parameter (mline=20, mcont=2, mrec=2, mspec=6)
  integer(kind=4) :: ncfr(mcont), itun(mrec), isb1(mrec), isb2(mrec)
  integer(kind=4) :: iband(mspec), krec(mspec)
  integer(kind=4) :: jsky(mrec), jharm(mrec), jmult(mrec), wifl(1000,5,mrec)
  integer(kind=4) :: jm, jmin(mrec), jmax(mrec), jrec
  logical :: first, bf10_done, filled, ok
  character(len=80) :: ch, linename(mline), linevelo, cline(mrec)
  character(len=80) :: contname(mline), contbands
  character(len=3) :: csb(-1:1), ctun(mrec), csky(mrec)
  real(kind=8) :: linefreq(mline), linevres(mline), linevmin(mline), linevmax(mline)
  real(kind=8) :: ftmin(2), ftmax(2), flo2(mrec), flo1, best, ft, clight
  real(kind=8) :: eps, fiend(2), ftunemin(2,2), ftunemax(2,2), f1, f2, ftrymin(2)
  real(kind=8) :: ftrymax(2), ftune(mrec), contfr(20,mcont), fif3, df, deltaf
  real(kind=8) :: flo3(mspec), ifstep, cent, bf, ftumin(mrec), ftumax(mrec), vc,velocity
  parameter (best=1875., clight=299792.458, ifstep=0.625)
  !!      PARAMETER (BEST=1875., CLIGHT=299792.458, IFSTEP=1.00)
  parameter (eps=(100d0+50d0/512d0))   !	MHz
  character*9 rname
  !
  data isky/1,-1/
  data fiend/100d0, 600d0/
  data csb /'LSB','DSB','USB'/
  data cent/350./
  data first /.true./
  data lck / -1/
  data band /160,80,40,20,10/
  data rname /'LINE_AUTO'/
  !
  ! resulting parameters accessed as variables:
  save cline, ftune, jsky, jharm, ctun, csky
  save nspec, krec, flo3, iband
  save first
  !-----------------------------------------------------------------------
  ! Get parameters from variables defined in project.pro
  call sic_get_inte('N_LINE',nline,error)
  call sic_get_inte('N_CONT',ncont,error)
  call sic_get_dble('VLSR_1',velocity,error)
  if (error) then
    call astro_message(seve%e,rname,'Variables not defined')
    return
  endif
  if (nline.gt.mline) then
    call astro_message(seve%f,rname,'Too many line tables')
    error = .true.
    return
  endif
  do irec=1, 2
    nb(irec) = 1
    do isb = 1, 2
      ftunemin(isb,irec) = 0
      ftunemax(isb,irec) = 1000000.
    enddo
    cline(irec)= '*'
    jmult(irec) = 1
    if (irec.eq.2) jmult(irec) = 3
    ftune(irec) = -1.
    ftumin(irec) = 0.
    ftumax(irec) = 100000000.
  enddo
  !
  ! Get parameters, and find out about USB or LSB or DSB:
  ! Line tables first:
  if (nline.gt.0) then
    do i=1, nline
      call name_it('LINENAME',i,ch,lch)
      call sic_get_char(ch(1:lch),linename(i),nc,error)
      call name_it('LINEVELO',i,ch,lch)
      call sic_get_char(ch(1:lch),linevelo,nc,error)
      read (linevelo(1:nc),*,err=900) linevmin(i), linevmax(i)
      call name_it('LINEFREQ',i,ch,lch)
      call sic_get_dble(ch(1:lch),linefreq(i),error)
      linefreq(i) = min(300.d3,max(70.d3,linefreq(i)))
      call name_it('LINEVRES',i,ch,lch)
      call sic_get_dble(ch(1:lch),linevres(i),error)
      if (error) return
      irec = nint(linefreq(i)/135000d0)
      ftumin(irec) = min(ftumin(irec),linefreq(i))
      ftumax(irec) = max(ftumax(irec),linefreq(i))
      if (cline(irec).eq.'*') then
        cline(irec) = linename(i)
        ftune(irec) = linefreq(i)
      endif
    enddo
  else
    call astro_message(seve%i,rname,'Continuum only')
  endif
  !
  ! Then continuum tables:
  if (ncont.gt.0) then
    do i=1, ncont
      call name_it('CONTTABLE',i,ch,lch)
      call sic_get_char(ch(1:lch),contname(i),nc,error)
      call name_it('CONTBANDS',i,ch,lch)
      call sic_get_char(ch(1:lch),contbands,nc,error)
      do j=1, 20
        contfr(j,i) = 0
      enddo
      read (contbands,*,iostat=ier) (contfr(k,i),k=1,20)
      ncfr(i) = 0
      do j=1, 20, 2
        if (contfr(j,i).gt.0) ncfr(i) = ncfr(i)+2
      enddo
      ! print *, 'i, NCFR(I), (CONTFR(J,I), j=1, NCFR(I))'
      ! print *, i, NCFR(I), (CONTFR(J,I), j=1, NCFR(I))
      ft = (contfr(1,i)+contfr(ncfr(i),i))/2.
      irec = nint(ft/135000d0)
      ftumin(irec) = min(ftumin(irec),contfr(1,i))
      ftumax(irec) = max(ftumax(irec),contfr(ncfr(i),i))
      if (cline(irec).eq.'*') then
        cline(irec) = contname(i)
        ftune(irec) = ft
      endif
      ! print *, 'irec, CLINE(IREC), FTUNE(IREC), FTUMIN(IREC), FTUMAX(IREC)'
      ! print *, irec, CLINE(IREC), FTUNE(IREC), FTUMIN(IREC), FTUMAX(IREC)
    enddo
  else
    call astro_message(seve%i,rname,'No Continuum')
  endif
  !
  ! Rec 1 must be tuned USB or LSB depending on line frequency:
  if (ftune(1).gt.112d3) then
    itun(1) = 1
    isb1(1) = 1
  else
    itun(1) = -1
    isb1(1) = 2
  endif
  jsky(1) = itun(1)
  isb2(1) = isb1(1)
  !
  ! Rec 2 is tuned DSB by default (we try line LSB or USB)
  itun(2) = 0
  if (ftumax(2)-ftumin(2).lt.fiend(2)-fiend(1)) then
    jsky(2) = -1
    isb1(2) = 2
    isb2(2) = 2
  elseif ((ftune(2)-ftumin(2)) .gt. (ftumax(2)-ftune(2))) then
    jsky(2) = -1
    isb1(2) = 1
    isb2(2) = 2
  else
    jsky(2) = 1
    isb1(2) = 1
    isb2(2) = 2
  endif
  !
  ! Now find the exact frequencies:
  call astro_message(seve%i,rname,'Getting line setup ...')
  if (nline.gt.0) then
    do i=1, nline
      irec = nint(linefreq(i)/135000d0)
      sky = jsky(irec)
      mult = jmult(irec)
      lck = -1
      ! PRINT *, 'i, irec, sky, mult, lck'
      ! PRINT *, I, IREC, SKY, MULT, LCK
      do isb = isb1(irec), isb2(irec)
        ftmin(isb) = 1e10
        ftmax(isb) = -1e10
        f2 = best
        do iend= 1, 2
          ft = linefreq(i)-isky(isb)*(f2-fiend(iend)) +sky*(f2-cent)
          harm =nint(((ft+lck*eps*mult+sky*cent)/best-sky)/mult)
          f2 = (ft + lck*eps*mult+sky*cent)/(mult*harm+sky)
          ft = linefreq(i)-isky(isb)*(f2-fiend(iend)) +sky*(f2-cent)
          ftmin(isb)=min(ftmin(isb), ft*(1.-(linevmin(i)-velocity)/clight))
          ftmax(isb)=max(ftmax(isb), ft*(1.-(linevmax(i)-velocity)/clight))
        enddo
      enddo
      nok = 0
      do j=1, nb(irec)
        ! PRINT *, 'FTUNEMIN(J,IREC), FTUNEMAX(J,IREC)'
        ! PRINT *, FTUNEMIN(J,IREC), FTUNEMAX(J,IREC)
        do isb = 1, 2
          f1 = max(ftunemin(j,irec),ftmin(isb))
          f2 = min(ftunemax(j,irec),ftmax(isb))
          if (f1.le.f2) then
            nok = nok+1
            ftrymin(nok) = f1
            ftrymax(nok) = f2
          endif
        enddo
      enddo
      if (nok.gt.0) then
        do j=1, nok
          ftunemin(j,irec) = ftrymin(j)
          ftunemax(j,irec) = ftrymax(j)
          nb(irec) = nok
        enddo
      else
        error = .true.
        call astro_message(seve%f,rname,linename(i)(1:nc)//' cannot be '//  &
        'observed.')
        return
      endif
    enddo
    !
    do irec=1, 2
      ! print *, 'irec, ftune(irec)'
      ! print *, irec, ftune(irec)
      ok = .false.
      do j=1, nb(irec)
        if (ftunemin(j,irec) .gt. 0) then
          if ( ftune(irec).ge.ftunemin(j,irec) .and.  &
               ftune(irec).le.ftunemax(j,irec) ) then
            ok = .true.
          else
            f1 = (ftunemin(j,irec)+ftunemax(j,irec))/2.
          endif
        endif
      enddo
      if (.not.ok)  ftune(irec)= f1
    enddo
  endif
  !
  ! If continuum only:
  if (ncont.gt.0) then
    do i=1, ncont
      ft = (contfr(1,i)+contfr(ncfr(i),i))/2.
      irec = nint(ft/135000d0)
      if (ftune(irec).lt.0.) then
        ftune(irec) = ft
      endif
    enddo
  endif
  !
  ! Print line setup
  do irec=1, 2
    ! print *, 'irec, ftune(irec)'
    ! print *, irec, ftune(irec)
    if (ftune(irec) .gt. 0) then
      sky = jsky(irec)
      mult = jmult(irec)
      ft = ftune(irec)
      ! print *, 'sky, mult, ft, lck, eps, best'
      ! print *, sky, mult, ft, lck, eps, best
      harm =nint(((ft+lck*eps*mult+sky*cent)/best-sky)/mult)
      f2 = (ft + lck*eps*mult+sky*cent)/(mult*harm+sky)
      jharm(irec) = harm
      flo2(irec) = f2
      csky(irec) = csb(jsky(irec))
      ctun(irec) = csb(itun(irec))
      print 1000, cline(irec), ft/1000., csky(irec), jharm(irec), irec
      1000 format(' LINE ',a12,' ',f13.6,' ',a3,' LOW 350 ',i5,' /RECEIVER ',i1)
    else
      ctun(irec) = 'UND'
      csky(irec) = 'UND'
    endif
  enddo
  !
  ! Get Spectral setup.
  ! attribute subbands to lines first:
  call astro_message(seve%i,rname,'Getting spectral setup ...')
  nspec = 0
  bf10_done = .false.
  j1 = nint(fiend(1)/ifstep)
  j2 = nint(fiend(2)/ifstep)
  do k= j1, j2
    do ibf=1, 5
      do irec=1, 2
        wifl(k,ibf, irec) = 0
      enddo
    enddo
  enddo
  if (nline.gt.0) then
    call astro_message(seve%i,rname,'Covering line tables ...')
    do i=1, nline
      irec = nint(linefreq(i)/135000d0)
      flo1 = ftune(irec)-jsky(irec)*(flo2(irec)-cent)
      vc = (linevmax(i)+linevmin(i))/2-velocity
      f1 = linefreq(i)*(1.-vc/clight)
      fif3 = flo2(irec)-abs(f1-flo1)
      df = linefreq(i) * linevres(i) / clight
      if (df.gt.2.4) then
        ibf = 1
      elseif (df.gt.0.62) then
        ibf = 2
      elseif (df.gt.0.155) then
        ibf = 3
      elseif (df.gt.0.077) then
        ibf = 4
      elseif (df.gt.0.037 .and. .not.bf10_done) then
        ibf = 5
        bf10_done = .true.
      else
        error = .true.
        call astro_message(seve%f,rname,'Resolution too high')
        return
      endif
      deltaf  = linefreq(i) * (linevmax(i)-linevmin(i)) / clight
      k1 = nint((fif3-deltaf/2)/ifstep)
      k2 = nint((fif3+deltaf/2)/ifstep)
      do k=k1, k2
        !               WIFL(K,IBF,IREC) = WIFL(K,IBF,IREC)+1000
        wifl(k,ibf,irec) = 1000
      enddo
      ! print *, 'i, irec, ibf, ifstep, k1, k2'
      ! print *, i, irec, ibf, ifstep, k1, k2
    enddo
  endif
  !
  ! Continuum
  i1 = nint(fiend(1)/ifstep)
  i2 = nint(fiend(2)/ifstep)
  ic = nint(cent/ifstep)
  do irec=1, 2
    do i= j1, j2
      wifl(i,1,irec) = wifl(i,1,irec)+abs(i2-i1)-abs(ic-i)
    enddo
  enddo
  if (ncont.gt.0) then
    call astro_message(seve%i,rname,'Covering continuum tables ...')
    do i=1, ncont
      irec = nint(contfr(1,i)/135000d0)
      flo1 = ftune(irec)-jsky(irec)*(flo2(irec)-cent)
      do j=1, ncfr(i), 2
        ! print *,'i, j, flo1, FLO2(IREC), CONTFR(J,I), CONTFR(J+1,I) '
        ! print *, i, j, flo1, FLO2(IREC), CONTFR(J,I), CONTFR(J+1,I)
        if (contfr(j,i).lt.flo1 .and. contfr(j+1,i).gt.flo1) then
          f2 = flo2(irec)
          f1 = max(0.d0, flo2(irec) -max(flo1-contfr(j,i),contfr(j+1,i)-flo1))
        else
          f1 = max(0.d0,flo2(irec) - abs(contfr(j,i)-flo1))
          f2 = max(0.d0,flo2(irec) - abs(contfr(j+1,i)-flo1))
        endif
        ! print *, 'cont i, irec, j, f1, f2 ', i, irec, j, f1, f2
        if1 = nint(f1/ifstep)
        if2 = nint(f2/ifstep)
        k1 = max(j1,min(if1,if2))
        k2 = min(j2,max(if1,if2))
        ! print *, 'cont i ,irec, k1, k2 ',  i ,irec, k1, k2
        do k= k1, k2
          !                  WIFL(K,1,IREC) = max(1000,WIFL(K,1,IREC)+1000)
          wifl(k,1,irec) = wifl(k,1,irec)+ 1000
        enddo
      enddo
    enddo
  endif
  !
  ! Now assign correlator units, dropping 10 % of bandwidths,
  ! starting from highest resolution.
  do ibf = 5, 1, -1
    bf = band(ibf)*0.90
    filled = .false.
    do while (.not.filled)
      scoremax = -1e8
      filled = .true.
      do irec=1, 2
        jmax(irec) = j1
        jmin(irec) = j2
        do j = j1, j2
          if (wifl(j,ibf,irec).gt.0) then
            jmax(irec)  = max(j,jmax(irec) )
            jmin(irec)  = min(j,jmin(irec) )
          endif
        enddo
        ! print *, ibf, irec, JMIN(irec), jmax(irec)
        ! in that case irec needs more units;
        if (jmin(irec).le.jmax(irec)) then
          filled = .false.
          do j = jmin(irec), jmax(irec)
            k1 = max(j1,j-nint(0.5*bf/ifstep))
            k2 = min(j2,j+nint(0.5*bf/ifstep))
            score = 0
            do k=k1, k2
              score=score+wifl(k,ibf,irec)
            enddo
            ! print *, 'j, score ', j, score
            if (score.gt.scoremax) then
              scoremax=score
              jm = j
              jrec = irec
            endif
          enddo
        endif
      enddo
      ! add one unit to receiver JREC at position JM if needed:
      if (.not.filled) then
        if (nspec.lt.mspec) then
          nspec = nspec+1
          iband(nspec) = band(ibf)
          flo3(nspec) = 0.625*nint(jm*ifstep/0.625)
          krec(nspec) = jrec
          k1 = max(j1,jm-nint(0.5*bf/ifstep))
          k2 = min(j2,jm+nint(0.5*bf/ifstep))
          do ibf2 = 1, 5
            do k=k1, k2
              wifl(k,ibf2,jrec) = 0    ! -10000
            enddo
          enddo
          print 1001, ' SPECTRAL ',nspec,iband(nspec),flo3(nspec),krec(nspec)
          1001 format(a10,i2,i4,f8.3,' /RECEIVER ',i2)
          ! we stop if no more units, with a warning.
        else
          call astro_message(seve%w,rname,'Not enough corr. units !')
          filled = .true.
        endif
      endif
    enddo
  enddo
  !
  ! 10 MHz check
  do i=1, mspec
    if (iband(i).eq.10 .and. i.ne.5) then
      k = iband(5)
      iband(5) = iband(i)
      iband(i) = k
      f1 = flo3(5)
      flo3(5) = flo3(i)
      flo3(i) = f1
      k = krec(5)
      krec(5) = krec(i)
      krec(i) = k
    endif
  enddo
  !
  if (first) then
    call sic_def_charn('LINE_C',cline,1,2,.false.,error)
    call sic_def_dble('LINE_F',ftune,1,2,.false.,error)
    call sic_def_charn('LINE_SB',csky,1,2,.false.,error)
    call sic_def_charn('LINE_TUN',ctun,1,2,.false.,error)
    call sic_def_inte('LINE_H',jharm,1,2,.false.,error)
    call sic_def_inte('SPEC_N',nspec,1,1,.false.,error)
    call sic_def_inte('SPEC_R',krec,1,mspec,.false.,error)
    call sic_def_inte('SPEC_B',iband,1,mspec,.false.,error)
    call sic_def_dble('SPEC_F',flo3,1,mspec,.false.,error)
    first = .false.
  endif
  return
  900   error = .true.
  call astro_message(seve%f,rname,'error reading frequencies')
  return
end subroutine line_auto
!
subroutine name_it(name,i,ch,lch)
  !---------------------------------------------------------------------
  ! @ private
  !---------------------------------------------------------------------
  character(len=*):: name           !
  integer(kind=4) :: i              !
  character(len=*):: ch             !
  integer(kind=4) :: lch            !
  ! Global
  integer(kind=4) :: lenc
  !
  lch = lenc(name)
  ch = name(1:lch)//'_'
  if (i.lt.10) then
    write(ch(lch+2:),'(i1)') i
  elseif (i.lt.100) then
    write(ch(lch+2:),'(i2)') i
  elseif (i.lt.1000) then
    write(ch(lch+2:),'(i3)') i
  endif
  lch = lenc(ch)
  return
end subroutine name_it
