def calibrate(): logging.info("[CALIBRATION] Starting calibration procedure") global ADC target_coeff = 1 max_amp = 2**30 #Maximum signed int value / 2 target_snr = 2 parameters = {'bc': [], 'tx': []} args_adc = config.hardware['ADC'].copy() args_adc.update({'selected_freq': config.test_params['tx_freq']}) zero_gains() analogue_IO.enable(**config.hardware['IO']) calib_metadata=dict() for chan in ["X", "Y", "Z"]: logging.info("[CALIBRATION] - Calibration, searching channel %s", chan) ADC = follower.follower() ADC.power_on() noise_level = get_trimmed_mean_amp(args_adc, chan, samples=10, max_dev=1.0) ADC.stop() logging.debug("[CALIBRATION] - Noise level = %f", noise_level) logging.debug("[CALIBRATION] - Find tx_coeff (what's the read amplitude it the current channel for a tx gain of 1)") tx_coeff = get_tx_coeff(args_adc, 0.0001, max_amp, 'tx', chan, noise_level) test_tx_gain = min(target_coeff, 0.3 * max_amp / tx_coeff) logging.debug("[CALIBRATION] - test_tx_gain = %f, tx_coeff = %f", test_tx_gain, tx_coeff) ADC = follower.follower() ADC.power_on() waveform_tx_only = ADC.get_sample_freq(**args_adc) ADC.stop() AWG.setGain('tx', 0, oneshot=True) logging.debug("[CALIBRATION] - Find bc_coeff (what's the read amplitude it the current channel for a bucking gain of 1)") bc_coeff = get_tx_coeff(args_adc, 0.0001, max_amp, chan, chan, noise_level) test_bc_gain = min(target_coeff, 0.7 * test_tx_gain * tx_coeff / bc_coeff, 0.3 * max_amp / bc_coeff) logging.debug("[CALIBRATION] - test_bc_gain = %f, bc_coeff = %f", test_bc_gain, bc_coeff) logging.debug("[CALIBRATION] - Use the coefficients we've found to find the best phase shift") AWG.program() AWG.setGain('tx', test_tx_gain) AWG.setGain(chan, test_bc_gain) AWG.run() best_phase = phase_min(args_adc, chan, samples=5) logging.info("[CALIBRATION] - Channel %s first pass results: tx=%f, bc=%f @ %f deg", chan, test_tx_gain, test_bc_gain, best_phase) # Now for the fine tuning: old_res = max_amp sig_test = -1 for iter in range(10): if tx_coeff <= bc_coeff: tx_gain = target_coeff bc_gain = target_coeff * tx_coeff / bc_coeff else: bc_gain = target_coeff tx_gain = target_coeff * bc_coeff / tx_coeff logging.debug("[CALIBRATION] - Fine tuning, bc_gain = %f, tx_gain = %f", bc_gain, tx_gain) AWG.program() AWG.setGain('tx', tx_gain) AWG.setGain(chan, bc_gain) AWG.setPhaseShift(chan, best_phase, deg=True) AWG.run() current_amp = get_trimmed_mean_amp(args_adc, chan, ref_sample=waveform_tx_only) logging.debug("[CALIBRATION] - Bucking gain = %f, TX gain = %f, residual amp = %f" , bc_gain, tx_gain, current_amp) if abs(old_res) < abs(current_amp): sig_test *= -1 old_res = current_amp if abs(current_amp) > target_snr * noise_level and iter < 10: #We still have work to do then... if tx_coeff <= bc_coeff: bc_coeff = (abs((target_coeff * tx_coeff) + sig_test * current_amp) / bc_gain + bc_coeff) / 2 else: tx_coeff = (abs((target_coeff * bc_coeff) + sig_test * current_amp) / tx_gain + tx_coeff) / 2 logging.debug("[CALIBRATION] - tx_coeff = %f, bc_coeff = %f", tx_coeff, bc_coeff) else: #We found acceptable parameters! logging.info("[CALIBRATION] - Channel %s residual signal amplitude: %f with tx=%f and bc=%f %f deg", chan, current_amp, tx_gain, bc_gain, best_phase) parameters['tx'].append(tx_gain) parameters['bc'].append({'gain': bc_gain, 'ps': best_phase}) break # Record some metadata: if not calib_metadata.has_key("noise_level"): calib_metadata["noise_level"] = dict() if not calib_metadata.has_key("coeffs"): calib_metadata["coeffs"] = {'tx': dict(), 'bc': dict()} calib_metadata["coeffs"]["tx"][chan] = tx_coeff calib_metadata["coeffs"]["bc"][chan] = bc_coeff calib_metadata["noise_level"][chan] = noise_level if not calib_metadata.has_key("no_bucking_ps"): calib_metadata["no_bucking_ps"] = dict() for rec_chan in ["X", "Y", "Z"]: calib_metadata["no_bucking_ps"][rec_chan] = waveform_tx_only.get_phase_shift(ord(rec_chan) - ord('X'), deg=True) parameters["metadata"] = calib_metadata params = print_parameters(parameters) filename = time.strftime(str(config.test_params['tx_freq']) + "Hz_%Y%m%d-%H%M%S.calib") f = open(filename, 'w') f.write(str(params)) f.close() if os.path.isfile('current.calib'): os.remove('current.calib') os.symlink(filename, 'current.calib')
def zero_gains(): AWG.program() for chan in AWG.REGISTERS_GAIN: AWG.setGain(chan, 0) AWG.setPhaseShift(chan, 0) AWG.run()