subroutine noema_spectral_sweep(line,error)
  use gbl_message
  use gkernel_interfaces
  use astro_interfaces, except_this=>noema_spectral_sweep
  use ast_astro
  use my_receiver_globals
  use astro_specsweep_types
  use plot_molecules_globals
  use frequency_axis_globals
  !-----------------------------------------------------------------------
  ! @ private
  ! Command to prepare multi-tuning spectral observations with NOEMA
  !-----------------------------------------------------------------------
  character(len=*), intent(inout) :: line        ! command line
  logical, intent(inout) :: error
  ! local
  character(len=*), parameter :: rname='SPECSWEEP'
  integer(kind=4), parameter :: i_optrange=1
  integer(kind=4), parameter :: i_optmaxband=2
  integer(kind=4), parameter :: i_optntuning=3
  integer(kind=4), parameter :: i_optzoom=4
  integer(kind=4), parameter :: i_optfile=5
  integer(kind=4), parameter :: i_optadd=6
  integer(kind=4), parameter :: margrange=2
  integer(kind=4), parameter :: margntuning=3
  logical, parameter :: doonline=.false.
  logical, parameter :: dotime=.false.
  real(kind=4), parameter :: resmed=250.0
  real(kind=4), parameter :: reslow=2000.0
  real(kind=4), parameter :: reshigh1=62.50
  real(kind=4) :: resuser
  type(noema_spsweep_t) :: ssweep
  real(kind=8) :: fs1,fs2
  character(len=filename_length) :: file,argum,file2
  integer(kind=4),parameter :: m_add=2 ! max number of additional tunings to complete the spectral sweep
  logical :: dorange,dontuning,dozoom,dofile,doadd
  integer(kind=4) :: nkey,lpar,is,iu,selmode,pmode,nplot,ier,nchar,olun
  integer(kind=4), parameter :: mkeys=3
  character(len=16) :: keys(mkeys),par,plotmode
  character(len=256) :: mess
  data keys/'MIN','CENTER','MAX'/ 
  integer(kind=4), parameter :: mp=2 ! plot modes
  character(len=16) :: plotmodes(mp)
  data plotmodes/'RECEIVER','RANGE'/
  !
  error=.false.
  !
  if (obsname.ne.'NOEMA') then
    call astro_message(seve%e,rname,'Inconsistency between Receiver Name and Observatory')
    error = .true.
    return
  endif
  !
  ! Reset Sweep structure
  call ssweep%reset(error)
  if (error) return
  !
  !Define receiver parameters
  call astro_def_receiver(rname,'NOEMA',ssweep%out%srdesc,error)
  if (error) return
  ssweep%out%srdesc%redshift = .true. ! tuning takes into accound source redshift
  if (.not.noema%recdesc%defined) noema%recdesc=ssweep%out%srdesc
  !Define source parameters
  call astro_def_recsource(rname,ssweep%out%srdesc,ssweep%out%srsou,error)
  if (error) return
  if (.not.noema%source%defined) noema%source=ssweep%out%srsou
  !
  ! Hardware related parameters
  ssweep%param%if_width=ssweep%out%srdesc%iflim(2)-ssweep%out%srdesc%iflim(1) ! 
  ssweep%param%tuning_width=2*ssweep%out%srdesc%iflim(2) ! 
  ssweep%param%couple_width=4*ssweep%param%if_width ! 
  !
  !Decoding Line Command
  doadd=sic_present(i_optadd,0) ! add to register
  dozoom=sic_present(i_optzoom,0)
  dorange=sic_present(i_optrange,0)
  dontuning=sic_present(i_optntuning,0)
  if (dorange.and.dontuning) then
    call astro_message(seve%e,rname,'Options /RANGE and /NTUNING are exclusive from each other')
    error=.true.
    return
  endif
  ! Output file
  dofile=sic_present(i_optfile,0)
  if (dofile) then
    call sic_ch(line,i_optfile,1,argum,nchar,.true.,error)
    if (error)  return
  endif
  ! Zoom
  pmode=2
  if (dozoom) then
    call sic_ke(line,i_optzoom,1,par,lpar,.false.,error)
    if (error) return
    call sic_ambigs_sub(rname,par,plotmode,nplot,plotmodes,mp,error)
    if (error) return
    if (nplot.ne.0) then
      pmode=nplot
    endif
  endif
  plotmode=plotmodes(pmode)
  ! Tuning parameters
  ssweep%in%do_limrange=.true.
  if (sic_present(i_optmaxband,0)) then
    if (.not.dorange) then
      call astro_message(seve%i,rname,'Option /BANDMAX ignored: can be combined with /RANGE only')
    else
      ssweep%in%do_limrange=.false.
    endif
  endif
  ! Command argument to define spectral mode
  resuser=2000.
  call sic_r4(line,0,1,resuser,.false.,error)
  if (error) return
  !
  if (resuser.eq.reshigh1) then
    call astro_message(seve%e,rname,'High Res coverage not implemented yet')
    error=.true.
    return
  else if  (resuser.eq.reslow) then
    selmode=1  
  else if  (resuser.eq.resmed) then
    selmode=3
  else
    call astro_message(seve%e,rname,'Entered resolution does not match any correlator mode')
    error=.true.
    return
  endif
  !
  ! Find and define the tunings
  if (dorange) then
    ssweep%in%in_range=.true.
    ssweep%in%in_ntune=.false.
    ! Sweep defined by frequency limits
    if (sic_narg(i_optrange).gt.margrange) then
      call astro_message(seve%e,rname,'Too many arguments')
      error=.true.
      return
    else  if (sic_narg(i_optrange).lt.margrange) then
      call astro_message(seve%i,rname,'Not enough arguments')
      error=.true.
      return
    endif
    ! Get limits in the command line
    call sic_r8(line,i_optrange,1,fs1,.true.,error)
    if (error) return
    call sic_r8(line,i_optrange,2,fs2,.true.,error)
    if (error) return
    if (fs1.ge.fs2) then
      call astro_message(seve%e,rname,'Please enter lower then higher frequency')
      error=.true.
      return
    endif
    fs1=fs1*mhzperghz
    call rec_inputtorest(rname,fs1,freq_axis%main,ssweep%out%srsou,ssweep%in%restlim(1),error)
    if (error) return    
    fs2=fs2*mhzperghz
    call rec_inputtorest(rname,fs2,freq_axis%main,ssweep%out%srsou,ssweep%in%restlim(2),error)
    if (error) return   
    call ssweep%dorange(error)
    if (error) return
  else if (dontuning) then
    ssweep%in%in_range=.false.
    ssweep%in%in_ntune=.true.
    ! Sweep defined with number of tunings
    ! Get requested number of tuning in the command line
    call sic_i4(line,i_optntuning,1,ssweep%in%n_tunings,.true.,error)
    if (error) return
    if (ssweep%in%n_tunings.lt.2) then
      call astro_message(seve%e,rname,'Spectral sweep requests at least 2 tunings')
      error=.true.
      return
    endif
    ! Get frequency for position of spectral sweep
    call sic_r8(line,i_optntuning,2,fs1,.true.,error)
    if (error) return
    fs1=fs1*mhzperghz
    call rec_inputtorest(rname,fs1,freq_axis%main,ssweep%out%srsou,ssweep%in%restref,error)
    if (error) return
    ssweep%in%rfref = ssweep%in%restref*ssweep%out%srsou%dopshift
    call rec_find_band(rname,ssweep%out%srdesc,ssweep%in%rfref,ssweep%out%iband,error)
    if (error) return
    ! Get code for alignement
    par='MIN'
    call sic_ke(line,i_optntuning,3,par,lpar,.false.,error)
    if (error) return
    call sic_ambigs(rname,par,ssweep%in%align,nkey,keys,mkeys,error)
    if (error) return
    write (mess,'(a,1x,i0,1x,a,1x,f0.3,1x,a,1x,a)') 'Preparing sweep of',ssweep%in%n_tunings, & 
                                  'tunings aligned on',ssweep%in%restref,'MHz',ssweep%in%align
    call astro_message(seve%i,rname,mess)
    call ssweep%donumber(error)
    if (error) return
  else
    call astro_message(seve%i,rname,'NOTHING TO DO')
    error=.true.
    return
  endif
  !  
  ! Define the IFdistribution and the backend
  do is=1,ssweep%in%n_tunings
    !Define ifproc parameters
    call rec_define_noema_ifproc(ssweep%out%sfebe(is)%i_f%ifproc,error)
    if (error) return
    call noema_ifproc(rname,ssweep%out%srdesc,ssweep%out%sfebe(is)%rectune,ssweep%out%sfebe(is)%i_f%ifproc,error)
    if (error) return
    ! define polyfix and assign if "cables" to correlator units [only input, no mode yet]
    call noema_define_pfx(ssweep%out%sfebe(is)%pfx,error)
    if (error) return
    call noema_reset_backend(ssweep%out%sfebe(is)%pfx,ssweep%out%sfebe(is)%spw%out,error)
    if (error) return
    call noema_assign_units(rname,ssweep%out%sfebe(is)%i_f%ifproc,ssweep%out%sfebe(is)%pfx,ssweep%out%srdesc,error)
    if (error) return
    do iu=1,ssweep%out%sfebe(is)%pfx%n_units
      ssweep%out%sfebe(is)%pfx%unit(iu)%imode=selmode
      call pfx_fixed_spw(rname,ssweep%out%srdesc,ssweep%out%srsou, &  
          ssweep%out%sfebe(is)%rectune,ssweep%out%sfebe(is)%pfx%unit(iu),ssweep%out%sfebe(is)%spw,error)
      if (error) return
    enddo !iu
    ! remove empty spw (if there was a reset)
    call noema_compress_spw(ssweep%out%sfebe(is)%spw%out,error)
    if (error) return
    ! sort spw
    ! Use temporary spw2 as buffer for sorting
    spw2%out=ssweep%out%sfebe(is)%spw%out
    call noema_sort_spw2(spw2%out,error)
    ssweep%out%sfebe(is)%spw%out=spw2%out
    if (error) return
    ! look for conflicts
    call noema_check_conflicts(rname,ssweep%out%sfebe(is)%spw%out,ssweep%out%sfebe(is)%pfx,error)
    if (error) return
  enddo
  !
  ! Do the plot
  call ssweep%plot(plotmode,molecules,cplot,freq_axis,error)
  if (error) return
  !
  if (doadd) then
    call noema%register%reallocate(m_register_alloc,error)
    if (error) return
    !Check that N_TUNINGS will fit in REGISTER
    if (noema%register%n_saved+ssweep%in%n_tunings.gt.noema%register%m_saved) then
      call astro_message(seve%e,rname,'Not enough free slots in register to save all FEBEs. Nothing Saved')
      error=.true.
      return
    endif
    do is=1,ssweep%in%n_tunings
      ! Add the febes to the register
      call noema%register%add(ssweep%out%sfebe(is),error)
      if (error) return
    enddo
  endif
  !
  if (dofile) then
    ! Print in files to be uploaded in SMS
    ier = sic_getlun(olun) !find a unit number
    if (ier.ne.1) then
      call astro_message(seve%e,rname,'No logical unit left')
      error = .true.
      return
    endif
    do is=1,ssweep%in%n_tunings  
      file2=""
      file=""
      write (file2,'(a,a,i0)') trim(argum),'-',is
      call sic_parse_file(file2,' ','.astro',file)
      ier = sic_open(olun,file,'NEW',.false.)
      if (ier.ne.0) then
        call astro_message(seve%e,rname,'Cannot open file '//file)
        error = .true.
        call sic_frelun(olun)
        return
      endif
      call noema_setup_check(rname,ssweep%out%srsou,ssweep%out%sfebe(is), & 
                          doonline,error)
      if (error) return
      call noema_setup_source(rname,ssweep%out%srsou,doonline,dotime,olun,error)
      if (error) return
      call noema_setup_print(rname,ssweep%out%srsou,ssweep%out%sfebe(is), &
                                molecules,doonline,olun,error)
      ier = sic_close(olun)
      if (error) exit
    enddo
    call sic_frelun(olun)
  endif
  !
  call ssweep%free(error)
  !
end subroutine noema_spectral_sweep
