Waveform
The module waveform.py implements the Waveform class which encapsulates a time-domain signal
transmitted from a set of transmitter antennas or received by a set of receiver antennas. A waveform object is
usually created by applying OFDM modulation to a resource grid object. See ofdmModulate()
method of the Grid class for more information.
- class neoradium.waveform.Waveform(waveform, noiseVar=0)
This class encapsulates a set of sequences of complex values representing the time-domain signals as transmitted by each transmitter antenna or as received by each receiver antenna. A Waveform object is usually created by applying OFDM modulation to a resource grid.
Once you have a Waveform object, you can apply a channel model to it, add AWGN noise to it, or apply other signal processing tasks such as windowing. All of these processes result in new
Waveformobjects.At the receiver the received signals are usually converted back to the frequency domain by applying OFDM demodulation, which results in a
Gridobject representing the received resource grid.- Parameters:
waveform (2D complex NumPy array) – A
P x Ns2D complex NumPy array representing a set of time-domain signals of lengthNsfor each one ofPantenna elements. The valuePis equal toNt, the number of transmitter antennas when this is a transmitted signal, and equal toNr, the number of receiver antennas when this is a received signal.noiseVar (float) – The variance of the noise applied to the time-domain signals in this Waveform object. This is usually initialized to zero. When an AWGN noise is applied to the waveform using the
addNoise()function, the variance of the noise is saved in the Waveform object.
Other Read-Only Properties:
- shape:
Returns the shape of the 2-dimensional waveform NumPy array.
- numPorts:
The number of transmitter or receiver antennas (
P) for this waveform.- length:
The length of the time-domain signal in number of samples (
Ns).
- print(indent=0, title=None, getStr=False)
Prints the properties of this Waveform object.
- Parameters:
indent (int) – The number of indentation characters.
title (str) – If specified, it is used as a title for the printed information.
getStr (Boolean) – If True, returns a text string instead of printing it.
- Returns:
If the
getStrparameter is True, then this function returns the information in a text string. Otherwise, nothing is returned.- Return type:
None or str
- getNoiseStd(snr, bwp)
This function calculates the noise standard deviation for the given signal-to-noise ratio. It first calculates the average received signal power per resource element (RE) and then uses it, along with the given signal-to-noise ratio, to calculate the noise power. The returned standard deviation can be used directly by the
addNoise()method using thenoiseStdargument.- Parameters:
snr (float) – The signal-to-noise ratio in the linear form (not dB).
bwp (
BandwidthPart) – The bandwidth part object used to create the waveform.
- Returns:
The noise standard deviation.
- Return type:
float
- addNoise(**kwargs)
Adds Additive White Gaussian Noise (AWGN) to this waveform based on the given noise properties. The noisy waveform is then returned in a new
Waveformobject.This is similar to the
addNoise()method of theGridclass, which applies noise in the frequency domain.If you have the noise signal in a numpy array, you can use the
noiseparameter of this function to apply it to this waveform:ExamplemyNoise = random.awgn(rxWaveform.shape, 0.1) # Create AWGN with σ = 0.1 rxWaveform.addNoise(noise=myNoise)
If you know the variance or standard deviation of the noise, then you can use them directly by setting the arguments
noiseStdandnoiseVarrespectively.ExamplerxWaveform.addNoise(noiseStd=0.1) # Same results as above rxWaveform.addNoise(noiseVar=0.01) # Same results as above
If you have a signal-to-noise ratio, there are two different approaches to adding noise to the received waveform.
Matlab Approach:
In this case, it is assumed that the received signal power is normalized to \(\frac 1 {N_r}\) where \(N_r\) is the number of receiver antenna. Please note that when channel models such as CDL, TDL, or trajectory based channel models are used in the communication pipleline, this assumption is not always true. Support for this approach is included only to allow comparison with Matlab.
\[\sigma^2_{AWGN} = \frac 1 {N_r.nFFT.10^{\frac {snrDb} {10}}}\]where \(nFFT\) is the FFT size derived from the given
BandwidthPartobject.ExamplerxWaveform.addNoise(snrDb=mySnrDb, bwp=bwp, useRxPower=False)
Using RX Power:
In this case, this function first calculates the average received signal power per resource element (RE), and uses it, along with the given signal-to-noise ratio to calculate the noise power.
\[\sigma^2_{AWGN} = \frac {\sigma^2_{RX}} {nFFT.10^{\frac {snrDb} {10}}}\]ExamplerxWaveform.addNoise(snrDb=mySnrDb, bwp=bwp, useRxPower=True)
Please refer to the notebook SNR Calculations in NeoRadium for a complete analysis of how NeoRadium calculates and applies noise power for a given signal-to-noise ratio.
- Parameters:
kwargs (dict) –
One of the following methods of specifying the noise must be specified.
- noise:
A NumPy array with the same shape as this
Waveformobject containing the noise information. If the noise information is provided bynoise, it is added directly to the waveform. In this case all other parameters are ignored.- noiseStd:
The standard deviation of the noise. An AWGN complex noise signal is generated with zero mean and the specified standard deviation. If
noiseStdis specified,noiseVarandsnrDbare ignored.- noiseVar:
The variance of the noise. An AWGN complex noise signal is generated with zero mean and the specified variance. If
noiseVaris specified, the value ofsnrDbis ignored.- snrDb:
The signal-to-noise ratio in dB. First the noise standard deviation is calculated using the given SNR value and the
bwpanduseRxPowerparameters. Then an AWGN complex noise signal is generated with zero mean and the calculated standard deviation. Please note that if an SNR value is used to specify the amount of noise, then aBandwidthPartobject also needs to be provided.- bwp:
BandwidthPartThe bandwidth part object used to extract the FFT information. This is only used ifsnrDbis used to specify the amount of noise.- useRxPower:
Boolean If True, this function first calculates the average received signal power per resource element (RE), and uses it with the given signal-to-noise ratio to calculate the noise power. Otherwise, it is assumed that the received signal power is normalized to \(\frac 1 {N_r}\) where \(N_r\) is the number of receiver antenna (Matlab Approach).
Note
Currently the default value of
useRxPoweris False (Matlab approach) for backward compatibility. However, in future releases this may be changed to True. To ensure forward-compatible code, explicitly set this parameter instead of relying on the default.- ranGen:
If provided, it is used as the random generator for the AWGN generation. Otherwise, if this is not specified, NeoRadium’s global random generator is used.
- Returns:
A new Waveform object containing the noisy version of this waveform.
- Return type:
- pad(numPad)
Appends a sequence of
numPadzeros to the end of time-domain signals in thisWaveformobject.To make sure a signal is received in its entirety when it goes through a channel model, we usually need to pad zeros to the end of the time-domain signal. The number of these zeros usually depends on the maximum channel delay. The function
getMaxDelay()of the channel model can be used to get the number of padded zeros.- Parameters:
numPad (int) – The number of time-domain zero samples to be appended to the end of this waveform.
- Returns:
A new Waveform object which is
numPadsamples longer than the original waveform.- Return type:
- sync(timingOffset)
Removes
timingOffsetvalues from the beginning of the time-domain signals in thisWaveformobject. This effectively shifts the signal in time domain bytimingOffsetsamples.When a time-domain signal goes through a channel model, it is delayed in time because of the propagation delay. Different transmission paths may be affected by different propagation delays. The channel’s
chanOffsetmember can be used to obtain thetimingOffset. In practice, this value is calculated by finding the time-domain sample index where the correlation between the received signal and a set of reference signals is at its maximum. See for example the functionestimateTimingOffset()of theGridclass.
- applyChannel(channel)
Applies the channel model
channelto this Waveform object and returns a new Waveform object representing the received signal. This function internally calls theapplyToSignal()method of the channel model passing in this waveform object as theinputSignal.- Parameters:
channel (
ChannelModel) – The channel model that is applied to this time-domain waveform.- Returns:
A new Waveform object which represents the received time-domain waveform.
- Return type:
- applyWindowing(cpLens, windowing, bwp)
This is a helper function that is used to apply windowing to the OFDM waveform obtained from OFDM modulation of a resource grid.
This method supports several different windowing approaches including the ones specified in 3GPP TS 38.104, Sections B.5.2 and C.5.2.
You usually do not need to call this function directly. It is called internally at the end of the OFDM modulation process when the function
ofdmModulate()of theGridclass is called.- Parameters:
cpLens (list) – A list of integer values each representing the length of cyclic prefix part at the beginning of each OFDM symbol in number of time-domain samples. This list can be obtained from the
BandwidthPartobject.windowing (str) –
A text string specifying how the window length is obtained. It can be one of the following:
- ”STD”:
The windowing size is determined based on 3GPP TS 38.104, Sections B.5.2 and C.5.2.
- Ratio as percentage:
A windowing ratio can be specified as a percentage value. For example, the text string “%25” represents a windowing ratio of
0.25. The window length is calculated as the minimum value ofcpLensmultiplied by the windowing ratio, and rounded to the nearest integer value.- Ratio:
A windowing ratio (between 0 and 1) can be specified as a number. For example, the text string “0.125” represents a windowing ratio of
0.125. The window length is calculated as the minimum value ofcpLensmultiplied by the windowing ratio and rounded to the nearest integer value.- Window Length:
The actual window length can also be specified as an integer value. For example, the text string “164” represents a window length equal to
164.
bwp (
BandwidthPart) – The bandwidth part used for the communication.
- Returns:
A new Waveform object which represents the waveform after applying the windowing.
- Return type:
- ofdmDemodulate(bwp, f0=0, cpOffsetRatio=0.5)
Applies OFDM demodulation to the waveform which results in a frequency-domain resource grid returned as a
Gridobject.If an AWGN noise was applied to the waveform using the
addNoise()method, then the amount of noise is transferred to theGridobject that is created. The noise variance of the returned resource grid is equal to the waveform’s noise variance timesnFFT.- Parameters:
bwp (
BandwidthPart) – The bandwidth part used for the communication.f0 (float) – The carrier frequency of the waveform. If it is 0 (default), then a baseband waveform is assumed. This should match the value originally used when applying OFDM modulation at the transmitter side. See the
ofdmModulate()method of theGridclass.cpOffsetRatio (float) – This value determines where, in the cyclic prefix (as a ratio from the beginning of the CP), the FFT should be applied. The default value of
0.5means that the FFT is applied at the midpoint of the cyclic prefix.”
- Returns:
A
Gridobject representing the received resource grid.- Return type: