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
Example #5
0
    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