def print_spec_data(rawdata_dir, chnl): """ Print the saved data to .pdf images for an easy check. :param rawdata_dir: directory where to read the data and print the plot. :param chnl: channel where the tone is injected. """ # get data specdata = np.load(rawdata_dir + "/chnl_" + str(chnl) + ".npz") a2 = specdata['a2'] b2 = specdata['b2'] # compute power levels pow_a2 = cd.scale_and_dBFS_specdata(a2, acc_len, dBFS) pow_b2 = cd.scale_and_dBFS_specdata(b2, acc_len, dBFS) # plot spec usb plt.figure() plt.plot(if_freqs, pow_a2, 'b') plt.ylim((-85, 5)) plt.grid() plt.xlabel('Frequency [MHz]') plt.ylabel('Power [dBFS]') plt.savefig(rawdata_dir + '/chnl_' + str(chnl) + '_a2.pdf') plt.close() # plot spec lsb plt.figure() plt.plot(if_freqs, pow_b2, 'r') plt.ylim((-85, 5)) plt.grid() plt.xlabel('Frequency [MHz]') plt.ylabel('Power [dBFS]') plt.savefig(rawdata_dir + '/chnl_' + str(chnl) + '_b2.pdf') plt.close()
def get_lnrdata(line0, line1, line2): """ Get the lnr data assumimg a broadband noise signal is injected. The lnr data is the power of the input after applying the calibration constants (rf), and the negative of the constants (lo). :param line0: line for first axis. :param line1: line for second axis. :param line1: line for third axis. :return: calibration data: a2, b2, and ab. """ # read data time.sleep(pause_time) rf = cd.read_interleave_data(roach, bram_rf, bram_addr_width, bram_word_width, pow_data_type) lo = cd.read_interleave_data(roach, bram_lo, bram_addr_width, bram_word_width, pow_data_type) # scale and dBFS data for plotting rf_plot = cd.scale_and_dBFS_specdata(rf, acc_len, dBFS) lo_plot = cd.scale_and_dBFS_specdata(lo, acc_len, dBFS) # compute lnr for plotting lnr_ratios = np.divide(lo, rf) # plot data line0.set_data(if_freqs, rf_plot) line1.set_data(if_freqs, lo_plot) line2.set_data(if_freqs, 10*np.log10(lnr_ratios)) fig.canvas.draw() fig.canvas.flush_events() return rf, lo
def get_srrdata(rf_freqs, tone_sideband): """ Sweep a tone through a sideband and get the srr data. The srr data is the power of each tone after applying the calibration constants for each sideband (usb and lsb). The full sprecta measured for each tone is saved to data for debugging purposes. :param rf_freqs: frequencies of the tones to perform the sweep (in GHz). :param tone_sideband: sideband of the injected test tone. Either USB or LSB :return: srr data: usb and lsb. """ fig.canvas.set_window_title(tone_sideband.upper() + " Tone Sweep") usb_arr = [] lsb_arr = [] for i, chnl in enumerate(test_channels): # set test tone freq = rf_freqs[chnl] rf_generator.ask("freq " + str(freq) + " ghz; *opc?") time.sleep(pause_time) # read data usb = cd.read_interleave_data(roach, bram_usb, bram_addr_width, bram_word_width, pow_data_type) lsb = cd.read_interleave_data(roach, bram_lsb, bram_addr_width, bram_word_width, pow_data_type) # append data to arrays usb_arr.append(usb[chnl]) lsb_arr.append(lsb[chnl]) # scale and dBFS data for plotting usb_plot = cd.scale_and_dBFS_specdata(usb, acc_len, dBFS) lsb_plot = cd.scale_and_dBFS_specdata(lsb, acc_len, dBFS) # compute srr for plotting if tone_sideband == 'usb': srr = np.divide(usb_arr, lsb_arr) else: # tone_sideband=='lsb srr = np.divide(lsb_arr, usb_arr) # define sb plot line line_sb = lines[2] if tone_sideband == 'usb' else lines[3] # plot data lines[0].set_data(if_freqs, usb_plot) lines[1].set_data(if_freqs, lsb_plot) line_sb.set_data(if_test_freqs[:i + 1], 10 * np.log10(srr)) fig.canvas.draw() fig.canvas.flush_events() # save data np.savez(srr_datadir+"/rawdata_tone_" + tone_sideband + "/chnl_" + \ str(chnl), usb=usb, lsb=lsb) # compute interpolations usb_arr = np.interp(if_freqs, if_test_freqs, usb_arr) lsb_arr = np.interp(if_freqs, if_test_freqs, lsb_arr) return usb_arr, lsb_arr
def get_caldata(rf_freqs, tone_sideband): """ Sweep a tone through a sideband and get the calibration data. The calibration data is the power of each tone in both inputs (a and b) and the cross-correlation of both inputs as a complex number (ab*). The full sprecta measured for each tone is saved to data for debugging purposes. :param rf_freqs: frequencies of the tones to perform the sweep (in GHz). :param tone_sideband: sideband of the injected test tone. Either USB or LSB :return: calibration data: a2, b2, and ab. """ fig.canvas.set_window_title(tone_sideband.upper() + " Tone Sweep") a2_arr = []; b2_arr = []; ab_arr = [] for i, chnl in enumerate(test_channels): # set test tone freq = rf_freqs[chnl] rf_generator.ask("freq " + str(freq) + " ghz; *opc?") time.sleep(pause_time) # read data a2 = cd.read_interleave_data(roach, bram_a2, bram_addr_width, bram_word_width, pow_data_type) b2 = cd.read_interleave_data(roach, bram_b2, bram_addr_width, bram_word_width, pow_data_type) ab_re = cd.read_interleave_data(roach, bram_ab_re, bram_addr_width, bram_word_width, crosspow_data_type) ab_im = cd.read_interleave_data(roach, bram_ab_im, bram_addr_width, bram_word_width, crosspow_data_type) # append data to arrays a2_arr.append(a2[chnl]) b2_arr.append(b2[chnl]) ab_arr.append(ab_re[chnl] + 1j*ab_im[chnl]) # scale and dBFS data for plotting a2_plot = cd.scale_and_dBFS_specdata(a2, acc_len, dBFS) b2_plot = cd.scale_and_dBFS_specdata(b2, acc_len, dBFS) # compute input ratios for plotting ab_ratios = np.divide(ab_arr, b2_arr) # plot data lines[0].set_data(if_freqs, a2_plot) lines[1].set_data(if_freqs, b2_plot) lines[2].set_data(if_test_freqs[:i+1], np.abs(ab_ratios)) lines[3].set_data(if_test_freqs[:i+1], np.angle(ab_ratios, deg=True)) fig.canvas.draw() fig.canvas.flush_events() # save data np.savez(cal_datadir+"/rawdata_tone_" + tone_sideband + "/chnl_" + str(chnl), a2=a2, b2=b2, ab_re=ab_re, ab_im=ab_im) # compute interpolations a2_arr = np.interp(if_freqs, if_test_freqs, a2_arr) b2_arr = np.interp(if_freqs, if_test_freqs, b2_arr) ab_arr = np.interp(if_freqs, if_test_freqs, ab_arr) return a2_arr, b2_arr, ab_arr
def get_lnrdata(rf_freqs, tone_sideband): """ Sweep a tone through a sideband and get the lnr data. The lnr data is the power of each tone after applying the calibration constants (rf), and the negative of the constants (lo). The full sprecta measured for each tone is saved to data for debugging purposes. :param rf_freqs: frequencies of the tones to perform the sweep. :param tone_sideband: sideband of the injected test tone. Either USB or LSB :return: lnr data: rf and lo. """ fig.canvas.set_window_title(tone_sideband.upper() + " Sweep") rf_arr = []; lo_arr = [] for i, chnl in enumerate(test_channels): # set test tone freq = rf_freqs[chnl] rf_generator.ask("freq " + str(freq*1e6) + ";*opc?") # freq must be in Hz time.sleep(pause_time) # read data rf = cd.read_interleave_data(roach, bram_rf, bram_addr_width, bram_word_width, pow_data_type) lo = cd.read_interleave_data(roach, bram_lo, bram_addr_width, bram_word_width, pow_data_type) # append data to arrays rf_arr.append(rf[chnl]) lo_arr.append(lo[chnl]) # scale and dBFS data for plotting rf_plot = cd.scale_and_dBFS_specdata(rf, acc_len, dBFS) lo_plot = cd.scale_and_dBFS_specdata(lo, acc_len, dBFS) # compute lnr for plotting lnr = np.divide(lo_arr, rf_arr) # define sb plot line line_sb = line2 if tone_sideband=='usb' else line3 # plot data line0.set_data(if_freqs, rf_plot) line1.set_data(if_freqs, lo_plot) line_sb.set_data(if_test_freqs[:i+1], 10*np.log10(lnr)) fig.canvas.draw() fig.canvas.flush_events() # save data np.savez(datadir+"/rawdata_tone_" + tone_sideband + "/chnl_" + str(chnl), rf=rf, lo=lo) # compute interpolations rf_arr = np.interp(if_freqs, if_test_freqs, rf_arr) lo_arr = np.interp(if_freqs, if_test_freqs, lo_arr) return rf_arr, lo_arr
def print_singlelo_data(measdir): """ Print the saved data to .pdf images for an easy check. :param measdir: directory where to read the data of single measurement and save the image (sub directory of main srr_datadir). """ # get data srrdata = np.load(measdir + "/srrdata.npz") usb_toneusb = srrdata['usb_toneusb'] lsb_toneusb = srrdata['lsb_toneusb'] usb_tonelsb = srrdata['usb_tonelsb'] lsb_tonelsb = srrdata['lsb_tonelsb'] # compute power levels pow_usb_toneusb = cd.scale_and_dBFS_specdata(usb_toneusb, acc_len, dBFS) pow_usb_tonelsb = cd.scale_and_dBFS_specdata(usb_tonelsb, acc_len, dBFS) pow_lsb_toneusb = cd.scale_and_dBFS_specdata(lsb_toneusb, acc_len, dBFS) pow_lsb_tonelsb = cd.scale_and_dBFS_specdata(lsb_tonelsb, acc_len, dBFS) # compute ratios srr_usb = usb_toneusb / lsb_toneusb srr_lsb = lsb_tonelsb / usb_tonelsb # plot power level signal plt.figure() plt.plot(if_freqs, pow_usb_toneusb, 'b', label="USB toneUSB") plt.plot(if_freqs, pow_lsb_tonelsb, 'r', label="LSB toneLSB") plt.grid() plt.xlabel('Frequency [MHz]') plt.ylabel('Power [dBFS]') plt.legend() plt.savefig(measdir + '/power_lev_sig.pdf') plt.close() # plot power level image plt.figure() plt.plot(if_freqs, pow_usb_tonelsb, 'b', label="USB toneLSB") plt.plot(if_freqs, pow_lsb_toneusb, 'r', label="LSB toneUSB") plt.grid() plt.xlabel('Frequency [MHz]') plt.ylabel('Power [dBFS]') plt.legend() plt.savefig(measdir + '/power_lev_img.pdf') plt.close() # print SRR plt.figure() plt.plot(if_freqs, 10 * np.log10(srr_usb), 'b', label="USB") plt.plot(if_freqs, 10 * np.log10(srr_lsb), 'r', label="LSB") plt.grid() plt.xlabel('Frequency [MHz]') plt.ylabel('SRR [dB]') plt.legend() plt.savefig(measdir + '/srr.pdf') plt.close()
def get_caldata(rf_freqs): """ Sweep a tone through a sideband and get the complex ratio of first (a) and second (b) input. It is later used to compute the adc delay using the angle difference information. :param rf_freqs: frequencies of the tones to perform the sweep (GHz). :return ab_ratios: complex ratios between a and b. """ a2_arr = [] b2_arr = [] ab_arr = [] for i, chnl in enumerate(sync_channels): # set test tone freq = rf_freqs[chnl] rf_generator.ask("freq " + str(freq) + " ghz; *opc?") time.sleep(pause_time) # read data a2 = cd.read_interleave_data(roach, bram_a2, bram_addr_width, bram_word_width, pow_data_type) b2 = cd.read_interleave_data(roach, bram_b2, bram_addr_width, bram_word_width, pow_data_type) ab_re = cd.read_interleave_data(roach, bram_ab_re, bram_addr_width, bram_word_width, crosspow_data_type) ab_im = cd.read_interleave_data(roach, bram_ab_im, bram_addr_width, bram_word_width, crosspow_data_type) # append data to arrays a2_arr.append(a2[chnl]) b2_arr.append(b2[chnl]) ab_arr.append(ab_re[chnl] + 1j * ab_im[chnl]) # scale and dBFS data for plotting a2_plot = cd.scale_and_dBFS_specdata(a2, acc_len, dBFS) b2_plot = cd.scale_and_dBFS_specdata(b2, acc_len, dBFS) # compute input ratios for plotting ab_ratios = np.divide(np.conj(ab_arr), a2_arr) # (ab*)* /aa* = a*b / aa* = b/a # plot data lines[0].set_data(if_freqs, a2_plot) lines[1].set_data(if_freqs, b2_plot) lines[2].set_data(if_sync_freqs[:i + 1], np.abs(ab_ratios)) lines[3].set_data(if_sync_freqs[:i + 1], np.angle(ab_ratios, deg=True)) fig.canvas.draw() fig.canvas.flush_events() return ab_ratios
def animate(_): # get spectral data specdata_list = get_specdata(roach, specbrams, 2, bram_addr_width, bram_word_width, bram_data_type) for line, specdata in zip(lines, specdata_list): specdata = cd.scale_and_dBFS_specdata(specdata, acc_len, dBFS) line.set_data(freqs, specdata) return lines
def animate(_): for line, specbrams in zip(lines, specbrams_list): # update acc_len acc_len = roach.read_uint(acc_len_reg) # get spectral data specdata = cd.read_interleave_data(roach, specbrams, spec_addr_width, spec_word_width, spec_data_type) specdata = cd.scale_and_dBFS_specdata(specdata, acc_len, dBFS) line.set_data(freqs, specdata) return lines
def plot_convergence(roach): # useful data nspecs = 2**conv_addr_width time = np.arange(0, nspecs) * (1.0 / bandwidth) * nchannels # create window root = Tk.Tk() # create figure fig = plt.Figure() fig.set_tight_layout(True) canvas = FigureCanvasTkAgg(fig, master=root) toolbar = NavigationToolbar2Tk(canvas, root) toolbar.update() canvas._tkcanvas.pack(side=Tk.TOP, fill=Tk.BOTH, expand=1) # create axis ax = fig.add_subplot(1, 1, 1) ax.set_ylim((-100, 10)) ax.set_xlabel('Time [$\mu$s]') ax.set_ylabel('Power [dBFS]') ax.grid() # add save button button_frame = Tk.Frame(master=root) button_frame.pack(side=Tk.TOP, anchor="w") add_conv_save_button(roach, button_frame) # get data chnl, max, mean = get_conv_data(roach) chnl = cd.scale_and_dBFS_specdata(chnl, 1, dBFS) max = cd.scale_and_dBFS_specdata(max, 1, dBFS) mean = cd.scale_and_dBFS_specdata(mean, 1, dBFS) ax.plot(time, chnl, label="channel") ax.plot(time, max, label="max") ax.plot(time, mean, label="mean") ax.legend()
def get_caldata(): """ Get the calibration data assumimg a broadband noise signal is injected. The calibration data is the power of each input (a and b) and the cross-correlation of both inputs as a complex number (ab*). :return: calibration data: a2, b2, and ab. """ # read data time.sleep(pause_time) a2 = cd.read_interleave_data(roach, bram_a2, bram_addr_width, bram_word_width, pow_data_type) b2 = cd.read_interleave_data(roach, bram_b2, bram_addr_width, bram_word_width, pow_data_type) ab_re = cd.read_interleave_data(roach, bram_ab_re, bram_addr_width, bram_word_width, crosspow_data_type) ab_im = cd.read_interleave_data(roach, bram_ab_im, bram_addr_width, bram_word_width, crosspow_data_type) # get crosspower as complex values ab = ab_re + 1j * ab_im # scale and dBFS data for plotting a2_plot = cd.scale_and_dBFS_specdata(a2, acc_len, dBFS) b2_plot = cd.scale_and_dBFS_specdata(b2, acc_len, dBFS) # compute input ratios for plotting ab_ratios = np.divide(ab, b2) # plot data line0.set_data(if_freqs, a2_plot) line1.set_data(if_freqs, b2_plot) line2.set_data(if_freqs, np.abs(ab_ratios)) line3.set_data(if_freqs, np.angle(ab_ratios, deg=True)) fig.canvas.draw() fig.canvas.flush_events() return a2, b2, ab
def animate(_): # get spectral data from beamformers bf_data = self.get_bf_data() # extract the data from the specified channel only bf_data = np.array(bf_data)[:, chnl] # convert into dBFS bf_data = cd.scale_and_dBFS_specdata(bf_data, acclen, self.dBFS) # reshape the data into a matrix bf_data = np.reshape(bf_data, (8,8)) # update the plot grid and colormap img.set_data(bf_data) img.set_clim(vmin=np.min(bf_data), vmax=np.max(bf_data)) cbar.update_normal(img) return []
def get_dram_spectrogram_data(roach, addr_width, data_width, dtype): """ Get spectrogram data from DRAM. :param roach: CalanFpga object. :param addr_width: address width in bits. :param data_width: data width in bits. :param dtype: data type of dram data. :return: spectrogram data in dBFS. """ specgram_data = cd.read_dram_data(roach, addr_width, data_width, dtype) specgram_data = specgram_data.reshape( nchannels, nspecs) # convert spectrogram data into a time x freq matrix specgram_data = np.transpose( specgram_data ) # rotate matrix to have freq in y axis, and time in x axis specgram_data = cd.scale_and_dBFS_specdata(specgram_data, 1, dBFS) # convert data to dBFS return specgram_data
def plot_stability_data(): global a2_arr, b2_arr, anglediff_arr, magratios_arr, srr_arr, time_arr tone_sideband = 'usb' a2_arr = [] b2_arr = [] magratios_arr = [] anglediff_arr = [] srr_arr = [] time_arr = [] start_time = time.time() try: while True: time.sleep(pause_time) time_arr.append(time.time() - start_time) # read cal data a2 = cd.read_interleave_data(roach, bram_a2, bram_addr_width, bram_word_width, pow_data_type) b2 = cd.read_interleave_data(roach, bram_b2, bram_addr_width, bram_word_width, pow_data_type) ab_re = cd.read_interleave_data(roach, bram_ab_re, bram_addr_width, bram_word_width, crosspow_data_type) ab_im = cd.read_interleave_data(roach, bram_ab_im, bram_addr_width, bram_word_width, crosspow_data_type) # read syn data usb = cd.read_interleave_data(roach, bram_usb, bram_addr_width, bram_word_width, pow_data_type) lsb = cd.read_interleave_data(roach, bram_lsb, bram_addr_width, bram_word_width, pow_data_type) # scale and dBFS data for plotting a2_plot = cd.scale_and_dBFS_specdata(a2, acc_len, dBFS) b2_plot = cd.scale_and_dBFS_specdata(b2, acc_len, dBFS) ab = ab_re[stab_chnl] + 1j * ab_im[stab_chnl] # compute input ratios for plotting if tone_sideband == 'usb': ab_ratio = np.divide(np.conj(ab), a2) # (ab*)* /aa* = a*b / aa* = b/a else: # tone_sideband=='lsb ab_ratio = np.divide(ab, b2) # ab* / bb* = a/b # append data to arrays a2_arr.append(a2_plot[stab_chnl]) b2_arr.append(b2_plot[stab_chnl]) magratios_arr.append(np.abs(ab_ratio[stab_chnl])) anglediff_arr.append(np.angle(ab_ratio[stab_chnl], deg=True)) # compute srr if tone_sideband == 'usb': srr = np.divide(usb, lsb) else: # tone_sideband=='lsb srr = np.divide(lsb, usb) srr_arr.append(10 * np.log10(srr[stab_chnl])) # plot data if show_plots: lines[0].set_data(time_arr, a2_arr) lines[1].set_data(time_arr, b2_arr) lines[2].set_data(time_arr, magratios_arr) lines[3].set_data(time_arr, anglediff_arr) lines[4].set_data(time_arr, srr_arr) # update axes axes[0].set_ylim(np.min(a2_arr), np.max(a2_arr)) axes[1].set_ylim(np.min(b2_arr), np.max(b2_arr)) axes[2].set_ylim(np.min(magratios_arr), np.max(magratios_arr)) axes[3].set_ylim(np.min(anglediff_arr), np.max(anglediff_arr)) axes[4].set_ylim(np.min(srr_arr), np.max(srr_arr)) axes[4].set_xlim(0, time_arr[-1]) fig.canvas.draw() fig.canvas.flush_events() except: make_post_measurements_actions()
def print_multilo_data(): """ Print the saved data from all LO settings to .pdf image. """ # create power level signal figure fig1, ax1 = plt.subplots(1, 1) ax1.grid() ax1.set_xlabel('Frequency [GHz]') ax1.set_ylabel('Power [dBFS]') # create power level image figure fig2, ax2 = plt.subplots(1, 1) ax2.grid() ax2.set_xlabel('Frequency [GHz]') ax2.set_ylabel('Power [dBFS]') # create magnitude ratio figure fig3, ax3 = plt.subplots(1, 1) ax3.grid() ax3.set_xlabel('Frequency [GHz]') ax3.set_ylabel('Mag ratio [lineal]') # create angle difference figure fig4, ax4 = plt.subplots(1, 1) ax4.grid() ax4.set_xlabel('Frequency [GHz]') ax4.set_ylabel('Angle diff [degrees]') # create analog srr figure fig5, ax5 = plt.subplots(1, 1) ax5.grid() ax5.set_xlabel('Frequency [GHz]') ax5.set_ylabel('SRR [dB]') # get colors for plotting colors = plt.rcParams['axes.prop_cycle'].by_key()['color'] for lo1_freq, color in zip(lo1_freqs, colors): for lo2_freq in lo2_freqs: # get measurement subdirectory measname = "lo1_" + str(lo1_freq) + "ghz_lo2_" + \ str(lo2_freq) + "ghz" measdir = cal_datadir + "/" + measname # compute rf frequencies rf_freqs_usb = lo1_freq + lo2_freq + (if_freqs / 1e3) # GHz rf_freqs_lsb = lo1_freq - lo2_freq - (if_freqs / 1e3) # GHz # get data caldata = np.load(measdir + "/caldata.npz") a2_toneusb = caldata['a2_toneusb'] a2_tonelsb = caldata['a2_tonelsb'] b2_toneusb = caldata['b2_toneusb'] b2_tonelsb = caldata['b2_tonelsb'] ab_toneusb = caldata['ab_toneusb'] ab_tonelsb = caldata['ab_tonelsb'] # compute power levels pow_a2_toneusb = cd.scale_and_dBFS_specdata( a2_toneusb, acc_len, dBFS) pow_a2_tonelsb = cd.scale_and_dBFS_specdata( a2_tonelsb, acc_len, dBFS) pow_b2_toneusb = cd.scale_and_dBFS_specdata( b2_toneusb, acc_len, dBFS) pow_b2_tonelsb = cd.scale_and_dBFS_specdata( b2_tonelsb, acc_len, dBFS) # plot power levels signal ax1.plot(rf_freqs_usb, pow_a2_toneusb, color=color) ax1.plot(rf_freqs_lsb, pow_b2_tonelsb, color=color) # plot power levels image ax2.plot(rf_freqs_usb, pow_a2_tonelsb, color=color) ax2.plot(rf_freqs_lsb, pow_b2_toneusb, color=color) # compute ratios ab_ratios_usb = np.conj( ab_toneusb) / a2_toneusb # (ab*)* /aa* = a*b / aa* = b/a ab_ratios_lsb = ab_tonelsb / b2_tonelsb # ab* / bb* = a/b # plot magnitude ratios ax3.plot(rf_freqs_usb, np.abs(ab_ratios_usb), color=color) ax3.plot(rf_freqs_lsb, np.abs(ab_ratios_lsb), color=color) # plot angle difference ax4.plot(rf_freqs_usb, np.angle(ab_ratios_usb, deg=True), color=color) ax4.plot(rf_freqs_lsb, np.angle(ab_ratios_lsb, deg=True), color=color) # compute srr analog srr_usb = a2_toneusb / b2_toneusb srr_lsb = b2_tonelsb / a2_tonelsb # plot srr analog plt.plot(rf_freqs_usb, 10 * np.log10(srr_usb), color=color) plt.plot(rf_freqs_lsb, 10 * np.log10(srr_lsb), color=color) # print figures fig1.savefig(cal_datadir + '/power_lev_sig.pdf') fig2.savefig(cal_datadir + '/power_lev_img.pdf') fig3.savefig(cal_datadir + '/mag_ratios.pdf') fig4.savefig(cal_datadir + '/angle_diff.pdf') fig5.savefig(cal_datadir + '/srr_analog.pdf')
def print_singlelo_data(measdir): """ Print the saved data to .pdf images for an easy check. :param measdir: directory where to read the data of single measurement and save the image (sub directory of main cal_datadir). """ # get data caldata = np.load(measdir + "/caldata.npz") a2_toneusb = caldata['a2_toneusb'] a2_tonelsb = caldata['a2_tonelsb'] b2_toneusb = caldata['b2_toneusb'] b2_tonelsb = caldata['b2_tonelsb'] ab_toneusb = caldata['ab_toneusb'] ab_tonelsb = caldata['ab_tonelsb'] # compute power levels pow_a2_toneusb = cd.scale_and_dBFS_specdata(a2_toneusb, acc_len, dBFS) pow_a2_tonelsb = cd.scale_and_dBFS_specdata(a2_tonelsb, acc_len, dBFS) pow_b2_toneusb = cd.scale_and_dBFS_specdata(b2_toneusb, acc_len, dBFS) pow_b2_tonelsb = cd.scale_and_dBFS_specdata(b2_tonelsb, acc_len, dBFS) # compute ratios ab_ratios_usb = np.conj( ab_toneusb) / a2_toneusb # (ab*)* /aa* = a*b / aa* = b/a ab_ratios_lsb = ab_tonelsb / b2_tonelsb # ab* / bb* = a/b # compute srr analog srr_usb = a2_toneusb / b2_toneusb srr_lsb = b2_tonelsb / a2_tonelsb # print power level signal plt.figure() plt.plot(if_freqs, pow_a2_toneusb, 'b', label="USB toneUSB") plt.plot(if_freqs, pow_b2_tonelsb, 'r', label="LSB toneLSB") plt.grid() plt.xlabel('Frequency [MHz]') plt.ylabel('Power [dBFS]') plt.legend() plt.savefig(measdir + '/power_lev_sig.pdf') plt.close() # print power level image plt.figure() plt.plot(if_freqs, pow_a2_tonelsb, 'b', label="USB toneLSB") plt.plot(if_freqs, pow_b2_toneusb, 'r', label="LSB toneUSB") plt.grid() plt.xlabel('Frequency [MHz]') plt.ylabel('Power [dBFS]') plt.legend() plt.savefig(measdir + '/power_lev_img.pdf') plt.close() # print magnitude ratios plt.figure() plt.plot(if_freqs, np.abs(ab_ratios_usb), 'b', label="USB") plt.plot(if_freqs, np.abs(ab_ratios_lsb), 'r', label="LSB") plt.grid() plt.xlabel('Frequency [MHz]') plt.ylabel('Mag ratio [lineal]') plt.legend() plt.savefig(measdir + '/mag_ratios.pdf') plt.close() # print angle difference plt.figure() plt.plot(if_freqs, np.angle(ab_ratios_usb, deg=True), 'b', label="USB") plt.plot(if_freqs, np.angle(ab_ratios_lsb, deg=True), 'r', label="LSB") plt.grid() plt.xlabel('Frequency [MHz]') plt.ylabel('Angle diff [degrees]') plt.legend() plt.savefig(measdir + '/angle_diff.pdf') plt.close() # print srr analog plt.figure() plt.plot(if_freqs, 10 * np.log10(srr_usb), 'b', label="USB") plt.plot(if_freqs, 10 * np.log10(srr_lsb), 'r', label="LSB") plt.grid() plt.xlabel('Frequency [MHz]') plt.ylabel('SRR [dB]') plt.legend() plt.savefig(measdir + '/srr_analog.pdf') plt.close()
def print_multilo_data(): """ Print the saved data from all LO settings to .pdf image. """ # create power level signal figure fig1, ax1 = plt.subplots(1, 1) ax1.grid() ax1.set_xlabel('Frequency [GHz]') ax1.set_ylabel('Power [dBFS]') # create power level signal figure fig2, ax2 = plt.subplots(1, 1) ax2.grid() ax2.set_xlabel('Frequency [GHz]') ax2.set_ylabel('Power [dBFS]') # create SRR figure fig3, ax3 = plt.subplots(1, 1) ax3.grid() ax3.set_xlabel('Frequency [GHz]') ax3.set_ylabel('SRR [dB]') # get colors for plotting colors = plt.rcParams['axes.prop_cycle'].by_key()['color'] for lo1_freq, color in zip(lo1_freqs, colors): for lo2_freq in lo2_freqs: # get measurement subdirectory measname = "lo1_" + str(lo1_freq) + "ghz_lo2_" + \ str(lo2_freq) + "ghz" measdir = srr_datadir + "/" + measname # compute rf frequencies rf_freqs_usb = lo1_freq + lo2_freq + (if_freqs / 1e3) # GHz rf_freqs_lsb = lo1_freq - lo2_freq - (if_freqs / 1e3) # GHz # get data srrdata = np.load(measdir + "/srrdata.npz") usb_toneusb = srrdata['usb_toneusb'] lsb_toneusb = srrdata['lsb_toneusb'] usb_tonelsb = srrdata['usb_tonelsb'] lsb_tonelsb = srrdata['lsb_tonelsb'] # compute power levels pow_usb_toneusb = cd.scale_and_dBFS_specdata( usb_toneusb, acc_len, dBFS) pow_usb_tonelsb = cd.scale_and_dBFS_specdata( usb_tonelsb, acc_len, dBFS) pow_lsb_toneusb = cd.scale_and_dBFS_specdata( lsb_toneusb, acc_len, dBFS) pow_lsb_tonelsb = cd.scale_and_dBFS_specdata( lsb_tonelsb, acc_len, dBFS) # compute SRR srr_usb = usb_toneusb / lsb_toneusb srr_lsb = lsb_tonelsb / usb_tonelsb # plot power levels signal ax1.plot(rf_freqs_usb, pow_usb_toneusb, color=color) ax1.plot(rf_freqs_lsb, pow_lsb_tonelsb, color=color) # plot power levels image ax2.plot(rf_freqs_usb, pow_usb_tonelsb, color=color) ax2.plot(rf_freqs_lsb, pow_lsb_toneusb, color=color) # plot SRR ax3.plot(rf_freqs_usb, 10 * np.log10(srr_usb), color=color) ax3.plot(rf_freqs_lsb, 10 * np.log10(srr_lsb), color=color) # print figures fig1.savefig(srr_datadir + '/power_lev_sig.pdf') fig2.savefig(srr_datadir + '/power_lev_img.pdf') fig3.savefig(srr_datadir + '/srr_digital.pdf')