aboutsummaryrefslogtreecommitdiffstats
path: root/dpd/src/Measure_Shoulders.py
diff options
context:
space:
mode:
authorMatthias P. Braendli <matthias.braendli@mpb.li>2018-12-04 10:18:33 +0100
committerMatthias P. Braendli <matthias.braendli@mpb.li>2018-12-04 10:18:33 +0100
commitd5cbe10c0e2298b0e40161607a3da158249bdb82 (patch)
tree5f6a0ff40ce5b3dd39d0df1c348557b183b48a7e /dpd/src/Measure_Shoulders.py
parent594cb2691debaa7562fd7d76d3b224701ec087ea (diff)
downloaddabmod-d5cbe10c0e2298b0e40161607a3da158249bdb82.tar.gz
dabmod-d5cbe10c0e2298b0e40161607a3da158249bdb82.tar.bz2
dabmod-d5cbe10c0e2298b0e40161607a3da158249bdb82.zip
Move python stuff to folder
Diffstat (limited to 'dpd/src/Measure_Shoulders.py')
-rw-r--r--dpd/src/Measure_Shoulders.py158
1 files changed, 0 insertions, 158 deletions
diff --git a/dpd/src/Measure_Shoulders.py b/dpd/src/Measure_Shoulders.py
deleted file mode 100644
index fd90050..0000000
--- a/dpd/src/Measure_Shoulders.py
+++ /dev/null
@@ -1,158 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# DPD Computation Engine, calculate peak to shoulder difference.
-#
-# http://www.opendigitalradio.org
-# Licence: The MIT License, see notice at the end of this file
-
-import datetime
-import os
-import logging
-import multiprocessing
-import numpy as np
-import matplotlib.pyplot as plt
-
-
-def plt_next_axis(sub_rows, sub_cols, i_sub):
- i_sub += 1
- ax = plt.subplot(sub_rows, sub_cols, i_sub)
- return i_sub, ax
-
-
-def plt_annotate(ax, x, y, title=None, legend_loc=None):
- ax.set_xlabel(x)
- ax.set_ylabel(y)
- if title is not None:
- ax.set_title(title)
- if legend_loc is not None:
- ax.legend(loc=legend_loc)
-
-
-def calc_fft_db(signal, offset, c):
- fft = np.fft.fftshift(np.fft.fft(signal[offset:offset + c.MS_FFT_size]))
- fft_db = 20 * np.log10(np.abs(fft))
- return fft_db
-
-
-def _calc_peak(fft, c):
- assert fft.shape == (c.MS_FFT_size,), fft.shape
- idxs = (c.MS_peak_start, c.MS_peak_end)
- peak = np.mean(fft[idxs[0]:idxs[1]])
- return peak, idxs
-
-
-def _calc_shoulder_hight(fft_db, c):
- assert fft_db.shape == (c.MS_FFT_size,), fft_db.shape
- idxs_left = (c.MS_shoulder_left_start, c.MS_shoulder_left_end)
- idxs_right = (c.MS_shoulder_right_start, c.MS_shoulder_right_end)
-
- shoulder_left = np.mean(fft_db[idxs_left[0]:idxs_left[1]])
- shoulder_right = np.mean(fft_db[idxs_right[0]:idxs_right[1]])
-
- shoulder = np.mean((shoulder_left, shoulder_right))
- return shoulder, (idxs_left, idxs_right)
-
-
-def calc_shoulder(fft, c):
- peak = _calc_peak(fft, c)[0]
- shoulder = _calc_shoulder_hight(fft, c)[0]
- assert (peak >= shoulder), (peak, shoulder)
- return peak, shoulder
-
-
-def shoulder_from_sig_offset(arg):
- signal, offset, c = arg
- fft_db = calc_fft_db(signal, offset, c)
- peak, shoulder = calc_shoulder(fft_db, c)
- return peak - shoulder, peak, shoulder
-
-
-class Measure_Shoulders:
- """Calculate difference between the DAB signal and the shoulder hight in the
- power spectrum"""
-
- def __init__(self, c):
- self.c = c
- self.plot = c.MS_plot
-
- def _plot(self, signal):
- if self.c.plot_location is None:
- return
-
- dt = datetime.datetime.now().isoformat()
- fig_path = self.c.plot_location + "/" + dt + "_sync_subsample_aligned.png"
-
- fft = calc_fft_db(signal, 100, self.c)
- peak, idxs_peak = _calc_peak(fft, self.c)
- shoulder, idxs_sh = _calc_shoulder_hight(fft, self.c)
-
- sub_rows = 1
- sub_cols = 1
- fig = plt.figure(figsize=(sub_cols * 6, sub_rows / 2. * 6))
- i_sub = 0
-
- i_sub, ax = plt_next_axis(sub_rows, sub_cols, i_sub)
- ax.scatter(np.arange(fft.shape[0]), fft, s=0.1,
- label="FFT",
- color="red")
- ax.plot(idxs_peak, (peak, peak))
- ax.plot(idxs_sh[0], (shoulder, shoulder), color='blue')
- ax.plot(idxs_sh[1], (shoulder, shoulder), color='blue')
- plt_annotate(ax, "Frequency", "Magnitude [dB]", None, 4)
-
- ax.text(100, -17, str(calc_shoulder(fft, self.c)))
-
- ax.set_ylim(-20, 30)
- fig.tight_layout()
- fig.savefig(fig_path)
- plt.close(fig)
-
- def average_shoulders(self, signal, n_avg=None):
- if not self.c.MS_enable:
- logging.info("Shoulder Measurement disabled via Const.py")
- return None
-
- assert signal.shape[0] > 4 * self.c.MS_FFT_size
- if n_avg is None:
- n_avg = self.c.MS_averaging_size
-
- off_min = 0
- off_max = signal.shape[0] - self.c.MS_FFT_size
- offsets = np.linspace(off_min, off_max, num=n_avg, dtype=int)
-
- args = zip(
- [signal, ] * offsets.shape[0],
- offsets,
- [self.c, ] * offsets.shape[0]
- )
-
- pool = multiprocessing.Pool(self.c.MS_n_proc)
- res = pool.map(shoulder_from_sig_offset, args)
- shoulders_diff, shoulders, peaks = zip(*res)
-
- if logging.getLogger().getEffectiveLevel() == logging.DEBUG and self.plot:
- self._plot(signal)
-
- return np.mean(shoulders_diff), np.mean(shoulders), np.mean(peaks)
-
-# The MIT License (MIT)
-#
-# Copyright (c) 2017 Andreas Steger
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in all
-# copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-# SOFTWARE.