def test_down_conversion(args): """ @brief test to see if input signal of known frequency has been down converted after mixing with known frequency """ output_steps = 2**args.freq_bits # define the timestep for the 2 time series dt_ddc = output_steps / args.clk dt_data = 1. / args.clk # read in the data from the ddc_bram and data_bram files t_ddc, d_ddc = digital_utils.process_ddc_bram(args.ddc_file, timestep=dt_ddc) t_data, d_data = digital_utils.process_data_bram(args.data_file, timestep=dt_data) # get the power spectra of the signals f_ddc, p_ddc = digital_utils.power(d_ddc, dt_ddc) f_data, p_data = digital_utils.power(d_data, dt_data) # plot the input signal on first subplot pl.subplots_adjust(hspace=0.3) pl.subplot(211) pl.plot(f_data / 1e6, p_data) # add the necessary info to the subplot pl.figtext(0.2, 0.85, 'input tone at %.3f MHz' % (args.input_freq / 1e6)) pl.xlabel('frequency (MHz)', fontsize=16) pl.ylabel('power', fontsize=16) pl.xlim(-1.5 * args.input_freq / 1e6, 1.5 * args.input_freq / 1e6) pl.subplot(212) # determine the expected down-converted frequency, as mixer frequency - input freq f_expected = abs(args.lof_int * args.clk / output_steps - args.input_freq) # plot the down-converted spectra pl.plot(f_ddc / 1e3, p_ddc) pl.figtext(0.2, 0.4, 'mixed tone at %.3f kHz' % (f_expected / 1e3)) pl.xlabel('frequency (kHZ)', fontsize=16) pl.ylabel('power', fontsize=16) pl.xlim(-1.5 * f_expected / 1e3, 1.5 * f_expected / 1e3) pl.show() return
def test_down_conversion(args): """ @brief test to see if input signal of known frequency has been down converted after mixing with known frequency """ output_steps = 2**args.freq_bits # define the timestep for the 2 time series dt_ddc = output_steps/args.clk dt_data = 1./args.clk # read in the data from the ddc_bram and data_bram files t_ddc, d_ddc = digital_utils.process_ddc_bram(args.ddc_file, timestep=dt_ddc) t_data, d_data = digital_utils.process_data_bram(args.data_file, timestep=dt_data) # get the power spectra of the signals f_ddc, p_ddc = digital_utils.power(d_ddc, dt_ddc) f_data, p_data = digital_utils.power(d_data, dt_data) # plot the input signal on first subplot pl.subplots_adjust(hspace=0.3) pl.subplot(211) pl.plot(f_data/1e6, p_data) # add the necessary info to the subplot pl.figtext(0.2, 0.85, 'input tone at %.3f MHz' %(args.input_freq/1e6)) pl.xlabel('frequency (MHz)', fontsize=16) pl.ylabel('power', fontsize=16) pl.xlim(-1.5*args.input_freq/1e6, 1.5*args.input_freq/1e6) pl.subplot(212) # determine the expected down-converted frequency, as mixer frequency - input freq f_expected = abs(args.lof_int * args.clk / output_steps - args.input_freq) # plot the down-converted spectra pl.plot(f_ddc/1e3, p_ddc) pl.figtext(0.2, 0.4, 'mixed tone at %.3f kHz' %(f_expected/1e3)) pl.xlabel('frequency (kHZ)', fontsize=16) pl.ylabel('power', fontsize=16) pl.xlim(-1.5*f_expected/1e3, 1.5*f_expected/1e3) pl.show() return
def __plot_data(self, time_ax, fft_ax, data): """ @brief plot the timeseries and power spectrum of data @param time_ax: the Axes object corresponding to timseries subplot @param fft_ax: the Axes object corresponding to power subplot @param data: the data to plot """ # clear the axes to remove old data fft_ax.cla() time_ax.cla() # get the time array (in microseconds) ts = np.arange(0, self.dt*self.max_to_plot, self.dt)*1e6 # plot the real and if data is DDC, the imaginary parts of timeseries time_ax.plot(ts, data.real, c='b') if self.dtype == 'ddc': time_ax.plot(ts, data.imag, c='r' ) # compute the power spectrum of timeseries and plot freqs, power = digital_utils.power(data, timestep=self.dt) fft_ax.plot( freqs, power, c='k') # label the axes and set limits fft_ax.set_xlabel('frequency (Hz)', fontsize=16) fft_ax.set_ylabel('power', fontsize=16) time_ax.set_xlabel(r'time ($\mu$s)', fontsize=16) time_ax.set_ylabel('signal amplitude', fontsize=16) time_ax.set_xlim(0, self.dt*self.show*1e6) # draw and then we are finished pl.draw() return
def __plot_data(self, time_ax, fft_ax, data): """ @brief plot the timeseries and power spectrum of data @param time_ax: the Axes object corresponding to timseries subplot @param fft_ax: the Axes object corresponding to power subplot @param data: the data to plot """ # clear the axes to remove old data fft_ax.cla() time_ax.cla() # get the time array (in microseconds) ts = np.arange(0, self.dt * self.max_to_plot, self.dt) * 1e6 # plot the real and if data is DDC, the imaginary parts of timeseries time_ax.plot(ts, data.real, c='b') if self.dtype == 'ddc': time_ax.plot(ts, data.imag, c='r') # compute the power spectrum of timeseries and plot freqs, power = digital_utils.power(data, timestep=self.dt) fft_ax.plot(freqs, power, c='k') # label the axes and set limits fft_ax.set_xlabel('frequency (Hz)', fontsize=16) fft_ax.set_ylabel('power', fontsize=16) time_ax.set_xlabel(r'time ($\mu$s)', fontsize=16) time_ax.set_ylabel('signal amplitude', fontsize=16) time_ax.set_xlim(0, self.dt * self.show * 1e6) # draw and then we are finished pl.draw() return
parser.add_argument('signal_file', type=str, help='name of file containing true input signal') parser.add_argument('convolved_file', type=str, help='name of file containing convolved signal') parser.add_argument('--dt', type=float, default=5e-9, help='timestep of data file') parser.add_argument('--keepDC', action='store_false', help='do not remove DC bias from input signal') parser.add_argument('--smoothing', type=int, default=0, help='kernel of gaussian smoothing function to apply to power spectra') parser.add_argument('--fitGaussian', action='store_true', help='whether to fit a gaussian to filter shape') parser.add_argument('--fitSinc', action='store_true', help='whether to fit a sinc to filter shape') args = parser.parse_args() # proces the data from the convolved and true input signal files t_conv, d_conv = digital_utils.process_data_bram(args.convolved_file, timestep=args.dt) t_true, d_true = digital_utils.process_data_bram(args.signal_file, timestep=args.dt) # get the power spectra f_conv, p_conv = digital_utils.power(d_conv, args.dt, smoothing=args.smoothing, keepDC=args.keepDC) f_true, p_true = digital_utils.power(d_true, args.dt, smoothing=args.smoothing, keepDC=args.keepDC) # restrict the filter to positive frequencies filt = p_conv/p_true inds = np.where(f_true > 0)[0] filt = filt[inds] f_true = f_true[inds]/1e6 # now in MHz # plot the filter pl.plot(f_true, filt, c='k', label='recovered filter') # fit the filter to a gaussian and sinc and plot if args.fitGaussian: t, f_fitted = fitFilter(f_true, filt, model='gaussian', bandpass=np.amax(f_true)) pl.plot(t, f_fitted, c='b', label='best fit gaussian')
help='whether to fit a gaussian to filter shape') parser.add_argument('--fitSinc', action='store_true', help='whether to fit a sinc to filter shape') args = parser.parse_args() # proces the data from the convolved and true input signal files t_conv, d_conv = digital_utils.process_data_bram(args.convolved_file, timestep=args.dt) t_true, d_true = digital_utils.process_data_bram(args.signal_file, timestep=args.dt) # get the power spectra f_conv, p_conv = digital_utils.power(d_conv, args.dt, smoothing=args.smoothing, keepDC=args.keepDC) f_true, p_true = digital_utils.power(d_true, args.dt, smoothing=args.smoothing, keepDC=args.keepDC) # restrict the filter to positive frequencies filt = p_conv / p_true inds = np.where(f_true > 0)[0] filt = filt[inds] f_true = f_true[inds] / 1e6 # now in MHz # plot the filter pl.plot(f_true, filt, c='k', label='recovered filter')