Pour ceux qui essaient de faire la connexion entre SNR et une variable aléatoire normale générée par numpy:
[1]
, où il est important de garder à l'esprit que P est la puissance moyenne .
Ou en dB:
[2]
Dans ce cas, nous avons déjà un signal et nous voulons générer du bruit pour nous donner un SNR souhaité.
Bien que le bruit puisse prendre différentes saveurs en fonction de ce que vous modélisez, un bon début (en particulier pour cet exemple de radiotélescope) est le bruit gaussien blanc additif (AWGN) . Comme indiqué dans les réponses précédentes, pour modéliser l'AWGN, vous devez ajouter une variable aléatoire gaussienne de moyenne zéro à votre signal d'origine. La variance de cette variable aléatoire affectera la puissance moyenne du bruit.
Pour une variable aléatoire gaussienne X, la puissance moyenne
, également appelée second moment , est
[3] 
Donc pour le bruit blanc,
et la puissance moyenne est alors égale à la variance
.
Lors de la modélisation en python, vous pouvez soit
1. Calculer la variance en fonction d'un SNR souhaité et d'un ensemble de mesures existantes, ce qui fonctionnerait si vous vous attendez à ce que vos mesures aient des valeurs d'amplitude assez cohérentes.
2. Vous pouvez également régler la puissance du bruit à un niveau connu pour correspondre à quelque chose comme le bruit du récepteur. Le bruit du récepteur peut être mesuré en pointant le télescope dans l'espace libre et en calculant la puissance moyenne.
Dans tous les cas, il est important de vous assurer d'ajouter du bruit à votre signal et de prendre des moyennes dans l'espace linéaire et non en unités dB.
Voici un code pour générer un signal et tracer la tension, la puissance en watts et la puissance en dB:
import numpy as np
import matplotlib.pyplot as plt
t = np.linspace(1, 100, 1000)
x_volts = 10*np.sin(t/(2*np.pi))
plt.subplot(3,1,1)
plt.plot(t, x_volts)
plt.title('Signal')
plt.ylabel('Voltage (V)')
plt.xlabel('Time (s)')
plt.show()
x_watts = x_volts ** 2
plt.subplot(3,1,2)
plt.plot(t, x_watts)
plt.title('Signal Power')
plt.ylabel('Power (W)')
plt.xlabel('Time (s)')
plt.show()
x_db = 10 * np.log10(x_watts)
plt.subplot(3,1,3)
plt.plot(t, x_db)
plt.title('Signal Power in dB')
plt.ylabel('Power (dB)')
plt.xlabel('Time (s)')
plt.show()

Voici un exemple d'ajout d'AWGN basé sur un SNR souhaité:
target_snr_db = 20
sig_avg_watts = np.mean(x_watts)
sig_avg_db = 10 * np.log10(sig_avg_watts)
noise_avg_db = sig_avg_db - target_snr_db
noise_avg_watts = 10 ** (noise_avg_db / 10)
mean_noise = 0
noise_volts = np.random.normal(mean_noise, np.sqrt(noise_avg_watts), len(x_watts))
y_volts = x_volts + noise_volts
plt.subplot(2,1,1)
plt.plot(t, y_volts)
plt.title('Signal with noise')
plt.ylabel('Voltage (V)')
plt.xlabel('Time (s)')
plt.show()
y_watts = y_volts ** 2
y_db = 10 * np.log10(y_watts)
plt.subplot(2,1,2)
plt.plot(t, 10* np.log10(y_volts**2))
plt.title('Signal with noise (dB)')
plt.ylabel('Power (dB)')
plt.xlabel('Time (s)')
plt.show()

Et voici un exemple d'ajout d'AWGN basé sur une puissance de bruit connue:
target_noise_db = 10
target_noise_watts = 10 ** (target_noise_db / 10)
mean_noise = 0
noise_volts = np.random.normal(mean_noise, np.sqrt(target_noise_watts), len(x_watts))
y_volts = x_volts + noise_volts
plt.subplot(2,1,1)
plt.plot(t, y_volts)
plt.title('Signal with noise')
plt.ylabel('Voltage (V)')
plt.xlabel('Time (s)')
plt.show()
y_watts = y_volts ** 2
y_db = 10 * np.log10(y_watts)
plt.subplot(2,1,2)
plt.plot(t, 10* np.log10(y_volts**2))
plt.title('Signal with noise')
plt.ylabel('Power (dB)')
plt.xlabel('Time (s)')
plt.show()
