diff options
Diffstat (limited to 'python')
| -rwxr-xr-x | python/dpdce.py | 63 | ||||
| -rwxr-xr-x | python/gui/api.py | 9 | ||||
| -rw-r--r-- | python/gui/static/js/odr-predistortion.js | 18 | ||||
| -rw-r--r-- | python/gui/templates/predistortion.html | 39 | 
4 files changed, 98 insertions, 31 deletions
| diff --git a/python/dpdce.py b/python/dpdce.py index f76b0f6..90cd436 100755 --- a/python/dpdce.py +++ b/python/dpdce.py @@ -80,6 +80,7 @@ else:  logging.info("DPDCE starting up"); +import time  import socket  from lib import yamlrpc  import numpy as np @@ -238,9 +239,9 @@ def engine_worker():                      # Extract usable data from measurement                      tx, rx, phase_diff, n_per_bin = extStat.extract(txframe_aligned, rxframe_aligned) -                    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")) +                    utctime = datetime.datetime.utcnow() +                    plot_file = "stats_{}.png".format(utctime.strftime("%s")) +                    extStat.plot(os.path.join(plot_path, plot_file), utctime.strftime("%Y-%m-%dT%H%M%S"))                      n_meas = Heuristics.get_n_meas(n_runs)                      with lock: @@ -248,7 +249,6 @@ def engine_worker():                          results['stateprogress'] += 5                          results['summary'] += ["Extracted Statistics: TX median={} RX median={}".format(tx_median, rx_median),                                  "Runs: {}/{}".format(extStat.n_meas, n_meas)] -                        internal_data['n_runs'] += 1                      if extStat.n_meas >= n_meas:                          break @@ -265,11 +265,11 @@ def engine_worker():                      model.train(tx, rx, phase_diff, lr=Heuristics.get_learning_rate(n_runs)) -                    time = datetime.datetime.utcnow() -                    model_plot_file = "model_{}.png".format(time.strftime("%s")) +                    utctime = datetime.datetime.utcnow() +                    model_plot_file = "model_{}.png".format(utctime.strftime("%s"))                      model.plot(                              os.path.join(plot_path, model_plot_file), -                            time.strftime("%Y-%m-%dT%H%M%S")) +                            utctime.strftime("%Y-%m-%dT%H%M%S"))                      with lock:                          results['modelplot'] = "dpd/" + model_plot_file @@ -293,6 +293,47 @@ def engine_worker():                          results['state'] = 'Idle'                          results['stateprogress'] = 100                          results['summary'] += ["New DPD coefficients calculated"] +            elif cmd == "adapt": +                with lock: +                    dpddata = internal_data['dpddata'] +                    results['state'] = 'Update Predistorter' +                    results['stateprogress'] = 50 +                    results['summary'] = [""] +                    iteration = internal_data['n_runs'] +                    internal_data['n_runs'] += 1 + +                adapt.set_predistorter(dpddata) + +                time.sleep(2) + +                txframe_aligned, tx_ts, rxframe_aligned, rx_ts, rx_median, tx_median = meas.get_samples() + +                # Store all settings for pre-distortion, tx and rx +                adapt.dump() + +                # Collect logging data +                off = symbol_align.calc_offset(txframe_aligned) +                tx_mer = mer.calc_mer(txframe_aligned[off:off + c.T_U], debug_name='TX') +                rx_mer = mer.calc_mer(rxframe_aligned[off:off + c.T_U], debug_name='RX') +                mse = np.mean(np.abs((txframe_aligned - rxframe_aligned) ** 2)) +                tx_gain = adapt.get_txgain() +                rx_gain = adapt.get_rxgain() +                digital_gain = adapt.get_digital_gain() +                rx_shoulder_tuple = meas_shoulders.average_shoulders(rxframe_aligned) +                tx_shoulder_tuple = meas_shoulders.average_shoulders(txframe_aligned) + +                lr = Heuristics.get_learning_rate(iteration) + +                summary = [f"Signal measurements after iteration {iteration} with learning rate {lr}", +                        f"TX MER {tx_mer}, RX MER {rx_mer}", +                        "Shoulders: TX {!r}, RX {!r}".format(tx_shoulder_tuple, rx_shoulder_tuple), +                        f"Mean-square error: {mse}", +                        f"Running with digital gain {digital_gain}, TX gain {tx_gain} and RX gain {rx_gain}"] + +                with lock: +                    results['state'] = 'Update Predistorter' +                    results['stateprogress'] = 100 +                    results['summary'] = ["Signal measurements after predistortion update"] + summary      finally:          with lock:              results['state'] = 'Terminated' @@ -318,13 +359,9 @@ try:              logging.error('YAML-RPC unknown error')              break -        if method == 'trigger_run': -            logging.info('YAML-RPC request : {}'.format(method)) -            command_queue.put('trigger_run') -            cmd_socket.send_success_response(addr, msg_id, None) -        elif method == 'reset': +        if any(method == m for m in ['trigger_run', 'reset', 'adapt']):              logging.info('YAML-RPC request : {}'.format(method)) -            command_queue.put('reset') +            command_queue.put(method)              cmd_socket.send_success_response(addr, msg_id, None)          elif method == 'set_setting':              logging.info('YAML-RPC request : {} -> {}'.format(method, params)) diff --git a/python/gui/api.py b/python/gui/api.py index bff224e..42c89c9 100755 --- a/python/gui/api.py +++ b/python/gui/api.py @@ -107,6 +107,15 @@ class API:      @cherrypy.expose      @cherrypy.tools.json_out() +    def dpd_adapt(self, **kwargs): +        if cherrypy.request.method == 'POST': +            return self._wrap_dpd("adapt") +        else: +            cherrypy.response.status = 400 +            return send_error("POST only") + +    @cherrypy.expose +    @cherrypy.tools.json_out()      def dpd_reset(self, **kwargs):          if cherrypy.request.method == 'POST':              return self._wrap_dpd("reset") diff --git a/python/gui/static/js/odr-predistortion.js b/python/gui/static/js/odr-predistortion.js index f46219c..b5f29ea 100644 --- a/python/gui/static/js/odr-predistortion.js +++ b/python/gui/static/js/odr-predistortion.js @@ -67,17 +67,25 @@ $(function(){          });      }); +    $('#triggerbtn').click(function() { +        doApiRequestPOST("/api/dpd_trigger_run", {}, function(data) { +            console.log("run succeeded: " + JSON.stringify(data)); +        }); +    }); + +    $('#adaptbtn').click(function() { +        doApiRequestPOST("/api/dpd_adapt", {}, function(data) { +            console.log("adapt succeeded: " + JSON.stringify(data)); +        }); +    }); + +      $('#resetbtn').click(function() {          doApiRequestPOST("/api/dpd_reset", {}, function(data) {              console.log("reset succeeded: " + JSON.stringify(data));          });      }); -    $('#triggerbtn').click(function() { -        doApiRequestPOST("/api/dpd_trigger_run", {}, function(data) { -            console.log("run succeeded: " + JSON.stringify(data)); -        }); -    });  });  /* diff --git a/python/gui/templates/predistortion.html b/python/gui/templates/predistortion.html index d102101..8682054 100644 --- a/python/gui/templates/predistortion.html +++ b/python/gui/templates/predistortion.html @@ -11,28 +11,41 @@        <div class="panel panel-default">          <div class="panel-heading">Status and calibration</div>          <div class="panel-body"> -          <div>Current DPDCE status: -            <div> -              <div id="dpdstatus" style="font-weight:bold;">N/A</div> -              <div class="progress"> -                <div id="dpdprogress" class="progress-bar" role="progressbar" style="width:0%"> -                    <span id="dpdprogresstext"></span> + +          <div class="container-fluid"> +            <div class="row"> +              <div class="col-sm-8"> +                <h2>Current DPDCE status</h2> +                <div> +                  <div id="dpdstatus" style="font-weight:bold;">N/A</div> +                  <div class="progress"> +                    <div id="dpdprogress" class="progress-bar" role="progressbar" style="width:0%"> +                      <span id="dpdprogresstext"></span> +                    </div> +                  </div>                  </div> +                <div class="well well-sm" id="dpdresults">N/A</div> +              </div> +              <div class="col-sm-4"> +                <h2>Summary</h2> +                <p>Calibration needs to be done once before the PA model +                can be trained. Every time calibration is changed, the predistortion +                parameters are invalidated!</p> +                <p>Once calibration succeeded and correct RX gain is set, you +                can trigger a capture and model the PA. Usually, several capture +                runs are needed before the model can be trained.</p> +                <p>The capture and model analysis will calculate a new set of +                DPD model data, that you can apply using the Update Predistorter button.</p>                </div>              </div> -            <div class="well well-sm" id="dpdresults">N/A</div>            </div> -          <div>Calibration needs to be done once before the PA model -          can be trained. Every time calibration is changed, the predistortion -          parameters are invalidated!</div> -          <div>Once calibration succeeded and correct RX gain is set, you -            can trigger a capture and model the PA. Usually, several capture -            runs are needed before the model can be trained.</div>            <button type="button" class="btn btn-sm btn-warning" id="calibratebtn">              Calibrate</button>            <button type="button" class="btn btn-sm btn-warning" id="triggerbtn">              Trigger Capture and PA Modeling</button> +          <button type="button" class="btn btn-sm btn-warning" id="adaptbtn"> +            Update Predistorter</button>            <button type="button" class="btn btn-sm btn-info" id="resetbtn">              Reset captured data</button>          </div> | 
