diff --git a/awg_data.py b/awg_data.py index 41aab75..2e42b38 100644 --- a/awg_data.py +++ b/awg_data.py @@ -2,15 +2,19 @@ import numpy as np class RunsFiles: - def __init__(self, uut, files): + def __init__(self, uut, files, run_forever=False): self.uut = uut self.files = files + self.run_forever = run_forever def load(self): - for f in self.files: - with open(f, mode='r') as fp: - self.uut.load_awg(fp.read()) - yield f + for ii in range(99999 if self.run_forever else 1): + for f in self.files: + with open(f, mode='r') as fp: + self.uut.load_awg(fp.read()) + yield f + + class RainbowGen: @@ -30,25 +34,26 @@ def sinc(self, ch): nsam = self.nsam nchan = self.nchan NCYCLES = self.NCYCLES - xoff = ch*nsam/NCYCLES/10 + xoff = ch*100 xx = np.array(range(-nsam/2-xoff,nsam/2-xoff))*NCYCLES*2*np.pi/nsam return [ np.sin(x)/x if x != 0 else 1 for x in xx ] - def __init__(self, uut, nchan, nsam): + def __init__(self, uut, nchan, nsam, run_forever=False): self.uut = uut self.nchan = nchan - self.nsam = nsam + self.nsam = nsam + self.run_forever = run_forever self.sw = self.sin() self.aw = np.zeros((nsam,nchan)) for ch in range(nchan): self.aw[:,ch] = self.rainbow(ch) - def load(self): - #for ch in range(self.nchan): - for ch in range(8): # convenient to plot 8 - aw1 = np.copy(self.aw) - aw1[:,ch] = np.add(np.multiply(self.sinc(ch),5),2) - print("loading array ", aw1.shape) - self.uut.load_awg((aw1*(2**15-1)/10).astype(np.int16)) - print("loaded array ", aw1.shape) - yield ch + def load(self): + for ii in range(99999 if self.run_forever else 1): + for ch in range(self.nchan): + aw1 = np.copy(self.aw) + aw1[:,ch] = np.add(np.multiply(self.sinc(ch),5),2) + print("loading array ", aw1.shape) + self.uut.load_awg((aw1*(2**15-1)/10).astype(np.int16)) + print("loaded array ", aw1.shape) + yield ch diff --git a/hil_plot.py b/hil_plot.py new file mode 100755 index 0000000..0d92579 --- /dev/null +++ b/hil_plot.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python +# Harware In Loop : load AO data,run a shot, get AI data, 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. + +import sys +import acq400_hapi +import awg_data +import argparse +import numpy as np +import matplotlib.pyplot as plt + +def store_file(it, rdata, nchan, nsam): + fn = 'DATA/ai%04d.dat' % (it) + print("store_file {}".format(fn)) + + with open(fn, 'w') as f: + f.write(rdata) + +def plot(it, rdata, nchan, nsam): + raw = np.fromstring(rdata, dtype=np.int16) + chx = np.reshape(raw, (nsam, nchan)) + for ch in range(0,nchan): + plt.plot(chx[:,ch]) + + plt.show() + plt.pause(0.0001) + +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) + + for sx in uut.modules: + uut.modules[sx].trg = '1,1,1' if args.trg == 'int' else '1,0,1' + + if args.files != "": + work = awg_data.RunsFiles(uut, args.files.split(','), run_forever=True) + else: + work = awg_data.RainbowGen(uut, args.nchan, args.awglen, run_forever=True) + + store = store_file + loader = work.load() + for ii in range(0, args.loop): + print("shot: %d" % (ii)) + f = loader.next() + print("Loaded %s" % (f)) + uut.run_oneshot() + print("read_chan %d" % (args.post*args.nchan)) + rdata = uut.read_chan(0, args.post*args.nchan) + store(ii, rdata, args.nchan, args.post) + if args.plot > 0 : + if args.plot == 1: + plt.cla() + plt.title("AI for shot %d %s" % (ii, "persistent plot" if args.plot > 1 else "")) + plot(ii, rdata, args.nchan, args.post) + + raw_input("hit return when done") + + +def run_main(): + parser = argparse.ArgumentParser(description='acq1001 HIL demo') + parser.add_argument('--files', default="", help="list of files to load") + parser.add_argument('--loop', type=int, default=1, help="loop count") + parser.add_argument('--nchan', type=int, default=32, help='channel count for pattern') + 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('uuts', nargs=1, help="uut ") + run_shots(parser.parse_args()) + +# execution starts here + +if __name__ == '__main__': + run_main() +