Source code for hil_plot

#!/usr/bin/env python

""" hil_plot Hardware In Loop : load AO data,run a shot, get AI data, plot, repeat.

    - upload to AWG and optionally run a capture.
    - data for upload is either File (host-local data file) or Rainbow, a test pattern.
    - assumes that clocking has been pre-assigned.

usage:: 

    hil_plot.py [-h] [--autorearm AUTOREARM] [--is_debug IS_DEBUG]
                   [--files FILES] [--pulse PULSE] [--loop LOOP]
                   [--range RANGE] [--store STORE] [--nchan NCHAN]
                   [--aochan AOCHAN] [--awglen AWGLEN] [--post POST]
                   [--trg TRG] [--plot PLOT] [--plot_volts PLOT_VOLTS]
                   [--wait_user WAIT_USER]
                   uuts

acq1001 HIL demo

positional arguments:
  uuts                  uut

optional arguments:
  -h, --help            show this help message and exit
  --autorearm AUTOREARM     load the waveform once, repeat many
  --is_debug IS_DEBUG       set debug level
  --files FILES         list of files to load
  --pulse PULSE         interval,duration,scan: + : each channel in turn
  --loop LOOP           loop count
  --range RANGE         set range on ADC
  --store STORE         save data when true
  --nchan NCHAN         channel count for pattern
  --aochan AOCHAN       AO channel count, if different to AI (it happens)
  --awglen AWGLEN       samples in AWG waveform
  --post POST           samples in ADC waveform
  --trg TRG             trg "int|ext rising|falling"
  --plot PLOT           --plot 1 : plot data, 2: persistent
  --plot_volts PLOT_VOLTS
                        1: plot values in volts
  --wait_user WAIT_USER
                        1: force user input each shot


"""
import sys
import acq400_hapi
from acq400_hapi import awg_data
import argparse
import numpy as np
import matplotlib.pyplot as plt
import hil_plot_support as pltsup
import os
import subprocess

import hil_plot_support as pltsup
from future import builtins
from builtins import input


[docs]def run_shots(args): uut = acq400_hapi.Acq400(args.uuts[0]) acq400_hapi.cleanup.init() if args.plot: plt.ion() uut.s0.transient = 'POST=%d SOFT_TRIGGER=%d DEMUX=0' % \ (args.post, 1 if args.trg == 'int' else 0) if args.aochan == 0: args.aochan = args.nchan for sx in uut.modules: if args.trg == 'int': uut.modules[sx].trg = '1,1,1' else: if args.trg.contains('falling'): uut.modules[sx].trg = '1,0,0' else: uut.modules[sx].trg = '1,0,1' if args.pulse != None: work = awg_data.Pulse(uut, args.aochan, args.awglen, args.pulse.split(',')) elif args.files != "": work = awg_data.RunsFiles(uut, args.files.split(','), run_forever=True) else: work = awg_data.RainbowGen(uut, args.aochan, args.awglen, run_forever=True) # compensate gain ONLY Rainbow Case if args.range != "default": gain = 10/float(args.range.strip('V')) print("setting work.gain {}".format(gain)) work.gain = gain # Set range knobs, valid ALL data sources. if args.range != "default": for sx in uut.modules: print("setting GAIN_ALL {}".format(args.range)) uut.modules[sx].GAIN_ALL = args.range break print("args.autorearm {}".format(args.autorearm)) loader = work.load(autorearm = args.autorearm) for ii in range(0, args.loop): print("shot: %d" % (ii)) if ii == 0 or not args.autorearm: f = next(loader) print("Loaded %s" % (f)) else: if args.autorearm and ii+1 == args.loop: # on the final run, drop out of autorearm mode. # the final shot MUST be in ONCE mode so that the DMAC # is freed on conclusion for sx in uut.modules: if uut.modules[sx].MODEL.startswith('AO'): uut.modules[sx].playloop_oneshot = '1' uut.run_oneshot() print("read_chan %d" % (args.post*args.nchan)) rdata = uut.read_chan(0, args.post*args.nchan) if args.store: pltsup.store_file(ii, rdata, args.nchan, args.post) if args.plot > 0 : plt.cla() plt.title("AI for shot %d %s" % (ii, "persistent plot" if args.plot > 1 else "")) pltsup.plot(uut, args, ii, rdata) if args.wait_user is not None: input("hit return to continue")
[docs]def is_exe(fpath): return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
[docs]class ExecFile: def __init__(self, fname): self.fname = fname def __call__(self): args = [self.fname, pltsup.current_file] print("subprocess.call({})".format(args)) subprocess.call(args, stdout=sys.stdout, shell=False)
[docs]class Integer: def __init__(self, value): self.value = int(value) def __call__(self): return self.value
[docs]class Prompt: def __call__(self): input("hit return to continue")
[docs]def select_prompt_or_exec(value): if is_exe(value): return ExecFile(value) else: if int(value) == 1: return Prompt()
[docs]def run_main(): parser = argparse.ArgumentParser(description='acq1001 HIL demo') # --type=bool does not work, try this: # https://stackoverflow.com/questions/15008758/parsing-boolean-values-with-argparse parser.add_argument('--autorearm', default=False, type=lambda x: (str(x).lower() in ['true', 't', 'yes', '1']), help="load the waveform once, repeat many") parser.add_argument('--is_debug', default=False, type=lambda x: (str(x).lower() in ['true', 't', 'yes', '1'])), parser.add_argument('--files', default="", help="list of files to load") parser.add_argument('--pulse', help="interval,duration,scan: + : each channel in turn") parser.add_argument('--loop', type=int, default=1, help="loop count") parser.add_argument('--range', default="default", help="set range on ADC") parser.add_argument('--store', type=int, default=1, help="save data when true") parser.add_argument('--nchan', type=int, default=32, help='channel count for pattern') parser.add_argument('--aochan', type=int, default=0, help='AO channel count, if different to AI (it happens)') parser.add_argument('--awglen', type=int, default=2048, help='samples in AWG waveform') parser.add_argument('--post', type=int, default=100000, help='samples in ADC waveform') parser.add_argument('--trg', default="int", help='trg "int|ext rising|falling"') parser.add_argument('--plot', type=int, default=1, help='--plot 1 : plot data, 2: persistent') parser.add_argument('--plot_volts', type=int, default=0, help='1: plot values in volts') parser.add_argument('--wait_user', type=select_prompt_or_exec, default=0, help='1: force user input each shot') parser.add_argument('uuts', nargs=1, help="uut ") run_shots(parser.parse_args())
# execution starts here if __name__ == '__main__': run_main()