def test_uploading_standard_pulses(self): # Tests that all waveforms are present and no error is raised. self.AWG8_MW_LutMan.load_waveforms_onto_AWG_lookuptable() expected_wf = wf.mod_gauss( amp=self.AWG8_MW_LutMan.mw_amp180(), sigma_length=self.AWG8_MW_LutMan.mw_gauss_width(), f_modulation=self.AWG8_MW_LutMan.mw_modulation(), sampling_rate=self.AWG8_MW_LutMan.sampling_rate(), phase=0, motzoi=self.AWG8_MW_LutMan.mw_motzoi())[0] # Make sure the expected waveform has a length that is a multiple of # 8 samples. expected_wf = adjust_array_len(expected_wf, 8) uploaded_wf = self.AWG.get('wave_ch1_cw001') np.testing.assert_array_almost_equal(expected_wf, uploaded_wf) expected_wf_spec = wf.block_pulse( length=self.AWG8_MW_LutMan.spec_length(), amp=self.AWG8_MW_LutMan.spec_amp(), sampling_rate=self.AWG8_MW_LutMan.sampling_rate(), delay=0, phase=0)[0] expected_wf_spec = adjust_array_len(expected_wf_spec, 8) uploaded_wf = self.AWG.get('wave_ch1_cw008') np.testing.assert_array_almost_equal(expected_wf_spec, uploaded_wf)
def test_generating_standard_pulses(self): """Test if standard waveforms are correctly generated.""" self.AWG8_MW_LutMan.LutMap(mwl.default_mw_lutmap) print(self.AWG8_MW_LutMan.LutMap()) self.AWG8_MW_LutMan.generate_standard_waveforms() # remove this line later self.AWG8_MW_LutMan.set_default_lutmap() expected_wf = wf.mod_gauss( amp=self.AWG8_MW_LutMan.mw_amp180(), sigma_length=self.AWG8_MW_LutMan.mw_gauss_width(), f_modulation=self.AWG8_MW_LutMan.mw_modulation(), sampling_rate=self.AWG8_MW_LutMan.sampling_rate(), phase=0, motzoi=self.AWG8_MW_LutMan.mw_motzoi())[0] # expected on cw 1 based on LutMap generated_wf = self.AWG8_MW_LutMan._wave_dict[1] np.testing.assert_array_almost_equal(expected_wf, generated_wf[0]) generated_wf = self.AWG8_MW_LutMan._wave_dict[8] expected_wf_spec = wf.block_pulse( length=self.AWG8_MW_LutMan.spec_length(), amp=self.AWG8_MW_LutMan.spec_amp(), sampling_rate=self.AWG8_MW_LutMan.sampling_rate(), delay=0, phase=0)[0] np.testing.assert_array_almost_equal(expected_wf_spec, generated_wf[0])
def load_pulses_onto_AWG_lookuptable(self): self.QWG.get_instr().stop() # Microwave pulses G_amp = self.Q_amp180()/self.QWG.get_instr().get('ch{}_amp'.format(1)) # Amplitude is set using the channel amplitude (at least for now) G, D = wf.gauss_pulse(G_amp, self.Q_gauss_width(), motzoi=self.Q_motzoi(), sampling_rate=1e9) # sampling rate of QWG self.QWG.get_instr().deleteWaveformAll() self.QWG.get_instr().createWaveformReal('X180_q0_I', G) self.QWG.get_instr().createWaveformReal('X180_q0_Q', D) self.QWG.get_instr().createWaveformReal('X90_q0_I', self.Q_amp90_scale()*G) self.QWG.get_instr().createWaveformReal('X90_q0_Q', self.Q_amp90_scale()*D) self.QWG.get_instr().createWaveformReal('Y180_q0_I', D) self.QWG.get_instr().createWaveformReal('Y180_q0_Q', -G) self.QWG.get_instr().createWaveformReal('Y90_q0_I', self.Q_amp90_scale()*D) self.QWG.get_instr().createWaveformReal('Y90_q0_Q', -self.Q_amp90_scale()*G) self.QWG.get_instr().createWaveformReal('mX90_q0_I', -self.Q_amp90_scale()*G) self.QWG.get_instr().createWaveformReal('mX90_q0_Q', -self.Q_amp90_scale()*D) self.QWG.get_instr().createWaveformReal('mY90_q0_I', -self.Q_amp90_scale()*D) self.QWG.get_instr().createWaveformReal('mY90_q0_Q', self.Q_amp90_scale()*G) # Spec pulse if self.spec_pulse_type() == 'gauss': spec_G, spec_Q = wf.gauss_pulse(self.spec_amp(), self.spec_length(), motzoi=0, sampling_rate=1e9) elif self.spec_pulse_type() == 'block': spec_G, spec_Q = wf.block_pulse(self.spec_amp(), self.spec_length(), sampling_rate=1e9) self.QWG.get_instr().createWaveformReal('spec_q0_I', spec_G) self.QWG.get_instr().createWaveformReal('spec_q0_Q', spec_Q) # Filler waveform self.QWG.get_instr().createWaveformReal('zero', [0]*4) self.QWG.get_instr().codeword_0_ch1_waveform('X180_q0_I') self.QWG.get_instr().codeword_0_ch2_waveform('X180_q0_Q') self.QWG.get_instr().codeword_0_ch3_waveform('X180_q0_I') self.QWG.get_instr().codeword_0_ch4_waveform('X180_q0_Q') self.QWG.get_instr().codeword_1_ch1_waveform('Y180_q0_I') self.QWG.get_instr().codeword_1_ch2_waveform('Y180_q0_Q') self.QWG.get_instr().codeword_1_ch3_waveform('Y180_q0_I') self.QWG.get_instr().codeword_1_ch4_waveform('Y180_q0_Q') self.QWG.get_instr().codeword_2_ch1_waveform('X90_q0_I') self.QWG.get_instr().codeword_2_ch2_waveform('X90_q0_Q') self.QWG.get_instr().codeword_2_ch3_waveform('X90_q0_I') self.QWG.get_instr().codeword_2_ch4_waveform('X90_q0_Q') self.QWG.get_instr().codeword_3_ch1_waveform('Y90_q0_I') self.QWG.get_instr().codeword_3_ch2_waveform('Y90_q0_Q') self.QWG.get_instr().codeword_3_ch3_waveform('Y90_q0_I') self.QWG.get_instr().codeword_3_ch4_waveform('Y90_q0_Q') self.QWG.get_instr().codeword_4_ch1_waveform('mX90_q0_I') self.QWG.get_instr().codeword_4_ch2_waveform('mX90_q0_Q') self.QWG.get_instr().codeword_4_ch3_waveform('mX90_q0_I') self.QWG.get_instr().codeword_4_ch4_waveform('mX90_q0_Q') self.QWG.get_instr().codeword_5_ch1_waveform('mY90_q0_I') self.QWG.get_instr().codeword_5_ch2_waveform('mY90_q0_Q') self.QWG.get_instr().codeword_5_ch3_waveform('mY90_q0_I') self.QWG.get_instr().codeword_5_ch4_waveform('mY90_q0_Q') self.QWG.get_instr().codeword_6_ch1_waveform('spec_q0_I') self.QWG.get_instr().codeword_6_ch2_waveform('spec_q0_Q') self.QWG.get_instr().codeword_6_ch3_waveform('spec_q0_I') self.QWG.get_instr().codeword_6_ch4_waveform('spec_q0_Q') self.QWG.get_instr().start() self.QWG.get_instr().getOperationComplete()
def generate_standard_pulses(self): ''' Generates a basic set of pulses (I, X-180, Y-180, x-90, y-90, Block, X180_delayed) using the parameters set on this meta-instrument and returns the corresponding waveforms for both I and Q channels as a dict. Note the primitive set is a different set than the one used in Serwan's thesis. ''' # Standard qubit pulses Wave_I = [np.zeros(10), np.zeros(10)] Wave_X_180 = wf.mod_gauss(self.get('Q_amp180'), self.get('Q_gauss_width'), self.get('Q_modulation'), axis='x', motzoi=self.get('Q_motzoi_parameter'), sampling_rate=self.get('sampling_rate'), Q_phase_delay=self.get('mixer_IQ_phase_skewness')) Wave_X_90 = wf.mod_gauss(self.get('Q_amp90'), self.get('Q_gauss_width'), self.get('Q_modulation'), axis='x', motzoi=self.get('Q_motzoi_parameter'), sampling_rate=self.get('sampling_rate'), Q_phase_delay=self.get('mixer_IQ_phase_skewness')) Wave_Y_180 = wf.mod_gauss(self.get('Q_amp180'), self.get('Q_gauss_width'), self.get('Q_modulation'), axis='y', motzoi=self.get('Q_motzoi_parameter'), sampling_rate=self.get('sampling_rate'), Q_phase_delay=self.get('mixer_IQ_phase_skewness')) Wave_Y_90 = wf.mod_gauss(self.get('Q_amp90'), self.get('Q_gauss_width'), self.get('Q_modulation'), axis='y', motzoi=self.get('Q_motzoi_parameter'), sampling_rate=self.get('sampling_rate'), Q_phase_delay=self.get('mixer_IQ_phase_skewness')) Wave_mX90 = wf.mod_gauss(-self.get('Q_amp90'), self.get('Q_gauss_width'), self.get('Q_modulation'), axis='x', motzoi=self.get('Q_motzoi_parameter'), sampling_rate=self.get('sampling_rate'), Q_phase_delay=self.get('mixer_IQ_phase_skewness')) Wave_mY90 = wf.mod_gauss(-self.get('Q_amp90'), self.get('Q_gauss_width'), self.get('Q_modulation'), axis='y', motzoi=self.get('Q_motzoi_parameter'), sampling_rate=self.get('sampling_rate'), Q_phase_delay=self.get('mixer_IQ_phase_skewness')) Block = wf.block_pulse(self.get('Q_ampCW'), self.Q_block_length.get(), # ns sampling_rate=self.get('sampling_rate'), delay=0, phase=0) ModBlock = wf.mod_pulse(Block[0], Block[1], f_modulation=self.Q_modulation.get(), sampling_rate=self.sampling_rate.get(), Q_phase_delay=self.mixer_IQ_phase_skewness.get()) # RO pulses M = wf.block_pulse(self.get('M_amp'), self.M_length.get(), # ns sampling_rate=self.get('sampling_rate'), delay=0, phase=self.get('M_phi')) Mod_M = wf.mod_pulse(M[0], M[1], f_modulation=self.M_modulation.get(), sampling_rate=self.sampling_rate.get(), Q_phase_delay=self.mixer_IQ_phase_skewness.get()) # advanced RO pulses # with ramp-up M_up = wf.block_pulse(self.get('M_up_amp'), self.M_up_length.get(), # ns sampling_rate=self.get('sampling_rate'), delay=0, phase=self.get('M_up_phi')) M_up_mid = (np.concatenate((M_up[0], M[0])), np.concatenate((M_up[1], M[1]))) Mod_M_up_mid = wf.mod_pulse(M_up_mid[0], M_up_mid[1], f_modulation=self.get('M_modulation'), sampling_rate=self.get('sampling_rate'), Q_phase_delay=self.get('mixer_IQ_phase_skewness')) # with ramp-up and double frequency depletion M_down0 = wf.block_pulse(self.get('M_down_amp0'), self.get('M_down_length'), # ns sampling_rate=self.get('sampling_rate'), delay=0, phase=self.get('M_down_phi0')) M_down1 = wf.block_pulse(self.get('M_down_amp1'), self.get('M_down_length'), # ns sampling_rate=self.get('sampling_rate'), delay=0, phase=self.get('M_down_phi1')) Mod_M_down0 = wf.mod_pulse(M_down0[0], M_down1[1], f_modulation=self.get('M0_modulation'), sampling_rate=self.get('sampling_rate'), Q_phase_delay=self.get('mixer_IQ_phase_skewness')) Mod_M_down1 = wf.mod_pulse(M_down1[0], M_down1[1], f_modulation=self.get('M1_modulation'), sampling_rate=self.get('sampling_rate'), Q_phase_delay=self.get('mixer_IQ_phase_skewness')) # summing the depletion components Mod_M_down = (np.add(Mod_M_down0[0], Mod_M_down1[0]), np.add(Mod_M_down0[1], Mod_M_down1[1])) # concatenating up, mid and depletion Mod_M_up_mid_down = (np.concatenate((Mod_M_up_mid[0], Mod_M_down[0])), np.concatenate((Mod_M_up_mid[1], Mod_M_down[1]))) self._wave_dict = {'I': Wave_I, 'X180': Wave_X_180, 'Y180': Wave_Y_180, 'X90': Wave_X_90, 'Y90': Wave_Y_90, 'mX90': Wave_mX90, 'mY90': Wave_mY90, 'Block': Block, 'ModBlock': ModBlock, 'M_square': Mod_M, 'M_up_mid': Mod_M_up_mid, 'M_up_mid_double_dep': Mod_M_up_mid_down } if self.mixer_apply_predistortion_matrix(): M = self.get_mixer_predistortion_matrix() for key, val in self._wave_dict.items(): self._wave_dict[key] = np.dot(M, val) return self._wave_dict
def generate_standard_pulses(self): ''' Generates a basic set of pulses (I, X-180, Y-180, x-90, y-90, Block, X180_delayed) using the parameters set on this meta-instrument and returns the corresponding waveforms for both I and Q channels as a dict. Note the primitive set is a different set than the one used in Serwan's thesis. ''' # Standard qubit pulses Wave_I = [np.zeros(10), np.zeros(10)] Wave_X_180 = wf.mod_gauss(self.get('Q_amp180'), self.get('Q_gauss_width'), self.get('Q_modulation'), axis='x', motzoi=self.get('Q_motzoi_parameter'), sampling_rate=self.get('sampling_rate'), Q_phase_delay=self.get('mixer_IQ_phase_skewness')) Wave_X_90 = wf.mod_gauss(self.get('Q_amp90'), self.get('Q_gauss_width'), self.get('Q_modulation'), axis='x', motzoi=self.get('Q_motzoi_parameter'), sampling_rate=self.get('sampling_rate'), Q_phase_delay=self.get('mixer_IQ_phase_skewness')) Wave_Y_180 = wf.mod_gauss(self.get('Q_amp180'), self.get('Q_gauss_width'), self.get('Q_modulation'), axis='y', motzoi=self.get('Q_motzoi_parameter'), sampling_rate=self.get('sampling_rate'), Q_phase_delay=self.get('mixer_IQ_phase_skewness')) Wave_Y_90 = wf.mod_gauss(self.get('Q_amp90'), self.get('Q_gauss_width'), self.get('Q_modulation'), axis='y', motzoi=self.get('Q_motzoi_parameter'), sampling_rate=self.get('sampling_rate'), Q_phase_delay=self.get('mixer_IQ_phase_skewness')) Wave_mX90 = wf.mod_gauss(-self.get('Q_amp90'), self.get('Q_gauss_width'), self.get('Q_modulation'), axis='x', motzoi=self.get('Q_motzoi_parameter'), sampling_rate=self.get('sampling_rate'), Q_phase_delay=self.get('mixer_IQ_phase_skewness')) Wave_mY90 = wf.mod_gauss(-self.get('Q_amp90'), self.get('Q_gauss_width'), self.get('Q_modulation'), axis='y', motzoi=self.get('Q_motzoi_parameter'), sampling_rate=self.get('sampling_rate'), Q_phase_delay=self.get('mixer_IQ_phase_skewness')) Wave_Rphi180 = wf.mod_gauss(self.get('Q_amp180'), self.Q_gauss_width(), self.get('Q_modulation'), phase=self.Q_Rphi(), motzoi=self.get('Q_motzoi_parameter'), sampling_rate=self.get('sampling_rate'), Q_phase_delay=self.get('mixer_IQ_phase_skewness')) Wave_Rphi90 = wf.mod_gauss(self.get('Q_amp90'), self.Q_gauss_width(), self.get('Q_modulation'), phase=self.Q_Rphi(), motzoi=self.get('Q_motzoi_parameter'), sampling_rate=self.get('sampling_rate'), Q_phase_delay=self.get('mixer_IQ_phase_skewness')) Block = wf.block_pulse(self.get('Q_ampCW'), self.Q_block_length.get(), # ns sampling_rate=self.get('sampling_rate'), delay=0, phase=0) ModBlock = wf.mod_pulse(Block[0], Block[1], f_modulation=self.Q_modulation.get(), sampling_rate=self.sampling_rate.get(), Q_phase_delay=self.mixer_IQ_phase_skewness.get()) # RO pulses M = wf.block_pulse(self.get('M_amp'), self.M_length.get(), # ns sampling_rate=self.get('sampling_rate'), delay=0, phase=self.get('M_phi')) Mod_M = wf.mod_pulse(M[0], M[1], f_modulation=self.M_modulation.get(), sampling_rate=self.sampling_rate.get(), Q_phase_delay=self.mixer_IQ_phase_skewness.get()) # advanced RO pulses # with ramp-up M_up = wf.block_pulse(self.get('M_up_amp'), self.M_up_length.get(), # ns sampling_rate=self.get('sampling_rate'), delay=0, phase=self.get('M_up_phi')) M_up_mid = (np.concatenate((M_up[0], M[0])), np.concatenate((M_up[1], M[1]))) Mod_M_up_mid = wf.mod_pulse(M_up_mid[0], M_up_mid[1], f_modulation=self.get('M_modulation'), sampling_rate=self.get('sampling_rate'), Q_phase_delay=self.get('mixer_IQ_phase_skewness')) # with ramp-up and double frequency depletion M_down0 = wf.block_pulse(self.get('M_down_amp0'), self.get('M_down_length'), # ns sampling_rate=self.get('sampling_rate'), delay=0, phase=self.get('M_down_phi0')) M_down1 = wf.block_pulse(self.get('M_down_amp1'), self.get('M_down_length'), # ns sampling_rate=self.get('sampling_rate'), delay=0, phase=self.get('M_down_phi1')) Mod_M_down0 = wf.mod_pulse(M_down0[0], M_down1[1], f_modulation=self.get('M0_modulation'), sampling_rate=self.get('sampling_rate'), Q_phase_delay=self.get('mixer_IQ_phase_skewness')) Mod_M_down1 = wf.mod_pulse(M_down1[0], M_down1[1], f_modulation=self.get('M1_modulation'), sampling_rate=self.get('sampling_rate'), Q_phase_delay=self.get('mixer_IQ_phase_skewness')) # summing the depletion components Mod_M_down = (np.add(Mod_M_down0[0], Mod_M_down1[0]), np.add(Mod_M_down0[1], Mod_M_down1[1])) # concatenating up, mid and depletion Mod_M_up_mid_down = (np.concatenate((Mod_M_up_mid[0], Mod_M_down[0])), np.concatenate((Mod_M_up_mid[1], Mod_M_down[1]))) self._wave_dict = {'I': Wave_I, 'X180': Wave_X_180, 'Y180': Wave_Y_180, 'X90': Wave_X_90, 'Y90': Wave_Y_90, 'mX90': Wave_mX90, 'mY90': Wave_mY90, 'Rphi90': Wave_Rphi90, 'Rphi180': Wave_Rphi180, 'Block': Block, 'ModBlock': ModBlock, 'M_square': Mod_M, 'M_up_mid': Mod_M_up_mid, 'M_up_mid_double_dep': Mod_M_up_mid_down } if self.mixer_apply_predistortion_matrix(): M = self.get_mixer_predistortion_matrix() for key, val in self._wave_dict.items(): self._wave_dict[key] = np.dot(M, val) return self._wave_dict