summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dpd/README.md4
-rwxr-xr-xdpd/apply_adapt_dumps.py2
-rw-r--r--dpd/environment.yml20
-rwxr-xr-xdpd/main.py114
-rw-r--r--dpd/src/Const.py16
-rw-r--r--dpd/src/ExtractStatistic.py6
-rw-r--r--dpd/src/Heuristics.py4
-rw-r--r--dpd/src/TX_Agc.py2
-rw-r--r--dpd/src/Test_data.py2
9 files changed, 88 insertions, 82 deletions
diff --git a/dpd/README.md b/dpd/README.md
index 77c53bd..4f92ecb 100644
--- a/dpd/README.md
+++ b/dpd/README.md
@@ -87,11 +87,11 @@ ODR-DabMod/odr-dabmod dpd/dpd.ini
The script uses automatic gain control for both TX and RX gain, to get both a high quantization quality for the most frequent amplitude regions and a high enough back-off so the peaks are also quantized correctly. This means that the output power will stay at the same level, but the script may change TX gain to trade it with digital gain and also change RX gain.
-As a first test you can run the main script without parameters. It preserves the output power and generates all available visualization plots in the newly created logging directory `/tmp/dpd_<time_stamp>`. As the script should increase the preak to shoulder ratio, tune the txgain in a way to be able to see a the change. For example to a ratio of -30dB. You can do this using the telnet remote control from `odr-dabmod`. To run it do following:
+As a first test you can run the main script with the *--plot* parameter. It preserves the output power and generates all available visualization plots in the newly created logging directory `/tmp/dpd_<time_stamp>`. As the script should increase the preak to shoulder ratio, tune the txgain in a way to be able to see a the change. For example to a ratio of -30dB. You can do this using the telnet remote control from `odr-dabmod`. To run it do following:
```
cd dpd
-python main.py
+python main.py --plot
```
Each plot is stored to the logging directory under a filename containing its time stamp and its label. Following plots are generated chronologically:
diff --git a/dpd/apply_adapt_dumps.py b/dpd/apply_adapt_dumps.py
index 790a64a..4dac657 100755
--- a/dpd/apply_adapt_dumps.py
+++ b/dpd/apply_adapt_dumps.py
@@ -105,7 +105,7 @@ samplerate = cli_args.samplerate
searchpath = cli_args.searchpath
target_median = cli_args.target_median
-c = src.Const.Const(samplerate, target_median, -1, -1, -1)
+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)
diff --git a/dpd/environment.yml b/dpd/environment.yml
index 5c19258..8abedb2 100644
--- a/dpd/environment.yml
+++ b/dpd/environment.yml
@@ -1,5 +1,6 @@
name: dab
channels:
+- jochym
- defaults
dependencies:
- _nb_ext_conf=0.4.0=py27_1
@@ -7,7 +8,7 @@ dependencies:
- backports=1.0=py27_0
- backports_abc=0.5=py27_0
- bleach=1.5.0=py27_0
-- cairo=1.14.8=0
+- cairo=1.12.18=6
- clyent=1.2.2=py27_0
- configparser=3.5.0=py27_0
- cycler=0.10.0=py27_0
@@ -16,13 +17,14 @@ dependencies:
- entrypoints=0.2.3=py27_0
- enum34=1.1.6=py27_0
- expat=2.1.0=0
-- fontconfig=2.12.1=3
+- fontconfig=2.11.1=6
- freetype=2.5.5=2
- functools32=3.2.3.2=py27_0
- get_terminal_size=1.0.0=py27_0
- glib=2.50.2=1
- gst-plugins-base=1.8.0=0
- gstreamer=1.8.0=0
+- harfbuzz=0.9.39=1
- html5lib=0.9999999=py27_0
- icu=54.1=0
- ipykernel=4.6.1=py27_0
@@ -30,7 +32,7 @@ dependencies:
- ipython_genutils=0.2.0=py27_0
- ipywidgets=6.0.0=py27_0
- jinja2=2.9.6=py27_0
-- jpeg=9b=0
+- jpeg=8d=2
- jsonschema=2.6.0=py27_0
- jupyter=1.0.0=py27_3
- jupyter_client=5.1.0=py27_0
@@ -60,16 +62,18 @@ dependencies:
- openssl=1.0.2k=2
- pandas=0.20.1=np112py27_0
- pandocfilters=1.4.1=py27_0
+- pango=1.39.0=0
- path.py=10.3.1=py27_0
- pathlib2=2.3.0=py27_0
- pcre=8.39=1
- pexpect=4.2.1=py27_0
- pickleshare=0.7.4=py27_0
- pip=9.0.1=py27_1
-- pixman=0.34.0=0
+- pixman=0.32.6=0
- plotly=2.0.9=py27_0
- prompt_toolkit=1.0.14=py27_0
- ptyprocess=0.5.2=py27_0
+- py2cairo=1.10.0=py27_2
- pycairo=1.10.0=py27_0
- pygments=2.2.0=py27_0
- pyparsing=2.1.4=py27_0
@@ -79,11 +83,12 @@ dependencies:
- pytz=2017.2=py27_0
- pyyaml=3.12=py27_0
- pyzmq=16.0.2=py27_0
-- qt=5.6.2=4
+- qt=5.6.2=0
- qtconsole=4.3.0=py27_0
- readline=6.2=2
- requests=2.14.2=py27_0
- scandir=1.5=py27_0
+- scikit-learn=0.18.1=np112py27_1
- scipy=0.19.0=np112py27_0
- setuptools=27.2.0=py27_0
- simplegeneric=0.8.1=py27_1
@@ -105,6 +110,11 @@ dependencies:
- yaml=0.1.6=0
- zeromq=4.1.5=0
- zlib=1.2.8=3
+- atk=2.8.0=0
+- gdk-pixbuf=2.28.2=0
+- gtk2=2.24.28=0
+- pygobject2=2.28.6=0
+- pygtk2=2.24.0=0
- pip:
- backports-abc==0.5
- backports.shutil-get-terminal-size==1.0.0
diff --git a/dpd/main.py b/dpd/main.py
index 5eaa81f..176f80f 100755
--- a/dpd/main.py
+++ b/dpd/main.py
@@ -12,45 +12,11 @@ predistortion module of ODR-DabMod."""
import datetime
import os
+import argparse
import matplotlib
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 numpy as np
-import traceback
-import src.Measure as Measure
-import src.Model as Model
-import src.ExtractStatistic as ExtractStatistic
-import src.Adapt as Adapt
-import src.Agc as Agc
-import src.TX_Agc as TX_Agc
-from src.Symbol_align import Symbol_align
-from src.Const import Const
-from src.MER import MER
-from src.Measure_Shoulders import Measure_Shoulders
-import argparse
-import src.Heuristics as Heur
parser = argparse.ArgumentParser(
description="DPD Computation Engine for ODR-DabMod")
@@ -91,16 +57,13 @@ parser.add_argument('-i', '--iterations', default=1, type=int,
parser.add_argument('-L', '--lut',
help='Use lookup table instead of polynomial predistorter',
action="store_true")
-parser.add_argument('--n_bins', default='64', type=int,
- required=False)
-parser.add_argument('--n_per_bin', default='128', type=int,
- required=False)
-parser.add_argument('--n_meas', default='20', type=int,
- help='Number of samples to request from ODR-DabMod',
- required=False)
+parser.add_argument('--plot',
+ help='Enable all plots, to be more selective choose plots in Const.py',
+ action="store_true")
+parser.add_argument('--name', default="", type=str,
+ help='Name of the logging directory')
cli_args = parser.parse_args()
-logging.info(cli_args)
port = cli_args.port
port_rc = cli_args.rc_port
@@ -112,24 +75,59 @@ num_iter = cli_args.iterations
target_median = cli_args.target_median
rxgain = cli_args.rxgain
txgain = cli_args.txgain
+name = cli_args.name
+plot = cli_args.plot
-n_bins = cli_args.n_bins
-n_per_bin = cli_args.n_per_bin
-n_meas = cli_args.n_meas
+# Logging
+import logging
-c = Const(samplerate, target_median, n_bins, n_per_bin, n_meas)
+dt = datetime.datetime.now().isoformat()
+logging_path = '/tmp/dpd_{}'.format(dt).replace('.', '_').replace(':', '-')
+if name: logging_path += '_' + name
+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)
+
+logging.info(cli_args)
+
+import numpy as np
+import traceback
+from src.Model import Lut, Poly
+import src.Heuristics as Heuristics
+from src.Measure import Measure
+from src.ExtractStatistic import ExtractStatistic
+from src.Adapt import Adapt
+from src.Agc import Agc
+from src.TX_Agc import TX_Agc
+from src.Symbol_align import Symbol_align
+from src.Const import Const
+from src.MER import MER
+from src.Measure_Shoulders import Measure_Shoulders
+
+c = Const(samplerate, target_median, plot)
SA = Symbol_align(c)
MER = MER(c)
MS = Measure_Shoulders(c)
-
-meas = Measure.Measure(samplerate, port, num_req)
-extStat = ExtractStatistic.ExtractStatistic(c)
-adapt = Adapt.Adapt(port_rc, coef_path)
+meas = Measure(samplerate, port, num_req)
+extStat = ExtractStatistic(c)
+adapt = Adapt(port_rc, coef_path)
if cli_args.lut:
- model = Model.Lut(c)
+ model = Lut(c)
else:
- model = Model.Poly(c)
+ model = Poly(c)
adapt.set_predistorter(model.get_dpd_data())
adapt.set_digital_gain(digital_gain)
@@ -171,10 +169,10 @@ elif dpddata[0] == "lut":
else:
logging.error("Unknown dpd data format {}".format(dpddata[0]))
-tx_agc = TX_Agc.TX_Agc(adapt, c)
+tx_agc = TX_Agc(adapt, c)
# Automatic Gain Control
-agc = Agc.Agc(meas, adapt, c)
+agc = Agc(meas, adapt, c)
agc.run()
state = "measure"
@@ -191,7 +189,7 @@ while i < num_iter:
# Extract usable data from measurement
tx, rx, phase_diff, n_per_bin = extStat.extract(txframe_aligned, rxframe_aligned)
- n_meas = Heur.get_n_meas(i)
+ n_meas = Heuristics.get_n_meas(i)
if extStat.n_meas >= n_meas: # Use as many measurements nr of runs
state = 'model'
else:
@@ -200,10 +198,10 @@ while i < num_iter:
# Model
elif state == 'model':
# Calculate new model parameters and delete old measurements
- lr = Heur.get_learning_rate(i)
+ lr = Heuristics.get_learning_rate(i)
model.train(tx, rx, phase_diff, lr=lr)
dpddata = model.get_dpd_data()
- extStat = ExtractStatistic.ExtractStatistic(c)
+ extStat = ExtractStatistic(c)
state = 'adapt'
# Adapt
diff --git a/dpd/src/Const.py b/dpd/src/Const.py
index bf46796..ebdfeb2 100644
--- a/dpd/src/Const.py
+++ b/dpd/src/Const.py
@@ -6,9 +6,8 @@
import numpy as np
class Const:
- def __init__(self, sample_rate, target_median, n_bins, n_per_bin, n_meas):
+ def __init__(self, sample_rate, target_median, plot):
self.sample_rate = sample_rate
- self.n_meas = n_meas
self.tx_gain_max = 89
@@ -41,11 +40,11 @@ class Const:
self.phase_offset_per_sample = 1. / sample_rate * 2 * np.pi * 1000
# Constants for ExtractStatistic
- self.ES_plot = False
+ self.ES_plot = plot
self.ES_start = 0.0
self.ES_end = 1.0
- self.ES_n_bins = n_bins
- self.ES_n_per_bin = n_per_bin
+ self.ES_n_bins = 64
+ self.ES_n_per_bin = 128
# Constants for TX_Agc
self.TAGC_max_txgain = 89
@@ -53,22 +52,21 @@ class Const:
self.TAGC_tx_median_max = self.TAGC_tx_median_target*1.4
self.TAGC_tx_median_min = self.TAGC_tx_median_target/1.4
-
self.RAGC_min_rxgain = 25
self.RAGC_rx_median_target = self.TAGC_tx_median_target
# Constants for Model
- self.MDL_plot = True
+ self.MDL_plot = True or plot # Override default
# Constants for MER
- self.MER_plot = False
+ self.MER_plot = plot
# Constants for Model_PM
self.MPM_tx_min = 0.1
# Constants for Measure_Shoulder
self.MS_enable = False
- self.MS_plot = False
+ self.MS_plot = plot
assert sample_rate==8192000
meas_offset = 976 # Offset from center frequency to measure shoulder [kHz]
meas_width = 100 # Size of frequency delta to measure shoulder [kHz]
diff --git a/dpd/src/ExtractStatistic.py b/dpd/src/ExtractStatistic.py
index bf9eba5..9df85bc 100644
--- a/dpd/src/ExtractStatistic.py
+++ b/dpd/src/ExtractStatistic.py
@@ -126,7 +126,8 @@ class ExtractStatistic:
def _rx_value_per_bin(self):
rx_values = []
for values in self.rx_values_lists:
- rx_values.append(np.mean(np.abs(values)))
+ mean = np.mean(np.abs(values)) if len(values) > 0 else np.nan
+ rx_values.append(mean)
return rx_values
def _tx_value_per_bin(self):
@@ -147,7 +148,8 @@ class ExtractStatistic:
def _phase_diff_value_per_bin(self, phase_diffs_values_lists):
phase_list = []
for values in phase_diffs_values_lists:
- phase_list.append(np.mean(values))
+ mean = np.mean(values) if len(values) > 0 else np.nan
+ phase_list.append(mean)
return phase_list
def extract(self, tx_dpd, rx):
diff --git a/dpd/src/Heuristics.py b/dpd/src/Heuristics.py
index 467c5da..a32ccff 100644
--- a/dpd/src/Heuristics.py
+++ b/dpd/src/Heuristics.py
@@ -10,7 +10,7 @@ import numpy as np
def get_learning_rate(idx_run):
idx_max = 10.0
lr_min = 0.05
- lr_max = 1
+ lr_max = 0.4
lr_delta = lr_max - lr_min
idx_run = min(idx_run, idx_max)
learning_rate = lr_max - lr_delta * idx_run/idx_max
@@ -24,5 +24,3 @@ def get_n_meas(idx_run):
idx_run = min(idx_run, idx_max)
learning_rate = n_meas_delta * idx_run/idx_max + n_meas_min
return int(np.round(learning_rate))
-
-
diff --git a/dpd/src/TX_Agc.py b/dpd/src/TX_Agc.py
index 7b74c8f..2602ea6 100644
--- a/dpd/src/TX_Agc.py
+++ b/dpd/src/TX_Agc.py
@@ -90,7 +90,7 @@ class TX_Agc:
# Set new values.
# Avoid temorary increase of output power with correct order
- if digital_gain_factor < 0:
+ if digital_gain_factor < 1:
self.adapt.set_digital_gain(digital_gain)
time.sleep(0.5)
txgain = self._set_tx_gain(new_txgain)
diff --git a/dpd/src/Test_data.py b/dpd/src/Test_data.py
index 67f4dff..bbef282 100644
--- a/dpd/src/Test_data.py
+++ b/dpd/src/Test_data.py
@@ -40,7 +40,7 @@ class Test_data:
plt.plot(np.angle(np.fft.fftshift(np.fft.fft(tx_orig))), 'p')
"""
- self.c = src.Const.Const(sample_rate)
+ self.c = src.Const.Const(sample_rate,, False
self.du = src.Dab_Util.Dab_Util(sample_rate)
self.file_paths = {