!-------------------------------------------------------------------------
!
! ALMA simulation 2001 (F. Gueth, S. Guilloteau, J. Pety)
! 
!-------------------------------------------------------------------------
!
@ alma_preliminary ! Some usefull stuff
!
!------------------------------------------------------------------------ 
!
! Definition and initialization of global variables.
!
!------------------------------------------------------------------------ 
!
if (.not.exist(alma_init)) then
   sic logical ps: ps
   !
   define logical alma_init cautious test /global
   define character working_dir*128 /global
   define character int_name*32[2] /global
   !
   define character kname*32[7] oname*32[3] pname*32[3] /global
   define integer pkind okind /global !
   define logical alma_print /global
   !
   ! Names of possible options
   !
   let int_name[1]   "alma"               ! Beginning of all the file which concern ALMA
   let int_name[2]   "aca"                ! Beginning of all the file which concern ACA
   !
   let kname[1] 'int_name[1]'"-only"
   let kname[2] 'int_name[2]'"-only"
   let kname[3] 'int_name[1]'"-"'int_name[2]'
   let kname[4] 'int_name[1]'"-short"
   let kname[5] 'int_name[2]'"-short"
   let kname[6] "all"
   let kname[7] "hybrid"
   !
   let pname[1] "FAST"
   let pname[2] "GREY"
   let pname[3] "COLOR"
   !
   let oname[1] "DEFAULT PRINTER"
   let oname[2] "PS FILE"
   !
   let pkind 3 ! Color PS device
   let okind 2 ! File output
   let alma_print no ! Do not print results
   !
   let cautious yes
   let test no
   !
   ! Start saved variables definition
   !
   sic save define_all TOTO
   define logical do_anrefr /global ! Anomalous refraction
   let do_anrefr no
   !
   ! File names
   !
   define character fullname*32 /global
   define character input_dir*128 output_dir*128 /global
   define character image_dir*128 config_dir*128 pnterr_dir*128 atmscreen_dir*128 /global
   define character model*128 inname*32 tmp_inname*32 new_inname*32 /global
   define character pbeamed*32 outname*32 /global
   define character difference*32 fidname*32 histogram*32 /global
   define character result*32 /global
   define character uv_coverage*32 shortspacings*32 tmp*32 uvfidelity*32 /global
   define character a_sum*32 a_avg*32 /global
   !
   ! Filenames and directories which depend on the kind of simulation
   ! we are doing.
   !
   let output_dir  "."                             ! Output directory
   !
   let working_dir 'sic%directory'                 ! Directory from where `alma.map' was called
!!   if (sic%version.ne."MS-Windows") then
      if file("gag_mis:demo/m51ha.gdf") then
         sic directory gag_mis:demo
      else if file("gag_demo:m51ha.gdf") then
         sic directory gag_demo:
      else
         say "E-ALMA, neither gag_mis:demo nor gag_demo: directories exist"
         @ alma_error
      endif
      let input_dir  'sic%directory'"/"            ! Default input  directory
      let config_dir "gag_data:"                   ! Configuration directory
      let model      'sic%directory'"/m51ha.gdf"   ! Beginning image model
      sic directory  'working_dir'
!!   else 
!!      let input_dir "C:\gildas\alma\"     !" ! Previous comment is to avoid fontification problems under emacs.
!!      let config_dir "gag_astro:alma"        ! Configuration directory
!!      let model      "gag_demo:m51ha.gdf"    ! Beginning image model
!!   endif
   !
   let image_dir     'input_dir'"images/gdf"         ! Image directory
   let pnterr_dir    'input_dir'"pnt_err"            ! Pointing errors directory
   let atmscreen_dir 'input_dir'"atm_screens"        ! Phase screen directory
   !
   ! Filenames that should be generic whatever the kind of simulation.
   !
   let inname        "input"              ! Input image with modified header
   let pbeamed       "pbeamed"            ! Idem but with primary beam
   let tmp_inname    "tmp-ninp"           ! One of the 2 previous one for temporary use
   let new_inname    "-ninp"              ! The input image that will be used for comparison with `output'
   let outname       "-outp"              ! The same but adapted for the comparison with `new_inname' (the output of the simulation)
   let difference    "-diff"              ! The difference `inname'-`outname'
   let fidname       "-fide"              ! The fidelity
   let histogram     "-hist"              ! The fidelity histogram
   let uvfidelity    "-uvfid"             ! The uv fidelity
   let result        "result"             ! UV table (but for what ???)
   let uv_coverage   "uv_coverage"        ! UV coverage for beam plotting
   let shortspacings "shortspacings"      ! Output of UV_SHORT
   let tmp           "tmp"                ! Temporary UV table
   let a_sum         "-sum"               ! 1D azimuthal sum of the dirty beam or uv fidelity
   let a_avg         "-avg"               ! 1D azimuthal avg of the dirty beam of uv fidelity
   ! Option definitions
   !
   define integer kind /global !
   !
   let kind  1 ! ALMA only 
   !
   ! Array definition.
   !
   define character array*24[2] config*12[2] /global
   define integer int_nant[2] nant iarray /global
   define double diameter[2] primbeam[2] /global
   !
   let array  "alma" "aca" ! The 2 studied arrays will be ALMA and ACA
   let config  "es1"  "I"  ! The ALMA configuration is the compact early science one
   let diameter  12  7     ! Assumes ALMA and ACA diameters
   let primbeam  -1 -1     ! Primary beam width (Will be find in `alma_interfero')
   let int_nant  -1 -1     ! Number of antenna  (Will be find in `alma_interfero')
   let iarray     1        ! Current Array being used
   !
   ! Model definition.
   !
   define logical change_dec change_size /global
   define character model_name*32 /global
   define double image_size[2] dec /global
   !
   let model_name  ""   ! Name of the model image (set in alma_setup and only used in plots)
   let change_dec  Yes  ! Change the declination
   let change_size No   ! Change the image size
   let dec         -23  ! Declination adapted to ALMA site
   let image_size 15 15 ! Single field size 
   !
   ! Mosaic definition.
   !
   define integer nfields full_iter /global
   define real xoffset[1] yoffset[1] /global
   define double inttime[2] mos_size[2] mos_orien /global
   define logical closest /global
   !
   let mos_size 0 0 ! Image size as default mosaic size.
   let mos_orien  0 ! The mosaic will be horizontal by default.
   let full_iter  1 ! Nb of full iterations on the mosaic during the observing time
   let nfields    1 ! will be overwritten by `alma_position'
   let xoffset    0 ! will be overwritten by `alma_position'
   let yoffset    0 ! will be overwritten by `alma_position'
   let mosaic    no ! No mosaic by default
   let closest   no ! Do not take only the closest neighbours in the hexagonal pattern
   let inttime  0.0 !
   !
   ! Interferometric observation conditions.
   !
   define double freq dfreq hour[2,2] horizon[2] /global
   define double tau[2] trec[2] phase_rms[2] /global
   !
   let freq       230        ! Frequency in GHz
   let dfreq      8000       ! Bandwidth in MHz
   let hour[,1]  -0.15 0.15  ! ALMA hour angle range
   let hour[,2]   4*hour[,1] ! ACA hour angle range
   let horizon    0          ! Minimum elevations
   let trec       100        ! Receiver temperatures
   let tau        0.150      ! Zenithal opacities
   let phase_rms      0      ! Phase noises
   !
   ! Pointing error model for interferometric observations.
   !
   define double pointerr[2,2] /global
   define integer pe_code[2] nbin /global
   define character int_pe*128[2] int_used_pe*32 /global
   !
   let int_pe[1]    'pnterr_dir'"/alma-both-pe-1.2.tab" ! ALMA input table of pointing errors
   let int_pe[2]    'pnterr_dir'"/aca-both-pe-1.2.tab"  ! ACA  input table of pointing errors
   let int_used_pe  "int_used_pe"         ! Used table of pointing errors (input of `uv_pointing')
   let pe_code         1                  ! No pointing error by default
   let pointerr[,1]   0 0                 ! ALMA pointing error sigmas in each direction
   let pointerr[,2]   0 0                 ! ACA  pointing error sigmas in each direction
   !
   ! Global processing options.
   !
   define logical addnoise[2] addshort /global
   define integer process /global
   !
   let addnoise  no ! Do not add noise to interferometric observations
   let addshort  no ! Do not add single dish antenna observations
   let process    3 ! Process both ALMA and ACA arrays
   !
   ! Deconvolution paramaters and results.
   !
   define character mask_kind*32 alma_method*12 /global
   define integer diter /global
   define double truncate[2] beam_scale[2] f_thres /global
   define double cbeam[3] /global 
   define double fluxes[3] pfluxes[3] /global
   define double fidmax fidrange fidelities[4] /global
   define double uvranges[4] uvfidelities[4] /global
   define double gains[2] asmooth /global 
   !
   let gains       0.15 0.15      ! Long and Compact CLEAN gains
   let asmooth     0.0            ! Smoothing kernel size
   let f_thres     0.01           ! Flux threshold where CLEAN component selection change
   let truncate    0.1  0.25      ! Primary beam truncation
   let beam_scale  1.00 1.00      ! Primary beam angular scale
   let diter       10000          ! Number of clean components
   let cbeam       0.0 0.0 0.0    ! Minor axis, major axis, and PA of clean beam
   let fluxes      0.0            ! Fluxes of input image, output image, difference image
   let pfluxes     0.0            ! Corresponding percentages
   let fidelities  0.0            ! Simulation median fidelities
   let fidmax      0.0            ! Simulation maximum fidelity
   let fidrange    0.0            ! Fidelity range
   let uvranges    15 37.5 75 150 !
   let uvfidelities 0.0           ! 
   let alma_method "CLARK"
   !
   let mask_kind "soft-sharp"     !
   !
   define character hybrid_in1_names*32[2] hybrid_in2_names*32[2] /global
   define integer hybrid_in1_code hybrid_in2_code /global
   define double hybrid_uvradius /global
   !
   let hybrid_in1_names[1] 'kname[1]'".lmv-clean"
   let hybrid_in1_names[2] 'kname[4]'".lmv-clean"
   let hybrid_in2_names[1] 'kname[5]'".lmv-clean"
   let hybrid_in2_names[2] 'kname[6]'".lmv-clean"
   let hybrid_in1_code   2             ! alma-short.lmv-clean will be used for hybridation
   let hybrid_in2_code   1             !  aca-short.lmv-clean will be used for hybridation
   let hybrid_uvradius   15            ! UV radius used in the hybridation method
   !
   ! Single dish section
   !
   define character sd_pnt*32 sd_used_pnt*32 sd_pe*128 sd_used_pe*32 /global
   define character sd_res*32 sd_zero*32 sd_sing*32 /global
   define double sd_diam sd_sigma sd_weight sd_rweight[2] sd_pointerr[2] /global
   define double sd_ampoff[2] sd_ampdrift sd_amptime sd_inttime sd_time sd_tsys /global
   define inte sd_nant sd_ppb sd_gpos sd_pe_code sd_nsamp /global
   define logical sd_addnoise sd_addcalerr /global
   !
   let sd_nsamp     0              ! *** well, well, well...
   !
   let sd_pnt      "sd_pnt"             ! Table of pointing centers (output of `image_sampling')
   let sd_used_pnt "sd_used_pnt"        ! Table of pointing centers (input  of `short_model')
   let sd_pe       'pnterr_dir'"/sd-both-pe-1.2.tab" ! Input table of pointing errors
   let sd_used_pe  "sd_used_pe"         ! Used  table of pointing errors (input of `short_model')
   let sd_res      "sd_res"             ! Temporary resulting table (for use by `uv_zero' AND `uv_short')
   let sd_zero     "sd_uvzero"          ! Input of `uv_zero'
   let sd_sing     "sd_uvsingle"        ! Input of `uv_short'
   !
   let sd_nant     4                    ! Number of antennas used as SD
   let sd_diam     diameter[1]          ! SD diameter
   let sd_sigma    0                    ! Required noise level
   let sd_weight   0.0                  ! Total SD weight in `uv_short'
   let sd_rweight  1.0 0.7              ! Multiplicative factor to the automatically found SD weight
   let sd_ppb      3                    ! Sampling rate (point per beam)
   let sd_gpos     1                    ! Grid position
   let sd_time     hour[2,2]-hour[1,2]  ! Integration time
   let sd_pe_code  1                    ! No pointing error by default
   let sd_pointerr 0 0                  ! Pointing error sigmas in each direction
   let sd_ampoff   0.0 0.0              ! 
   let sd_ampdrift 0.0                  !
   let sd_amptime  3600                 ! Time between 2 amplitude calibrations (s) 
   let sd_inttime  1                    ! Integration time (s)
   let sd_addnoise  no                  ! Noise flag
   let sd_addcalerr no                  ! Calibration error flag
   !
   ! Special setting for the system temperature
   !
   if (freq.lt.400) then
      let sd_tsys '15+0.6*freq'
   else
      let sd_tsys 1200
   endif
   !
   ! Atmospheric screen section
   !
   define logical do_screen /global
   define double wind[3] /global
   define character calibrator*128 phase_screen*128[2] /global
   define double dumps[2] phase_noise[2] /global
   define double calangle[2] /global
   define double spline_step /global  ! Spline step
   define integer ispline /global   ! Polynom (>0) or Spline (<0)
   define logical do_calib do_wvr /global
   define double wvr[2] /global
   !
   ! Amplitude error
   define double amplitude[2,2] /global ! Error and Drift for ALMA / ACA
   define double amp_time[2]    /global ! Amplitude error time scale (in seconds)
   !
   let amplitude 0.0 0.0 0.0 0.0 !
   let amp_time  3600
   !
   ! For plot action
   !
   define logical plot_calib /global
   define character solution*132 sorted*132 raw*132 cal*132 /global
   let sorted "sorted"
   !
   let do_calib  yes                  ! Apply Calibration
   let do_screen no                   ! Use phase screen
   let phase_screen[1] 'atmscreen_dir'"/alma_gradient"   ! Phase screen file name
   let phase_screen[2] 'atmscreen_dir'"/aca_gradient"    ! Phase screen file name
   let calibrator calib               ! Calibrator UV table
   let wind 0.0 10.0 1000.0           ! Angle, Velocity, Height
   let calangle 90.0 2.0              ! Angle, Distance
   let dumps    20 2                  ! Source / Cal integration time
   let ispline  1                     ! Use spline (2 = Polynom)
   let spline_step 1.0                ! In hours ?
   let do_wvr no
   let phase_noise 0.0
   let wvr 0 0
   !
   let solution "solution"
   !
   ! Pipeline behaviour
   !
   define logical do_setup do_sd do_alma do_aca /global
   define logical do_uvmap do_decon do_hybrid do_compa done /global
   !
   let do_setup  yes ! Allow setup on entry.
   let do_sd     yes ! Allow SD modelization on entry.
   let do_alma   yes ! Allow ALMA modelization on entry.
   let do_aca    yes ! Allow ACA  modelization on entry.
   let do_uvmap  yes ! Allow dirty map computation on entry.
   let do_decon  yes ! Allow deconvolution on entry.
   let do_hybrid no  ! Does not allow hybridation on entry.
   let do_compa  yes ! Allow comparison with model on entry.
   let done      no  ! Says whether current simulation went to its end.
   !
   sic save ! Finish saving
   !
   define logical force_setup force_sd force_alma force_aca /global
   define logical force_uvmap force_decon force_compa /global
   let force_setup no ! Do not force setup.
   let force_sd    no ! Do not force SD modelization.
   let force_alma  no ! Do not force ALMA modelization.
   let force_aca   no ! Do not force ACA  modelization.
   let force_uvmap no ! Do not force dirty map computation.
   let force_decon no ! Do not force deconvolution.
   let force_compa no ! Do not force comparison with model.
   !
   ! Misc.
   !
   !
   ! Display settings, not saved in "old" stuff
   !
   define integer display_mode /global
   define double uv_limit /global
   define logical multi_window /global
   !
   let display_mode 6  ! Means: display image comparison
   let uv_limit 0 
   let multi_window no
   !
   !
   symb TOTO "@ createold"
   sic output gag_proc:define_old.map
   @ gag_proc:define_all
   sic output
   symb TOTO continue
   !
   @ gag_proc:define_old.map
   !
   input
   let do_bit yes
   let do_contour no
   !
   ! ????
   !
   define double cin[2] cout[2] /global 
   define integer ablc[2] atrc[2] /global
   define character in1*256 in2*256 out*256 /global  ! used for task .init files
   !
   define double rstep /global
   !
   define double uvmin uvmax uvrange[2] /global
   !
   define integer screen_size[2] window_size[2] wait_time /global
   !
   let screen_size 1280 1024
   let window_size 0.5*0.925*screen_size
   let wait_time   1
   !
endif
!
!------------------------------------------------------------------------ 
!
! Widget definition
!
!------------------------------------------------------------------------ 
!
if (.not.exist(batch)) then
   define logical batch /global
   let batch no
endif
if (.not.exist(alma_pipeline)) then
   define logical alma_pipeline /global
   let alma_pipeline yes
endif
if (.not.batch) then 
   !
   ! Define plotting window and a nice color setup
   !
   dev i w
   let lut%saturation[i] i/10.
   lut
   !
   ! The next 2 operations can been done only when the procedures are 
   ! defined. 
   !
   if (alma_init) then
      !
      ! Restore private initialization
      !
      if (file("gag_init:init.alma")) then
         say " "
         say "Loads init.alma"
         @ gag_init:init.alma
         say "Loading done"
         say " "
      endif
      !
      ! Restore last values
      !
      if (file("parameters.map")) then
         @ parameters.map
         if (done) then
            @ alma_display
         else
            say ""
            say "E-ALMA, This kind of  simulation has not gone up to its end."
            say "E-ALMA, Push the COMPUTE button to make it with the current parameters."
            say ""
         endif
      endif
      !
      ! Choose the kind of user interface
      !
      if (alma_pipeline) then
         @ alma_pipeline_mode
      endif
      !
   endif
   !
else
   on error exit
endif
!
if (alma_init) then
   say " "
   say "ALMA simulation package -- Version 3.5 24-Jan-2002"
   say "     3.1   Anomalous Refraction"
   say "     3.2   Beam truncation in UV plane (uv_pointing)"
   say "     3.3   Mosaic mask applied before image comparison"
   say "     3.4   Revised mask definition"
   say "     3.5   Choice of deconvolution method"
   say "     3.6   New Mosaic table extraction method:"
   say "           Should work even if shadowing occurs."
   return
endif
!
!-------------------------------------------------------------------------
!
! Procedure definition
!
!-------------------------------------------------------------------------
!
! Added V3.5 by S.Guilloteau to select the deconvolution method
!
begin procedure deconvolve 
   if (alma_method.eq."CLARK") then
     clark /flux 0 '1.1*fluxes[1]'
   else if (alma_method.eq."HOGBOM") then
     hogbom /flux 0 '1.1*fluxes[1]'
   else if (alma_method.eq."MULTI") then
     multi /flux 0 '1.1*fluxes[1]'
   else if (alma_method.eq."SDI") then
     sdi /flux 0 '1.1*fluxes[1]'
   else
	SAY "Don't know yet"
      PAUSE
   endif
end procedure deconvolve
!
!
!-------------------------------------------------------------------------
!
! Button LOAD
!
!-------------------------------------------------------------------------
!
begin procedure alma_load
  !
  ! To understand the behavior, first read the "curious's corner" in the 
  ! `pipeline_mode.hlp' file.
  !
  ! Change directory when necessary. Do not take any particular precaution:
  ! do not warn the user if the directory already exists.
  !
  let cautious no
  @ alma_change_outdir
  !
  ! Verify that the simulation has been done
  !
  define character pars_name*32
  let pars_name 'kname[kind]'-pars.map
  !
  if (file(pars_name)) then
     !
     ! Verify that the last state of the simulation exists.
     !
     if (.not.file("parameters.map")) then
        !
        say "W-ALMA, You are trying to load an old simulation"
        say "W-ALMA, But the file (parameters.map) which reflects the last" 
        say "W-ALMA, simulation states does not exist"
        say "W-ALMA, Redo the computation from scratch or prepare for trouble."
        pause
        !
     endif
     !
     ! Load the old simulation parameters
     !
     @ 'pars_name'
     !
     ! Update widget because of a bug in the widget behavior
     !
     if (alma_pipeline) then
        @ alma_pipeline_mode
     endif
     !
     ! Plot results when simulation went to its end: that should always
     ! be the case (just to be safe).
     !
     if (done) then
        !
        let old_kind kind ! We have loaded...
        @ alma_display
        !
     else
        !
        say ""
        say "E-ALMA, This kind of  simulation has not gone up to its end."
        say "E-ALMA, Push the COMPUTE button to make it with the current parameters."
        say ""
        !
     endif
     !
  else
     !
     say ""
     say "E-ALMA, This kind of simulation has not yet been made in the"
     say "E-ALMA, output directory."
     say "E-ALMA, Push the COMPUTE button to make it with the current parameters."
     say ""     
     !
  endif
  !
  let cautious yes
  !
end procedure alma_load
!
!-------------------------------------------------------------------------
!
! Button COMPUTE
!
!-------------------------------------------------------------------------
!
begin procedure alma_compute
  !
  ! Ensure that "GO UV_MAP" will use the task (for backward compatibility)
  define logical in_map_task
  let in_map_task map%task
  let map%task yes
  let diam%int 12
  let diam%sd  12
  !
  define character date_begin*32 date_end*32
  sic date
  let date_begin "'sys_date'"
  !
  ! To understand the behavior, first read the "curious's corner" in the 
  ! `pipeline_mode.hlp' file.
  !
  ! Define logical variables that will help decide what will have to be 
  ! computed
  !
  define logical doit search_sd search_alma search_aca
  !
  let search_sd   no ! A priori, do not search among SD   parameters
  let search_alma no ! A priori, do not search among ALMA parameters
  let search_aca  no ! A priori, do not search among ACA  parameters
  !
  ! Analyse input parameters and compare them to old values. 
  ! If at least one of them differs from its old value, say to make
  ! corresponding computations.
  ! 
  ! First analyse the simulation kind. Depending on this kind, update 
  ! some global variables and say what input parameter sections have to 
  ! be searched.
  !
  ! Some general sections will always be searched anyway.
  !
  if (kind.eq.1) then
     !
     let search_alma  yes
     !
     let process 1
     let addshort no
     ! 
  else if (kind.eq.2) then
     !
     let search_aca   yes
     !
     let process 2
     let addshort no
     !
  else if (kind.eq.3) then
     !
     let search_alma  yes
     let search_aca   yes
     !
     let process 3
     let addshort no
     !
  else if (kind.eq.4) then
     !
     let search_sd    yes
     let search_alma  yes
     !
     let process 1
     let addshort yes
     !
  else if (kind.eq.5) then
     !
     let search_sd    yes
     let search_aca   yes
     !
     let process 2
     let addshort yes
     !
  else if (kind.eq.6) then
     !
     let search_sd    yes
     let search_alma  yes
     let search_aca   yes
     !
     let process 3
     let addshort yes
     !
  else if (kind.eq.7) then
     !
     let do_hybrid yes
     let do_compa yes
     !
  else
     !
     say "E-ALMA, should not be here"
     @ alma_error
     !
  endif
  !
  ! In addition, if the simulation kind changed, the simulation will have
  ! to compute the dirty maps, deconvolve and compare.
  !
  if (kind.ne.old_kind) then
     !
     if (kind.ne.7) then
        let do_uvmap yes
        let do_decon yes
        let do_compa yes
     else
        let do_compa yes
     endif
     !
  endif
  !
  ! First section: observation setup (always searched). 
  ! The model name is included in it.
  ! In this particular case, everything will have to be recomputed at
  ! one time or another. So reset everybody to yes.
  !
  let doit no
  if (model.ne.old_model) then
     SAY "Model changed from "'old_model'" to "'model'
     let doit yes
  endif
  if (output_dir.ne.old_output_dir) then
     SAY "Output_dir changed from "'old_output_dir'" to "'output_dir'
     let doit yes
  endif
  if (dec.ne.old_dec) then
     SAY "Dec changed from "'old_dec'" to "'dec'
     let doit yes
  endif
  if (change_size.ne.old_change_size) then
     SAY "Change_size changed from "'old_change_size'" to "'change_size'
     let doit yes
  endif
  if (image_size[1].ne.old_image_size[1]).or.(image_size[2].ne.old_image_size[2]) then
     SAY "Image_size changed from ["'old_image_size[1]'","'old_image_size[2]'"] to " -
     "["'image_size[1]'","'image_size[2]'"]"
     let doit yes
  endif
  if (freq.ne.old_freq) then
     SAY "Freq changed from "'old_freq'" to "'freq'
     let doit yes
  endif
  if (dfreq.ne.old_dfreq) then
     SAY "Dfreq changed from "'old_dfreq'" to "'dfreq'
     let doit yes
  endif
  let doit doit.or.(closest.ne.old_closest)
  if (mos_size[1].ne.old_mos_size[1]).or.(mos_size[2].ne.old_mos_size[2]) then
     SAY "Mos_size changed from ["'old_mos_size[1]'","'old_mos_size[2]'"] to " -
     "["'mos_size[1]'","'mos_size[2]'"]"
     let doit yes
  endif
  if (mos_orien.ne.old_mos_orien) then
     SAY "mos_orien changed from "'old_mos_orien'" to "'mos_orien'
     let doit yes
  endif
  if (closest.ne.old_closest) then
     SAY "Closest changed from "'old_closest'" to "'closest'
     let doit yes
  endif
  !
  if (doit) then
     !
     let do_setup yes
     let do_sd yes
     let do_alma yes
     let do_aca yes
     let do_uvmap yes
     let do_decon yes
     let do_compa yes
     !
  endif
  !
  ! Second section: single dish setup (sometimes searched).
  !
  if (search_sd) then
     SAY "Searching SD parameters"
     !
     let doit (sd_diam.ne.old_sd_diam)
     let doit doit.or.(sd_nant.ne.old_sd_nant)
     let doit doit.or.(sd_ppb.ne.old_sd_ppb)
     let doit doit.or.(sd_gpos.ne.old_sd_gpos)
     let doit doit.or.(sd_pe_code.ne.old_sd_pe_code)
     let doit doit.or.(sd_pointerr[1].ne.old_sd_pointerr[1])
     let doit doit.or.(sd_pointerr[2].ne.old_sd_pointerr[2])
     let doit doit.or.(sd_pe.ne.old_sd_pe)
     let doit doit.or.(sd_time.ne.old_sd_time)
     let doit doit.or.(sd_tsys.ne.old_sd_tsys)
     let doit doit.or.(sd_ampoff[1].ne.old_sd_ampoff[1])
     let doit doit.or.(sd_ampoff[2].ne.old_sd_ampoff[2])
     let doit doit.or.(sd_ampdrift.ne.old_sd_ampdrift)
     let doit doit.or.(sd_amptime.ne.old_sd_amptime)
     let doit doit.or.(sd_addnoise.ne.old_sd_addnoise)
     let doit doit.or.(sd_addcalerr.ne.old_sd_addcalerr)
     !
     if (doit) then
        let do_sd yes
     endif
     !
  endif
  !
  ! Third section: alma setup (sometimes searched).
  !
  if (search_alma) then
     !
     SAY "Searching ALMA parameters"
     let doit (diameter[1].ne.old_diameter[1])
     let doit doit.or.(array[1].ne.old_array[1])
     let doit doit.or.(config[1].ne.old_config[1])
     let doit doit.or.(hour[1,1].ne.old_hour[1,1])
     let doit doit.or.(hour[2,1].ne.old_hour[2,1])
     let doit doit.or.(horizon[1].ne.old_horizon[1])
     let doit doit.or.(pe_code[1].ne.old_pe_code[1])
     let doit doit.or.(pointerr[1,1].ne.old_pointerr[1,1])
     let doit doit.or.(pointerr[2,1].ne.old_pointerr[2,1])
     let doit doit.or.(int_pe[1].ne.old_int_pe[1])
     let doit doit.or.(trec[1].ne.old_trec[1])
     let doit doit.or.(tau[1].ne.old_tau[1])
     let doit doit.or.(addnoise[1].ne.old_addnoise[1])
     let doit doit.or.(phase_rms[1].ne.old_phase_rms[1])
     !
     if (doit) then
        let do_alma yes
     endif
     !
  endif
  !
  ! Fourth section: aca setup (sometimes searched).
  !
  if (search_aca) then
     SAY "Searching ACA parameters"
     !
     let doit (diameter[2].ne.old_diameter[2])
     let doit doit.or.(array[2].ne.old_array[2])
     let doit doit.or.(config[2].ne.old_config[2])
     let doit doit.or.(hour[1,2].ne.old_hour[1,2])
     let doit doit.or.(hour[2,2].ne.old_hour[2,2])
     let doit doit.or.(horizon[2].ne.old_horizon[2])
     let doit doit.or.(pe_code[2].ne.old_pe_code[2])
     let doit doit.or.(pointerr[1,2].ne.old_pointerr[1,2])
     let doit doit.or.(pointerr[2,2].ne.old_pointerr[2,2])
     let doit doit.or.(int_pe[2].ne.old_int_pe[2])
     let doit doit.or.(trec[2].ne.old_trec[2])
     let doit doit.or.(tau[2].ne.old_tau[2])
     let doit doit.or.(addnoise[2].ne.old_addnoise[2])
     let doit doit.or.(phase_rms[2].ne.old_phase_rms[2])
     !
     if (doit) then
        let do_aca yes
     endif
     !
  endif
  !
  ! Atmospheric parameters
  SAY "Searching Atmospheric Parameters"
  let doit do_screen.ne.old_do_screen
  let doit doit.or.(do_calib.ne.old_do_calib)
  let doit doit.or.(do_wvr.ne.old_do_wvr)
  let doit doit.or.(dumps[1].ne.old_dumps[1])
  let doit doit.or.(dumps[2].ne.old_dumps[2])
  let doit doit.or.(calangle[1].ne.old_calangle[1])
  let doit doit.or.(calangle[2].ne.old_calangle[2])
  let doit doit.or.(wind[1].ne.old_wind[1])
  let doit doit.or.(wind[2].ne.old_wind[2])
  let doit doit.or.(wind[3].ne.old_wind[3])
  let doit doit.or.(wvr[1].ne.old_wvr[1])
  let doit doit.or.(wvr[2].ne.old_wvr[2])
  let doit doit.or.(ispline.ne.old_ispline)
  let doit doit.or.(spline_step.ne.old_spline_step)
  !
  if (search_alma) then
     let doit doit.or.(phase_noise[1].ne.old_phase_noise[1])
     let doit doit.or.(phase_screen[1].ne.old_phase_screen[1])
     if (doit) then
        let do_alma yes
     endif
  endif
  if (search_aca) then
     let doit doit.or.(phase_noise[2].ne.old_phase_noise[2])
     let doit doit.or.(phase_screen[2].ne.old_phase_screen[2])
    if (doit) then
        let do_aca yes
     endif
  endif
  !
  !
  ! Fifth section: uvmap setup (always searched).
  ! Here the user want to have dirty map computations, deconvolution and 
  ! comparison done in a single step.
  !
  ! Must re-do uv_map if any of these has changed
  let doit do_alma.and.search_alma
  let doit doit.or.(do_aca.and.search_aca)
  let doit doit.or.(do_sd.and.search_sd)
  !
  let doit doit.or.(truncate[1].ne.old_truncate[1])
  let doit doit.or.(truncate[2].ne.old_truncate[2])
  let doit doit.or.(beam_scale[1].ne.old_beam_scale[1])
  let doit doit.or.(beam_scale[2].ne.old_beam_scale[2])
  let doit doit.or.(sd_rweight[1].ne.old_sd_rweight[1])
  let doit doit.or.(sd_rweight[2].ne.old_sd_rweight[2])
  let doit doit.or.(addshort.ne.old_addshort)
  !
  if (doit) then
     let do_uvmap yes
     let do_decon yes
     let do_compa yes
  endif
  !
  ! Sixth section: deconvolution setup (always searched).
  ! Here the user want to have deconvolution and comparison done in a 
  ! single step.
  !
  let doit (diter.ne.old_diter)
  let doit doit.or.(gains[1].ne.old_gains[1])
  let doit doit.or.(gains[2].ne.old_gains[2])
  let doit doit.or.(f_thres.ne.old_f_thres)
  let doit doit.or.(asmooth.ne.old_asmooth)
  let doit doit.or.(alma_method.ne.old_alma_method)
  !
  if (doit) then
     let do_decon yes
     let do_compa yes
  endif
  !
  ! Compute accordingly to previous analysis
  !
  let old_model 'model'
  let old_kind  kind
  !
  if (force_setup.or.do_setup) then
     !
     if (test) then
        say "setup"
     else
        @ alma_setup
     endif
     !
     ! Operation succeeded: update variables.
     !
     let old_change_dec  change_dec
     let old_dec         dec
     let old_change_size change_size
     let old_image_size  image_size
     let old_freq        freq
     let old_dfreq       dfreq
     let old_mos_size    mos_size
     let old_mos_orien   mos_orien
     let old_closest     closest
     !
  endif
  if (force_sd.or.(do_sd.and.search_sd)) then
     !
     if (test) then
        say "sd"
     else
        @ alma_single_dish
     endif
     !
     ! Operation succeeded: update variables.
     !
     let old_sd_diam      sd_diam
     let old_sd_nant      sd_nant
     let old_sd_ppb       sd_ppb
     let old_sd_gpos      sd_gpos
     let old_sd_pe_code   sd_pe_code
     let old_sd_pointerr  sd_pointerr
     let old_sd_pe        'sd_pe'
     let old_sd_time      sd_time
     let old_sd_tsys      sd_tsys
     let old_sd_ampoff    sd_ampoff
     let old_sd_ampdrift  sd_ampdrift
     let old_sd_amptime   sd_amptime
     let old_sd_addnoise  sd_addnoise
     let old_sd_addcalerr sd_addcalerr
     !
  endif
  if (force_alma.or.(do_alma.and.search_alma)) then
     !
     if (test) then
        say "alma"
     else
        @ alma_interfero 1
     endif
     !
     ! Operation succeeded: update variables.
     !
     let old_diameter[1]  diameter[1]
     let old_array[1]     'array[1]'
     let old_config[1]    'config[1]'
     let old_hour[1,1]    hour[1,1]
     let old_hour[2,1]    hour[2,1]
     let old_horizon[1]   horizon[1]
     let old_pe_code[1]   pe_code[1]
     let old_pointerr[,1] pointerr[,1]
     let old_int_pe[1]    'int_pe[1]'
     let old_trec[1]      trec[1]
     let old_tau[1]       tau[1]
     let old_addnoise[1]  addnoise[1]
     let old_phase_rms[1]   phase_rms[1]
     let old_phase_noise[1] phase_noise[1]
     !
  endif
  if (force_aca.or.(do_aca.and.search_aca)) then
     !
     if (test) then
        say "aca"
     else
        @ alma_interfero 2
     endif
     !
     ! Operation succeeded: update variables.
     !
     let old_diameter[2]  diameter[2]
     let old_array[2]     'array[2]'
     let old_config[2]    'config[2]'
     let old_hour[1,2]    hour[1,2]
     let old_hour[2,2]    hour[2,2]
     let old_horizon[2]   horizon[2]
     let old_pe_code[2]   pe_code[2]
     let old_pointerr[,2] pointerr[,2]
     let old_int_pe[2]    'int_pe[2]'
     let old_trec[2]      trec[2]
     let old_tau[2]       tau[2]
     let old_addnoise[2]  addnoise[2]
     let old_phase_rms[2]   phase_rms[2]
     let old_phase_noise[2] phase_noise[2] 
     !
  endif
  !
  let old_do_calib do_calib          
  let old_do_screen do_screen
  let old_phase_screen[1] 'phase_screen[1]'  ! Phase screen file name
  let old_phase_screen[2] 'phase_screen[2]'  ! Phase screen file name
  let old_calibrator 'calibrator'               ! Calibrator UV table
  let old_wind wind 
  let old_calangle calangle 
  let old_dumps    dumps 
  let old_ispline  ispline 
  let old_spline_step spline_step 
  let old_do_wvr do_wvr 
  let old_wvr wvr  
  !
  if (force_uvmap.or.do_uvmap) then
     !
     if (test) then
        say "uvmap"
     else
        @ alma_uvmap
     endif
     !
     ! Operation succeeded: update variables.
     !
     let old_truncate         truncate
     let old_beam_scale       beam_scale
     let old_sd_rweight       sd_rweight
     let old_addshort         addshort
     !
  endif
  if (force_decon.or.do_decon) then
     !
     if (test) then
        say "deconv"
     else
        @ alma_deconv
     endif
     !
     ! Operation succeeded: update variables.
     !
     let old_diter   diter
     let old_gains   gains
     let old_alma_method alma_method
     let old_f_thres f_thres
     let old_asmooth  asmooth
     !
  endif
  if (do_hybrid) then
     !
     if (test) then
        say "hybridation"
     else
        @ alma_hybridation
     endif
     !
     ! Operation succeeded: update variables.
     !
     let old_hybrid_uvradius hybrid_uvradius
     let old_hybrid_in1_code hybrid_in1_code
     let old_hybrid_in2_code hybrid_in2_code
     !
  endif
  if (force_compa.or.do_compa) then
     !
     if (test) then
        say "compare"
     else
        @ alma_compare
     endif
     !
     ! Operation succeeded: update variables.
     !
  endif
  !
  ! Always plot the results.
  !
  if (test) then
     say "display"
  else
     @ alma_display
  endif
  sic date
  let date_end "'sys_date'"
  SIC OUTPUT time.dat
  say "Started at "'date_begin'
  say "Ended at "'date_end'
  SIC OUTPUT
  type time.dat
  !
  ! Revert map%task to its beginning status
  let map%task in_map_task
  !
end procedure alma_compute
!
!-------------------------------------------------------------------------
!
! Button DISPLAY
!
!-------------------------------------------------------------------------
!
begin procedure alma_display
  !
  !
  !
  if (batch) then
     return
  endif
  !
  ! Verify that the user did not change the directory. 
  ! And then plots the results. It is assumed that each plotting procedure
  ! must verify that it has the useful file to make the plotting job.
  ! 
  if ((output_dir.ne.old_output_dir).and.cautious) then
     say "E-ALMA, You changed the output directory"
     say "E-ALMA, Please push the LOAD or the COMPUTE button"
  else if (kind.ne.old_kind.and.cautious) then
     say "E-ALMA, You changed the simulation kind"
     say "E-ALMA, Please push the LOAD or the COMPUTE button"
  else
     !
     change directory <greg
     destroy all
     let multi_window no
     !
     if (display_mode.eq.1) then
        @ alma_plot_fields
     else if (display_mode.eq.2) then
        @ alma_plot_sd
     else if (display_mode.eq.3) then
        @ alma_plot_uvweights
     else if (display_mode.eq.4) then
        @ alma_plot_beam
     else if (display_mode.eq.5) then
        @ alma_plot_cct
     else if (display_mode.eq.6) then
        @ alma_plot_image_comp
     else if (display_mode.eq.7) then
        @ alma_plot_uvplane_comp
     else if (display_mode.eq.8) then
        let multi_window yes
        @ alma_plot_fields
        @ alma_plot_sd
     else if (display_mode.eq.9) then
        let multi_window yes
        @ alma_plot_cct
        @ alma_plot_beam
        @ alma_plot_image_comp
        @ alma_plot_uvplane_comp
     else if (display_mode.eq.10) then
        @ alma_plot_phase
     else
        say "E-ALMA, should not be here"
        @ alma_error
     endif
     !
  endif
  !
let tmp_inname "tmp-ninp"
!
end procedure alma_display
!
!-------------------------------------------------------------------------
!
! Button PREPARE
!
!-------------------------------------------------------------------------
!
begin procedure alma_setup
  !
  ! Says it begins a new simulation.
  !
  let done no
  !
  ! Check directory
  !
  @ alma_change_outdir
  !
  ! Change single dish system temperature according to frequency.
  !
  if (freq.lt.400) then
     let sd_tsys '15+0.6*freq'
  else
     let sd_tsys 1200
  endif
  ! 
  ! Prepare input model image: dimension = power of 2.
  ! Output: 'inname'.gdf
  !
  @ alma_prepare
  !
  ! Change declination in 'inname'.gdf header
  ! 
  define header a 'inname'.gdf write
  if (change_dec) then
     let a%dec dec*pi/180.0
     let a%d0  dec*pi/180.0
  endif
  !
  ! Change image size in 'inname'.gdf header
  ! 
  if (change_size) then
     let a%convert[3,1] sign((image_size[1]*sec)/a%dim[1],a%convert[3,1])
     let a%convert[3,2] sign((image_size[2]*sec)/a%dim[2],a%convert[3,2])
     let a%convert[3,1] -abs(a%convert[3,1])  ! Mandatory for proper comparison
     let a%convert[3,2] abs(a%convert[3,2])
  endif
!
  if (a%ptype.eq.0) then
     let a%ptype 3
  endif
  if (a%spec.eq.0) then
     let a%spec 48
     let a%restfre freq*1e3
  endif
  let a%convert[2,] 0
  if (a%convert[1,1].ne.(a%dim[1]/2+1)).or.(a%convert[1,2].ne.(a%dim[2]/2+1)) then
     say "Warning, imaged recentered on ["'a%dim[1]/2+1'","'a%dim[2]/2+1'"]"
     let a%convert[1,1] a%dim[1]/2+1
     let a%convert[1,2] a%dim[2]/2+1
  endif
  delete /var a
  !
  ! Compute total model flux and get model name
  !
  define image a 'inname'.gdf read
  define real lambda
  compute fluxes[1] sum a
  let fluxes[1] fluxes[1]*abs(a%convert[3,1]*a%convert[3,2])
  let lambda 2.99792458e8|freq*1e-9
  let fluxes[1] 2.0*1.38e3*fluxes[1]|lambda^2
  let model_name 'a%source'
  delete /var a
  !
  ! Compute position of the mosaic fields from diameter of the largest 
  ! antenna (#1). 
  !
  let iarray 1
  let primbeam[iarray] 63*100/freq*12/diameter[iarray]
  @ alma_position
  !
  ! Say the procedure succeeded and save simulation state
  !
  let do_setup no
  @ alma_save parameters.map all
  !
end procedure alma_setup
!
!-------------------------------------------------------------------------
!
begin procedure alma_change_outdir
  !
  ! If the output directory has been changed by the user:
  !   1 If the directory already exists, usually warn the user. Else
  !     create a new directory.
  !   2 Go to this directory.
  !
  if (output_dir.ne.old_output_dir) then
     if (file(output_dir)) then
        if ((.not.batch).and.(cautious)) then 
           say "W-ALMA, Output directory already exists"
           pause
        endif
     else
        say "I-ALMA, Creating directory "'output_dir'
        sic mkdir 'output_dir'
     endif
     if (sic%directory.ne.working_dir) then
        sic directory 'working_dir'
     endif
     sic directory      'output_dir'
     let old_output_dir 'output_dir'
  endif
  !
end procedure alma_change_outdir
!
!-------------------------------------------------------------------------
!
begin procedure alma_prepare
  !
  ! prepares the model image: 
  ! - check weather the image is centered in an integer pixel
  ! - plunge the model in an image with power-of-two dimensions
  ! 
  if (.not.exist(refin)) then
     define double refin[2] /global
  endif
  define integer nx ny 
  define header mod 'model' read
  !
  ! find where is the (0,0)
  ! 
  let refin[1] -mod%convert[2,1]/mod%convert[3,1]+mod%convert[1,1]
  let refin[2] -mod%convert[2,2]/mod%convert[3,2]+mod%convert[1,2]
  if (abs(nint(refin[1])-refin[1]).gt.1e-3.or.abs(nint(refin[2])-refin[2]).gt.1e-3) then
     say "W-ALMA, Image not centered on an integer pixel"
     exa refin
  endif
  !
  ! find nearest power of two
  !
  if (.not.exist(nout)) then
     define integer nout /global
  endif
  ! 
  ! I do not understand that... If we want to preserve the coordinate system, it is more
  ! difficult to do...
  !!!  let nx max(refin[1]-1,mod%dim[1]-refin[1]+1)
  !!!  let ny max(refin[2]-1,mod%dim[2]-refin[2]+1)
  ! Make simple things: powers of 2, centered on middle of image...
  let nx mod%dim[1]
  let ny mod%dim[2]
  let refin mod%dim[1:2]/2+1 
  !
  let nout 2
  for /while (nout.lt.nx.or.nout.lt.ny)
     let nout 2*nout
  next
  if (nout.lt.mod%dim[1].or.nout.lt.mod%dim[2]) then
     let nout 2*nout
  endif
  say "I-ALMA, Creating a "'nout'" by "'nout'" image "
  !
  ! plunge model in output image
  !
  run extract gag_scratch:alma_prepare.init /nowin
  !
  ! end
  !
  delete /var nout refin
  !
end procedure alma_prepare
!
!-------------------------------------------------------------------------
!
begin procedure alma_position
  ! 
  ! Computes offsets for a mosaic
  ! - exact hexagonal pattern
  ! - there is always a field in (0,0) 
  !        => odd number of fields in each direction. 
  !
  ! local variables
  !
  define integer nra ndec k joff
  define real size_ra size_dec first_ra first_dec delta_ra delta_dec
  define real ra_off dec_off
  define real model_size[2] limit_size[2]
  define logical even jeven
  !
  ! Deletes the offset arrays and redefines them later as global variables 
  ! with the right dimension.
  !
  if (exist(xoffset)) then
     delete /var xoffset
  endif
  if (exist(yoffset)) then
     delete /var yoffset
  endif
  !
  ! Computes input image size
  !
  define header mod 'inname'.gdf read
  let model_size[1] mod%dim[1]*abs(mod%convert[3,1])/sec
  let model_size[2] mod%dim[2]*abs(mod%convert[3,2])/sec
  delete /var mod
  !
  ! Increases a bit the possible mosaic size to avoid loosing too much of 
  ! the input image in the mosaic definition because we impose to have an 
  ! odd number of fields in each direction. 
  !
  let limit_size model_size+0.5*primbeam[iarray]
  !
  ! Compares input image size to user-defined mosaic size
  !
  let size_ra  mos_size[1]
  let size_dec mos_size[2]
  if (size_ra.eq.0) then
     let size_ra  'limit_size[1]'
  endif
  if (size_dec.eq.0) then
     let size_dec 'limit_size[2]'
  endif
  if (size_ra.gt.limit_size[1]) then
     say "W-ALMA, Mosaic RA size is much larger than the input image"
  endif
  if (size_dec.gt.limit_size[2]) then
     say "W-ALMA, Mosaic Dec size is much larger than the input image"
  endif
  !
  ! Computes pixel size to obtain an hexagonal pattern. Takes into account
  ! the fact that an hexagonal pattern is asymetric in ra and dec (see 
  ! below).
  ! If you want something else than an hexagonal pattern this is the 
  ! place to make some modifications! 
  !
  if (mos_orien.eq.0.0) then
     let delta_ra  0.5*primbeam[iarray]
     let delta_dec 0.25*sqrt(3.0)*primbeam[iarray]
  else if (mos_orien.eq.90.0) then
     let delta_ra  0.25*sqrt(3.0)*primbeam[iarray]
     let delta_dec 0.5*primbeam[iarray]
  else
     say "E-ALMA_POSITION, mos_orien is neither 0 nor 90 deg"
     @ alma_error
  endif
  !
  ! `nra' and `ndec' are the number of beams the mosaic will have in ra 
  ! and dec. These must at least be 1.
  !
  let nra  max(1,int(size_ra/(2.0*delta_ra)))
  let ndec max(1,int(size_dec/(2.0*delta_dec)))
  !
  ! `first_ra' and `first_dec' are the coordiantes of the first 
  ! pointing position.
  !
  let first_ra    (nra-1)*delta_ra
  let first_dec -(ndec-1)*delta_dec
  !
  ! Finds position of fields in ra and dec.
  !
  define real xoff['2*nra-1'] yoff['2*ndec-1']
  for i 0 to 2*nra-2
     let xoff['i+1'] first_ra-delta_ra*i
  next
  for j 0 to 2*ndec-2
     let yoff['j+1'] first_dec+delta_dec*j
  next
  !
  ! Here is the hard part.
  !  - Tries to make a good use of the fact that an hexagonal pattern 
  !    is asymetric in ra and dec;
  ! That probably can be done in a more elegant way but that is working!
  !
  let k 1
  if (mos_orien.eq.0.0) then
     !
     let even (2*int(ndec/2).eq.ndec)
     if (even) then 
        let nfields (2*nra-2)*ndec+(2*nra-1)*(ndec-1)
     else
        let nfields (2*nra-2)*(ndec-1)+(2*nra-1)*ndec
     endif
     !
     define real xoffset[nfields] yoffset[nfields] /global
     !
     let ra_off 0.5*delta_ra
     for j 1 to 2*ndec-1
        let jeven (2*int(j/2).eq.j)
        if ((even.and.jeven).or.((.not.even).and.(.not.jeven))) then
           for i 1 to 2*nra-1
              let xoffset[k] xoff[i]
              let yoffset[k] yoff[j]
              let k k+1
           next
        else
           for i 1 to 2*nra-2
              let xoffset[k] xoff[i]-ra_off
              let yoffset[k] yoff[j]
              let k k+1
           next
        endif
     next
     !
  else
     !
     let even (2*int(nra/2).eq.nra)
     if (even) then 
        let nfields (2*ndec-2)*nra+(2*ndec-1)*(nra-1)
     else
        let nfields (2*ndec-2)*(nra-1)+(2*ndec-1)*nra
     endif
     !
     define real xoffset[nfields] yoffset[nfields] /global
     !
     let dec_off 0.5*delta_dec
     for j 1 to 2*nra-1
        let jeven (2*int(j/2).eq.j)
        if ((even.and.jeven).or.((.not.even).and.(.not.jeven))) then
           for i 1 to 2*ndec-1
              let xoffset[k] xoff[j]
              let yoffset[k] yoff[i]
              let k k+1
           next
        else
           for i 1 to 2*ndec-2
              let xoffset[k] xoff[j]
              let yoffset[k] yoff[i]+dec_off
              let k k+1
           next
        endif
     next
     !
  endif
  !
  ! When asked, selects only the fields which are in a circular region 
  ! (i.e. the closest neighbours of the central field).
  !
  if (closest) then
     define real new_xoffset[nfields] new_yoffset[nfields]
     define real circular_limit
     ! The 1.01 factor comes from rounding problems.
     if (mos_orien.eq.0.0) then
        let circular_limit (1.01*(nra-1)*delta_ra)^2 
     else
        let circular_limit (1.01*(ndec-1)*delta_dec)^2
     endif
     let k 1
     for i 1 to nfields
        say 'circular_limit' 'xoffset[i]^2+yoffset[i]^2'
        if ((xoffset[i]^2+yoffset[i]^2).le.circular_limit) then
           let new_xoffset[k] xoffset[i]
           let new_yoffset[k] yoffset[i]
           let k k+1
        endif
     next
     delete /var xoffset yoffset
     let nfields k-1
     define real xoffset[nfields] yoffset[nfields] /global
     let xoffset new_xoffset[1:nfields]
     let yoffset new_yoffset[1:nfields]
     delete /var new_xoffset new_yoffset
  endif
  !
  ! Plots the field positions.
  !
  let multi_window no
  @ alma_plot_fields
  !
  ! Mosaic case?
  ! 
  if (nfields.gt.1) then
     let mosaic yes
  else 
     let mosaic no
  endif
  !
  ! Final message.
  !
  say " "
  say "I-ALMA, Frequency = "'freq'" GHz"
  say "I-ALMA, Primary beam = "'nint(primbeam[iarray]*100)/100'" arcsec"
  say "I-ALMA, Mosaic needs "'nfields'" fields"
  say " "
  !
end procedure alma_position
!
!-------------------------------------------------------------------------
!
begin procedure alma_plot_fields
  !
  ! Do not plot when on batch mode
  !
  if (batch) then
     return
  endif
  !
  ! Prepare plotting window
  !
  if (multi_window) then
     !
     create dir <fields /geometry 'window_size[1]' 'window_size[2]'
     change dir <fields
     ! sic wait 'wait_time'
     change pos 9
     !
  else
     destroy all
  endif
  !
  define real half_ra half_dec
  define real size_ra size_dec model_size[2]
  !
  ! Computes input image size and mosaic size
  !
  define header mod 'inname'.gdf read
  let model_size[1] mod%dim[1]*abs(mod%convert[3,1])/sec
  let model_size[2] mod%dim[2]*abs(mod%convert[3,2])/sec
  delete /var mod
  !
  let size_ra  mos_size[1]
  let size_dec mos_size[2]
  if (size_ra.eq.0) then
     let size_ra  'model_size[1]'
  endif
  if (size_dec.eq.0) then
     let size_dec 'model_size[2]'
  endif
  !
  ! Plot image
  !
  let name 'inname'
  let type gdf
  sic\@ p_load.greg aaa        ! Load image & compute extrema if needed 
  sic\@ p_scale.greg aaa       ! Compute scaling 
  sic\@ p_level.greg aaa       ! Compute levels must come AFTER p_scale
  sic\@ alma_header.greg aaa      ! Draw header 
  rgdata aaa /variable
  limits /rgdata
  set box 3.600000       22.70000       1.799999       20.90000
  plot /scaling lin true_scale[1] true_scale[2]
  set expand 1.0
  box /absolute
  !
  ! Plot fields
  !
  set marker 4 1 0.4 45
  points xoffset yoffset
  !
  pen 1 /weight 3
  for i 1 to nfields
     ellipse 'primbeam[iarray]/2' /user 'xoffset[i]' 'yoffset[i]' sec 
  next
  !
  ! Plot box that define the mosaic size
  !
  if ((size_ra.lt.model_size[1]).and.(size_dec.lt.model_size[2])) then
     let half_ra  0.5*size_ra
     let half_dec 0.5*size_dec
     draw relocate -half_ra  half_dec /user seconds
     draw line     -half_ra -half_dec /user seconds
     draw line      half_ra -half_dec /user seconds
     draw line      half_ra  half_dec /user seconds
     draw line     -half_ra  half_dec /user seconds
  else if (size_ra.lt.model_size[1]) then
     let half_ra  0.5*size_ra
     let half_dec 0.5*model_size[2]
     draw relocate -half_ra  half_dec /user seconds
     draw line     -half_ra -half_dec /user seconds
     draw relocate  half_ra -half_dec /user seconds
     draw line      half_ra  half_dec /user seconds
  else if (size_dec.lt.model_size[2]) then
     let half_ra  0.5*model_size[1]
     let half_dec 0.5*size_dec
     draw relocate -half_ra  half_dec /user seconds
     draw line      half_ra  half_dec /user seconds
     draw relocate  half_ra -half_dec /user seconds
     draw line     -half_ra -half_dec /user seconds
  endif
  !
  pen 0
  go wedge
  !
  ! Print when asked
  !
  if (alma_print) then
     @ alma_print fields.eps 
  endif
  !
end procedure alma_plot_fields
!
!-------------------------------------------------------------------------
!
! Button SINGLE DISH
!
!-------------------------------------------------------------------------
!
begin procedure alma_single_dish
  !
  ! Say it begins or continues a new simulation.
  !
  let done no
  !
  ! Compute SD noise level (in K) from SD integration time
  !
  let sd_sigma '2.0*sd_tsys/sqrt(sd_nant*dfreq*1e6*sd_time*3600.0)'
  !
  ! Defines the sampling grid for use by `short_model'.
  !
  run image_sampling gag_scratch:image_sampling.init /nowin
  !
  ! Adds at the beginning of the `sd_pnt' file the positions of the centers
  ! of the mosaic fields for use by `uv_zero'.
  !
  define integer sd_occur jstart jend
  define image grid 'sd_pnt'.tab read
  let sd_occur int(grid%dim[1]/nfields)
  let sd_nsamp 2*grid%dim[1]
  define image used_grid['sd_nsamp','sd_nant',2] 'sd_used_pnt'.tab real
  let used_grid%source 'model'
  for i 1 to sd_nant
     let jstart 1
     for j 1 to sd_occur
        let jend jstart+nfields-1
        let used_grid[jstart:jend,i,1] xoffset*sec
        let used_grid[jstart:jend,i,2] yoffset*sec
        let jstart jend+1
     next
     if (jend.lt.grid%dim[1]) then
        let jend grid%dim[1]
        let used_grid[jstart:jend,i,1] xoffset[1:'jend-jstart+1']*sec
        let used_grid[jstart:jend,i,2] yoffset[1:'jend-jstart+1']*sec
        let jstart jend+1
     endif
  next
  let used_grid[jstart:sd_nsamp,,] grid
  let sd_inttime sd_time*3600.0/grid%dim[1] ! Sampling rate in seconds...
  delete /var grid used_grid
  !
  ! Now defines the corresponding pointing error file when `sd_pe' exists.
  !
  if (sd_pe_code.eq.5) then
     if (file(sd_pe)) then
        @ alma_smooth_pe 'sd_inttime' 'sd_time' 'sd_pe' smoothed_pe
        define image smoothed_pe_tab smoothed_pe.tab read
        define image sd_used_pe_tab[sd_nsamp,sd_nant,2] 'sd_used_pe'.tab real
        if ((smoothed_pe_tab%dim[1].lt.sd_nsamp/2).or.(smoothed_pe_tab%dim[2].lt.sd_nant)) then
           say "E-ALMA, Dimensions of pointing error file not adapted to " -
               "parameters of single dish observations"
           @ alma_error
        endif
        let sd_used_pe_tab[1:'sd_nsamp/2',,]          smoothed_pe_tab[1:'sd_nsamp/2',1:sd_nant,1:2]
        let sd_used_pe_tab['1+sd_nsamp/2':sd_nsamp,,] smoothed_pe_tab[1:'sd_nsamp/2',1:sd_nant,1:2]
        delete /var smoothed_pe_tab sd_used_pe_tab
        sic delete smoothed_pe.tab
     else
        say "E-ALMA, the file "'sd_pe'" does not exist"
        say "E-ALMA, Contact gildas@iram.fr to get this default file"
        @ alma_error
     endif
  endif
  !
  ! Computes the the corresponding single dish observations (with 
  ! pointing errors, thermal noise, and calibration errors)
  !
  run short_model gag_scratch:short_model.init /nowin
  !
  ! Averages the fluxes coming from the `sd_nant'.
  ! *** This assumes that the observed positions are identical for all ***
  ! *** the SD antennas.                                               ***
  !
  define image sd_res_tab 'sd_res'.tab read
  define image sd_sing_tab['sd_res_tab%dim[1]','sd_res_tab%dim[3]'] 'sd_sing'.tab real
  !
  let sd_sing_tab% sd_res_tab%
  let sd_sing_tab[1:2,] sd_res_tab[1:2,1,]
  let sd_sing_tab[3:4,] 0.0
  for i 1 to sd_nant
     let sd_sing_tab[3,] sd_sing_tab[3,]+sd_res_tab[3,i,]
     let sd_sing_tab[4,] sd_sing_tab[4,]+sd_res_tab[4,i,]*sd_res_tab[3,i,]
  next
  let sd_sing_tab[4,] sd_sing_tab[4,]/sd_sing_tab[3,]
  delete /var sd_res_tab sd_sing_tab
  !
  sic delete 'sd_res'.tab
  !
  ! Extracts the fluxes corresponding to the mosaic field centers and 
  ! writes them in 'sd_zero'.uvt
  !
  sic rename 'sd_sing'.tab 'sd_res'.tab
  define image sd_res_tab 'sd_res'.tab read
  define image sd_sing_tab['sd_res_tab%dim[1]','sd_res_tab%dim[2]/2'] -
    'sd_sing'.tab real
  define image uvzero['nfields',2] 'sd_zero'.uvt real
  !
  let uvzero%source 'model'
  !
  let uvzero 0.0
  let jstart 1
  for j 1 to sd_occur
     let jend jstart+nfields-1
     let uvzero[,1] uvzero[,1]+sd_res_tab[4,jstart:jend]*sd_res_tab[3,jstart:jend] ! uv amplitude.
     let uvzero[,2] uvzero[,2]+sd_res_tab[3,jstart:jend]                           ! uv weight. 
     let jstart jend+1
  next
  !
  if (jend.lt.'sd_nsamp/2') then
     define integer nend
     let nend sd_nsamp/2-jend 
     let uvzero[1:nend,1] uvzero[1:nend,1]+sd_res_tab[4,jstart:'sd_nsamp/2']*sd_res_tab[3,jstart:'sd_nsamp/2'] ! uv amplitude.
     let uvzero[1:nend,2] uvzero[1:nend,2]+sd_res_tab[3,jstart:'sd_nsamp/2']                                   ! uv weight. 
  endif
  !
  let uvzero[,1] uvzero[,1]/uvzero[,2]
  !
  say " "
  say "I-ALMA, Flux measured by SD antennas ("'sd_diam'"m) at" -
      "ALMA pointing centers"
  for i 1 to nfields
     say "I-ALMA, uvzero =" 'uvzero[i,1]' "Jy for field #" 'i' 
  next
  say " "
  !
  let sd_sing_tab% sd_res_tab%
  let sd_sing_tab sd_res_tab[,'sd_nsamp/2+1':sd_nsamp]
  delete /var sd_res_tab sd_sing_tab uvzero
  !
  sic delete 'sd_res'.tab
  !
  ! Plot the resulting observation
  !
  if (alma_pipeline) then
     let multi_window yes
  endif
  @ alma_plot_sd
  !
  ! Free disk space
  !
  sic delete 'sd_used_pnt'.tab singledish.lmv
  !
  ! Say the procedure succeeded and save simulation state
  !
  let do_sd no
  @ alma_save parameters.map all
  !
end procedure alma_single_dish
!
!-------------------------------------------------------------------------
!
begin procedure alma_plot_sd
  !
  ! Do not plot when on batch mode
  !
  if (batch) then
     return
  endif
  !
  ! Prepare plotting window
  !
  if (multi_window) then
     !
     create dir <sd_map /geometry 'window_size[1]' 'window_size[2]'
     change dir <sd_map
     ! sic wait 'wait_time'
     change pos 3
     !
  endif
  !
  ! Verify that needed files exist
  ! 
  if (.not.file("'sd_sing'.tab")) then
     say "E-ALMA, Simulation of single dish observations has not yet been made."
     return
  endif
  !
  ! Plot the obtained SD map:
  !   1 transposition
  !   2 interpolation
  !   3 plotting
  !
  transpose 'sd_sing'.tab 'sd_sing'.bat 21
  !
  sic\@ alma_header.greg ! Draw header 
  !
  column x 1 y 2 z 4 /table 'sd_sing'.bat
  let x x/sec
  let y y/sec
  limits /reverse x
  random_map 128 128 /blanking 0 0
  set expand 1.0
  set box 3.600000 22.70000 1.799999 20.90000
  box
  plot /scaling lin 
  let true_scale rgmin rgmax
  !
  ! Plot observed positions by SD
  !
  column x 1 y 2 /table 'sd_sing'.bat
  let x x/sec
  let y y/sec
  set marker 4 1 0.3 45.0
  points
  column /close
  !
  ! Plot interferometric mosaic
  !
  pen 1 /weight 3
  for i 1 to nfields
     ellipse 'primbeam[1]/2' /user 'xoffset[i]' 'yoffset[i]'
  next
  pen 0
  !
  ! Free disk space.
  !
  sic delete 'sd_sing'.bat
  !
  ! Plot wedge
  ! 
  go wedge
  !
  ! Print when asked
  !
  if (alma_print) then
     @ alma_print sd.eps 
  endif
  !
  ! Returns to main window
  !
  if (multi_window) then
     change dir <greg
  endif
  !
end procedure alma_plot_sd
!
!-------------------------------------------------------------------------
!
! Buttons ALMA/ACA ARRAY
!
!-------------------------------------------------------------------------
!
begin procedure alma_interfero
  !
  ! Says it begins or continues a new simulation.
  !
  let done no
  !
  ! this procedure has an input parameter: &1 is the array to be 
  ! used  1 = ALMA  2 = ACA  
  !
  let iarray &1
  !
  ! Check diameter
  !
  if (diameter[iarray].le.0) then
     say "E-ALMA, Wrong diameter"
     @ alma_error
  else if (diameter[iarray].gt.12) then
     say "W-ALMA, Diameter larger than 12 m ??"
     pause
  endif
  !
  ! Primary beam
  ! 
  let primbeam[iarray] 63*100/freq*12/diameter[iarray]
  !
  ! Plot field positions
  !
  let multi_window no
  @ alma_plot_fields
  !
  ! Find number of antennas
  !
  column x 1 /file 'config_dir'"/"'array[iarray]'-'config[iarray]'.cfg 
  column /close
  let int_nant[iarray] nxy
  if (int_nant[iarray].eq.-1) then
     say "E-ALMA, Configuration file "'array[iarray]'"-"'config[iarray]'".cfg is empty"
     @ alma_error
  endif
  say " "
  say "I-ALMA, Using configuration file "'array[iarray]'"-"'config[iarray]'".cfg"
  say "I-ALMA, Number of "'diameter[iarray]'"-m antennas: "'int_nant[iarray]' 
  say " "
  !
  ! Check input image
  ! 
  define header a_a 'inname'.gdf read
!SG-Hum!   let dec '(a_a%dec)/pi*180.'
  let dec '(a_a%dec)/pi*180.' !JP-Hum!
  if (a_a%convert[1,1].ne.(a_a%dim[1]/2+1)).or.(a_a%convert[1,2].ne.(a_a%dim[2]/2+1)) then
     say "Image must be centered on ["'a_a%dim[1]/2+1'","'a_a%dim[2]/2+1'"]"
     say "Use the PREPARE tool to do it"
     @ alma_error
  endif 
  delete /var a_a
  !
  ! Single-field or mosaic case
  !
  if (nfields.eq.1) then
     say "I-ALMA, Running single field procedure"
     say " "
     if (do_screen) then
        if (.not.file(phase_screen[iarray])) then
           say "E-ALMA, No phase screen file"
           say "E-ALMA, Contact gildas@iram.fr to get this default file"
           @ alma_error
        endif
        @ alma_single_phase  ! SG-Phase
     else
        @ alma_single
     endif
  else
     say "I-ALMA, Running mosaic procedure ("'nfields'" fields)"
     say " "
     if (do_screen) then
        if (.not.file(phase_screen[iarray])) then
           say "E-ALMA, No phase screen file"
           say "E-ALMA, Contact gildas@iram.fr to get this default file"
           @ alma_error
        endif
        @ alma_mosaic_phase  ! SG-Phase
     else
        @ alma_mosaic
     endif
  endif
  !
  ! Say the procedure succeeded and save simulation state
  !
  if (iarray.eq.1) then
     let do_alma no
  endif
  if (iarray.eq.2) then
     let do_aca  no
  endif
  @ alma_save parameters.map all
  !
end procedure alma_interfero
!
!-------------------------------------------------------------------------
!
begin procedure alma_single
  !
  ! Antenna type is given by the global variable: `iarray'
  !
  ! local variables
  ! 
  define integer oiter  
  !
  ! uv_track
  !
  let inttime 0.0   ! In seconds 
  run uv_track gag_scratch:alma_uv.init /nowin
  !
  ! check the pointing error file
  !   
  if (pe_code[iarray].eq.5) then
     if (.not.file(int_pe)) then
        say "E-ALMA, No pointing error file"
        say "E-ALMA, Contact gildas@iram.fr to get this default file"
        @ alma_error
     endif
  endif
  !
  ! Read the integration time, smooth the pointing error table
  !
  ! Use 'name' for the pointing error filename to be used by 
  ! uv_pointing: could be ascii or gdf file depending on pe_code
  !
  ! *** We dont test the pointing table dimensions: it has to
  ! *** be (NTT,NA,2) with NTT = number of visibility dump
  ! ***			 NA = number of antennas
  ! 
  if (pe_code[iarray].eq.5) then
     say "I-ALMA, Smoothing the pointing error table"
     define header hh 'uv_coverage'.uvt read
     let inttime[iarray] hh%convert[3,2]
     delete /var hh
     say ""
     say "Integration time per visibility" 'inttime[iarray]'
     say ""
     @ alma_smooth_pe 'inttime[iarray]' 'hour[2,iarray]-hour[1,iarray]' 'int_pe' 'int_used_pe'
  endif
  !
  ! Apply primary beam on the model image
  !
  run primary gag_scratch:alma_primary.init /nowin
  !
  ! Simulate visibilities
  ! Note: - uv_fmodel takes as input `pbeamed' = image WITH primary beam
  !       - uv_pointing takes as input `inname' = image WITHOUT primary 
  ! 	  beam but then deals with the primary beam
  ! The results are in 'result'.uvt
  !               
  if (pe_code[iarray].eq.1) then
     run uv_fmodel gag_scratch:alma_model.init /nowin
  else
     run uv_pointing_new gag_scratch:alma_point.init /nowin
  endif
  !
  ! Add noise ?
  !
  if (addnoise[iarray]) then
     say "I-ALMA, Adding noise to the simulations"
     @ alma_addnoise
  endif
  !
  ! The results are in 'result'.uvt
  ! Now make explicit name (`int_name[iarray]'-only)
  !
  sic copy 'result'.uvt 'int_name[iarray]'-only.uvt
  !
end procedure alma_single
!
!-------------------------------------------------------------------------
!
begin procedure alma_mosaic
  ! 
  ! local variables
  !
  define integer oiter
  define integer number_visib nbase nv 
  define integer nn index ! various index 
  define real n_visib inttime_max
  ! 
  ! Antenna type is the global variable: `iarray'
  !
  let nant int_nant[iarray]
  !  
  ! uv_track 
  !
  let inttime[iarray] 0.
  run uv_track gag_scratch:alma_uv.init /nowin
  !
  ! get integration time (Nyquist rate) and compare it to the maximum
  ! integration time needed to have one full coverage of the mosaic
  ! 
  define header hh 'uv_coverage'.uvt read
  let inttime[iarray] hh%convert[3,2]
  delete /var hh
  let inttime_max abs(hour[2,iarray]-hour[1,iarray])*3600/nfields
  if (inttime[iarray].gt.inttime_max) then
     say " "
     say "W-ALMA, The hour angle range is too short"
     say "W-ALMA, Using integration time = "'inttime_max'" sec"
     say " "
     let inttime[iarray] inttime_max       ! in Seconds
     run uv_track gag_scratch:alma_uv.init /nowin
  endif
  !
  ! nb visibilities = (nb baselines)x(nb fields)x(iteration) 
  ! find int(iteration) = full_iter
  !
  define header hh 'uv_coverage'.uvt read
  let number_visib hh%dim[2]
  let inttime[iarray] hh%convert[3,2]
  let nbase nant*(nant-1)/2
  !
  !SG-Shadowing begin
  ! This does not work. It assumes there is never any shadowing
  !             
  !       let n_visib number_visib/nbase
  !
  ! Use UV_SPLITFIELD to scan properly the UV table
  !
  if (.not.exist(n_times)) then
    define integer n_times /global
  endif
  if (exist(n_bases)) then
    delete /var n_bases
  endif
  if (file("uv_scantime.tmp")) then
    sic delete uv_scantime.tmp
  endif
  run uv_splitfield gag_scratch:uv_scantime.alma /nowindow
  @ uv_scantime.tmp n_times n_bases
  sic delete uv_scantime.tmp
  let n_visib n_times ! That must be correct
  !SG-Shadowing end
  say " "
  say "I-ALMA, Simulated observations:"
  say "  Hour angle range: "'hour[1,iarray]'" to "'hour[2,iarray]'
  say "  Integration time per dump: "'inttime[iarray]'" sec"
  say "  Maximum nb of baselines: "'nbase'", Actual numbers"
  exa n_bases
  say "  Nb of time dumps: "'n_visib'
  let full_iter int(n_visib/nfields)
  say "  Nb of full iterations on the "'nfields'"-fields mosaic: "'full_iter'
  say "  Nb of visibility dumps used: "'nfields*full_iter'
  say "  Nb of visibility dumps NOT used: "'n_visib-nfields*full_iter'
  say " "
  if (full_iter.eq.0) then
     say "E-ALMA, All fields must have been observed! Increase HA range."
     @ alma_error
  endif
  !
  ! check the pointing error file
  ! - if no pointing errors (pe_code = 0) or if the file doesn't exist, 
  !   create an empty file
  ! - otherwise smooth it to the integration time
  ! in both case, the pointing error file to be used is `int_used_pe'.
  !
  ! *** We dont test the pointing table dimensions: it has to
  ! *** be (NTT,NA,2) with NTT = number of visibility dump	
  ! ***			 NA = number of antennas
  !
  if (pe_code[iarray].ne.5) then
     say "I-ALMA, Creating a pointing error table"
!SG-Shadowing
!     let nv (number_visib/nbase)   ! is an integer, except if shadowing...
     let nv n_visib   ! This is the actual number of time steps...
     define image aa[nv,nant,2] 'int_used_pe'.tab real
     let aa% hh%
     let aa 0.
     delete /var aa
  else
     if (.not.file(int_pe)) then
        say "E-ALMA, No pointing error file"
        say "E-ALMA, Contact gildas@iram.fr to get this default file"
        @ alma_error
     endif
     say "I-ALMA, Smoothing the pointing error table"
     @ alma_smooth_pe 'inttime[iarray]' 'hour[2,iarray]-hour[1,iarray]' 'int_pe' 'int_used_pe'
  endif
  delete /var hh
  !
  ! edit the pointing error file to add the mosaic field offsets
  ! 
  define image err 'int_used_pe'.tab write
  let nn 0
  for i 1 to err%dim[1] 
     let nn nn+1
     if (nn.gt.nfields) then
        let nn 1
     endif
     let err[i,,1] err[i,,1]+xoffset[nn]
     let err[i,,2] err[i,,2]+yoffset[nn]
  next
  delete /var err
  !
  ! compute visibilities
  !
  run uv_pointing_new gag_scratch:alma_point.init /nowin
  !
  ! add noise ?
  !
  if (addnoise[iarray]) then
     say "Adding noise to the simulations"
     @ alma_addnoise
  endif
  !
  let fullname 'int_name[iarray]'-only
  !
  ! Split them in individual fields
  !
  run uv_splitfield gag_scratch:uv_splitfield.alma /nowindow
  for i 1 to nfields
     define uvtable aa 'fullname'-'i'.uvt write
     let aa%dec aa%dec+yoffset[i]*sec	        ! do NOT modify a0 and d0
     let aa%ra aa%ra+xoffset[i]/cos(aa%dec)*sec ! do NOT modify a0 and d0
     let aa%ptype 3 		     		! indispensable!!
     delete /var aa
  next
  !
end procedure alma_mosaic
!
!-------------------------------------------------------------------------
!
begin procedure alma_smooth_pe
  !
  ! Smooth pointing error table to the integration time defined by UV_TRACK
  ! 
  ! *** One should check the integration time in the input table
  ! *** Here, it is assumed to be 1sec
  !
  define integer nsamp nout nant nsmo
  define character fine_pe*128 smoothed_pe*128
  let nsmo        &1
  let nout        int(&2*3600.0/&1)+1
  let fine_pe     "&3"
  let smoothed_pe "&4"
  !
  define image afine 'fine_pe' read
  let nsamp afine%dim[1]
  let nant  afine%dim[2]
  if (nsamp.lt.nout) then
     say "E-ALMA, input pointing error table not long enough"
     @ alma_error
  endif
  !
  define image bsmo[nout,nant,2] 'smoothed_pe'.tab real
  define 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
  delete /var afine bsmo
  !
end procedure alma_smooth_pe
!
!-------------------------------------------------------------------------
!
begin procedure alma_addnoise
  !
  ! add noise to the uv_table 'result'.uvt
  ! - thermal noise deduced from weights
  ! - phase noise in variable phase   
  ! 
  define uvtable tt 'result'.uvt write
  define integer nn
  let nn tt%dim[2]			 ! number of visibilities
  define real thermal[nn] pha[nn] amp[nn] p[nn]
  !
  let thermal 1e-3/sqrt(tt[10,])     	 ! sigma in Jy
  !
  !let pha atan2(tt[9,],tt[8,])           ! phase
  !let amp sqrt(tt[8,]**2+tt[9,]**2)  	 ! amplitude
  !let p phase_rms[iarray]*pi/180		 ! phase noise in rad
  !let pha pha+noise(p)			 ! phase+phase noise
  !let tt[8,] amp*cos(pha)+noise(thermal) ! back to (real, imag) and
  !let tt[9,] amp*sin(pha)+noise(thermal) ! add thermal noise
  let tt[8,] tt[8,]+noise(thermal)
  let tt[9,] tt[9,]+noise(thermal)
  !
  delete /var tt
  !
end procedure alma_addnoise
!
!-------------------------------------------------------------------------
!
! Button UV->MAP
!
!-------------------------------------------------------------------------
!
begin procedure alma_uvmap
  !
  ! Says it begins or continues a new simulation.
  !
  let done no
  !
  ! Local variables
  !
  define integer istart iend
  define character dummy_name*32[2]
  !
  let dummy_name[1] 'int_name[1]'-only
  let dummy_name[2] 'int_name[2]'-only
  !
  ! `iarray' will be the interferometer array to which single dish data
  ! is added.
  !
  if (process.eq.1) then
     !
     ! Process ALMA only.
     !
     let iarray 1
     let istart 1
     let iend   1
     !
  else if (process.eq.2) then
     !
     ! Process ACA only.
     !
     let iarray 2
     let istart 2
     let iend   2
     !
  else if (process.eq.3) then
     !
     ! Process ALMA and ACA. Add short spacing to ACA when asked.
     !
     ! *** Assumes that the `diameter[2]' is the smallest interferometer 
     !     diameter.
     !
     let iarray 2
     let istart 1
     let iend   2
     !
  else
     !
     say "E-ALMA, should not be here"
     @ alma_error
     !
  endif
  !
  ! alma_add_short: when asked, add zero or short spacings deduced from 
  !                 the single dish observations to the small antenna uv 
  !                 table.
  !
  if (addshort) then
     @ alma_add_short
     let dummy_name[iarray] 'int_name[iarray]'-short
  else
     let dummy_name[iarray] 'int_name[iarray]'-only
  endif
  !
  ! Loop over the array
  !
  for i istart to iend
     !
     ! Need to know the array kind and simulation name on a global level
     !
     let iarray i
     let name 'dummy_name[iarray]'
     !
     ! alma_sampling: find MAP_CELL, MAP_SIZE, and binning factor
     !
     @ alma_sampling
     !
     ! alma_dirty_maps: Makes dirty maps.
     !
     @ alma_dirty_maps
     !
  next
  !
  ! Delete variables
  !
  delete /var istart iend dummy_name
  !
  ! Say the procedure succeeded and save simulation state
  !
  let do_uvmap no
  @ alma_save parameters.map all
  !
end procedure alma_uvmap
!
!-------------------------------------------------------------------------
!
begin procedure alma_add_short
  ! 
  ! Do circular averaging and derive the density of uv points
  !
  if (mosaic) then
     let fullname 'int_name[iarray]'-only-1
  else
     let fullname 'int_name[iarray]'-only
  endif
  let uvrange '1.25*diameter[iarray]' 0.0
  let rstep   '1.25*diameter[iarray]'
  run uv_circle gag_scratch:alma_uvcircle.init /nowin
  !
  define real in_wdens out_wdens
  !
  define uvtable uvt 'fullname'-avg.uvt read
  let out_wdens uvt[10,1]
  delete /var uvt
  sic delete 'fullname'-avg.uvt
  !
  let out_wdens out_wdens/(3.0*pi*rstep^2)
  !
  ! Case: 
  !   1 single dish antenna is LARGER than interferometer
  !     ==> add short spacings to the small antenna uv-table
  !   2 single dish antenna is IDENTICAL to interferometer
  !     ==> add zero spacings to the small antenna uv-table
  !   3 single dish antenna is SMALLER than interferometer
  !     ==> Cannot do anything
  !
  if (sd_diam.gt.diameter[iarray]) then
     !
     define real xoffset_rad[nfields] yoffset_rad[nfields] /global
     !
     let xoffset_rad xoffset*sec
     let yoffset_rad yoffset*sec
     !
     run uv_short gag_scratch:alma_uvshort.init /nowin
     !
     delete /var xoffset_rad yoffset_rad
     !
     if (mosaic) then
        define uvtable shortspacings_uvt 'shortspacings'-1.uvt read
     else
        define uvtable shortspacings_uvt 'shortspacings'.uvt read
     endif
     compute in_wdens sum shortspacings_uvt[10,] 
     delete /var shortspacings_uvt
     !
     let in_wdens in_wdens/(pi*(rstep)^2)
     !
     if (in_wdens.ne.0) then
        let sd_weight 'out_wdens/in_wdens'
     else
        say "E-ALMA, the short spacing has a zero weight density"
        @ alma_error
     endif
     !
     let sd_weight 'sd_weight*sd_rweight[iarray]'
     !
     for i 1 to nfields
        !
        if (mosaic) then
           let in2 'int_name[iarray]'-only-'i'
           let in1 'shortspacings'-'i'
           let out 'int_name[iarray]'-short-'i'
        else
           let in2 'int_name[iarray]'-only
           let in1 'shortspacings'
           let out 'int_name[iarray]'-short
        endif
        !
        run uv_merge gag_scratch:alma_uvmerge.init /nowin
        !
     next
     !
  else if (sd_diam.eq.diameter[iarray]) then
     !
     define image uvzero 'sd_zero'.uvt read
     if (.not.exist(zscf)) then
        define real zscf zs_weight /global
     endif
     !
     compute in_wdens sum uvzero[,2] 
     !
     let in_wdens in_wdens/(pi*(rstep)^2)
     let in_wdens in_wdens
     !
     if (in_wdens.ne.0) then
        let sd_weight '(out_wdens/in_wdens)*(diameter[iarray]^4/sd_diam^4)'
     else
        say "E-ALMA, the short spacing has a zero weight density"
        @ alma_error
     endif
     !
     let sd_weight 'sd_weight*sd_rweight[iarray]'
     !
     for i 1 to nfields
        !
        if (mosaic) then
           sic copy 'int_name[iarray]'-only-'i'.uvt 'int_name[iarray]'-short-'i'.uvt
           let in1  'int_name[iarray]'-short-'i'
        else
           sic copy 'int_name[iarray]'-only.uvt 'int_name[iarray]'-short.uvt
           let in1  'int_name[iarray]'-short
        endif
        !
        let zscf uvzero[i,1]                ! Zero Spacing Continuum Flux
        let zs_weight sd_weight*uvzero[i,2] ! Zero Spacing Weight
        !
        run uv_zero gag_scratch:alma_uvzero.init /nowin
        !
     next
     !
     delete /var zscf zs_weight uvzero
     !
  else
     !
     say "E-ALMA, Can not use single dish information"
     say "E-ALMA, because the single dish diameter is smaller than interferometer diameters"
     @ alma_error
     !
  endif
  !
  delete /var in_wdens out_wdens
  !
end procedure alma_add_short
!
!-------------------------------------------------------------------------
!
begin procedure alma_sampling
  !
  ! Define local variables
  !
  define double freq f_to_k rbin pixel
  let f_to_k 2.d0*pi/299792458.d-6
  !
  ! Define used name depending whether we are on mosaic case.
  !
  if (mosaic) then
     let fullname 'name'-1
  else
     let fullname 'name'
  endif
  !
  ! Read uv range
  ! 
  define uvtable uvt 'fullname'.uvt read
  define integer nuv 
  let nuv uvt%dim[2]
  define real uv1[nuv] uv2[nuv] the_size
  let uv1 uvt[1,]
  let uv2 uvt[2,]
  let uv2 uv1^2+uv2^2
  compute uvmax max uv2 
  let uv2[i] uvmax /where uv2.eq.0 ! To avoid uvmin = 0 in `map_size' def.
  compute uvmin min uv2
  let uvmin sqrt(uvmin)
  let uvmax sqrt(uvmax)
  let freq uvt%convert[2,1]
  del /var uvt uv1 uv2
  ! 
  ! Do circular averaging and derive the density of uv points
  !
  let uvrange '3*diameter[iarray]/4' 'uvmax'
  let rstep diameter[iarray]
  run uv_circle gag_scratch:alma_uvcircle.init /nowin
  define uvtable uvt 'fullname'-avg.uvt read 
  let nuv uvt%dim[2]
  define real uv1[nuv] uv2[nuv] uv3[nuv]
  let uv1 uvt[1,]
  let uv2 uvt[10,]
  del /var uvt
  sic delete 'fullname'-avg.uvt
  let uv2 uv2/uv1     ! Need the true spatial density, not the radial...
  let uv3 1 /where uv2.ne.0
  compute rbin mean uv2
  let uv2 uv2/rbin
  !
  ! Fit gives the expected beam size
  !
  mfit uv2=&a*exp(-(uv1/&b)^2) /start 2,500 /step 0.05,12 /weight uv3
  let uvmax mfit%par[2]
  let uvmax uvmax*freq*f_to_k
  let uvmin uvmin*freq*f_to_k
  let pixel pi/uvmax/sqrt(log(2))  ! beam size in radians
  say "I-ALMA, Estimated beam size is " pixel/sec """" /FORMAT A F8.3 A
  !
  ! Check initial sampling and derive binning factor
  !
  let pixel pixel/3D0            ! The goal is pixel = beam/3, 
  !! let pixel pixel/2.5D0       ! The goal is pixel = beam/3, 
  !! but since we round because of binning, some margin 
  !! could be acceptable and would allow smaller images
  !!
  define header mod 'inname'.gdf read
  let rbin pixel/abs(mod%convert[3,1])
  if (rbin.lt.1.0) then
     say "E-ALMA, Input image is insufficiently sampled"
     @ alma_error
  else
     let nbin 1
     for /while nbin.lt.rbin
        let nbin 2*nbin
     next
     let nbin nbin/2
  endif
  say "I-ALMA, Binning factor "'nbin'" " 'rbin' /format A F8.2
  !
  ! MAP_CELL and MAP_SIZE parameters for UV_MAP task
  !
  let map_cell nbin*abs(mod%convert[3,1])/sec
  let map_size[2] nint(1.75*180.*3600./map_cell[1]/uvmin)
  !
  ! UV_MAP image must be at least twice the original image OR mosaic size 
  !
  if (nfields.eq.1) then
     if (map_size[2]*map_cell[2].lt.mod%dim[2]*mod%convert[3,2]/sec) then
        say "W-ALMA, Missing short baselines: "
        say " imageable field is only " map_size[2]*map_cell[2]  /FORMAT A F9.1 
        say " initial image size is  " mod%dim[2]*mod%convert[3,2]/sec /FORMAT A F9.1
     endif
     ! More than Twice the initial image
     let map_size[2] abs(3*mod%dim[2]*mod%convert[3,2]/sec/map_cell[2])
  else
     let the_size max(mos_size[1],mos_size[2])
     if (the_size.eq.0) then
        let the_size mod%dim[2]*mod%convert[3,2]/sec
     endif
     let map_size[2] 2*(the_size+primbeam[1])/map_cell[2]
  endif
  !
  ! Find nearest power of two for MAP_SIZE 
  !
  define logical more
  let map_size[1] 64 
  let more yes 
  for /while (more)
     if (map_size[1].lt.map_size[2]) then
        let map_size[1] 2*map_size[1]
     else
        let more no
     endif
  next
  let map_size[2] map_size[1]
  !
  ! End
  !
  input uv_map
  delete /var mod
  !
end procedure alma_sampling
!
!-------------------------------------------------------------------------
!
begin procedure alma_dirty_maps
  !
  ! Produce dirty maps.
  ! Note: when mosaicing, `fullname' should be the table before splitting, 
  !                                  ie with all fields
  !
  let fullname 'name'
  !
  if (mosaic) then
     !
     ! Let's mosaic
     !
     ! Make one dirty map per field
     !
     for i 1 to nfields
        let name 'fullname'-'i'
        go uv_map
     next
     !
     ! Make the dirty map for the whole mosaic and compute the extrema
     !
     run make_mosaic gag_scratch:make_mosaic.init /nowin
     header 'fullname'.lmv    /extr
     header 'fullname'.beam   /extr
     header 'fullname'.lobe   /extr
     header 'fullname'.weight /extr
     !
     ! Frees disk space 
     ! (all the freed information is stored somewhere else).
     !
     for i 1 to nfields
        !
        sic delete 'fullname'-'i'.beam
        sic delete 'fullname'-'i'.lmv
        !
     next
     !
  else
     !
     ! No mosaic: easy case
     !
     let name 'fullname'
     go uv_map
     !
  endif
  !
  ! Restore old `name' state
  !
  let name 'fullname'
  go setup
  !
end procedure alma_dirty_maps
!
!-------------------------------------------------------------------------
!
! Button DECONVOLUTION
!
!-------------------------------------------------------------------------
!
begin procedure alma_deconv
  !
  ! Says it begins or continues a new simulation.
  !
  let done no
  !
  ! Local variables
  ! 
  define integer oiter
  define character fullname1*32 fullname2*32
  !
  ! Define file names to be used
  !
  if (addshort) then
     if (process.eq.1) then
        let fullname  'kname[4]'
     else if (process.eq.2) then
        let fullname  'kname[5]'
     else
        let fullname1 'kname[1]'
        let fullname2 'kname[5]'
        let fullname  'kname[6]'
     endif
  else 
     if (process.eq.1) then
        let fullname  'kname[1]'
     else if (process.eq.2) then
        let fullname  'kname[2]'
     else
        let fullname1 'kname[1]'
        let fullname2 'kname[2]'
        let fullname  'kname[3]'
     endif
  endif
  !
  ! Deconvolution parameters
  !
  let oiter niter
  if (process.eq.3) then
     !
     define real ratio
     define image alma 'fullname1'.lmv read
     define image aca  'fullname2'.lmv read
     let ratio (alma%dim[1]*alma%dim[2])/(aca%dim[1]*aca%dim[2])
     delete /var alma aca
     !
     let niter ratio*diter
     !
  else if (process.eq.2)
     !
     let niter 3*diter/16
     !
  else
     !
     let niter diter
     !
  endif
  let ares 0
  let fres 1e-4
  let major 0
  let minor 0
  let angle 0
  let blc 0
  let trc 0
  let gain gains[1]
  let c_gain gains[2]
  let smooth asmooth
  !
  ! Does the job.
  !
  if (process.lt.3) then
     !
     ! First case: process only one image coming from ACA or ALMA
     !
     if (mosaic) then 
        !
        ! Mosaic: deconvolution IN MAPPING
        !
        read dirty   'fullname'
        read beam    'fullname'
        read primary 'fullname'
        if (.not.batch) then
           let do_contour no
           show dirty
        endif
        @ deconvolve ! /flux 0 '1.1*fluxes[1]'
        write clean 'fullname'.lmv-clean
        !
     else
        !
        ! No mosaic: easy case
        !
        read dirty   'fullname'
        read beam    'fullname'
        !
        if (.not.batch) then
           let do_contour no
           show dirty
        endif
        !
        @ deconvolve ! /flux 0 '1.1*fluxes[1]'
        write clean 'fullname'.lmv-clean
        !
     endif
     !
  else
     !
     ! Process both ALMA and ACA arrays
     !
     say "W-ALMA, Still experimental..."
     if (.not.mosaic) then
        say "E-ALMA, Can only process a mosaic..."
        @ alma_error
     endif
     !
     read dirty   'fullname1'
     read beam    'fullname1'
     read primary 'fullname1'
     !
     read dirty   'fullname2' /compact
     read beam    'fullname2' /compact
     read primary 'fullname2' /compact 
     !
     say " "
     say "Gains "'gain' 'c_gain'
     say "Total number of components "'niter'
     say "Goals per cycle "'ngoal'
     say "Smoothing kernel size" 'smooth'
     say " "
     !
     if (batch) then
        alma /method hogbom
     else
        alma /method hogbom /flux 0 '1.1*fluxes[1]'
     endif
     !
     write clean 'fullname'.lmv-clean
     !
  endif
  !
  write cct 'fullname'.cct 
  !
  let niter oiter
  !
  ! Say the procedure succeeded and save simulation state
  !
  let do_decon no
  @ alma_save parameters.map all
  !
end procedure alma_deconv
!
!-------------------------------------------------------------------------
!
! Button HYBRIDATION
!
!-------------------------------------------------------------------------
!
begin procedure alma_hybridation
  !
  ! Hybrids ALMA and ACA deconvolved maps in the UV plane.
  !
  if (mosaic) then
     run uv_hybrid gag_scratch:alma_uvhybrid.init /nowin
  else
     !
     ! Apply ALMA primary beam by using an "intermediate" primary beam
     ! on the ACA image only...
     !
     sic rename 'hybrid_in2_names[hybrid_in2_code]' tmp-2.gdf
     run primary gag_scratch:aca_onep.init /nowin
     run uv_hybrid gag_scratch:alma_uvhybrid.init /nowin
     sic rename tmp-2.gdf 'hybrid_in2_names[hybrid_in2_code]' 
  endif
  !
  ! Say the procedure succeeded and save simulation state
  !
  let do_hybrid no
  @ alma_save parameters.map all
  !
end procedure alma_hybridation
!
!-------------------------------------------------------------------------
!
! Button COMPARE
!
!-------------------------------------------------------------------------
!
begin procedure alma_compare
  !
  ! Says it begins or continues a new simulation.
  !
  let done no
  !
  ! Define simulation kind when in expert mode
  !
  if ((.not.alma_pipeline).and.(kind.ne.7)) then
     !
     if (addshort) then
        if (process.eq.1) then
           let kind 4
        else if (process.eq.2) then
           let kind 5
        else if (process.eq.3) then
           let kind 6
        else
           say "E-ALMA, Should not be here"
           @ alma_error
        endif
     else
        if (process.eq.1) then
           let kind 1
        else if (process.eq.2) then
           let kind 2
        else if (process.eq.3) then
           let kind 3
        else
           say "E-ALMA, Should not be here"
           @ alma_error
        endif
     endif
  endif
  !
  ! Read model (`inname') and simulated image (`kname[kind]'.lmv-clean)
  ! note: use cbeam variable, not beam (beam is a buffer in mapping)
  !
  define double theta[2] k lambda nu jyperk
  define header sim 'kname[kind]'.lmv-clean read 
  define header inp 'inname'.gdf read
  let cbeam sim%major sim%minor sim%pa
  let nu sim%restfre/1e3
  let nbin nint(abs(sim%convert[3,1]/inp%convert[3,1]))
  delete /var inp
  !
  ! Single field case: the input image WITH primary beam is in `pbeamed'
  ! Mosaic case: the input image WITHOUT the primary beam is in `inname'
  !              we want to compare this one with the simulated image 
  !              (clean image is corrected for prim. beam)
  !                
  !       --> take a new variable name `tmp_inname' for everybody
  !
  if (mosaic) then
     let tmp_inname 'inname'
  else
     let tmp_inname 'pbeamed'
     if (kind.eq.7) then
        let iarray 1
        run primary gag_scratch:alma_primary.init /nowin
     endif
     SAY "Not in mosaic " 'tmp_inname'
  endif
  !
  ! Smooth model to simulated image resolution and compress its size 
  ! if needed.
  !  
  if (nbin.ne.1) then
     run gauss_compress gag_scratch:gauss_compress.init /nowin
  else
     run gauss_smooth gag_scratch:gauss_smooth.init /nowin
  endif
  ! 
  ! Change unit of the `new_inname' image and update its header
  !
  define image nin 'kname[kind]''new_inname'.gdf write
  let theta cbeam[1] cbeam[2] 
  let theta theta|2.|sqrt(log(2.0))
  let lambda 2.99792458e8|nu*1e-9
  say 'lambda' 'theta[1]' 'theta[2]'
  let jyperk 2.0*1.38e3*pi*theta[1]*theta[2]|lambda^2
  say "K per Jy" '1|jyperk'
  say "mJy per K" '1e3*jyperk'
  let nin      nin*jyperk
  let nin%max  nin%max*jyperk
  let nin%min  nin%min*jyperk
  let nin%unit "Jy/beam"
  let nin%ra   sim%ra
  let nin%dec  sim%dec
  let nin%a0   sim%a0
  let nin%d0   sim%d0
  let nin%restfre nu*1e3
  let nin%major   cbeam[1]
  let nin%minor   cbeam[2]
  let nin%pa      cbeam[3]
  let nin%beam    12
  delete /var nin
  !
  ! Plunge simulated image into the `new_inname' image grid
  !
  if (.not.exist(nin)) then
     define header nin 'kname[kind]''new_inname'.gdf read /global
  endif
  let cin[1]  sim%convert[1,1]
  let cin[2]  sim%convert[1,2]
  let cout[1] nin%convert[1,1]
  let cout[2] nin%convert[1,2]
  let ablc    cin-cout+1
  let atrc[1] ablc[1]+nin%dim[1]-1
  let atrc[2] ablc[2]+nin%dim[2]-1
  run extract gag_scratch:alma_extract.init /nowin
  delete /var sim nin
  !
  ! Apply a soft mosaic mask on model = 'kname[kind]''new_inname'.gdf
  ! and on simulation = 'kname[kind]''outname'.gdf
  !
  if (mosaic) then
     if ((kind.eq.2).or.(kind.eq.5)) then
        @ apply_mosaic_mask 'kname[kind]''new_inname' 'kname[kind]''outname' update sharp 2 !  ACA mosaic
     else
        @ apply_mosaic_mask 'kname[kind]''new_inname' 'kname[kind]''outname' update sharp 1 ! ALMA mosaic
     endif
  else ! S.G. for single field imaging
     sic copy 'kname[kind]''new_inname'.gdf 'kname[kind]''new_inname'"-masked.gdf"
     sic copy 'kname[kind]''outname'.gdf 'kname[kind]''outname'"-masked.gdf"
  endif 
  !
  ! Difference image
  !
  define image nin 'kname[kind]''new_inname'.gdf read
  define image out 'kname[kind]''outname'.gdf read
  define image dif 'kname[kind]''difference'.gdf real /like nin
  let dif% out%
  let dif nin-out
  let dif%extrema 0
  delete /var out
  !
  ! Fidelity image
  ! 
  define image fid 'kname[kind]''fidname'.gdf real /like dif
  let fid% dif%
  compute fid%rms rms dif
  let fid abs(dif)
  let fid%rms abs(fid%rms)
  let fid max(fid,fid%rms*0.7) 
  define real a /like nin
  define real b
  let a 1 /where fid.eq.fid%rms*0.7
  compute b sum a
  say "Changed "'100.0*b/fid%dim[1]/fid%dim[2]'" % of pixels" 
  let fid abs(nin/fid) ! Make the absolute value
  compute fid%max max fid
  let fidmax 0.95*fid%max
  delete /var a b fid
  !
  ! Fidelity histogram
  !
  run histo_simple gag_scratch:alma_histo.init /nowin
  !
  ! Compute median fidelities.
  !
  define real xima yima /like nin
  define real xmax thresholds[4]
  !
  let thresholds 0.0033 0.01 0.033 0.1
  compute xmax max nin
  !
  for i 1 to 4
     !
     let xima 0
     let xima nin /where nin.gt.(thresholds[i]*xmax)
     !
     let yima 0
     let yima abs(dif/xima) /where xima.ne.0 
     let yima 1.0/yima /where yima.ne.0 ! Fidelity unclipped
     !
     compute fidelities[i] median yima /blanking 0 0
     !
  next
  !
  delete /var nin dif
  !
  ! Compute fluxes associated with `new_inname', `outname', `difference' 
  ! and the corresponding %.
  !
  define character names*32[3]
  !
  let names[1] 'kname[kind]''new_inname'
  let names[2] 'kname[kind]''outname'
  let names[3] 'kname[kind]''difference'
  !
  for i 1 to 3
     !
     define image abc 'names[i]'.gdf read
     !
     compute fluxes[i] sum abc
     let fluxes[i] fluxes[i]*abs(abc%convert[3,1]*abc%convert[3,2])
     let fluxes[i] fluxes[i]/pi/abc%major/abc%minor*4*log(2.)     
     !
     delete /var abc
     !
  next
  !
  let pfluxes nint(abs(fluxes/fluxes[1])*100.0)
  !
  ! Compute the UV plots
  !
  if (mosaic) then
     if ((kind.eq.2).or.(kind.eq.5)) then
        @ apply_mosaic_mask 'kname[kind]''new_inname' 'kname[kind]''outname' new 'mask_kind' 2 !  ACA mosaic
     else
        @ apply_mosaic_mask 'kname[kind]''new_inname' 'kname[kind]''outname' new 'mask_kind' 1 ! ALMA mosaic
     endif
  else ! S.G. for single field imaging
     sic copy 'kname[kind]''new_inname'.gdf 'kname[kind]''new_inname'"-masked.gdf"
     sic copy 'kname[kind]''outname'.gdf 'kname[kind]''outname'"-masked.gdf"
  endif 
  !
  run uv_fidelity gag_scratch:alma_uvfidelity.init /nowindow
  !
!  sic delete 'kname[kind]''new_inname'"-masked".gdf
!  sic delete 'kname[kind]''outname'"-masked".gdf
  !
  ! Compute azimuth average of uv fidelity image and associated uvfidelities.
  !
  let in1 'kname[kind]''uvfidelity'.gdf
  let first 3
  run azimuth_average gag_scratch:alma_average.init /nowindow
  !
  define image uvfid_avg 'in1''a_avg' read
  define integer istart iend 
  !
  let istart 1
  !
  for i 1 to 4
     !
     let iend int(uvranges[i]/uvfid_avg%convert[3,1])
     if (istart.le.uvfid_avg%dim[1]) then
        if (iend.gt.uvfid_avg%dim[1]) then
           let iend uvfid_avg%dim[1]
        else if (iend.lt.istart) then
           let iend istart
        endif
        compute uvfidelities[i] median uvfid_avg[istart:iend] /blanking 0 0
     else
        let uvfidelities[i] 0.0
     endif
     let istart iend+1
     !
  next
  !
  delete /var uvfid_avg istart iend
  !
  ! Frees disk space
  !
  sic delete 'in1''a_sum' ! This file will not be used afterward.
  !
  ! Say the procedure and simulation succeeded and save simulation state
  !
  let done yes
  let do_compa no
  let old_kind kind ! *** This does not seems to be the right place for that JP.
  @ alma_save parameters.map all
  @ alma_save 'kname[kind]'"-pars.map" new
  !
end procedure alma_compare
!
!-------------------------------------------------------------------------
!
begin procedure apply_mosaic_mask
  !
  ! This procedure applies a soft mosaic mask on input images
  ! This soft mask should be applied before all the FFT to avoid 
  ! oscillations.
  !
  define character file1*256 file2*256
  !
  let file1 &1
  let file2 &2
  let iarray &5
  !
  say "I-APPLY_MOSAIC_MASK, Applying a &4 mosaic mask to files "'file1'" and "'file2'
  !
  say "I-APPLY_MOSAIC_MASKS, Using a primary beam of "'primbeam[iarray]'" sec and a truncation at "'truncate[iarray]'" %" /format A F4.1 A F4.2 A
  !
  ! Defines the 'map1', 'map2', 'weight' and 'prim' arrays.
  !
  define image map1 'file1' read
  define image map2 'file2' read
  !
  if ("&3".eq."update") then
     define image map1_masked 'file1' write
     define image map2_masked 'file2' write
  else if ("&3".eq."new") then
     define image map1_masked 'file1'"-masked" real /like map1
     define image map2_masked 'file2'"-masked" real /like map2
     let map1_masked% map1%
     let map2_masked% map2%
  else
     @ alma_error
  endif
  !
  if (map1%ndim.eq.2) then
     define real weight prim distance /like map1
  else if (map1%ndim.eq.3) then
     define real weight prim distance /like map1[1]
  else
     say "E-APPLY_MOSAIC_MASK, Wrong input file dimension"
     @ alma_error
  endif
  !
  if ((map1%dim[1].ne.map2%dim[1]).or.(map1%dim[2].ne.map2%dim[2])) then
     say "E-APPLY_MOSAIC_MASK, incompatible input file dimension"
     @ alma_error
  endif
  !
!!$  for i 1 to 3
!!$     if ((map1%convert[i,1].ne.map2%convert[i,1]).or.(map1%convert[i,2].ne.map2%convert[i,2])) then
!!$        say "E-APPLY_MASK_MOSAIC, incompatible axis of input file"
!!$        @ alma_error
!!$     endif
!!$  next
  !
  ! Defines the mosaic weight.
  !
  define real i0 j0 size_x size_y
  !
  let size_x primbeam[iarray]*sec|abs(map1%convert[3,1])|(2*sqrt(log(2)))
  let size_y primbeam[iarray]*sec|abs(map1%convert[3,2])|(2*sqrt(log(2)))
  !
  let weight 0.0
  for i 1 to nfields
     let i0 xoffset[i]*sec|map1%convert[3,1]+map1%convert[1,1]
     let j0 yoffset[i]*sec|map1%convert[3,2]+map1%convert[1,2]
     let prim[ii,jj] exp(-(((ii-i0)/size_x)^2+((jj-j0)/size_y)^2))
     let prim 0.0 /where prim.lt.truncate[iarray]
     let weight weight+prim*prim
  next
  !
  ! Defines the mask from the mosaic weight.
  !
  define image mask 'int_name[iarray]'"-mask.gdf" real /like weight
  define real min max trun
  !
  let weight 10.0 /where weight.eq.0.0
  compute min min weight
  let weight 0.0 /where weight.eq.10.0
  if (truncate[iarray].lt.min) then
     let trun min
  else
     let trun truncate[iarray]
  endif
  !
  let mask 1.0 /where weight.ge.trun
  let mask 0.0 /where weight.lt.trun
  !
  if ("&4".eq."soft") then
     !
!     say "soft"
     !
     let i0 map1%dim[1]|2+1
     let j0 map1%dim[2]|2+1
     let distance[ii,jj] sqrt((ii-i0)^2+(jj-j0)^2)
     let mask distance*(1.0-mask)
     !
     compute max max mask
     let mask max /where mask.eq.0.0
     compute min min mask
     !
     let mask 1.0-distance/min /where distance.le.min
     let mask 0.0              /where distance.gt.min
     !
  else if ("&4".eq."soft-sharp") then
     !
!     say "soft-sharp"
     !
     let mask (weight-trun)/(0.9-trun) /where weight.ge.trun
     let mask 1.0 /where mask.gt.1.0
     !
  else if ("&4".eq."sharp") then
     !
!     say "sharp"
     !
     ! Does nothing.
     !
  else
     !
     @ alma_error
     !
  endif
  !
  ! Applies the mask.
  !
  if (map1%ndim.eq.2) then
     let map1_masked map1*mask
  else if (map1%ndim.eq.3) then
     for i 1 to map1%dim[3]
        let map1_masked[i] map1[i]*mask
     next
  endif
  !
  compute min min map1_masked
  compute max max map1_masked
  let map1_masked%min min
  let map1_masked%max max
  !
  if (map2%ndim.eq.2) then
     let map2_masked map2*mask
  else if (map2%ndim.eq.3) then
     for i 1 to map2%dim[3]
        let map2_masked[i] map2[i]*mask
     next
  endif
  !
  compute min min map2_masked
  compute max max map2_masked
  let map2_masked%min min
  let map2_masked%max max
  !
  delete /var prim distance weight min max trun
  delete /var map1_masked map2_masked map1 map2 mask 
  !
end procedure apply_mosaic_mask
!
!-------------------------------------------------------------------------
!
! Procedures of general interest (plotting and parameter saving)
!
!-------------------------------------------------------------------------
!
begin procedure window
  !
  ! Allow an easy positionning on the plot page
  !
  def int nwindowx nwindowy wnumber
  let nwindowx &1
  let nwindowy &2
  let wnumber &3
  !
  !examine nwindowx
  !examine nwindowy
  !examine wnumber
  !
  def int wnumberx wnumbery 
  def real xsize ysize xmargin ymargin
  !
  let xmargin 0.15
  let ymargin 0.1
  let xsize ((1-2*xmargin)|nwindowx)
  let ysize ((1-2*ymargin)|nwindowy)
  let wnumbery (wnumber|nwindowx)-0.51
  !examine wnumbery
  let wnumberx (wnumber-wnumbery*nwindowx-1)
  !examine wnumberx
  !
  set viewport (xmargin+wnumberx*xsize) (xmargin+(wnumberx+1)*xsize) (1-(ymargin+(wnumbery+1)*ysize)) (1-(ymargin+wnumbery*ysize)) 
  !
end procedure window
!
!-------------------------------------------------------------------------
!
begin procedure alma_plot_cct
  !
  ! Do not plot when on batch mode
  !
  if (batch) then
     return
  endif
  !
  ! Define plotting window
  !
  if (multi_window) then
     !
     create dir <flux /geometry 'window_size[1]' 'window_size[2]'
     change dir <flux
     ! sic wait 'wait_time'
     change pos 7
     !
  endif
  !
  define char cct_file*256
  let cct_file 'kname[kind]'.cct
  !
  if file(cct_file) then
     !
     ! Open table.
     !
     define image abc 'kname[kind]'.cct read
     ! 
     ! Compute the limit: for y, max of the cumulated fluxes of the input 
     !                    table and 1.1 times the expected flux.
     !
     limit /var abc[4] abc[5]
     define real plot_ymax
     if ('1.1*fluxes[1]'.gt.user_ymax) then
        let plot_ymax 1.1*fluxes[1]
        limit = = = plot_ymax
     endif
     delete /var plot_ymax
     !
     ! Define plotting window
     !
     set box 3.600000 22.70000 1.799999 20.90000
     !
     ! Plot
     !
     connect abc[4] abc[5]
     draw relocate user_xmin fluxes[1] /user
     draw line     user_xmax fluxes[1] /user
     !
     ! Make labels
     !
     set expand 1.0
     box
     label "Clean component number" /x
     label "Cumulated flux (Jy)"    /y
     !
     delete /var abc
     !
     ! Make header
     !
     sic\@ alma_header.greg 
     !
     ! Print when asked
     !
     if (alma_print) then
        @ alma_print cct.eps 
     endif
     !
  else
     !
     say "W-ALMA_PLOT_CCT, skip "'kname[kind]'" because cct file does not exist"
     !
  endif
  !
end procedure alma_plot_cct
!
!-------------------------------------------------------------------------
!
begin procedure alma_plot_fidelity
  !
  destroy all
  clear alpha
  !
  define image nin 'kname[kind]''new_inname'.gdf  read
  define image dif 'kname[kind]''difference'.gdf read
  define real x['dif%dim[1]','dif%dim[2]'] y['nin%dim[1]','nin%dim[2]']
  define real xmin xmax ymin ymax xrange yrange fidelity max_factor
  !
  for i 1 to 2
     !
     if (i.eq.1) then
        !
        let x dif
        let y nin
        !
     else
        !
        let x abs(dif)
        let y abs(nin)
        !
     endif
     !
     compute ymin min nin
     compute ymax max nin
     let yrange ymax-ymin
     let ymin ymin-0.05*yrange
     let ymax ymax+0.05*yrange
     !
     let max_factor 0.015
     !
     if (i.eq.1) then
        !
        let xmin -0.1*max_factor*ymax
        let xmax      max_factor*ymax
        !
     else
        !
        let xmin -max_factor*ymax
        let xmax  max_factor*ymax
        !
     endif
     !
     @ window 2 1 'i'
     limit xmin xmax ymin ymax
     set marker 1 * * *
     point x y
     box
     !
     for j 1 to 4
        let fidelity fidelities[j]
        draw relocate 0.0 0.0 /user
        if ('user_xmax*fidelity'.gt.user_ymax) then
           draw line 'user_ymax/fidelity' user_ymax /user
        else
           draw line user_xmax 'user_xmax*fidelity' /user
        endif
     next
     !
     if (i.eq.1) then
        !
        label "Model-Simulation (Jy)" /x
        label "Model fluxes (Jy)"     /y
        !
     else
        !
        label "|Model-Simulation| (Jy)" /x
!        label "|Model fluxes| (Jy)"     /y
        !
     endif
     !
  next
  !
  delete /var nin dif x y
  !
  set viewport 0.150 0.925 0.125 0.925
  !
end procedure alma_plot_fidelity
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
begin procedure alma_plot_image_comp
  !
  ! Do not plot when on batch mode
  !
  if (batch) then
     return
  endif
  !
  ! Prepare plotting window
  !
  if (multi_window) then
     !
     create dir <image /geometry 'window_size[1]' 'window_size[2]'
     change dir <image
     ! sic wait 'wait_time'
     change pos 9
     !
  endif
  !
  ! General Procedure to plot multiple contour maps of spectral line images 
  !	Options:	
  !	DO_CONTOUR	do/not draw contours 
  !	DO_BIT		do/not plot bitmap 
  !	DO_NICE		do/not make a nice truncation for beam 
  !	DO_MASK		do/not mask some part for text 
  ! 
  ! Global variables defined in DEFINE.GRAPHIC 
  ! 
  ! Calls 
  !	P_LOAD.GREG    (to load images) 
  !       P_LEVELS.GREG  (to compute automatic contour levels) 
  !       P_SCALE.GREG   (to compute scaling for bitmaps) 
  !       P_BEAM.GREG    (to plot the clean beam, if any) 
  !
  define character fname*32[4] ftype*12[4] aname*32[4] 
  !
  let fname[1] 'kname[kind]''new_inname'
  let fname[2] 'kname[kind]''outname'
  let fname[3] 'kname[kind]''difference'
  let fname[4] 'kname[kind]''fidname'
  !
  let ftype[1] gdf
  let ftype[2] gdf
  let ftype[3] gdf
  let ftype[4] gdf
  !
  let aname[1] "Smoothed_Object"
  let aname[2] "Simulated_Observation"
  let aname[3] "Difference_RMS_"
  let aname[4] "Fidelity_Range_"
  !
  let do_mask no
  let spacing 0
  !
  let name 'fname[1]'
  let type 'ftype[1]'
  !
  def real x2 dx y2 fidelity_range dummy
  def double xmark ratio 
  def integer m n n1 n2 imark nmap nadd 
  def character cmark*32 cmark2*32
  ! 
  @ p_load.greg aaa        ! Load image & compute extrema if needed 
  ! 
  @ p_level.greg aaa       ! Compute levels 
  @ p_scale.greg aaa       ! Compute scaling 
  @ alma_header.greg  aaa       ! Draw header 
  if do_color then 
     @ p_color.graphic      ! Setup nice colour table 
  endif
  ! 
  rgdata aaa /variable 
  if (aaa%angle.ne.0) then 
     symbol option "/UNIT SEC" 
  else 
     symbol option "/ABSOLUTE" 
  endif
  if (size[1].eq.0) then 
     limits /rgdata 
  else if (size[1].gt.0) then 
     limits size[1]|2 -size[1]|2 -size[1]|2 size[1]|2 seconds 
  endif 
  if (aspect.eq.0) then 
     let ratio abs((user_xmax-user_xmin)|(user_ymax-user_ymin)) 
  else 
     let ratio aspect 
  endif
  let box_aspect ratio 
  let x2 box_xmax 
  let y2 box_ymax 
  let first 1
  let last 1 
  if (first.eq.0) then 
     let n1 1 
  else 
     let n1 first 
  endif
  if (last.eq.0) then 
     let n2 aaa%dim[3] 
  else 
     let n2 last 
  endif
  ! 
  let n 2
  let m 2
  !
  set expand min(6.0|(m+n),1.) 
  let dx (x2-box_xmin)|n|ratio 
  let dx min((y2-box_ymin)|m,dx) 
  ! 
  delete /variable mbox nbox ubox
  define integer mbox nbox /global 
  define integer k istep 
  if (step.lt.0) then 
     let istep -1 
     let k n2+1 
  else 
     let istep 1 
     let k n1-1 
  endif
  let mbox m 
  let nbox n 
  define real ubox[5,nbox,mbox] /global 
  for j 1 to m 
     for i 1 to n 
        ! 
        let ubox[1,i,j] x2+(i-n-1)*dx*ratio 
        let ubox[2,i,j] x2+(i-n)*dx*ratio 
        let ubox[3,i,j] y2-j*dx 
        let ubox[4,i,j] y2+(1-j)*dx 
        set box x2+(i-n-1)*dx*ratio x2+(i-n)*dx*ratio y2-j*dx y2+(1-j)*dx 
        let k k+istep 
        let ubox[5,i,j] 1.0*k 
        !
        let name  'fname[k]'
        let type  'ftype[k]'
        let cmark 'aname[k]'
        if (k.eq.4) then
           let cmark2 ""
        else
           define character cflux*32
           let cflux 'fluxes[k]' /format 1PG11.4
           let cmark2 "Flux = "'cflux'" Jy ("'pfluxes[k]'"%)"
           delete /var cflux
        endif
        @ p_load.greg aaa        ! Load image & compute extrema if needed 
        !
        if (k.eq.1) then
           let fidelity_range max(-aaa%min,aaa%max)
        else if (k.eq.3) then
           let spacing true_spacing/10.0
           @ p_level.greg aaa       ! Compute levels 
           @ p_scale.greg aaa       ! Compute scaling
           compute dummy rms aaa
           let fidrange fidelity_range/dummy
           define character diff_rms*32
           let diff_rms dummy /format 1PG11.4
           let cmark 'aname[k]'"= "'diff_rms'" Jy"
        else if k.eq.4 then
           levels 10 30 100 300 1000 3000 1e4
           @ p_scale.greg aaa       ! Compute scaling 
           define character frange*32
           let frange 'fidrange' /format 1PG11.4
           let cmark 'aname[k]'"= "'frange'
        endif
        if (aaa%ndim.le.2) then 
           rgdata aaa /variable 
        else if (aaa%ndim.eq.3) then 
           rgdata aaa[1] /variable 
        else 
           rgdata aaa[1,1] /variable 
        endif
        if (do_bit) then          ! Plot the RGDATA array... 
           if (k.ne.4) then
              plot /scaling linear true_scale[1] true_scale[2] 
           else
              plot /scaling log 1 1000 ! Image fidelity 
           endif
        endif
        if (do_grey) then 
           rgmap quiet /abs 1.0 /grey 
        endif
        !
        if (do_contour) then 
           rgmap quiet /abs 1.0 
        endif
        if (cross.ne.0) then 
           dra relo 0 cross*sec /user 
           dra line 0 -cross*sec /user /clip
           dra relo cross*sec 0 /user 
           dra line -cross*sec 0 /user /clip
        endif
        @ p_beam.greg aaa 
        if i.eq.1.and.(j.eq.m) then               !  K+N.GT.N2) THEN 
           box 'option' 
        else 
           box n n 'option' 
        endif
        if (exist(do_mask)) then 
           if (do_mask) then 
              @ p_mask.greg 7 0.3 0.15 
           endif
        endif
        set coord box 
        draw text 0.2 -0.1 'cmark' 3 /box 7
        draw text 0.2 -0.7 'cmark2' 3 /box 7 
        if ((k.eq.3).or.(k.eq.4)) then
           wedge bottom
        endif
     next 
  next 
  !
  define real last_box[4] 
  let last_box[1] box_xmin 
  let last_box[2] box_xmax 
  let last_box[3] box_ymin 
  let last_box[4] box_ymax 
  !
  set box 23.75 29.75 6.0 12.0
  col x 2 z 1 /table 'kname[kind]''histogram'.gdf
  defin real cum
  let cum 0
  for l nxy to 1 by -1
  let cum cum+z[l]
  let y[l] cum
  next
  limits 1 1000 0.5 * /xlog  /ylog
  set expand 0.9
  if (exist(fidelities)) then
     define real xx[4] yy[4] zz[4] f
     define integer color[4]
     let color 2 1 3 0 
     let xx -3 3 -3 3
     let yy -1.5 -1.5 -2.5 -2.5
     let zz 3 10 33 100
     for l 1 to 4
        pen 0 /col color[l]
        draw relo fidelities[l] 0.5 /user
        draw line fidelities[l] user_ymax /user
        let f nint(fidelities[l])
        draw text xx[l] yy[l] 'f'" - "'0.1*zz[l]'"%" 5 0 /char 2
     next
     pen 0 /col 0
     delet /var f xx yy
  endif
  set blank 0 0
  draw text 0 1 "Cumulative Fidelity" 5 /char 8
  histo ! /base 0.5
  set expand 0.65
  box
  !
  set expand 1.0 
  set box last_box[1] last_box[2] last_box[3] last_box[4] 
  !
  ! Print when asked
  !
  if (alma_print) then
     @ alma_print image_fid.eps
  endif
  !
  ! *** To correct bug.
  !
  limit * * * *
  !
end procedure alma_plot_image_comp
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
begin procedure alma_plot_uvplane_comp
  !
  ! Do not plot when on batch mode
  !
  if (batch) then
     return
  endif
  !
  ! Prepare plotting window
  !
  if (multi_window) then
     !
     create dir <uv_plane /geometry 'window_size[1]' 'window_size[2]'
     change dir <uv_plane
     ! sic wait 'wait_time'
     change pos 3
     !
  endif
  !
  ! Display Model, Result and Fidelity UV plane images
  !
  !
  let name 'kname[kind]''uvfidelity'
  let type gdf
  if (.not.exist(uvf)) then
     define image uvf 'name'.'type' read /global
  endif
  @ alma_header.greg uvf      ! Draw header 
  define real bmin bmax
  !
  set box 4 13 2 11
  if (uv_limit.eq.0) then
     limi /rg uvf
  else
     limit uv_limit -uv_limit -uv_limit uv_limit ! *** Sign question
  endif
  compute bmin min uvf[1]
  compute bmax max uvf[1]
  let bmin max(bmin,sqrt(1e-5)*bmax)
  rgdata uvf[1] /var
  plot /scal log bmin bmax
  wedge left
  ellipse 12 /user 0 0
  ellipse 150 /user 0 0
  box p n
  draw text 0 -2 "Difference" 5 /char 2
  !
  set box 4 13 11 20 
  compute bmin min uvf[2]
  compute bmax max uvf[2]
! let bmin max(bmin,1e-5*bmax)
  rgdata uvf[2] /var
! plot /scal log bmin bmax
  plot /scal lin bmin bmax
  wedge left
  ellipse 12 /user 0 0
  ellipse 150 /user 0 0
  box n n
! axis yright /label o
  draw text 0 1 "Model"  5 /char 8
  !
  set box 13 22 2 11 
  rgdata uvf[3] /var
  plot  /scal log 1 1000
  ellipse 12 /user 0 0
  ellipse 150 /user 0 0
  box p n
  draw text 0 -2 "Fidelity"  5 /char 2
  draw relo 24 -24 /user
  draw line 24 24 /user
  draw line -24 24 /user
  draw line -24 -24 /user
  draw line 24 -24 /user
  draw relo -24 24 /user
  !
  set box 14 21 13 20
  lim 24 -24 -24 24
  draw line -24 -24 /user
  set box 13 22 2 11 
  if (uv_limit.eq.0) then
     limi /rg uvf
  else
     limit -uv_limit uv_limit -uv_limit uv_limit
  endif
  draw relo 24 24 /user
  set box 14 21 13 20
  lim 24 -24 -24 24
  draw line 24 -24 /user
  rgdata uvf[3] /var
  plot  /scal log 1 1000
  wedge right
  ellipse 12 /user 0 0
  box p n
  draw text 0 -2 "Fidelity"  5 /char 2
  delete /var uvf
  !
  !
  !
  define image average 'name'".gdf"'a_avg' read
  define real uvfid_avg['average%dim[1]',2]
  !
  let uvfid_avg[i,j] (i+1-average%convert[1,1])*average%convert[3,1]+average%convert[2,1]
  let uvfid_avg[,2] average
  let uvfid_avg[,2] 1.0 /where average.lt.1.0
  !
  set box 23.75 29.75 6.0 12.0
  if (uv_limit.eq.0.0) then
     limits -10 200 1 1000 /ylog
  else 
     limits -0.1*uv_limit uv_limit 1 1000 /ylog
  endif
  !
  pen 1
  draw relo  12 1 /user
  draw line  12 user_ymax /user
  draw relo 150 1 /user
  draw line 150 user_ymax /user
  pen 0
  !
  histogram uvfid_avg[,1] uvfid_avg[,2]
  box
  !
  set box /default
  let first 1
  let last 1
  !
  ! Print when asked
  !
  if (alma_print) then
     @ alma_print uvplane_fid.eps
  endif
  !
end procedure alma_plot_uvplane_comp
!
!-------------------------------------------------------------------------
!
begin procedure alma_plot_uvweights
  !
  ! Do not plot when on batch mode
  !
  if (batch) then
     return
  endif
  !
  ! Prepare plotting window
  !
  if (multi_window) then
     !
     create dir <uv_weights  /geometry 'window_size[1]' 'window_size[2]'
     change dir <uv_weights
     ! sic wait 'wait_time'
     change pos 7
     !
  endif
  !
  if (process.eq.3) then
     ! **** To be done when deconvolution algorithm ok.
     say "The plot of the combined beam is not yet implemented"
     return
  endif
  !
  if (mosaic) then
     let name 'kname[kind]'-1
  else
     let name 'kname[kind]'
  endif
  !
  let xtype radius
  let ytype weight
  read uv 'name'
  show uv
  !
  sic delete 'name'.tuv
  !
  ! Print when asked
  !
  if (alma_print) then
     @ alma_print uvweights.eps
  endif
  !
end procedure alma_plot_uvweights
!
!-------------------------------------------------------------------------
!
begin procedure alma_plot_beam
  !
  ! Do not plot when on batch mode
  !
  if (batch) then
     return
  endif
  !
  ! Prepare plotting window
  !
  if (multi_window) then
     !
     create dir <beam /geometry 'window_size[1]' 'window_size[2]'
     change dir <beam
     ! sic wait 'wait_time'
     change pos 1
     !
  endif
  !
  if (process.eq.1) then
     let iarray 1
  else if (process.eq.2) then
     let iarray 2
  else
     ! **** To be done when deconvolution algorithm ok.
     say "The plot of the combined beam is not yet implemented"
     return
  endif
  !
  define character config_file*128
  let config_file 'config_dir'"/"'array[iarray]'-'config[iarray]'
  let nant int_nant[iarray]
  !
  let name 'kname[kind]'
  !
  if (mosaic) then
     let fullname 'kname[kind]'"-1"
  else
     let fullname 'kname[kind]'
  endif
  !
  let first 1
  let last  1
  !
  ! Prepare display of beam & UV coverage
  !
  define uvtable uvt 'fullname'.uvt read
  define integer nuv 
  let nuv uvt%dim[2]
  define real uv1[nuv] uv2[nuv]
  let uv1 uvt[1,]
  let uv2 uvt[2,]
  let uv2 uv1^2+uv2^2
  compute uvmax max uv2 
  let uvmax sqrt(uvmax)
  del /var uvt uv1 uv2
  !
  let uvrange '3*diameter[iarray]/4' 'uvmax'
  let rstep diameter[iarray]/2
  run uv_circle gag_scratch:alma_uvcircle.init /nowin
  transpose 'fullname'-avg.uvt 'fullname'-avg.tuv 21
  !
  ! Options:	
  !	DO_CONTOUR	do/not draw contours 
  !	DO_BIT		do/not plot bitmap 
  !	DO_NICE		do/not make a nice truncation for beam 
  !	DO_MASK		do/not mask some part for text 
  ! 
  ! Global variables defined in DEFINE.GRAPHIC 
  ! 
  ! Calls 
  !	  P_LOAD.GREG    (to load images)
  !       P_LEVELS.GREG  (to compute automatic contour levels) 
  !       P_SCALE.GREG   (to compute scaling for bitmaps) 
  !       P_BEAM.GREG    (to plot the clean beam, if any) 
  !
  let spacing 0.05
  def real x2 dx y2 aamin aamax xm ym
  def double xmark ratio 
  def integer m n n1 n2 imark nmap nadd 
  def character cmark*12 
  def logical do_clean do_dirty do_coverage do_array do_weight do_w
  def logical do_cut1 do_cut2 do_sum
  let do_clean beam_type.eq."CLEAN" 
  let do_dirty beam_type.eq."DIRTY" 
!  let do_coverage uv_limit.ne.0
!  let do_array yes
!  let do_weight yes
  let do_coverage no
  let do_array    no
  let do_weight   no
  !
  let do_cut1 yes
  let do_cut2 yes
  let do_sum  yes
  !
  define header bbb 'kname[kind]'.lmv-clean read
  let type beam
  @ p_load.greg aaa        ! Load image & compute extrema if needed 
  @ p_level.greg aaa       ! Compute levels 
  @ p_scale.greg aaa       ! Compute scaling 
  @ alma_header.greg aaa      ! Draw header 
  if (do_color) then 
     @ p_color.graphic      ! Setup nice colour table 
  endif
  let spacing 0
  ! 
  rgdata aaa /variable 
  if (aaa%angle.ne.0) then 
     symbol option "/UNIT SEC" 
  else 
     symbol option "/ABSOLUTE" 
  endif
  if (size[1].eq.0) then 
     limits /rgdata 
  else if (size[1].gt.0) then 
     limits size[1]|2 -size[1]|2 -size[1]|2 size[1]|2 seconds 
  endif
  if (aspect.eq.0) then 
     let ratio abs((user_xmax-user_xmin)|(user_ymax-user_ymin)) 
  else 
     let ratio aspect 
  endif
  let box_aspect ratio 
  let x2 box_xmax 
  let y2 box_ymax 
  if (first.eq.0) then 
     let n1 1 
  else 
     let n1 first 
  endif
  if (last.eq.0) then 
     let n2 aaa%dim[3] 
  else 
     let n2 last 
  endif
  let nmap n2-n1+1 
  let nadd 0
  if (do_array) then
     let nadd nadd+1  ! Add array layout 
  endif
  if (do_weight) then
     let nadd nadd+2 
  endif
  if (do_clean.or.do_dirty) then 
     let nadd nadd+1 
  endif
  if (do_coverage) then 
     let nadd nadd+1 
  endif
  if (do_cut1) then
     let nadd nadd+1 
  endif
  if (do_cut2) then 
     let nadd nadd+1 
  endif
  if (do_sum) then 
     let nadd nadd+1 
  endif
  if (ratio.gt.1.d0) then           ! M > N 
     let m int(sqrt((nmap+nadd)*ratio+1)) 
     let n nint(m|ratio) 
     if (m*n.lt.(nmap+nadd)) then 
        let m = m+1 
        if (m*n.lt.(nmap+nadd)) then 
           let n n+1 
        endif
     endif
  else 
     let n int(sqrt((nmap+nadd)|ratio+1)) 
     let m nint(n*ratio) 
     if (m*n.lt.(nmap+nadd)) then 
        let n = n+1 
        if (m*n.lt.(nmap+nadd)) then 
           let m m+1 
        endif
     endif
  endif
  ! 
  set expand min(6.0|(m+n),1.) 
  let dx (x2-box_xmin)|n|ratio 
  let dx min((y2-box_ymin)|m,dx) 
  ! 
  delete /variable mbox nbox ubox 
  define integer mbox nbox /global 
  define integer k istep 
  if (step.lt.0) then 
     let istep -1 
     let k n2+1 
  else 
     let istep 1 
     let k n1-1 
  endif
  let mbox m 
  let nbox n 
  define real ubox[5,nbox,mbox] /global
  let ddx 1.5 /new real
  !
  let type lmv-clean
  !
  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  !
  define real cut1['aaa%dim[1]',2] cut2['aaa%dim[2]',2]
  !
  for i 1 to aaa%dim[1]
     let cut1[i,1] (i+1-aaa%convert[1,1])*aaa%convert[3,1]+aaa%convert[2,1]
  next
  let cut1[,1] cut1[,1]|sec
  !
  for i 1 to aaa%dim[2]
     let cut2[i,1] (i+1-aaa%convert[1,2])*aaa%convert[3,2]+aaa%convert[2,2]
  next
  let cut2[,1] cut2[,1]|sec
  if (aaa%ndim.eq.3) then
    let cut1[,2] aaa[,'aaa%dim[2]|2+1',1]
    let cut2[,2] aaa['aaa%dim[1]|2+1',,1]
  else
    let cut1[,2] aaa[,'aaa%dim[2]|2+1']
    let cut2[,2] aaa['aaa%dim[1]|2+1',]
  endif
  !
  let in1 'name'.beam
  run azimuth_average gag_scratch:alma_average.init /nowindow
  !
  define image avg 'in1''a_avg' read
  define real average['avg%dim[1]',2]
  !
  let average[i,j] (i+1-avg%convert[1,1])*avg%convert[3,1]+avg%convert[2,1]
  let average[,1] average[,1]|sec
  let average[,2] avg
  !
  define image sum 'in1''a_sum' read
  define real int_sum['sum%dim[1]',2] int_gauss['sum%dim[1]']
  !
  let int_sum[i,j] (i+1-sum%convert[1,1])*sum%convert[3,1]+sum%convert[2,1]
  let int_sum[,1] int_sum[,1]|sec
  let int_sum[,2] sum[]
  !
!!$  let int_gauss = exp(-(int_sum[,1]|(2.0*sqrt(log(2.0))*1.3))^2)
!!$  let int_gauss = int_gauss*2*3.1415*int_sum[,1]|(sum%convert[3,1]|sec)
  !
  for i 2 to sum%dim[1]
     let int_sum[i,2] int_sum['i-1',2]+int_sum[i,2]
!!$     let int_gauss[i] int_gauss['i-1']+int_gauss[i]
  next
  !
  !
  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  !
  for j 1 to m 
     for i 1 to n 
        ! 
        let ubox[1,i,j] x2+(i-n-1)*dx*ratio+ddx 
        let ubox[2,i,j] x2+(i-n)*dx*ratio 
        let ubox[3,i,j] y2-j*dx+ddx 
        let ubox[4,i,j] y2+(1-j)*dx 
        set box ubox[1,i,j] ubox[2,i,j] ubox[3,i,j] ubox[4,i,j] y2+(1-j)*dx 
        let k k+istep 
        if ((k.gt.aaa%dim[3]).or.(k.gt.n2).or.(k.lt.n1)) then 
           let ubox[5,i,j] 0 
           if do_clean then 
              box n n 'option' 
              ellipse 0.5*aaa%major 0.5*aaa%minor 90-180*aaa%pa|pi /box dx|2 dx|2 
              draw text -0.2 0.2 "Clean Beam" 7 /box 3 
              let do_clean = .false. 
           else if do_dirty then 
              ! Plot the beam 
              define image lob 'kname[kind]'.beam read 
              levels -0.5 to -0.1 by 0.1 0.1 to 0.5 by 0.1 
              rgdata lob /var 
              if (do_bit) then 
                 plot lob /scaling linear -0.5 1.0 
              endif
              if (do_contour) then 
                 rgmap quiet 
              endif
              box n n 'option' 
              draw text -0.2 0.2 "Dirty Beam" 7 /box 3 
              let do_dirty = .false. 
              delete /var lob 
           else if do_coverage then 
              limits -uv_limit uv_limit -uv_limit uv_limit
              box p n 
              axis yr /label o 
              ! 
              ! Check dates 
              define integer uvt__date tuv__date 
              compute uvt__date date 'kname[kind]'.uvt 
              if (file("'kname[kind]'.tuv")) then 
                 compute tuv__date date 'kname[kind]'.tuv 
              else 
                 let tuv__date = -1 
              endif
              if (tuv__date.le.uvt__date) then 
                 vector\transpose 'kname[kind]'.uvt 'kname[kind]'.tuv 21
              endif
              define uvtable uvt 'kname[kind]'.tuv read 
              set expand min(3.|n,1.) 
              points uvt[1] uvt[2] 
              limits uv_limit -uv_limit uv_limit -uv_limit
              points uvt[1] uvt[2] 
              draw text -0.2 0.2 "UV Coverage" 7 /box 3 
              let do_coverage = .false. 
              delete /variable uvt uvt__date tuv__date 
           else if do_array then
              col x 6 y 7 z 1 /file 'config_file'.cfg
              compute xm mean x
              compute ym mean y
              let x x-xm
              let y y-ym
              compute xm max x
              compute ym max y
              let ym max(xm,ym)
              compute xm min x
              let xm -xm
              let ym max(xm,ym)
              compute xm min y
              let xm -xm
              let ym 1.2*max(xm,ym)
              limi -ym ym -ym ym
              box n n
              axis xl
              axis yl
              axis yr 
              for ii 1 to nxy
                 ellipse 0.5*diameter[iarray] /user x[ii] y[ii]
              next
              let do_array no
              col z 1 /file 'config_file'.cfg
           else if do_weight then
              define uvtable uc 'fullname'-avg.tuv read
              define real uw /like uc[10]
              define real ac nshort
              compute ac sum uc[10]
              let ac ac*2/(nant*(nant-1))
              let nshort 0.01*nint(100*uc[1,10]/ac) 
              say 'nshort'" short baselines"
              say '0.01*nint(100*uc[1,10]/ac/nant)'" short baselines per antenna"
              say '0.01*nint(100*uc[2,10]/ac/nant)'" short baselines per antenna"
              !
              let uw uc[10]/ac  !  Convert to number of baselines ...
              limits 0 * 0 * /var uc[1] uw
              histo uc[1] uw /base 0
              box
              draw text 0 -2 "Number of baselines" 5 0 /char 8
              let do_weight no
              let do_w yes
           else if (do_w) then
              let uw uw/uc[1]*(uc[2,1]-uc[1,1]) /where uc[1].ne.0  !  Convert to weight density 
              limits 0 * 0 * /var uc[1] uw
              histo uc[1] uw /base 0
              box
              draw text 0 -2 "Density of weights" 5 0 /char 8
              let do_w no
           else if (do_cut1) then
              limits /var cut1[,1] cut1[,2]
              connect cut1[,1] cut1[,2]
              pen 1
!              connect average[,1] average[,2]
              pen 0
              box
              let do_cut1 no
           else if (do_cut2) then
              limits /var cut2[,1] cut2[,2]
              connect cut2[,1] cut2[,2]
              pen 1
!              connect average[,1] average[,2]
              pen 0
              box
              let do_cut2 no
           else if (do_sum) then
              limits /var int_sum[,1] int_sum[,2]
              connect int_sum[,1] int_sum[,2]
              box
              pen 1
              connect int_sum[,1] int_gauss
              pen 0
              let do_sum no
           else
              set expand 1.0 
              return 
           endif
        else 
           let ubox[5,i,j] 1.0*k 
           if (aaa%ndim.le.2) then 
              rgdata aaa /variable 
           else if (aaa%ndim.eq.3) then 
              rgdata aaa[k] /variable 
           else 
              rgdata aaa[k,1] /variable 
           endif
           if (do_bit) then          ! Plot the RGDATA array... 
              plot /scaling linear true_scale[1] true_scale[2] 
           endif
           if (do_grey) then 
              rgmap quiet /abs 1.0 /grey 
           endif
           ! Now the graphic 
           let xmark aaa%convert[2,3]+(k-aaa%convert[1,3])*aaa%convert[3,3] 
           if (mark.eq."FREQUENCY") then 
              let imark nint((-(xmark-aaa%veloff)*aaa%restfre|299792.458+aaa%restfre)*1e3) 
              let xmark 1d-6*imark 
           else if (mark.eq."CHANNEL") then 
              let xmark 1.0*k 
           else 
              if (mark.ne."NONE") then 
                 let mark "VELOCITY" 
                 let imark nint(xmark*100.) 
                 let xmark 1d-2*imark 
              endif
           endif
           if (do_contour) then 
              rgmap quiet /abs 1.0 
           endif
           if (cross.ne.0) then 
              dra relo 0 cross*sec /user 
              dra line 0 -cross*sec /user /clip
              dra relo cross*sec 0 /user 
              dra line -cross*sec 0 /user /clip
           endif
           if (do_nice) then 
              @ p_beam.greg aaa 
           endif
           if i.eq.1 then ! .and.(j.eq.m) then               !  K+N.GT.N2) THEN 
              box 'option' 
           else 
              box n n 'option' 
           endif
           if (exist(do_mask)) then 
              if (do_mask) then 
                 @ p_mask.greg 7 0.3 0.15 
              endif
           endif
           set coord box 
           let cmark 'xmark' 
           if (mark.ne."NONE") then 
              dra text 0.2 -0.1 'cmark' 3 /box 7 
           endif
        endif
     next 
  next 
  set expand 1.0 
  define real last_box[4] 
  let last_box[1] box_xmin 
  let last_box[2] box_xmax 
  let last_box[3] box_ymin 
  let last_box[4] box_ymax 
  set box last_box[1] last_box[2] last_box[3] last_box[4] 
  !
  ! Free disk space.
  !
  sic delete 'fullname'-avg.uvt
  sic delete 'fullname'-avg.tuv
  sic delete 'in1''a_avg'
  sic delete 'in1''a_sum'
  !
  ! Print when asked
  !
  if (alma_print) then
     @ alma_print beam.eps
  endif
  !
end procedure alma_plot_beam
!
!-------------------------------------------------------------------------
!
begin procedure alma_print
  !
  if (okind.eq.1) then
     !
     hardcopy /dev eps 'pname[pkind]' /plot
     !
  else
     !
     if (.not.file("ps:")) then
        sic mkdir ps:
     endif
     !
     if (file("ps:&1")) then
        sic delete ps:&1
     endif
     !
     hardcopy ps:&1 /dev eps 'pname[pkind]'
     !
  endif
  !
end procedure alma_print
!
!-------------------------------------------------------------------------
!
begin procedure alma_save
  !
  sic output "&1"
     !
     ! Delete variables of varying dimension.
     !
     say "if (exist(xoffset)) then"                      !
     say "   delete /var xoffset"                        !
     say "endif"                                         !
     say "if (exist(yoffset)) then"                      !
     say "   delete /var yoffset"                        !
     say "endif"                                         !
     say "define real xoffset["'nfields'"] yoffset["'nfields'"] /global" !
     say "!"
     say "! Normal section"
     say "!---------------"
     !
     say "let mosaic "'mosaic' 
     !
     symbol TOTO "@ sayall.greg"
     @ gag_proc:define_all
     symbol TOTO "continue"
     !
     if ("&2".eq."all") then 
        !
        say "!"
        say "! Old section"
        say "!------------"
        symbol TOTO "@ sayold"
        @ gag_proc:define_all
        symbol TOTO "continue"
     endif
     !
  sic output
  !
end procedure alma_save
!
!-------------------------------------------------------------------------
!
begin procedure alma_error
  !
  if (batch) then 
     exit
  else
     return base
  endif
  !
end procedure alma_error
!
!-------------------------------------------------------------------------
!
begin procedure alma_mosaic_phase
  ! 
  ! local variables
  !
  define integer oiter
  define integer number_visib nbase nv 
  define integer nn index ! various index 
  define real n_visib inttime_max
  ! 
  ! Antenna type is the global variable: `iarray'
  !
  let nant int_nant[iarray]
  !  
  ! 1) Generate the Coverage & Calibrator UV Tables
  ! 
  run uv_observe_new gag_scratch:uv_observe.alma /nowin
  !
  ! get integration time (Nyquist rate) and compare it to the maximum
  ! integration time needed to have one full coverage of the mosaic
  ! 
!  define header hh 'uv_coverage'-fine.uvt read
!  let dumps[1] hh%convert[3,2]
!  delete /var hh
  let inttime_max abs(hour[2,iarray]-hour[1,iarray])*3600/nfields
  if (dumps[1].gt.inttime_max) then
     say " "
     say "W-ALMA, The hour angle range is too short"
     say "W-ALMA, Using integration time = "'inttime_max'" sec"
     say " "
     let dumps[1] inttime_max   ! input of uv_track is Seconds
  endif
  !
  ! 2) Smooth the UV coverage 
  !
  run uv_timeaverage gag_scratch:uv_timeaverage.alma /nowin
  !
  ! nb visibilities = (nb baselines)x(nb fields)x(iteration) 
  ! find int(iteration) = full_iter
  !
  define header hh 'uv_coverage'.uvt read
  let number_visib hh%dim[2]
  let inttime[iarray] hh%convert[3,2]
  let nbase nant*(nant-1)/2
  !
  !SG-Shadowing begin
  ! This does not work. It assumes there is never any shadowing
  !             
  !       let n_visib number_visib/nbase
  !
  ! Use UV_SPLITFIELD to scan properly the UV table
  !
  if (.not.exist(n_times)) then
    define integer n_times /global
  endif
  if (exist(n_bases)) then
    delete /var n_bases
  endif
  if (file("uv_scantime.tmp")) then
    sic delete uv_scantime.tmp
  endif
  run uv_splitfield gag_scratch:uv_scantime.alma /nowindow
  @ uv_scantime.tmp n_times n_bases
  sic delete uv_scantime.tmp
  let n_visib n_times ! That must be correct
  !SG-Shadowing end
  say " "
  say "I-ALMA, Simulated observations:"
  say "  Hour angle range: "'hour[1,iarray]'" to "'hour[2,iarray]'
  say "  Integration time per dump: "'inttime[iarray]'" sec"
  say "  Maximum nb of baselines: "'nbase'", Actual numbers"
  exa n_bases
  say "  Nb of time dumps: "'n_visib'
  let full_iter int(n_visib/nfields)
  say "  Nb of full iterations on the "'nfields'"-fields mosaic: "'full_iter'
  say "  Nb of visibility dumps used: "'nfields*full_iter'
  say "  Nb of visibility dumps NOT used: "'n_visib-nfields*full_iter'
  say " "
  if (full_iter.eq.0) then
     say "E-ALMA, All fields must have been observed! Increase HA range."
     @ alma_error
  endif
  !
  ! 3) Normal model & pointing error treatment...
  !
  !
  ! check the pointing error file
  ! - if no pointing errors (pe_code = 0) or if the file doesn't exist, 
  !   create an empty file
  ! - otherwise smooth it to the integration time
  ! in both case, the pointing error file to be used is `int_used_pe'.
  !
  ! *** We dont test the pointing table dimensions: it has to
  ! *** be (NTT,NA,2) with NTT = number of visibility dump	
  ! ***			 NA = number of antennas
  !
  if (pe_code[iarray].ne.5) then
     say "I-ALMA, Creating a pointing error table"
!SG-Shadowing
!     let nv (number_visib/nbase)   ! is an integer, except if shadowing...
     let nv n_visib   ! This is the actual number of time steps...
     define image aa[nv,nant,2] 'int_used_pe'.tab real
     let aa% hh%
     let aa 0.
     delete /var aa
  else
     if (.not.file(int_pe)) then
        say "E-ALMA, No pointing error file"
        say "E-ALMA, Contact gildas@iram.fr to get this default file"
        @ alma_error
     endif
     say "I-ALMA, Smoothing the pointing error table"
     @ alma_smooth_pe 'inttime[iarray]' 'hour[2,iarray]-hour[1,iarray]' 'int_pe' 'int_used_pe'
  endif
  delete /var hh
  !
  ! edit the pointing error file to add the mosaic field offsets
  ! 
  define image err 'int_used_pe'.tab write
  let nn 0
  for i 1 to err%dim[1] 
     let nn nn+1
     if (nn.gt.nfields) then
        let nn 1
     endif
     let err[i,,1] err[i,,1]+xoffset[nn]
     let err[i,,2] err[i,,2]+yoffset[nn]
  next
  delete /var err
  !
  ! compute visibilities
  !
  run uv_pointing_new gag_scratch:alma_point.init /nowin
  !
  ! 4) Apply Phase & Amplitude errors
  ! 
  run uv_applyphase  gag_scratch:uv_applyphase.alma /now
  ! 
  ! 5) Calibrate 
  !
  if (.not.do_wvr) then
     ! Sort the input calibrator data
     let solution 'calibrator'
     run uv_sort gag_scratch:uv_sort-bt.alma /nowindow
     ! Prepare it's plot
     run uv_timebase gag_scratch:uv_timebase.alma /nowin
     !
     sic rename 'result'.uvt 'result'-raw.uvt
     let plot_calib yes 
     let raw 'result'-raw
     let cal 'result'-cal
     let solution "solution"
     run uv_solve gag_scratch:uv_solve.alma /nowindow
     !
     ! Plot the solution 
     run uv_sort gag_scratch:uv_sort-bt.alma /nowin
     run uv_timebase gag_scratch:uv_timebase.alma /nowin
     !
     ! 6) Done                  
     !
     sic rename 'result'-cal.uvt 'result'.uvt
     !
  endif
  !
  ! add noise ?
  !
  if (addnoise[iarray]) then
     say "Adding noise to the simulations"
     @ alma_addnoise
  endif
  !
  let fullname 'int_name[iarray]'-only
  !
  ! Split them in individual fields
  !
  run uv_splitfield gag_scratch:uv_splitfield.alma /nowindow
  for i 1 to nfields
     define uvtable aa 'fullname'-'i'.uvt write
     let aa%dec aa%dec+yoffset[i]*sec	        ! do NOT modify a0 and d0
     let aa%ra aa%ra+xoffset[i]/cos(aa%dec)*sec ! do NOT modify a0 and d0
     let aa%ptype 3 		     		! indispensable!!
     delete /var aa
  next
  !
end procedure alma_mosaic_phase
!
!-------------------------------------------------------------------------
!
begin procedure alma_single_phase
  !
  say "ALMA Single Field & Phase model"
  !
  ! B) Option
  ! 1) Generate the Coverage & Calibrator UV tables
  ! 2) Smooth the Coverage UV table
  ! 3) Run uv_fmodel on it
  ! 4) Apply phase & amplitude
  ! 5) Calibrate
  ! 6) Back to simulation...
  !
  !
  ! 1) Generate the Coverage & Calibrator UV Tables
  ! 
  run uv_observe_new gag_scratch:uv_observe.alma /nowin
  ! 
  ! 2) Smooth the UV coverage 
  !
  run uv_timeaverage gag_scratch:uv_timeaverage.alma /nowin
  !
  ! 3) Normal model & pointing error treatment...
  !
  ! check the pointing error file
  !   
  if (pe_code[iarray].eq.5) then
     if (.not.file(int_pe)) then
        say "E-ALMA, No pointing error file"
        say "E-ALMA, Contact gildas@iram.fr to get this default file"
        @ alma_error
     endif
  endif
  !
  ! Read the integration time, smooth the pointing error table
  !
  ! Use 'name' for the pointing error filename to be used by 
  ! uv_pointing: could be ascii or gdf file depending on pe_code
  !
  ! *** We dont test the pointing table dimensions: it has to
  ! *** be (NTT,NA,2) with NTT = number of visibility dump
  ! ***			 NA = number of antennas
  ! 
  if (pe_code[iarray].eq.5) then
     say "I-ALMA, Smoothing the pointing error table"
     define header hh 'uv_coverage'.uvt read
     let inttime[iarray] hh%convert[3,2]
     delete /var hh
     say ""
     say "Integration time per visibility" inttime[iarray]
     say ""
     @ alma_smooth_pe 'inttime[iarray]' 'hour[2,iarray]-hour[1,iarray]' 'int_pe' 'int_used_pe'
  endif
  !
  ! Apply primary beam on the model image
  !
  run primary gag_scratch:alma_primary.init /nowin
  !
  ! Simulate visibilities
  ! Note: - uv_fmodel takes as input `pbeamed' = image WITH primary beam
  !       - uv_pointing takes as input `inname' = image WITHOUT primary 
  ! 	  beam but then deals with the primary beam
  ! The results are in 'result'.uvt
  !               
  if (pe_code[iarray].eq.1) then
     run uv_fmodel gag_scratch:alma_model.init /nowin
  else
     run uv_pointing_new gag_scratch:alma_point.init /nowin
  endif
  !
  ! 4) Apply Phase & Amplitude errors
  ! 
  run uv_applyphase  gag_scratch:uv_applyphase.alma /now
  ! 
  ! 5) Calibrate -- TO BE DONE ONLY IF WVR NOT USED
  ! 
  if (.not.do_wvr) then
     !
     ! Sort the input calibrator data
     let solution 'calibrator'
     run uv_sort gag_scratch:uv_sort-bt.alma /nowindow
     ! Prepare its plot
     run uv_timebase gag_scratch:uv_timebase.alma /nowin
     !
     sic rename 'result'.uvt 'result'-raw.uvt
     let plot_calib yes 
     let raw 'result'-raw
     let cal 'result'-cal
     let solution "solution"
     run uv_solve gag_scratch:uv_solve.alma /nowindow
     !
     ! Plot the solution 
     run uv_sort gag_scratch:uv_sort-bt.alma /nowin
     run uv_timebase gag_scratch:uv_timebase.alma /nowin
     !
     let solution 'result'-raw
     run uv_sort gag_scratch:uv_sort-bt.alma /nowin
     run uv_timebase gag_scratch:uv_timebase.alma /nowin
     let solution 'result'-cal
     run uv_sort gag_scratch:uv_sort-bt.alma /nowin
     run uv_timebase gag_scratch:uv_timebase.alma /nowin
     !
     let solution "solution"
     !
     ! 6) Done                  
     !
     sic rename 'result'-cal.uvt 'result'.uvt
     !
  endif
  !
  ! Add noise ?
  !
  if (addnoise[iarray]) then
     say "I-ALMA, Adding noise to the simulations"
     @ alma_addnoise
  endif
  !
  ! The results are in 'result'.uvt
  ! Now make explicit name (`int_name[iarray]'-only)
  !
  sic copy 'result'.uvt 'int_name[iarray]'-only.uvt
  !
end procedure alma_single_phase
!
begin procedure alma_plot_phase.map
  !
  ! Plot Calibrator Data 
  defin ima a 'calibrator'"-plot.uvt" read
  define real pha /like a[1]
  defin ima b 'solution'"-plot.uvt" read
  define real phb /like b[1]
  define real ra rb phmin phmax
  let pha atan2(a[2],a[1])*180/pi
  let phb atan2(b[2],b[1])*180/pi
  !
  lim /rg a[1]
  clea plot
  set box 3 15 2 11
  compute ra min pha
  compute rb min phb
  let phmin min(ra,rb)
  compute ra max pha
  compute rb max phb
  let phmax max(ra,rb)
  plot pha /scal lin phmin phmax /bound 0.5 a%dim[1]+0.5 user_ymin user_ymax
  box
  !
  ! Plot solution 
  set box 15 27 2 11
  plot phb /scal lin phmin phmax /bound 1.0 b%dim[1]+1.0 user_ymin user_ymax
  box p n
  wedge 
  dele /var a b pha phb
  !
  !
  ! Plot Source Data 
  defin ima a 'result'"-raw-plot.uvt" read
  define real pha /like a[1]
  let pha atan2(a[2],a[1])*180/pi
  delete /var a
  defin ima a 'result'"-cal-plot.uvt" read
  define real phb /like a[1]
  let phb atan2(a[2],a[1])*180/pi
  compute ra min pha
  compute rb min phb
  let phmin min(ra,rb)
  compute ra max pha
  compute rb max phb
  let phmax max(ra,rb)
!
!  lim = = /rg a[1]
  set box 3 15 11 20
  plot pha /scal lin phmin phmax /bound 1.0 a%dim[1]+1.0 user_ymin user_ymax
  box n o
  axis xu /label p
  !
  ! Plot Corrected Data  
  set box 15 27 11 20
  plot phb /scal lin phmin phmax /bound 1.0 a%dim[1]+1.0 user_ymin user_ymax
  box n n
  set box 3 27 11 20
  wedge
  delet /var a
  !
end procedure alma_plot_phase
!
!-------------------------------------------------------------------------
!
! Init file definition
!
!-------------------------------------------------------------------------
!
begin data gag_scratch:alma_prepare.init
  !
  ! parameter file for EXTRACT
  ! 
  TASK\FILE "Input file name" Y_NAME$ 'model'
  TASK\FILE "Output file name" X_NAME$ 'inname'.gdf
  TASK\INTEGER "Bottom left corner" BLC$[4] 0 0 0 0 
  TASK\INTEGER "Top right corner" TRC$[4] 0 0 0 0
  TASK\INTEGER "Position of one pixel in input image" PIXEL_IN$[4] -
      'refin[1]' 'refin[2]' 1 1 
  TASK\INTEGER "Position of this pixel in output image" PIXEL_OUT$[4] -
      'nout/2+1' 'nout/2+1' 1 1
  TASK\LOGICAL "Initialize output image" INITIALIZE$ YES
  TASK\INTEGER "Dimensions of output image" X_DIM$[4] 'nout' 'nout' 0 0
  TASK\LOGICAL "Initialize with blanking value" BLANKOUT$ NO
  TASK\REAL "Initialization value" INITVAL$ 0
  TASK\GO
end data gag_scratch:alma_prepare.init
!
!-------------------------------------------------------------------------
!
begin data gag_scratch:image_sampling.init
  !
  ! Parameter file for IMAGE_SAMPLING
  !
  task\file "Name of sky Image"         SKY$      'inname'.gdf
  task\file "Output Table Name"         SAMPLE$   'sd_pnt'.tab
  task\inte "Number of antenna"         NANT$     'sd_nant'
  task\real "Antenna Diameter (in m)"   DIAM$     'sd_diam'
  task\real "Observational Frequency"   FREQ$     'freq'
  task\inte "Number of Points per Beam" POINT_PER_BEAM$ 'sd_ppb'
  task\inte "Grid Position"             GPOSITION$ 'sd_gpos'
  task\go
  !
end data gag_scratch:image_sampling.init
!
!-------------------------------------------------------------------------
!
begin data gag_scratch:short_model.init
  !
  ! Parameter file for SHORT_MODEL
  !
  task\file "Name of sky Image"                SKY$       'inname'.gdf
  task\file "Table Name of Pointing Centers"   POINT$     'sd_used_pnt'.tab
  task\file "Table Name of Pointing Errors"    ERROR$     'sd_used_pe'.tab
  task\file "Output Table Name"                MODEL$     'sd_res'.tab
  task\inte "Number of mosaic fields"          NFIELDS$   'sd_nsamp/2'
  task\real "Antenna Diameter (in m)"          DIAM$      'sd_diam'
  task\real "Observational Frequency (in GHz)" FREQ$      'freq'
  task\real "Noise Level Required for Weighting (in K)" NOISE$ 'sd_sigma'
  TASK\REAL "Mean and RMS amplitude offset at each calibration (in %, optional)" CALOFF$[2] 'sd_ampoff[1]' 'sd_ampoff[2]'
  TASK\REAL "RMS amplitude drift (in %/hour, optional)"    CALDRIFT$ 'sd_ampdrift'
  TASK\REAL "Time between 2 amplitude calibrations (in s)" CALTIME$  'sd_amptime'
  TASK\REAL "Integration time (in s)"          INTTIME$   'sd_inttime'
  task\real "Pointing Error Sigmas (Optional)" SERR$[2]   'sd_pointerr[1]' 'sd_pointerr[2]'
  task\inte "Pointing Error Model"             PEC$       'sd_pe_code'
  task\logi "Adds Noise ?"                     ADDNOISE$  'sd_addnoise'
  task\logi "Adds Calibration Error ?"         ADDCALERR$ 'sd_addcalerr'
  task\go
  !
end data gag_scratch:short_model.init
!
!-------------------------------------------------------------------------
!
begin data gag_scratch:alma_uv.init
  !
  ! Parameter file for UV_TRACK
  !
  TASK\REAL "Source Declination" DECLINATION$ 'dec'
  TASK\REAL "Line Frequency" FREQUENCY$ 'freq'
  TASK\LOGICAL "New or Old table" NEW$ YES
  TASK\FILE "Table name" UV_TABLE$  'uv_coverage'.uvt
  TASK\FILE "Station file name" STATION_FILE$ 'config_dir'"/"'array[iarray]'-'config[iarray]'.cfg
  TASK\REAL "UV spacing" UV_SPACING$ 'diameter[iarray]/2'
  TASK\REAL "Antenna Diameter" DIAMETER$ 'diameter[iarray]'
  TASK\REAL "Minimum Elevation" HORIZON$ 'horizon[iarray]'
  TASK\REAL "Observatory latitude" LATITUDE$ -23.0
  TASK\REAL "Hour angle range" HOUR$[2]  'hour[1,iarray]' 'hour[2,iarray]'
  TASK\REAL "Integration time" INTEGRATION$ 'inttime[iarray]'
  TASK\REAL "Bandwidth (MHz)" BANDWIDTH$ 'dfreq'
  TASK\REAL "Receiver temperature" TREC$ 'trec[iarray]'
  TASK\REAL "Zenith opacity" TAU$ 'tau[iarray]'
  TASK\REAL "Phase noise" PHASE$ 'phase_rms[iarray]'  
  TASK\GO
  !
end data gag_scratch:alma_uv.init
!
!-------------------------------------------------------------------------
!
begin data gag_scratch:alma_primary.init
  !
  ! Parameter file for PRIMARY
  ! Note: FWHM is negative to APPLY primary beam rather than correct for it
  !       In that case, we dont want to truncate the result
  !
  TASK\FILE "Image to be corrected" Y_NAME$ 'inname'.gdf 
  TASK\FILE "Corrected image" X_NAME$ 'pbeamed'.gdf
  TASK\REAL "FWHM of primary beam (radians)" BEAM$ '-primbeam[iarray]*sec'
  TASK\REAL "Radius to truncate data (radians)" RADIUS$ 1. 
  TASK\GO
  !
end data gag_scratch:alma_primary.init
!
begin data gag_scratch:aca_onep.init
  !
  ! Parameter file for PRIMARY
  !    Correct for primary beam
  TASK\FILE "Image to be corrected" Y_NAME$ tmp-2.gdf 
  TASK\FILE "Corrected image" X_NAME$ 'hybrid_in2_names[hybrid_in2_code]'
  TASK\REAL "FWHM of primary beam (radians)" BEAM$ '-sqrt(primbeam[2]^2-primbeam[1]^2)*sec'
  TASK\REAL "Radius to truncate data (radians)" RADIUS$ 1.0 ! 'primbeam[1]*sec/2'
  TASK\GO
  !
end data gag_scratch:aca_onep.init
!
!-------------------------------------------------------------------------
!
begin data gag_scratch:alma_model.init
  !
  ! Paramater file for UV_FMODEL
  !
  TASK\FILE "Input UV Sample Table" UVSAMPLE$ 'uv_coverage'.uvt
  TASK\FILE "Input Image" IMAGE$ 'pbeamed'.gdf
  TASK\FILE "Output UV Model Table" UVMODEL$ 'result'.uvt
  TASK\REAL "Output Frequency " FREQUENCY$ 'freq'
  TASK\LOGICAL "Accurate or rough method" LARGE$ YES
  TASK\GO
  !
end data gag_scratch:alma_model.init
!
!-------------------------------------------------------------------------
!
begin data gag_scratch:alma_point.init
  !
  ! Parameter file for UV_POINTING
  !
  TASK\FILE "Input UV Sample Table" UVSAMPLE$ 'uv_coverage'.uvt
  TASK\FILE "Input Image"  IMAGE$ 'inname'.gdf
  TASK\FILE "Output UV Model Table" UVMODEL$ 'result'.uvt
  TASK\REAL "Output Frequency " FREQUENCY$ 'freq'
  TASK\LOGICAL "Mosaic observations" MOSAIC$ 'mosaic'
  TASK\INTEGER "Pointing model" CODE$ 'pe_code[iarray]'
  TASK\CHARACTER "Pointing error file" POINTING$ 'int_used_pe'
  TASK\REAL "Pointing Errors" ERRORS$[2]  'pointerr[1,iarray]' 'pointerr[2,iarray]' 
  TASK\REAL "Half-Power Beam Width" PRIMARY$ 'primbeam[iarray]'
  task\logical "Add Anomalous Refraction" ADD_AR$ 'do_anrefr'
  TASK\REAL "Diameter of antenna" DIAMETER$ 'diameter[iarray]'
  TASK\GO
  !
end data gag_scratch:alma_point.init
!
!-------------------------------------------------------------------------
!
begin data gag_scratch:patch.init
  !
  ! Parameter file for EXTRACT
  !
  TASK\FILE "Input file name" Y_NAME$ 'result'.uvt
  TASK\FILE "Output file name" X_NAME$ 'tmp'.uvt
  TASK\INTEGER "Bottom left corner" BLC$[4] 1 1 0 0
  TASK\INTEGER "Top right corner" TRC$[4] 12 -
         'full_iter*nant*(nant-1)/2' 0 0
  TASK\INTEGER "Position of one pixel in input image" PIXEL_IN$[4] 1 1 1 1
  TASK\INTEGER "Position of this pixel in output image" PIXEL_OUT$[4] 1 1 1 1
  TASK\LOGICAL "Initialize output image" INITIALIZE$ YES
  TASK\INTEGER "Dimensions of output image" X_DIM$[4] 12 -
         'full_iter*nant*(nant-1)/2' 0 0
  TASK\LOGICAL "Initialize with blanking value" BLANKOUT$ NO
  TASK\REAL "Initialization value" INITVAL$ 0
  TASK\GO
  !
end data gag_scratch:patch.init
!
!-------------------------------------------------------------------------
! 
begin data gag_scratch:alma_uvshort.init
  !
  ! Parameter file for UV_SHORT
  ! 
  TASK\CHARACTER "Input TABLE name" TABLE$ 'sd_sing'.tab
  TASK\FILE "UV table" UV_TABLE$ 'shortspacings'
  TASK\CHARACTER "Output MAP name" MAP$ singledish
  !
  TASK\INTEGER "Column of X coordinates" XCOL$ 1
  TASK\INTEGER "Column of Y coordinates" YCOL$ 2
  TASK\INTEGER "Column for weights" WCOL$ 3
  TASK\INTEGER "First and last column to grid" MCOL$[2] 4 0
  !
  TASK\CHARACTER "Gridding Mode (GRid, NAtural or UNiform)" WEIGHT_MODE$ NA
  TASK\REAL "X-Y position tolerance" TOLE$ 1*sec     !*** Is it correct?
  TASK\REAL "Minimum weight"  MIN_WEIGHT$[2]  0.01 0 !*** Is it correct?
  !
  TASK\REAL "Single dish beam diameter (radians)" SD_BEAM$ -
                 '63*100/freq*12/sd_diam'*sec 
  TASK\REAL "Single dish diameter (m)" SD_DIAM$ 'sd_diam'
  TASK\REAL "Interferometer primary beam (radians)" IP_BEAM$ -
                 'primbeam[iarray]'*sec
  TASK\REAL "Interferometer diameter (m)" IP_DIAM$  'diameter[iarray]' 
  TASk\REAL "Single dish uv truncation radius (m)" UV_TRUNC$ -
                 'sd_diam-diameter[iarray]' 
  TASK\LOGICAL "Do single dish deconvolution" DO_SINGLE$ YES
  TASK\LOGICAL "Do primary beam product" DO_PRIMARY$ YES
  TASK\REAL "Single dish total weight" SD_WEIGHT$ 1.0
  TASK\REAL "Single dish calibration factor" SD_FACTOR$ 1.0 
  !
  TASK\CHARACTER "Center of mosaic: R.A." MOSAIC_RA$ 0. 
  TASK\CHARACTER "Center of mosaic: Dec." MOSAIC_DEC$ 0.
  TASK\INTEGER "Number of fields" NF$ 'nfields'
  TASK\REAL "Offsets of fields in X (RA) (radians)"  RA$[NF$] xoffset_rad
  TASK\REAL "Offsets of fields in Y (Dec) (radians)" DEC$[NF$] yoffset_rad
  TASK\GO
  !
end data gag_scratch:alma_uvshort.init
!
!-------------------------------------------------------------------------
! 
begin data gag_scratch:alma_uvmerge.init
  !
  ! Parameter file for UV_MERGE
  ! 
  TASK\FILE "First input UV Table" TABLE_IN$ 'in1'
  TASK\REAL "Weight multiplicative factors" WEIGHT$ 'sd_weight' 
  TASK\REAL "Data multiplicative factors" FACTOR$ 1 
  TASK\FILE "Second input UV Table (reference)" TABLE_REF$ 'in2'
  TASK\FILE "Output merged UV Table" TABLE_OUT$ 'out'
  TASK\GO
  !
end data gag_scratch:alma_uvmerge.init
!
!-------------------------------------------------------------------------
!
begin data gag_scratch:alma_uvzero.init
  !
  ! Parameter file for UV_ZERO
  !
  TASK\FILE "UV table" UV_TABLE$ 'in1'
  TASK\REAL "Zero spacing continuum flux" FLUX$ 'zscf'
  TASK\LOGI "Include spectral data" DO_SPECTRUM$ no
  TASK\FILE "GREG table from CLASS" GREG_TABLE$ "dummy"
  TASK\REAL "Zero spacing weight" WEIGHT$ 'zs_weight'
  TASK\REAL "Zero spacing calibration factor" FACTOR$ 1.0
  TASK\GO
  !
end data gag_scratch:alma_uvzero.init
!
!-------------------------------------------------------------------------
! 
begin data gag_scratch:make_mosaic.init
  !
  ! Parameter file for MAKE_MOSAIC
  !
  TASK\INTEGER "Number of fields" FIELDS$ 'nfields'
  TASK\FILE "Generic file name (without extension)" NAME$ 'fullname' 
  TASK\REAL "Half-Power Primary Beam (in radians)" BEAM$ 'primbeam[iarray]*beam_scale[iarray]*sec'
  TASK\REAL "Truncation Threshold" BMIN$ 'truncate[iarray]'
  TASK\GO 
  !
end data gag_scratch:make_mosaic.init
!
!-------------------------------------------------------------------------
!
begin data gag_scratch:alma_uvcircle.init
  !
  ! parameter file for UV_CIRCLE
  !
  TASK\FILE "Input table" UVTABLE$ 'fullname'
  TASK\FILE "Output table" OUTABLE$ 'fullname'-avg
  TASK\REAL "Minimum radius (m)"  QMIN$  'uvrange[1]'
  TASK\REAL "Maximum radius (m)"  QMAX$  'uvrange[2]'
  TASK\REAL "Radius interval (m)" QSTEP$ 'rstep'
  TASK\GO
  !
end data gag_scratch:alma_uvcircle.init
!
!-------------------------------------------------------------------------
!
begin data gag_scratch:alma_uvhybrid.init
  !
  ! Parameter file for UV_HYBRID
  !
  TASK\CHAR "ALMA image"           ALMA$ 'hybrid_in1_names[hybrid_in1_code]'
  TASK\CHAR "ALMA+ACA image"       ACA$  'hybrid_in2_names[hybrid_in2_code]'
  TASK\CHAR "Output Image"         ALL$  'kname[7]'".lmv-clean"
  TASK\REAL "UV transition radius" UVRADIUS$ 'hybrid_uvradius'
  TASK\GO
  !
end data gag_scratch:alma_uvhybrid.init
begin data gag_scratch:alma_uvhybrid2.init
  !
  ! Parameter file for UV_HYBRID
  !
  TASK\CHAR "ALMA image"           ALMA$ 'hybrid_in1_names[hybrid_in1_code]'
  TASK\CHAR "ALMA+ACA image"       ACA$  'hybrid_in2_names[hybrid_in2_code]'
  TASK\CHAR "Output Image"         ALL$  tmp-3.gdf ! 'kname[7]'".lmv-clean"
  TASK\REAL "UV transition radius" UVRADIUS$ 'hybrid_uvradius'
  TASK\GO
  !
end data gag_scratch:alma_uvhybrid2.init
!
!-------------------------------------------------------------------------
!
begin data gag_scratch:gauss_smooth.init
  !
  ! Parameter file for GAUSS_SMOOTH
  !
  TASK\FILE "Input file" Y_NAME$ 'tmp_inname'.gdf
  TASK\FILE "Output smoothed image" X_NAME$ 'kname[kind]''new_inname'.gdf
  TASK\REAL "Major axis of convolving gaussian" MAJOR$ 'cbeam[1]'
  TASK\REAL "Minor axis of convolving gaussian" MINOR$ 'cbeam[2]'
  TASK\REAL "Position angle" PA$ 'cbeam[3]*180/pi'
  TASK\GO
  !
end data gag_scratch:gauss_smooth.init
!
!-------------------------------------------------------------------------
!
begin data gag_scratch:gauss_compress.init
  !
  ! Parameter file for GAUSS_COMPRESS
  !
  TASK\FILE "Input file name" INPUT_MAP$ 'tmp_inname'.gdf
  TASK\FILE "Output file name" OUTPUT_MAP$ 'kname[kind]''new_inname'.gdf
  TASK\INTEGER "Compression factor" COMPRESS$ 'nbin'
  TASK\REAL "Major axis of convolving gaussian" MAJOR$ 'cbeam[1]'
  TASK\REAL "Minor axis of convolving gaussian" MINOR$ 'cbeam[2]'
  TASK\REAL "Position angle" PA$ 'cbeam[3]*180/pi'
  TASK\GO
  !
end data gag_scratch:gauss_compress.init
!
!-------------------------------------------------------------------------
!
begin data gag_scratch:alma_extract.init
  !
  ! Parameter file for EXTRACT
  !
  TASK\FILE "Input file name" Y_NAME$ 'kname[kind]'.lmv-clean
  TASK\FILE "Output file name" X_NAME$ 'kname[kind]''outname'.gdf
  TASK\INTEGER "Bottom left corner" BLC$[4] 'ablc[1]' 'ablc[2]' 0 0 
  TASK\INTEGER "Top right corner" TRC$[4] 'atrc[1]' 'atrc[2]' 0 0
  TASK\INTEGER "Position of one pixel in input image" PIXEL_IN$[4] -
     'cin[1]' 'cin[2]' 1 1 
  TASK\INTEGER "Position of this pixel in output image" PIXEL_OUT$[4] -
     'cout[1]' 'cout[2]' 1 1
  TASK\LOGICAL "Initialize output image" INITIALIZE$ YES
  TASK\INTEGER "Dimensions of output image" X_DIM$[4] 'nin%dim[1]' 'nin%dim[2]' 0 0
  TASK\LOGICAL "Initialize with blanking value" BLANKOUT$ NO
  TASK\REAL "Initialization value" INITVAL$ 0
  TASK\GO
  !
end data gag_scratch:alma_extract.init
!
! ------------------------------------------------------------------------
!
begin data gag_scratch:alma_histo.init
  !
  ! Parameter file for HISTO_SIMPLE
  !
  TASK\FILE "Input image" Y_NAME$ 'kname[kind]''fidname'.gdf
  TASK\INTEGER "Bottom left corner" Y_BLC$[4]  0 0 0 0
  TASK\INTEGER "Top right corner" Y_TRC$[4]  0 0 0 0
  TASK\INTEGER "Number of histograms bins" X_BINS$ 256
  TASK\REAL "Minimum value" X_MIN$ 1
  TASK\REAL "Maximum value" X_MAX$ 'fidmax'
  TASK\FILE "Output histogram name" X_NAME$ 'kname[kind]''histogram'.gdf
  TASK\GO
  !
end data gag_scratch:alma_histo.init
!
!-------------------------------------------------------------------------
!
begin data gag_scratch:alma_average.init
  !
  ! Parameter file for AZIMUTH_AVERAGE
  !
  TASK\FILE "Name of input 2D image"         IMAGE$    'in1'
  TASK\FILE "Name of 1D azimuthal sum"       SUMMED$   'in1''a_sum'
  TASK\FILE "Name of 1D azimuthal average"   AVERAGED$ 'in1''a_avg'
  TASK\FILE "Plane number of the used image" NPLANE$   'first'
  TASK\GO
  !
end data gag_scratch:alma_average.init
!
!-------------------------------------------------------------------------
!
begin data gag_scratch:alma_uvfidelity.init
  !
  ! Parameter file for UV_FIDELITY
  !
  TASK\FILE "Input model image" MODEL$ 'kname[kind]''new_inname'"-masked".gdf
  TASK\FILE "Input simulated image" IMAGE$ 'kname[kind]''outname'"-masked".gdf
  TASK\CHAR "Result file" RESULT$ 'kname[kind]''uvfidelity'.gdf
  TASK\GO
end data gag_scratch:alma_uvfidelity.init
!
!-------------------------------------------------------------------------
!
begin data gag_scratch:uv_timeaverage.alma
  TASK\FILE     "Input UV table" INPUT$ 'uv_coverage'-fine.uvt 
  TASK\FILE     "Smoothed UV table" OUTPUT$ 'uv_coverage'.uvt
  TASK\REAL     "Integration time" NTIME$ 'dumps[1]'
  TASK\LOGI     "Correct for decorrelation?" DO_DECORR$ NO
  TASK\GO
end data gag_scratch:uv_timeaverage.alma
!
!-------------------------------------------------------------------------
!
begin data gag_scratch:uv_applyphase.alma
  !
  ! Parameter file for UV_APPLYPHASE
  !
  TASK\FILE 	"Input UV Sample Table" INPUT$ 'uv_coverage'.uvt
  TASK\FILE 	"Output UV Model Table" OUTPUT$ 'result'.uvt
  TASK\LOGICAL  "Normalize amplitude?" AMP_CORRECT$ NO
  TASK\GO
end data gag_scratch:uv_applyphase.alma
!
! Restore private initialization
if (file("gag_init:init.alma")) then
   say " "
   say "Loads init.alma"
   @ gag_init:init.alma
   say "Loading done"
   say " "
endif
!-------------------------------------------------------------------------
!
begin data gag_scratch:uv_observe.alma
  !
  ! Parameter file for UV_TRACK
  !
  TASK\REAL "Source Declination" DECLINATION$ 'dec'
  TASK\REAL "Line Frequency" FREQUENCY$ 'freq'
  TASK\LOGICAL "New or Old table" NEW$ YES
  TASK\FILE "Table name" UV_TABLE$  'uv_coverage'-fine.uvt !SG
  TASK\FILE "Station file name" STATION_FILE$ 'config_dir'"/"'array[iarray]'-'config[iarray]'.cfg
  TASK\REAL "UV spacing" UV_SPACING$ 'diameter[iarray]/2'
  TASK\REAL "Antenna Diameter" DIAMETER$ 'diameter[iarray]'
  TASK\REAL "Minimum Elevation" HORIZON$ 'horizon[iarray]'
  TASK\REAL "Observatory latitude" LATITUDE$ -23.0
  TASK\REAL "Hour angle range" HOUR$[2]  'hour[1,iarray]' 'hour[2,iarray]'
  TASK\REAL "Integration time" INTEGRATION$ 2.0 ! 'inttime[iarray]'
  TASK\REAL "Bandwidth (MHz)" BANDWIDTH$ 'dfreq'
  TASK\REAL "Receiver temperature" TREC$ 'trec[iarray]'
  TASK\REAL "Zenith opacity" TAU$ 'tau[iarray]'
  TASK\REAL "Phase noise" PHASE$ 'phase_rms[iarray]'
  !
  TASK\LOGICAL "Use phase screen?" DO_SCREEN$ do_screen
  TASK\CHARACTER "Phase screen file" PHASE_SCREEN$ 'phase_screen[iarray]'
  TASK\REAL "Phase noise at 100-m" PHASE_NOISE$ 'phase_noise[iarray]'
  TASK\REAL "Wind position angle (deg)" WINDANGLE$  'wind[1]'
  TASK\REAL "Wind velocity (m/s)" WINDVELO$ 'wind[2]'
  !
  TASK\LOGICAL "Create calibrator table?" DO_CALIB$ YES
  TASK\CHARACTER "Calibrator uv table" CAL_UV_TABLE$ 'calibrator'
  TASK\REAL "Dead time (sec)" DEADTIME$ 2.0
  TASK\REAL "Calib. integ. time (dumps)" CAL_INTEG$ 'dumps[2]/2.0'
  TASK\REAL "Source integ. time (dumps)" SOURCE_INTEG$ 'dumps[1]/2.0'
  TASK\REAL "Angular distance of calib. (deg)" CAL_DIST$ 'calangle[2]'
  TASK\REAL "Position angle calib. direction" CAL_ANGLE$ 'calangle[1]'
  TASK\REAL "Phase screen altitude" ALTITUDE$ 'wind[3]'
  !
  TASK\LOGICAL "Apply WVR ?" DO_RADIOM$ do_wvr
  TASK\REAL "WVR Precision" WVR_PRECIS$ 'wvr[1]'
  TASK\REAL "WVR Noise" WVR_NOISE$ 'wvr[2]'
  TASK\LOGICAL "Correct Calibrator Phase" DO_CORRECT$ 'do_calib'  
  !
  TASK\REAL "Amplitude error and drift" AMPLITUDE$[2] 'amplitude[1,iarray]' 'amplitude[2,iarray]'
  TASK\REAL "Time between amplitude calibration" AMP_TIME$ 'amp_time[iarray]'
  !
  TASK\LOGICAL "Compute anomalous refraction?" DO_ANREFR$ 'do_anrefr'
  TASK\GO
end data gag_scratch:uv_observe.alma
!
!-------------------------------------------------------------------------
!
begin data gag_scratch:uv_sort-bt.alma
  TASK\CHARACTER "Input UVDATA table" UVDATA$ 'solution'".uvt" 
  TASK\CHARACTER "Output sorted table" UVSORT$ 'solution'"-sorted.uvt"
  TASK\CHARACTER "Sort type (UV or TB)" TYPE$ "BT"
  TASK\GO
end data gag_scratch:uv_sort-bt.alma
!
!-------------------------------------------------------------------------
!
begin data gag_scratch:uv_scantime.alma
  TASK\FILE 	"Input UV Sample Table" INPUT$ 'uv_coverage'".uvt"
  TASK\FILE 	"Output UV Model Table" OUTPUT$ uv_scantime.tmp
  TASK\FILE     "Number of fields" FIELDS$ 0
  TASK\GO
end data gag_scratch:uv_scantime.alma
!
begin data gag_scratch:uv_splitfield.alma
  TASK\FILE "Input UV table" INPUT$ 'result'
  TASK\FILE "Generic name of output UV tables" OUTPUT$ 'fullname'
  TASK\INTEGER "Number of fields " FIELDS$ 'nfields'
  TASK\GO
end data gag_scratch:uv_splitfield.alma
!
begin data gag_scratch:uv_timebase.alma
  TASK\FILE 	"Input UV Sample Table" INPUT$ 'solution'"-sorted.uvt" 
  TASK\FILE 	"Output UV Model Table" OUTPUT$ 'solution'"-plot.uvt" 
  TASK\GO
end data gag_scratch:uv_timebase.alma
!
!-------------------------------------------------------------------------
!
begin data gag_scratch:uv_solve.alma
 TASK\CHAR  "Calibrator UV table "  CALIBRATOR$ 'calibrator'"-sorted.uvt"
 TASK\CHAR  "Solution UV table"  RESULT$ 'solution'".uvt"
 TASK\CHAR  "Raw UV table"  RAW$ 'raw'".uvt" 
 TASK\CHAR  "Calibrated UV table"  CAL$ 'cal'".uvt"
 TASK\LOGI  "Solve Amplitude"  SOLVE_AMP$ NO
 TASK\LOGI  "Solve Phase"  SOLVE_PHASE$ YES
 TASK\LOGI  "Apply Amplitude "  APPLY_AMP$ NO
 TASK\LOGI  "Apply Phase"  APPLY_PHASE$ 'do_calib'
 TASK\INTE  "Spline or Polynom" FUNCTION$ ispline
 TASK\REAL  "Polynom degree or Spline time step"  ORDER$ spline_step
 TASK\GO
end data gag_scratch:uv_solve.alma
!-------------------------------------------------------------------------
!
! Miscelleanous
!
!-------------------------------------------------------------------------
!
! Restore last values
!
if (file("parameters.map")) then
   !
   @ parameters.map
   if (done) then
      @ alma_display
   else
      say ""
      say "E-ALMA, This kind of  simulation has not gone up to its end."
      say "E-ALMA, Push the COMPUTE button to make it with the current parameters."
      say ""
   endif
   !
endif
!
if (batch) then
   return
endif
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
begin procedure alma_pipeline_mode
  !
  ! Everything single variable that you add here should have a `old_' 
  ! counterpart. 
  ! Accordingly, you should update:
  !    1 the section about the definition and initialization of global
  !      variables;
  !    2 the `alma_compute' procedure;
  !    3 the `alma_save' procedure.
  ! If you skip a step, the simulation will be in a weird state.
  !
  gui\panel "ALMA+ACA Simulation (email: gildas@iram.fr)" gag_log:pipeline_mode.hlp
  !
  ! Start with parameter definitions
  !
  sic\let model 'model' /prompt "Input model file" /file 'image_dir'"/*.gdf"
  sic\let output_dir 'output_dir' /prompt "Output directory name" /file *
  !
  sic\let kind 'kind' /prompt "Simulation kind" -
         /index "ALMA only" "ACA only" "ALMA+ACA" "ALMA+SD" "ACA+SD" "All" "Hybrid" 
  !
  gui\button "" "SHOW SOURCE" "Observation Setup" gag_log:observations.hlp "Parameters" 
     sic\say "Source"
     sic\let change_dec 'change_dec' /prompt "Change Declination ?"
     sic\let dec 'dec' /prompt "New declination"
     sic\let change_size 'change_size' /prompt "Change image size ?"
     sic\let image_size 'image_size[1]' 'image_size[2]' /prompt "New image size"
     sic\say
     sic\say "Mosaic definition"
     sic\let mos_size  'mos_size[1]' 'mos_size[2]' /prompt "Mosaic size (arcsec)"
     sic\let mos_orien 'mos_orien' /prompt "Mosaic orientation (deg)" /choice 0 90
     sic\let closest 'closest' /prompt "Circular or rectangular shape ?" 
          sic\say "SD sampling parameters"
     sic\let sd_ppb  'sd_ppb'  /prompt "Number of points per beam"
     sic\let sd_gpos 'sd_gpos' /prompt "Grid position" -
                               /index  "Centered" "Reference"
     sic\say 
     sic\say "Frequency"
     sic\let freq 'freq' /prompt "Observing frequency (GHz)"
     sic\let dfreq 'dfreq' /prompt "Bandwidth (MHz)"
     sic\say
     sic\say "Observing time"
     sic\let hour[,1] 'hour[1,1]' 'hour[2,1]' /prompt "ALMA hour angle range"
     sic\let hour[,2] 'hour[1,2]' 'hour[2,2]' /prompt "ACA hour angle range"
     sic\let sd_time  'sd_time'  /prompt "SD (on+off) integration time (hour)"
  !
  gui\button "" "SHOW CONF" "Configuration Setup" gag_log:configurations.hlp "Parameters" 
     sic\say "ALMA array setup"
     sic\let diameter[1] 'diameter[1]' /prompt "Diameter (fixed)" /choice 
     sic\let array[1] 'array[1]' /prompt "Array name"
     sic\let config[1] 'config[1]' /prompt "Configuration name" 
     sic\say
     sic\say "ACA array setup"
     sic\let diameter[2] 'diameter[2]' /prompt "Diameter (m)"  
     sic\let array[2] 'array[2]' /prompt "Array name"
     sic\let config[2] 'config[2]' /prompt "Configuration name"
     sic\say
     sic\say "Single Dish"
     sic\let sd_diam 'sd_diam' /prompt "Diameter (m)"
     sic\let sd_nant 'sd_nant' /prompt "Number of antennas"
  !
  gui\button "" "SHOW POINT" "Pointing Errors" gag_log:obs_conditions.hlp "Parameters" 
     sic\let pe_code[1] 'pe_code[1]' /prompt "ALMA            Error model" -
             /index "No errors" "Fix" "Random" "Antenna" "GDF file" 
     sic\let pointerr[,1] 'pointerr[1,1]' 'pointerr[2,1]' /prompt "Pointing errors"
     sic\let int_pe[1]  'int_pe[1]' /prompt "Error file" /file 'pnterr_dir'"/*alma*.tab"
     sic\let pe_code[2] 'pe_code[2]' /prompt "ACA             Error model" -
             /index "No errors" "Fix" "Random" "Antenna" "GDF file" 
     sic\let pointerr[,2] 'pointerr[1,2]' 'pointerr[2,2]' /prompt "Pointing errors"
     sic\let int_pe[2] 'int_pe[2]' /prompt "Error file" /file 'pnterr_dir'"/*aca*.tab"
     sic\let sd_pe_code 'sd_pe_code' /prompt "SD              Error model" -
             /index "No errors" "Fix" "Random" "Antenna" "GDF file" 
     sic\let sd_pointerr 'sd_pointerr[1]' 'sd_pointerr[2]' /prompt "Pointing errors"
     sic\let sd_pe 'sd_pe' /prompt "Error file" /file 'pnterr_dir'"/*sd*.tab"
  !
  gui\button "" "SHOW AMP" "Amplitude conditions" gag_log:obs_conditions.hlp "Parameters" 
     sic\let trec 'trec[1]' 'trec[2]' /prompt "ALMA / ACA / SD Receiver temperature"
     sic\let tau  'tau[1]'  'tau[2]'  /prompt "ALMA / ACA / SD Zenith opacity"
     sic\let sd_tsys 'sd_tsys' /prompt "SD            System temperature"
     sic\let addnoise[1] 'addnoise[1]' /prompt "Add thermal noise to ALMA?" 
     sic\let addnoise[2] 'addnoise[2]' /prompt "Add thermal noise to ACA?" 
     sic\let sd_addnoise 'sd_addnoise' /prompt "Add thermal noise to SD ?" 
     sic\let sd_addcalerr 'sd_addcalerr' /prompt "Add amplitude error to SD ?" 
     sic\let amplitude[1] 'amplitude[1,1]' 'amplitude[2,1]' /prompt "ALMA Amplitude errors & drift"
     sic\let amplitude[2] 'amplitude[1,2]' 'amplitude[2,2]' /prompt "ACA Amplitude errors & drift"
     sic\let amp_time     'amp_time[1]'    'amp_time[2]'    /prompt "ALMA/ACA Amplitude error time scale"
     sic\let sd_ampoff    'sd_ampoff[1]'   'sd_ampoff[2]'   /prompt "SD mean and RMS of amplitude offset at calibration time (%)"
     sic\let sd_ampdrift  'sd_ampdrift'                     /prompt "SD drift slope (%/hour)"
     sic\let sd_amptime   'sd_amptime'                      /prompt "Time between 2 SD amplitude calibration"
  !
  gui\button "" "SHOW PHASE" "Phase conditions" gag_log:obs_phase.hlp "Parameters"
     sic\let do_screen 'do_screen' /prompt "Use phase screen"
     sic\let phase_screen[1] 'phase_screen[1]' /prompt "ALMA Phase screen file"
     sic\let phase_screen[2] 'phase_screen[2]' /prompt "ACA Phase screen file"
     sic\let phase_noise 'phase_noise[1]' 'phase_noise[2]' /prompt "Phase noise"
     sic\let wind 'wind[1]' 'wind[2]' 'wind[3]' /prompt "Wind direction/speed/altitude"
     sic\let calibrator 'calibrator'  /prompt "Calibrator UV table"
     sic\let dumps 'dumps[1]' 'dumps[2]' /prompt "Dumps on Source / Calibrator"
     sic\let calangle 'calangle[1]' 'calangle[2]' /prompt "Calibrator Direction / Distance"
     !
     sic\say
     sic\say "Water Vapour Radiometer"
     sic\let do_wvr 'do_wvr' /prompt "Use WVR"
     sic\let wvr 'wvr[1]' 'wvr[2]' /prompt "WVR precision and noise"
     sic\let do_calib 'do_calib' /prompt "Apply Calibration"
     sic\say "If no WVR calibration"
     sic\let spline_step 'spline_step' /prompt "Spline step"
     sic\let ispline 'ispline' /prompt "Polynom degree"
     sic\say
     sic\let phase_rms 'phase_rms[1]' 'phase_rms[2]' /prompt "ALMA/ACA Phase noise (deg)"
     sic\let do_anrefr 'do_anrefr' /prompt "Use anomalous refraction"
  !
  gui\button "@ alma_compute" "COMPUTE" "Deconvolution setup" gag_log:deconvolution.hlp "Parameters" 
     sic\let sd_weight  'sd_weight'  /prompt "Automatically found single dish weight" /choice
     sic\let sd_rweight 'sd_rweight[1]' 'sd_rweight[2]' /prompt "Multiplicative factor"
     sic\let truncate 'truncate[1]' 'truncate[2]' /prompt "Primary beam truncation ALMA / ACA"
     sic\let beam_scale 'beam_scale[1]' 'beam_scale[2]' /prompt "Primary beam angular scale ALMA / ACA"
     sic\say
     sic\let alma_method 'alma_method' /prompt "Deconvolution" /choice "HOGBOM   " "CLARK  " "MULTI   " "SDI    "
     sic\let diter 'diter'   /prompt "Number of CLEAN components"
     sic\let gains 'gains[1]' 'gains[2]' /prompt "ALMA & Compact Clean gain"
     sic\let f_thres 'f_thres' /prompt "Flux threshold for ALMA+ACA" 
     sic\let asmooth 'asmooth' /prompt "Smoothing kernel size (in pixel)"
     sic\say
     sic\let hybrid_in1_code 'hybrid_in1_code' /prompt "ALMA file to be used for hybridation" - 
             /index 'hybrid_in1_names[1]' 'hybrid_in1_names[2]'
     sic\let hybrid_in2_code 'hybrid_in2_code' /prompt " ACA file to be used for hybridation" - 
             /index 'hybrid_in2_names[1]' 'hybrid_in2_names[2]'
     sic\let hybrid_uvradius 'hybrid_uvradius' /prompt "UV transition radius during hybridation"
  !
  gui\button "@ alma_display" "DISPLAY" "Display results" gag_log:display.hlp "Parameters"
     sic\let display_mode 'display_mode' /prompt "What to plot ?" -
             /index "Field positions" "SD map" "UV weights" "Beam" -
                    "Flux convergence" "Image comparison" "UV comparison" -
                    "Results 1" "Results 2" "Calibration"
!!     sic\say
     sic\let do_bit 'do_bit' /prompt "Show bitmap images ?" 
     sic\let do_contour 'do_contour' /prompt "Draw contours ?" 
     sic\let do_grey 'do_grey' /prompt "Fill contours ?" 
     sic\let do_nice yes
     sic\let size[1] 'size[1]' /prompt "Display size (arcsec)"
     sic\let uv_limit 'uv_limit' /prompt "UV Range"
!!     sic\say
     sic\let alma_print 'alma_print' /prompt "Print results?"
     sic\let pkind 'pkind' /prompt "PS device" -
             /index 'pname[1]' 'pname[2]' 'pname[3]' 
     sic\let okind 'okind' /prompt "Output mode" -
             /index 'oname[1]' 'oname[2]' 
!!     sic\say
  !
  gui\button "@ alma_compute" "EXPERT" "Expert setup" gag_log:expert_mode.hlp "Parameters" 
     sic\let force_setup 'force_setup' /prompt "Do setup the simulation"
     sic\let force_sd    'force_sd'    /prompt "Do compute single dish image"
     sic\let force_alma  'force_alma'  /prompt "Do compute ALMA UV table"
     sic\let force_aca   'force_aca'   /prompt "Do compute ACA UV table"
     sic\let force_uvmap 'force_uvmap' /prompt "Do make maps from UV tables"
     sic\let force_decon 'force_decon' /prompt "Do deconvolve"
     sic\let force_compa 'force_compa' /prompt "Do compare simulated with input image"
  !
  gui\button "" "SETUP" "File location" gag_log:location.hlp "Parameters"
     sic\let image_dir  'image_dir'  /prompt "Image directory"          /file 'input_dir'*
     sic\let config_dir 'config_dir' /prompt "Configuration directory"  /file 'input_dir'*
     sic\let pnterr_dir 'pnterr_dir' /prompt "Pointing error directory" /file 'input_dir'*
  !
  ! General buttons at the end only
  gui\button "@ alma_load"        "LOAD"
  gui\button "@ alma_compute"     "COMPUTE"
  gui\button "@ alma_compare"     "COMPARE"
  gui\button "@ alma_display"     "DISPLAY"
  gui\button "@ alma_expert_mode" "EXPERT"
  !
  ! See the beginning of the `alma_compute' procedure for an explanation. 
  !
  on error "return base"
  gui\go
  !
end procedure alma_pipeline_mode
!
!-------------------------------------------------------------------------
!
begin procedure alma_expert_mode
  !
  gui\panel "ALMA+ACA Simulation" gag_log:expert_mode.hlp
  !
  sic\say "This is the rope to hang yourself!"
  sic\say "This does not keep track of what you're doing."
  !
  sic\let model 'model' /prompt "Input model file" /file 'image_dir'"/*.gdf"
  sic\let image_dir  'image_dir'  /prompt "Image directory"          /file 'input_dir'*
  sic\let config_dir 'config_dir' /prompt "Configuration directory"  /file 'input_dir'*
  sic\let pnterr_dir 'pnterr_dir' /prompt "Pointing error directory" /file 'input_dir'*
  sic\let output_dir 'output_dir' /prompt "Output directory name"    /file *
  !
  gui\button "@ alma_load" -
     "LOAD" "Load a simulation" gag_log:alma_load.hlp "Parameters"
     sic\let kind 'kind' /prompt "Simulation kind" -
         /index "ALMA only" "ACA only" "ALMA+ACA" "ALMA+SD" "ACA+SD" "all" 
  !
  gui\button "@ alma_setup" -
     PREPARE "Prepare observations" gag_log:alma_setup.hlp "Parameters"
     sic\say "Source"
     sic\let change_dec 'change_dec' /prompt "Change Declination ?"
     sic\let dec 'dec' /prompt "New declination"
     sic\let change_size 'change_size' /prompt "Change image size ?"
     sic\let image_size 'image_size[1]' 'image_size[2]' /prompt "New image size"
     sic\say 
     sic\say "Observations"
     sic\let freq 'freq' /prompt "Observing frequency (GHz)"
     sic\let dfreq 'dfreq' /prompt "Bandwidth (MHz)"
     sic\let mos_size 'mos_size[1]' 'mos_size[2]' /prompt "Mosaic size (arcsec)"
  !
  gui\button "@ alma_single_dish" -
     "SINGLE DISH" "Observations with" gag_log:alma_single_dish.hlp "Parameters"
     sic\say "Antennas"
     sic\let sd_diam 'sd_diam' /prompt "Diameter (m)"
     sic\let sd_nant 'sd_nant' /prompt "Number of antennas"
     sic\say 
     sic\say "(Observing frequency can be modified with the PREPARE tool)"
     sic\let freq    'freq'    /prompt "Obs. frequency (fixed)" /choice 
     sic\say 
     sic\say "Sampling parameters"
     sic\let sd_ppb  'sd_ppb'  /prompt "Number of points per beam"
     sic\let sd_gpos 'sd_gpos' /prompt "Grid position" -
                               /index  "Centered" "Reference"
     sic\say
     sic\say "Pointing errors"
     sic\let sd_pe_code 'sd_pe_code' /prompt "Error model" -
             /index "No errors" "Fix" "Random" "Antenna" "GDF file" 
     sic\let sd_pointerr 'sd_pointerr[1]' 'sd_pointerr[2]' /prompt "Pointing errors"
     sic\let sd_pe  'sd_pe' /prompt "Error file" /file 'pnterr_dir'"/*sd*.tab"
     sic\say 
     sic\say "Weights and Noise"
     sic\say "(Only one of the 2 first parameters must be set)"
     sic\say "(Calibration parameters are optional)"
     sic\let sd_sigma 'sd_sigma' /prompt "Required noise level (K)"
     sic\let sd_time  'sd_time'  /prompt "Total (on+off) integration time (hour)"
     sic\let sd_tsys  'sd_tsys'  /prompt "System temperature"
     sic\let sd_addnoise 'sd_addnoise' /prompt "Add thermal noise?" 
     sic\let sd_addcalerr 'sd_addcalerr' /prompt "Add calibration error ?" 
  !
  gui\button "@ alma_interfero 1" -
     "ALMA ARRAY" "Observations with" gag_log:alma_interfero.hlp "Parameters"  
     sic\say "ALMA array setup"
     sic\let diameter[1] 'diameter[1]' /prompt "Diameter (fixed)" /choice 
     sic\let array[1] 'array[1]' /prompt "Array name"
     sic\let config[1] 'config[1]' /prompt "Configuration name"
     sic\say 
     sic\say "Observations"
     sic\let hour[,1]   'hour[1,1]' 'hour[2,1]' /prompt "Hour angle range"
     sic\let horizon[1] 'horizon[1]' /prompt "Minimum Elevation"
     sic\say 
     sic\say "Pointing errors"
     sic\let pe_code[1] 'pe_code[1]' /prompt "Error model" -
             /index "No errors" "Fix" "Random" "Antenna" "GDF file" 
     sic\let pointerr[,1] 'pointerr[1,1]' 'pointerr[2,1]' /prompt "Pointing errors"
     sic\let int_pe[1] 'int_pe[1]' /prompt "Error file" /file 'pnterr_dir'"/*alma*.tab"
     sic\say 
     sic\say "Weights and Noise"
     sic\say "(Observing frequency can be modified with the PREPARE tool)"
     sic\let freq 'freq' /prompt "Obs. frequency (fixed)" /choice 
     sic\let trec[1] 'trec[1]' /prompt "Receiver temperature"
     sic\let tau[1]  'tau[1]'  /prompt "Zenith opacity"
     sic\let addnoise[1] 'addnoise[1]' /prompt "Add thermal+phase noise ?" 
     sic\let phase_rms[1]    'phase_rms[1]'    /prompt "Phase noise (deg)"


  !
  gui\button "@ alma_interfero 2" -
     "ACA ARRAY" "Observations with" gag_log:alma_interfero.hlp "Parameters"  \
     sic\say "ACA array setup"
     sic\let diameter[2] 'diameter[2]' /prompt "Diameter (m)"  
     sic\let array[2] 'array[2]' /prompt "Array name"
     sic\let config[2] 'config[2]' /prompt "Configuration name"
     sic\say 
     sic\say "Observations"
     sic\let hour[,2]   'hour[1,2]' 'hour[2,2]' /prompt "Hour angle range"
     sic\let horizon[2] 'horizon[2]' /prompt "Minimum Elevation"
     sic\say 
     sic\say "Pointing errors"
     sic\let pe_code[2] 'pe_code[2]' /prompt "Error model" -
             /index "No errors" "Fix" "Random" "Antenna" "GDF file" 
     sic\let pointerr[,2] 'pointerr[1,2]' 'pointerr[2,2]' /prompt "Pointing errors"
     sic\let int_pe[2] 'int_pe[2]' /prompt "Error file" /file 'pnterr_dir'"/*aca*.tab"
     sic\say 
     sic\say "Weights and Noise"
     sic\say "(Observing frequency can be modified with the PREPARE tool)"
     sic\let freq 'freq' /prompt "Obs. frequency (fixed)" /choice 
     sic\let trec[2] 'trec[2]' /prompt "Receiver temperature"
     sic\let tau[2] 'tau[2]' /prompt "Zenith opacity"
     sic\let addnoise[2] 'addnoise[2]' /prompt "Add thermal+phase noise ?" 
     sic\let phase_rms[2]    'phase_rms[2]'    /prompt "Phase noise (deg)"
  !
  gui\button "@ alma_uvmap" -
     UV->MAP "Do the map(s)" gag_log:alma_uvmap.hlp "Parameters"
     sic\let process 'process' /prompt "Which array to process?" -
             /index ALMA ACA BOTH
     sic\let truncate 'truncate[1]' 'truncate[2]' /prompt "Primary beam truncation ALMA / ACA"
     sic\let beam_scale 'beam_scale[1]' 'beam_scale[2]' /prompt "Primary beam angular scale ALMA / ACA"
     sic\say 
     sic\say "Short Spacings"
     sic\let addshort 'addshort' /prompt "Add short spacings ?"
     sic\let sd_weight 'sd_weight' /prompt "Single dish weight" 
  !
  gui\button "@ alma_deconv" -
     DECONVOLUTION "Do the deconvolution" gag_log:alma_deconv.hlp "Parameters"
     sic\let process 'process' /prompt "Which array to process?" -
             /index ALMA ACA BOTH
     sic\let diter 'diter' /prompt "Number of CLEAN components"
  !
  gui\button "@ alma_compare" -
     COMPARE "Compare images" gag_log:alma_compare.hlp " "
  !
  gui\button "@ alma_display" DISPLAY "Display results" gag_log:display.hlp "Parameters"
     sic\let display_mode 'display_mode' /prompt "What to plot ?" -
             /index "Field positions" "SD map" "UV weights" "Beam" -
                    "Flux convergence" "Image comparison" "UV comparison" -
                    "Results 1" "Results 2"
     sic\say
     sic\let do_bit 'do_bit' /prompt "Show bitmap images ?" 
     sic\let do_contour 'do_contour' /prompt "Draw contours ?" 
     sic\let do_grey 'do_grey' /prompt "Fill contours ?" 
     sic\let do_nice yes
     sic\let size[1] 'size[1]' /prompt "Display size (arcsec)"
     sic\let uv_limit 'uv_limit' /prompt "UV Range"
     sic\say
     sic\let alma_print 'alma_print' /prompt "Print results?"
     sic\let pkind 'pkind' /prompt "PS device" -
             /index 'pname[1]' 'pname[2]' 'pname[3]' 
     sic\let okind 'okind' /prompt "Output mode" -
             /index 'oname[1]' 'oname[2]' 
     sic\say
  !
  on error return
  gui\go "@ alma_pipeline_mode"
  !
end procedure alma_expert_mode
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! Choose the kind of user interface
!
if (alma_pipeline) then
   @ alma_pipeline_mode
endif
!
! Will not redefine everything next time `alma.map' is called
!
let alma_init yes
!
!-------------------------------------------------------------------------
!
! Help files
!
!-------------------------------------------------------------------------
!
begin data gag_log:pipeline_mode.hlp

1 ALMA

           ALMA+ACA simulation package (Version 1.0)

Questions, comments, problems ? Please email to: gildas@iram.fr

***************************************************************************
1 IMPORTANT REMARK

The simulator is fully working in its default behavior. However, input
files are needed when adding pointing errors and/or atmospheric phase
noise.  Those input files are not included in the default distribution
because they are large (Tens of MB, i.e. ten times the size of the GILDAS
distribution). To get those, please contact gildas@iram.fr.

***************************************************************************
1 CONTEXT

ALMA is the Atacama Large Millimeter Array. In its baseline, ALMA is made
of 64 12m-antennas with submillimeter surface accuracy. 
ALMA configurations go from a compact one (150m) to an extended one 
(12km).

To enhance the wide field capabilities of ALMA, it is proposed to add an
interferometer of small antennas (typically 12 7m-antennas). This array is
named ACA, which stands for ALMA Compact Array.

***************************************************************************
1 PERFORMANCES

The simulator typically needs 20 minutes to finish a "normal" simulation
run on a AMD Athlon 800 MHz processor with 756MB of RAM. A few simulations
quickly fill hundreds of MB of hard disk.

***************************************************************************
1 GLOBAL_BEHAVIOR

From an input image, this package should be able to:
  - modelize single dish observations,
  - modelize ALMA and/or ACA interferometric observations,
  - merge single dish and interferometric observations,
  - deconvolve the observations,
  - compare simulated result with input image,
  - display the comparison.

Right now, only continuum observations can be simulated.
Multi-configuration is not yet implemented (*** it will need a partially
new interface to take correctly take care of the different
configurations). Note also that the ACA and ALMA arrays are simulated
independently, which implies that the hybrid correlations are not computed
and thus not considered by the imaging procedure.

The default mode is a pipeline. In this mode, user has just to set all the
input parameters and to push the COMPUTE button to obtain the result. The
default values for the input parameters are sensible ones. When the default
value of a given parameter is 0, it means that the simulator will replace
it by a sensible value at run time.

***************************************************************************
1 DETAILED_BEHAVIOR

4 Buttons are available:
    LOAD    To load the results of a previously computed simulation;
    COMPUTE To compute all the needed steps to obtain the results and 
            to plot one of them;
    DISPLAY To display different results of the current simulation;
    EXPERT  To go to an expert mode. Mostly for test purpose at IRAM.

2 MODEL
    Path of the input image file. User can browse his directory tree and 
    choose this file by pushing the FILE button.
2 OUTPUT_DIR
    Name of the directory where all the output files of the simulation will
    be stored.
2 KIND
    Simulation kind. Allows differents combination between ALMA 
    observations, ACA observations and Single Dish observations. Push the 
    CHOICES button to select it.

For information about the others button, push the corresponding HELP 
buttons (on the same line). 

***************************************************************************
1 CURIOUS_S_CORNER

 This section details the global behavior of the pipeline mode, i.e. the 
 actions undertaken when you push the COMPUTE or the LOAD button.

 Global behavior of the COMPUTE button:
    Depending on the simulation kind and on all the others input parameter
    values defined in the widget, the simulator will in turn call the
    following procedure (whose description can be found by pushing the 
    EXPERT button): 
       - "alma_setup":       Prepare the input image (sky model) 
                             (See the PREPARE help).
       - "alma_single_dish": Simulate single dish OTF observations 
                             (See the SINGLE DISH help).
       - "alma_interfero":   Simulate interferometric observations
                             (See the ALMA ARRAY help).
       - "alma_uvmap":       Make dirty maps from UV tables
                             (See the UV->MAP help).
       - "alma_deconv":      Deconvolve dirty maps
                             (See the DECONVOLUTION help).
       - "alma_compare":     Compare output image (cleaned map) with input 
                             image (See the COMPARE help).
       - "alma_display":     display and/or print different results
                             (See the DISPLAY help).

 Detailed behavior of the COMPUTE button:
    1 There are global variables (1 by procedure: do_setup, do_sd, 
      do_alma, do_aca, do_uvmap, do_decon, do_compa) that are set to yes
      when:
          a you enter a completely new simulation 
            (in the initialization section above);
          b one of the associated input paramaters has changed since 
            last time (this is done in this procedure). 
    2 There are local variables (search_sd, search_alma, search_aca) 
      that are set to yes according to the simulation kind.
    3 The computation of the procedure is done when both variables are 
      set to yes (i.e. "alma_single_dish" is done only when "do_sd" and
      "search_sd" are set to yes).
    4 The global variables and the simulation kind are saved after each
      procedure in "parameters.map" via "alma_save".
    5 At the beginning of each procedure the global variable "done" is 
      set to no. "done" is set to yes only at the end of "alma_compare"
      when the simulation has gone to its end.
    6 On error, return to the base.
 This way:
    A The simulation always know in which states it has been left: 
          a do we begin a brand new set of simulation (initialization)?
          b did the last simulation go to its end?
          c if not, where did it stop?
    B When the user push the "compute" button, only the useful 
      computational steps are made.
    C On error, the only end-user answer can be to change the input 
      parameters: so go back to widget base.

 Detailed behavior of the LOAD button:
    1 The "parameters.map" file always reflects the last state of the
       simulation. In this file, you both have the new and old variables
       used in the "alma_compute" procedure.
       There are 2 cases:
          a You begin a brand new state of the simulation: then there is
            no "parameters.map" file in the current directory. This 
            file will be created at each stage of the simulations you 
            will compute. 
          b You called "alma.map" in a directory where a 
            "parameters.map" file exists. It will be loaded at 
            initialization time to reflect what is inside all the 
            modelization files (eg *.uvt) of the current output directory.
    2 When a kind of simulation has been finished, only the new 
      parameters are saved in the "kname[kind]-pars.map" file. This 
      file will reflects the result files (the one used for plotting).
    3 When "kname[kind]-pars.map" exists, the procedure verifies that
      it knows the simulation state (i.e. the "parameters.map" file
      exists). If yes, it plots the results.
    4 Starts with a directory change because the user knows that 
      simulations have been done in directory "output_dir" and wants to 
      go there to load the simulation results. 
 This way:
    A The simulation always knows what was the last modelization state
      via the old variables in the "parameters.map" file.
    B The user can load simulation results made with a different 
      modelization state without creating a mess because the 
      "kname[kind]-pars.map" change only the current (not the old)
      variables. When the user will push the "compute" button after 
      loading another simulation results, the comparison between new and
      old variables will do a correct job.

***************************************************************************

end data gag_log:pipeline_mode.hlp
!
!-------------------------------------------------------------------------
!
begin data gag_log:observations.hlp

1 OBSERVING_SETUP

    This parameter section describes the observer s knowledge about the
    source: its size, its declination, the observing frequency where signal
    is expected, the observing time needed to achieve a given noise level.

    To help you choose the right observing time, you can push the SHOW
    NOISE button, which shows the approximate expected noise levels for
    ALMA/ACA/SD observations. Those noise levels obviously depend on the
    configuration setup and the observing conditions!
    *** not yet done.

***************************************************************************

2 CHANGE_DEC
    Logical flag to decide whether to change input image declination.
2 DEC
    New declination of source (only used when CHANGE_DEC = YES).
2 CHANGE_SIZE
    Logical flag to decide whether to change input image size at constant
    field of view.
2 IMAGE_SIZE[2]
    New image size (only used when CHANGE_SIZE = YES).
2 MOS_SIZE[2]
    2 element array which defines a rectangular space inside which the 
    mosaic will be defined. This allows to easily adapt the mosaic size to
    the image pattern.
2 CLOSEST
    Logical flag to decide if the mosaic pattern is restricted to the 
    closest neighbourgs (circular shape). Else the mosaic pattern will fill
    the rectangular space defined with MOS_SIZE.
2 SD_PPD
    OTF sampling rate defined as the number of pointings per beam in each
    direction (RA and DEC).
2 SD_GPOS
    OTF grid position. Can be:
       - CENTERED on the input image;
       - GOING through the reference pixel.
    *** Too specialized. Should exist only in expert mode.
2 FREQ
    Observing frequency (GHz)
2 DFREQ
    Bandwidth (MHz)
2 HOUR[2,2]
    Hour angle ranges (in decimal hour) for ALMA and ACA observations (eg,
    -0.15 0.15 for an half hour snapshot with ALMA).  Right now both of
    this is to the user to ensure that the observing time does not exceed 8
    hours (maximum transit time). *** should be changed.
2 SD_TIME
    Total (on+off) integration time (in decimal hour) for single dish OTF
    observations.

***************************************************************************

end data gag_log:observations.hlp
!
!-------------------------------------------------------------------------
!
begin data gag_log:configurations.hlp

1 CONFIGURATION_SETUP

    This parameter section defines the instrument configuration in the
    observing session. Default ALMA/ACA configurations are available.
    *** we should propose a choice of default configurations. 
    
    To help you choose the right configuration, you can push the 
    SHOW CONFIG button which shows the current configuration and the
    approximate associated angular resolution.
    *** not yet done.

    If you want to define your own configuration, please see the "CURIOUS'S
    CORNER".

***************************************************************************

2 DIAMETER[2]
    Antenna diameters of ALMA and ACA (m). Obviously ALMA diameter should
    be greater than ACA diameter.
2 ARRAY[2]
    Array names of ALMA and ACA. This defines the kind of array concept, 
    i.e. "donut" or "zoom".
2 CONFIG[2]
    Configuration names of ALMA and ACA. This defines the dimension of the 
    configuration, i.e. "e" corresponds to the compact configuration
    (150m-wide).
2 SD_DIAM
    Diameter of antenna used for single dish observations. It should be
    greater than the ALMA diameter.
2 SD_NANT
    Number of antenna used for single dish observations.
    
***************************************************************************
1 CURIOUS_S_CORNER

  The ARRAY and CONFIG variables are used to define the input configuration
  file.
  This file must exist in the directory dedicated to the configuration (see
  FILE LOCATION help) and its name must be build as:
               ARRAY[i]-CONFIG[i].cfg
  
  This file must be an ASCII table of 7 columns by number-of-antennas
  lines. Its format must be:
       Antenna number, Lx, Ly, Lz, diameter, X, Y,
  where:
       - Lx, Ly, Lz are the local 3D coordinates;
       - X, Y are the projected coordinates in the locally tangent plane.

***************************************************************************

end data gag_log:configurations.hlp
!
!-------------------------------------------------------------------------
!
begin data gag_log:obs_conditions.hlp

1 OBSERVING_CONDITION_SETUP

    This parameter section defines the observing conditions. It is divided 
    in 2 subsections:
       - setup of the pointing errors;
       - setup of the noise behavior.

    You can either very simple pointing error models or a quiet elaborate
    one using the "pointing_error.graphic" tool designed to work with this 
    package (See *** help). If you want to design, your own pointing error
    model, please see the "CURIOUS'S CORNER" to know the file format needed
    to input your model in the simulator. 

    To help you define the atmospheric conditions, you can push the 
    SHOW ATM button, which displays the atmospheric opacity as a function
    of the frequency for the Atacama site.
    *** not yet done.
    
***************************************************************************

2 PE_CODE[2]
    
2 POINTERR[2,2]
    
2 INT_PE[2]
    
2 SD_PE_CODE
    
2 SD_POINTERR[2]
    
2 SD_PE
    
***************************************************************************

2 TREC[2]
    ALMA/ACA receiver temperature.
2 TAU[2]
    ALMA/ACA zenith opacity.
2 SD_TSYS
    Single Dish system temperature.
2 ADDNOISE[2]
    Logical flag to decide whether to add thermal noise to ALMA/ACA
    observations. When this flag is set to YES, the noise RMS is chosen
    accordingly to TREC and TAU values.
2 SD_ADDNOISE
    Logical flag to decide whether to add thermal noise to single dish
    observations. When this flag is set to YES, the noise RMS is chosen
    accordingly to SD_TSYS value.
2 SD_ADDCALERR
    Logical flag to decide whether to add multiplicative noise (due to 
    calibration errors) to single dish observations.
2 PHASE_RMS[2]
    ALMA/ACA phase noise (in degree).
2 SD_MCAL
    Single dish calibration mean. Its value should be close to 1 but 
    can be different from 1 because of a calibration systematic error. 
    (Used only when SD_ADDCALERR = YES).
2 SD_SCAL
    Single dish calibration rms. Its value should be close to 0.0 but 
    can be different from 0 because of calibration random errors.
    (Used only when SD_ADDCALERR = YES).

***************************************************************************
1 CURIOUS_S_CORNER



***************************************************************************

end data gag_log:obs_conditions.hlp
!
!-------------------------------------------------------------------------
!
begin data gag_log:deconvolution.hlp

1 DECONVOLUTION_SETUP

    This parameter section defines the mapping and deconvolution 
    parameters. It is divided in 3 subsections:
       - setup ***;
       - setup of parameters used in every deconvolutions;
       - setup of parameters used only in ALMA/ACA joint deconvolutions.

***************************************************************************

2 SD_WEIGHT
    
2 TRUNCATE
    
2 BEAM_SCALE
    Those parameters are for specialists. It should be left to its default
    value (1) in a first approach.

***************************************************************************

2 DITER
    Number of CLEAN components.
2 GAIN
    CLEAN gain.
***************************************************************************

2 C_GAIN
    CLEAN gain used by the 
2 F_THRES
    
2 SMOOTH
    
***************************************************************************

end data gag_log:deconvolution.hlp
!
!-------------------------------------------------------------------------
!
begin data gag_log:display.hlp

1 PLOTTING_AND_PRINTING_SETUP

    This section defines the plotting and printing behavior of the 
    simulation.

    The following variables are not saved from between sessions.
    
***************************************************************************

2 DISPLAY_MODE
    Variable which selects the result to be plotted. Its value can be:
    
       1 "Field positions"
	 ALMA mosaic pattern overlaid on input image 
	 (with new size and new declination, if asked);

       2 "SD map"
	 Map resulting of single dish OTF observation.
	 The ALMA mosaic pattern is overlaid. 

       3 "UV weights"	     

       4 "Beam"
	 Image of dirty beam and antenna configuration; 
	 Number of baselines and density of weights as a 
	 function of spacial frequency (in m).

       5 "Flux convergence" 
	 Cumulative flux found as a function of the CLEAN component 
	 number during the deconvolution process.

       6 "Image comparison"
         Results are shown in the image plane:
           - The 2 top images show the model (right) and the simulated
             observation (left), both smoothed at the same resolution.
           - The 2 bottom images show complementary information: the 
	     difference (model-simulation, at left) and the fidelity
             (model/(model-simulation), at right).
           - To quantify the visual impression, several numbers are
             provided: integrated fluxes (and their percentage as compared
             to the model); rms of the difference image; fidelity range.
	   - Finally the histogram of cumulative fidelity is shown with
             median fidelities computed for the image pixels whose
             intensity is at least 0.3/1/3.3/10\% of the maximum value.

        7 "UV comparison"
	  Results are shown in the Fourier plane:
	    - The top left corner show the FFT of the model. 
	    - The bottom left corner the FFT of the difference
              (model-simulation).
            - The bottom right corner is the ratio of the 2 previous FFTs:
              this is an image of the fidelity of the observation in the uv
              plane.
            - Finally, the top right panel is a zoom of the uv fidelity. 
      	  The large circle enclose the region where visibilities were
          measured (its radius is the size of the ALMA configuration). The
          small 12m circle enclose the area where ALMA can a priori make
          only indirect visibility measurement (via mosaicing).

	8 "Results 1"
	  "Field positions" and "SD map" are displayed at the same time.

	9 "Results 2"
	  "Beam", "Flux convergence", "Image comparison" and "UV
	  comparison" are displayed at the same time.

***************************************************************************

2 DO_BIT
    Logical flag to decide whether to display the bitmap images.
2 DO_CONTOUR
    Logical flag to decide whether to draw contours.
2 DO_GREY
    Logical flag to decide whether to fill contours with grey shades.
2 SIZE
    Size (in arcsec) of the displayed area.
2 UV_LIMIT
    Maximum spatial frequency to be used for:
      - The beam plotting;
      - The zoom of the fidelity image in the UV comparison.

***************************************************************************

2 ALMA_PRINT
    Logical flag to decide whether to print the result defined by the 
    DISPLAY_MODE variable.
2 PKIND
    Kind of PS format:
      - FAST fast B&W but ***?
      - GREY;
      - COLOR.
2 OKIND
    Output support:
      - PS FILE in the "ps" subdirectory of the output directory;
      - DEFAULT PRINTER. To make this option work, the user must set the 
        GILDAS ?***? variable to his default printer in the MAPPING init
        file.
        *** Never checked whether it worked.
    
***************************************************************************

end data gag_log:display.hlp
!
!-------------------------------------------------------------------------
!
begin data gag_log:location.hlp

1 FILE_LOCATION_SETUP

  Define the directory tree where all the input files needed by the
  simulation can be found.

***************************************************************************

2 IMAGE_DIR
    Name of the directory where input image files are located.
2 CONFIG_DIR
    Name of the directory where ALMA and ACA configuration files are
    located.
2 PNTERR_DIR
    Name of the directory where the pointing error tables produced by
    the "point_error.graphic" package are located.

***************************************************************************

end data gag_log:location.hlp
!
!-------------------------------------------------------------------------
!
begin data gag_log:expert_mode.hlp

1 EXPERT_MODE

 This mode is for test purpose at IRAM. It does not completely keep track
 of the simulation state. So, as it is not as well protected as the
 pipeline mode, it will crash much more often.

 In this mode, most of the help will tell you how the simulator work. Only
 the variable which does not appear in the pipeline mode will be described
 here. For all the other ones, please see the pipeline help.

 To go back to the pipeline mode, push the GO button.

 Have fun.

***************************************************************************

end data gag_log:expert_mode.hlp
!
!-------------------------------------------------------------------------
!
begin data gag_log:alma_load.hlp

1 LOAD

 Please see the "CURIOUS'S CORNER" of the general help of the pipeline mode
 for details.

***************************************************************************

end data gag_log:alma_load.hlp
!
!-------------------------------------------------------------------------
!
begin data gag_log:alma_setup.hlp

1 PREPARE

 The called procedure reads the model image, which features the sky
 brightness distribution, and defines several critical parameters (***
 which ones?). Depending on the source and primary beam size, the simulator
 will switch between single field and mosaic modes, and automatically
 compute the field(s) position(s).

***************************************************************************
1 CURIOUS_S_CORNER

 1 Computational principles

     The original model is first plunged into an image whose size in pixel is
     a power of two. The header is then edited to modify the pixel size so
     that the angular size of the image corresponds to that required by the
     user; the declination of the source can also be modified.

     *** the reference pixel should also be changed: not yet done.

     Depending on the image and ALMA primary beam size, the simulator
     switches between the single-field and mosaic modes. In the latter case,
     the number and positions of the fields are automatically computed
     following an hexagonal pattern, sampled at half the primary beam width.

     *** Oversampling should be easy to implement: not yet done.

 2 Technical details

     Procedure name: alma_setup.

     Input:

     Output:

     Called procedures and tasks:

        alma_change_outdir to change output directory if needed;
        alma_prepare       to change reference pixel and to plunge into an 
                           image of dimension 2^N;
        alma_position      to compute field positions of the mosaic pattern;
        alma_plot_fields   to plot field position.

***************************************************************************

end data gag_log:alma_setup.hlp
!
!-------------------------------------------------------------------------
!
begin data gag_log:alma_single_dish.hlp

1 SINGLE_DISH

 The called procedure simulates single-dish observations of the source, to
 be used for short spacings computation. Calibration and thermal noise can
 be added. Input parameters: antenna diameter, sampling criteria, pointing
 errors model, weighting parameters (e.g. Tsys). Note that the system
 temperature is automatically computed from the frequency, but can be
 modified by the user.

 *** Should be modified to take as input Trec and tau.

***************************************************************************
1 CURIOUS_S_CORNER

 1 Computational principles

     This task simulates on-the-fly observations performed with single-dish
     antennas, to be used later on as short spacings information. The model
     image is convolved by the antenna lobe (via Fourier Transform) and the
     intensity is then estimated at (i) the position of the mosaic fields, and
     (ii) on an extended grid -- with typically 3 pixels per beam. If the
     required position does not coincide with a pixel center, a bilinear
     interpolation from the neighbor pixels is performed.

     Pointing errors can be simulated by estimating the intensity at a slightly
     wrong position. The same kind of pointing error models as for the
     interferometric observations (see below) are used.

     Thermal noise can then be added to the data, and the corresponding weight
     is stored. Finally, a calibration noise can be simulated: the observed
     intensities are multiplied by a random factor whose mean value (different
     form 1 if a systematic error is present) and rms can be specified.

 2 Technical details

     Procedure name: alma_single_dish.

     Input:

     Output:

     Called procedures and tasks:

        alma_smooth_pe   to adapt by smoothing the pointing error table 
                         integration time (when SD_PE_CODE = 5);
        IMAGE_SAMPLING   to define the OTF sampling positions;
        SHORT_MODEL      to compute the corresponding single dish observations.
        alma_plot_sd     to plot result of single dish observations.

***************************************************************************

end data gag_log:alma_single_dish.hlp
!
!-------------------------------------------------------------------------
!
begin data gag_log:alma_interfero.hlp

1 ALMA/ACA_ARRAY

 The called procedure simulates observations with the ALMA array,
 including pointing errors, phase noise, and thermal noise. Input
 parameters: configuration to be used, hour angle range, pointing error
 model, weighting parameters.

***************************************************************************
1 CURIOUS_S_CORNER

 1 Computational principles

     The simulations of the ALMA and ACA observations are actually done using
     the same procedure. The uv coverage is derived from the antenna locations
     (read from an input ascii file), the source declination, and the hour
     angle range of the observations. The integration time corresponding to a
     Nyquist sampling is used if it does not exceed 300 seconds.

     For a mosaic, the procedure assumes that the fields are observed in a loop
     (i.e. in a snapshot mode), each visibility dump corresponding to another
     position in the sky. The total integration time is truncated so that an
     integer number of cycles is observed.

     Visibilities computation

       In the absence of errors, the result of the simulation depends on the
       accuracy of the simulation process, and on the quality of the imaging
       methods. Calibration errors (phase and amplitude, but mostly pointing
       errors) greatly influence the image quality and are often the major
       limiting factor. These are inherently statistical errors, thus requiring
       several simulations to provide a representative sample of
       problems. Hence, computational speed becomes an issue. We have thus
       chosen a fast, but approximate, method to simulate the visibilities from
       an input model image and a required uv coverage.

       For a single field, the observed visibility is the Fourier Transform of
       the sky brightness distribution multiplied by the primary beam of the
       antenna, i.e. the convolution of the Fourier Transform of the sky
       brightness by the Fourier Transform of the antenna primary beam. For
       rapidly varying pointing errors, this quantity has to be computed for
       each visibility dump. To fasten this process, we use a "gridded
       convolution": the visibilities are estimated by the convolution of the
       FFTs, i.e. of two already-gridded distributions. Furthermore, the
       convolution is approximated by a weighted sum using only the neighbor
       points: this is a local operation in the uv plane, to be performed at
       each required uv position.

       Using images of 4096*4096 pixels, we obtain a precision of the order of
       0.3%. This limits the fidelity of the final image to 300:1, but this is
       acceptable since pointing errors contribute more significantly. Note
       also that a 1% calibration error would limit the image fidelity to
       100:1... *** Is it really true ???

       For a mosaic, the same algorithm is used, the field offset being added
       to the pointing error. The resulting uv table is then sorted to get one
       table per field.

     Pointing errors models

       The task simulating the visibilities can generate random uncorrelated
       pointing errors but it can also read an input pointing error table. This
       allows to run more sophisticated pointing error models to produce such a
       table. The model we developed takes into account different timescales
       and amplitudes for the pointing errors due to the following effects:
	 - errors of measurement at each pointing calibration (e.g. every 30
	   minutes)
	 - tracking uncertainty (timescale: 1 sec);
	 - bearing error (timescale: a few minutes);
	 - antenna structure change due to temperature variation 
	   (timescale: 1 hour);
	 - wind (timescale: 1 sec).
       The wind and thermal errors are assumed to be correlated among antennas
       (the correlation factor can be adjusted).

     Noise

       Adding thermal and phase noise to the simulated uv table(s) is an easy
       task. The thermal noise is derived from Tsys -- taking into account the
       variation with elevation --, the integration time, and the
       bandwidth. The corresponding weight is also stored, to be used in the
       imaging process. As of today, our simulator only includes a constant
       phase noise, independent of the baseline length. Another limitation is
       the lack of any calibration error.

 2 Technical details

     Procedure name: alma_interfero with a mandatory argument
                       (1 for ALMA, 2 for ACA).

     Input:

     Output:

     Called procedures and tasks:

        alma_plot_fields

        alma_single (when MOSAIC = NO)
           
            PRIMARY        to apply primary beam on model image;
            UV_TRACK       to compute the UV coverage;
            UV_FMODEL      to compute the corresponding visibilities;
            UV_POINTING    to compute the corresponding visibilities taking 
                           into account pointing errors;
            alma_addnoise  to add phase noise.

        alma_mosaic (when MOSAIC = YES)

            UV_TRACK       to compute the UV coverage;
            UV_POINTING    to compute the corresponding visibilities taking 
                           into account pointing errors;
            alma_addnoise  to add phase noise.

***************************************************************************

end data gag_log:alma_interfero.hlp
!
!-------------------------------------------------------------------------
!
begin data gag_log:alma_uvmap.hlp

1 UV->MAP

  The called procedure computes the maps from the observations simulated in
  the previous steps. It can process the ALMA array and/or the ACA
  array. The user can also choose to add the short spacings informations to
  the data: in that case, pseudo-visibilities are computed from the
  single-dish observations, and added to the interferometric uv table(s)
  before Fourier Transform.

***************************************************************************
1 CURIOUS_S_CORNER

 1 Computational principles

     The ALMA and/or ACA simulated uv tables are Fourier transformed using
     classical gridding and FFT algorithms. The size and number of pixels are
     automatically computed (*** how ???). Natural weighting is used by
     default. For a mosaic, this process is done for each field.

     Short spacings

       If the short spacings information is to be used, it is added to the uv
       table before imaging. The following method is used (assuming here that
       the single-dish antennas have a 12-m diameter):

	 - If only the ALMA array is processed, only the zero spacing (the
	   total flux) can be added to the interferometric data. In that case,
	   the flux measured by the 12-m antennas at each pointing position is
	   written into the ALMA uv table.

	 - If the ACA array is processed (together with ALMA or not), then
	   short spacings can be estimated:
	     * The on-the-fly single-dish measurements are re-gridded,
	       extrapolated and apodized to zero (The last 2 operations to
	       avoid aliasing in the subsequent convolutions). The result is
	       then Fourier transformed in the uv domain.
	     * The data are corrected for the single-dish lobe by division by
	       its Fourier Transform (truncated to the antenna diameter).
	     * The data are Fourier transformed back to the image plane and
	       the ACA primary lobe is applied (multiplication).
	     * The visibilities are then estimated on a regular grid after yet
	       another Fourier Transform.
	     * In the case of a mosaic, the two last operations are performed
	       for each pointing center.
	   Note that applying the ACA primary beam is a convolution in the uv
	   plane, i.e. a local average. It can therefore be estimated only in
	   the central region, up to an uv radius equal to the difference of
	   the two antenna diameters.

       In both cases, a relative weighting factor between the single-dish
       and interferometric data can be applied.

 2 Technical details

     Procedure name: alma_uvmap.

     Input:

     Output:

     Called procedures and tasks:

        alma_add_short

            UV_CIRCLE    to define ALMA of ACA weight density in the inner 
                         ring of the uv plane (this will be compared to the 
                         SD weight density);
            UV_SHORT     to compute visibilities from the single dish map 
                         (when SD_DIAM > min(DIAMETER));
            UV_MERGE     to merge previously computed uv table to ALMA or 
                         ACA one;
            UV_ZERO      to merge zero spacing visibility from SD 
                         observations to the interferometric uv table
                         (when SD_DIAM = min(DIAMETER)).

        alma_sampling

            UV_CIRCLE    to ***???

        alma_dirty_maps

            go uvmap     to make dirty maps and synthesized beams form uv tables;
            MAKE_MOSAIC  to mosaic individual dirty maps (when MOSAIC = YES).


***************************************************************************

end data gag_log:alma_uvmap.hlp
!
!-------------------------------------------------------------------------
!
begin data gag_log:alma_deconv.hlp

1 DECONVOLUTION

 The called procedure makes the deconvolution of the image computed at the
 previous step, using the CLEAN algorithm (or one of its variant).  It can
 process an heterogeneous array (ALMA+ACA), using a CLEAN-based multi-scale
 algorithm.
    
***************************************************************************
1 CURIOUS_S_CORNER

 1 Computational principles

     The deconvolution algorithms are based on CLEAN. The default is to use the
     Clark method, but other variants (Hogbom, Steer-Dewdney-Ito,
     multi-resolution) are available within the MAPPING software.


     Mosaic deconvolution

       The mosaic deconvolution is done using a CLEAN-based method developed
       for the IRAM Plateau de Bure interferometer (see e.g. the chapter on
       mosaicing in the proceedings of IRAM millimeter interferometry summer
       school). In short: the dirty mosaic is reconstructed as a linear
       combination of all dirty maps,

	   J = sum_i{ (B_i/sig_i^2)*F_i } / sum_i{ (B_i^2/sig_i^2) }

       where F_i and B_i are the dirty map and the primary beam of each
       field, respectively. The mosaic is therefore homogeneous to the sky
       brightness distribution, but the noise level is not uniform and strongly
       increases at the edges of the field of view. As a consequence, using the
       classical CLEAN method can be dangerous, as noise peaks might be
       selected as CLEAN components. The method used for Plateau de Bure data
       consists in selecting the CLEAN components on a modified mosaic: the
       initial mosaic is normalized by the noise level distribution. Hence,
       this distribution is homogeneous to the signal-to-noise ratio.

       The algorithm turns out to give excellent results, both in terms of
       image fidelity and convergence speed. It has been used during the last
       years to deconvolve the mosaics observed with the Plateau de Bure
       interferometer.

     Deconvolving an heterogeneous array

       We developed a CLEAN-based method allowing to deconvolve interferometric
       data observed with an heterogeneous array such as ALMA+ACA. The
       algorithm takes as input the two dirty maps, and uses a multi-scale
       approach: at each iteration, the CLEAN components are found on one or
       the other map, depending on which has the highest signal-to-noise
       ratio. Note that the hybrid correlations are not taken into account in
       such a method.

       Starting from two uv tables corresponding to the observations of the
       same source with two arrays, the following operations are performed:

	 - Fourier Transform of the data, and reconstruction of the two
	   mosaics. The mosaic field positions do not need to coincide in the
	   observations performed by the two arrays (although this is the case
	   with the current version of our simulation package).

	 - Major cycles are performed, in which CLEAN components are identified
	   in the residual image with the highest signal-to-noise ratio. A very
	   satisfactory method (in terms of image quality and convergence
	   speed) is to use the Clark method if the components are to be found
	   on the ALMA image, and the Steer-Dewdney-Ito approach if they are to
	   be found on the ACA image.

	   *** we should comments on the fact that we use only one "components"
	       for the SDI approach up to the point where the cumulative flux
	       is a percentage of something...

	 - The components found in each major cycle are removed from both maps.
	   If they were identified on the ALMA image, a compression allows to
	   re-sample them on the ACA grid. However, the components found on the
	   ACA image need a more careful processing, in order to make sure that
	   the same quantity is removed from both images (otherwise the method
	   would diverge): we first derive from each ACA component a set of
	   positions on the ALMA grid, such that they cover exactly the area of
	   pixel of the ACA grid; these components are then removed from the
	   ALMA map; they are also compressed -- via Fourier Transform -- back
	   to the ACA grid, to be removed from the ACA image. This
	   back-and-forth method allows us to get rid of the uncertainties that
	   would occur if the ACA components would have been directly
	   interpolated on the ALMA grid.

	 - Finally, the CLEAN components identified by the methods are
	   convolved by the ALMA clean beam (highest angular resolution), and
	   the weighted residuals are added.

       *** Smoothing kernel ???

 2 Technical details

     Procedure name: alma_deconv.

     Input:

     Output:

     Called procedures and tasks:


***************************************************************************

end data gag_log:alma_deconv.hlp
!
!-------------------------------------------------------------------------
!
begin data gag_log:alma_compare.hlp

1 COMPARE

 The called procedure performs the comparison between the model image and
 the result of the simulation. The comparison is done by resampling the
 original model on the grid of the simulated image, and by convolving it
 with the clean beam. The difference and the fidelity image can thus be
 easily computed. Image indicators such as the recovered flux or the
 fidelity range are also derived.
    
***************************************************************************
1 CURIOUS_S_CORNER

 1 Computational principles

     The comparison between the simulated and original image is done by
     resampling the original model on the grid of the simulated map, and by
     convolving it with the clean beam. Hence, the two images are directly
     comparable, and registration or scaling problems are avoided.

     Estimating the quality of the simulated image as compared to the original
     model is not an easy task: the actual criteria to estimate the observation
     quality depends on the science that is to be done!

     Fidelity

       The COMPARE procedure computes the so-called fidelity of the
       simulation. It is defined as the ratio of the input model by the
       difference (model-simulated image). The higher the fidelity, the
       better the simulated image. In practice, the very high fidelity points
       due to value coincidence between the model and simulation have to be
       flagged out, because they do not reflect the accuracy of the
       simulation. For that purpose, the lowest values of the difference image
       are truncated, and the fidelity image is thus computed as: 

	 fidelity = input_model / max(difference, 0.7*RMS(difference)).

       A cumulated histogram of the fidelity values (i.e. the number of pixels
       whose values are larger than a given fidelity) is also computed. Finally
       it computes the median fidelities, taking into account only the pixels
       whose intensity in the initial model image is higher than 0.3, 1, 3 or
       10% of the peak.

     Fidelity range

       Having one single number to quantify the accuracy of the simulated image
       is very convenient when doing a large number of simulations: this allows
       a global estimate of the effect of one of the parameters (e.g. pointing
       errors) on the simulation results. We used the "fidelity range"
       defined by L. Kogan:

	 fidelity_range = abs( max(model) / RMS(difference)).

 2 Technical details

     Procedure name: alma_compare.

     Input:

     Output:

     Called procedures and tasks:

        GAUSS_SMOOTH    to smooth model to simulated image resolution;
        MAP_COMPRESS    to adapt model size to simulated image one;
        EXTRACT         to plunge model image into simulated image grid *** or vice-versa;
        HISTO_SIMPLE    to compute histogram of fidelity image;
        UV_FIDELITY     to compute difference and fidelity images in uv plane.

***************************************************************************

end data gag_log:alma_compare.hlp
!
!------------------------ Simulation 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:
