!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! Setup On-The-Fly observing mode
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
begin procedure 30m-setup-otf-definitions
  if .not.exist(setup30m%otf) then
     define structure setup30m%otf /global
  endif
  !
  if .not.exist(setup30m%otf%inp) then
     define structure setup30m%otf%inp /global
     define double setup30m%otf%inp%size[2] setup30m%otf%inp%center[2] setup30m%otf%inp%angle /global
     define double setup30m%otf%inp%maxtime_betweencal setup30m%otf%inp%stabtime setup30m%otf%inp%dumptime /global
     define double setup30m%otf%inp%freq /global
     define integer setup30m%otf%inp%beamsampling /global
     define logical setup30m%otf%inp%overtime /global
     define character setup30m%otf%inp%source*12 /global
     define integer setup30m%otf%inp%filestart /global
     !
     define command 30MSETUP\OTFTIME  "@ 30m-setup-otf-time"
     define command 30MSETUP\OTFGEO   "@ 30m-setup-otf-geo"
     define command 30MSETUP\OTFINPUT "@ 30m-setup-otf-input"
     define command 30MSETUP\OTFPRO   "@ 30m-setup-otf-pro"
     define command 30MSETUP\OTFVIEW  "@ 30m-setup-otf-view-all"
     define command 30MSETUP\OTFHARD  "@ 30m-setup-otf-hard"
  endif
  !
  if .not.exist(setup30m%otf%out) then
     define structure setup30m%otf%out /global
     define double setup30m%otf%out%fwhm setup30m%otf%out%beam_area setup30m%otf%out%sampling /global
     !
     define structure setup30m%otf%out%numb /global
     define integer setup30m%otf%out%numb%dump[2] setup30m%otf%out%numb%ref_per_loop[2] setup30m%otf%out%numb%line_per_loop[2] /global
     define integer setup30m%otf%out%numb%loop_per_fullscan[2] setup30m%otf%out%numb%fullscan_per_cov[2] setup30m%otf%out%numb%line_per_cov[2] /global
     define integer setup30m%otf%out%numb%residual_lines[2] setup30m%otf%out%numb%cal_per_cov[2] /global
     !
     define structure setup30m%otf%out%time /global
     define double setup30m%otf%out%time%phase[2] setup30m%otf%out%time%dump[2] setup30m%otf%out%time%ref[2] setup30m%otf%out%time%otf[2] /global
     define double setup30m%otf%out%time%cal[2] setup30m%otf%out%time%loop[2] setup30m%otf%out%time%fullscan[2] /global
     define double setup30m%otf%out%time%residual[2] setup30m%otf%out%time%totcal[2] setup30m%otf%out%time%cov[2] /global
     define double setup30m%otf%out%time%betweenref[2] /global
     !
     define structure setup30m%otf%out%line /global
     define double setup30m%otf%out%line%length[2] /global
     define double setup30m%otf%out%line%numb[2] /global
     !
     define structure setup30m%otf%out%on /global
     define double setup30m%otf%out%on%slewvelo[2] setup30m%otf%out%on%areavelo[2] /global
     define double setup30m%otf%out%on%beamsampling[2] setup30m%otf%out%on%areasubmap[2] /global
     define integer setup30m%otf%out%on%peroff[2] /global
     !
     define structure setup30m%otf%out%geo /global
     define double setup30m%otf%out%geo%angle setup30m%otf%out%geo%beg[2] setup30m%otf%out%geo%end[2] setup30m%otf%out%geo%step[2] /global
     define integer setup30m%otf%out%geo%iscan setup30m%otf%out%geo%iperp /global
  endif
  !
  if .not.exist(scandirs) then
     define structure scandirs /global
     define integer scandirs%lamb scandirs%beta /global
     define character scandirs%names*6[2] /global
     let scandirs%lamb 1
     let scandirs%beta 2
     let scandirs%names "lambda" "beta"
  endif
  !
  if .not.exist(setup30m%otf%view) then
     define structure setup30m%otf%view /global
     define logical setup30m%otf%view%off setup30m%otf%view%coverage /global
     define logical setup30m%otf%view%scans setup30m%otf%view%subscans /global
     let setup30m%otf%view%off yes
     let setup30m%otf%view%coverage yes
     let setup30m%otf%view%scans yes
     let setup30m%otf%view%subscans yes
  endif
end procedure 30m-setup-otf-definitions
!
begin procedure 30m-setup-otf-defaults
  let setup30m%otf%inp%source "horsehead" ! [-] Source name to be searched in the souce catalog
  ! Geometry
  let setup30m%otf%inp%size 250 500       ! [arcsec] FoV size
  let setup30m%otf%inp%center 0           ! [arcsec] FoV center
  let setup30m%otf%inp%angle  0           ! [degree] FoV position angle
  let setup30m%otf%inp%overtime yes       ! [-]
  ! Sampling
  let setup30m%otf%inp%freq 116           ! [GHz] Highest observed frequency
  let setup30m%otf%inp%beamsampling 3     ! [points per beam] Number of samples per HPBW
  ! Typical times
  let setup30m%otf%inp%maxtime_betweencal 15 ! [minutes] Maximum time between two consecutive calibrations
  let setup30m%otf%inp%stabtime 120          ! [seconds] Maximum time between two consecutive references
  let setup30m%otf%inp%dumptime 1            ! [s] Integration time per spectrum
  ! Naming scheme
  let setup30m%otf%inp%filestart 0 !
end procedure 30m-setup-otf-defaults
!
begin procedure 30m-setup-otf-reset-out
  ! Telescope-related parameters
  let setup30m%otf%out%fwhm      0.0 ! [arcsec  ] Telescope HPBW 
  let setup30m%otf%out%sampling  0.0 ! [arcsec  ] Sampling step perpendicular to the scanning direction
  let setup30m%otf%out%beam_area 0.0 ! [arcsec^2] Area of a Gaussian beam (gridding is taken into account)
  ! Various numbers
  let setup30m%otf%out%numb%dump                 0 0 ! [-] Lambda and beta 
  let setup30m%otf%out%numb%ref_per_loop         0 0 ! [-] Lambda and beta 
  let setup30m%otf%out%numb%line_per_loop        0 0 ! [-] Lambda and beta 
  let setup30m%otf%out%numb%loop_per_fullscan    0 0 ! [-] Lambda and beta 
  let setup30m%otf%out%numb%fullscan_per_cov     0 0 ! [-] Lambda and beta 
  let setup30m%otf%out%numb%line_per_cov         0 0 ! [-] Lambda and beta 
  let setup30m%otf%out%numb%residual_lines       0 0 ! [-] Lambda and beta 
  let setup30m%otf%out%numb%cal_per_cov          0 0 ! [-] Lambda and beta 
  ! Various timescales
  let setup30m%otf%out%time%phase         0.0 0.0 ! [s] Lambda and beta time per phase
  let setup30m%otf%out%time%dump          0.0 0.0 ! [s] Lambda and beta time per final spectrum (combination of phases)
  let setup30m%otf%out%time%ref           0.0 0.0 ! [s] Lambda and beta time spent on reference (OFF subscan)
  let setup30m%otf%out%time%otf           0.0 0.0 ! [s] Lambda and beta time spent on one OTF line (ON subscan)
  let setup30m%otf%out%time%cal          60.0 60.0 ! [s] Lambda and beta time 
  let setup30m%otf%out%time%loop          0.0 0.0 ! [s] Lambda and beta time 
  let setup30m%otf%out%time%fullscan      0.0 0.0 ! [s] Lambda and beta time 
  let setup30m%otf%out%time%residual      0.0 0.0 ! [s] Lambda and beta time 
  let setup30m%otf%out%time%totcal        0.0 0.0 ! [s] Lambda and beta time 
  let setup30m%otf%out%time%cov           0.0 0.0 ! [s] Lambda and beta time 
  let setup30m%otf%out%time%betweenref    0.0 0.0 ! [s] Lambda and beta time 
  ! ON parameters
  let setup30m%otf%out%line%numb          0.0 0.0 ! [----------] Lambda and beta number of lines to cover one submap ???
  let setup30m%otf%out%line%length        0.0 0.0 ! [arcsec    ] Lambda and beta line length
  let setup30m%otf%out%on%slewvelo        0.0 0.0 ! [arcsec/s  ] Lambda and beta slew velocity
  let setup30m%otf%out%on%areavelo        0.0 0.0 ! [arcsec^2/2] Lambda and beta area covered by the telescope per second
  let setup30m%otf%out%on%areasubmap      0.0 0.0 ! [] Lambda and beta
  let setup30m%otf%out%on%beamsampling    0.0 0.0 ! [----------] Lambda and beta
  let setup30m%otf%out%on%peroff          0   0   ! [----------] Lambda and beta number of ON dumps per OFF
  ! OTF map geometry
  let setup30m%otf%out%geo%angle   0.0     ! [] Position angle of the OTF line
  let setup30m%otf%out%geo%beg     0.0 0.0 ! [arcsec] Map bottom left corner
  let setup30m%otf%out%geo%end     0.0 0.0 ! [arcsec] Map top right corner
  let setup30m%otf%out%geo%step    0.0 0.0 ! [arcsec] dX and dY step between two consecutive lines
  let setup30m%otf%out%geo%iscan   scandirs%lamb ! [-] Current scanning direction
  let setup30m%otf%out%geo%iperp   scandirs%beta ! [-] Current perpendicular direction with respect to the scanning direction
end procedure 30m-setup-otf-reset-out
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! User feedback
!
begin procedure 30m-setup-otf-input
  say "Input parameters:"
  say " * Source name: "'setup30m%otf%inp%source'
  say " * Observing mode: "'switch%names[setup30m%switch%mode]'
  if (setup30m%switch%mode.eq.switch%psw) then
     say " * OFF positions [arcsec]: "'setup30m%switch%offpos[1]' 'setup30m%switch%offpos[2]'
  else if (setup30m%switch%mode.eq.switch%fsw) then
     say " * Frequency throw [MHz]: "'setup30m%switch%freqthrow[1]'" "'setup30m%switch%freqthrow[2]'
     say " * Dump time         [s]: "'setup30m%otf%inp%dumptime'
  endif 
  say " * Size   [arcsec]: "'setup30m%otf%inp%size[1]' 'setup30m%otf%inp%size[2]'
  say " * Center [arcsec]: "'setup30m%otf%inp%center[1]' 'setup30m%otf%inp%center[2]'
  say " * Angle  [degree]: "'setup30m%otf%inp%angle'
  say " * Frequency [GHz]: "'setup30m%otf%inp%freq'
  say " * Number of points per beam:       "'setup30m%otf%inp%beamsampling'
  say " * Integration time      [second]:  "'setup30m%otf%inp%dumptime'
  say " * Max time between refs [second]:  "'setup30m%otf%inp%stabtime'
  say " * Max time between cals [minutes]: "'setup30m%otf%inp%maxtime_betweencal'
  say " * Overtime?                        "'setup30m%otf%inp%overtime'  
end procedure 30m-setup-otf-input
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! Engine
!
begin procedure 30m-setup-otf-rot2d
  ! if x = &1[1], y = &1[2] and angle [rad] = &2 
  ! then angle = angle from x to xrot or from y to yrot
  define double xyrot[2]
  let xyrot[1]  &1[1]*cos(&2)+&1[2]*sin(&2)
  let xyrot[2] -&1[1]*sin(&2)+&1[2]*cos(&2)
  let &1 xyrot
end procedure 30m-setup-otf-rot2d
!
begin procedure 30m-setup-otf-geometry
  if (&1.eq.scandirs%lamb) then
     ! Lambda scanning
     let setup30m%otf%out%geo%iscan scandirs%lamb
     let setup30m%otf%out%geo%iperp scandirs%beta
  else
     ! Beta scanning
     let setup30m%otf%out%geo%iscan scandirs%beta
     let setup30m%otf%out%geo%iperp scandirs%lamb
  endif
  ! Take care of rounding effects
  define double size[2]
  let size[1] (setup30m%otf%out%line%numb[2]-1)*setup30m%otf%out%sampling
  let size[2] (setup30m%otf%out%line%numb[1]-1)*setup30m%otf%out%sampling
  ! Scanned coordinates
  let setup30m%otf%out%geo%beg['setup30m%otf%out%geo%iscan'] -0.5*setup30m%otf%out%line%length['setup30m%otf%out%geo%iscan']
  let setup30m%otf%out%geo%end['setup30m%otf%out%geo%iscan'] +0.5*setup30m%otf%out%line%length['setup30m%otf%out%geo%iscan']
  let setup30m%otf%out%geo%step['setup30m%otf%out%geo%iscan'] 0
  ! Perpendicular coordinates
  let setup30m%otf%out%geo%beg['setup30m%otf%out%geo%iperp'] -0.5*size['setup30m%otf%out%geo%iperp']
  let setup30m%otf%out%geo%end['setup30m%otf%out%geo%iperp'] -0.5*size['setup30m%otf%out%geo%iperp']
  if (size['setup30m%otf%out%geo%iperp'].ne.0) then
     let setup30m%otf%out%geo%step['setup30m%otf%out%geo%iperp'] setup30m%otf%out%sampling
  else
     let setup30m%otf%out%geo%step['setup30m%otf%out%geo%iperp'] 0
  endif
  ! Take care of rotation
  let setup30m%otf%out%geo%angle setup30m%otf%inp%angle*3600*sec
  @ 30m-setup-otf-rot2d setup30m%otf%out%geo%beg  'setup30m%otf%out%geo%angle'
  @ 30m-setup-otf-rot2d setup30m%otf%out%geo%end  'setup30m%otf%out%geo%angle'
  @ 30m-setup-otf-rot2d setup30m%otf%out%geo%step 'setup30m%otf%out%geo%angle'
  ! Take care of center
  let setup30m%otf%out%geo%beg setup30m%otf%out%geo%beg+setup30m%otf%inp%center
  let setup30m%otf%out%geo%end setup30m%otf%out%geo%end+setup30m%otf%inp%center
end procedure 30m-setup-otf-geometry
!
begin procedure 30m-setup-otf-computations
  ! Dump time
  if (setup30m%otf%inp%dumptime.eq.0) then
     let setup30m%otf%out%time%dump 2
  else
     let setup30m%otf%out%time%dump setup30m%otf%inp%dumptime
  endif
  ! Off position and phase time
  if (setup30m%switch%mode.eq.switch%psw) then
     let setup30m%otf%out%time%phase setup30m%otf%out%time%dump
     if ((setup30m%switch%offpos[1].eq.0).and.(setup30m%switch%offpos[2].eq.0)) then
        message w otf "Off position is at the projection center!..."
     endif
  else if (setup30m%switch%mode.eq.switch%fsw) then
     let setup30m%otf%out%time%phase setup30m%otf%out%time%dump/2
  endif
  ! Beam sampling along the scanning direction
  if (setup30m%otf%inp%beamsampling.lt.3) then
     message e otf "The number of points per beam must be >=3 (Have a look at pety & rodriguez 2010, A&A section C)"
     return base
  else
     let setup30m%otf%out%on%beamsampling setup30m%otf%inp%beamsampling
  endif
  ! Map sampling
  define double diameter lambda clight nyquist
  let nyquist 2.1 ! A bit more than 2 because of the pixelling effect
  let diameter 30 ! This is the IRAM-30m!...
  let clight 0.299792458 ! For a frequency in GHz
  let lambda clight/setup30m%otf%inp%freq
  let setup30m%otf%out%sampling lambda/(nyquist*diameter)/sec
  ! Geometry: Number of line and line length
  let setup30m%otf%out%line%length setup30m%otf%inp%size
  let setup30m%otf%out%line%numb[1] nint(1+setup30m%otf%out%line%length[2]/setup30m%otf%out%sampling)
  let setup30m%otf%out%line%numb[2] nint(1+setup30m%otf%out%line%length[1]/setup30m%otf%out%sampling)
  if (setup30m%otf%inp%overtime) then
     ! Take care of edge effect due to difficulties to start OTF at the
     ! start of the line
     ! *** JP: It's probably not the right way of doing this as we want 
     !         to increase the time at start, not the total length of the line
     let setup30m%otf%out%line%length setup30m%otf%out%line%length*1.1
  endif
  ! Slew velocity
  define double beamsampling_time[2]
  let beamsampling_time setup30m%otf%out%on%beamsampling*setup30m%otf%out%time%dump
  if ((beamsampling_time[1].le.0).or.(beamsampling_time[2].le.0)) then
     message e otf "Negative or zero valued sampling time"
     return base
  endif
  let setup30m%otf%out%fwhm 2460/setup30m%otf%inp%freq
  let setup30m%otf%out%on%slewvelo setup30m%otf%out%fwhm/beamsampling_time 
  ! *** JP Some check needed on the slew velocity and/or the minimum dump time
  ! Number of dumps per line and otf time
  let setup30m%otf%out%numb%dump ceiling(setup30m%otf%out%line%length/(setup30m%otf%out%on%slewvelo*setup30m%otf%out%time%dump))
  let setup30m%otf%out%time%otf setup30m%otf%out%numb%dump*setup30m%otf%out%time%dump
  let setup30m%otf%out%line%length setup30m%otf%out%on%slewvelo*setup30m%otf%out%time%otf ! This can have slightly increased
  ! Loop time
  if (setup30m%switch%mode.eq.switch%fsw) then
     ! FSW code => No references
     let setup30m%otf%out%numb%ref_per_loop 0
     let setup30m%otf%out%time%ref 0
     let setup30m%otf%out%numb%line_per_loop 1
  else if (setup30m%switch%mode.eq.switch%psw) then
     ! Number of lines per loop
     define double Tstability
     let Tstability setup30m%otf%inp%stabtime
     let setup30m%otf%out%numb%line_per_loop floor(Tstability/setup30m%otf%out%time%otf)
     for idir scandirs%lamb scandirs%beta
        if (setup30m%otf%out%numb%line_per_loop[idir].le.0) then
           message e otf "Time to slew a line is larger than the stability time ("'Tstability'")"
           return base
        endif
     next idir
     ! Time between two references
     let setup30m%otf%out%time%betweenref setup30m%otf%out%numb%line_per_loop*setup30m%otf%out%time%otf
     for idir scandirs%lamb scandirs%beta
        if (abs((Tstability-setup30m%otf%out%time%betweenref[idir])/Tstability).gt.0.8) then
           message w otf "Time between two references is shorter than 80% of the maximum stability time ("'Tstability'")"
        endif
     next idir
     ! Beam area
     define double fwhm_area
     ! *** JP smoothing could be taken into account here with a condition 
     let fwhm_area (1+1/9)*setup30m%otf%out%fwhm^2 ! This takes gridding into account
     let setup30m%otf%out%beam_area (pi*fwhm_area)/(4*log(2))
     ! Area velocity
     let setup30m%otf%out%on%areavelo setup30m%otf%out%on%slewvelo*setup30m%otf%out%sampling
     ! Area scanned between two references
     let setup30m%otf%out%on%areasubmap setup30m%otf%out%on%areavelo*setup30m%otf%out%time%betweenref
     ! Number of independant on per off
     let setup30m%otf%out%on%peroff setup30m%otf%out%on%areasubmap/setup30m%otf%out%beam_area
     ! Reference time (two references are used to make an off, hence the factor 2)
     let setup30m%otf%out%time%ref (setup30m%otf%out%time%betweenref/setup30m%otf%out%on%peroff)*sqrt(setup30m%otf%out%on%peroff)/2
     for idir scandirs%lamb scandirs%beta
        if (setup30m%otf%out%time%ref[idir].lt.10) then
           ! Minimum enforced by PAKO
           let setup30m%otf%out%time%ref[idir] 10
           message w otf "Reference time set to 10 seconds"
        endif
     next idir
     ! Number of references per loop
     let setup30m%otf%out%numb%ref_per_loop 2
  endif
  let setup30m%otf%out%time%loop setup30m%otf%out%numb%line_per_loop*setup30m%otf%out%time%otf+setup30m%otf%out%numb%ref_per_loop*setup30m%otf%out%time%ref
  ! Number of loops per fullscan
  let setup30m%otf%out%numb%loop_per_fullscan floor(setup30m%otf%inp%maxtime_betweencal*60/setup30m%otf%out%time%loop)
  for idir scandirs%lamb scandirs%beta
     if (setup30m%otf%out%numb%loop_per_fullscan[idir].le.0) then
        message e otf "The time to make one OTF loop, e.g., ROOOR, is larger than the maximum time between two calibrations"
        message e otf "Either increase the maximum time between two calibrations, or decrease the stability time"
        return base
     endif
  next idir
  ! Number of fullscans and number of residual lines per coverage
  define integer nlines[2]
  let nlines setup30m%otf%out%numb%loop_per_fullscan*setup30m%otf%out%numb%line_per_loop
  let setup30m%otf%out%numb%fullscan_per_cov floor(setup30m%otf%out%line%numb/nlines)
  for idir scandirs%lamb scandirs%beta
     if (setup30m%otf%out%line%numb[idir].gt.(setup30m%otf%out%numb%fullscan_per_cov[idir]*nlines[idir])) then
        let setup30m%otf%out%numb%residual_lines[idir] setup30m%otf%out%line%numb[idir]-setup30m%otf%out%numb%fullscan_per_cov[idir]*nlines[idir]
     else
        let setup30m%otf%out%numb%residual_lines[idir] 0
     endif
  next idir
  ! Residual time and number of cals per coverage
  for idir scandirs%lamb scandirs%beta
     if (setup30m%otf%out%numb%residual_lines[idir].eq.0) then
        let setup30m%otf%out%time%residual[idir] 0
        let setup30m%otf%out%numb%cal_per_cov[idir] setup30m%otf%out%numb%fullscan_per_cov[idir]
     else
        let setup30m%otf%out%time%residual[idir] setup30m%otf%out%numb%residual_lines[idir]*setup30m%otf%out%time%otf[idir]+2*setup30m%otf%out%time%ref[idir]
        let setup30m%otf%out%numb%cal_per_cov[idir] setup30m%otf%out%numb%fullscan_per_cov[idir]+1
     endif
  next idir
  let setup30m%otf%out%time%totcal setup30m%otf%out%numb%cal_per_cov*setup30m%otf%out%time%cal
  let setup30m%otf%out%time%fullscan setup30m%otf%out%numb%loop_per_fullscan*setup30m%otf%out%time%loop
  let setup30m%otf%out%time%cov setup30m%otf%out%numb%fullscan_per_cov*setup30m%otf%out%time%fullscan+setup30m%otf%out%time%residual+setup30m%otf%out%time%totcal
end procedure 30m-setup-otf-computations
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! Procedure creation
!
begin procedure 30m-setup-otf-pro-preambule
  say "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
  say "!"
  say "! J.Pety & C.Buchbender (2007-2019)"
  say "!"
  say "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
  say "!"
  say "! Procedure #&2/&3"
  say "!"
  say "! Coverage parameters ("'scandirs%names[&1]'" scanning):"
  say "!  * General parameters:"
  say "!      - FWHM     [arcsec]: "'setup30m%otf%out%fwhm'
  say "!      - Sampling [arcsec]: "'setup30m%otf%out%sampling'" (Yes, it is better than FWHM/2)"
  say "!  * Geometry:"
  say "!      - Number of lines: "'setup30m%otf%out%line%numb[&1]'
  say "!      - Line length [arcsec]: "'setup30m%otf%out%line%length[&1]'
  say "!  * Time distribution:"
  say "!      - Total time  [hrs]: "'setup30m%otf%out%time%cov[&1]/3600'
  say "!      - ON+OFF time [hrs]: "'(setup30m%otf%out%time%cov[&1]-setup30m%otf%out%time%totcal[&1])/3600'
  say "!      - CAL time    [hrs]: "'setup30m%otf%out%time%totcal[&1]/3600'
  say "!      - Time between two calibrations [min]: "'setup30m%otf%out%time%fullscan[&1]/60'
  say "!  * OTF scan parameters:"
  say "!      - Time per ON subscan [s]: "'setup30m%otf%out%time%otf[&1]'
  say "!      - Number of subscans:"
!  say "!          o Total: "'setup30m%otf%out%numb%[&1]'
  say "!      - ON parameters:"
  say "!          o Time per phase       [s]: "'setup30m%otf%out%time%phase[&1]'
  say "!          o Dump time            [s]: "'setup30m%otf%out%time%dump[&1]'
  say "!          o Time to slew line    [s]: "'setup30m%otf%out%time%otf[&1]'
  say "!          o Slew velocity [arcsec/s]: "'setup30m%otf%out%on%slewvelo[&1]'
  say "!          o Beam sampling [pts/beam]: "'setup30m%otf%out%on%beamsampling[&1]'
!  say "!      - FSW parameters:"
!  for irec 1 to setup30m%otf%out%fsw%nrec
!     say "!          o Frequency throw [MHz]: "'2*setup30m%otf%out%fsw%throw[irec]'" for receiver "'setup30m%otf%out%fsw%rec[irec]'
!  next irec
  say "!      - OFF parameters:"
  say "!          o Offsets [arcsec]: "'setup30m%switch%offpos[1]' 'setup30m%switch%offpos[2]'
  say "!          o Time per OFF [s]: "'setup30m%otf%out%time%ref[&1]'
  say "!  * CAL scan parameters:"
  say "!      - Time per cal [s]: "'setup30m%otf%out%time%cal[&1]'
  say "!      - Number of cal: "'setup30m%otf%out%numb%cal_per_cov[&1]'
  say "!"
  say "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
  say "!"
  say "clear alpha"
  ! *** JP *** The following should be customizable.
  say "limits 500 -500 -500 500"
  say "box"
  say "!"
  say "! Reset backends"
  say "@ ~/"'setup30m%file%back'
  say "!"
  say "source "'setup30m%otf%inp%source'
  say "!"
  say "set angle arcsec"
  say "off /clear"
  say "!"
  if (setup30m%switch%mode.eq.switch%psw) then
     define character croloop*'2+setup30m%otf%out%numb%line_per_loop[&1]'
     let croloop "r"
     for iline 1 to setup30m%otf%out%numb%line_per_loop[&1]
        let croloop 'croloop'"o"
     next iline
     let croloop 'croloop'"r"
     say "swtotal /tphase "'setup30m%otf%out%time%phase[&1]'
     say "!"
     say "otfmap 0 0 0 0 /croloop "'croloop'" -"
     say "               /totf "'setup30m%otf%out%time%otf[&1]'" /tref "'setup30m%otf%out%time%ref[&1]'" -"
     say "               /ref "'setup30m%switch%offpos[1]'" "'setup30m%switch%offpos[2]'" proj -"
     say "               /syst proj /zigzag yes"
     delete /var croloop
  else if (setup30m%switch%mode.eq.switch%fsw) then
!!$     for irec 1 to setup30m%otf%out%fsw%nrec
!!$        say "swf "'-setup30m%otf%out%fsw%throw[irec]'" "'setup30m%otf%out%fsw%throw[irec]'" /tphase "'setup30m%otf%out%time%phase[&1]'" /rece "'setup30m%otf%out%fsw%rec[irec]'
!!$     next irec
     say "!"
     say "otfmap 0 0 0 0 /croloop o -"
     say "               /totf "'setup30m%otf%out%time%otf[&1]'" -"
     say "               /ref no /syst proj /zigzag yes"           
  endif
  say "!"
  say "cal /def"
  say "start"
end procedure 30m-setup-otf-pro-preambule
!
begin procedure 30m-setup-otf-pro-main
  define integer nloop
  define integer ioffset iotf notf nfullscan
  let ioffset setup30m%otf%inp%filestart
  for idir scandirs%lamb scandirs%beta
     let notf setup30m%otf%out%numb%loop_per_fullscan[idir]*setup30m%otf%out%numb%line_per_loop[idir]
     @ 30m-setup-otf-geometry 'idir'
     let nfullscan setup30m%otf%out%numb%fullscan_per_cov[idir]
     for ifullscan 1 to nfullscan
        sic output 'setup30m%file%otf''switch%names[setup30m%switch%mode]'"-"'scandirs%names[idir]'"-"'ifullscan+ioffset'".pako"
           @ 30m-setup-otf-pro-preambule 'idir' 'ifullscan' 'setup30m%otf%out%numb%fullscan_per_cov[idir]'
           say "otfmap" 'setup30m%otf%out%geo%beg[1]' 'setup30m%otf%out%geo%beg[2]' 'setup30m%otf%out%geo%end[1]' 'setup30m%otf%out%geo%end[2]' " /step" 'setup30m%otf%out%geo%step[1]' 'setup30m%otf%out%geo%step[2]' " /notf " 'notf' /format a f10.2 f10.2 f10.2 f10.2 a f8.2 f8.2 a i0
           say "start"
           let setup30m%otf%out%geo%beg setup30m%otf%out%geo%beg+notf*setup30m%otf%out%geo%step
           let setup30m%otf%out%geo%end setup30m%otf%out%geo%end+notf*setup30m%otf%out%geo%step
           say "!"
           say "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
        sic output
        type 'setup30m%file%otf''switch%names[setup30m%switch%mode]'"-"'scandirs%names[idir]'"-"'ifullscan+ioffset'".pako"
     next ifullscan
     let notf setup30m%otf%out%numb%residual_lines[idir]
     if (notf.gt.0) then
        let nfullscan nfullscan+1
        sic output 'setup30m%file%otf''switch%names[setup30m%switch%mode]'"-"'scandirs%names[idir]'"-"'nfullscan+ioffset'".pako"
           @ 30m-setup-otf-pro-preambule 'idir' 'nfullscan' 'setup30m%otf%out%numb%fullscan_per_cov[idir]'
           if (setup30m%switch%mode.eq.switch%psw) then
              define character croloop*'2+3*notf' ! *** JP 1) formula should be checked 2) a check on the line length is needed
              let notf setup30m%otf%out%numb%residual_lines[idir]
              !
              let nloop floor(notf/setup30m%otf%out%numb%line_per_loop[idir])
              let iotf 0
              let croloop ""
              for iloop 1 to nloop
                 let croloop 'croloop'"r"
                 for iline 1 to setup30m%otf%out%numb%line_per_loop[idir]
                    let croloop 'croloop'"o"
                    let iotf iotf+1
                 next iline
                 let croloop 'croloop'"r"
              next iloop
              let croloop 'croloop'"r"
              for jotf iotf+1 to notf
                 let croloop 'croloop'"o"
              next jotf
              let croloop 'croloop'"r"
              !
              say "otfmap 0 0 0 0 /croloop "'croloop'
              say "otfmap" 'setup30m%otf%out%geo%beg[1]' 'setup30m%otf%out%geo%beg[2]' 'setup30m%otf%out%geo%end[1]' 'setup30m%otf%out%geo%end[2]' " /step" 'setup30m%otf%out%geo%step[1]' 'setup30m%otf%out%geo%step[2]' " /notf " 'notf'  /format a f10.2 f10.2 f10.2 f10.2 a f8.2 f8.2 a i0
              say "start"
              delete /var croloop
           else if (setup30m%switch%mode.eq.switch%fsw) then
              say "!"
              say "cal /def"
              say "start"
              say "otfmap" 'setup30m%otf%out%geo%beg[1]' 'setup30m%otf%out%geo%beg[2]' 'setup30m%otf%out%geo%end[1]' 'setup30m%otf%out%geo%end[2]' " /step" 'setup30m%otf%out%geo%step[1]' 'setup30m%otf%out%geo%step[2]' " /notf " 'notf'  /format a f10.2 f10.2 f10.2 f10.2 a f8.2 f8.2 a i0
              say "start"
           endif
           say "!"
           say "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
        sic output
        type 'setup30m%file%otf''switch%names[setup30m%switch%mode]'"-"'scandirs%names[idir]'"-"'nfullscan+ioffset'".pako"
     endif
  next idir
end procedure 30m-setup-otf-pro-main
!
begin procedure 30m-setup-otf-pro
  @ 30m-setup-otf-reset-out
  @ 30m-setup-otf-computations
  @ 30m-setup-otf-pro-main
end procedure 30m-setup-otf-pro
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! Visualization
!
begin procedure 30m-setup-otf-view-subscans
  if (.not.setup30m%otf%view%subscans) return
  @ 30m-setup-otf-reset-out
  @ 30m-setup-otf-computations
  pen 0
  for idir scandirs%lamb scandirs%beta
     @ 30m-setup-otf-geometry 'idir'
     for iotf 1 to setup30m%otf%out%line%numb[idir]
        draw relo 'setup30m%otf%out%geo%beg[1]' 'setup30m%otf%out%geo%beg[2]' /user sec
        draw line 'setup30m%otf%out%geo%end[1]' 'setup30m%otf%out%geo%end[2]' /user sec
        let setup30m%otf%out%geo%beg setup30m%otf%out%geo%beg+setup30m%otf%out%geo%step
        let setup30m%otf%out%geo%end setup30m%otf%out%geo%end+setup30m%otf%out%geo%step
     next iotf
  next idir
end procedure 30m-setup-otf-view-subscans
!
begin procedure 30m-setup-otf-view-scans
  if (.not.setup30m%otf%view%scans) return
  @ 30m-setup-otf-reset-out
  @ 30m-setup-otf-computations
  pen 2
  define integer notf first last curr
  define double center[2] size[2] angle
  set expand 0.5
  for idir scandirs%lamb scandirs%beta
     let notf setup30m%otf%out%numb%loop_per_fullscan[idir]*setup30m%otf%out%numb%line_per_loop[idir]
     @ 30m-setup-otf-geometry 'idir'
     let setup30m%otf%out%geo%beg setup30m%otf%out%geo%beg-(0.5*notf+0.5)*setup30m%otf%out%geo%step
     let setup30m%otf%out%geo%end setup30m%otf%out%geo%end-(0.5*notf+0.5)*setup30m%otf%out%geo%step
     let curr setup30m%otf%inp%filestart
     if (idir.eq.1) then
        let angle setup30m%otf%inp%angle
     else
        let angle setup30m%otf%inp%angle+90
     endif
     for ifullscan 1 to setup30m%otf%out%numb%fullscan_per_cov[idir]
        let setup30m%otf%out%geo%beg setup30m%otf%out%geo%beg+notf*setup30m%otf%out%geo%step
        let setup30m%otf%out%geo%end setup30m%otf%out%geo%end+notf*setup30m%otf%out%geo%step
        let size[setup30m%otf%out%geo%iperp] 'setup30m%otf%out%line%length[idir]'
        let size[setup30m%otf%out%geo%iscan] 'setup30m%otf%out%sampling*notf'
        let center 0.5*(setup30m%otf%out%geo%end+setup30m%otf%out%geo%beg)
        go poly rectangle 'center[1]' 'center[2]' 'size[1]' 'size[2]' 'setup30m%otf%inp%angle'
        let curr curr+1
        draw text 'center[1]' 'center[2]' 'curr' 5 'angle' /user sec
     next ifullscan
  next idir
  set expand 1
  pen 1
  let center setup30m%otf%inp%center
  let first setup30m%otf%inp%filestart+1
  let last setup30m%otf%inp%filestart+setup30m%otf%out%numb%fullscan_per_cov[1]
  draw text 'center[1]' 'center[2]' 'first'"-"'last' 5 'setup30m%otf%inp%angle' /user sec
  let last setup30m%otf%inp%filestart+setup30m%otf%out%numb%fullscan_per_cov[2]
  draw text 'center[1]' 'center[2]' 'first'"-"'last' 5 'setup30m%otf%inp%angle+90' /user sec
  pen 0
end procedure 30m-setup-otf-view-scans
!
begin procedure 30m-setup-otf-view-fov
  if (.not.setup30m%otf%view%coverage) return
  @ 30m-setup-otf-reset-out
  @ 30m-setup-otf-computations
  pen 7
  go poly rectangle 'setup30m%otf%inp%center[1]' 'setup30m%otf%inp%center[2]' -
                    'setup30m%otf%inp%size[1]'   'setup30m%otf%inp%size[2]' -
                    '90+setup30m%otf%inp%angle'
  go poly rectangle 'setup30m%otf%inp%center[1]'      'setup30m%otf%inp%center[2]' -
                    'setup30m%otf%out%line%length[1]' 'setup30m%otf%out%line%length[2]' -
                    '90+setup30m%otf%inp%angle'
  pen 0
end procedure 30m-setup-otf-view-fov
!
begin procedure 30m-setup-otf-view-off
  if (.not.setup30m%otf%view%off) return
  @ 30m-setup-otf-reset-out
  @ 30m-setup-otf-computations
  pen 2
  if  (setup30m%switch%mode.eq.switch%psw) then
     define double offpos[2] cross
     let offpos setup30m%switch%offpos*sec
     let cross 50*sec
     greg1\draw relo offpos[1] offpos[2]+cross /user
     greg1\draw line offpos[1] offpos[2]-cross /user
     greg1\draw relo offpos[1]+cross offpos[2] /user
     greg1\draw line offpos[1]-cross offpos[2] /user
  endif
  pen 0
end procedure 30m-setup-otf-view-off
!
begin procedure 30m-setup-otf-view-all
  @ 30m-setup-otf-view-subscans
  @ 30m-setup-otf-view-scans
  @ 30m-setup-otf-view-fov
  @ 30m-setup-otf-view-off
end procedure 30m-setup-otf-view-all
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! Hardcopy
!
begin procedure 30m-setup-otf-hard
  ! Separated command as it may take times
  let setup30m%file%otfgeo 'setup30m%dir%hard''setup30m%proj%inp%nick'"-"'setup30m%name'"-geo"
  ha 'setup30m%file%otfgeo' /dev png /over
end procedure 30m-setup-otf-hard
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! Commands
!
begin procedure 30m-setup-otf-time
  if (pro%narg.eq.2) then
     if (pro%arg[1].eq."dump") then
        let setup30m%otf%inp%dumptime 'pro%arg[2]'
     else if (pro%arg[1].eq."stab") then
        let setup30m%otf%inp%stabtime 'pro%arg[2]'
     else if (pro%arg[1].eq."cycle") then
        let setup30m%otf%inp%maxtime_betweencal 'pro%arg[2]'
     else
        message e 30m-setup-source "Usage: OTFTIME DUMP|STAB|CYCLE time"
        return base
     endif
  else
     message e 30m-setup-source "Usage: OTFTIME DUMP|STAB|CYCLE time"
     return base
  endif
end procedure 30m-setup-otf-time
!
begin procedure 30m-setup-otf-geo
  if (pro%narg.eq.6) then
     let setup30m%otf%inp%source  'pro%arg[1]'
     let setup30m%otf%inp%size[1] 'pro%arg[2]'
     let setup30m%otf%inp%size[2] 'pro%arg[3]'
     let setup30m%otf%inp%angle   'pro%arg[4]'
     let setup30m%otf%inp%center[1] 'pro%arg[5]'
     let setup30m%otf%inp%center[2] 'pro%arg[6]'
  else
     message e 30m-setup-source "Usage: OTFGEO sourcename major minor pa center[1] center[2]"
     return base
  endif
end procedure 30m-setup-otf-geo
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! Widget
!
begin procedure 30m-setup-otf-widget
  define character mode*12
  let mode "&1" /lower
  if (mode.eq."psw") then
     let setup30m%switch%mode switch%psw
  else if (mode.eq."fsw") then
     message i otf-widget "OTF FSW is not yet implemented."
     return base
     ! let setup30m%switch%mode switch%fsw
  else
     message e otf-widget "Unknown switching mode: &1"
     return base
  endif
  gui\panel "30m Heterodyne OTF &1 Setup Facility (J.Pety, C.Buchbender)" gag_scratch:30m-setup-otf.hlp
     @ 30m-setup-widget-step otf
     gui\button "@ 30m-setup-otf-input" "Dump user inputs"
     gui\button "@ 30m-setup-otf-pro"   "Make procedures"
     gui\menu "VIEWS" /choices
        gui\button "@ 30m-setup-otf-view-all"      "View all"
        gui\button "@ 30m-setup-otf-view-off"      "View OFF position"
        gui\button "@ 30m-setup-otf-view-fov"      "View FoV"
        gui\button "@ 30m-setup-otf-view-scans"    "View scans"
        gui\button "@ 30m-setup-otf-view-subscans" "View subscans"
     gui\button "@ 30m-setup-otf-hard"  "Save image"
     say "Frequency setup (waiting for a more integrated solution)"
     let setup30m%file%back 'setup30m%file%back' /prompt "Name of backend setup procedure"
     let setup30m%otf%inp%freq 'setup30m%otf%inp%freq' /prompt " Maximum frequency of current setup [GHz]"
     say ""
     say "Map Parameters"
     let setup30m%otf%inp%source 'setup30m%otf%inp%source' /prompt "Projection center (One of the source defined in the catalog)"
     let setup30m%otf%inp%center 'setup30m%otf%inp%center[1]' 'setup30m%otf%inp%center[2]' /prompt "Center offsets [arcsec]"
     let setup30m%otf%inp%size 'setup30m%otf%inp%size[1]' 'setup30m%otf%inp%size[2]' /prompt "Size [arcsec]"
     let setup30m%otf%inp%angle 'setup30m%otf%inp%angle' /prompt "Position angle [degree]"
     say ""
     if (setup30m%switch%mode.eq.switch%psw) then
        say "Reference (OFF) position"
        let setup30m%switch%offpos 'setup30m%switch%offpos[1]' 'setup30m%switch%offpos[2]' /prompt "Offsets [arcsec]"
     endif
     say ""
     say "OTF additional parameters for specialists (Be careful)"
     let setup30m%otf%inp%maxtime_betweencal 'setup30m%otf%inp%maxtime_betweencal' /prompt "Maximum time between two consecutive calibrations [minute]"
     let setup30m%otf%inp%stabtime 'setup30m%otf%inp%stabtime' /prompt "Maximum time between two consecutive references [second]"
     let setup30m%otf%inp%dumptime 'setup30m%otf%inp%dumptime' /prompt "Integration time per spectrum [second]"
     let setup30m%otf%inp%beamsampling 'setup30m%otf%inp%beamsampling' /prompt "Number of dump per telescope HPBW [points per beam]"
     let setup30m%otf%inp%overtime 'setup30m%otf%inp%overtime' /prompt "Add extra margin at start and end of line?"
     @ 30m-setup-widget-image
     @ 30m-setup-widget-status
  gui\go "@ 30m-setup-otf-pipe"
end procedure 30m-setup-otf-widget
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
