Est. read time: 1 minute | Last updated: May 04, 2026 by John Gentile


Contents

Open In Colab

from IPython.display import YouTubeVideo, Markdown
import inspect

import numpy as np
import matplotlib.pyplot as plt
import scipy
from rfproto import impairments
YouTubeVideo('PNMOwhEHE6w')
YouTubeVideo('LBLvmNyAdSI')

Noise

Thermal Noise

Defined by the equation:

N=kTBFNN = kTBF_{N}

Where:

  • kk is the Boltzmann Constant
  • TT is the device temperature in Kelvin
  • BB is the receiver bandwidth in Hertz
  • FNF_{N} is the noise factor of the system
Markdown(f"```python\n{inspect.getsource(impairments.thermal_noise)}\n```")
def thermal_noise(T, B, Fn):
    return scipy.constants.k * T * B * Fn

At room temp (290 Kelvin), this relates to a noise power spectral density of -144 dBW/MHz, which means for every 1 MHz of bandwidth, -144 dBW of thermal noise is added).

room_temp = 290
bw = 10e6
# convert to dBW, then +30 to dBmW
therm_noise = 10*np.log10(impairments.thermal_noise(room_temp, bw, 1)) + 30
print(f"Thermal noise at room temp, {bw/1e6}MHz bandwidth: {therm_noise:.4} dBmW")

Thermal noise at room temp, 10.0MHz bandwidth: -104.0 dBmW

DC Offset Removal

I/Q Offset Correction

Wireless Channels

N = 5000000
EbNodB_range = range(11)
itr = len(EbNodB_range)
ber = [None]*itr

for n in range (itr): 
    EbNodB = EbNodB_range[n]   
    EbNo=10.0**(EbNodB/10.0)
    x = 2 * (np.random.rand(N) >= 0.5) - 1
    noise_std = 1/np.sqrt(2*EbNo)
    y = x + noise_std * np.random.randn(N)
    y_d = 2 * (y >= 0) - 1
    errors = (x != y_d).sum()
    ber[n] = 1.0 * errors / N

plt.figure()
plt.plot(EbNodB_range, ber, 'bo', EbNodB_range, ber, 'k')
plt.axis([0, 10, 1e-6, 0.1])
plt.xscale('linear')
plt.yscale('log')
plt.xlabel('EbNo(dB)')
plt.ylabel('BER')
plt.grid(True)
plt.title('BPSK Modulation')
plt.show()

png

References