module astro_specsweep_types
  use gbl_message
  use astro_types
  !
  public
  private :: specsweep_reallocate
  ! For spectral sweep tool
  type noema_spsweep_in_t
    logical :: in_range=.false.
    logical :: in_ntune=.false.
    ! Range mode
    real(kind=8) :: restlim(2)=[undef_freq,undef_freq] ! frequency limits in rest
    real(kind=8) :: rflim(2)=[undef_freq,undef_freq] ! frequency limits in rf
    real(kind=8) :: width=undef_freq
    logical :: do_limrange
    ! n tuning mode
    integer(kind=4) :: n_tunings=undef_freq ! integer number of tuning to co
    real(kind=8) :: restref=undef_freq     ! frequency to align the tuning
    real(kind=8) :: rfref=undef_freq     ! frequency to align the tuning, in RF
    character(len=8) :: align='MIN'   ! how to align tuning on ref freq
  end type noema_spsweep_in_t
  !
  type noema_spsweep_param_t
    real(kind=8) :: tuning_width=undef_freq
    real(kind=8) :: if_width=undef_freq !
    real(kind=8) :: couple_width=undef_freq
  end type noema_spsweep_param_t
  !
  type noema_spsweep_out_t
    integer(kind=4)    :: iband=0             ! band where sweep is done
    type(receiver_source_t) :: srsou
    type(receiver_desc_t)    :: srdesc                 ! receiver type = source, desc, and n_tunings
    integer(kind=4)         :: n_sweep=0
    type(noema_febe_t), allocatable :: sfebe(:)
  contains
    procedure, public :: addtuning => noema_specsweep_addtuning
  end type noema_spsweep_out_t
  !
  type noema_spsweep_t
    type(noema_spsweep_in_t) :: in
    type(noema_spsweep_param_t) :: param
    type(noema_spsweep_out_t) :: out
  contains
    procedure, public :: free => specsweep_free
    procedure, public :: reallocate => specsweep_reallocate
    procedure, public :: reset => noema_reset_spsweep
    procedure, public :: dorange => noema_specsweep_range
    procedure, public :: donumber => noema_specsweep_number
    procedure, public :: plot => noema_specsweep_plot
  end type noema_spsweep_t
  !
contains
  subroutine specsweep_reallocate(specsweep,n_sweep,error)
    use gkernel_interfaces
    !-----------------------------------------------------------------------
    ! allocate sweep structure to the right size
    !-----------------------------------------------------------------------
    class(noema_spsweep_t), intent(inout) :: specsweep
    integer(kind=4), intent(in) :: n_sweep
    logical, intent(inout)      :: error
    !
    character(len=*), parameter :: rname='SPECSWEEP>REALLOCATE'
    integer(kind=4) :: ier
    logical         :: alloc
    !
    alloc=.true.
    ! First check if alloc already
    if (allocated(specsweep%out%sfebe)) then
      if (specsweep%out%n_sweep.eq.n_sweep) then
        ! Already allocated at the right size
        alloc = .false.
      else
        ! Not the right size: deallocate
        call specsweep%free(error)
        if (error) return
        alloc=.true.
      endif
    endif
    if (alloc) then
      ! Allocate to right size
      allocate(specsweep%out%sfebe(n_sweep),stat=ier)
      if (failed_allocate(rname,'SPECSWEEP SIZE',ier,error))  return
      specsweep%out%n_sweep=n_sweep
    endif
    !
  end subroutine specsweep_reallocate
  !
  subroutine specsweep_free(specsweep,error)
    ! Deallocate pfx%unit
    class(noema_spsweep_t), intent(inout) :: specsweep
    logical, intent(inout)      :: error
    !
    if (allocated(specsweep%out%sfebe)) deallocate(specsweep%out%sfebe)
    !
  end subroutine specsweep_free
  !
  subroutine noema_reset_spsweep(specsweep,error)
    use gkernel_interfaces
    !-----------------------------------------------------------------------
    ! initialize spectral sweep structure (mainly inputs defaults)
    !-----------------------------------------------------------------------
    class(noema_spsweep_t), intent(inout) :: specsweep
    logical, intent(inout) :: error
    ! local
    character(len=*), parameter :: rname='SPECSWEEP>RESET'
    !
    specsweep%param%tuning_width=0d0
    specsweep%param%if_width=0d0
    specsweep%param%couple_width=0d0
    !
    specsweep%in%rflim(1)=0d0
    specsweep%in%rflim(2)=0d0
    specsweep%in%restlim(1)=0d0
    specsweep%in%restlim(2)=0d0
    specsweep%in%width=0d0
    specsweep%in%restref=0d0
    specsweep%in%rfref=0d0
    specsweep%in%align='NULL'
    specsweep%in%n_tunings=0
    !
    specsweep%out%iband=0
    specsweep%out%n_sweep=0
    !
  end subroutine noema_reset_spsweep
  !
  subroutine noema_specsweep_range(ssweep,error)
    use gkernel_interfaces
    !-----------------------------------------------------------------------
    ! find combination of tuning to cover an input range
    !-----------------------------------------------------------------------
    class(noema_spsweep_t), intent(inout) :: ssweep ! ssweep description
    logical, intent(inout) :: error
    ! local
    character(len=*), parameter :: rname='SPECSWEEP>DORANGE'
    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 the structure
    call ssweep%reallocate(ssweep%in%n_tunings,error)
    if (error) return
    ! 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 ssweep%out%addtuning(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 ssweep%out%addtuning(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_specsweep_range
  !
  subroutine noema_specsweep_addtuning(s_out,it,flo,error)
    !-----------------------------------------------------------------------
    ! do tuning #it in a spectral sweep
    !-----------------------------------------------------------------------
    class(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
    character(len=*), parameter :: rname='SPECSWEEP>ADDTUNING'
    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%sfebe(it)%rectune,error)
    if (error) return
    s_out%sfebe(it)%defined=.true.
    s_out%sfebe(it)%rectune%ongrid=.false.
    !
  end subroutine noema_specsweep_addtuning
  !
  subroutine noema_specsweep_number(ssweep,error)
    use gkernel_interfaces
    !-----------------------------------------------------------------------
    ! find combination of tuning to cover an input range
    !-----------------------------------------------------------------------
    class(noema_spsweep_t), intent(inout) :: ssweep ! spectral sweep description
    logical, intent(inout) :: error
    ! local
    character(len=*),parameter :: rname='SPECSWEEP>DONUMBER'
    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 than 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 than the band edge')
        error = .true.
        return
    endif
    !
    ! Allocate the structure
    call ssweep%reallocate(ssweep%in%n_tunings,error)
    if (error) return
    !
    do it=1,ssweep%in%n_tunings
        flo=fedge+ssweep%out%srdesc%iflim(2)
        call ssweep%out%addtuning(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_specsweep_number
  !
  subroutine noema_specsweep_plot(ssweep,plotmode,cata,cplot,drawaxis,error)
    use gkernel_interfaces
    !-----------------------------------------------------------------------
    ! Displays the frequency coverage of a multi tuning spectral sweep
    !-----------------------------------------------------------------------
    class(noema_spsweep_t), intent(inout) :: ssweep ! spectral sweep description
    character(len=*), intent(in) :: plotmode
    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
    character(len=*), parameter      :: rname='SPECSWEEP>PLOT'
    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%sfebe(it)%spw%out%n_spw
            if (ssweep%out%sfebe(it)%spw%out%win(is)%restmax.gt.maxb)  maxb=ssweep%out%sfebe(it)%spw%out%win(is)%restmax
            if (ssweep%out%sfebe(it)%spw%out%win(is)%restmin.lt.minb)  minb=ssweep%out%sfebe(it)%spw%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%sfebe(i)%rectune%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%sfebe(i)%rectune%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%sfebe(i)%rectune%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%sfebe(i)%rectune%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%sfebe(i)%spw%out,ssweep%out%sfebe(i)%pfx,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.and.plotmode.eq.'RECEIVER') 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%sfebe(i)%rectune,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%sfebe(i)%rectune,mess,error)
        if (error) return
        if (ssweep%out%sfebe(i)%rectune%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%sfebe(i)%spw%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%sfebe(i)%spw%out%win(1),ssweep%out%sfebe(i)%pfx &
                                ,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_specsweep_plot
  !
  subroutine noema_sweep_draw_spw(spwout,pfx,cplot,ib,molecules,drawaxis,error)
    use gkernel_interfaces
    !-----------------------------------------------------------------------
    ! 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
        soff=sbox/10d0
        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
  !
end module astro_specsweep_types
