#!/usr/bin/env python
# -*- coding: UTF-8 -*-

"""
Miscellaneous
^^^^^^^^^^^^^

.. autosummary::
:nosignatures:
:toctree: generated/

{}
"""
__all__ = ["bin_altitude", "bin_distance", "site_distance"]
__doc__ = __doc__.format("\n   ".join(__all__))

import numpy as np

[docs]def bin_altitude(r, theta, sitealt, re, ke=4.0 / 3.0):
"""Calculates the height of a radar bin taking the refractivity of the \
atmosphere into account.

Based on :cite:Doviak1993 the bin altitude is calculated as

.. math::

h = \\sqrt{r^2 + (k_e r_e)^2 + 2 r k_e r_e \\sin\\theta} - k_e r_e

Parameters
----------
r : :class:numpy:numpy.ndarray
Array of ranges [m]
theta : scalar or :class:numpy:numpy.ndarray
Array broadcastable to the shape of r elevation angles in degrees with 0°
at horizontal and +90° pointing vertically upwards from the radar
sitealt : float
Altitude in [m] a.s.l. of the referencing radar site
re : float
ke : float
affects radar beam propagation. In principle this is wavelength-
dependend. The default of 4/3 is a good approximation for most

Returns
-------
altitude : :class:numpy:numpy.ndarray
Array of heights of the radar bins in [m]

"""
reff = ke * re
sr = reff + sitealt
return np.sqrt(r**2 + sr**2 + 2 * r * sr * np.sin(np.radians(theta))) - reff

[docs]def bin_distance(r, theta, sitealt, re, ke=4.0 / 3.0):
"""Calculates great circle distance from radar site to radar bin over \
spherical earth, taking the refractivity of the atmosphere into account.

.. math::

s = k_e r_e \\arctan\\left(
\\frac{r \\cos\\theta}{r \\cos\\theta + k_e r_e + h}\\right)

where :math:h would be the radar site altitude amsl.

Parameters
----------
r : :class:numpy:numpy.ndarray
Array of ranges [m]
theta : scalar or :class:numpy:numpy.ndarray
Array broadcastable to the shape of r elevation angles in degrees with 0°
at horizontal and +90° pointing vertically upwards from the radar
sitealt : float
site altitude [m] amsl.
re : float
ke : float
affects radar beam propagation. In principle this is wavelength-
dependent. The default of 4/3 is a good approximation for most

Returns
-------
distance : :class:numpy:numpy.ndarray
Array of great circle arc distances [m]
"""
reff = ke * re
sr = reff + sitealt
return reff * np.arctan(r * np.cos(theta) / (r * np.sin(theta) + sr))

[docs]def site_distance(r, theta, binalt, re=None, ke=4.0 / 3.0):
"""Calculates great circle distance from bin at certain altitude to the \
radar site over spherical earth, taking the refractivity of the \
atmosphere into account.

Based on :cite:Doviak1993 the site distance may be calculated as

.. math::

s = k_e r_e \\arcsin\\left(
\\frac{r \\cos\\theta}{k_e r_e + h_n(r, \\theta, r_e, k_e)}\\right)

where :math:h_n would be provided by
:func:~wradlib.georef.misc.bin_altitude.

Parameters
----------
r : :class:numpy:numpy.ndarray
Array of ranges [m]
theta : scalar or :class:numpy:numpy.ndarray
Array broadcastable to the shape of r elevation angles in degrees with 0°
at horizontal and +90° pointing vertically upwards from the radar
binalt : :class:numpy:numpy.ndarray
site altitude [m] amsl. same shape as r.
re : float
ke : float
distance : :class:numpy:numpy.ndarray