Pour ceux qui essaient de faire le lien 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 moyennement le pouvoir.
Ou en dB :
[2]
Dans ce cas, nous avons déjà un signal et nous voulons générer du bruit pour obtenir le SNR souhaité.
Le bruit peut se présenter sous différentes formes saveurs en fonction de ce que vous modélisez, un bon début (surtout pour cet exemple de radiotélescope) est Bruit blanc gaussien 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 nulle à votre signal original. La variance de cette variable aléatoire affectera la valeur de moyennement la puissance sonore.
Pour une variable aléatoire gaussienne X, la puissance moyenne aussi connu comme le deuxième moment c'est
[3]
Donc pour le bruit blanc, et la puissance moyenne est alors égale à la variance .
Pour modéliser cela en python, vous pouvez soit
1. Calculez la variance sur la base d'un SNR souhaité et d'un ensemble de mesures existantes, ce qui fonctionne 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 s'assurer que vous ajoutez du bruit à votre signal et que vous prenez 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 :
# Signal Generation
# matplotlib inline
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 en fonction d'un SNR souhaité :
# Adding noise using target SNR
# Set a target SNR
target_snr_db = 20
# Calculate signal power and convert to dB
sig_avg_watts = np.mean(x_watts)
sig_avg_db = 10 * np.log10(sig_avg_watts)
# Calculate noise according to [2] then convert to watts
noise_avg_db = sig_avg_db - target_snr_db
noise_avg_watts = 10 ** (noise_avg_db / 10)
# Generate an sample of white noise
mean_noise = 0
noise_volts = np.random.normal(mean_noise, np.sqrt(noise_avg_watts), len(x_watts))
# Noise up the original signal
y_volts = x_volts + noise_volts
# Plot signal with noise
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()
# Plot in dB
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 :
# Adding noise using a target noise power
# Set a target channel noise power to something very noisy
target_noise_db = 10
# Convert to linear Watt units
target_noise_watts = 10 ** (target_noise_db / 10)
# Generate noise samples
mean_noise = 0
noise_volts = np.random.normal(mean_noise, np.sqrt(target_noise_watts), len(x_watts))
# Noise up the original signal (again) and plot
y_volts = x_volts + noise_volts
# Plot signal with noise
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()
# Plot in dB
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()