generate_time_channel.py (3777B)
1 # 2 # SPDX-FileCopyrightText: Copyright (c) 2021-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 # SPDX-License-Identifier: Apache-2.0 4 # 5 """Class for generating channel responses in the time domain""" 6 7 8 from sionna.channel.utils import cir_to_time_channel 9 10 class GenerateTimeChannel: 11 # pylint: disable=line-too-long 12 r"""GenerateTimeChannel(channel_model, bandwidth, num_time_samples, l_min, l_max, normalize_channel=False) 13 14 Generate channel responses in the time domain. 15 16 For each batch example, ``num_time_samples`` + ``l_max`` - ``l_min`` time steps of a 17 channel realization are generated by this layer. 18 These can be used to filter a channel input of length ``num_time_samples`` using the 19 :class:`~sionna.channel.ApplyTimeChannel` layer. 20 21 The channel taps :math:`\bar{h}_{b,\ell}` (``h_time``) returned by this layer 22 are computed assuming a sinc filter is used for pulse shaping and receive filtering. 23 Therefore, given a channel impulse response 24 :math:`(a_{m}(t), \tau_{m}), 0 \leq m \leq M-1`, generated by the ``channel_model``, 25 the channel taps are computed as follows: 26 27 .. math:: 28 \bar{h}_{b, \ell} 29 = \sum_{m=0}^{M-1} a_{m}\left(\frac{b}{W}\right) 30 \text{sinc}\left( \ell - W\tau_{m} \right) 31 32 for :math:`\ell` ranging from ``l_min`` to ``l_max``, and where :math:`W` is 33 the ``bandwidth``. 34 35 Parameters 36 ---------- 37 channel_model : :class:`~sionna.channel.ChannelModel` object 38 An instance of a :class:`~sionna.channel.ChannelModel`, such as 39 :class:`~sionna.channel.RayleighBlockFading` or 40 :class:`~sionna.channel.tr38901.UMi`. 41 42 bandwidth : float 43 Bandwidth (:math:`W`) [Hz] 44 45 num_time_samples : int 46 Number of time samples forming the channel input (:math:`N_B`) 47 48 l_min : int 49 Smallest time-lag for the discrete complex baseband channel (:math:`L_{\text{min}}`) 50 51 l_max : int 52 Largest time-lag for the discrete complex baseband channel (:math:`L_{\text{max}}`) 53 54 normalize_channel : bool 55 If set to `True`, the channel is normalized over the block size 56 to ensure unit average energy per time step. Defaults to `False`. 57 58 Input 59 ----- 60 61 batch_size : int 62 Batch size. Defaults to `None` for channel models that do not require this paranmeter. 63 64 Output 65 ------- 66 h_time : [batch size, num_rx, num_rx_ant, num_tx, num_tx_ant, num_time_samples + l_max - l_min, l_max - l_min + 1], tf.complex 67 Channel responses. 68 For each batch example, ``num_time_samples`` + ``l_max`` - ``l_min`` time steps of a 69 channel realization are generated by this layer. 70 These can be used to filter a channel input of length ``num_time_samples`` using the 71 :class:`~sionna.channel.ApplyTimeChannel` layer. 72 """ 73 74 def __init__(self, channel_model, bandwidth, num_time_samples, l_min, l_max, 75 normalize_channel=False): 76 77 # Callable used to sample channel input responses 78 self._cir_sampler = channel_model 79 80 self._l_min = l_min 81 self._l_max = l_max 82 self._l_tot = l_max - l_min + 1 83 self._bandwidth = bandwidth 84 self._num_time_steps = num_time_samples 85 self._normalize_channel = normalize_channel 86 87 def __call__(self, batch_size=None): 88 89 # Sample channel impulse responses 90 # pylint: disable=unbalanced-tuple-unpacking 91 h, tau = self._cir_sampler( batch_size, 92 self._num_time_steps + self._l_tot - 1, 93 self._bandwidth) 94 95 hm = cir_to_time_channel(self._bandwidth, h, tau, self._l_min, 96 self._l_max, self._normalize_channel) 97 98 return hm