!-------------------------------------------------------------------------
!
! Package to generate pointing errors for use by the ALMA simulation
! 2001 (S. Guilloteau)
! 
!-------------------------------------------------------------------------
!
sic verif off
!
!------------------------------------------------------------------------ 
!
! Definition of global variables.
!
!------------------------------------------------------------------------ 
!
if (.not.exist(batch)) then
   define logical batch /global
   let batch no
endif
if (.not.exist(pe_init)) then
   !
   define logical pe_init /global
   define character pfine*32 psmooth*32 /global
   define real track bear wind ther meas /global
   define real corr_wind corr_ther /global
   define real dtime    /global ! Step in seconds
   define logical aplot /global
   define integer noccur nsamp istart iend ntime nant nsmo /global
   !
endif
!
!------------------------------------------------------------------------ 
!
! Widget definition
!
!------------------------------------------------------------------------ 
!
gui\panel "Pointing Error Generation" toto.hlp
let pfine pointing /prompt "Pointing File"
let psmooth smoothed /prompt "Smoothed File"
!
gui\button "@ pe_table" GENERATE "Generate Table" point_generate.hlp "Parameters"
  let aplot no    /prompt "Plot sequences ?"
  let nant        /prompt "Number of antennas ?"
  let ntime 1800  /prompt "Sequence duration (sec)"
  let noccur      /prompt "Number of sequences"
  let track 1     /prompt "Tracking error"
  let bear  1     /prompt "Bearing error"
  let wind  1     /prompt "Wind error"
  let ther  1     /prompt "Thermal error"
  let meas  0.25  /prompt "Measurement error"
  let dtime 1     /prompt "Integration time (sec)"
  let corr_wind  0.5  /range 0 1 /prompt "Wind Correlation"
  let corr_ther  0.7  /range 0 1 /prompt "Thermal Correlation"
!
gui\button "@ pe_smooth" SMOOTH "Smooth Table" point_smooth.hlp "Parameters"
  let nsmo 10     /prompt "Smoothing time (sec)"
!
if (.not.batch) then 
   gui\go
   on error return
else
   on error exit
endif
!
if (pe_init) then
   return
endif
!
!-------------------------------------------------------------------------
!
! Procedure definition
!
!-------------------------------------------------------------------------
!
! Button GENERATE
!
!-------------------------------------------------------------------------
!
begin procedure pe_table
  define integer nsamp
  let nsamp noccur*ntime
  define image errors[2,nsamp,nant] 'pfine'.gdf real /global
  !
  let istart 1
  for ll 1 to noccur
     let iend istart+ntime-1
     @ pe_generation
     let istart iend+1
  next
  !
  delete /variable errors 
  transpose 'pfine'.gdf 'pfine'.tab 231
end procedure pe_table
!
!-------------------------------------------------------------------------
!
begin procedure pe_generation
  define real track_err[2,ntime,nant] bear_err[2,ntime,nant] 
  define real wind_err[2,ntime,nant] ther_err[2,ntime,nant] 
  define real err[2,ntime] total_err[2,ntime,nant] plot_err[ntime,2] 
  define real angle[ntime,nant] ang[ntime] angle_err[2,ntime,nant]
  define real ang_err[2,ntime]  meas_err[2,nant]
  !
  define integer nstep i1 i2 is
  let nstep ntime ! Simpler ...
  define real power[nstep,2] cpower[nstep,2] amp[nstep] phi[nstep] xx[nstep] 
  define real r1 r2
  !
  ! Measurement error
  !
  let meas_err[j,i] meas*noise(i/i)
  !
  ! Tracking error
  !
  let track track/sqrt(dtime)
  let track_err[k,i,j] noise(track*(k+i+j)/(k+i+j))
  !
  ! Bearing error: Compute a spectrum on 512 seconds, parabolic
  !
  for k 1 to nant
     let phi[i] 2*pi*random(i/i)
     let phi phi-phi[1]
     let amp[i] ((nstep/4)^2-(i-nstep/4-1)^2)/(nstep/4)^2
     for i 2 to nstep/2
        let i1 nstep-i+2
        let amp[i1] amp[i]
        let phi[i1] -phi[i]
     next
     let cpower[1] amp*cos(phi)
     let cpower[2] amp*sin(phi)
     compute power fft+ cpower
     compute r1 rms power[1]
     let amp power[1]
     let phi[i] 2*pi*random(i/i)
     let power[1] amp*cos(phi)
     let power[2] amp*sin(phi)
     let is nint(dtime)
     let i1 1
     if (is.gt.1) then
        for i 1 to ntime
           let i2 i1+is-1
           compute r2 mean power[i1:i2,1]
           let bear_err[1,i,k] r2/r1*bear
           compute r2 mean power[i1:i2,2]
           let bear_err[2,i,k] r2/r1*bear
           let i1 i2+1  
           if (i1.gt.nstep) then
              let i1 1
           endif
        next
     else
        let is int(ntime/nstep)
        for i 1 to is 
           let i2 i1+nstep-1
           let bear_err[1,i1:i2,k] power[,1]*bear/r1
           let bear_err[2,i1:i2,k] power[,2]*bear/r1
           let i1 i2+1
        next
     endif
  next
  compute r1 min bear_err
  compute r2 max bear_err
  let xx[i] i
  !
  if (aplot) then
     pen 0
     destroy all
     lim -10 ntime+10 r1-0.1*(r2-r1) r2+0.1*(r2-r1) 
     box
     for i 1 to nant
        pen i
        let plot_err[1] bear_err[1,,i]
        let plot_err[2] bear_err[2,,i]
        connect xx plot_err[1]
        connect xx plot_err[2]
     next
     label "Bearing error" /x
     pause
  endif
  !
  ! Wind error
  !
  let wind wind/sqrt(dtime)
  let wind_err[k,i,j] noise(wind*(i+j+k)/(i+j+k))
  let err[k,i] noise(wind*(i+k)/(i+k))
  for k 1 to nant
     let wind_err[k] err*corr_wind+(1-corr_wind)*wind_err[k]
  next
  !
  compute r1 min wind_err
  compute r2 max wind_err
  if (aplot) then
     pen 0
     let xx[i] i
     destroy all
     lim -10 ntime+10 r1-0.1*(r2-r1) r2+0.1*(r2-r1) 
     box
     for i 1 to nant
        pen i
        let plot_err[1] wind_err[1,,i]
        let plot_err[2] wind_err[2,,i]
        connect xx plot_err[1]
        connect xx plot_err[2]
     next
     label "Wind error" /x
     pause
  endif
  !
  ! Thermal error
  !
  let angle[i,j] (i*7.5*pi/180/ntime)+2*pi*random(j/j)
  let angle_err[1,,] angle
  let angle_err[2,,] angle
  let ther_err[k,i,j] ((2-k)*cos(angle_err)+(k-1)*sin(angle_err))*i*dtime/1800*ther*4
  let ang[i] (i*7.5*pi/180/ntime)+2*pi*random(1.0)
  let ang_err[1,] ang
  let ang_err[2,] ang
  let err[k,i] ((2-k)*cos(ang_err)+(k-1)*sin(ang_err))*i*dtime/1800*ther*4
  !
  for k 1 to nant
     let ther_err[k] err*corr_ther+(1-corr_ther)*ther_err[k]
  next
  compute r1 min ther_err
  compute r2 max ther_err
  if (aplot) then
     pen 0
     let xx[i] i
     destroy all
     lim -10 ntime+10 r1-0.1*(r2-r1) r2+0.1*(r2-r1) 
     box
     for i 1 to nant
        pen i
        let plot_err[1] ther_err[1,,i]
        let plot_err[2] ther_err[2,,i]
        connect xx plot_err[1]
        connect xx plot_err[2]
     next
     label "Thermal error " /x
     pause
  endif
  !
  let total_err wind_err+bear_err+ther_err+track_err
  for i 1 to nant
     let total_err[1,,i] total_err[1,,i]+meas_err[1,i]
     let total_err[2,,i] total_err[2,,i]+meas_err[2,i]
  next
  !
  if (aplot) then
     for i 1 to nant
        let plot_err[,1] sqrt(total_err[1,,i]^2+total_err[2,,i]^2)
        let plot_err[,2] 180/pi*atan2(total_err[1,,i],total_err[2,,i])
        destroy all
        limit /var xx plot_err[1]
        set box 5 15 4 16
        pen 0
        box
        label "Amplitude (`)" /x
        pen i
        connect xx plot_err[1]
        limit /var xx plot_err[2]
        set box 15 27 4 16
        pen 0
        box p n
        label "Phase (^)" /x
        axis yr /label o
        pen i
        connect xx plot_err[2]
        let plot_err[2] plot_err[1]^2
        compute r2 mean plot_err[2]
        let r2 sqrt(r2)
        say 'i' 'r2'
        pause
     next
     set box /def 
  endif
  exa istart
  exa iend
  !
  let errors[,istart:iend,] total_err[,,]
end procedure pe_generation
!
!-------------------------------------------------------------------------
!
! Button PREPARE: Smooth a pointing error table
!
!-------------------------------------------------------------------------
!
begin procedure pe_smooth
  defin ima afine 'pfine'.tab read
  defin integer nsamp nout nant
  let nsamp afine%dim[1]
  let nant afine%dim[2]
  let nout int(nsamp/nsmo)  ! Make integer division
  !
  defin ima bsmo[nout,nant,2] 'psmooth'.tab real
  defin integer i1 i2
  let i1 1
  for i 1 to nout
     let i2 i1+nsmo-1
     for j  1 to nant
	compute bsmo[i,j,1] mean afine[i1:i2,j,1]
	compute bsmo[i,j,2] mean afine[i1:i2,j,2]
     next
     let i1 i2+1
  next
end procedure pe_smooth
!
!-------------------------------------------------------------------------
!
let pe_init yes
!
!------------------------ point_error ends here ---------------------------
!
! The next lines are for better viewing of the file under emacs.
! If you do not like the result, you can delete them.
!
!!! Local Variables:
!!! mode: f90
!!! mode: hscroll
!!! truncate-lines: t
!!! End:
