subroutine solve_gain(line,error)
  use gildas_def
  use gkernel_interfaces
  use classic_api  
  !---------------------------------------------------------------------
  !     CLIC
  !     Support routine for command
  !     SOLVE GAIN [SCAN]
  !     [/output /plot /Store /Reset /Offset /Closure /Search] :
  !     Not relevant here
  !     SOLVE GAIN SCAN = reduction scan by scan; otherwise average of scans.
  !---------------------------------------------------------------------
  character(len=*) :: line          !
  logical :: error                  !
  ! Global
  include 'clic_parameter.inc'
  include 'clic_clic.inc'
  include 'clic_par.inc'
  include 'clic_display.inc'
  include 'gbl_pi.inc'
  ! Local
  logical :: last
  logical :: end, scan
  integer :: i,j,ier,qlun,k,narg,iu
  complex :: mean_visi(2,mnant,mnrec)
  real :: mean_wisi(2,mnant,mnrec)
  character(len=132) :: filnam,snam,ch
  character(len=2) :: rece(4)
  !
  integer :: mvoc1, nk,saved_pol_subb,saved_do_polar,ipol,ibb,bb,isolve
  integer:: i_solve(mnbb), n_solve
  logical :: saved_each_subb, saved_all_subb,saved_bb_select,saved_if_select
  parameter (mvoc1=2)
  character(len=12) :: argum, kw, voc1(mvoc1)
  data voc1/'NOSCAN','SCAN'/
  data rece/'-1','-2','-3','-4'/
  !------------------------------------------------------------------------
  qlun = 0
  !     Code:
  save_amplitude = do_amplitude
  save_flux = do_flux
  do_amplitude = .false.
  do_flux = .false.
  do_raw = .true.
  argum = 'NOSCAN'
  last = .false.
  !
  ! Reset saved phase differences.
  do i = 1, mnant
    ph_pol_saved = 0
  enddo
  !
  call sic_ke(line,0,2,argum,narg,.false.,error)
  if (error) return
  call sic_ambigs('SOLVE GAIN',argum,kw,nk,voc1,mvoc1,error)
  if (error) return
  scan = kw.eq.'SCAN'
  !
  call check_input_file(error)
  if (error) goto 999
  call check_index(error)
  if (error) goto 999
  !
  !     Do it for both polarization
  call get_first(.true.,error)
  if (.not.scan) then
    if (sic_present(10,0)) then
      ier = sic_getlun(qlun)
      filnam = 'gain'//rece(r_nrec)
      snam = filnam
      call sic_parsef(snam,filnam,'INTER_OBS:','.obs')
      ier = sic_open (qlun,filnam(1:lenc(filnam)),'NEW',   &
        .false.)
      if (ier.ne.0) then
        call message(6,3,'SOLVE GAIN',   &
          'Cannot open INTER_OBS:gain.obs')
        call messios(6,3,'SOLVE GAIN',ier)
        goto 999
      endif
      !            WRITE(QLUN,1005) 'DEFINE LOGICAL UPH'
      if (.not.bb_select.and..not.if_select.and..not.sic_present(5,0)) then
         write (qlun,'(a)') "You should think DROIT AU BUT"
         goto 999
       endif
      call check_scan(qlun,r_scan,'Gain')
    endif
  elseif (sic_present(10,0)) then
    call message(6,2,'SOLVE_GAIN',   &
      'No gain.obs produced with SCAN argument')
  endif
  !
  ! Save status and initialize everything
  saved_bb_select = bb_select
  saved_if_select = if_select
  all_subb = .false.
  each_subb = .false.
  !
  if (.not.sic_present(5,0)) then !!!!!!!!!!!!!
    !
    ! First derive receiver rejection per "input"
    !
    do ibb = 1, r_nbb
      bb = r_mapbb(ibb)
      n_baseband = 1
      l_baseband(1) = 1
      i_baseband(1,1) = bb
      call select_bb
      call set_bb_subbands(error)
      call show_display('SUB_BANDS',.false.,error)
      do j=1,mnrec
        do i=1,mnant
          do k=1,2
            mean_visi(k,i,j) = 0.0
            mean_wisi(k,i,j) = 0.0
          enddo
        enddo
      enddo
      !
      !     Loop on current index
200   call get_first(.true.,error)
      if (error) goto 999
      end = .false.
      do while (.not.end)
        if (r_nsb.ne.2) then
          call message(6,3,'SOLVE_GAIN','Scan has only one sideband')
          error = .true.
          goto 999
        else
          if (r_lmode.eq.1) then
            call sub_gain(mnant,mean_visi(1,1,r_nrec),   &
              mean_wisi(1,1,r_nrec),bb, error)
            if (error) goto 999
            if (scan) then
              call sub_solve_gain(qlun,r_nrec,mean_visi,mean_wisi,   &
                bb,error)
            endif
          else
            call message(8,1,'SOLVE_GAIN','Observation is not correlation')
          endif
        endif
        !
        !     Next observation
        call get_next(end, error)
        if (error) goto 999
      enddo
      if (.not.scan) then
        if (new_receivers) then
          if (r_nsb.ne.2) then
            call message(6,3,'SOLVE_GAIN','Scan has only one sideband')      
            error = .true.
            goto 999
          else
            if (r_lmode.eq.1) then
              call sub_solve_gain(qlun,r_nrec,mean_visi,mean_wisi,   &
                 bb,error)
            endif
          endif
        else
          call sub_solve_gain(qlun,1,mean_visi,mean_wisi,bb,error)
          call sub_solve_gain(qlun,2,mean_visi,mean_wisi,bb,error)
        endif
      endif
    enddo
  endif
  !
  ! Then derive horizontal and vertical polarizations.
  !
  bb_select = saved_bb_select
  if_select = saved_if_select
  !
  if (r_nbb.lt.2) goto 998 ! No need to phase if single polar
  !
  if (bb_select) then
    call message (6,1,'SOLVE_GAIN','Solving phases per basebands')
    n_solve = r_nbb
    do isolve = 1, n_solve
      i_solve(isolve) = r_mapbb(isolve)
    enddo
  elseif (saved_if_select) then
    call message (6,1,'SOLVE_GAIN','Solving phases per IF')
    n_solve = r_nif
  else
    call message (6,4,'SOLVE_GAIN','Select either basebands or IF')
    error = .true.
    return
  endif
  do isolve = 1, n_solve
    if (bb_select) then
      n_baseband = 1
      l_baseband(1) = 1
      i_baseband(1,1) = i_solve(isolve)
      call set_bb_subbands(error)
    elseif (if_select) then
      n_if = 1
      l_if(1) = 1
      i_if(1,1) = isolve
      call set_if_subbands(error)
    endif
    !
    do j=1,mnrec
      do i=1,mnant
        do k=1,2
          mean_visi(k,i,j) = 0.0
          mean_wisi(k,i,j) = 0.0
        enddo
      enddo
    enddo
    !
    !     Loop on current index
100 call get_first(.true.,error)
    if (error) goto 999
    end = .false.
    do while (.not.end)
      if (r_lmode.eq.1) then
        call sub_gain(mnant,mean_visi(1,1,r_nrec),   &
          mean_wisi(1,1,r_nrec),1, error)
        if (error) goto 999
        if (scan) then
          call sub_solve_pha(qlun,r_nrec,mean_visi,mean_wisi,isolve,error)
        endif
      endif
      !
      !     Next observation
      call get_next(end, error)
      if (error) goto 999
    enddo
    if (.not.scan) then
      if (r_lmode.eq.1) then
        call sub_solve_pha(qlun,r_nrec,mean_visi,mean_wisi,isolve,error)
      endif
    endif
  enddo
  !
998 do_raw = .false.
  do_amplitude = save_amplitude
  do_flux = save_flux
  !
  if (all_base) call set_all_baselines
  if (all_subb) call set_all_subbands
  if (each_subb) call set_each_subband
  if (all_base .or. all_subb .or. each_subb ) then   
    call set_display(error)
  endif 
  if (qlun.ne.0) then
    write(qlun,1005) '! '
    close(unit=qlun)
    call sic_frelun(qlun)
  endif
  return
999 error = .true.
  goto 998
  !
1005 format(a)
end subroutine solve_gain
!
subroutine sub_gain (m,mean_visi,mean_wisi,ibb,error)
  use gkernel_interfaces
  use gildas_def
  use classic_api
  use clic_rdata
  !---------------------------------------------------------------------
  ! CLIC
  !	Measure the receiver gain ratios
  !       M number of antennas
  !---------------------------------------------------------------------
  integer :: m                      !
  complex :: mean_visi(2,m)         !
  real ::    mean_wisi(2,m)         !
  integer :: ibb                   !
  logical :: error                  !
  ! Global
  include 'clic_parameter.inc'
  include 'clic_par.inc'
  include 'clic_sba.inc'
  include 'clic_clic.inc'
  include 'gbl_pi.inc'
  include 'clic_xy_code.inc'
  include 'clic_display.inc'
  include 'gbl_memory.inc'
  ! Local
  integer :: i, jw1, jw2, ix, iy, iband, ipol, kr, isb1, isb2, kb, kif
  integer(kind=address_length) :: data_in, ipk, ipkc,ipkl
  integer(kind=address_length) :: kin
  integer(kind=data_length)    :: ldata_in, h_offset, c_offset, l_offset
  real :: vt(4,3), wt(4,3)
  real*8 :: air_mass
  integer :: iv, imm
  ! Code:
  !
  ipol = 1 ! Dummy
  kb = 1 
  kif = 1
  if (r_nsb.eq.2) then
    isb1 = 1
    isb2 = 2
  else
    isb1 = (3-r_isb)/2 
    isb2 = isb1
  endif
  ! Two antenna case
  if (r_nant.le.2) then
    call message(6,3,'SUB_GAIN', 'At least 3 antennas required')
    error = .true.
    return
  endif
  !
  call get_data (ldata_in,data_in,error)
  if (error) goto 999
  !
  ! Select subbands and channels to be averaged
  call check_subb(1,.true.,error)
  if (error) goto 999
  jw1 = iw1(1)
  jw2 = iw2(1)
  iy = xy_ampli                ! Amplitude
  ix = xy_time
  !
  if (do_pass) then
    call set_pass (r_nsb,r_nband,r_nbas+r_ntri,   &
      r_lntch, passc, passl, error)
    if (error) goto 999
  endif
  ! Get average record
  kin = gag_pointer(data_in, memory)
  call spectral_dump(kr,0,0)
  ipk = kin + h_offset(kr)
  call decode_header (memory(ipk))
  call set_scaling(error)
  if (error) return
  do i = 1, r_nant
    call spectral_dump(kr,i,0)
    ipkc = kin + c_offset(kr)
    ipkl = kin + l_offset(kr)
    do iband = isb1, isb2
      do iv=1,4
        do imm=1,3
          vt(iv,imm) = 0
          wt(iv,imm) = 0
        enddo
      enddo
      ! Read antenna average over subbands:
      call arecord (   &
        r_nsb, r_nband, r_nbas, r_lntch,   &
        memory(ipkc), memory(ipkl), passc, passl,   &
        i, iband,ipol,kb, kif, l_subb(1),i_subb(1,1),jw1,jw2,ix,iy,   &
        vt,wt,.false.,error)
      if (error) goto 999
      if (wt(2,2).gt.0) then
        mean_wisi(iband,i) = mean_wisi(iband,i) + wt(2,2)
        ! Correct for differential atmospheric absorption
        ! signal band:
        if (r_sb(ibb) .eq. 3-2*iband) then
          mean_visi(iband,i) = mean_visi(iband,i)   &
            + cmplx(vt(3,2),vt(4,2))   &
            * exp((r_taus(1,ibb)) * air_mass(r_el))
        ! image band:
        else
          mean_visi(iband,i) = mean_visi(iband,i)   &
            + cmplx(vt(3,2),vt(4,2))   &
            * exp((r_taui(1,ibb)) * air_mass(r_el))
        endif
      endif
    enddo
  enddo
  return
  !
999 error = .true.
  return
  !
1001 format( 'Source ',a,' Az ',f8.2,' El ',f8.2,' Tamb',f8.2)
end subroutine sub_gain
!
subroutine sub_solve_pha(qlun, ir, mean_visi, mean_wisi, ibb, error)
  use gildas_def
  use gkernel_interfaces
  use classic_api  
  include 'clic_parameter.inc'
  integer :: qlun                      !
  integer :: ir                        !
  complex :: mean_visi(2,mnant,mnrec)  !
  real    :: mean_wisi(2,mnant,mnrec)  !
  integer :: ibb                       !
  logical :: error                     !
  ! Global
  include 'clic_clic.inc'
  include 'clic_display.inc'
  include 'clic_par.inc'
  include 'gbl_pi.inc'
  ! Local
  logical :: ok(mnant), do_rec
  integer :: i, ig, im, dim
  complex :: av(2), ratio
  real :: wratio
  real :: ph_pol(mnant), faz
  character(len=132) :: ch
  character(len=1) :: backslash
  character(len=1) :: pol(2)
  data pol/'H','V'/
  !-----------------------------------------------------------------------
  backslash=char(92)
  av(1) = 1.0
  av(2) = 1.0
  if (r_sb(ibb).eq.1) then
    ig = 1                     ! Upper sideband
    im = 2
  else
    ig = 2                     ! Lower sideband
    im = 1
  endif
  !
  do_rec  = .false.
  do i=1, r_nant
    ok(i) = mean_wisi(ig,i,ir).gt.0
    do_rec = do_rec .or. ok(i)
  enddo
  if (.not. do_rec) return
  !
  do i=1, r_nant
    if (ok(i)) then
      mean_visi(ig,i,ir) = mean_visi(ig,i,ir)/mean_wisi(ig,i,ir)
      !
      ! Mean phase for polarization phasing
      ph_pol(i) = faz(mean_visi(ig,i,ir))*180/pi
      ph_pol(i) = mod(ph_pol(i)+540.,360.)-180
    else
      write(ch,'(a,i0,a,i1)') 'No signal for antenna ',   &
        r_kant(i),' rec. ',ir
      call message(6,2,'SOLVE_GAIN',ch(1:lenc(ch)))
    endif
  enddo
  !
  ! Deal with Phases
  if (qlun.ne.0) then
    do i=1, r_nant
      if (ok(i)) then
        if (bb_select) then
          if (i.ne.ref_ant) then
            write(qlun,1009)backslash, ph_pol(i), r_kant(i),ir,   &
              r_bbname(i_baseband(1,1))
          else
            write(qlun,1009)backslash, 0.0, r_kant(i),ir,   &
              r_bbname(i_baseband(1,1))
          endif
        elseif (if_select) then
          if (i.ne.ref_ant) then
            write(qlun,1010)backslash, ph_pol(i), r_kant(i),ir,   &
              r_ifname(i_if(1,1))
          else
            write(qlun,1010)backslash, 0.0, r_kant(i),ir,   &
              r_ifname(i_if(1,1))
          endif
        endif
      endif
    enddo
  endif
  return
1009 format('  SET',a1,'PHASE BASEBAND ',f6.1,   &
    ' /ANTENNA ',i0,' /RECEIVER ',i1,' /BASEBAND ',a)
1010 format('  SET',a1,'PHASE POL ',f6.1,   &
    ' /ANTENNA ',i0,' /RECEIVER ',i1,' /IF ',a)
end subroutine sub_solve_pha
!
subroutine sub_solve_gain(qlun, ir, mean_visi, mean_wisi, bb,error)
  use gildas_def
  use gkernel_interfaces
  use classic_api  
  include 'clic_parameter.inc'
  integer :: qlun                      !
  integer :: ir                        !
  complex :: mean_visi(2,mnant,mnrec)  !
  real    :: mean_wisi(2,mnant,mnrec)  !
  integer :: bb
  logical :: error                     !
  ! Global
  include 'clic_clic.inc'
  include 'clic_par.inc'
  include 'gbl_pi.inc'
  include 'clic_display.inc'
  ! Local
  logical :: ok(mnant), do_rec
  integer :: i, inp, iu
  integer(kind=index_length) :: dim(2)
  complex :: av(2), ratio
  real :: wratio
  real :: solved_gain_1(mnant), solved_gain_1_err(mnant)
  real :: solved_gain_2(mnant), solved_gain_2_err(mnant)
  real :: solved_gain_3(mnant), solved_gain_3_err(mnant)
  real :: solved_gain_4(mnant), solved_gain_4_err(mnant)
  real :: solved_gain_5(mnant), solved_gain_5_err(mnant)
  real :: solved_gain_6(mnant), solved_gain_6_err(mnant)
  real,save :: solved_gain(mnant,mnbb), solved_gain_err(mnant,mnbb)
  character(len=132) :: ch
  logical, save :: sic_variable_defined = .false.
  !-----------------------------------------------------------------------
  error = .false.
  if (.not.sic_variable_defined) then
    dim(1) = mnant
    dim(2) = mnbb
    call sic_def_real ('SOLVED_GAIN',solved_gain,2,dim,   &
      .false.,error)
    sic_variable_defined = .true.
  endif
  av(1) = 1.0
  av(2) = 1.0
  !
  ! Deal with Side band ratios
  do_rec  = .false.
  do i=1, r_nant
    ok(i) = mean_wisi(1,i,ir).gt.0.and.mean_wisi(2,i,ir).gt.0
    do_rec = do_rec .or. ok(i)
  enddo
  if (.not. do_rec) return
  !
  do i=1, r_nant
    if (ok(i)) then
      mean_visi(1,i,ir) = mean_visi(1,i,ir)/mean_wisi(1,i,ir)
      mean_visi(2,i,ir) = mean_visi(2,i,ir)/mean_wisi(2,i,ir)
      !
      ! Compute ratio (=4): (AV here is set to 1)
      call mixband(4,r_sb(bb),mean_visi(1,i,ir),   &
        mean_wisi(1,i,ir),av,ratio,wratio)
      !
      write (ch,1004) ir,r_kant(i),abs(ratio),0.001/sqrt(wratio)
1004  format('R',i1,' A',i0,' I/S = ',f6.3,' +- ',f5.3)
      call message(6,1,'SOLVE_GAIN',ch(1:lenc(ch)))
      !
      ! Output values of gain
      inp = bb
      if (qlun.ne.0) then
        if (new_receivers) then
          write(qlun,1002) max(0.001,abs(ratio)) ,r_kant(i),   &
            ir,r_bbname(inp),0.001/sqrt(wratio)
        else
           write(qlun,1001) max(0.001,abs(ratio)) ,r_kant(i),   &
            ir,0.001/sqrt(wratio)
        endif
      endif
    else
      write(ch,'(a,i0,a,i1)') 'No signal for antenna ',   &
        r_kant(i),' rec. ',ir
      call message(6,2,'SOLVE_GAIN',ch(1:lenc(ch)))
    endif
    solved_gain(i,inp) = max(0.001,abs(ratio))
    solved_gain_err(i,inp) = 0.001/sqrt(wratio)
    if (inp.eq.1) then
      solved_gain_1(i) = max(0.001,abs(ratio))
      solved_gain_1_err(i) = 0.001/sqrt(wratio)
    elseif (inp.eq.2) then
      solved_gain_2(i) = max(0.001,abs(ratio))
      solved_gain_2_err(i) = 0.001/sqrt(wratio)
    elseif (inp.eq.3) then
      solved_gain_3(i) = max(0.001,abs(ratio))
      solved_gain_3_err(i) = 0.001/sqrt(wratio)
    elseif (inp.eq.4) then
      solved_gain_4(i) = max(0.001,abs(ratio))
      solved_gain_4_err(i) = 0.001/sqrt(wratio)
    elseif (inp.eq.5) then
      solved_gain_5(i) = max(0.001,abs(ratio))
      solved_gain_5_err(i) = 0.001/sqrt(wratio)
    elseif (inp.eq.6) then
      solved_gain_6(i) = max(0.001,abs(ratio))
      solved_gain_6_err(i) = 0.001/sqrt(wratio)
    endif
  enddo
  if (inp.eq.1) then
    call sic_delvariable ('SOLVED_GAIN_1',.false.,error)
    error = .false.
    call sic_delvariable ('SOLVED_GAIN_1_ERR',.false.,error)
    error = .false.
    dim = r_nant
    call sic_def_real ('SOLVED_GAIN_1',solved_gain_1,1,dim,   &
      .false.,error)
    call sic_def_real ('SOLVED_GAIN_1_ERR',solved_gain_1_err,1,dim,   &
      .false.,error)
    error = .false.
  elseif (inp.eq.2) then
    call sic_delvariable ('SOLVED_GAIN_2',.false.,error)
    error = .false.
    call sic_delvariable ('SOLVED_GAIN_2_ERR',.false.,error)
    error = .false.
    dim = r_nant
    call sic_def_real ('SOLVED_GAIN_2',solved_gain_2,1,dim,   &
      .false.,error)
    call sic_def_real ('SOLVED_GAIN_2_ERR',solved_gain_2_err,1,dim,   &
      .false.,error)
    error = .false.
  elseif (inp.eq.3) then
    call sic_delvariable ('SOLVED_GAIN_3',.false.,error)
    error = .false.
    call sic_delvariable ('SOLVED_GAIN_3_ERR',.false.,error)
    error = .false.
    dim = r_nant
    call sic_def_real ('SOLVED_GAIN_3',solved_gain_3,1,dim,   &
      .false.,error)
    call sic_def_real ('SOLVED_GAIN_3_ERR',solved_gain_3_err,1,dim,   &
      .false.,error)
    error = .false.
  elseif (inp.eq.4) then
    call sic_delvariable ('SOLVED_GAIN_4',.false.,error)
    error = .false.
    call sic_delvariable ('SOLVED_GAIN_4_ERR',.false.,error)
    error = .false.
    dim = r_nant
    call sic_def_real ('SOLVED_GAIN_4',solved_gain_4,1,dim,   &
      .false.,error)
    call sic_def_real ('SOLVED_GAIN_4_ERR',solved_gain_4_err,1,dim,   &
      .false.,error)
    error = .false.
  elseif (inp.eq.5) then
    call sic_delvariable ('SOLVED_GAIN_5',.false.,error)
    error = .false.
    call sic_delvariable ('SOLVED_GAIN_5_ERR',.false.,error)
    error = .false.
    dim = r_nant
    call sic_def_real ('SOLVED_GAIN_5',solved_gain_5,1,dim,   &
      .false.,error)
    call sic_def_real ('SOLVED_GAIN_5_ERR',solved_gain_5_err,1,dim,   &
      .false.,error)
    error = .false.
  elseif (inp.eq.6) then
    call sic_delvariable ('SOLVED_GAIN_6',.false.,error)
    error = .false.
    call sic_delvariable ('SOLVED_GAIN_6_ERR',.false.,error)
    error = .false.
    dim = r_nant
    call sic_def_real ('SOLVED_GAIN_6',solved_gain_6,1,dim,   &
      .false.,error)
    call sic_def_real ('SOLVED_GAIN_6_ERR',solved_gain_6_err,1,dim,   &
      .false.,error)
    error = .false.
  endif
  return
1001 format('SET GAIN ',f6.3,' /ANTENNA ',i0,   &
    ' /RECEIVER ',i1,'     ! +/- ',f5.3)
1002 format('SET GAIN ',f6.3,' /ANTENNA ',i0,   &
    ' /RECEIVER ',i1,' /BASEBAND ',a,'     ! +/- ',f5.3)
end subroutine sub_solve_gain
