summaryrefslogtreecommitdiffstats
path: root/dpd/src/Symbol_align.py
diff options
context:
space:
mode:
Diffstat (limited to 'dpd/src/Symbol_align.py')
-rw-r--r--dpd/src/Symbol_align.py67
1 files changed, 36 insertions, 31 deletions
diff --git a/dpd/src/Symbol_align.py b/dpd/src/Symbol_align.py
index e21e793..4ea79c5 100644
--- a/dpd/src/Symbol_align.py
+++ b/dpd/src/Symbol_align.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
-# Modulation Error Rate
+# DPD Calculation Engine, Modulation Error Rate.
#
# http://www.opendigitalradio.org
# Licence: The MIT License, see notice at the end of this file
@@ -8,24 +8,50 @@
import datetime
import os
import logging
-import time
+
try:
logging_path = os.path.dirname(logging.getLoggerClass().root.handlers[0].baseFilename)
except:
logging_path = "/tmp/"
import numpy as np
-import src.Const
import scipy
import matplotlib
+
matplotlib.use('agg')
import matplotlib.pyplot as plt
+
+def _remove_outliers(x, stds=5):
+ deviation_from_mean = np.abs(x - np.mean(x))
+ inlier_idxs = deviation_from_mean < stds * np.std(x)
+ x = x[inlier_idxs]
+ return x
+
+
+def _calc_delta_angle(fft):
+ # Introduce invariance against carrier
+ angles = np.angle(fft) % (np.pi / 2.)
+
+ # Calculate Angle difference and compensate jumps
+ deltas_angle = np.diff(angles)
+ deltas_angle[deltas_angle > np.pi / 4.] = \
+ deltas_angle[deltas_angle > np.pi / 4.] - np.pi / 2.
+ deltas_angle[-deltas_angle > np.pi / 4.] = \
+ deltas_angle[-deltas_angle > np.pi / 4.] + np.pi / 2.
+ deltas_angle = _remove_outliers(deltas_angle)
+
+ delta_angle = np.mean(deltas_angle)
+
+ return delta_angle
+
+
class Symbol_align:
"""
Find the phase offset to the start of the DAB symbols in an
unaligned dab signal.
"""
+
def __init__(self, c, plot=False):
self.c = c
self.plot = plot
@@ -95,8 +121,8 @@ class Symbol_align:
ax.set_title("Min Filter")
ax = fig.add_subplot(4, 1, 4)
- tx_product_crop = tx_product[peaks[0]-50:peaks[0]+50]
- x = range(tx_product.shape[0])[peaks[0]-50:peaks[0]+50]
+ tx_product_crop = tx_product[peaks[0] - 50:peaks[0] + 50]
+ x = range(tx_product.shape[0])[peaks[0] - 50:peaks[0] + 50]
ax.plot(x, tx_product_crop)
ylim = ax.get_ylim()
ax.plot((peaks[0], peaks[0]), (ylim[0], ylim[1]))
@@ -113,38 +139,16 @@ class Symbol_align:
# of the shift to find the offset of the symbol start.
return (offset + self.c.T_C) % self.c.T_S
- def _remove_outliers(self, x, stds=5):
- deviation_from_mean = np.abs(x - np.mean(x))
- inlier_idxs = deviation_from_mean < stds * np.std(x)
- x = x[inlier_idxs]
- return x
-
- def _calc_delta_angle(self, fft):
- # Introduce invariance against carrier
- angles = np.angle(fft) % (np.pi / 2.)
-
- # Calculate Angle difference and compensate jumps
- deltas_angle = np.diff(angles)
- deltas_angle[deltas_angle > np.pi/4.] =\
- deltas_angle[deltas_angle > np.pi/4.] - np.pi/2.
- deltas_angle[-deltas_angle > np.pi/4.] = \
- deltas_angle[-deltas_angle > np.pi/4.] + np.pi/2.
- deltas_angle = self._remove_outliers(deltas_angle)
-
- delta_angle = np.mean(deltas_angle)
-
- return delta_angle
-
def _delta_angle_to_samples(self, angle):
return - angle / self.c.phase_offset_per_sample
- def _calc_sample_offset(self, sig, debug=False):
- assert sig.shape[0] == self.c.T_U,\
+ def _calc_sample_offset(self, sig):
+ assert sig.shape[0] == self.c.T_U, \
"Input length is not a Symbol without cyclic prefix"
fft = np.fft.fftshift(np.fft.fft(sig))
fft_crop = np.delete(fft[self.c.FFT_start:self.c.FFT_end], self.c.FFT_delete)
- delta_angle = self._calc_delta_angle(fft_crop)
+ delta_angle = _calc_delta_angle(fft_crop)
delta_sample = self._delta_angle_to_samples(delta_angle)
delta_sample_int = np.round(delta_sample).astype(int)
error = np.abs(delta_sample_int - delta_sample)
@@ -154,6 +158,7 @@ class Symbol_align:
return delta_sample_int
def calc_offset(self, tx):
+ """Calculate the offset the first symbol"""
off_sym = self._calc_offset_to_first_symbol_without_prefix(
tx)
off_sam = self._calc_sample_offset(
@@ -168,7 +173,7 @@ class Symbol_align:
off = self.calc_offset(tx)
return tx[
off:
- off+self.c.T_U
+ off + self.c.T_U
]
# The MIT License (MIT)