subroutine noema_spectral_sweep(line,error)
  use gbl_message
  use gkernel_interfaces
  use astro_interfaces, except_this=>noema_spectral_sweep
  use astro_types
  use ast_astro
  use my_receiver_globals
  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 :: 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
  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 noema_reset_spsweep(ssweep,error)
  if (error) return
  !
  !Define receiver parameters
  call astro_def_receiver(rname,'NOEMA',ssweep%out%srdesc,error)
  if (error) return
  ! Put in memory the current ASTRO%SOURCE parameters
  ssweep%out%srdesc%redshift = .true. ! tuning takes into accound source redshift
  call astro_def_recsource(rname,ssweep%out%srdesc,ssweep%out%srsou,error)
  if (error) return
  !
  ! 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
  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=2
  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 noema_sweep_range(rname,ssweep,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 ssweep of',ssweep%in%n_tunings, & 
                                  'tunings aligned on',ssweep%in%restref,'MHz',ssweep%in%align
    call astro_message(seve%i,rname,mess)
    call noema_sweep_number(rname,ssweep,error)
    if (error) return
  else
    call astro_message(seve%i,rname,'NOTHING TO DO')
    error=.true.
    return
  endif
  !
  ! Allocate spectral sweep output
  allocate(ssweep%out%sspw(ssweep%in%n_tunings),ssweep%out%sifproc(ssweep%in%n_tunings), &
            ssweep%out%spfx(ssweep%in%n_tunings),stat=ier)
  if (ier.ne.0) then
    call astro_message(seve%e,rname,'Problem allocating structure dimensions')
    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%sifproc(is),error)
    if (error) return
    call noema_ifproc(rname,ssweep%out%srdesc,ssweep%out%srtune(is),ssweep%out%sifproc(is),error)
    if (error) return
    ! define polyfix and assign if "cables" to correlator units [only input, no mode yet]
    call noema_define_pfx(ssweep%out%spfx(is),error)
    if (error) return
    call noema_reset_backend(ssweep%out%spfx(is),ssweep%out%sspw(is)%out,error)
    if (error) return
    call noema_assign_units(ssweep%out%sifproc(is),ssweep%out%spfx(is),error)
    if (error) return
    do iu=1,ssweep%out%spfx(is)%n_units
      ssweep%out%spfx(is)%unit(iu)%imode=selmode
      call pfx_fixed_spw(rname,ssweep%out%srdesc,ssweep%out%srsou, &  
          ssweep%out%srtune(is),ssweep%out%spfx(is)%unit(iu),ssweep%out%sspw(is),error)
      if (error) return
    enddo !iu
    ! remove empty spw (if there was a reset)
    call noema_compress_spw(ssweep%out%sspw(is)%out,error)
    if (error) return
    ! sort spw
    ! Use temporary spw2 as buffer for sorting
    spw2%out=ssweep%out%sspw(is)%out
    call noema_sort_spw(spw2%out,error)
    ssweep%out%sspw(is)%out=spw2%out
    if (error) return
    ! look for conflicts
    call noema_check_conflicts(rname,ssweep%out%sspw(is)%out,ssweep%out%spfx(is),error)
    if (error) return
  enddo
  !
  ! Do the plot
  call noema_sweep_plot(rname,plotmode,ssweep,molecules,cplot,freq_axis,error)
  if (error) return
  !
  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_print(rname,ssweep%out%srsou,ssweep%out%srtune(is),ssweep%out%spfx(is),ssweep%out%sspw(is) &
                            ,molecules,doonline,dotime,olun,error)
      ier = sic_close(olun)
      if (error) exit
    enddo
    call sic_frelun(olun)
  endif
  !
  deallocate(ssweep%out%srtune,ssweep%out%sspw,ssweep%out%sifproc,ssweep%out%spfx)
  !
end subroutine noema_spectral_sweep
!
subroutine noema_reset_spsweep(ss,error)
  use gbl_message
  use gkernel_interfaces
  use astro_interfaces, except_this=>noema_reset_spsweep
  use astro_types
  !-----------------------------------------------------------------------
  ! @ private
  ! initialize spectral sweep structure
  !-----------------------------------------------------------------------
  type(noema_spsweep_t), intent(inout) :: ss
  logical, intent(inout) :: error
  ! local
  !
  ss%param%tuning_width=0d0
  ss%param%if_width=0d0
  ss%param%couple_width=0d0
  !
  ss%in%rflim(1)=0d0
  ss%in%rflim(2)=0d0
  ss%in%restlim(1)=0d0
  ss%in%restlim(2)=0d0
  ss%in%width=0d0
  ss%in%restref=0d0
  ss%in%rfref=0d0
  ss%in%align='NULL'
  ss%out%iband=0
  ss%in%n_tunings=0
  !
end subroutine noema_reset_spsweep
!
subroutine noema_sweep_range(rname,ssweep,error)
  use gbl_message
  use gkernel_interfaces
  use astro_interfaces, except_this=>noema_sweep_range
  use astro_types
  !-----------------------------------------------------------------------
  ! @ private
  ! find combination of tuning to cover an input range
  !-----------------------------------------------------------------------
  character(len=*), intent(in) :: rname
  type(noema_spsweep_t), intent(inout) :: ssweep ! ssweep description
  logical, intent(inout) :: error
  ! local
  integer(kind=4),parameter :: m_add=2 ! max number of additional tunings to complete the ssweep
  logical :: add_fold(m_add),add_right(m_add)
  integer(kind=4) :: it,ia,n_tune_couple,n_add,band1,band2
  real(kind=8) :: flo,fedge,couplewidth,wleft,check_bandup,ncouple,add_shift_off(m_add)
  real(kind=8) :: percent_freq,percent_tuning
  real(kind=8), parameter :: percent_lim=30d0  !percent of freq in last tuning (to trigger warning)
  character(len=256) :: mess
  !
  ssweep%in%rflim(1) = ssweep%in%restlim(1)*ssweep%out%srsou%dopshift   !MHz
  call rec_find_band(rname,ssweep%out%srdesc,ssweep%in%rflim(1),band1,error)
  if (error) return
  ssweep%in%rflim(2) = ssweep%in%restlim(2)*ssweep%out%srsou%dopshift   !MHz
  call rec_find_band(rname,ssweep%out%srdesc,ssweep%in%rflim(2),band2,error)
  if (error) return
  if (band1.ne.band2) then
    call astro_message(seve%e,rname,'Fmin and Fmax are not in the same receiver band')
    error=.true.
    return
  endif
  ssweep%out%iband=band1
  ssweep%in%width=abs(ssweep%in%rflim(2)-ssweep%in%rflim(1))
  if (ssweep%in%width.le.ssweep%param%if_width) then
    call astro_message(seve%e,rname,'Spectral sweep can be done in a single tuning')
    error=.true.
    return
  endif

  ! Compute number of tuning
  ! Fist full combinations of 2 tunings
  couplewidth=4*ssweep%param%if_width
  ncouple=floor(ssweep%in%width/couplewidth)
  if (ncouple.eq.0) then
    ssweep%in%do_limrange=.false.
  endif
  n_tune_couple=ncouple*2
  ! Then remaining tunings
  wleft=mod(ssweep%in%width,couplewidth)
  check_bandup=ssweep%out%srdesc%rflim(2,ssweep%out%iband)-ssweep%in%rflim(2)+wleft
  n_add=0
  add_fold(1)=.false.
  add_fold(2)=.false.
  add_right(1)=.false.
  add_right(2)=.false.
  add_shift_off(1)=0d0
  add_shift_off(2)=0d0
  if (wleft.lt.ssweep%param%if_width) then
    n_add=1
    add_fold(1)=.true.
    if (check_bandup.lt.ssweep%param%if_width.or.ssweep%in%do_limrange) then
      add_right=.true.
    endif
  else if (wleft.lt.2*ssweep%param%if_width) then
    n_add=2
    if (ncouple.eq.0) then
      if (ssweep%out%srdesc%rflim(2,ssweep%out%iband)-ssweep%in%rflim(1).ge.3*ssweep%param%if_width) then
        add_fold(1)=.false.
      else
        add_fold(1)=.true.
      endif
      if (ssweep%out%srdesc%rflim(2,ssweep%out%iband)-ssweep%in%rflim(1)-ssweep%param%if_width  &
          .ge.3*ssweep%param%if_width) then
        add_fold(2)=.false.
      else
        add_fold(2)=.true.  
      endif
    else
      add_fold(1)=.true.
      add_fold(2)=.true.
    endif
    if (check_bandup.lt.2*ssweep%param%if_width.or.ssweep%in%do_limrange) then 
      add_right(1)=.true.
      add_shift_off(1)=-ssweep%param%if_width
      add_right(2)=.true.
      add_shift_off(2)=0d0
    endif
!     endif
  else if (wleft.lt.3*ssweep%param%if_width) then
    n_add=2
    add_fold(1)=.false.
    if (ncouple.eq.0) then
      if (ssweep%out%srdesc%rflim(2,ssweep%out%iband)-ssweep%in%rflim(1).ge.3*ssweep%param%if_width) then
        add_fold(1)=.false.
      else
        add_fold(1)=.true.
      endif
      if (ssweep%out%srdesc%rflim(2,ssweep%out%iband)-ssweep%in%rflim(1)-ssweep%param%if_width & 
          .ge.3*ssweep%param%if_width) then
        add_fold(2)=.false.
      else
        add_fold(2)=.true.
      endif
    else
      add_fold(2)=.true.
      if (check_bandup.lt.3*ssweep%param%if_width.or.ssweep%in%do_limrange) then 
        add_right(1)=.true.
        add_shift_off(1)=0d0
        add_right(2)=.true.
        add_shift_off(2)=-ssweep%param%if_width
      endif
    endif
  else if (wleft.lt.4*ssweep%param%if_width) then
    n_add=2
    add_fold(1)=.false.
    add_fold(2)=.false.
    if (check_bandup.lt.4*ssweep%param%if_width.or.ssweep%in%do_limrange) then 
      add_right(1)=.true.
      add_shift_off(1)=-ssweep%param%if_width
      add_right(2)=.true.
      add_shift_off(2)=0
    endif
  else
    call astro_message(seve%e,rname,'Problem with wleft')
    error=.true.
    return
  endif
  ssweep%in%n_tunings=ncouple*2+n_add
  allocate(ssweep%out%srtune(ssweep%in%n_tunings))
  ! Start aligned on lower frequency
  fedge=ssweep%in%rflim(1)
  ! Do the full couples of tunings
  do it=1,n_tune_couple
    flo=fedge+ssweep%out%srdesc%iflim(2)
    call noema_sweep_addtuning(rname,ssweep%out,it,flo,error)
    if (error) return
    print *,'Tuning done  #',it
    if (mod(it,2).eq.0) then
      ! even number
      fedge=fedge+ssweep%param%tuning_width
    else
      ! odd number
      fedge=fedge+ssweep%param%if_width
    endif
  enddo
  !
 ! Do the last tunings (0,1 or 2)
  it=n_tune_couple
  if (n_add.gt.0) then
    do ia=1,n_add
      it=it+1
      if (ssweep%in%do_limrange) then
        flo=ssweep%in%rflim(2)-ssweep%out%srdesc%iflim(2)+add_shift_off(ia)
      else
        if (.not.add_right(ia)) then
          ! Not close to band edge
          if (add_fold(ia)) then
            flo=fedge-ssweep%out%srdesc%iflim(1)
          else
            flo=fedge+ssweep%out%srdesc%iflim(2)
          endif
        else
          flo=ssweep%out%srdesc%rflim(2,ssweep%out%iband)-ssweep%out%srdesc%iflim(2)+add_shift_off(ia)
        endif
      endif
      call noema_sweep_addtuning(rname,ssweep%out,it,flo,error)
      if (error) return
      if (ia.eq.1) then
        fedge=fedge+ssweep%param%if_width
      else if (ia.eq.2) then
        fedge=fedge+ssweep%param%tuning_width
      endif
    enddo
  endif
  !
  ! Check if 1 tuning is added for small increase of total coverage
  percent_freq=(wleft-(n_add-1)*ssweep%param%if_width)/ssweep%in%width*100d0
  if (percent_freq.lt.percent_lim) then
    percent_tuning=100d0/(ssweep%in%n_tunings)
    write (mess,'(a,1x,f0.3,1x,a)') 'Last Tuning added to cover missing', & 
                                      wleft-(n_add-1)*ssweep%param%if_width,'MHz'
    call astro_message(seve%w,rname,mess)
    write (mess,'(f0.1,a,1x,f0.1,a)') percent_tuning,'% supplementary time to get' & 
                                      ,percent_freq,'% wider coverage'
    call astro_message(seve%w,rname,mess)    
  endif
  !
end subroutine noema_sweep_range
!
subroutine noema_sweep_addtuning(rname,s_out,it,flo,error)
  use astro_interfaces, except_this=>noema_sweep_addtuning
  use astro_types
  !-----------------------------------------------------------------------
  ! @ private
  ! do tuning #it in a spectral sweep
  !-----------------------------------------------------------------------
  character(len=*), intent(in) :: rname
  type(noema_spsweep_out_t), intent(inout) :: s_out
  integer(kind=4), intent(in) :: it ! id of the current tuning
  real(kind=8), intent(in) :: flo ! LO freq for the tuning
  logical, intent(inout) :: error
  ! local
  type(receiver_comm_t) :: rcomm
  real(kind=8) :: ifcent  !IF position for tuning
  !
  ifcent=(s_out%srdesc%iflim(1)+s_out%srdesc%iflim(2))/2d0
  rcomm%fcent=ifcent
  rcomm%rec_name=s_out%srdesc%name
  write (rcomm%name,'(a,i0)') 'SpecSweep',it
  rcomm%frest=(flo-ifcent)*ghzpermhz/s_out%srsou%dopshift ! back in rest frame
  rcomm%sideband="LSB"  
  call astro_tune_receiver(rname,s_out%srdesc,s_out%srsou,rcomm,s_out%srtune(it),error)
  if (error) return
  !
end subroutine noema_sweep_addtuning
!
subroutine noema_sweep_number(rname,ssweep,error)
  use gbl_message
  use gkernel_interfaces
  use astro_interfaces, except_this=>noema_sweep_number
  use astro_types
  !-----------------------------------------------------------------------
  ! @ private
  ! find combination of tuning to cover an input range
  !-----------------------------------------------------------------------
  character(len=*), intent(in) :: rname
  type(noema_spsweep_t), intent(inout) :: ssweep ! spectral sweep description
  logical, intent(inout) :: error
  ! local
  integer(kind=4) :: it
  real(kind=8) :: flo,fedge
  integer(kind=4) :: n_couple,n_add
  ! Compute width
  n_add=mod(ssweep%in%n_tunings,2)
  n_couple=floor(ssweep%in%n_tunings/2d0)
  if (n_add.eq.0) then
    ssweep%in%width=n_couple*ssweep%param%couple_width
  else if (n_add.eq.1) then
    ssweep%in%width=n_couple*ssweep%param%couple_width+ssweep%param%if_width
  else if (n_add.gt.1) then
    call astro_message(seve%e,rname,'Problem with number of tuning')
    error=.true.
    return
  endif
  !
  ! Compute lowest frequency
  select case (ssweep%in%align)
  case ('MIN')
    fedge=ssweep%in%rfref
  case ('MAX')
    fedge=ssweep%in%rfref-ssweep%in%width
  case ('CENTER')
    fedge=ssweep%in%rfref-ssweep%in%width/2d0
  case default
    call astro_message(seve%e,rname,'Problem with the alignment code')
    error = .true.
    return
  end select  
  ! Check that lowest freq is in the band
  if (fedge.lt.ssweep%out%srdesc%rflim(1,ssweep%out%iband)) then
    call astro_message(seve%e,rname,'Spectral sweep goes to frequency lower thant the band edge')
    error = .true.
    return
  endif
  ssweep%in%rflim(1)=fedge
  ssweep%in%restlim(1)=ssweep%in%rflim(1)/ssweep%out%srsou%dopshift
  !
  ! Check that hisghest freq is in the band
  ssweep%in%rflim(2)=fedge+ssweep%in%width
  ssweep%in%restlim(2)=ssweep%in%rflim(2)/ssweep%out%srsou%dopshift
  if (ssweep%in%rflim(2).gt.ssweep%out%srdesc%rflim(2,ssweep%out%iband)) then
    call astro_message(seve%e,rname,'Spectral sweep goes to frequency higher thant the band edge')
    error = .true.
    return
  endif
  !
  allocate(ssweep%out%srtune(ssweep%in%n_tunings))
  do it=1,ssweep%in%n_tunings
    flo=fedge+ssweep%out%srdesc%iflim(2)
    call noema_sweep_addtuning(rname,ssweep%out,it,flo,error)
    if (error) return
    if (mod(it,2).eq.0.and.ssweep%in%n_tunings.gt.it+1) then
      fedge=fedge+ssweep%param%tuning_width
    else
      fedge=fedge+ssweep%param%if_width
    endif
  enddo
  !
end subroutine noema_sweep_number
!
subroutine noema_sweep_plot(rname,plotmode,ssweep,cata,cplot,drawaxis,error)
  use gbl_message
  use gkernel_interfaces
  use astro_interfaces, except_this=>noema_sweep_plot
  use astro_types
  !-----------------------------------------------------------------------
  ! @ private
  ! Displays the frequency coverage of a multi tuning spectral sweep
  !-----------------------------------------------------------------------
  character(len=*), intent(in)      :: rname
  character(len=*), intent(in) :: plotmode
  type(noema_spsweep_t), intent(inout) :: ssweep ! spectral sweep description
  type(plot_molecules_t), intent(in)   :: cata     !plot known lines from current catalog
  type(current_boxes_t), intent(inout) :: cplot
  type(frequency_axis_t), intent(in) :: drawaxis
  logical, intent(inout) :: error
  ! local
  integer(kind=4)       :: i,j,iband,sb_code(m_sideband),ip,is,it,lmess
  real(kind=8)          :: px,py,yoff,boxsize,frf,xt,yt
  real(kind=8) ::fmin,fmax,maxb,maxs,minb,mins
  real(kind=4) :: smess
  character(len=200)    :: comm,defchar,molchar,mess,mess2
  type(draw_rect_t)     :: sbrect
  type(draw_line_t)     :: line
  type(draw_mark_t)     :: mark
  !
  ! Clear the current window, and ONLY the current window
  call gr_execl('CHANGE DIRECTORY') ! No arg = go to the top directory
  call gr_execl('CLEAR DIRECTORY') ! No arg = clear the whole window
  call gr_exec1('TICKSPACE 0 0 0 0')
  call gr_pen(colour=adefcol,error=error)
  if (error) return
  ! get page info
  call sic_get_dble('page_x',px,error)
  if (error) return
  call sic_get_dble('page_y',py,error)
  if (error) return
  if (px.lt.29) then
    call astro_message(seve%w,rname,'PLOT is optimized for LANDSCAPE orientation of the display')
  endif
  ! set plot parameters
  cplot%nbox = ssweep%in%n_tunings
  do i=1,cplot%nbox
    call rec_reset_box(cplot%box(i),error)
  enddo
  cplot%desc%defchar = 0.4
  write (defchar,'(a,1x,f0.3)') 'SET CHARACTER',cplot%desc%defchar
  cplot%desc%molchar = 0.2
  write (molchar,'(a,1x,f0.3)') 'SET CHARACTER',cplot%desc%molchar
  if (px.gt.25) then
    cplot%desc%smallchar = 0.3
  else if (px.le.25) then
    cplot%desc%smallchar = 0.2
  else
    call astro_message(seve%e,rname,'Problem with page size')
    error = .true.
    return
  endif
  call gr_exec1(defchar)
  yoff = 2d0
  boxsize = min((py-3.d0)/cplot%nbox-yoff,4.)
  !Loop on tunings
  iband=ssweep%out%iband
  !limits of the plot
  if (plotmode.eq.'RECEIVER') then
    fmin=ssweep%out%srdesc%restlim(1,iband)
    fmax=ssweep%out%srdesc%restlim(2,iband)
  else if (plotmode.eq.'RANGE') then
    maxs=-1d3
    mins=1d30
    do it=1,ssweep%in%n_tunings
      maxb=-1d3
      minb=1d30
      do is=1,ssweep%out%sspw(it)%out%n_spw
        if (ssweep%out%sspw(it)%out%win(is)%restmax.gt.maxb)  maxb=ssweep%out%sspw(it)%out%win(is)%restmax
        if (ssweep%out%sspw(it)%out%win(is)%restmin.lt.minb)  minb=ssweep%out%sspw(it)%out%win(is)%restmin
      enddo
      if (maxb.gt.maxs)  maxs=maxb
      if (minb.lt.mins)  mins=minb
    enddo  
    fmin=min(ssweep%in%restlim(1),mins)
    fmax=max(ssweep%in%restlim(2),maxs)
  else
    call astro_message(seve%e,rname,'Problem with Plot Mode')
    error=.true.
    return
  endif
  do i=1,cplot%nbox
    ! Physical description of the box
    cplot%box(i)%phys%sx = px-4.5d0
    cplot%box(i)%phys%sy = boxsize
    cplot%box(i)%phys%xmin = 3d0
    cplot%box(i)%phys%xmax = cplot%box(i)%phys%xmin+cplot%box(i)%phys%sx
    cplot%box(i)%phys%ymax = py-yoff-(i-1)*(boxsize+yoff)
    cplot%box(i)%phys%ymin = cplot%box(i)%phys%ymax-boxsize
    write (comm,'(a,i0)') 'CREATE DIRECTORY BOX',i
    call gr_execl(comm)
    write (comm,'(a,i0)') 'CHANGE DIRECTORY BOX',i
    call gr_execl(comm)
    cplot%box(i)%iband = iband
    !define the box limits in all freq frames
    call rec_def_fbox(fmin,fmax,'REST',cplot%box(i),ssweep%out%srdesc, &
                      ssweep%out%srsou,ssweep%out%srtune(i)%flo1,error)
    if (error) return
    !locate the box
    call rec_locate_fbox(cplot%box(i)%phys,error)
    if (error) return
    if (i.eq.1) then
      call rec_draw_source(rname,ssweep%out%srsou,error)
      if (error) return
    endif
    sbrect%xmin = cplot%box(i)%rest%xmin
    sbrect%xmax = cplot%box(i)%rest%xmax
    sbrect%ymin = cplot%box(i)%rest%ymin
    sbrect%ymax = cplot%box(i)%rest%ymax
    sbrect%col = aavailcol
    call rec_draw_frect(sbrect,cplot%box(i)%rest,error)
    if (error) return
    !ID sidebands
    if (ssweep%out%srdesc%n_sbands.eq.2) then
      sb_code(1) = usb_code !usb first
      sb_code(2) = lsb_code !lsb
    else if (ssweep%out%srdesc%n_sbands.eq.1) then
      sb_code(1) = ssweep%out%srtune(i)%sb_code ! tuned side band for single sideband
    else
      call astro_message(seve%e,rname,'We should have 1 or 2 sidebands')
      error = .true.
      return
    endif
    do j=1,ssweep%out%srdesc%n_sbands
      call if1torf(ssweep%out%srtune(i)%flo1,ssweep%out%srdesc%iflim(2),sb_code(j),frf,error)
      if (error) return
      call rftorest(ssweep%out%srsou%dopshift,frf,sbrect%xmax,error)
      if (error) return
      call if1torf(ssweep%out%srtune(i)%flo1,ssweep%out%srdesc%iflim(1),sb_code(j),frf,error)
      if (error) return
      call rftorest(ssweep%out%srsou%dopshift,frf,sbrect%xmin,error)
      if (error) return
      sbrect%ymin = cplot%box(i)%rest%ymin
      sbrect%ymax = cplot%box(i)%rest%ymax
      sbrect%col = atunedcol
      call rec_draw_frect(sbrect,cplot%box(i)%rest,error)
      if (error) return
    enddo
    !ID areas outside call for proposal
    sbrect%xmin = ssweep%out%srdesc%restlim(1,iband)
    sbrect%xmax = ssweep%out%srdesc%restcall(1,iband)
    sbrect%ymin = cplot%box(i)%rest%ymin
    sbrect%ymax = cplot%box(i)%rest%ymax
    sbrect%col = adefcol
    call rec_draw_hrect(sbrect,cplot%box(i)%rest,error)
    if (error) return
    sbrect%xmax = ssweep%out%srdesc%restlim(2,iband)
    sbrect%xmin = ssweep%out%srdesc%restcall(2,iband)
    sbrect%ymin = cplot%box(i)%rest%ymin
    sbrect%ymax = cplot%box(i)%rest%ymax
    sbrect%col = adefcol
    call rec_draw_hrect(sbrect,cplot%box(i)%rest,error)
    if (error) return
    ! Draw the SPW 
    call noema_sweep_draw_spw(ssweep%out%sspw(i)%out,ssweep%out%spfx(i),cplot,i,cata,drawaxis,error)
    if (error) return
    !Draw the box
    call rec_draw_fbox(cplot,i,drawaxis,error)
    if (error) return
    ! Show the edges of the coverage
    if (ssweep%in%in_range) then
      do ip=1,2
        line%xmax = ssweep%in%restlim(ip)
        line%xmin = ((ssweep%in%restlim(1)+ssweep%in%restlim(2))/2)
        line%ymax = cplot%box(i)%rest%ymin+(cplot%box(i)%rest%ymax-cplot%box(i)%rest%ymin)*0.5
        line%ymin = line%ymax
        line%col   = asweepfcol
        line%dash = 1
        call rec_draw_arrow(line,cplot%box(i)%rest,error)
        if (error) return
      enddo
    endif
    ! show tuning line
    call rec_draw_linetune(ssweep%out%srtune(i),cplot%box(i)%rest,error)
    if (error) return
    if (ssweep%out%srsou%z.ne.0) then
      call gr_pen(colour=azcol,error=error)
      if (error) return
    else
      call gr_pen(colour=adefcol,error=error)
      if (error) return
    endif
    write (comm,'(a,1x,a,1x,a)') 'DRAW TEXT -1.5 0 "',trim(ssweep%out%srdesc%bandname(iband)),'" 5 90 /CHARACTER 4'
    call gr_exec1(comm)
    ! Draw tuning name
    xt=0d0
    yt=2d0
    call rec_make_title(ssweep%out%srtune(i),mess,error)
    if (error) return
    if (ssweep%out%srtune(i)%outlo) then
      call gr_pen(colour=aconflictcol,error=error)
      if (error) return
      write (mess2,'(a,1x,a)') trim(mess),'(out of LO range)'
      call gr_exec1(comm)
    else
      mess2=trim(mess)
      call gr_pen(colour=adefcol,error=error)
      if (error) return
    endif
    write (comm,'(a,1x,f0.3,1x,f0.3,1x,a,1x,a,1x,a)') &
          'DRAW TEXT',xt,yt,'"',trim(mess2),'" 6 0 /CHARACTER 7'
    call gr_exec1(comm)
    call gr_pen(colour=adefcol,error=error)
    if (error) return
    ! plot molecular lines
    call gr_exec1(molchar)
    call rec_draw_molecules(cata,cplot%box(i)%rest,error)
    if (error) return
    ! Draw resolution caption
    if (i.eq.ssweep%in%n_tunings) then
      call gr_exec1(defchar)
      xt=0
      yt=-2*cplot%desc%defchar
      write (mess,'(a,1x,f0.1,1x,a)') 'df =',ssweep%out%sspw(i)%out%win(1)%resol,'kHz'
      call gr_pen(colour=adefcol,error=error)
      if (error) return
      write (comm,'(a,1x,f0.3,1x,f0.3,1x,a,a,a)') 'DRAW TEXT', &
            xt,yt,'"',trim(mess),'" 4 0 /BOX 3'
      call gr_exec1(comm)
      call gr_pen(colour=adefcol,error=error)
      if (error) return
      ! draw the marker
      lmess=len(trim(mess))
      call gtg_charlen(lmess,trim(mess),cplot%desc%defchar,smess,0)
      xt=xt-smess-cplot%desc%defchar
      call noema_spw_getcol(rname,ssweep%out%sspw(i)%out%win(1),ssweep%out%spfx(i) & 
                            ,icol_fill,mark%col,error)
      mark%nside=4
      mark%style=3
      mark%s=cplot%desc%smallchar
      mark%x=xt
      mark%y=-2*cplot%desc%defchar
      mark%ref='BOX'
      mark%iref=3
      call rec_draw_mark(mark,error)
      if (error) return
      mark%col=adefcol
      mark%style=0
      call rec_draw_mark(mark,error)
    endif
    call gr_exec1(defchar)
    call gr_execl('CHANGE DIRECTORY')
    cplot%desc%plotmode = pm_tunedbands
  enddo
  !
end subroutine noema_sweep_plot
!
subroutine noema_sweep_draw_spw(spwout,pfx,cplot,ib,molecules,drawaxis,error)
  use gbl_message
  use gkernel_interfaces
  use astro_interfaces, except_this=>noema_sweep_draw_spw
  use astro_types
  !-----------------------------------------------------------------------
  ! @ private
  ! Draw coverage of spectral units in global view (for spectral sweep)
  !
  !-----------------------------------------------------------------------
  type(spw_output_t), intent(in) :: spwout
  type(pfx_t), intent(in) :: pfx
  type(current_boxes_t), intent(inout) :: cplot
  integer(kind=4), intent(in) :: ib
  type(plot_molecules_t), intent(in) :: molecules
  type(frequency_axis_t), intent(in) :: drawaxis
  logical, intent(inout) :: error
  ! local
  character(len=*), parameter :: rname='PLOT'
  integer(kind=4) :: ispw
  real(kind=8)  :: srect,sbox,soff,spos,yh,yv
  type(draw_rect_t) :: sprec
  character(len=256) :: molchar,defchar
  !
  write (defchar,'(a,1x,f0.3)') 'SET CHARACTER',cplot%desc%defchar
  write (molchar,'(a,1x,f0.3)') 'SET CHARACTER',cplot%desc%molchar

  do ispw=1,spwout%n_spw
    if ((spwout%win(ispw)%restmin.lt.cplot%box(ib)%rest%xmin) &
      .or. (spwout%win(ispw)%restmax.gt.cplot%box(ib)%rest%xmax)) cycle
    ! Parameters for the plot
    sbox=cplot%box(ib)%rest%ymax-cplot%box(ib)%rest%ymin
    soff=3*sbox/50d0
    spos=sbox
    srect=(spos-4d0*soff)/2d0
    ! get color according to SPW mode/resolution
    call noema_spw_getcol(rname,spwout%win(ispw),pfx,icol_fill,sprec%col,error)
    if (error) return
    spos=sbox
    if (spwout%win(ispw)%itype.eq.1) then
      soff=sbox/10d0
    else
      call astro_message(seve%e,rname,'Problem with chunk type')
      error=.true.
      return
    endif
    srect=(spos-4d0*soff)/2d0
    sprec%xmin=spwout%win(ispw)%restmin
    sprec%xmax=spwout%win(ispw)%restmax
    if (spwout%win(ispw)%pol_code.eq.hpol_code) then
      sprec%ymax=spos-soff
      sprec%ymin=sprec%ymax-srect
      yh=(sprec%ymax+sprec%ymin)/2d0
    else if (spwout%win(ispw)%pol_code.eq.vpol_code) then
      sprec%ymin=cplot%box(ib)%rest%ymin+soff
      sprec%ymax=sprec%ymin+srect
      yv=(sprec%ymax+sprec%ymin)/2d0
    else
      call astro_message(seve%e,rname,'Problem with polarizations')
      error=.true.
      return
    endif
    call rec_draw_frect(sprec,cplot%box(ib)%rest,error)
    if (error) return
    call noema_spw_getcol(rname,spwout%win(ispw),pfx,icol_border,sprec%col,error)
    if (error) return
    sprec%dash=1
    call rec_draw_rect(sprec,cplot%box(ib)%rest,error)
    if (error) return
  enddo ! ispw
  ! Draw molecules
  call gr_exec1(molchar)
  call rec_draw_molecules(molecules,cplot%box(ib)%rest,error)
  if (error) return
  call gr_exec1(defchar)
  call rec_draw_fbox(cplot,ib,drawaxis,error)
  if (error) return
  call gr_pen(colour=adefcol,error=error)
  if (error) return
  !
end subroutine noema_sweep_draw_spw
