From 9d2c85f7a2a23fcf9ce3c842d86227afed43a153 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Tue, 18 Dec 2018 16:53:56 +0100 Subject: GUI: Automatically iterate captures and show model plots --- python/dpd/Model_AM.py | 23 +++--- python/dpd/Model_PM.py | 23 +++--- python/dpd/Model_Poly.py | 14 ++-- python/dpdce.py | 117 ++++++++++++++++-------------- python/gui/static/js/odr-predistortion.js | 7 ++ python/gui/templates/predistortion.html | 2 + 6 files changed, 98 insertions(+), 88 deletions(-) diff --git a/python/dpd/Model_AM.py b/python/dpd/Model_AM.py index 75b226f..b07a5a5 100644 --- a/python/dpd/Model_AM.py +++ b/python/dpd/Model_AM.py @@ -42,22 +42,18 @@ class Model_AM: """Calculates new coefficients using the measurement and the previous coefficients""" - def __init__(self, - c, - learning_rate_am=1, - plot=False): + def __init__(self, c, learning_rate_am=1): self.c = c - self.learning_rate_am = learning_rate_am - self.plot = plot + self._plot_data = None + + def plot(self, plot_location, title): + if self._plot_data is not None: + tx_dpd, rx_received, coefs_am, coefs_am_new = self._plot_data - def _plot(self, tx_dpd, rx_received, coefs_am, coefs_am_new): - if self.plot and self.c.plot_location 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) - dt = datetime.datetime.now().isoformat() - fig_path = self.c.plot_location + "/" + dt + "_Model_AM.png" sub_rows = 1 sub_cols = 1 fig = plt.figure(figsize=(sub_cols * 6, sub_rows / 2. * 6)) @@ -76,14 +72,14 @@ class Model_AM: label="Binned Data", color="blue", s=1) - ax.set_title("Model_AM") + ax.set_title("Model_AM {}".format(title)) ax.set_xlabel("TX Amplitude") ax.set_ylabel("RX Amplitude") ax.set_xlim(-0.5, 1.5) ax.legend(loc=4) fig.tight_layout() - fig.savefig(fig_path) + fig.savefig(plot_location) plt.close(fig) def get_next_coefs(self, tx_dpd, rx_received, coefs_am): @@ -95,13 +91,14 @@ class Model_AM: coefs_am_new = coefs_am + \ self.learning_rate_am * (coefs_am_new - coefs_am) - self._plot(tx_dpd, rx_received, coefs_am, coefs_am_new) + self._plot_data = (tx_dpd, rx_received, coefs_am, coefs_am_new) return coefs_am_new # The MIT License (MIT) # # Copyright (c) 2017 Andreas Steger +# Copyright (c) 2018 Matthias P. Braendli # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal diff --git a/python/dpd/Model_PM.py b/python/dpd/Model_PM.py index 7b80bf3..40fa1d4 100644 --- a/python/dpd/Model_PM.py +++ b/python/dpd/Model_PM.py @@ -28,22 +28,18 @@ class Model_PM: """Calculates new coefficients using the measurement and the previous coefficients""" - def __init__(self, - c, - learning_rate_pm=1, - plot=False): + def __init__(self, c, learning_rate_pm=1): self.c = c - self.learning_rate_pm = learning_rate_pm - self.plot = plot + self._plot_data = None + + def plot(self, plot_location, title): + if self._plot_data is not None: + tx_dpd, phase_diff, coefs_pm, coefs_pm_new = self._plot_data - def _plot(self, tx_dpd, phase_diff, coefs_pm, coefs_pm_new): - if self.plot and self.c.plot_location 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) - dt = datetime.datetime.now().isoformat() - fig_path = self.c.plot_location + "/" + dt + "_Model_PM.png" sub_rows = 1 sub_cols = 1 fig = plt.figure(figsize=(sub_cols * 6, sub_rows / 2. * 6)) @@ -62,13 +58,13 @@ class Model_PM: label="Binned Data", color="blue", s=1) - ax.set_title("Model_PM") + ax.set_title("Model_PM {}".format(title)) ax.set_xlabel("TX Amplitude") ax.set_ylabel("Phase DIff") ax.legend(loc=4) fig.tight_layout() - fig.savefig(fig_path) + fig.savefig(plot_location) plt.close(fig) def _discard_small_values(self, tx_dpd, phase_diff): @@ -97,13 +93,14 @@ class Model_PM: coefs_pm_new = self.fit_poly(tx_dpd, phase_diff) coefs_pm_new = coefs_pm + self.learning_rate_pm * (coefs_pm_new - coefs_pm) - self._plot(tx_dpd, phase_diff, coefs_pm, coefs_pm_new) + self._plot_data = (tx_dpd, phase_diff, coefs_pm, coefs_pm_new) return coefs_pm_new # The MIT License (MIT) # # Copyright (c) 2017 Andreas Steger +# Copyright (c) 2018 Matthias P. Braendli # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal diff --git a/python/dpd/Model_Poly.py b/python/dpd/Model_Poly.py index c8f6135..ca39492 100644 --- a/python/dpd/Model_Poly.py +++ b/python/dpd/Model_Poly.py @@ -36,20 +36,20 @@ class Poly: """Calculates new coefficients using the measurement and the previous coefficients""" - def __init__(self, - c, - learning_rate_am=1.0, - learning_rate_pm=1.0): + def __init__(self, c, learning_rate_am=1.0, learning_rate_pm=1.0): self.c = c - self.plot = c.MDL_plot self.learning_rate_am = learning_rate_am self.learning_rate_pm = learning_rate_pm self.reset_coefs() - self.model_am = Model_AM.Model_AM(c, plot=self.plot) - self.model_pm = Model_PM.Model_PM(c, plot=self.plot) + self.model_am = Model_AM.Model_AM(c) + self.model_pm = Model_PM.Model_PM(c) + + def plot(self, am_plot_location, pm_plot_location, title): + self.model_am.plot(am_plot_location, title) + self.model_pm.plot(pm_plot_location, title) def reset_coefs(self): self.coefs_am = np.zeros(5, dtype=np.float32) diff --git a/python/dpdce.py b/python/dpdce.py index a9ed140..e601d9c 100755 --- a/python/dpdce.py +++ b/python/dpdce.py @@ -142,6 +142,8 @@ internal_data = { } results = { 'statplot': None, + 'amplot': None, + 'pmplot': None, 'tx_median': 0, 'rx_median': 0, 'state': 'Idle', @@ -203,71 +205,76 @@ def engine_worker(): results['stateprogress'] = 0 n_runs = internal_data['n_runs'] - # Get Samples and check gain - txframe_aligned, tx_ts, rxframe_aligned, rx_ts, rx_median, tx_median = meas.get_samples() - # TODO Check TX median - - with lock: - results['stateprogress'] = 20 - results['summary'] = ["Captured {} samples".format(len(txframe_aligned)), - "TX/RX median: {} / {}".format(tx_median, rx_median)] + while True: + # Get Samples and check gain + txframe_aligned, tx_ts, rxframe_aligned, rx_ts, rx_median, tx_median = meas.get_samples() + # TODO Check TX median - # Extract usable data from measurement - tx, rx, phase_diff, n_per_bin = extStat.extract(txframe_aligned, rxframe_aligned) - - time = datetime.datetime.utcnow() + with lock: + results['stateprogress'] += 5 + results['summary'] = ["Captured {} samples".format(len(txframe_aligned)), + "TX/RX median: {} / {}".format(tx_median, rx_median)] - plot_file = "stats_{}.png".format(time.strftime("%s")) - extStat.plot(os.path.join(plot_path, plot_file), time.strftime("%Y-%m-%dT%H%M%S")) + # Extract usable data from measurement + tx, rx, phase_diff, n_per_bin = extStat.extract(txframe_aligned, rxframe_aligned) - with lock: - results['statplot'] = "dpd/" + plot_file - results['stateprogress'] = 30 - results['summary'] += ["Extracted Statistics".format(tx_median, rx_median)] - - n_meas = Heuristics.get_n_meas(n_runs) - if extStat.n_meas >= n_meas: # Use as many measurements nr of runs - if any(x is None for x in [tx, rx, phase_diff]): - with lock: - results['summary'] += ["Error! No data to calculate model"] - results['state'] = 'Idle' - results['stateprogress'] = 0 - else: - with lock: - results['state'] = 'Capture + Model' - results['stateprogress'] = 40 - results['summary'] += ["Training model"] - - model.train(tx, rx, phase_diff, lr=Heuristics.get_learning_rate(n_runs)) - - with lock: - results['state'] = 'Capture + Model' - results['stateprogress'] = 60 - results['summary'] += ["Getting DPD data"] - - dpddata = model.get_dpd_data() - with lock: - internal_data['dpddata'] = dpddata - internal_data['n_runs'] = 0 - - results['state'] = 'Capture + Model' - results['stateprogress'] = 80 - results['summary'] += ["Reset statistics"] - - extStat = ExtractStatistic(c) - - with lock: - results['state'] = 'Idle' - results['stateprogress'] = 100 - results['summary'] += ["New DPD coefficients calculated"] + time = datetime.datetime.utcnow() + plot_file = "stats_{}.png".format(time.strftime("%s")) + extStat.plot(os.path.join(plot_path, plot_file), time.strftime("%Y-%m-%dT%H%M%S")) + n_meas = Heuristics.get_n_meas(n_runs) with lock: + results['statplot'] = "dpd/" + plot_file + results['stateprogress'] += 5 + results['summary'] += ["Extracted Statistics".format(tx_median, rx_median), + "Runs: {}/{}".format(extStat.n_meas, n_meas)] internal_data['n_runs'] += 1 + if extStat.n_meas >= n_meas: + break + + if any(x is None for x in [tx, rx, phase_diff]): + with lock: + results['summary'] += ["Error! No data to calculate model"] + results['state'] = 'Idle' + results['stateprogress'] = 0 else: + with lock: + results['state'] = 'Capture + Model' + results['stateprogress'] = 60 + results['summary'] += ["Training model"] + + model.train(tx, rx, phase_diff, lr=Heuristics.get_learning_rate(n_runs)) + + time = datetime.datetime.utcnow() + am_plot_file = "model_am_{}.png".format(time.strftime("%s")) + pm_plot_file = "model_pm_{}.png".format(time.strftime("%s")) + model.plot( + os.path.join(plot_path, am_plot_file), + os.path.join(plot_path, pm_plot_file), + time.strftime("%Y-%m-%dT%H%M%S")) + + with lock: + results['amplot'] = "dpd/" + am_plot_file + results['pmplot'] = "dpd/" + pm_plot_file + results['state'] = 'Capture + Model' + results['stateprogress'] = 70 + results['summary'] += ["Getting DPD data"] + + dpddata = model.get_dpd_data() + with lock: + internal_data['dpddata'] = dpddata + internal_data['n_runs'] = 0 + + results['state'] = 'Capture + Model' + results['stateprogress'] = 80 + results['summary'] += ["Reset statistics"] + + extStat = ExtractStatistic(c) + with lock: results['state'] = 'Idle' results['stateprogress'] = 100 - results['summary'] += ["More data required to train model"] + results['summary'] += ["New DPD coefficients calculated"] finally: with lock: diff --git a/python/gui/static/js/odr-predistortion.js b/python/gui/static/js/odr-predistortion.js index e9f7c96..ff82142 100644 --- a/python/gui/static/js/odr-predistortion.js +++ b/python/gui/static/js/odr-predistortion.js @@ -39,6 +39,13 @@ function resultrefresh() { if (data['statplot']) { $('#dpdcapturestats').attr('src', data['statplot']); } + + if (data['amplot']) { + $('#dpdamplot').attr('src', data['amplot']); + } + if (data['pmplot']) { + $('#dpdpmplot').attr('src', data['pmplot']); + } }); jqxhr.always(function() { diff --git a/python/gui/templates/predistortion.html b/python/gui/templates/predistortion.html index adbba7e..e21c688 100644 --- a/python/gui/templates/predistortion.html +++ b/python/gui/templates/predistortion.html @@ -42,6 +42,8 @@
Capture Statistics
+ +
-- cgit v1.2.3