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 rcv(self, ns, trig): """ @brief receive the data from a UDP socket @param ns: the shared Namespace between the two running Processes (multiprocessing.Manager.Namespace) @param trig: a trigger event to make sure we don't write/read shared array at same time (multiprocessing.Event) """ # set up the socket as UDP sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # always make sure we close the socket if program crashes try: # bind the socket to the input port sock.bind(('0.0.0.0', self.port)) # loop continuously and receive data while True: # read in new data as long as the trig is not set if not trig.is_set(): # receive the binary data through the socket binary_data = sock.recv(self.max_recvd_bytes) # process the binary data depending on if it is from a ddc_bram or data_bram file if self.dtype == 'ddc': times, newdata = digital_utils.process_ddc_bram( None, timestep=self.dt, data=binary_data) else: times, newdata = digital_utils.process_data_bram( None, timestep=self.dt, data=binary_data) # concatenate these unseen samples together ns.unseen_samples = np.concatenate( (ns.unseen_samples, newdata)) except: raise finally: sock.close()
def rcv(self, ns, trig): """ @brief receive the data from a UDP socket @param ns: the shared Namespace between the two running Processes (multiprocessing.Manager.Namespace) @param trig: a trigger event to make sure we don't write/read shared array at same time (multiprocessing.Event) """ # set up the socket as UDP sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # always make sure we close the socket if program crashes try: # bind the socket to the input port sock.bind( ('0.0.0.0', self.port) ) # loop continuously and receive data while True: # read in new data as long as the trig is not set if not trig.is_set(): # receive the binary data through the socket binary_data = sock.recv(self.max_recvd_bytes) # process the binary data depending on if it is from a ddc_bram or data_bram file if self.dtype == 'ddc': times, newdata = digital_utils.process_ddc_bram(None, timestep=self.dt, data=binary_data) else: times, newdata = digital_utils.process_data_bram(None, timestep=self.dt, data=binary_data) # concatenate these unseen samples together ns.unseen_samples = np.concatenate( (ns.unseen_samples, newdata) ) except: raise finally: sock.close()
if __name__ == '__main__': # parse the input arguments parser = argparse.ArgumentParser(description="charactize digital filter for input signal") 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')
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