From a62e05c9564045044df734fd3723b3f665ad91ae Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Fri, 29 Dec 2017 06:43:49 +0100 Subject: DPD: Make logging to file optional in all modules, simplify apply_adapt_dumps --- dpd/apply_adapt_dumps.py | 132 ++----------------------------------------- dpd/dpd.ini | 2 +- dpd/main.py | 2 +- dpd/src/Adapt.py | 10 +++- dpd/src/Const.py | 6 +- dpd/src/Dab_Util.py | 15 +++-- dpd/src/ExtractStatistic.py | 8 ++- dpd/src/MER.py | 8 ++- dpd/src/Measure.py | 2 - dpd/src/Measure_Shoulders.py | 8 ++- dpd/src/Model.py | 6 ++ dpd/src/Model_AM.py | 8 ++- dpd/src/Model_Lut.py | 6 +- dpd/src/Model_PM.py | 8 ++- dpd/src/Model_Poly.py | 6 +- dpd/src/RX_Agc.py | 8 ++- dpd/src/Symbol_align.py | 4 +- dpd/src/TX_Agc.py | 5 +- dpd/src/phase_align.py | 7 ++- dpd/src/subsample_align.py | 8 ++- 20 files changed, 92 insertions(+), 167 deletions(-) (limited to 'dpd') diff --git a/dpd/apply_adapt_dumps.py b/dpd/apply_adapt_dumps.py index 6b15aff..f1f3359 100755 --- a/dpd/apply_adapt_dumps.py +++ b/dpd/apply_adapt_dumps.py @@ -6,38 +6,16 @@ # http://www.opendigitalradio.org # Licence: The MIT License, see notice at the end of this file -"""This Python script is the main file for ODR-DabMod's DPD Computation Engine. -This engine calculates and updates the parameter of the digital -predistortion module of ODR-DabMod.""" - import datetime import os -import matplotlib import glob -import natsort -matplotlib.use('GTKAgg') - import logging dt = datetime.datetime.now().isoformat() -logging_path = "/tmp/dpd_{}".format(dt).replace(".", "_").replace(":", "-") -os.makedirs(logging_path) logging.basicConfig(format='%(asctime)s - %(module)s - %(levelname)s - %(message)s', datefmt='%Y-%m-%d %H:%M:%S', - filename='{}/dpd.log'.format(logging_path), - filemode='w', level=logging.DEBUG) -# also log up to INFO to console -console = logging.StreamHandler() -console.setLevel(logging.INFO) -# set a format which is simpler for console use -formatter = logging.Formatter('%(asctime)s - %(module)s - %(levelname)s - %(message)s') -# tell the handler to use this format -console.setFormatter(formatter) -# add the handler to the root logger -logging.getLogger('').addHandler(console) - import src.Measure as Measure import src.Model as Model import src.ExtractStatistic as ExtractStatistic @@ -59,120 +37,22 @@ parser.add_argument('--port', default=50055, type=int, parser.add_argument('--rc-port', default=9400, type=int, help='port of ODR-DabMod ZMQ Remote Control to connect to (default: 9400)', required=False) -parser.add_argument('--samplerate', default=8192000, type=int, - help='Sample rate', - required=False) -parser.add_argument('--coefs', default='/tmp/poly.coef', +parser.add_argument('--coefs', default='poly.coef', help='File with DPD coefficients, which will be read by ODR-DabMod', required=False) -parser.add_argument('--txgain', default=75, - help='TX Gain', - required=False, - type=int) -parser.add_argument('--rxgain', default=30, - help='TX Gain', - required=False, - type=int) -parser.add_argument('--digital_gain', default=1, - help='Digital Gain', - required=False, - type=float) -parser.add_argument('--samps', default='81920', type=int, - help='Number of samples to request from ODR-DabMod', - required=False) -parser.add_argument('--target_median', default=0.1, - help='target_median', - required=False, - type=float) -parser.add_argument('--searchpath', default='./stored', type=str, - help='Path to search .pkl files with stored configuration' - 'for adapt', - required=False) -parser.add_argument('-L', '--lut', - help='Use lookup table instead of polynomial predistorter', - action="store_true") +parser.add_argument('file', help='File to read the DPD settings from') cli_args = parser.parse_args() port = cli_args.port port_rc = cli_args.rc_port coef_path = cli_args.coefs -digital_gain = cli_args.digital_gain -txgain = cli_args.txgain -rxgain = cli_args.rxgain -num_req = cli_args.samps -samplerate = cli_args.samplerate -searchpath = cli_args.searchpath -target_median = cli_args.target_median - -c = src.Const.Const(samplerate, target_median, False) -SA = src.Symbol_align.Symbol_align(c) -MER = src.MER.MER(c) -MS = src.Measure_Shoulders.Measure_Shoulders(c) - -meas = Measure.Measure(samplerate, port, num_req) -extStat = ExtractStatistic.ExtractStatistic(c) -adapt = Adapt.Adapt(port_rc, coef_path) -dpddata = adapt.get_predistorter - -if cli_args.lut: - model = Model.Lut(c) -else: - model = Model.Poly(c) -adapt.set_predistorter(model.get_dpd_data()) -adapt.set_digital_gain(digital_gain) -adapt.set_txgain(txgain) -adapt.set_rxgain(rxgain) - -tx_gain = adapt.get_txgain() -rx_gain = adapt.get_rxgain() -digital_gain = adapt.get_digital_gain() - -dpddata = adapt.get_predistorter() -if dpddata[0] == "poly": - coefs_am = dpddata[1] - coefs_pm = dpddata[2] - logging.info( - "TX gain {}, RX gain {}, dpd_coefs_am {}," - " dpd_coefs_pm {}, digital_gain {}".format( - tx_gain, rx_gain, coefs_am, coefs_pm, digital_gain - ) - ) -elif dpddata[0] == "lut": - scalefactor = dpddata[1] - lut = dpddata[2] - logging.info( - "TX gain {}, RX gain {}, LUT scalefactor {}," - " LUT {}, digital_gain {}".format( - tx_gain, rx_gain, scalefactor, lut, digital_gain - ) - ) -else: - logging.error("Unknown dpd data format {}".format(dpddata[0])) - -tx_agc = TX_Agc.TX_Agc(adapt, c) - -# Automatic Gain Control -agc = Agc.Agc(meas, adapt, c) -agc.run() - -paths = natsort.natsorted(glob.glob(searchpath + "/*.pkl")) -print(paths) - -for i, path in enumerate(paths): - print(i, path) - adapt.load(path) - dpddata_after = adapt.get_predistorter() - - coefs_am, coefs_pm = model.reset_coefs() - adapt.set_predistorter(("poly", coefs_am, coefs_pm)) - print("Loaded configuration without pre-distortion") +filename = cli_args.file - raw_input("Key for pre-distortion ") - adapt.set_predistorter(dpddata_after) - print("Pre-distortion done") +adapt = Adapt(port_rc, coef_path) - raw_input("Key for next ") +print("Loading and applying DPD settings from {}".format(filename)) +adapt.load(filename) # The MIT License (MIT) # diff --git a/dpd/dpd.ini b/dpd/dpd.ini index 7e4bd5f..af5c2fb 100644 --- a/dpd/dpd.ini +++ b/dpd/dpd.ini @@ -18,7 +18,7 @@ gainmode=var rate=8192000 # keep in mind that the DPDCE will set the digital gain through the RC! -digital_gain=0.6 +digital_gain=0.01 [firfilter] enabled=1 diff --git a/dpd/main.py b/dpd/main.py index 49c0d1d..e15c6b5 100755 --- a/dpd/main.py +++ b/dpd/main.py @@ -45,7 +45,7 @@ parser.add_argument('--digital_gain', default=0.6, required=False, type=float) parser.add_argument('--target_median', default=0.05, - help='target_median', + help='The target median for the RX and TX AGC', required=False, type=float) parser.add_argument('--samps', default='81920', type=int, diff --git a/dpd/src/Adapt.py b/dpd/src/Adapt.py index 7e19a2c..c78c920 100644 --- a/dpd/src/Adapt.py +++ b/dpd/src/Adapt.py @@ -16,7 +16,10 @@ import os import datetime import pickle -logging_path = os.path.dirname(logging.getLoggerClass().root.handlers[0].baseFilename) +try: + logging_path = os.path.dirname(logging.getLoggerClass().root.handlers[0].baseFilename) +except AttributeError: + logging_path = None LUT_LEN = 32 FORMAT_POLY = 1 @@ -226,7 +229,10 @@ class Adapt: """Backup current settings to a file""" dt = datetime.datetime.now().isoformat() if path is None: - path = logging_path + "/" + dt + "_adapt.pkl" + if logging_path is not None: + path = logging_path + "/" + dt + "_adapt.pkl" + else: + raise Exception("Cannot dump Adapt without either logging_path or path set") d = { "txgain": self.get_txgain(), "rxgain": self.get_rxgain(), diff --git a/dpd/src/Const.py b/dpd/src/Const.py index 6c9bafa..d80cfac 100644 --- a/dpd/src/Const.py +++ b/dpd/src/Const.py @@ -73,14 +73,14 @@ class Const: self.MPM_tx_min = 0.1 # Constants for TX_Agc - self.TAGC_max_txgain = 89 # USRP specific + self.TAGC_max_txgain = 89 # USRP B200 specific self.TAGC_tx_median_target = target_median self.TAGC_tx_median_max = self.TAGC_tx_median_target * 1.4 self.TAGC_tx_median_min = self.TAGC_tx_median_target / 1.4 # Constants for RX_AGC - self.RAGC_min_rxgain = 25 # USRP specific - self.RAGC_rx_median_target = self.TAGC_tx_median_target + self.RAGC_min_rxgain = 25 # USRP B200 specific + self.RAGC_rx_median_target = target_median # The MIT License (MIT) # diff --git a/dpd/src/Dab_Util.py b/dpd/src/Dab_Util.py index 2021f38..56c9503 100644 --- a/dpd/src/Dab_Util.py +++ b/dpd/src/Dab_Util.py @@ -9,7 +9,10 @@ import datetime import os import logging -logging_path = os.path.dirname(logging.getLoggerClass().root.handlers[0].baseFilename) +try: + logging_path = os.path.dirname(logging.getLoggerClass().root.handlers[0].baseFilename) +except AttributeError: + logging_path = None import numpy as np import matplotlib @@ -53,7 +56,7 @@ class Dab_Util: off = sig_rec.shape[0] c = np.abs(signal.correlate(sig_orig, sig_rec)) - if logging.getLogger().getEffectiveLevel() == logging.DEBUG and self.plot: + if logging.getLogger().getEffectiveLevel() == logging.DEBUG and self.plot and logging_path is not None: dt = datetime.datetime.now().isoformat() corr_path = (logging_path + "/" + dt + "_tx_rx_corr.svg") plt.plot(c, label="corr") @@ -107,7 +110,7 @@ class Dab_Util: Returns an aligned version of sig_tx and sig_rx by cropping and subsample alignment """ - if logging.getLogger().getEffectiveLevel() == logging.DEBUG and self.plot: + if logging.getLogger().getEffectiveLevel() == logging.DEBUG and self.plot and logging_path is not None: dt = datetime.datetime.now().isoformat() fig_path = logging_path + "/" + dt + "_sync_raw.svg" @@ -151,7 +154,7 @@ class Dab_Util: sig_tx = sig_tx[:-1] sig_rx = sig_rx[:-1] - if logging.getLogger().getEffectiveLevel() == logging.DEBUG and self.plot: + if logging.getLogger().getEffectiveLevel() == logging.DEBUG and self.plot and logging_path is not None: dt = datetime.datetime.now().isoformat() fig_path = logging_path + "/" + dt + "_sync_sample_aligned.svg" @@ -175,7 +178,7 @@ class Dab_Util: sig_rx = sa.subsample_align(sig_rx, sig_tx) - if logging.getLogger().getEffectiveLevel() == logging.DEBUG and self.plot: + if logging.getLogger().getEffectiveLevel() == logging.DEBUG and self.plot and logging_path is not None: dt = datetime.datetime.now().isoformat() fig_path = logging_path + "/" + dt + "_sync_subsample_aligned.svg" @@ -199,7 +202,7 @@ class Dab_Util: sig_rx = pa.phase_align(sig_rx, sig_tx) - if logging.getLogger().getEffectiveLevel() == logging.DEBUG and self.plot: + if logging.getLogger().getEffectiveLevel() == logging.DEBUG and self.plot and logging_path is not None: dt = datetime.datetime.now().isoformat() fig_path = logging_path + "/" + dt + "_sync_phase_aligned.svg" diff --git a/dpd/src/ExtractStatistic.py b/dpd/src/ExtractStatistic.py index d27cd77..e917909 100644 --- a/dpd/src/ExtractStatistic.py +++ b/dpd/src/ExtractStatistic.py @@ -12,8 +12,10 @@ import matplotlib.pyplot as plt import datetime import os import logging - -logging_path = os.path.dirname(logging.getLoggerClass().root.handlers[0].baseFilename) +try: + logging_path = os.path.dirname(logging.getLoggerClass().root.handlers[0].baseFilename) +except AttributeError: + logging_path = None def _check_input_extract(tx_dpd, rx_received): @@ -64,7 +66,7 @@ class ExtractStatistic: self.plot = c.ES_plot def _plot_and_log(self, tx_values, rx_values, phase_diffs_values, phase_diffs_values_lists): - if logging.getLogger().getEffectiveLevel() == logging.DEBUG and self.plot: + if logging.getLogger().getEffectiveLevel() == logging.DEBUG and self.plot and logging_path is not None: dt = datetime.datetime.now().isoformat() fig_path = logging_path + "/" + dt + "_ExtractStatistic.png" diff --git a/dpd/src/MER.py b/dpd/src/MER.py index f186261..a4c3591 100644 --- a/dpd/src/MER.py +++ b/dpd/src/MER.py @@ -11,7 +11,7 @@ import logging try: logging_path = os.path.dirname(logging.getLoggerClass().root.handlers[0].baseFilename) except: - logging_path = "/tmp/" + logging_path = None import numpy as np import matplotlib @@ -76,9 +76,11 @@ class MER: spectrum = self._calc_spectrum(tx) - if self.plot: + if self.plot and logging_path is not None: dt = datetime.datetime.now().isoformat() fig_path = logging_path + "/" + dt + "_MER" + debug_name + ".svg" + else: + fig_path = None MERs = [] for i, (x, y) in enumerate(self._split_in_carrier( @@ -103,7 +105,7 @@ class MER: ylim = ax.get_ylim() ax.set_ylim(ylim[0] - (ylim[1] - ylim[0]) * 0.1, ylim[1]) - if self.plot: + if fig_path is not None: plt.tight_layout() plt.savefig(fig_path) plt.show() diff --git a/dpd/src/Measure.py b/dpd/src/Measure.py index d4b1d9e..e4333d9 100644 --- a/dpd/src/Measure.py +++ b/dpd/src/Measure.py @@ -11,9 +11,7 @@ import struct import numpy as np import src.Dab_Util as DU import os - import logging -logging_path = os.path.dirname(logging.getLoggerClass().root.handlers[0].baseFilename) class Measure: """Collect Measurement from DabMod""" diff --git a/dpd/src/Measure_Shoulders.py b/dpd/src/Measure_Shoulders.py index c733dfd..2249ac6 100644 --- a/dpd/src/Measure_Shoulders.py +++ b/dpd/src/Measure_Shoulders.py @@ -10,7 +10,10 @@ import os import logging import multiprocessing -logging_path = os.path.dirname(logging.getLoggerClass().root.handlers[0].baseFilename) +try: + logging_path = os.path.dirname(logging.getLoggerClass().root.handlers[0].baseFilename) +except AttributeError: + logging_path = None import numpy as np import matplotlib.pyplot as plt @@ -79,6 +82,9 @@ class Measure_Shoulders: self.plot = c.MS_plot def _plot(self, signal): + if logging_path is None: + return + dt = datetime.datetime.now().isoformat() fig_path = logging_path + "/" + dt + "_sync_subsample_aligned.svg" diff --git a/dpd/src/Model.py b/dpd/src/Model.py index 67feeb6..b2c303f 100644 --- a/dpd/src/Model.py +++ b/dpd/src/Model.py @@ -2,6 +2,12 @@ from src.Model_Poly import Poly from src.Model_Lut import Lut +def select_model_from_dpddata(dpddata): + if dpddata[0] == 'lut': + return Lut + elif dpddata[0] == 'poly': + return Poly + # The MIT License (MIT) # # Copyright (c) 2017 Andreas Steger diff --git a/dpd/src/Model_AM.py b/dpd/src/Model_AM.py index d7e880c..596ca4a 100644 --- a/dpd/src/Model_AM.py +++ b/dpd/src/Model_AM.py @@ -8,8 +8,10 @@ import datetime import os import logging - -logging_path = os.path.dirname(logging.getLoggerClass().root.handlers[0].baseFilename) +try: + logging_path = os.path.dirname(logging.getLoggerClass().root.handlers[0].baseFilename) +except AttributeError: + logging_path = None import numpy as np import matplotlib.pyplot as plt @@ -55,7 +57,7 @@ class Model_AM: self.plot = plot def _plot(self, tx_dpd, rx_received, coefs_am, coefs_am_new): - if logging.getLogger().getEffectiveLevel() == logging.DEBUG and self.plot: + if logging.getLogger().getEffectiveLevel() == logging.DEBUG and self.plot and logging_path is not None: tx_range, rx_est = calc_line(coefs_am, 0, 0.6) tx_range_new, rx_est_new = calc_line(coefs_am_new, 0, 0.6) diff --git a/dpd/src/Model_Lut.py b/dpd/src/Model_Lut.py index 6d4db52..b349433 100644 --- a/dpd/src/Model_Lut.py +++ b/dpd/src/Model_Lut.py @@ -7,8 +7,10 @@ import os import logging - -logging_path = os.path.dirname(logging.getLoggerClass().root.handlers[0].baseFilename) +try: + logging_path = os.path.dirname(logging.getLoggerClass().root.handlers[0].baseFilename) +except AttributeError: + logging_path = None import numpy as np diff --git a/dpd/src/Model_PM.py b/dpd/src/Model_PM.py index d4f8c00..e721d1a 100644 --- a/dpd/src/Model_PM.py +++ b/dpd/src/Model_PM.py @@ -8,8 +8,10 @@ import datetime import os import logging - -logging_path = os.path.dirname(logging.getLoggerClass().root.handlers[0].baseFilename) +try: + logging_path = os.path.dirname(logging.getLoggerClass().root.handlers[0].baseFilename) +except AttributeError: + logging_path = None import numpy as np import matplotlib.pyplot as plt @@ -41,7 +43,7 @@ class Model_PM: self.plot = plot def _plot(self, tx_dpd, phase_diff, coefs_pm, coefs_pm_new): - if logging.getLogger().getEffectiveLevel() == logging.DEBUG and self.plot: + if logging.getLogger().getEffectiveLevel() == logging.DEBUG and self.plot and logging_path is not None: tx_range, phase_diff_est = self.calc_line(coefs_pm, 0, 0.6) tx_range_new, phase_diff_est_new = self.calc_line(coefs_pm_new, 0, 0.6) diff --git a/dpd/src/Model_Poly.py b/dpd/src/Model_Poly.py index ff15941..1cf8ecd 100644 --- a/dpd/src/Model_Poly.py +++ b/dpd/src/Model_Poly.py @@ -7,8 +7,10 @@ import os import logging - -logging_path = os.path.dirname(logging.getLoggerClass().root.handlers[0].baseFilename) +try: + logging_path = os.path.dirname(logging.getLoggerClass().root.handlers[0].baseFilename) +except AttributeError: + logging_path = None import numpy as np diff --git a/dpd/src/RX_Agc.py b/dpd/src/RX_Agc.py index 670fbbb..7b5e0b6 100644 --- a/dpd/src/RX_Agc.py +++ b/dpd/src/RX_Agc.py @@ -9,7 +9,10 @@ import datetime import os import logging import time -logging_path = os.path.dirname(logging.getLoggerClass().root.handlers[0].baseFilename) +try: + logging_path = os.path.dirname(logging.getLoggerClass().root.handlers[0].baseFilename) +except AttributeError: + logging_path = None import numpy as np import matplotlib @@ -70,6 +73,9 @@ class Agc: def plot_estimates(self): """Plots the estimate of for Max, Median, Mean for different number of samples.""" + if logging_path is None: + return + self.adapt.set_rxgain(self.min_rxgain) time.sleep(1) diff --git a/dpd/src/Symbol_align.py b/dpd/src/Symbol_align.py index d921f25..f2802ee 100644 --- a/dpd/src/Symbol_align.py +++ b/dpd/src/Symbol_align.py @@ -12,7 +12,7 @@ import logging try: logging_path = os.path.dirname(logging.getLoggerClass().root.handlers[0].baseFilename) except: - logging_path = "/tmp/" + logging_path = None import numpy as np import scipy @@ -75,7 +75,7 @@ class Symbol_align: offset = peaks[np.argmin([tx_product_avg[peak] for peak in peaks])] - if logging.getLogger().getEffectiveLevel() == logging.DEBUG and self.plot: + if logging.getLogger().getEffectiveLevel() == logging.DEBUG and self.plot and logging_path is not None: dt = datetime.datetime.now().isoformat() fig_path = logging_path + "/" + dt + "_Symbol_align.svg" diff --git a/dpd/src/TX_Agc.py b/dpd/src/TX_Agc.py index 3c804fa..7555450 100644 --- a/dpd/src/TX_Agc.py +++ b/dpd/src/TX_Agc.py @@ -10,7 +10,10 @@ import os import logging import time -logging_path = os.path.dirname(logging.getLoggerClass().root.handlers[0].baseFilename) +try: + logging_path = os.path.dirname(logging.getLoggerClass().root.handlers[0].baseFilename) +except AttributeError: + logging_path = None import numpy as np import matplotlib diff --git a/dpd/src/phase_align.py b/dpd/src/phase_align.py index 68c216d..21a210c 100644 --- a/dpd/src/phase_align.py +++ b/dpd/src/phase_align.py @@ -7,7 +7,10 @@ import datetime import os import logging -logging_path = os.path.dirname(logging.getLoggerClass().root.handlers[0].baseFilename) +try: + logging_path = os.path.dirname(logging.getLoggerClass().root.handlers[0].baseFilename) +except AttributeError: + logging_path = None import numpy as np import matplotlib.pyplot as plt @@ -24,7 +27,7 @@ def phase_align(sig, ref_sig, plot=False): real_diffs = np.cos(angle_diff) imag_diffs = np.sin(angle_diff) - if logging.getLogger().getEffectiveLevel() == logging.DEBUG and plot: + if logging.getLogger().getEffectiveLevel() == logging.DEBUG and plot and logging_path is not None: dt = datetime.datetime.now().isoformat() fig_path = logging_path + "/" + dt + "_phase_align.svg" diff --git a/dpd/src/subsample_align.py b/dpd/src/subsample_align.py index 68f3591..a5e9f8c 100755 --- a/dpd/src/subsample_align.py +++ b/dpd/src/subsample_align.py @@ -7,8 +7,10 @@ import datetime import logging import os - -logging_path = os.path.dirname(logging.getLoggerClass().root.handlers[0].baseFilename) +try: + logging_path = os.path.dirname(logging.getLoggerClass().root.handlers[0].baseFilename) +except AttributeError: + logging_path = None import numpy as np from scipy import optimize @@ -72,7 +74,7 @@ def subsample_align(sig, ref_sig, plot=False): if optim_result.success: best_tau = optim_result.x - if plot: + if plot and logging_path is not None: corr = np.vectorize(correlate_for_delay) ixs = np.linspace(-1, 1, 100) taus = corr(ixs) -- cgit v1.2.3