Fading channel#
This module contains the FadingChannel class,
which can be used to simulate OFDM transmission through 3GPP TDL and CDL fading channels.
The implementation uses GPU acceleration.
- class aerial.phy5g.channel_models.channel_config.FadingChannelConfig#
Abstract base configuration for fading channel models.
This is an abstract class containing parameters common to all fading channel types. Do not instantiate directly - use TdlChannelConfig or CdlChannelConfig instead.
- Parameters:
delay_profile (str) – 3GPP delay profile identifier [3GPP TR 38.901, Sec 7.7.2]. Values: ‘A’, ‘B’, ‘C’, ‘D’, ‘E’. Default: ‘A’.
delay_spread (float) – RMS delay spread in nanoseconds [3GPP TR 38.901, Table 7.7.3-1]. Typical values: 30 (short), 100 (nominal), 300 (long). Default: 30.
max_doppler_shift (float) – Maximum Doppler frequency shift in Hz. Determined by UE velocity (v) and carrier frequency (fc) as fd = v * fc / c. Default: 5.0.
n_cell (int) – Number of cells in the simulation. Default: 1.
n_ue (int) – Number of UEs per cell. Default: 1.
cfo_hz (float) – Carrier frequency offset in Hz. Models oscillator mismatch between transmitter and receiver. Default: 0.0.
delay (float) – Propagation delay in seconds. Default: 0.0.
save_ant_pair_sample (int) –
Save per antenna pair samples for debugging:
0: Disabled (default).
1: Enabled.
rand_seed (int) – Random seed for reproducible channel generation. Default: 0.
- __init__(
- delay_profile='A',
- delay_spread=30.0,
- max_doppler_shift=5.0,
- n_cell=1,
- n_ue=1,
- cfo_hz=0.0,
- delay=0.0,
- save_ant_pair_sample=0,
- rand_seed=0,
- Parameters:
delay_profile (str)
delay_spread (float)
max_doppler_shift (float)
n_cell (int)
n_ue (int)
cfo_hz (float)
delay (float)
save_ant_pair_sample (int)
rand_seed (int)
- Return type:
None
- class aerial.phy5g.channel_models.channel_config.TdlChannelConfig#
TDL (Tapped Delay Line) channel configuration.
TDL models are used for link-level simulations with simplified spatial characteristics. Suitable for SISO or basic MIMO without antenna array geometry [3GPP TR 38.901, Sec 7.7.2].
The TDL model uses a tapped delay line structure where each tap represents a multipath component with specific delay and power. The model does not include spatial correlation between antenna elements.
Example
>>> config = TdlChannelConfig( ... delay_profile='A', ... delay_spread=30.0, ... max_doppler_shift=5.0, ... n_bs_ant=4, ... n_ue_ant=2 ... )
- Parameters:
n_bs_ant (int) – Number of base station antennas. Default: 1.
n_ue_ant (int) – Number of UE antennas. Default: 1.
n_path (int) – Number of delay taps in the channel model. The number of taps depends on the delay profile (e.g., TDL-A has 23 taps). Default: 23.
use_simplified_pdp (bool) – Use simplified power delay profile with fewer taps for faster computation at the cost of reduced accuracy. Default: False.
- __init__(
- delay_profile='A',
- delay_spread=30.0,
- max_doppler_shift=5.0,
- n_cell=1,
- n_ue=1,
- cfo_hz=0.0,
- delay=0.0,
- save_ant_pair_sample=0,
- rand_seed=0,
- n_bs_ant=1,
- n_ue_ant=1,
- n_path=23,
- use_simplified_pdp=False,
- Parameters:
delay_profile (str)
delay_spread (float)
max_doppler_shift (float)
n_cell (int)
n_ue (int)
cfo_hz (float)
delay (float)
save_ant_pair_sample (int)
rand_seed (int)
n_bs_ant (int)
n_ue_ant (int)
n_path (int)
use_simplified_pdp (bool)
- Return type:
None
- class aerial.phy5g.channel_models.channel_config.CdlChannelConfig#
CDL (Clustered Delay Line) channel configuration.
CDL models include full spatial characteristics with antenna array geometry and angular spreads. Suitable for MIMO simulations requiring accurate spatial correlation [3GPP TR 38.901, Sec 7.7.1].
The CDL model extends TDL by adding angular information (arrival and departure angles) for each cluster, enabling accurate modeling of antenna array responses and spatial correlation.
Example
>>> config = CdlChannelConfig( ... delay_profile='A', ... delay_spread=30.0, ... bs_ant_size=(8, 4, 2), # 8 rows, 4 cols, dual-pol = 64 antennas ... ue_ant_size=(1, 1, 2) # single element, dual-pol = 2 antennas ... )
- Parameters:
bs_ant_size (Tuple[int, int, int]) – Base station antenna array dimensions as (rows, columns, polarizations). Total antennas = rows * columns * polarizations. Default: (2, 2, 2) = 8 antennas.
bs_ant_spacing (Tuple[float, float]) – BS antenna element spacing in wavelengths as (vertical_spacing, horizontal_spacing). Typical value is 0.5 wavelengths. Default: (0.5, 0.5).
bs_ant_polar_angles (Tuple[float, float]) – BS antenna polarization slant angles in degrees for dual-polarized arrays. Default: (45.0, -45.0) for cross-polarized.
bs_ant_pattern (int) –
BS antenna element radiation pattern type:
0: Isotropic pattern (default).
1: 3GPP directional pattern [3GPP TR 38.901, Table 7.3-1].
ue_ant_size (Tuple[int, int, int]) – UE antenna array dimensions as (rows, columns, polarizations). Default: (1, 1, 2) = 2 antennas.
ue_ant_spacing (Tuple[float, float]) – UE antenna element spacing in wavelengths as (vertical_spacing, horizontal_spacing). Default: (0.5, 0.5).
ue_ant_polar_angles (Tuple[float, float]) – UE antenna polarization slant angles in degrees. Default: (0.0, 90.0) for vertical/horizontal polarization.
ue_ant_pattern (int) – UE antenna element radiation pattern type. Default: 0.
n_ray (int) – Number of rays per cluster for angular spread modeling. Default: 20.
v_direction (Tuple[float, float, float]) – UE velocity direction vector as (azimuth_deg, elevation_deg, speed_m_s) for Doppler calculation. Default: (0.0, 0.0, 0.0).
- property n_bs_ant: int#
Total number of base station antennas.
- property n_ue_ant: int#
Total number of UE antennas.
- __init__(
- delay_profile='A',
- delay_spread=30.0,
- max_doppler_shift=5.0,
- n_cell=1,
- n_ue=1,
- cfo_hz=0.0,
- delay=0.0,
- save_ant_pair_sample=0,
- rand_seed=0,
- bs_ant_size=(2, 2, 2),
- bs_ant_spacing=(0.5, 0.5),
- bs_ant_polar_angles=(45.0, -45.0),
- bs_ant_pattern=0,
- ue_ant_size=(1, 1, 2),
- ue_ant_spacing=(0.5, 0.5),
- ue_ant_polar_angles=(0.0, 90.0),
- ue_ant_pattern=0,
- n_ray=20,
- v_direction=(0.0, 0.0, 0.0),
- Parameters:
delay_profile (str)
delay_spread (float)
max_doppler_shift (float)
n_cell (int)
n_ue (int)
cfo_hz (float)
delay (float)
save_ant_pair_sample (int)
rand_seed (int)
bs_ant_size (Tuple[int, int, int])
bs_ant_spacing (Tuple[float, float])
bs_ant_polar_angles (Tuple[float, float])
bs_ant_pattern (int)
ue_ant_size (Tuple[int, int, int])
ue_ant_spacing (Tuple[float, float])
ue_ant_polar_angles (Tuple[float, float])
ue_ant_pattern (int)
n_ray (int)
v_direction (Tuple[float, float, float])
- Return type:
None
- aerial.phy5g.channel_models.channel_config.create_antenna_pattern(ant_model)#
Generate antenna patterns for isotropic or directional antenna models.
This helper function creates the antenna patterns required for AntPanelConfig when using antenna model 0 (isotropic) or 1 (directional/3GPP).
- Parameters:
ant_model (int) –
Antenna model type:
0: Isotropic pattern (constant 0 dB gain in all directions)
1: Directional pattern (3GPP TR 38.901 compliant)
- Returns:
ant_theta: List of 181 floats for A(theta, phi=0) pattern in dB
ant_phi: List of 360 floats for A(theta=90, phi) pattern in dB
- Return type:
Tuple of (ant_theta, ant_phi) where
- Raises:
ValueError – If ant_model is not 0 or 1.
Example
>>> ant_theta, ant_phi = create_antenna_pattern(ant_model=1) >>> config = AntPanelConfig( ... n_ant=4, ... ant_size=[1, 1, 1, 2, 2], ... ant_spacing=[0, 0, 0.5, 0.5], ... ant_theta=ant_theta, ... ant_phi=ant_phi, ... ant_polar_angles=[45, -45], ... ant_model=1 ... )
Note
For ant_model=2 (direct pattern), you must provide your own measured or custom antenna patterns.
- class aerial.phy5g.channel_models.fading_channel.FadingChannel#
GPU-accelerated fading channel for 5G NR simulations.
Implements TDL and CDL channel models with OFDM modulation/demodulation and AWGN noise addition. Supports both CuPy arrays (zero-copy GPU operation) and NumPy arrays (automatic GPU transfer).
The channel processes frequency-domain input signals and produces frequency-domain output signals with applied fading and optional noise.
Example
>>> from aerial.phy5g.channel_models import TdlChannelConfig, FadingChannel >>> >>> config = TdlChannelConfig( ... delay_profile='A', ... delay_spread=30.0, ... n_bs_ant=4, ... n_ue_ant=2 ... ) >>> channel = FadingChannel( ... channel_config=config, ... n_sc=3276, ... numerology=1 ... ) >>> >>> # Run with CuPy (zero-copy) or NumPy (auto-transfer) >>> rx_signal = channel(freq_in=tx_signal, tti_idx=0, snr_db=20.0)
- Parameters:
channel_config (FadingChannelConfig) – Channel model configuration. Must be either TdlChannelConfig or CdlChannelConfig.
n_sc (int) – Number of subcarriers. Default: 3276.
numerology (int) –
5G NR numerology index determining subcarrier spacing [3GPP TS 38.211, Sec 4.2]:
0: 15 kHz subcarrier spacing.
1: 30 kHz subcarrier spacing (default).
2: 60 kHz subcarrier spacing.
3: 120 kHz subcarrier spacing.
n_fft (int) – FFT size for OFDM processing. Default: 4096.
n_symbol_slot (int) – Number of OFDM symbols per slot. Default: 14 (normal CP).
n_sc_prbg (int) – Number of subcarriers per PRB group. Default: 48.
cp_type (int) –
Cyclic prefix type:
0: Normal CP (default).
1: Extended CP.
cuda_stream (Optional[CudaStream]) – CUDA stream for GPU operations. If None, a new CudaStream is created. Use
with stream:to scope work; callstream.synchronize()explicitly when sync is needed. Default: None.disable_noise (bool) – If True, skip AWGN noise addition. Useful for debugging or when noise is added externally. Default: False.
- __init__(
- *,
- channel_config,
- n_sc=3276,
- numerology=1,
- n_fft=4096,
- n_symbol_slot=14,
- n_sc_prbg=48,
- cp_type=0,
- cuda_stream=None,
- disable_noise=False,
Initialize FadingChannel.
- Parameters:
channel_config (FadingChannelConfig) – Channel model configuration. Must be either TdlChannelConfig or CdlChannelConfig.
n_sc (int) – Number of subcarriers.
numerology (int) – 5G NR numerology index (0-3) determining subcarrier spacing.
n_fft (int) – FFT size for OFDM processing.
n_symbol_slot (int) – Number of OFDM symbols per slot.
n_sc_prbg (int) – Number of subcarriers per PRB group.
cp_type (int) – Cyclic prefix type (0: normal, 1: extended).
cuda_stream (CudaStream | None) – CUDA stream. If None, a new CudaStream is created.
disable_noise (bool) – If True, skip AWGN noise addition.
- Return type:
None
- run(
- *,
- freq_in,
- tti_idx,
- snr_db,
- enable_swap_tx_rx=False,
Run the fading channel on input signal.
Processes the input frequency-domain signal through the channel model, applying fading effects and optionally adding AWGN noise.
- Parameters:
freq_in (Array) – Frequency-domain input signal. Shape depends on channel configuration: (n_cell, n_ue, n_tx_ant, n_symbol, n_sc). Accepts both CuPy arrays (zero-copy) and NumPy arrays (auto-transferred to GPU).
tti_idx (int) – Transmission Time Interval index. Used to calculate the reference time for time-varying channel coefficients.
snr_db (float) – Signal-to-Noise Ratio in dB for AWGN noise addition. Ignored if disable_noise=True.
enable_swap_tx_rx (bool) – Swap transmit and receive roles to simulate uplink using downlink channel. Default: False.
- Returns:
- Frequency-domain output signal with fading and noise applied.
Same type as input (CuPy if input was CuPy, NumPy if input was NumPy). Shape: (n_cell, n_ue, n_rx_ant, n_symbol, n_sc).
- Return type:
Array
- reset()#
Reset the channel state.
Reinitializes the internal channel state, useful when starting a new simulation or when channel coherence time has been exceeded.
- Return type:
None
- get_channel_frequency_response(granularity='subcarrier')#
Get the channel frequency response (CFR).
- Parameters:
granularity (str) –
CFR granularity:
’subcarrier’: Per-subcarrier CFR.
’prbg’: Per-PRB group CFR.
- Returns:
Channel frequency response array.
- Return type:
np.ndarray
- Raises:
ValueError – If granularity is not ‘subcarrier’ or ‘prbg’.