Пример #1
0
    def __init__(self,
                 major_sweep_function,
                 minor_sweep_function,
                 major_values,
                 name=None,
                 parameter_name=None,
                 unit=None):
        super().__init__()

        self.major_sweep_function = \
            mc_parameter_wrapper.wrap_par_to_swf(major_sweep_function) \
                if isinstance(major_sweep_function, qcodes.Parameter) \
                else major_sweep_function
        self.minor_sweep_function = \
            mc_parameter_wrapper.wrap_par_to_swf(minor_sweep_function) \
                if isinstance(minor_sweep_function, qcodes.Parameter) \
                else minor_sweep_function
        if self.major_sweep_function.sweep_control != 'soft' or \
                self.minor_sweep_function.sweep_control != 'soft':
            raise ValueError('Offset_Sweep: Only software sweeps supported')
        self.sweep_control = 'soft'
        self.major_values = np.array(major_values)
        self.parameter_name = self.major_sweep_function.parameter_name \
            if parameter_name is None else parameter_name
        self.name = self.major_sweep_function.name if name is None else name
        self.unit = self.major_sweep_function.unit if unit is None else unit
    def measure_pulsed_spectroscopy(self, freqs, mode='ROGated_SpecGate', MC=None,
                                    analyze=True, close_fig=True, force_load=False):
        # This is a trick so I can reuse the heterodyne instr
        # to do pulsed-spectroscopy
        self.heterodyne_instr._disable_auto_seq_loading = True

        if mode=='ROMod_SpecGated':
            if ('Pulsed_spec_with_RF_mod' not in self.AWG.setup_filename.get()) or force_load:
                st_seqs.Pulsed_spec_seq_RF_mod(
                    IF=self.f_RO_mod.get(),
                    spec_pulse_length=spec_pulse_length, marker_interval=30e-6,
                    RO_pulse_delay=self.RO_pulse_delay.get())
        elif mode=='ROGated_SpecGate':
            if ('Pulsed_spec_with_RF_gated' not in self.AWG.setup_filename.get()) or force_load:
                st_seqs.Pulsed_spec_seq_RF_gated(self.RO_pars,
                                                 self.pulse_pars)
        else:
            NotImplementedError('Pulsed Spec mode not supported. Only ROMod_SpecGated and ROGated_SpecGate are avaible right now.\n')

        self.cw_source.pulsemod_state.set('on')
        self.cw_source.power.set(self.spec_pow_pulsed.get())

        self.AWG.start()
        if hasattr(self.heterodyne_instr, 'mod_amp'):
            self.heterodyne_instr.set('mod_amp', self.mod_amp_cw.get())
        else:
            self.heterodyne_instr.RF.power(self.RO_power_cw())
        MC.set_sweep_function(pw.wrap_par_to_swf(
                              self.cw_source.frequency))
        MC.set_sweep_points(freqs)
        MC.set_detector_function(det.Heterodyne_probe(self.heterodyne_instr))
        MC.run(name='pulsed-spec'+self.msmt_suffix)
        if analyze:
            ma.MeasurementAnalysis(auto=True, close_fig=close_fig)
    def measure_spectroscopy(self,
                             freqs,
                             pulsed=False,
                             MC=None,
                             analyze=True,
                             close_fig=True,
                             mode='ROGated_SpecGate',
                             force_load=False):
        self.prepare_for_continuous_wave()
        self.cw_source.on()
        if MC is None:
            MC = self.MC
        if pulsed:
            # Redirect to the pulsed spec function
            return self.measure_pulsed_spectroscopy(freqs=freqs,
                                                    MC=MC,
                                                    analyze=analyze,
                                                    close_fig=close_fig,
                                                    mode=mode,
                                                    force_load=force_load)

        MC.set_sweep_function(pw.wrap_par_to_swf(self.cw_source.frequency))
        MC.set_sweep_points(freqs)
        MC.set_detector_function(
            det.Heterodyne_probe(self.heterodyne_instr,
                                 trigger_separation=2.8e-6))
        MC.run(name='spectroscopy' + self.msmt_suffix)

        if analyze:
            ma.MeasurementAnalysis(auto=True, close_fig=close_fig)
        self.cw_source.off()
    def measure_spectroscopy(self, freqs, pulsed=False, MC=None,
                             analyze=True, close_fig=True, mode='ROGated_SpecGate',
                             force_load=True, use_max=False, update=True):
        self.prepare_for_continuous_wave()
        self.cw_source.on()
        if MC is None:
            MC = self.MC
        if pulsed:
            # Redirect to the pulsed spec function
            return self.measure_pulsed_spectroscopy(freqs=freqs,
                                                    MC=MC,
                                                    analyze=analyze,
                                                    close_fig=close_fig,
                                                    update=update,
                                                    upload=force_load)

        MC.set_sweep_function(pw.wrap_par_to_swf(
                              self.cw_source.frequency))
        MC.set_sweep_points(freqs)
        MC.set_detector_function(
            det.Heterodyne_probe(self.heterodyne_instr, trigger_separation=2.8e-6))
        MC.run(name='spectroscopy'+self.msmt_suffix)

        if analyze:
            ma.MeasurementAnalysis(auto=True, close_fig=close_fig)
        self.cw_source.off()
    def measure_spectroscopy(self, freqs, pulsed=False, MC=None,
                             analyze=True, close_fig=True,
                             force_load=True, use_max=False, update=True):
        self.prepare_for_continuous_wave()
        self.cw_source.get_instr().on()
        if MC is None:
            MC = self.MC.get_instr()
        if pulsed:
            # Redirect to the pulsed spec function
            return self.measure_pulsed_spectroscopy(freqs=freqs,
                                                    MC=MC,
                                                    analyze=analyze,
                                                    close_fig=close_fig,
                                                    update=update,
                                                    upload=force_load)

        MC.set_sweep_function(pw.wrap_par_to_swf(
                              self.cw_source.get_instr().frequency, retrieve_value=True))
        MC.set_sweep_points(freqs)
        MC.set_detector_function(
            det.Heterodyne_probe(
                self.heterodyne_instr.get_instr(),
                trigger_separation=5e-6 + self.RO_acq_integration_length(),
                RO_length=self.RO_acq_integration_length()))
        MC.run(name='spectroscopy'+self.msmt_suffix)

        if analyze:
            ma.MeasurementAnalysis(auto=True, close_fig=close_fig)
        self.cw_source.get_instr().off()
Пример #6
0
    def measure_spectroscopy(self,
                             freqs=None,
                             MC=None,
                             analyze=True,
                             close_fig=True,
                             update=False):
        """ Varies qubit drive frequency and measures the resonator
        transmittance """
        if freqs is None:
            raise ValueError("Unspecified frequencies for "
                             "measure_spectroscopy and no previous value")

        if MC is None:
            MC = self.MC

        self.prepare_for_continuous_wave()
        self.cw_source.on()

        MC.set_sweep_function(pw.wrap_par_to_swf(self.cw_source.frequency))
        MC.set_sweep_points(freqs)
        MC.set_detector_function(
            det.Heterodyne_probe(self.heterodyne_instr,
                                 trigger_separation=2.8e-6,
                                 demod_mode='single'))
        MC.run(name='spectroscopy' + self.msmt_suffix)

        self.cw_source.off()

        if analyze:
            ma.MeasurementAnalysis(auto=True, close_fig=close_fig)
Пример #7
0
    def measure_heterodyne_spectroscopy(self,
                                        freqs=None,
                                        MC=None,
                                        analyze=True,
                                        close_fig=True):
        """ Varies the frequency of the microwave source to the resonator and
        measures the transmittance """
        if freqs is None:
            raise ValueError("Unspecified frequencies for measure_heterodyne_"
                             "spectroscopy")

        if MC is None:
            MC = self.MC

        previous_freq = self.heterodyne_instr.frequency()

        self.prepare_for_continuous_wave()
        MC.set_sweep_function(
            pw.wrap_par_to_swf(self.heterodyne_instr.frequency))
        MC.set_sweep_points(freqs)
        MC.set_detector_function(
            det.Heterodyne_probe(self.heterodyne_instr,
                                 trigger_separation=5e-6,
                                 demod_mode='single'))
        MC.run(name='resonator_scan' + self.msmt_suffix)

        self.heterodyne_instr.frequency(previous_freq)

        if analyze:
            ma.MeasurementAnalysis(auto=True, close_fig=close_fig)
 def measure_rabi(self,
                  amps,
                  n=1,
                  MC=None,
                  analyze=True,
                  close_fig=True,
                  verbose=False):
     self.prepare_for_timedomain()
     if MC is None:
         MC = self.MC
     cal_points = [0, 0]
     amps = cal_points + list(amps)
     self.CBox.AWG0_mode('Codeword-trigger mode')
     self.CBox.AWG1_mode('Codeword-trigger mode')
     self.CBox.AWG2_mode('Codeword-trigger mode')
     self.CBox.set_master_controller_working_state(0, 0, 0)
     self.CBox.load_instructions('CBox_v3_test_program\Rabi.asm')
     self.CBox.set_master_controller_working_state(1, 0, 0)
     MC.set_sweep_function(pw.wrap_par_to_swf(self.LutMan.amp180))
     MC.set_sweep_points(amps)
     MC.set_detector_function(
         det.CBox_v3_single_int_avg_with_LutReload(
             self.CBox, self.LutMan, awg_nrs=[self.awg_nr.get()]))
     MC.run('Rabi-n{}'.format(n) + self.msmt_suffix)
     if analyze:
         ma.MeasurementAnalysis(auto=True, close_fig=close_fig)
 def measure_resonator_dac(self, freqs, dac_voltages,
                           MC=None, analyze=True, close_fig=True):
     self.prepare_for_continuous_wave()
     if MC is None:
         MC = self.MC
     MC.set_sweep_functions(
         [pw.wrap_par_to_swf(self.heterodyne_instr.frequency),
          pw.wrap_par_to_swf(
             self.IVVI['dac{}'.format(self.dac_channel.get())])
          ])
     MC.set_sweep_points(freqs)
     MC.set_sweep_points_2D(dac_voltages)
     MC.set_detector_function(det.Heterodyne_probe(self.heterodyne_instr))
     MC.run(name='Resonator_dac_scan'+self.msmt_suffix, mode='2D')
     if analyze:
         ma.MeasurementAnalysis(auto=True, TwoD=True, close_fig=close_fig)
Пример #10
0
 def measure_resonator_power(self, freqs, powers,
                             MC=None, analyze=True, close_fig=True):
     '''
     N.B. This one does not use powers but varies the mod-amp.
     Need to find a way to keep this function agnostic to that
     '''
     self.prepare_for_continuous_wave()
     if MC is None:
         MC = self.MC
     MC.set_sweep_functions(
         [pw.wrap_par_to_swf(self.heterodyne_instr.frequency),
          pw.wrap_par_to_swf(self.heterodyne_instr.RF_power)])
     MC.set_sweep_points(freqs)
     MC.set_sweep_points_2D(powers)
     MC.set_detector_function(det.Heterodyne_probe(self.heterodyne_instr))
     MC.run(name='Resonator_power_scan'+self.msmt_suffix, mode='2D')
     if analyze:
         ma.MeasurementAnalysis(auto=True, TwoD=True, close_fig=close_fig)
 def measure_resonator_power(self, freqs, mod_amps,
                             MC=None, analyze=True, close_fig=True):
     '''
     N.B. This one does not use powers but varies the mod-amp.
     Need to find a way to keep this function agnostic to that
     '''
     self.prepare_for_continuous_wave()
     if MC is None:
         MC = self.MC
     MC.set_sweep_functions(
         [pw.wrap_par_to_swf(self.heterodyne_instr.frequency),
          pw.wrap_par_to_swf(self.heterodyne_instr.mod_amp)])
     MC.set_sweep_points(freqs)
     MC.set_sweep_points_2D(mod_amps)
     MC.set_detector_function(det.Heterodyne_probe(self.heterodyne_instr))
     MC.run(name='Resonator_power_scan'+self.msmt_suffix, mode='2D')
     if analyze:
         ma.MeasurementAnalysis(auto=True, TwoD=True, close_fig=close_fig)
 def set_sweep_function(self, sweep_function):
     '''
     Used if only 1 sweep function is set.
     '''
     # If it is not a sweep function, assume it is a qc.parameter
     # and try to auto convert it it
     if not isinstance(sweep_function, swf.Sweep_function):
         sweep_function = wrap_par_to_swf(sweep_function)
     self.sweep_functions = [sweep_function]
     self.set_sweep_function_names(
         [str(sweep_function.name)])
 def measure_heterodyne_spectroscopy(self, freqs, MC=None,
                                     analyze=True, close_fig=True):
     self.prepare_for_continuous_wave()
     if MC is None:
         MC = self.MC
     MC.set_sweep_function(pw.wrap_par_to_swf(
                           self.heterodyne_instr.frequency))
     MC.set_sweep_points(freqs)
     MC.set_detector_function(det.Heterodyne_probe(self.heterodyne_instr, trigger_separation=2.8e-6))
     MC.run(name='Resonator_scan'+self.msmt_suffix)
     if analyze:
         ma.MeasurementAnalysis(auto=True, close_fig=close_fig)
    def set_sweep_function_2D(self, sweep_function):
        # If it is not a sweep function, assume it is a qc.parameter
        # and try to auto convert it it
        if not isinstance(sweep_function, swf.Sweep_function):
            sweep_function = wrap_par_to_swf(sweep_function)

        if len(self.sweep_functions) != 1:
            raise KeyError(
                'Specify sweepfunction 1D before specifying sweep_function 2D')
        else:
            self.sweep_functions.append(sweep_function)
            self.sweep_function_names.append(
                str(sweep_function.__class__.__name__))
 def set_sweep_functions(self, sweep_functions):
     '''
     Used to set an arbitrary number of sweep functions.
     '''
     sweep_function_names = []
     for i, sweep_func in enumerate(sweep_functions):
         # If it is not a sweep function, assume it is a qc.parameter
         # and try to auto convert it it
         if not hasattr(sweep_func, 'sweep_control'):
             sweep_func = wrap_par_to_swf(sweep_func)
             sweep_functions[i] = sweep_func
         sweep_function_names.append(str(swf.__class__.__name__))
     self.sweep_functions = sweep_functions
     self.set_sweep_function_names(sweep_function_names)
    def measure_pulsed_spectroscopy(self, freqs, MC=None, analyze=True,
                                    return_detector=False,
                                    close_fig=True, upload=True, update=True,
                                    use_max=False):
        """
        Measure pulsed spec with the qubit.

            Accepts a manual sequence parameters, which has to be a call to a
            pulse generation allowing for alternative sequences to be played
            instead of the standard one

        """

        self.prepare_for_pulsed_spec()
        self.heterodyne_instr.get_instr()._disable_auto_seq_loading = True

        self.cw_source.get_instr().pulsemod_state.set('On')
        self.cw_source.get_instr().power.set(self.spec_pow_pulsed.get())
        self.cw_source.get_instr().on()

        if MC is None:
            MC = self.MC.get_instr()

        spec_pars, RO_pars = self.get_spec_pars()
        # Upload the AWG sequence
        sq.Pulsed_spec_seq(spec_pars, RO_pars)

        self.AWG.get_instr().start()
        if return_detector:
            return det.Heterodyne_probe(self.heterodyne_instr.get_instr())

        else:
            MC.set_sweep_function(pw.wrap_par_to_swf(
                self.cw_source.get_instr().frequency, retrieve_value=True))
            MC.set_sweep_points(freqs)
            MC.set_detector_function(
                det.Heterodyne_probe(self.heterodyne_instr.get_instr()))
            MC.run(name='pulsed-spec'+self.msmt_suffix)
            if analyze or update:
                ma_obj = ma.Qubit_Spectroscopy_Analysis(
                    auto=True, label='pulsed', close_fig=close_fig)
                if use_max:
                    f_qubit = ma_obj.peaks['peak']
                else:
                    f_qubit = ma_obj.fitted_freq
                if update:
                    self.f_qubit(f_qubit)
            self.cw_source.get_instr().off()
            return f_qubit
Пример #17
0
 def __init__(self,
              sweep_functions: list,
              parameter_name=None,
              name=None,
              **kw):
     self.set_kw()
     self.sweep_functions = [mc_parameter_wrapper.wrap_par_to_swf(s)
                             if isinstance(s, qcodes.Parameter) else s
                             for s in sweep_functions]
     self.sweep_control = 'soft'
     self.name = name or 'multi_sweep'
     self.unit = sweep_functions[0].unit
     self.parameter_name = parameter_name or 'multiple_parameters'
     for i, sweep_function in enumerate(sweep_functions):
         if self.unit.lower() != sweep_function.unit.lower():
             raise ValueError('units of the sweepfunctions are not equal')
    def measure_heterodyne_spectroscopy(self, freqs, MC=None,
                                        analyze=True, close_fig=True):
        self.prepare_for_continuous_wave()

        # sqts.Pulsed_spec_seq(spec_pars, RO_pars)
        if MC is None:
            MC = self.MC.get_instr()
        MC.set_sweep_function(pw.wrap_par_to_swf(
                              self.heterodyne_instr.get_instr().frequency, retrieve_value=True))
        MC.set_sweep_points(freqs)
        MC.set_detector_function(
            det.Heterodyne_probe(self.heterodyne_instr.get_instr(),
                                 trigger_separation=self.RO_acq_integration_length()+5e-6, RO_length=self.RO_acq_integration_length()))
        MC.run(name='Resonator_scan'+self.msmt_suffix)
        if analyze:
            ma.MeasurementAnalysis(auto=True, close_fig=close_fig)
 def measure_heterodyne_spectroscopy(self,
                                     freqs,
                                     MC=None,
                                     analyze=True,
                                     close_fig=True,
                                     RO_length=2000e-9):
     self.prepare_for_continuous_wave()
     if MC is None:
         MC = self.MC
     MC.set_sweep_function(
         pw.wrap_par_to_swf(self.heterodyne_instr.frequency))
     MC.set_sweep_points(freqs)
     MC.set_detector_function(
         det.Heterodyne_probe(self.heterodyne_instr,
                              trigger_separation=2.8e-6,
                              RO_length=2274e-9))
     MC.run(name='Resonator_scan' + self.msmt_suffix)
     if analyze:
         ma.MeasurementAnalysis(auto=True, close_fig=close_fig)
    def measure_pulsed_spectroscopy(self,
                                    freqs,
                                    mode='ROGated_SpecGate',
                                    MC=None,
                                    analyze=True,
                                    close_fig=True,
                                    force_load=False):
        # This is a trick so I can reuse the heterodyne instr
        # to do pulsed-spectroscopy
        self.heterodyne_instr._disable_auto_seq_loading = True

        if mode == 'ROMod_SpecGated':
            if ('Pulsed_spec_with_RF_mod'
                    not in self.AWG.setup_filename.get()) or force_load:
                st_seqs.Pulsed_spec_seq_RF_mod(
                    IF=self.f_RO_mod.get(),
                    spec_pulse_length=spec_pulse_length,
                    marker_interval=30e-6,
                    RO_pulse_delay=self.RO_pulse_delay.get())
        elif mode == 'ROGated_SpecGate':
            if ('Pulsed_spec_with_RF_gated'
                    not in self.AWG.setup_filename.get()) or force_load:
                st_seqs.Pulsed_spec_seq_RF_gated(self.RO_pars, self.pulse_pars)
        else:
            NotImplementedError(
                'Pulsed Spec mode not supported. Only ROMod_SpecGated and ROGated_SpecGate are avaible right now.\n'
            )

        self.cw_source.pulsemod_state.set('on')
        self.cw_source.power.set(self.spec_pow_pulsed.get())

        self.AWG.start()
        if hasattr(self.heterodyne_instr, 'mod_amp'):
            self.heterodyne_instr.set('mod_amp', self.mod_amp_cw.get())
        else:
            self.heterodyne_instr.RF.power(self.RO_power_cw())
        MC.set_sweep_function(pw.wrap_par_to_swf(self.cw_source.frequency))
        MC.set_sweep_points(freqs)
        MC.set_detector_function(det.Heterodyne_probe(self.heterodyne_instr))
        MC.run(name='pulsed-spec' + self.msmt_suffix)
        if analyze:
            ma.MeasurementAnalysis(auto=True, close_fig=close_fig)
Пример #21
0
 def __init__(self,
              sweep_function,
              transformation,
              name=None,
              parameter_name=None,
              unit=None):
     super().__init__()
     if isinstance(sweep_function, qcodes.Parameter):
         sweep_function = mc_parameter_wrapper.wrap_par_to_swf(
             sweep_function)
     if sweep_function.sweep_control != 'soft':
         raise ValueError(f'{self.__class__.__name__}: Only software '
                          f'sweeps supported')
     self.sweep_function = sweep_function
     self.transformation = transformation
     self.sweep_control = sweep_function.sweep_control
     self.name = self.sweep_function.name if name is None else name
     self.unit = self.sweep_function.unit if unit is None else unit
     self.parameter_name = self.default_param_name() \
         if parameter_name is None else parameter_name
 def measure_rabi(self, amps, n=1,
                  MC=None, analyze=True, close_fig=True,
                  verbose=False):
     self.prepare_for_timedomain()
     if MC is None:
         MC = self.MC
     cal_points = [0, 0]
     amps = cal_points + list(amps)
     self.CBox.AWG0_mode('Codeword-trigger mode')
     self.CBox.AWG1_mode('Codeword-trigger mode')
     self.CBox.AWG2_mode('Codeword-trigger mode')
     self.CBox.set_master_controller_working_state(0, 0, 0)
     self.CBox.load_instructions('CBox_v3_test_program\Rabi.asm')
     self.CBox.set_master_controller_working_state(1, 0, 0)
     MC.set_sweep_function(pw.wrap_par_to_swf(self.LutMan.amp180))
     MC.set_sweep_points(amps)
     MC.set_detector_function(det.CBox_v3_single_int_avg_with_LutReload(
                              self.CBox, self.LutMan,
                              awg_nrs=[self.awg_nr.get()]))
     MC.run('Rabi-n{}'.format(n)+self.msmt_suffix)
     if analyze:
         ma.MeasurementAnalysis(auto=True, close_fig=close_fig)
Пример #23
0
    def measure_homodyne_acqusition_delay(self,
                                          delays=None,
                                          MC=None,
                                          analyze=True,
                                          close_fig=True):
        """
        Varies the delay between the homodyne modulation signal and
        acquisition. Measures the transmittance.
        """
        if delays is None:
            raise ValueError("Unspecified delays for measure_homodyne_"
                             "acquisition_delay")

        if MC is None:
            MC = self.MC

        # set number of averages to 1 due to a readout bug
        previous_nr_averages = self.heterodyne_instr.nr_averages()
        self.heterodyne_instr.nr_averages(1)
        previous_delay = self.heterodyne_instr.acquisition_delay()

        self.prepare_for_continuous_wave()
        MC.set_sweep_function(
            pw.wrap_par_to_swf(self.heterodyne_instr.acquisition_delay))
        MC.set_sweep_points(delays)
        MC.set_detector_function(
            det.Heterodyne_probe(self.heterodyne_instr,
                                 trigger_separation=5e-6,
                                 demod_mode='single'))
        MC.run(name='acquisition_delay_scan' + self.msmt_suffix)

        self.heterodyne_instr.acquisition_delay(previous_delay)
        self.heterodyne_instr.nr_averages(previous_nr_averages)

        if analyze:
            ma.MeasurementAnalysis(auto=True, close_fig=close_fig)
    def calibrate_pulse_parameters(self,
                                   method='resetless_rb',
                                   nr_cliff=10,
                                   parameters=['amp', 'motzoi', 'frequency'],
                                   amp_guess=None,
                                   motzoi_guess=None,
                                   frequency_guess=None,
                                   a_step=30,
                                   m_step=.1,
                                   f_step=20e3,
                                   MC=None,
                                   nested_MC=None,
                                   update=False,
                                   close_fig=True,
                                   verbose=True):
        '''
        Calibrates single qubit pulse parameters currently only using
        the resetless rb method (requires reasonable (80%+?) discrimination
        fidelity)

        If it there is only one parameter to sweep it will use brent's method
        instead.

        The function returns the values it found for the optimization.
        '''
        if method is not 'resetless_rb':
            raise NotImplementedError()

        self.prepare_for_timedomain()
        if MC is None:
            MC = self.MC
        if nested_MC is None:
            nested_MC = self.nested_MC

        d = self.get_resetless_rb_detector(nr_cliff=nr_cliff, MC=nested_MC)

        name = 'RB_{}cl_numerical'.format(nr_cliff)
        MC.set_detector_function(d)

        if amp_guess is None:
            amp_guess = self.amp180.get()
        if motzoi_guess is None:
            motzoi_guess = self.motzoi.get()
        if frequency_guess is None:
            frequency_guess = self.f_qubit.get()
        # Because we are sweeping the source and not the qubit frequency
        start_freq = frequency_guess - self.f_pulse_mod.get()

        sweep_functions = []
        x0 = []
        init_steps = []
        if 'amp' in parameters:
            sweep_functions.append(cb_swf.LutMan_amp180_90(self.LutMan))
            x0.append(amp_guess)
            init_steps.append(a_step)
        if 'motzoi' in parameters:
            sweep_functions.append(
                pw.wrap_par_to_swf(self.LutMan.motzoi_parameter))
            x0.append(motzoi_guess)
            init_steps.append(m_step)
        if 'frequency' in parameters:
            sweep_functions.append(pw.wrap_par_to_swf(
                self.td_source.frequency))
            x0.append(start_freq)
            init_steps.append(f_step)
        if len(sweep_functions) == 0:
            raise ValueError(
                'parameters "{}" not recognized'.format(parameters))

        MC.set_sweep_functions(sweep_functions)

        if len(sweep_functions) != 1:
            # noise ensures no_improv_break sets the termination condition
            ad_func_pars = {
                'adaptive_function': nelder_mead,
                'x0': x0,
                'initial_step': init_steps,
                'no_improv_break': 10,
                'minimize': False,
                'maxiter': 500
            }
        elif len(sweep_functions) == 1:
            # Powell does not work for 1D, use brent instead
            brack = (x0[0] - 5 * init_steps[0], x0[0])
            # Ensures relative change in parameter is relevant
            if parameters == ['frequency']:
                tol = 1e-9
            else:
                tol = 1e-3
            print('Tolerance:', tol, init_steps[0])
            print(brack)
            ad_func_pars = {
                'adaptive_function': brent,
                'brack': brack,
                'tol': tol,  # Relative tolerance in brent
                'minimize': False
            }
        MC.set_adaptive_function_parameters(ad_func_pars)
        MC.run(name=name, mode='adaptive')
        if len(sweep_functions) != 1:
            a = ma.OptimizationAnalysis(auto=True,
                                        label=name,
                                        close_fig=close_fig)
            if verbose:
                # Note printing can be made prettier
                print('Optimization converged to:')
                print('parameters: {}'.format(parameters))
                print(a.optimization_result[0])
            if update:
                for i, par in enumerate(parameters):
                    if par == 'amp':
                        self.amp180.set(a.optimization_result[0][i])
                    elif par == 'motzoi':
                        self.motzoi.set(a.optimization_result[0][i])
                    elif par == 'frequency':
                        self.f_qubit.set(a.optimization_result[0][i] +
                                         self.f_pulse_mod.get())
            return a
        else:
            a = ma.MeasurementAnalysis(label=name, close_fig=close_fig)
            print('Optimization for {} converged to: {}'.format(
                parameters[0], a.sweep_points[-1]))
            if update:
                if parameters == ['amp']:
                    self.amp180.set(a.sweep_points[-1])
                elif parameters == ['motzoi']:
                    self.motzoi.set(a.sweep_points[-1])
                elif parameters == ['frequency']:
                    self.f_qubit.set(a.sweep_points[-1] +
                                     self.f_pulse_mod.get())
            return a.sweep_points[-1]
Пример #25
0
def mixer_skewness_calibration_5014(SH, source, station,
                                    MC=None,
                                    QI_amp_ratio=None, IQ_phase=None,
                                    frequency=None, f_mod=10e6,
                                    I_ch=1, Q_ch=2,
                                    name='mixer_skewness_calibration_5014'):
    '''
    Loads a cos and sin waveform in the specified I and Q channels of the
    tektronix 5014 AWG (taken from station.pulsar.AWG).
    By looking at the frequency corresponding with the spurious sideband the
    phase_skewness and amplitude skewness that minimize the signal correspond
    to the mixer skewness.

    Inputs:
        SH              (instrument)
        Source          (instrument)     MW-source used for driving
        station         (qcodes station) Contains the AWG and pulasr sequencer
        QI_amp_ratio    (parameter)      qcodes parameter
        IQ_phase        (parameter)
        frequency       (float Hz)       Spurious SB freq: f_source - f_mod
        f_mod           (float Hz)       Modulation frequency
        I_ch/Q_ch       (int or str)     Specifies the AWG channels

    returns:
        alpha, phi     the coefficients that go in the predistortion matrix
    For the spurious sideband:
        alpha = 1/QI_amp_optimal
        phi = -IQ_phase_optimal
    For details, see Leo's notes on mixer skewness calibration in the docs
    '''
    if frequency is None:
        # Corresponds to the frequency where to minimize with the SH
        frequency = source.frequency.get() - f_mod
    if QI_amp_ratio is None:
        QI_amp_ratio = ManualParameter('QI_amp', initial_value=1)
    if IQ_phase is None:
        IQ_phase = ManualParameter('IQ_phase', unit='deg', initial_value=0)
    if MC is None:
        MC = station.MC
    if type(I_ch) is int:
        I_ch = 'ch{}'.format(I_ch)
    if type(Q_ch) is int:
        Q_ch = 'ch{}'.format(Q_ch)

    d = det.SH_mixer_skewness_det(frequency, QI_amp_ratio, IQ_phase, SH,
                                  f_mod=f_mod,
                                  I_ch=I_ch, Q_ch=Q_ch, station=station)
    S1 = pw.wrap_par_to_swf(QI_amp_ratio)
    S2 = pw.wrap_par_to_swf(IQ_phase)

    ad_func_pars = {'adaptive_function': nelder_mead,
                    'x0': [1.0, 0.0],
                    'initial_step': [.15, 10],
                    'no_improv_break': 12,
                    'minimize': True,
                    'maxiter': 500}
    MC.set_sweep_functions([S1, S2])
    MC.set_detector_function(d)
    MC.set_adaptive_function_parameters(ad_func_pars)
    MC.run(name=name, mode='adaptive')
    a = ma.OptimizationAnalysis()
    # phi and alpha are the coefficients that go in the predistortion matrix
    alpha = 1/a.optimization_result[0][0]
    phi = -1*a.optimization_result[0][1]

    return phi, alpha
def mixer_skewness_calibration_5014(SH, source, station,
                                    MC=None,
                                    QI_amp_ratio=None, IQ_phase=None,
                                    frequency=None, f_mod=10e6,
                                    I_ch=1, Q_ch=2,
                                    name='mixer_skewness_calibration_5014'):
    '''
    Loads a cos and sin waveform in the specified I and Q channels of the
    tektronix 5014 AWG (taken from station.pulsar.AWG).
    By looking at the frequency corresponding with the spurious sideband the
    phase_skewness and amplitude skewness that minimize the signal correspond
    to the mixer skewness.

    Inputs:
        SH              (instrument)
        Source          (instrument)     MW-source used for driving
        station         (qcodes station) Contains the AWG and pulasr sequencer
        QI_amp_ratio    (parameter)      qcodes parameter
        IQ_phase        (parameter)
        frequency       (float Hz)       Spurious SB freq: f_source - f_mod
        f_mod           (float Hz)       Modulation frequency
        I_ch/Q_ch       (int or str)     Specifies the AWG channels

    returns:
        alpha, phi     the coefficients that go in the predistortion matrix
    For the spurious sideband:
        alpha = 1/QI_amp_optimal
        phi = -IQ_phase_optimal
    For details, see Leo's notes on mixer skewness calibration in the docs
    '''
    if frequency is None:
        # Corresponds to the frequency where to minimize with the SH
        frequency = source.frequency.get() - f_mod
    if QI_amp_ratio is None:
        QI_amp_ratio = ManualParameter('QI_amp', initial_value=1)
    if IQ_phase is None:
        IQ_phase = ManualParameter('IQ_phase', units='deg', initial_value=0)
    if MC is None:
        MC = station.MC
    if type(I_ch) is int:
        I_ch = 'ch{}'.format(I_ch)
    if type(Q_ch) is int:
        Q_ch = 'ch{}'.format(Q_ch)

    d = det.SH_mixer_skewness_det(frequency, QI_amp_ratio, IQ_phase, SH,
                                  f_mod=f_mod,
                                  I_ch=I_ch, Q_ch=Q_ch, station=station)
    S1 = pw.wrap_par_to_swf(QI_amp_ratio)
    S2 = pw.wrap_par_to_swf(IQ_phase)

    ad_func_pars = {'adaptive_function': nelder_mead,
                    'x0': [1.0, 0.0],
                    'initial_step': [.15, 10],
                    'no_improv_break': 10,
                    'minimize': True,
                    'maxiter': 500}
    MC.set_sweep_functions([S1, S2])
    MC.set_detector_function(d)
    MC.set_adaptive_function_parameters(ad_func_pars)
    MC.run(name=name, mode='adaptive')
    a = MA.OptimizationAnalysis()
    # phi and alpha are the coefficients that go in the predistortion matrix
    alpha = 1/a.optimization_result[0][0]
    phi = -1*a.optimization_result[0][1]

    return phi, alpha
def mixer_carrier_cancellation_5014(AWG, SH, source, MC,
                                    frequency=None,
                                    AWG_channel1=1,
                                    AWG_channel2=2,
                                    voltage_grid=[.1, 0.05, 0.02],
                                    xtol=0.001, **kw):
    '''
    Varies the mixer offsets to minimize leakage at the carrier frequency.
    this is the version for a tektronix AWG.

    station:    QCodes station object that contains the instruments
    source:     the source for which carrier leakage must be minimized
    frequency:  frequency in Hz on which to minimize leakage, if None uses the
                current frequency of the source

    returns:
         ch_1_min, ch_2_min

    voltage_grid defines the ranges for the preliminary coarse sweeps.
    If the range is too small, add another number infront of -0.12

    Note: Updated for QCodes
    '''
    ch_1_min = 0  # Initializing variables used later on
    ch_2_min = 0
    last_ch_1_min = 1
    last_ch_2_min = 1
    ii = 0
    min_power = 0

    source.on()
    if frequency is None:
        frequency = source.get('frequency')
    else:
        source.set('frequency', frequency)

    '''
    Make coarse sweeps to approximate the minimum
    '''
    if type(AWG_channel1) is int:
        ch1_offset = AWG['ch{}_offset'.format(AWG_channel1)]
    else:
        ch1_offset = AWG[AWG_channel1+'_offset']
    if type(AWG_channel2) is int:
        ch2_offset = AWG['ch{}_offset'.format(AWG_channel2)]
    else:
        ch2_offset = AWG[AWG_channel2+'_offset']

    ch1_swf = pw.wrap_par_to_swf(ch1_offset)
    ch2_swf = pw.wrap_par_to_swf(ch2_offset)
    for voltage_span in voltage_grid:
        # Channel 1
        MC.set_sweep_function(ch1_swf)
        MC.set_detector_function(
            det.Signal_Hound_fixed_frequency(signal_hound=SH,
                                             frequency=frequency))
        MC.set_sweep_points(np.linspace(ch_1_min + voltage_span,
                                        ch_1_min - voltage_span, 11))
        MC.run(name='Mixer_cal_Offset_%s' % AWG_channel1,
               sweep_delay=.1, debug_mode=True)
        Mixer_Calibration_Analysis = MA.Mixer_Calibration_Analysis(
            label='Mixer_cal', auto=True)
        ch_1_min = Mixer_Calibration_Analysis.fit_results[0]
        ch1_offset.set(ch_1_min)

        # Channel 2
        MC.set_sweep_function(ch2_swf)
        MC.set_sweep_points(np.linspace(ch_2_min + voltage_span,
                                        ch_2_min - voltage_span, 11))
        MC.run(name='Mixer_cal_Offset_ch%s' % AWG_channel2,
               sweep_delay=.1, debug_mode=True)
        Mixer_Calibration_Analysis = MA.Mixer_Calibration_Analysis(
            label='Mixer_cal', auto=True)
        ch_2_min = Mixer_Calibration_Analysis.fit_results[0]
        ch2_offset.set(ch_2_min)

    # Refine and repeat the sweeps to find the minimum
    while(abs(last_ch_1_min - ch_1_min) > xtol
          and abs(last_ch_2_min - ch_2_min) > xtol):
        ii += 1
        dac_resolution = 0.001
        # channel 1 finer sweep
        MC.set_sweep_function(ch1_swf)
        MC.set_sweep_points(np.linspace(ch_1_min - dac_resolution*6,
                                        ch_1_min + dac_resolution*6, 13))
        MC.run(name='Mixer_cal_Offset_%s' % AWG_channel1,
               sweep_delay=.1, debug_mode=True)
        Mixer_Calibration_Analysis = MA.Mixer_Calibration_Analysis(
            label='Mixer_cal', auto=True)
        last_ch_1_min = ch_1_min
        ch_1_min = Mixer_Calibration_Analysis.fit_results[0]
        ch1_offset.set(ch_1_min)
        # Channel 2 finer sweep
        MC.set_sweep_function(ch2_swf)
        MC.set_sweep_points(np.linspace(ch_2_min - dac_resolution*6,
                                        ch_2_min + dac_resolution*6, 13))
        MC.run(name='Mixer_cal_Offset_%s' % AWG_channel2,
               sweep_delay=.1, debug_mode=True)
        Mixer_Calibration_Analysis = MA.Mixer_Calibration_Analysis(
            label='Mixer_cal', auto=True)
        last_ch_2_min = ch_2_min
        min_power = min(Mixer_Calibration_Analysis.measured_powers)
        ch_2_min = Mixer_Calibration_Analysis.fit_results[0]
        ch2_offset.set(ch_2_min)

        if ii > 10:
            logging.error('Mixer calibration did not converge')
            break
    print(ch_1_min, ch_2_min)
    return ch_1_min, ch_2_min
    def calibrate_pulse_parameters(self, method='resetless_rb', nr_cliff=10,
                                   parameters=['amp', 'motzoi', 'frequency'],
                                   amp_guess=None, motzoi_guess=None,
                                   frequency_guess=None,
                                   a_step=30, m_step=.1, f_step=20e3,
                                   MC=None, nested_MC=None,
                                   update=False, close_fig=True,
                                   verbose=True):
        '''
        Calibrates single qubit pulse parameters currently only using
        the resetless rb method (requires reasonable (80%+?) discrimination
        fidelity)

        If it there is only one parameter to sweep it will use brent's method
        instead.

        The function returns the values it found for the optimization.
        '''
        if method is not 'resetless_rb':
            raise NotImplementedError()

        self.prepare_for_timedomain()
        if MC is None:
            MC = self.MC
        if nested_MC is None:
            nested_MC = self.nested_MC

        d = self.get_resetless_rb_detector(nr_cliff=nr_cliff, MC=nested_MC)

        name = 'RB_{}cl_numerical'.format(nr_cliff)
        MC.set_detector_function(d)

        if amp_guess is None:
            amp_guess = self.amp180.get()
        if motzoi_guess is None:
            motzoi_guess = self.motzoi.get()
        if frequency_guess is None:
            frequency_guess = self.f_qubit.get()
        # Because we are sweeping the source and not the qubit frequency
        start_freq = frequency_guess - self.f_pulse_mod.get()

        sweep_functions = []
        x0 = []
        init_steps = []
        if 'amp' in parameters:
            sweep_functions.append(cb_swf.LutMan_amp180_90(self.LutMan))
            x0.append(amp_guess)
            init_steps.append(a_step)
        if 'motzoi' in parameters:
            sweep_functions.append(
                pw.wrap_par_to_swf(self.LutMan.motzoi_parameter))
            x0.append(motzoi_guess)
            init_steps.append(m_step)
        if 'frequency' in parameters:
            sweep_functions.append(
                pw.wrap_par_to_swf(self.td_source.frequency))
            x0.append(start_freq)
            init_steps.append(f_step)
        if len(sweep_functions) == 0:
            raise ValueError(
                'parameters "{}" not recognized'.format(parameters))

        MC.set_sweep_functions(sweep_functions)

        if len(sweep_functions) != 1:
            # noise ensures no_improv_break sets the termination condition
            ad_func_pars = {'adaptive_function': nelder_mead,
                            'x0': x0,
                            'initial_step': init_steps,
                            'no_improv_break': 10,
                            'minimize': False,
                            'maxiter': 500}
        elif len(sweep_functions) == 1:
            # Powell does not work for 1D, use brent instead
            brack = (x0[0]-5*init_steps[0], x0[0])
            # Ensures relative change in parameter is relevant
            if parameters == ['frequency']:
                tol = 1e-9
            else:
                tol = 1e-3
            print('Tolerance:', tol, init_steps[0])
            print(brack)
            ad_func_pars = {'adaptive_function': brent,
                            'brack': brack,
                            'tol': tol,  # Relative tolerance in brent
                            'minimize': False}
        MC.set_adaptive_function_parameters(ad_func_pars)
        MC.run(name=name, mode='adaptive')
        if len(sweep_functions) != 1:
            a = ma.OptimizationAnalysis(auto=True, label=name,
                                        close_fig=close_fig)
            if verbose:
                # Note printing can be made prettier
                print('Optimization converged to:')
                print('parameters: {}'.format(parameters))
                print(a.optimization_result[0])
            if update:
                for i, par in enumerate(parameters):
                    if par == 'amp':
                        self.amp180.set(a.optimization_result[0][i])
                    elif par == 'motzoi':
                        self.motzoi.set(a.optimization_result[0][i])
                    elif par == 'frequency':
                        self.f_qubit.set(a.optimization_result[0][i] +
                                         self.f_pulse_mod.get())
            return a
        else:
            a = ma.MeasurementAnalysis(label=name, close_fig=close_fig)
            print('Optimization for {} converged to: {}'.format(
                parameters[0], a.sweep_points[-1]))
            if update:
                if parameters == ['amp']:
                    self.amp180.set(a.sweep_points[-1])
                elif parameters == ['motzoi']:
                    self.motzoi.set(a.sweep_points[-1])
                elif parameters == ['frequency']:
                    self.f_qubit.set(a.sweep_points[-1]+self.f_pulse_mod.get())
            return a.sweep_points[-1]