subroutine gvalue (qsb, qband, qant, qntch,   &
    gainc, gainl, wgainc, wgainl,   &
    iant, iband, isub, jw1, jw2, jw3, w, zz, aa, ww, ny,error)
  use gildas_def
  use classic_api
  !---------------------------------------------------------------------
  ! CLIC
  !     Get an antenna gain-like value
  !     QSB     INTEGER   Number of sidebands (2)
  !     QBAND   INTEGER   Number of temporal data
  !     QANT    INTEGER   Number of antennas
  !     QNTCH   INTEGER   Number of channels (in total per baseline)
  !     GAINC(QBAND,QSB,QANT)   COMPLEX  Antenna gains (temporal data)
  !     GAINL(QNTCH,QSB,QBAND)  COMPLEX  Antenna gains (spectral data)
  !     WGAINC(QBAND,QSB,QANT)  REAL  Weight of antenna gain
  !     WGAINL(QNTCH,QSB,QBAND) REAL  Weight of antenna gain
  !     IANT    INTEGER   Antenna number
  !     IBAND   INTEGER   Subband number
  !     ISUB    INTEGER   Sideband number
  !     NY      INTEGER   Number of Y values (output)
  !     JW1,JW2 INTEGER   Lowest and Highest channel in window subband
  !     W       REAL      Signed integration time
  !     AA(*)   REAL      Positive weights
  !     WW(*)   REAL      Total weights
  !     ZZ(*)   COMPLEX   Complex output
  ! Call Tree
  !	...	SUB_READ_SPEC
  !---------------------------------------------------------------------
  integer :: qsb                     !
  integer :: qband                   !
  integer :: qant                    !
  integer :: qntch                   !
  complex :: gainc(qband,qsb,qant)   !
  complex :: gainl(qntch,qsb,qband)  !
  real :: wgainc(qband,qsb,qant)     !
  real :: wgainl(qntch,qsb,qband)    !
  integer :: iant                    !
  integer :: iband                   !
  integer :: isub                    !
  integer :: jw1                     !
  integer :: jw2                     !
  integer :: jw3                     !
  real*4 :: w                        !
  complex :: zz(*)                   !
  real*4 :: aa(*)                    !
  real*4 :: ww(*)                    !
  integer :: ny                      !
  logical :: error
  ! Global
  include 'clic_parameter.inc'
  include 'clic_display.inc'
  include 'clic_clic.inc'
  include 'clic_par.inc'
  ! INCLUDE 'clic_sba.inc'
  ! Local
  integer :: ig, im, is, ii, ii1, ii2, k, i, jok(mch)
  complex :: zzz(2), z, av(2)
  real :: www(2), fw
  !------------------------------------------------------------------------
  !
  ! Correlation scan
  if (r_isb.eq.1) then
    ig = 1
    im = 2
  else
    ig = 2
    im = 1
  endif
  do i=1, 2
    av(i) = 1.
  enddo
  !
  if (qsb.eq.1) then ! Check available sideband
    if (isub.le.mbands) then
      is = isub
    else
      is = isub-mbands
    endif
    if (r_lsband(1,is).ne.iband) then
      call message(6,3,'GVALUE','Sideband unavailable')
      error = .true.
      return
    endif
  endif
  do i=1, 2
    av(i) = 1.0
  enddo
  ! normally one should take here the antenna based side band averages
  ! to be computed in SET_PASS
  ! Use side band averages just determined in CONT_AVERAGE.
  !      DO I=1, 2
  !         IF  (WSBA(I,-IANT).NE.0) THEN
  !            AV(I) = ABS(ZSBA(I,-IANT))/ZSBA(I,-IANT)
  !         ENDIF
  !      ENDDO
  !
  if (iband.le.2) then
    ii1 = iband
    ii2 = iband
  else
    ii1 = 1
    ii2 = 2
  endif
  if (isub.le.mbands) then
    ny = 1
    is = isub
    do ii = ii1, ii2
      zzz(ii) = gainc(is,ii,iant)
      www(ii) = wgainc(is,ii,iant)
    enddo
    !c         CALL MIXBAND(IBAND,IG,IM,ZZZ,WWW,AV,Z,FW)
    call mixband(iband,r_sb(is),zzz,www,av,z,fw)
    zz(1) = zz(1) + fw * z
    if (j_average.ne.1) then
      aa(1) = aa(1) + fw * abs(z)
    endif
    if (fw.gt.0) ww(1) = ww(1) + fw
  else
    is = isub-mbands
    ny = r_lnch(is)
    k = r_lich(is)
    call jlimits(r_lnch(is),jw1,jw2,jw3,jok)
    call jmask(r_lnch(is),nmask(is,iant),cmask(:,:,is,iant),jok)
    do i = 1, ny
      k = k + 1
      do ii = ii1, ii2
        zzz(ii) = gainl(k,ii,iant)
        www(ii) = wgainl(k,ii,iant)
      enddo
      !cc            CALL MIXBAND(IBAND,IG,IM,ZZZ,WWW,AV,Z,FW)
      call mixband(iband,r_sb(is),zzz,www,av,z,fw)
      fw = fw * jok(i)
      zz(i) = zz(i) + fw * z
      if (j_average.ne.1) then
        aa(i) = aa(i) + fw * abs(z)
      endif
      if (fw.gt.0) ww(i) = ww(i) + fw
    enddo
  endif
  return
end subroutine gvalue
!
subroutine mixband(iband,isb,z,w,av,zm,wm)
  use classic_api
  !---------------------------------------------------------------------
  !     IBAND    INTEGER   Sideband code (u/l/aver/diff/ratio)
  !     Z(2)     COMPLEX   Complex antenna gain for both sidebands
  !     W(2)     REAL      Weight
  !     AV(2)    COMPLEX   Complex sideband ratio
  !     ZM       COMPLEX   Output complex gain
  !     WM       REAL      Output weight
  !---------------------------------------------------------------------
  integer :: iband                  !
  integer :: isb                    !
  complex :: z(2)                   !
  real :: w(2)                      !
  complex :: av(2)                  !
  complex :: zm                     !
  real :: wm                        !
  ! Global
  include 'clic_parameter.inc'
  include 'clic_par.inc'
  ! Local
  integer :: ig, im
  !------------------------------------------------------------------------
  ! Code:
  ig = (3-isb)/2
  im = (3+isb)/2
  !
  if (iband.le.2) then
    zm = z(iband)
    wm = w(iband)
  elseif (iband.eq.3) then
    zm = av(ig)*z(ig)*w(ig) + av(im)*z(im)*w(im)
    wm = w(ig) + w(im)
    if (wm.ne.0) zm = zm / wm
  elseif (iband.eq.5) then
    zm = av(ig)*z(ig) - av(im)*z(im)
    wm = w(ig) + w(im)
  elseif (iband.eq.4) then
    if (z(im).ne.0.and.z(ig).ne.0   &
      .and.w(ig).ne.0.and.w(im).ne.0) then
      zm = av(im)*z(im) / (av(ig)*z(ig))
      wm = 1/w(ig)/abs(z(ig))**2 + 1/w(im)/abs(z(im))**2
      wm = 1/wm/abs(zm)**2
    else
      zm = 0
      wm = 0.
    endif
  endif
  return
end subroutine mixband
!
subroutine gain_cont (qsb,qband,qbas,qant,   &
    data_in, passc,gainc,wgainc,error)
  use gildas_def
  use gkernel_interfaces
  use classic_api
  !---------------------------------------------------------------------
  ! CLIC
  !     Compute the antenna gains from temporal data
  ! Arguments
  !     QSB     INTEGER   Number of sidebands (2)
  !     QBAND   INTEGER   Number of temporal data
  !     QANT    INTEGER   Number of antennas
  !     QBAS    INTEGER   Number of baselines
  !     DATC(QBAND,QSB,QBAS)   COMPLEX  Temporal data
  !     PASSC(QBAND,QSB,QBAS)  COMPLEX  PassBand of temporal data
  !     GAINC(QBAND,QSB,QANT)  COMPLEX  Antenna gains (temporal data)
  !     WGAINC(QBAND,QSB,QANT) REAL  Weight of antenna gain
  ! Call Tree
  !	...	SUB_READ_SPEC
  !---------------------------------------------------------------------
  integer :: qsb                           !
  integer :: qband                         !
  integer :: qbas                          !
  integer :: qant                          !
  integer(kind=address_length) :: data_in  !
  complex :: passc(qband,qsb,qbas)         !
  complex :: gainc(qband,qsb,qant)         !
  real :: wgainc(qband,qsb,qant)           !
  logical :: error                         !
  ! Global
  include 'clic_parameter.inc'
  include 'clic_clic.inc'
  include 'clic_par.inc'
  include 'clic_dheader.inc'
  include 'gbl_memory.inc'
  ! Local
  integer :: isb, ib, ic, iant, kr, c_offset, isb1, isb2, ibnd, ibdata
  logical :: down_channel, down_baseline
  real :: tsys_b, w(mnbas), want(mnant), afac
  complex :: z(mnbas), zant(mnant)
  integer(kind=address_length) :: ipkc, kin
  !------------------------------------------------------------------------
  ! Code:
  kin = gag_pointer(data_in,memory)
  !
  !
  do ic = 1, r_nband
    ! Number of sidebands.
    if (r_lnsb.eq.1) then
      isb1 = r_lsband(1,ic)
      isb2 = isb1
      ibnd = 1
    else 
      isb1 = 1
      isb2 = 2
      ibnd = 0
    endif
    do ib = 1, r_nbas
      do isb=isb1, isb2
        if (down_baseline(ib) .or.   &
          down_channel(ib,ic)) then
          z(ib) = 0
          w(ib) = 0
        else
          if (ibnd.ne.0) then
            ibdata = ibnd
          else
            ibdata = isb
          endif
          call spectral_dump(kr,0,ib)
          ipkc = kin + c_offset(kr)
          afac = 1
          call retrieve_datac(qband,qsb,qbas,   &
            memory(ipkc),ic,ibdata,ib,z(ib))
          if (do_pass.or.do_spidx) then
            z(ib) = z(ib)*passc(ic,isb,ib)
          endif
          call scaling (ic,isb,ib,z(ib),afac,error)
          if (.not.error) then
            w(ib) = 2*dh_integ*r_cfwid(ic)/tsys_b(ic,isb,ib)   &
              /afac**2
          else
            w(ib) = 0
          endif
        endif
      enddo
      call antgain (z,w,zant,want)
      do iant = 1, r_nant
        gainc(ic,isb,iant) = zant(iant)
        wgainc(ic,isb,iant) = want(iant)
      enddo
    enddo
  enddo
  return
end subroutine gain_cont
!
subroutine gain_line (qntch,qsb,qbas,qant,   &
    data_in,passl,gainl,wgainl,error)
  use gildas_def
  use gkernel_interfaces
  use classic_api
  !---------------------------------------------------------------------
  ! CLIC
  !     Compute the antenna gains from temporal data
  ! Arguments
  !     QSB     INTEGER   Number of sidebands (2)
  !     QNTCH   INTEGER   Number of spectral channels
  !     QANT    INTEGER   Number of antennas
  !     QBAS    INTEGER   Number of baselines
  !     DATL(QNTCH,QSB,QBAS)   COMPLEX  Spectral data
  !     PASSL(QNTCH,QSB,QBAS)  COMPLEX  PassBand of spectral data
  !     GAINL(QNTCH,QSB,QANT)  COMPLEX  Antenna gains (spectral data)
  !     WGAINL(QNTCH,QSB,QANT) REAL     Weight of antenna gain
  ! Call Tree
  !	...	SUB_READ_SPEC
  !---------------------------------------------------------------------
  integer :: qntch                         !
  integer :: qsb                           !
  integer :: qbas                          !
  integer :: qant                          !
  integer(kind=address_length) :: data_in  !
  complex :: passl(qntch,qsb,qbas)         !
  complex :: gainl(qntch,qsb,qant)         !
  real :: wgainl(qntch,qsb,qant)           !
  logical :: error                         !
  ! Global
  include 'clic_parameter.inc'
  include 'clic_clic.inc'
  include 'clic_display.inc'
  include 'clic_par.inc'
  include 'clic_dheader.inc'
  include 'gbl_memory.inc'
  ! Local
  integer :: isb, ib, ic, ny, k, i, iant, jok(mch), l_offset, kr
  integer :: jokant(mch,mnant)
  integer :: ia, ja
  integer :: isb1, isb2, ibnd, ibdata
  logical :: down_channel, down_baseline
  real :: tsys_b, w(mnbas), want(mnant), afac
  complex :: z(mnbas), zant(mnant)
  integer(kind=address_length) :: ipkl, kin
  !------------------------------------------------------------------------
  ! Code:
  kin = gag_pointer(data_in,memory)
  !
  !
  !
  do ic=1, r_lband
    ! Number of sidebands.
    if (r_lnsb.eq.1) then
      isb1 = r_lsband(1,ic)
      isb2 = isb1
      ibnd = 1
    else 
      isb1 = 1
      isb2 = 2
      ibnd = 0
    endif
    do isb=isb1, isb2
      ny = r_lnch(ic)
      call jlimits(ny,0,0,ngibbs,jok)
      do iant = 1, mnant
        do i = 1, ny
          jokant(i,iant) = jok(i)
        enddo
        call jmask(ny,nmask(ic,iant),cmask(:,:,ic,iant),jokant(1,iant))
      enddo
      !$OMP PARALLEL &
      !$OMP & SHARED(gainl,wgainl,ny,r_lich,ic,r_nbas,ibnd,isb,kin) &
      !$OMP & SHARED(qntch,qsb,qbas,memory,do_pass,do_spidx,passl) &
      !$OMP & SHARED(dh_integ,r_lfres,r_nant,jokant,jok,r_iant,r_jant) &
      !$OMP & PRIVATE(i,k,ib,ibdata,ipkl,kr,afac,z,w,iant,error,zant,want,ia,ja) & 
      !$OMP & DEFAULT(none)
      !
      !$OMP DO
      do i = 1, ny
        error = .false.
        k = r_lich(ic)+i
        do ib = 1, r_nbas
          if (ib.le.mnbas) then
            ia = r_iant(ib)
            ja = r_jant(ib)
          else
            ia = 1
            ja = ia
          endif
          if (down_baseline(ib) .or.   &
            down_channel(ib,ic+mbands) .or.   &
            jokant(i,ia).eq.0 .or. jokant(i,ja).eq.0) then
            z(ib) = 0
            w(ib) = 0
          else
            if (ibnd.ne.0) then
              ibdata = ibnd
            else
              ibdata = isb
            endif
            call spectral_dump(kr,0,ib)
            ipkl = kin + l_offset(kr)
            afac = 1
            call retrieve_datal(qntch,qsb,qbas,   &
              memory(ipkl),k,ibdata,ib,z(ib))
            if (do_pass.or.do_spidx) then
              z(ib) = z(ib)*passl(k,isb,ib)
            endif
            call scaling (ic,isb,ib,z(ib),afac,error)
            if (.not.error)  then
              w(ib) = 2*dh_integ*abs(r_lfres(ic))/tsys_b(ic   &
                ,isb,ib)/afac**2
            else
              w(ib) = 0
            endif
          endif
        enddo
        if (jok(i).ne.0) then
          call antgain (z,w,zant,want)
          do iant = 1, r_nant
            gainl(k,isb,iant) = zant(iant)
            wgainl(k,isb,iant) = want(iant)
          enddo
        else
          do iant = 1, r_nant
            gainl(k,isb,iant) = 0
            wgainl(k,isb,iant) = 0
          enddo
        endif
      enddo
      !$OMP END DO
      !$OMP END PARALLEL
    enddo
  enddo
  return
end subroutine gain_line
!
!
subroutine antgain(z,w,zant,want)
  use gildas_def
  !---------------------------------------------------------------------
  ! CLIC
  !     Derive antenna "gains" from baseline visibilities
  ! Arguments:
  !     Z(MNBAS)    COMPLEX   Visibility
  !     W(MNBAS)    REAL      Weight
  !     ZANT(MNANT) COMPLEX   Complex antenna gain
  !     WANT(MNANT) REAL      Weight
  ! Call Tree
  !	...	GAIN_CONT
  !	...	GAIN_LINE
  !	...	ARECORD
  !	...	CONT_AVERAGE
  !	...	SUB_SOLVE_PASS
  !---------------------------------------------------------------------
  include 'clic_parameter.inc'
  complex :: z(mnbas)               !
  real*4 :: w(mnbas)                !
  complex :: zant(mnant)            !
  real*4 :: want(mnant)             !
  include 'clic_clic.inc'
  ! Code
  if (new_ant_gain) then
    call new_antgain(z,w,zant,want)
  else
    call old_antgain(z,w,zant,want)
  endif
end subroutine antgain
!
!
subroutine new_antgain (z,w,zant,want)
  use gildas_def
  use classic_api  
  !---------------------------------------------------------------------
  ! CLIC
  !     Derive antenna "gains" from baseline visibilities
  ! Arguments:
  !     Z(MNBAS)    COMPLEX   Visibility
  !     W(MNBAS)    REAL      Weight
  !     ZANT(MNANT) COMPLEX   Complex antenna gain
  !     WANT(MNANT) REAL      Weight
  ! Call Tree
  !	...	GAIN_CONT
  !	...	GAIN_LINE
  !	...	ARECORD
  !	...	CONT_AVERAGE
  !	...	SUB_SOLVE_PASS
  !---------------------------------------------------------------------
  include 'clic_parameter.inc'
  complex :: z(mnbas)               !
  real*4 :: w(mnbas)                !
  complex :: zant(mnant)            !
  real*4 :: want(mnant)             !
  ! Global
  include 'gbl_pi.inc'
  include 'clic_constant.inc'
  include 'clic_clic.inc'
  include 'clic_display.inc'
  include 'clic_par.inc'
  ! Local
  real*4 :: aa, faz, wl(mnbas)
  complex :: zl(mnbas)
  integer :: ib, ia, base, iref, itry, i, nant2, nant, repl, ia1
  integer :: irepl(r_nant),nbas,nrem
  parameter (nant2=mnant**2)
  logical :: refok, error
  real*8 :: yy(mnbas), wy(mnbas), ss(mnbas)
  real*8 :: wk2(nant2), wk3(mnant)
  real*8 :: amp(mnant), wamp(mnant), pha(mnant), wpha(mnant)
  !------------------------------------------------------------------------
  ! Code:
  !
  ! Solve for phases, using retroprojection algorithm:
  !
  nant = r_nant
  nbas = r_nbas
  repl = 0
  !
  ! Copy baseline based values into local variables
  do ib = 1, mnbas
    wl(ib) = w(ib)
    zl(ib) = z(ib)
  enddo
  !
  ! Find if there are flagged antennas
  do ia = 1, r_nant
    want(ia) = 0
    do ia1 = 1, r_nant
      if (ia1.ne.ia) then
        ib = base(ia,ia1)
        want(ia) = want(ia) + wl(ib)
      endif
    enddo
    if (want(ia).eq.0) then
      repl = repl + 1
      irepl(repl) = ia
    endif
  enddo
  !
  ! Reduce arrays accordingly
  ! Iterate on flagged antennas in decreasing logical order
  if (repl.ne.0) then
    nrem = 0
    do i = repl, 1, -1
      !
      ! If the flagged antenna I is the last, do nothing
      ! else first remove all baselines IJ with J>I
      if(irepl(i).ne.nant) then
        do ia = nant,irepl(i)+1,-1
          do ib = (ia-2)*(ia-1)/2+irepl(i),nbas
            wl(ib) = wl(ib+1)
            zl(ib) = zl(ib+1)
          enddo
          nrem = nrem + 1
        enddo
        !
        ! Then remove all baseline IJ with J<I
        ib = 1+(irepl(i)-2)*(irepl(i)-1)/2
        do ia = ib,nbas
          zl(ia) = zl(ia+irepl(i)-1)
          wl(ia) = wl(ia+irepl(i)-1)
        enddo
      endif
      !
      ! Reduce array and modify reference antenna if needed
      nant = nant - 1
      nbas = nant * (nant - 1) / 2
      if (iref.gt.irepl(i)) then
        iref =  iref - 1
      endif
    enddo
  endif
  !
  ! No baseline survived for this channel after flagging/masking.
  ! In that case there is no antenna-based solve to perform.
  if (nant.le.1 .or. nbas.le.0) then
    do ia = 1, r_nant
      zant(ia) = 1.
      want(ia) = 0.
    enddo
    return
  endif
  !
  ! Find reference antenna for phase
  refok = .false.
  error = .false.
  iref = ref_ant
  itry = 1
  do while (.not.refok .and. itry.le.r_nant)
    do ia=1, nant
      if (ia.lt.iref) then
        ib = base(ia,iref)
        refok = refok .or. wl(ib).gt.0
      elseif (ia.gt.iref) then
        ib = base(iref,ia)
        refok = refok .or. wl(ib).gt.0
      endif
    enddo
    if (.not.refok) then
      itry = itry+1
      iref = mod(iref,r_nant)+1
    endif
  enddo
  !
  ! Phases
  do ib = 1, nbas
    yy(ib) = faz(zl(ib))
    wy(ib) = wl(ib)
  enddo
  !
  ! Phases
  call gain_ant(2, nbas, r_iant, r_jant, iref,   &
    nant, yy, wy, wk2, wk3, ss, pha, wpha, error)
  !
  ! Amplitudes
  do ib = 1, nbas
    aa = abs(zl(ib))
    yy(ib) = log(aa)
    wy(ib) = wl(ib)*aa**2
  enddo
  call gain_ant(1, nbas, r_iant, r_jant, iref,   &
    nant, yy, wy, wk2, wk3, ss, amp, wamp, error)
  !
  do ia=1, r_nant
    aa = exp(2*amp(ia))
    zant(ia) = aa * exp(cmplx(0.,pha(ia)))
    want(ia) = wamp(ia)/aa**2
  enddo
  !
  ! Special case: less than 3 antennas
  if (nant.lt.3) then
    do ia = 1, nant
      do ib=1, nbas
        if (wl(ib).gt.0) then
          amp(ia) = abs(zl(ib))
          pha(ia) = faz(zl(ib))
          want(ia) = wl(ib)
        endif
      enddo
      zant(ia) = amp(ia) * exp(cmplx(0.,pha(ia)))
    enddo
  endif
  !
  ! Subsitute back flagged value
  if (repl.ne.0) then
    do i = 1,repl ,1
      do ia = nant,max(1,nant-(r_nant-irepl(i))+1),-1
        zant(ia+1) = zant(ia)
        want(ia+1) = want(ia)
      enddo
      nant = nant + 1
      zant(irepl(i))=1
      want(irepl(i))=0
    enddo
  endif
  !
  return
end subroutine new_antgain
!
!
subroutine old_antgain (z,w,zant,want)
  use gildas_def
  use classic_api  
  !---------------------------------------------------------------------
  ! CLIC
  !     Derive antenna "gains" from baseline visibilities
  ! Arguments:
  !     Z(MNBAS)    COMPLEX   Visibility
  !     W(MNBAS)    REAL      Weight
  !     ZANT(MNANT) COMPLEX   Complex antenna gain
  !     WANT(MNANT) REAL      Weight
  ! Call Tree
  !	...	GAIN_CONT
  !	...	GAIN_LINE
  !	...	ARECORD
  !	...	CONT_AVERAGE
  !	...	SUB_SOLVE_PASS
  !---------------------------------------------------------------------
  include 'clic_parameter.inc'
  complex :: z(mnbas)               !
  real*4 :: w(mnbas)                !
  complex :: zant(mnant)            !
  real*4 :: want(mnant)             !
  ! Global
  include 'gbl_pi.inc'
  include 'clic_constant.inc'
  include 'clic_clic.inc'
  include 'clic_display.inc'
  include 'clic_par.inc'
  ! Local
  real*4 :: pha(mnant), amp(mnant), aa, faz, wa, add, aji, aki, ajk
  real*4 :: pha0(mnant)
  integer :: ib, ia, j_i, k_i, j_k, ja, ka, base, iref, itry, i
  logical :: retro, refok
  parameter (retro=.false.)
  !------------------------------------------------------------------------
  ! Code:
  !
  ! Solve for phases, using retroprojection algorithm:
  !
  refok = .false.
  iref = ref_ant
  itry = 1
  do while (.not.refok .and. itry.le.r_nant)
    do ia=1, r_nant
      if (ia.lt.iref) then
        ib = base(ia,iref)
        refok = refok .or. w(ib).gt.0
      elseif (ia.gt.iref) then
        ib = base(iref,ia)
        refok = refok .or. w(ib).gt.0
      endif
    enddo
    if (.not.refok) then
      itry = itry+1
      iref = mod(iref,r_nant)+1
    endif
  enddo
  if (.not.refok) then
    do i=1, r_nant
      pha(i) = 0
    enddo
  else
    !
    pha0(iref) = 0.
    do ia=1, r_nant
      if (ia.lt.iref) then
        ib = base(ia,iref)
        if (w(ib).gt.0) pha0(ia) = -faz(z(ib))
      elseif (ia.gt.iref) then
        ib = base(iref,ia)
        if (w(ib).gt.0) pha0(ia) = faz(z(ib))
      endif
    enddo
    do ia = 1, r_nant
      add = 0
      do ja = 1, r_nant
        if (ja.lt.ia) then
          ib = base(ja,ia)
          if (w(ib).gt.0) then
            add = add + faz(z(ib)) - pha0(ia) + pha0(ja)
          endif
        elseif (ja.gt.ia) then
          ib = base(ia,ja)
          if (w(ib).gt.0) then
            add = add - faz(z(ib)) - pha0(ia) + pha0(ja)
          endif
        endif
      enddo
      add = mod(add+31d0*pi,2d0*pi)-pi
      pha(ia) = pha0(ia)+add/r_nant
    enddo
  endif
  !
  ! solve for amplitudes, using retroprojection algorithm:
  ! (to be checked again)
  ! note:
  ! to compute this way the weights must be provided by antenna,
  ! not by baseline. (RL 2002-02-27)
  if (retro) then
    do ia = 1, r_nant
      want(ia) = 0
      amp(ia) = 0
      do ib=1, r_nbas
        if (w(ib).gt.0) then
          if (r_iant(ib).eq.ia .or. r_jant(ib).eq.ia) then
            amp(ia) = amp(ia)+log(abs(z(ib)))*wa
            want(ia) = want(ia)+wa
          else
            amp(ia) = amp(ia)-log(abs(z(ib)))*wa/(r_nant-2)
            want(ia) = want(ia)-wa/(r_nant-2)
          endif
        endif
      enddo
      if (want(ia).gt.0) then
        amp(ia) = amp(ia)/want(ia)
      else
        amp(ia) = 0.
      endif
      if (r_nant.gt.1) then
        amp(ia) = amp(ia)/(r_nant-1)
        want(ia) = want(ia)/(r_nant-1)
      endif
      zant(ia) = exp(cmplx(amp(ia),pha(ia)))
    !            if (want(ia).gt.0) WANT(IA) = EXP(WANT(IA))
    enddo
  else
    !
    ! Solve for amplitudes
    do ia = 1, r_nant
      want(ia) = 0
      amp(ia) = 0
      if (r_nant.gt.2) then
        do ja = 1, r_nant
          if (ja.ne.ia .and. ja.lt.r_nant) then
            do  ka = ja+1, r_nant
              if (ka.ne.ia) then
                j_i = base(min(ja,ia),max(ja,ia))
                k_i = base(min(ka,ia),max(ka,ia))
                j_k = base(ja,ka)
                if (z(j_k).ne.0 .and. z(j_i).ne.0 .and.   &
                  z(k_i).ne.0 .and. w(j_k).ne.0 .and.   &
                  w(j_i).ne.0 .and. w(k_i).ne.0) then
                  aji = abs(z(j_i))
                  aki = abs(z(k_i))
                  ajk = abs(z(j_k))
                  if (aji.lt.1e15 .and. aki.lt.1e15   &
                    .and. ajk.lt.1e15) then
                    aa = aji*aki/ajk
                    wa = 1./w(j_i)/abs(z(j_i))**2   &
                      +1./w(k_i)/abs(z(k_i))**2   &
                      +1./w(j_k)/abs(z(j_k))**2
                    wa = 1/aa**2/wa
                    amp(ia) = amp(ia) + aa*wa
                    want(ia) = want(ia) + wa
                  endif
                endif
              endif
            enddo
          endif
        enddo
        if (want(ia).ne.0) amp(ia) = amp(ia) / want(ia)
      endif
      !
      ! if previous algorithm did not work, take first valid baseline
      ! containing IA. This will work if there is only one operational baseline ...
      if (want(ia).le.0) then
        do ib=1, r_nbas
          if (w(ib).gt.0) then
            amp(ia) = abs(z(ib))
            want(ia) = w(ib)
          endif
        enddo
      endif
      zant(ia) = amp(ia) * exp(cmplx(0.,pha(ia)))
    !
    !            ZANT(IA) =CMPL2(AMP(IA), PHA(IA))
    !            if (amp(ia).GT.BLANK4-D_BLANK4) want(ia) = 0
    enddo
  endif
  return
end subroutine old_antgain
!
subroutine gain_ant(iy, nbas, iant, jant, iref,   &
    nant, y, w, wk2, wk3, ss, c, wc, error)
  use gkernel_interfaces
  !---------------------------------------------------------------------
  !     gain_ant computes a weighted least-squares approximation
  !     to the antenna amplitudes or phases
  !     for an arbitrary set of baseline data points.
  ! parameters:
  !     iy             I   Input    1 for log(amplitude), 2 for phase
  !     nbas           I   Input    the number of baselines
  !     iant(nbas)     I   Input    start antenna for each baseline
  !     jant(nbas)     I   Input    end  antenna for each baseline
  !     iref           i   Input    Reference antenna for phases
  !     nant           I   Input    the number of antennas
  !     y(m,nbas)      R8  Input    the data values
  !     w(m,nbas)      R8  Input    weights
  !     wk2(nant**2)   R8  Output   work space
  !     wk3(nant)      R8  Output   work space
  !     ss(nbas)       R8  Output   rms of fit for each baseline
  !     c(nant)        R8  Output   the gains
  !     wc(nant)        R8  Output   the output weights
  !---------------------------------------------------------------------
  integer :: iy                     !
  integer :: nbas                   !
  integer :: iant(nbas)             !
  integer :: jant(nbas)             !
  integer :: iref                   !
  integer :: nant                   !
  real*8 :: y(nbas)                 !
  real*8 :: w(nbas)                 !
  real*8 :: wk2(nant,nant)          !
  real*8 :: wk3(nant)               !
  real*8 :: ss(nbas)                !
  real*8 :: c(nant)                 !
  real*8 :: wc(nant)                !
  logical :: error                  !
  ! Global
  include 'gbl_pi.inc'
  ! Local
  real*8 :: norm, tol
  parameter (tol=1d-14)
  integer :: zant, i, ia, ib, nantm1, ja, l, iter
  real*8 ::  wi, ww, yi
  !------------------------------------------------------------------------
  ! Code
  !
  ! Check that the weights are positive.
  !
  do ib = 1, nbas
    if (w(ib).lt.0.0d0) then
      call gagout('E-GAIN_ANT, Weights not positive')
      error = .true.
      return
    endif
  enddo
  !
  ! Amplitude case is simple...
  !
  if (iy.eq.1) then
    do i=1,nant
      do l=1,nant
        wk2(l,i) = 0.0d0
      enddo
      wk3(i) = 0.0d0
    enddo
    !
    ! store the upper-triangular part of the normal equations in wk2
    ! and the right-hand side in wk3.
    do ib=1,nbas
      wi = w(ib)
      if (wi.gt.0) then
        ia = iant(ib)
        ja = jant(ib)
        wk2(ia,ia) = wk2(ia,ia)+wi
        wk2(ia,ja) = wk2(ia,ja)+wi
        wk2(ja,ia) = wk2(ja,ia)+wi
        wk2(ja,ja) = wk2(ja,ja)+wi
      endif
    enddo
    do ib=1, nbas
      ia = iant(ib)
      ja = jant(ib)
      wi = w(ib)*y(ib)
      wk3(ia) = wk3(ia) + wi
      wk3(ja) = wk3(ja) + wi
    enddo
    !
    ! Solve the system of normal equations by first computing the Cholesky
    ! factorization
    call mth_dpotrf ('GAIN_ANT','U',nant,wk2,nant,error)
    if (error) goto 999
    call mth_dpotrs ('GAIN_ANT','U',nant,1,wk2,nant,wk3,nant,error)
    if (error) goto 999
    do i=1,nant
      wc(i) = wk2(i,i)**2
      c(i) = wk3(i)
    enddo
  !
  ! Phase is more complicated ...
  elseif (iy.eq.2) then
    nantm1 = nant-1
    do i=1,nant
      c(i) = 0.0d0
      wc(i) = 0.0d0
    enddo
    !
    ! start iterating
    norm = 1e10
    iter = 0
    do while (norm.gt.tol .and. iter.lt.100)
      iter = iter + 1
      do i=1,nantm1
        do l=1,nantm1
          wk2(l,i) = 0.0d0
        enddo
        wk3(i) = 0.0d0
      enddo
      do ib=1,nbas
        wi = w(ib)
        if (wi.gt.0) then
          ia = zant(iant(ib),iref)
          ja = zant(jant(ib),iref)
          if (ia.ne.0) then
            wk2(ia,ia) = wk2(ia,ia)+wi
          endif
          if (ja.ne.0) then
            wk2(ja,ja) = wk2(ja,ja)+wi
          endif
          if (ia.ne.0 .and. ja.ne.0) then
            wk2(ja,ia) = wk2(ja,ia)-wi
            wk2(ia,ja) = wk2(ia,ja)-wi
          endif
        endif
      enddo
      do ib=1, nbas
        if (w(ib).gt.0) then
          yi = y(ib)
          ia = iant(ib)
          ja = jant(ib)
          yi = yi+(c(ia)-c(ja))
        else
          yi = 0
        endif
        yi = sin(yi)
        ia = zant(iant(ib),iref)
        ja = zant(jant(ib),iref)
        wi = w(ib)*yi
        if (ia.ne.0) then
          wk3(ia) = wk3(ia) - wi
        endif
        if (ja.ne.0) then
          wk3(ja) = wk3(ja) + wi
        endif
      enddo
      !
      ! Solve the system of normal equations by first computing the Cholesky
      ! factorization
      call mth_dpotrf('GAIN_ANT','U',nantm1,wk2,nant,error)
      if (error) goto 999
      call mth_dpotrs ('GAIN_ANT','U',nantm1,1,wk2,nant,   &
        wk3,nantm1,error)
      if (error) goto 999
      !  Add the result to c:
      norm = 0
      do ia=1,nant
        i = zant(ia,iref)
        if (i.ne.0) then
          ww = wk3(i)
          c(ia) = c(ia)+ww
          wc(ia) = wk2(i,i)**2
          norm = norm+ww**2
        endif
      enddo
    enddo
  endif
  return
  !
999 error = .true.
  return
end subroutine gain_ant
!
function cmpl2(amp, pha)
  !---------------------------------------------------------------------
  ! Returns a complex of given amplitude and phase
  ! Test blanking value BLANK4
  !---------------------------------------------------------------------
  complex :: cmpl2                  !
  real :: amp                       !
  real :: pha                       !
  ! Global
  include 'clic_parameter.inc'
  !-----------------------------------------------------------------------
  if ((pha.gt.blank4-d_blank4   &
    .and. pha.le.blank4+d_blank4)   &
    .or. (amp.gt.blank4-d_blank4   &
    .and. amp.le.blank4+d_blank4)) then
    cmpl2 = cmplx(blank4,blank4)
    return
  endif
  cmpl2 = amp * exp(cmplx(0,pha))
  return
end function cmpl2
!
subroutine retrieve_datac(qband,qsb,qbas,datac,ic,isb,ib,z)
  integer :: qband                  !
  integer :: qsb                    !
  integer :: qbas                   !
  complex :: datac(qband,qsb,qbas)  !
  integer :: ic                     !
  integer :: isb                    !
  integer :: ib                     !
  complex :: z                      !
  !-----------------------------------------------------------------------
  z = datac(ic,isb,ib)
  return
end subroutine retrieve_datac
!
subroutine retrieve_datal(qntch,qsb,qbas,datal,k,isb,ib,z)
  integer :: qntch                  !
  integer :: qsb                    !
  integer :: qbas                   !
  complex :: datal(qntch,qsb,qbas)  !
  integer :: k                      !
  integer :: isb                    !
  integer :: ib                     !
  complex :: z                      !
  !-----------------------------------------------------------------------
  z = datal(k,isb,ib)
  return
end subroutine retrieve_datal
