Signal to Noise Ratio Determination
Difficulty Level:
Tags pre-process☁quality☁noise☁snr

SNR, standing for Signal to Noise Ratio , is an estimation of how much noise there is in a digital signal. All digital signals can be divided in two main elements: the relevant data that we meant to record and the non relevant noise that got unavoidably recorded along with it. An ideal signal would have a very high SNR value. The higher the value, the less noise there is in the signal. However this is not always easy to achieve in real life.

Because the presence of noise usually shadows the "real" and relevant data we want to analyse, it is important to be able to filter as much noise as possible without unwillingly removing relevant pieces of information. There is already a really interesting Jupyter Notebook explaining the process of digital filtering electrophysiological signals, which you can find here .

In this Jupyter Notebook , however, we will focus on how to estimate the SNR in a digital signal, therefore determining the quality of the recording.

1 - Importation of the needed packages

In [1]:
# biosignalsnotebooks own package for loading and plotting the acquired data
import biosignalsnotebooks as bsnb

# Scientific packages
from numpy import array, linspace, mean, log10
from scipy.signal import butter, filtfilt
In [2]:
# Base packages used in OpenSignals Tools Notebooks for plotting data
from bokeh.plotting import figure, output_file, show, curdoc
from bokeh.io import output_notebook
from bokeh.layouts import column
from bokeh.models import ColumnDataSource, Plot, LinearAxis, BoxAnnotation, Arrow, VeeHead, LinearAxis, Range1d
output_notebook(hide_banner=True)

2 - Load of sample signal data

In [3]:
# Load of data (using a relative path to the project folder)
data, header = bsnb.load("/signal_samples/eeg_sample_artefacts_seg1.h5", get_header=True)

3 - Storage of sampling frequency and acquired data inside variables

Since in this case we know that the original signal is an EEG recording, we can also convert its units to $\mu V$ following the method explained in the EEG Sensor - Unit Conversion notebook.

In [4]:
# Sampling frequency and acquired data
fs = header["sampling rate"]

# Let's get de raw signal data and the time range of the recording
channel = list(data.keys())[0]
signal_raw = data[channel]
time = linspace(0, len(signal_raw) / fs, len(signal_raw))

# Let's convert the signal's units, since we know it is a ECG signal
vcc = 3e6 # uV
gain = 40000
resolution = header['resolution'] # Resolution (number of available bits)
signal = (((array(signal_raw) / 2**resolution) - 0.5) * vcc) / gain
In [5]:
# Let's plot our raw signal
p = figure(plot_width=1200, plot_height=200, x_axis_label="Time (s)", y_axis_label="EEG (\u03BCV)", **bsnb.opensignals_kwargs("figure"))
p.ygrid.grid_line_alpha=0.5

# add a circle renderer with x and y coordinates, size, color, and alpha
p.line(time, signal, **bsnb.opensignals_kwargs("line"))

# apply OpenSignals style
bsnb.opensignals_style([p])

show(p) # show the results