Skip to content

Radar

Pulse-Doppler radar system parameter model.

Defines the :class:Radar dataclass that collects all system-level parameters (carrier frequency, transmit power, gains, noise figure, PRF, dwell time, etc.) and derives secondary quantities such as number of pulses and unambiguous range.

Radar dataclass

Pulse-Doppler radar system parameters.

All gain and loss fields are linear power ratios (not dB). n_pulses is derived automatically from dwell_time and prf.

Attributes:

Name Type Description
fcar float

Carrier frequency [Hz].

tx_power float

Transmit power [W].

tx_gain float

Transmit antenna gain [linear].

rx_gain float

Receive antenna gain [linear].

op_temp float

Receiver operating temperature [K].

sample_rate float

ADC sampling rate [Hz].

noise_factor float

Receiver noise factor [linear].

total_losses float

Total two-way system losses [linear].

prf float

Pulse repetition frequency [Hz].

dwell_time float

Coherent processing interval (CPI) duration [s].

n_pulses int

Number of pulses per CPI, computed as ceil(dwell_time * prf) [dimensionless].

Source code in src/rad_lab/pulse_doppler_radar.py
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
@dataclass
class Radar:
    """Pulse-Doppler radar system parameters.

    All gain and loss fields are linear power ratios (not dB).
    ``n_pulses`` is derived automatically from ``dwell_time`` and ``prf``.

    Attributes:
        fcar: Carrier frequency [Hz].
        tx_power: Transmit power [W].
        tx_gain: Transmit antenna gain [linear].
        rx_gain: Receive antenna gain [linear].
        op_temp: Receiver operating temperature [K].
        sample_rate: ADC sampling rate [Hz].
        noise_factor: Receiver noise factor [linear].
        total_losses: Total two-way system losses [linear].
        prf: Pulse repetition frequency [Hz].
        dwell_time: Coherent processing interval (CPI) duration [s].
        n_pulses: Number of pulses per CPI, computed as
            ``ceil(dwell_time * prf)`` [dimensionless].
    """

    fcar: float
    tx_power: float
    tx_gain: float
    rx_gain: float
    op_temp: float
    sample_rate: float
    noise_factor: float
    total_losses: float
    prf: float
    dwell_time: float
    n_pulses: int = field(init=False)

    def __post_init__(self) -> None:
        """Compute n_pulses from dwell_time and prf."""
        self.n_pulses = int(math.ceil(self.dwell_time * self.prf))

dwell_time instance-attribute

fcar instance-attribute

n_pulses = field(init=False) class-attribute instance-attribute

noise_factor instance-attribute

op_temp instance-attribute

prf instance-attribute

rx_gain instance-attribute

sample_rate instance-attribute

total_losses instance-attribute

tx_gain instance-attribute

tx_power instance-attribute

__init__(fcar, tx_power, tx_gain, rx_gain, op_temp, sample_rate, noise_factor, total_losses, prf, dwell_time)

__post_init__()

Compute n_pulses from dwell_time and prf.

Source code in src/rad_lab/pulse_doppler_radar.py
47
48
49
def __post_init__(self) -> None:
    """Compute n_pulses from dwell_time and prf."""
    self.n_pulses = int(math.ceil(self.dwell_time * self.prf))

first_echo_pulse_bin(range, prf)

Determine the pulse index (slow-time bin) in which the first target return arrives.

Parameters:

Name Type Description Default
range float

True target range [m]

required
prf float

Pulse repetition frequency [Hz]

required

Returns:

Name Type Description
int int

The pulse interval index (0-indexed) [unitless]

Source code in src/rad_lab/pulse_doppler_radar.py
169
170
171
172
173
174
175
176
177
178
179
180
def first_echo_pulse_bin(range: float, prf: float) -> int:
    """
    Determine the pulse index (slow-time bin) in which the first target return arrives.

    Args:
        range (float): True target range [m]
        prf (float): Pulse repetition frequency [Hz]

    Returns:
        int: The pulse interval index (0-indexed) [unitless]
    """
    return int(range / range_unambiguous(prf))

frequency_aliased(freq, fs)

Calculate the apparent frequency after aliasing into the Nyquist interval [-fs/2, fs/2].

Parameters:

Name Type Description Default
freq float

Input frequency [Hz]

required
fs float

Sampling frequency [Hz]

required

Returns:

Name Type Description
float float

Aliased frequency within [-fs/2, fs/2][Hz]

Source code in src/rad_lab/pulse_doppler_radar.py
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
def frequency_aliased(freq: float, fs: float) -> float:
    """
    Calculate the apparent frequency after aliasing into the Nyquist interval [-fs/2, fs/2].

    Args:
        freq (float): Input frequency [Hz]
        fs (float): Sampling frequency [Hz]

    Returns:
        float: Aliased frequency within [-fs/2, fs/2] [Hz]
    """
    f = freq % fs
    if f > fs / 2:
        return f - fs
    return f

frequency_delta_doppler(range_rate, f0)

Calculate the Doppler frequency shift resulting from target motion.

Parameters:

Name Type Description Default
range_rate float

Target range rate (radial velocity) [m/s]

required
f0 float

Carrier frequency of the radar pulse [Hz]

required

Returns:

Name Type Description
float float

Doppler frequency shift [Hz]

Source code in src/rad_lab/pulse_doppler_radar.py
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
def frequency_delta_doppler(range_rate: float, f0: float) -> float:
    """
    Calculate the Doppler frequency shift resulting from target motion.

    Args:
        range_rate (float): Target range rate (radial velocity) [m/s]
        f0 (float): Carrier frequency of the radar pulse [Hz]

    Returns:
        float: Doppler frequency shift [Hz]
    """
    return f0 * (-2 * range_rate / c.C)

range_aliased(range, prf)

Calculate the apparent target range as it appears after range wrap-around.

Parameters:

Name Type Description Default
range float

True target range [m]

required
prf float

Pulse repetition frequency [Hz]

required

Returns:

Name Type Description
float float

Aliased (apparent) range [m]

Source code in src/rad_lab/pulse_doppler_radar.py
78
79
80
81
82
83
84
85
86
87
88
89
def range_aliased(range: float, prf: float) -> float:
    """
    Calculate the apparent target range as it appears after range wrap-around.

    Args:
        range (float): True target range [m]
        prf (float): Pulse repetition frequency [Hz]

    Returns:
        float: Aliased (apparent) range [m]
    """
    return range % range_unambiguous(prf)

range_rate_aliased_prf_f0(range_rate, prf, f0)

Calculate the apparent range rate after aliasing based on system parameters.

Parameters:

Name Type Description Default
range_rate float

True range rate [m/s]

required
prf float

Pulse repetition frequency [Hz]

required
f0 float

Carrier frequency of the radar pulse [Hz]

required

Returns:

Name Type Description
float float

Aliased range rate [m/s]

Source code in src/rad_lab/pulse_doppler_radar.py
154
155
156
157
158
159
160
161
162
163
164
165
166
def range_rate_aliased_prf_f0(range_rate: float, prf: float, f0: float) -> float:
    """
    Calculate the apparent range rate after aliasing based on system parameters.

    Args:
        range_rate (float): True range rate [m/s]
        prf (float): Pulse repetition frequency [Hz]
        f0 (float): Carrier frequency of the radar pulse [Hz]

    Returns:
        float: Aliased range rate [m/s]
    """
    return range_rate_aliased_rrmax(range_rate, range_rate_pm_unambiguous(prf, f0))

range_rate_aliased_rrmax(range_rate, range_rate_max)

Calculate the apparent range rate after aliasing within specified velocity bounds.

Parameters:

Name Type Description Default
range_rate float

True range rate [m/s]

required
range_rate_max float

Maximum unambiguous range rate magnitude [m/s]

required

Returns:

Name Type Description
float float

Aliased range rate within [-range_rate_max, range_rate_max][m/s]

Source code in src/rad_lab/pulse_doppler_radar.py
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
def range_rate_aliased_rrmax(range_rate: float, range_rate_max: float) -> float:
    """
    Calculate the apparent range rate after aliasing within specified velocity bounds.

    Args:
        range_rate (float): True range rate [m/s]
        range_rate_max (float): Maximum unambiguous range rate magnitude [m/s]

    Returns:
        float: Aliased range rate within [-range_rate_max, range_rate_max] [m/s]
    """
    r = range_rate % (2 * range_rate_max)
    if r > range_rate_max:
        return r - 2 * range_rate_max
    return r

range_rate_pm_unambiguous(prf, f0)

Calculate the unambiguous radial velocity (range rate) limits (+/-).

Parameters:

Name Type Description Default
prf float

Pulse repetition frequency [Hz]

required
f0 float

Carrier frequency of the radar pulse [Hz]

required

Returns:

Name Type Description
float float

Maximum unambiguous range rate magnitude [m/s]

Source code in src/rad_lab/pulse_doppler_radar.py
123
124
125
126
127
128
129
130
131
132
133
134
def range_rate_pm_unambiguous(prf: float, f0: float) -> float:
    """
    Calculate the unambiguous radial velocity (range rate) limits (+/-).

    Args:
        prf (float): Pulse repetition frequency [Hz]
        f0 (float): Carrier frequency of the radar pulse [Hz]

    Returns:
        float: Maximum unambiguous range rate magnitude [m/s]
    """
    return prf * c.C / (4 * f0)

range_resolution(B)

Calculate the slant range resolution based on the signal bandwidth.

Parameters:

Name Type Description Default
B float

Pulse bandwidth [Hz]

required

Returns:

Name Type Description
float float

Range resolution [m]

Source code in src/rad_lab/pulse_doppler_radar.py
65
66
67
68
69
70
71
72
73
74
75
def range_resolution(B: float) -> float:
    """
    Calculate the slant range resolution based on the signal bandwidth.

    Args:
        B (float): Pulse bandwidth [Hz]

    Returns:
        float: Range resolution [m]
    """
    return c.C / (2 * B)

range_unambiguous(prf)

Calculate the maximum unambiguous range for a given pulse repetition frequency.

Parameters:

Name Type Description Default
prf float

Pulse repetition frequency [Hz]

required

Returns:

Name Type Description
float float

Maximum unambiguous range [m]

Source code in src/rad_lab/pulse_doppler_radar.py
52
53
54
55
56
57
58
59
60
61
62
def range_unambiguous(prf: float) -> float:
    """
    Calculate the maximum unambiguous range for a given pulse repetition frequency.

    Args:
        prf (float): Pulse repetition frequency [Hz]

    Returns:
        float: Maximum unambiguous range [m]
    """
    return c.C / (2 * prf)