if (exist(self_mode)) return
!
define character*12 self_mode /global
define real self_times[3] self_minflux[3] self_snr /global
define integer self_loop self_iter self_niter[3] self_refant self_channel[2] /global
define real self_flux self_snoise /global
define logical self_restore self_display self_flag /global
define charact*64 self_string self_sname /global
define real self_trange[2] self_prange[2] self_arange[2] self_precision self_threshold /global
define integer self_status self_applied /global
define real self_color /global
define logical self_hard /global
!
let self_mode PHASE   ! Mode
let self_channel 0 0  ! Channel range
let self_times  45    ! Integration time
let self_minflux 0    ! Min flux of Clean components to retain
let self_snr 3        ! Min SNR for valid solution
let self_niter 0 ! Automatic guess
let self_flux 0       ! Displayed flux in Clean
let self_loop 3       ! Number of loops
let self_loop /status Read ! Make it Read-Only
let self_restore yes  ! Use UV_RESTORE ?
let self_display yes  ! Display solution
let self_flag yes     ! Flag or Keep uncalibrated data ?
let self_snoise 1.0   ! Noise scaling factor (test)
!
let self_sname test   ! Solution name
let self_hard NO      ! Hardcopy via @ sub-self-show
!
let self_trange 0     ! Time range
let self_prange 0     ! Phase range
let self_arange 0     ! Amplitude range
!
let self_status 0     ! Return status (-1 bad phase, -2 bad amplitude, 0 none, 1 good phase, 2 good amplitude)
let self_applied 0    ! Calibration status: 0 not done, 1 PHASE done, 2 AMPLI done
let self_precision 0.01  ! 1 % convergence test
!
let self_color -8     ! Control Color Scale at each iteration (see HELP COLOR)
let self_threshold 0  ! Min global S/N to perform Self-Calibration
!
begin procedure selfcal_sum
  if .not.exist(self_dynamic) then
    MESSAGE W SELFCAL 'ansi%bold''ansi%blue'"No Self Calibration performed yet"'ansi%none'
    return
  endif
  !
  SAY " "
  SAY " ----   Self Calibration Summary   ----"
  SAY " Iteration     Rms     Maximum    Dynamic   Loss"
  let self_dynamic self_maxclean/self_rmsclean
  SAY 0 self_rmsclean[1] self_maxclean[1] self_dynamic[1] self_rmsclean[1]/clean%noise /format I8 1PES11.2 1PES11.2  F10.2 F10.2
  define integer mloop i1
  let mloop self_loop+1 
  FOR I 2 TO self_loop+1
    SAY i-1 self_rmsclean[i] self_maxclean[i] self_dynamic[i] self_rmsclean[i]/clean%noise /format I8 1PES11.2 1PES11.2  F10.2 F10.2
    let i1 i-1
    if (self_rmsclean[i].gt.(1.-self_precision)*self_rmsclean[i1]) then
      if (self_dynamic[i].lt.(1.+self_precision)*self_dynamic[i1]) let mloop min(mloop,i1)
    endif
  next
  let mloop mloop-1
  SAY " "
  if (mloop.eq.0) then
    MESSAGE W SELFCAL  'ansi%bold''ansi%red'"Self Calibration does not improve data quality"'ansi%none'
    let self_status -abs(self_status)
  else if (mloop.ne.self_loop) then
    MESSAGE W SELFCAL  'ansi%bold''ansi%blue'"Self Calibration saturates at "'mloop'" loops"'ansi%none'
    let self_status abs(self_status)+10*mloop
  endif
  !
  if (self_applied.gt.0) then
    if (mod(self_applied,10).eq.1) then
      MESSAGE I SELFCAL 'ansi%bold''ansi%green'"PHASE Self-calibration applied"'ansi%none'
    else 
      MESSAGE I SELFCAL 'ansi%bold''ansi%green'"AMPLITUDE Self-calibration applied"'ansi%none'
    endif
  else
    MESSAGE W SELFCAL 'ansi%bold''ansi%red'"Self-calibration not yet applied"'ansi%none'
  endif
  !
end procedure selfcal_sum
!
! Define the SELF% alias structure for backward compatibility (temporary)
if (exist(self)) dele /var self
define structure self /global
begin procedure sub_selfalias
  define alias self%&1 self_&1 /global
end procedure
begin procedure selfalias
  for i 1 to pro%narg
    @ sub_selfalias 'pro%arg[i]'
  next
end procedure
@ selfalias mode times snr minflux loop iter niter refant flux
@ selfalias restore display flag channel
!
