subroutine excess_path (f_ghz, p_atm, p_vap, t, dh,   &
     &    z, path, c_snell, n_index)
  !--------------------------------------------------------------------------
  !
  ! Calculation of the excess path length (path length difference between
  ! vacuum and atmospheric propagation) for a parallel medium of
  ! constant refraction index.
  ! Source for the path length formula: Thompson, Moran, Swenson (1986),
  !                     Interferometry and Synthesis in Radio Astronomy, p 407
  !
  ! Input:  real*4 f_ghz   frequency in GHz
  !                p_atm   total atmospherical pressure in millibar
  !                p_vap   partial pressure of water vapor in millibar
  !                t       temperature in kelvin
  !                z       Zenith distance angle (radians)
  ! Output: real*8 c_snell : Constant of Snell's law
  !                n_index : refraction index
  !         real*4 path    : path length difference in units of dh.
  !
  ! Author: 25-Jan-1994  Michael Bremer, IRAM
  !-------------------------------------------------------------------------
  real refract_total, f_ghz, p_atm, p_vap, t, dh, z, path, refr
  real*8 sin_z, cos_z,  c_snell, n_index
  !----------------------------------------------
  !
  refr    = refract_total( f_ghz, p_atm, p_vap, t)
  !
  ! Apply the definition of refractivity to get the refraction index :
  !
  n_index = 1.0d+00 + refr * 1.0d-06
  !
  ! c_snell stays constant along the line of sight (Snell's law) and
  ! is calculated if the given value is .lt. 0. This should make life
  ! easier when dealing with multiple layers.
  !
  if (c_snell .lt. 0) c_snell = sin( z ) * n_index
  sin_z   = c_snell / n_index
  cos_z   = sqrt(1.d+00 - sin_z * sin_z)
  !
  path = refr * 1.0d-06 * dh / cos_z
  !
end subroutine excess_path
!
function refract_total (f_ghz, p_atm, p_vap, t )
  !-------------------------------------------------------------------
  !
  ! Calculation of the total atmospheric refractivity (dry component and
  ! water vapor), taking into account the dependences from
  ! frequency, pressure, temperature
  ! Source of formulae: Hill and Cliffort (1981), Radio Science 16, pp. 77-82
  !                and  Thompson, Moran, Swenson (1986),
  !                     Interferometry and Synthesis in Radio Astronomy, p 407
  !
  ! Input: real*4 f_ghz  frequency in GHz
  !               p_atm  total atmospherical pressure in millibar
  !               p_vap  partial pressure of water vapor in millibar
  !               t      temperature in kelvin
  !
  ! Author: 25-Jan-1994  Michael Bremer, IRAM
  !
  !-------------------------------------------------------------------
  real refract_total, f_ghz, p_atm, p_vap, t
  real ref_dry, ref_vap,  sc, refract_vapor
  !
  !--------------------------------------------
  !
  ! sc = scaling factor for the wavelenght dependent part of the wet refration
  ! (normal conditions 300K, 1013mbar, 80% humidity -> partial pressure of
  !  water vapor 28.2mbar ):
  !
  sc      = (p_vap / 28.2) * (300./t)**2
  ref_dry = 77.493 * p_atm / t
  ref_vap = - 12.8 * p_vap / t + refract_vapor( f_ghz ) * sc
  refract_total = ref_dry + ref_vap
end function refract_total
!
function refract_vapor (f_ghz)
  !-----------------------------------------------------------------------
  !
  ! Function to calculate the refractivity of water vapor 0-480 GHz, under
  ! conditions T=300K, P=1atm, 80% rel. humidity (i.e. partial pressure of
  ! water vapor 28.2 mbar).
  !
  ! Source: Hill and Clifford (1981), Radio Science 16, curve p. 80
  ! Method of digitalisation: zoomed copy to a transparency,
  !                           points read by cursor.
  !                           Approx. errors: F +-1.5 GHz, R +-0.1
  !
  ! Author: 24-Jan-1993 Michael Bremer, IRAM
  !------------------------------------------------------------------------
  real refract_vapor, f_ghz
  integer npoint, i
  parameter (npoint = 53)
  real freq(npoint), refr(npoint), u
  !
  data freq /  &
      0.00 ,  18.00 ,  22.53 ,  47.95 ,  &
     59.41 ,  79.04 ,  98.67 , 115.85 ,  &
    133.03 , 152.66 , 167.39 , 181.70 ,  &
    183.57 , 185.66 , 188.11 , 195.47 ,  &
    215.65 , 235.29 , 250.83 , 271.28 ,  &
    288.28 , 305.46 , 315.27 , 321.64 ,  &
    323.50 , 327.18 , 328.82 , 336.18 ,  &
    348.45 , 358.27 , 366.45 , 371.35 ,  &
    374.63 , 377.90 , 379.53 , 378.72 ,  &
    381.35 , 382.99 , 387.90 , 393.44 ,  &
    405.71 , 427.26 , 431.07 , 437.80 ,  &
    441.07 , 446.16 , 448.80 , 449.62 ,  &
    456.98 , 469.07 , 472.97 , 476.43 ,  &
    480.01 /
  data refr /  &
    115.64 , 115.68 , 115.59 , 115.69 ,  &
    115.76 , 115.88 , 116.07 , 116.25 ,  &
    116.50 , 116.81 , 117.24 , 118.08 ,  &
    117.80 , 116.25 , 116.38 , 117.00 ,  &
    117.65 , 118.21 , 118.71 , 119.39 ,  &
    120.07 , 120.87 , 121.53 , 122.26 ,  &
    122.45 , 121.33 , 121.33 , 122.20 ,  &
    123.38 , 124.37 , 125.61 , 126.91 ,  &
    128.27 , 129.85 , 125.73 , 121.89 ,  &
    119.29 , 119.29 , 121.89 , 123.30 ,  &
    125.70 , 129.18 , 129.87 , 132.29 ,  &
    132.42 , 134.90 , 129.51 , 125.30 ,  &
    129.07 , 133.47 , 134.59 , 134.24 ,  &
    134.96 /
  ! -------------------------------
  !
  ! negative frequencies are NOT accepted (not even in jest):
  !
  if (f_ghz .lt. 0) then
    write(6,*) 'E-ATM,  Error from refract_vapor: frequency < 0'
    stop
  endif
  !
  ! Find the frequency interval (i-1,i) of the input frequency:
  i = 2
  !
  10    continue
  if (freq(i) .gt. f_ghz) goto 20
  i = i + 1
  !
  if (i .le. npoint) goto 10
  !
  !     Print an error message, if the frequency range has been checked and the
  !     requested frequency lies beyond, and give the last data range value:
  !      PRINT *,'Error from refract_vapor: ',F_GHZ,' outside 0-480 GHz.'
  !
  refract_vapor = refr(npoint)
  return
  !
  20    continue
  !
  ! Perform linear interpolation between the interval borders:
  !
  u = (f_ghz - freq(i-1)) / (freq(i) - freq(i-1))
  refract_vapor = refr(i-1) + (refr(i) - refr(i-1)) * u
end function refract_vapor
