Source code for radarx.fundamentals.doppler
"""
Doppler Radar Calculations
===========================
Functions related to Doppler radar performance and velocity limits.
.. autosummary::
:nosignatures:
:toctree: generated/
doppler_dilemma
doppler_frequency_shift
dual_prf_velocity
max_frequency
nyquist_velocity
unambiguous_range
References
----------
- Rinehart, R. E. (1997). Radar for Meteorologists.
- Doviak, R. J., & Zrnić, D. S. (1993). Doppler Radar and Weather Observations.
"""
import numpy as np
from .constants import C
[docs]
def max_frequency(prf):
"""
Compute the maximum observable Doppler frequency.
Parameters
----------
prf : float or array-like
Pulse repetition frequency [Hz]
Returns
-------
float or array-like
Maximum Doppler frequency [Hz]
"""
return np.asarray(prf) / 2.0
[docs]
def nyquist_velocity(prf, wavelength):
"""
Compute Nyquist velocity (maximum unambiguous Doppler velocity).
Parameters
----------
prf : float or array-like
Pulse repetition frequency [Hz]
wavelength : float or array-like
Radar wavelength [m]
Returns
-------
float or array-like
Nyquist velocity [m/s]
"""
return np.asarray(prf) * np.asarray(wavelength) / 4.0
[docs]
def unambiguous_range(prf):
"""
Compute maximum unambiguous range for a given PRF.
Parameters
----------
prf : float or array-like
Pulse repetition frequency [Hz]
Returns
-------
float or array-like
Maximum unambiguous range [m]
"""
return C / (2.0 * np.asarray(prf))
def _doppler_shift_relativistic(frequency, vr):
return frequency * (np.sqrt((1 + vr / C) / (1 - vr / C)) - 1)
def _doppler_shift_exact(frequency, vr):
return 2.0 * frequency * vr / (C - vr)
def _doppler_shift_basic(frequency, vr):
return 2.0 * frequency * vr / C
[docs]
def doppler_frequency_shift(frequency, vr, exact=False, relativistic=False):
"""
Compute Doppler frequency shift.
Parameters
----------
frequency : float or array-like
Transmitted radar frequency [Hz]
vr : float or array-like
Radial velocity of the target [m/s], positive if approaching
exact : bool, optional
If True, uses the classical but accurate Doppler formula: (2 * f * v) / (c - v).
relativistic : bool, optional
If True, uses the relativistic Doppler formula. Overrides `exact` if both are True.
Returns
-------
float or array-like
Doppler frequency shift [Hz]
"""
frequency = np.asarray(frequency)
vr = np.asarray(vr)
if relativistic:
return _doppler_shift_relativistic(frequency, vr)
if exact:
return _doppler_shift_exact(frequency, vr)
return _doppler_shift_basic(frequency, vr)
[docs]
def doppler_dilemma(value, wavelength):
"""
Solve the Doppler dilemma equation: trade-off between unambiguous range and velocity.
Parameters
----------
value : float or array-like
Either Nyquist velocity [m/s] or unambiguous range [m]
wavelength : float
Radar wavelength [m]
Returns
-------
float or array-like
Corresponding range or velocity [m or m/s]
"""
return (C * wavelength / 8.0) / np.asarray(value)
[docs]
def dual_prf_velocity(wavelength, prf1, prf2):
"""
Compute Nyquist velocity using dual-PRF scheme.
Parameters
----------
wavelength : float
Radar wavelength [m]
prf1 : float
First PRF [Hz]
prf2 : float
Second PRF [Hz]
Returns
-------
float
Maximum unambiguous velocity from dual-PRF scheme [m/s]
Notes
-----
The sign of the result depends on the order of PRF values. Ensure prf1 > prf2 for positive velocity.
"""
return wavelength / (4.0 * (1.0 / prf1 - 1.0 / prf2))
__all__ = [
"doppler_dilemma",
"doppler_frequency_shift",
"dual_prf_velocity",
"max_frequency",
"nyquist_velocity",
"unambiguous_range",
"_doppler_shift_basic",
"_doppler_shift_exact",
"_doppler_shift_relativistic",
]