def set_spectroscopy_mode(self, channels_off=None): if self.hardware_state == 'cw_mode': return self.hardware_state = 'cw_mode' self.hdawg.stop() self.cw_sequence = zi_scripts.CWSequence(awg=self.hdawg, sequencer_id=2) # self.hdawg.set_sequencer(self.cw_sequence) self.hdawg.set_sequence(2, self.cw_sequence) self.cw_sequence.set_amplitude_i(0) self.cw_sequence.set_amplitude_q(0) self.cw_sequence.set_phase_i(0) self.cw_sequence.set_phase_q(0) self.cw_sequence.set_offset_i(cw_settings['mixer_thru']) self.cw_sequence.set_offset_q(0) self.hdawg.set_output(output=1, channel=0) self.hdawg.set_output(output=1, channel=1) self.hdawg.set_output(output=1, channel=2) self.hdawg.set_output(output=1, channel=3) self.hdawg.set_output(output=1, channel=4) self.hdawg.set_output(output=1, channel=5) self.hdawg.set_output(output=0, channel=6) self.hdawg.set_output(output=0, channel=7) if channels_off is not None: for channel_off in channels_off: self.hdawg.set_output(output=0, channel=channel_off) self.pna.set_sweep_mode("LIN") self.hardware_state = 'cw_mode'
def _calibrate_zero_sa(self, sa): """Performs IQ mixer calibration for DC signals at the I and Q inputs.""" import time from scipy.optimize import fmin print(self.lo.get_frequency()) self.calibration_switch_setter() sequence = zi_scripts.CWSequence(self.sequencer_id, self.awg) self.awg.set_sequence(self.sequencer_id, sequence) sequence.stop() sequence.set_amplitude_i(0) sequence.set_amplitude_q(0) sequence.set_phase_i(0) sequence.set_phase_q(0) sequence.set_offset_i(0) sequence.set_offset_q(0) sequence.start() res_bw = 4e6 video_bw = 2e2 sa.set_res_bw(res_bw) sa.set_video_bw(video_bw) sa.set_detector('rms') sa.set_centerfreq(self.lo.get_frequency()) sa.set_sweep_time(50e-3) #time.sleep(0.1) if hasattr(sa, 'set_nop'): sa.set_span(0) sa.set_nop(1) #self.set_trigger_mode('CONT') else: sa.set_span(res_bw) self.lo.set_status(True) def tfunc(x): sequence.set_offset_i(x[0]) sequence.set_offset_q(x[1]) if hasattr(sa, 'set_nop'): result = sa.measure()['Power'].ravel()[0] else: #result = np.log10(np.sum(10**(sa.measure()['Power']/10)))*10 result = np.log10(np.sum(sa.measure()['Power']))*10 print (x, result) return result #solution = fmin(tfunc, [0.3,0.3], maxiter=30, xtol=2**(-14)) solution = fmin(tfunc, [0.1,0.1], maxiter=50, xtol=2**(-13)) x = self.clip_dc(solution[0]+1j*solution[1]) self.zero = x self.dc_calibrations[self.dc_cname()] = {'dc': solution[0]+solution[1]*1j} return self.dc_calibrations[self.dc_cname()]
def set_cw_mode(self, channels_off=None): if self.hardware_state == 'cw_mode': return self.hardware_state = 'cw_mode' self.cw_sequence = zi_scripts.CWSequence(awg=self.hdawg, sequencer_id=2) #self.hdawg.set_sequencer(self.cw_sequence) self.hdawg.set_sequence(2, self.cw_sequence) self.cw_sequence.set_amplitude_i(0) self.cw_sequence.set_amplitude_q(0) self.cw_sequence.set_phase_i(0) self.cw_sequence.set_phase_q(0) self.cw_sequence.set_offset_i(cw_settings['mixer_thru']) self.cw_sequence.set_offset_q(0) self.pna.set_sweep_mode("LIN") self.hardware_state = 'cw_mode'
def _calibrate_cw_sa(self, sa, carrier, num_sidebands = 3, use_central = False, num_sidebands_final = 9, half_length = True, use_single_sweep=False): """Performs IQ mixer calibration with the spectrum analyzer sa with the intermediate frequency.""" from scipy.optimize import fmin #import time res_bw = 4e6 video_bw = 1e3 sequence = zi_scripts.CWSequence(self.sequencer_id, self.awg) self.awg.set_sequence(self.sequencer_id, sequence) sequence.stop() sequence.set_frequency(np.abs(carrier.get_if())) sequence.set_amplitude_i(0) sequence.set_amplitude_q(0) sequence.set_phase_i(0) sequence.set_phase_q(0) sequence.set_offset_i(0) sequence.set_offset_q(0) sequence.start() self.calibration_switch_setter() if hasattr(sa, 'set_nop') and use_single_sweep: sa.set_centerfreq(self.lo.get_frequency()) sa.set_span((num_sidebands-1)*np.abs(carrier.get_if())) sa.set_nop(num_sidebands) sa.set_detector('POS') sa.set_res_bw(res_bw) sa.set_video_bw(video_bw) #sa.set_trigger_mode('CONT') sa.set_sweep_time_auto(1) else: sa.set_detector('rms') sa.set_res_bw(res_bw) sa.set_video_bw(video_bw) sa.set_span(res_bw) if hasattr(sa, 'set_nop'): res_bw = 1e6 video_bw = 2e2 sa.set_sweep_time(50e-3) sa.set_nop(1) self.lo.set_status(True) sign = 1 if carrier.get_if() > 0 else -1 solution = [-0.1, 0.1] def tfunc(x): # dc = x[0] + x[1]*1j target_sideband_id = 1 if carrier.get_if() > 0 else -1 sideband_ids = np.asarray(np.linspace(-(num_sidebands - 1) / 2, (num_sidebands - 1) / 2, num_sidebands), dtype=int) I = 0.3 Q = x[0] + x[1] * 1j if np.abs(Q) >= 0.5: Q = Q/np.abs(Q)*0.5 sequence.set_amplitude_i(np.abs(I)) sequence.set_amplitude_q(np.abs(Q)) sequence.set_phase_i(np.angle(I)*360/np.pi) sequence.set_phase_q(np.angle(Q)*360/np.pi) sequence.set_offset_i(np.real(self.calib_dc()['dc'])) sequence.set_offset_q(np.imag(self.calib_dc()['dc'])) max_amplitude = np.max([np.abs(I)+np.real(self.calib_dc()['dc']), np.abs(Q)+np.imag(self.calib_dc()['dc'])]) if max_amplitude < 1: clipping = 0 else: clipping = (max_amplitude - 1) # if we can measure all sidebands in a single sweep, do it if hasattr(sa, 'set_nop') and use_single_sweep: time.sleep(0.1) result = sa.measure()['Power'].ravel() else: # otherwise, sweep through each sideband result = [] for sideband_id in range(num_sidebands): sa.set_centerfreq( self.lo.get_frequency() + (sideband_id - (num_sidebands - 1) / 2.) * np.abs(carrier.get_if())) result.append(np.log10(np.sum(10 ** (sa.measure()['Power'] / 10))) * 10) result = np.asarray(result) if use_central: bad_sidebands = sideband_ids != target_sideband_id else: bad_sidebands = np.logical_and(sideband_ids != target_sideband_id, sideband_ids != 0) bad_power = np.sum(10 ** ((result[bad_sidebands]) / 20)) good_power = np.sum(10 ** ((result[sideband_ids == target_sideband_id]) / 20)) bad_power_dbm = np.log10(bad_power) * 20 good_power_dbm = np.log10(good_power) * 20 print('\rdc: {0: 4.2e}\tI: {1: 4.2e}\tQ:{2: 4.2e}\t' 'B: {3:4.2f} G: {4:4.2f}, C:{5:4.2f}'.format(self.calib_dc()['dc'], I, Q, bad_power_dbm, good_power_dbm, clipping) + str(result), end="") return -good_power / bad_power + np.abs(good_power / bad_power) * 10 * clipping if tfunc(solution) > tfunc(-np.asarray(solution)): solution = -np.asarray(solution) print (carrier.get_if(), carrier.frequency) for iter_id in range(1): #solution = fmin(tfunc, solution, maxiter=75, xtol=2**(-13)) solution = fmin(tfunc, solution, maxiter=30, xtol=2**(-12)) num_sidebands = num_sidebands_final use_central = True score = tfunc(solution) Q_save = solution[0]+solution[1]*1j if np.abs(Q_save) >= 0.5: Q_save = Q_save / np.abs(Q_save) * 0.5 self.rf_calibrations[self.rf_cname(carrier)] = {'I': 0.3, 'Q': Q_save, 'score': score, 'num_sidebands': num_sidebands, 'if': carrier._if, 'lo_freq': self.lo.get_frequency()} return self.rf_calibrations[self.rf_cname(carrier)]