def compute_noise(minfreq, maxfreq, data_parent_folder, meas_folder, en_fig): # variables to be input # data_parent_folder : the folder for all datas # meas_folder : the specific folder for one measurement # en_fig : enable figure file_name_prefix = 'dat_' data_folder = (data_parent_folder + '/' + meas_folder + '/') fig_num = 200 # variables from NMR settings (param_list, value_list) = data_parser.parse_info(data_folder, 'acqu.par') # read file adcFreq = int(data_parser.find_value('adcFreq', param_list, value_list)) nrPnts = int(data_parser.find_value('nrPnts', param_list, value_list)) total_scan = int( data_parser.find_value('nrIterations', param_list, value_list)) # parse file and remove DC component # data = np.zeros(nrPnts) for m in range(1, total_scan + 1): file_path = (data_folder + file_name_prefix + '{0:03d}'.format(m)) # read the data from the file and store it in numpy array format one_scan = np.array(data_parser.read_data(file_path)) one_scan = (one_scan - np.mean(one_scan)) / \ total_scan # remove DC component # data = data + one_scan spectx, specty = nmr_fft(one_scan, adcFreq, 0) fft_range = [ i for i, value in enumerate(spectx) if (value >= minfreq and value <= maxfreq) ] # limit fft display # standard deviation of the fft print('\t\tNOISE RMS = ' + '{0:.5f}'.format(np.std(specty[fft_range]))) if en_fig: plt.ion() fig = plt.figure(fig_num) fig.clf() ax = fig.add_subplot(2, 1, 1) line1, = ax.plot(spectx[fft_range], specty[fft_range], 'r-') # ax.set_ylim(-50, 0) ax.set_xlabel('Frequency [MHz]') ax.set_ylabel('Amplitude [a.u.]') ax.set_title("Noise spectrum") ax.grid() ax = fig.add_subplot(2, 1, 2) line1, = ax.plot(one_scan, 'r-') ax.set_xlabel('Time') ax.set_ylabel('Amplitude [a.u.]') ax.set_title("Noise amplitude") ax.grid() fig.canvas.draw() fig.canvas.flush_events()
def compute_stats(minfreq, maxfreq, data_parent_folder, meas_folder, plotname, en_fig): # variables to be input # data_parent_folder : the folder for all datas # meas_folder : the specific folder for one measurement # en_fig : enable figure # compute settings process_sum_data = 1 # otherwise process raw data file_name_prefix = 'dat_' data_folder = (data_parent_folder + '/' + meas_folder + '/') fig_num = 200 # variables from NMR settings (param_list, value_list) = data_parser.parse_info(data_folder, 'acqu.par') # read file adcFreq = data_parser.find_value('adcFreq', param_list, value_list) nrPnts = int(data_parser.find_value('nrPnts', param_list, value_list)) total_scan = int( data_parser.find_value('nrIterations', param_list, value_list)) # parse file and remove DC component nmean = 0 if process_sum_data: file_path = (data_folder + 'asum') one_scan_raw = np.array(data_parser.read_data(file_path)) nmean = np.mean(one_scan_raw) one_scan = (one_scan_raw - nmean) / total_scan else: for m in range(1, total_scan + 1): file_path = (data_folder + file_name_prefix + '{0:03d}'.format(m)) # read the data from the file and store it in numpy array format one_scan_raw = np.array(data_parser.read_data(file_path)) nmean = np.mean(one_scan_raw) one_scan = (one_scan_raw - nmean) / \ total_scan # remove DC component # compute fft spectx, specty = nmr_fft(one_scan, adcFreq, 0) specty = abs(specty) fft_range = [ i for i, value in enumerate(spectx) if (value >= minfreq and value <= maxfreq) ] # limit fft display # compute std nstd = np.std(one_scan) if en_fig: plt.ion() fig = plt.figure(fig_num) # maximize window plot_backend = matplotlib.get_backend() mng = plt.get_current_fig_manager() if plot_backend == 'TkAgg': # mng.resize(*mng.window.maxsize()) mng.resize(800, 600) elif plot_backend == 'wxAgg': mng.frame.Maximize(True) elif plot_backend == 'Qt4Agg': mng.window.showMaximized() fig.clf() ax = fig.add_subplot(311) line1, = ax.plot(spectx[fft_range], specty[fft_range], 'b-') # ax.set_ylim(-50, 0) ax.set_xlabel('Frequency (MHz)') ax.set_ylabel('Amplitude (a.u.)') ax.set_title("Spectrum") ax.grid() ax = fig.add_subplot(312) x_time = np.linspace(1, len(one_scan_raw), len(one_scan_raw)) x_time = np.multiply(x_time, (1 / adcFreq)) # in us x_time = np.multiply(x_time, 1e-3) # in ms line1, = ax.plot(x_time, one_scan_raw, 'b-') ax.set_xlabel('Time(ms)') ax.set_ylabel('Amplitude (a.u.)') ax.set_title("Amplitude. std=%0.2f. mean=%0.2f." % (nstd, nmean)) ax.grid() # plot histogram n_bins = 200 ax = fig.add_subplot(313) n, bins, patches = ax.hist(one_scan, bins=n_bins) ax.set_title("Histogram") plt.tight_layout() fig.canvas.draw() fig.canvas.flush_events() # fig = plt.gcf() # obtain handle plt.savefig(data_folder + plotname) # standard deviation of signal print('\t\t: rms= ' + '{0:.4f}'.format(nstd) + ' mean= {0:.4f}'.format(nmean)) return nstd, nmean
def compute_wobble(nmrObj, data_parent_folder, meas_folder, s11_min, S11mV_ref, useRef, en_fig, fig_num): # S11mV_ref is the reference s11 corresponds to maximum reflection (can be made by totally untuning matching network, e.g. disconnecting all caps in matching network) # useRef uses the S11mV_ref as reference, otherwise it will use the max # signal available in the data # settings # put 1 if the data file uses binary representation, otherwise it is in # ascii format. Find the setting in the C programming file binary_OR_ascii = 1 # manual setting: put the same setting from the C programming data_folder = (data_parent_folder + '/' + meas_folder + '/') (param_list, value_list) = data_parser.parse_info(data_folder, 'acqu.par') # read file freqSta = data_parser.find_value('freqSta', param_list, value_list) freqSto = data_parser.find_value('freqSto', param_list, value_list) freqSpa = data_parser.find_value('freqSpa', param_list, value_list) nSamples = data_parser.find_value('nSamples', param_list, value_list) freqSamp = data_parser.find_value('freqSamp', param_list, value_list) spect_bw = (freqSamp / nSamples) * 4 # determining the RBW file_name_prefix = 'tx_acq_' # plus freqSpa/2 is to include the endpoint (just like what the C does) freqSw = np.arange(freqSta, freqSto + (freqSpa / 2), freqSpa) S11mV = np.zeros(len(freqSw)) S11_ph = np.zeros(len(freqSw)) for m in range(0, len(freqSw)): # for m in freqSw: file_path = (data_folder + file_name_prefix + '{:4.3f}'.format(freqSw[m])) if binary_OR_ascii: # one_scan = data_parser.read_hex_int16(file_path) # use binary # representation one_scan = data_parser.read_hex_int32( file_path) # use binary representation for 32-bit file else: one_scan = np.array( data_parser.read_data(file_path)) # use ascii representation os.remove(file_path) # delete the file after use # find voltage at the input of ADC in mV one_scan = one_scan * nmrObj.uvoltPerDigit / 1e3 spectx, specty = nmr_fft(one_scan, freqSamp, 0) # FIND INDEX WHERE THE MAXIMUM SIGNAL IS PRESENT # PRECISE METHOD: find reflection at the desired frequency: creating precision problem where usually the signal shift a little bit from its desired frequency # ref_idx = abs(spectx - freqSw[m]) == min(abs(spectx - freqSw[m])) # BETTER METHOD: find reflection signal peak around the bandwidth ref_idx = (abs(spectx - freqSw[m]) <= (spect_bw / 2)) # S11mV[m] = max( abs( specty[ref_idx] ) ) # find reflection peak # compute the mean of amplitude inside RBW S11mV[m] = np.mean(abs(specty[ref_idx])) S11_ph[m] = np.mean(np.angle(specty[ref_idx])) * (360 / (2 * np.pi)) if useRef: # if reference is present S11dB = 20 * np.log10(np.divide(S11mV, S11mV_ref)) # convert to dB scale else: # if reference is not present S11dB = 20 * np.log10(S11mV / max(S11mV)) # convert to dB scale S11_min10dB = (S11dB <= s11_min) minS11 = min(S11dB) minS11_freq = freqSw[np.argmin(S11dB)] try: S11_fmin = min(freqSw[S11_min10dB]) S11_fmax = max(freqSw[S11_min10dB]) except: S11_fmin = 0 S11_fmax = 0 print('S11 requirement is not satisfied...') S11_bw = S11_fmax - S11_fmin if en_fig: plt.ion() fig = plt.figure(fig_num) fig.clf() ax = fig.add_subplot(211) line1, = ax.plot(freqSw, S11dB, 'r-') ax.set_ylim(-35, 10) ax.set_ylabel('S11 [dB]') ax.set_title("Reflection Measurement (S11) Parameter") ax.grid() bx = fig.add_subplot(212) bx.plot(freqSw, S11_ph, 'r-') bx.set_xlabel('Frequency [MHz]') bx.set_ylabel('Phase (deg)') bx.set_title( 'incorrect phase due to non-correlated transmit and sampling') bx.grid() fig.canvas.draw() fig.canvas.flush_events() plt.savefig(data_folder + 'wobble.png') # write S11mV to a file with open(data_folder + 'S11mV.txt', 'w') as f: for (a, b, c) in zip(freqSw, S11dB, S11_ph): f.write('{:-8.3f},{:-8.3f},{:-7.1f}\n'.format(a, b, c)) # print(S11_fmin, S11_fmax, S11_bw) if useRef: return S11dB, S11_fmin, S11_fmax, S11_bw, minS11, minS11_freq else: return S11mV, S11_fmin, S11_fmax, S11_bw, minS11, minS11_freq
def compute_gain(nmrObj, data_parent_folder, meas_folder, en_fig, fig_num): data_folder = (data_parent_folder + '/' + meas_folder + '/') # settings # put 1 if the data file uses binary representation, otherwise it is in # ascii format. Find the setting in the C programming file binary_OR_ascii = 1 # manual setting: put the same setting from the C programming (param_list, value_list) = data_parser.parse_info(data_folder, 'acqu.par') # read file freqSta = data_parser.find_value('freqSta', param_list, value_list) freqSto = data_parser.find_value('freqSto', param_list, value_list) freqSpa = data_parser.find_value('freqSpa', param_list, value_list) nSamples = data_parser.find_value('nSamples', param_list, value_list) freqSamp = data_parser.find_value('freqSamp', param_list, value_list) spect_bw = (freqSamp / nSamples) * 4 # determining the RBW file_name_prefix = 'tx_acq_' # plus freqSpa/2 is to include the endpoint (just like what the C does) freqSw = np.arange(freqSta, freqSto + (freqSpa / 2), freqSpa) S21 = np.zeros(len(freqSw)) S21_ph = np.zeros(len(freqSw)) for m in range(0, len(freqSw)): # for m in freqSw: file_path = (data_folder + file_name_prefix + '{:4.3f}'.format(freqSw[m])) if binary_OR_ascii: # one_scan = data_parser.read_hex_int16(file_path) # use binary # representation one_scan = data_parser.read_hex_int32( file_path) # use binary representation for 32-bit file else: one_scan = np.array( data_parser.read_data(file_path)) # use ascii representation os.remove(file_path) # delete the file after use ''' plt.ion() fig = plt.figure( 64 ) fig.clf() ax = fig.add_subplot( 111 ) ax.plot( one_scan ) fig.canvas.draw() fig.canvas.flush_events() ''' # find voltage at the input of ADC in mV one_scan = one_scan * nmrObj.uvoltPerDigit / 1e3 spectx, specty = nmr_fft(one_scan, freqSamp, 0) # FIND INDEX WHERE THE MAXIMUM SIGNAL IS PRESENT # PRECISE METHOD: find reflection at the desired frequency: creating precision problem where usually the signal shift a little bit from its desired frequency # ref_idx = abs(spectx - freqSw[m]) == min(abs(spectx - freqSw[m])) # BETTER METHOD: find reflection signal peak around the bandwidth # divide 2 is due to +/- half-BW around the interested frequency ref_idx = (abs(spectx - freqSw[m]) <= (spect_bw / 2)) # compute the mean of amplitude inside RBW S21[m] = np.mean(abs(specty[ref_idx])) # compute the angle mean. Currently it is not useful because the phase # is not preserved in the sequence S21_ph[m] = np.mean(np.angle(specty[ref_idx])) * (360 / (2 * np.pi)) S21dB = 20 * np.log10(S21) # convert to dBmV scale maxS21 = max(S21dB) maxS21_freq = freqSw[np.argmax(S21dB)] if en_fig: plt.ion() fig = plt.figure(fig_num) fig.clf() ax = fig.add_subplot(111) line1, = ax.plot(freqSw, S21dB, 'r-') ax.set_ylim(-30, 80) ax.set_ylabel('S21 [dBmV]') ax.set_title("Transmission Measurement (S21) Parameter") ax.grid() # bx = fig.add_subplot( 212 ) # bx.plot( freqSw, S21_ph, 'r-' ) # bx.set_xlabel( 'Frequency [MHz]' ) # bx.set_ylabel( 'Phase (deg)' ) # bx.set_title( 'incorrect phase due to non-correlated transmit and sampling' ) # bx.grid() fig.canvas.draw() fig.canvas.flush_events() plt.savefig(data_folder + 'gain.png') # write gain values to a file with open(data_folder + 'S21.txt', 'w') as f: for (a, b, c) in zip(freqSw, S21dB, S21_ph): f.write('{:-8.3f},{:-8.3f},{:-7.1f}\n'.format(a, b, c)) return maxS21, maxS21_freq, S21
def compute_wobble(data_parent_folder, meas_folder, s11_min, en_fig, fig_num): data_folder = (data_parent_folder + '/' + meas_folder + '/') (param_list, value_list) = data_parser.parse_info(data_folder, 'acqu.par') # read file freqSta = data_parser.find_value('freqSta', param_list, value_list) freqSto = data_parser.find_value('freqSto', param_list, value_list) freqSpa = data_parser.find_value('freqSpa', param_list, value_list) nSamples = data_parser.find_value('nSamples', param_list, value_list) freqSamp = data_parser.find_value('freqSamp', param_list, value_list) spect_bw = (freqSamp / nSamples) * 8 file_name_prefix = 'wobbdata_' freqSw = np.arange(freqSta, freqSto, freqSpa) S11 = np.zeros(len(freqSw)) for m in range(0, len(freqSw)): # for m in freqSw: file_path = (data_folder + file_name_prefix + '{:4.3f}'.format(freqSw[m])) one_scan = np.array(data_parser.read_data(file_path)) spectx, specty = nmr_fft(one_scan, freqSamp, 0) # FIND INDEX WHERE THE MAXIMUM SIGNAL IS PRESENT # PRECISE METHOD: find reflection at the desired frequency: creating precision problem where usually the signal shift a little bit from its desired frequency # ref_idx = abs(spectx - freqSw[m]) == min(abs(spectx - freqSw[m])) # BETTER METHOD: find reflection signal peak around the bandwidth ref_idx = (abs(spectx - freqSw[m]) <= spect_bw) S11[m] = max(specty[ref_idx]) # find reflection peak S11 = 20 * np.log10(S11 / max(S11)) # convert to dB scale S11_min10dB = (S11 <= s11_min) minS11 = min(S11) minS11_freq = freqSw[np.argmin(S11)] try: S11_fmin = min(freqSw[S11_min10dB]) S11_fmax = max(freqSw[S11_min10dB]) except: S11_fmin = 0 S11_fmax = 0 print('S11 requirement is not satisfied...') S11_bw = S11_fmax - S11_fmin if en_fig: plt.ion() fig = plt.figure(fig_num) fig.clf() ax = fig.add_subplot(1, 1, 1) line1, = ax.plot(freqSw, S11, 'r-') ax.set_ylim(-50, 0) ax.set_xlabel('Frequency [MHz]') ax.set_ylabel('S11 [dB]') ax.set_title("Reflection Measurement (S11) Parameter") ax.grid() fig.canvas.draw() fig.canvas.flush_events() # old code, freeze after plotting # plt.figure(fig_num) # plt.plot(freqSw, S11) # plt.title("Reflection Measurement (S11) Parameter") # plt.xlabel('Frequency [MHz]') # plt.ylabel('S11 [dB]') # plt.grid() # plt.show() # print(S11_fmin, S11_fmax, S11_bw) return S11_fmin, S11_fmax, S11_bw, minS11, minS11_freq
def compute_wobble(nmrObj, data_parent_folder, meas_folder, s11_min, en_fig, fig_num): data_folder = (data_parent_folder + '/' + meas_folder + '/') (param_list, value_list) = data_parser.parse_info(data_folder, 'acqu.par') # read file freqSta = data_parser.find_value('freqSta', param_list, value_list) freqSto = data_parser.find_value('freqSto', param_list, value_list) freqSpa = data_parser.find_value('freqSpa', param_list, value_list) nSamples = data_parser.find_value('nSamples', param_list, value_list) freqSamp = data_parser.find_value('freqSamp', param_list, value_list) spect_bw = (freqSamp / nSamples) * 4 # determining the RBW file_name_prefix = 'wobbdata_' freqSw = np.arange( freqSta, freqSto + (freqSpa / 2), freqSpa ) # plus half is to remove error from floating point number operation S11 = np.zeros(len(freqSw)) S11_ph = np.zeros(len(freqSw)) for m in range(0, len(freqSw)): # for m in freqSw: file_path = (data_folder + file_name_prefix + '{:4.3f}'.format(freqSw[m])) one_scan = np.array(data_parser.read_data(file_path)) os.remove(file_path) # delete the file after use # find voltage at the input of ADC in mV one_scan = one_scan * nmrObj.uvoltPerDigit / 1e3 spectx, specty = nmr_fft(one_scan, freqSamp, 0) # FIND INDEX WHERE THE MAXIMUM SIGNAL IS PRESENT # PRECISE METHOD: find reflection at the desired frequency: creating precision problem where usually the signal shift a little bit from its desired frequency # ref_idx = abs(spectx - freqSw[m]) == min(abs(spectx - freqSw[m])) # BETTER METHOD: find reflection signal peak around the bandwidth ref_idx = (abs(spectx - freqSw[m]) <= (spect_bw / 2)) # S11[m] = max( abs( specty[ref_idx] ) ) # find reflection peak S11[m] = np.mean(abs( specty[ref_idx])) # compute the mean of amplitude inside RBW S11_ph[m] = np.mean(np.angle(specty[ref_idx])) * (360 / (2 * np.pi)) S11dB = 20 * np.log10(S11 / max(S11)) # convert to dB scale S11_min10dB = (S11dB <= s11_min) minS11 = min(S11dB) minS11_freq = freqSw[np.argmin(S11dB)] try: S11_fmin = min(freqSw[S11_min10dB]) S11_fmax = max(freqSw[S11_min10dB]) except: S11_fmin = 0 S11_fmax = 0 print('S11 requirement is not satisfied...') S11_bw = S11_fmax - S11_fmin if en_fig: plt.ion() fig = plt.figure(fig_num) fig.clf() ax = fig.add_subplot(211) line1, = ax.plot(freqSw, S11dB, 'r-') ax.set_ylim(-35, 0) ax.set_ylabel('S11 [dB]') ax.set_title("Reflection Measurement (S11) Parameter") ax.grid() bx = fig.add_subplot(212) bx.plot(freqSw, S11_ph, 'r-') bx.set_xlabel('Frequency [MHz]') bx.set_ylabel('Phase (deg)') bx.set_title( 'incorrect phase due to non-correlated transmit and sampling') bx.grid() fig.canvas.draw() fig.canvas.flush_events() plt.savefig(data_folder + 'wobble.png') # write S11 to a file with open(data_folder + 'S11.txt', 'w') as f: for (a, b, c) in zip(freqSw, S11dB, S11_ph): f.write('{:-8.3f},{:-8.3f},{:-7.1f}\n'.format(a, b, c)) # print(S11_fmin, S11_fmax, S11_bw) return S11, S11_fmin, S11_fmax, S11_bw, minS11, minS11_freq