Пример #1
0
    def calibrate_motzoi(self, MC=None, verbose=True, update=True):
        motzois = gen_sweep_pts(center=0, span=1, num=31)

        # large range
        a = self.measure_motzoi(MC=MC, motzois=motzois, analyze=True)
        opt_motzoi = a.optimal_motzoi
        if opt_motzoi > max(motzois) or opt_motzoi < min(motzois):
            if verbose:
                print('optimal motzoi {:.3f} '.format(opt_motzoi) +
                      'outside of measured span, aborting')
            return False

        # fine range around optimum
        motzois = gen_sweep_pts(center=a.optimal_motzoi, span=.4, num=31)
        a = self.measure_motzoi(motzois)
        opt_motzoi = a.optimal_motzoi
        if opt_motzoi > max(motzois) or opt_motzoi < min(motzois):
            if verbose:
                print('optimal motzoi {:.3f} '.format(opt_motzoi) +
                      'outside of measured span, aborting')
        if update:
            if verbose:
                print('Setting motzoi to {:.3f}'.format(opt_motzoi))
            self.motzoi(opt_motzoi)
        return opt_motzoi
Пример #2
0
 def setUpClass(self):
     self.test_file_dir = join(pq.__path__[0], 'tests', 'qasm_files')
     self.config_fn = join(self.test_file_dir, 'config.json')
     self.simple_config_fn = join(self.test_file_dir, 'config_simple.json')
     self.qubit_name = 'q0'
     self.jump_to_start = ("beq r14, r14, Exp_Start " +
                           "\t# Jump to start ad nauseam")
     self.times = gen.gen_sweep_pts(start=100e-9, stop=5e-6, step=200e-9)
     self.clocks = np.round(self.times / 5e-9).astype(int)
Пример #3
0
    def test_gen_sweep_pts(self):
        lin = gen.gen_sweep_pts(start=3.8, stop=4.2, num=21)
        np.testing.assert_array_equal(lin, np.linspace(3.8, 4.2, 21))

        linspan = gen.gen_sweep_pts(center=3.8, span=.2, num=21)
        linspan2 = gen.span_num(3.8, .2, 21)
        np.testing.assert_array_equal(linspan, linspan2)

        ran = gen.gen_sweep_pts(start=3.8, stop=4.2, step=.05)
        np.testing.assert_array_equal(ran, np.arange(3.8, 4.2001, .05))

        ran = gen.gen_sweep_pts(center=3.8, span=.2, step=.05)
        np.testing.assert_array_equal(ran, gen.span_step(3.8, .200, .05))

        # missing arguments or invalid combinations of arguments should
        # raise errors
        with self.assertRaises(ValueError):
            gen.gen_sweep_pts(center=3.8, stop=4, step=5)
        with self.assertRaises(ValueError):
            gen.gen_sweep_pts(start=3.8, stop=.3)
        with self.assertRaises(ValueError):
            gen.gen_sweep_pts(center=3.8, span=.3)
    def setUpClass(self):
        self.test_file_dir = join(pq.__path__[0], 'tests', 'qasm_files')
        self.config_fn = join(self.test_file_dir, 'config.json')

        self.times = gen.gen_sweep_pts(start=100e-9, stop=5e-6, step=200e-9)
        self.clocks = np.round(self.times / 5e-9).astype(int)
        self.simple_config_fn = join(self.test_file_dir, 'config_simple.json')
        self.jump_to_start = ("beq r14, r14, Exp_Start " +
                              "\t# Jump to start ad nauseam")
        self.QWG_flux_lutman = qlm.QWG_FluxLookuptableManager(
            'QWG_flux_lutman')

        with open(self.simple_config_fn) as data_file:
            self.config_simple = json.load(data_file)
Пример #5
0
    def calibrate_grover_1Q_phase_fine(self,
                                       correction_qubit=None,
                                       spectator_qubit=None,
                                       msmt_suffix: str = None,
                                       span: float = 0.04,
                                       num: int = 31,
                                       min_fit_pts: int = 15,
                                       MC=None) -> bool:
        '''
        Fine-tune the single qubit phase correction for the second CZ pulse
        in Grover's algorithm based on the last known value. A range around
        the last known value is measured and a parabolic fit is used to find
        the minimum.

        Args:
            correction_qubit (obj):
                    Qubit object representing the qubit to which the phase
                    correction is applied.
            spectator_qubit (obj):
                    Qubit object representing the other qubit involved in the
                    CZ.
            span (float):
                    Full span of the range around the last known value for
                    Z_amp_grover.
            num (int):
                    Number of points measured in the specified range.
            min_fit_pts (int):
                    Minimum number of points that should be used for the fit.
                    The measurement is repeated with an adapted range if
                    there are less points than left after discarding points
                    that are too far away from the minimum.
        '''
        if MC is None:
            MC = qc.station.components['MC']

        if correction_qubit is None:
            correction_qubit = self.qubits()[0]
        if spectator_qubit is None:
            spectator_qubit = self.qubits()[1]

        old_z_amp = correction_qubit.flux_LutMan.get_instr().Z_amp_grover()
        repeat_calibration = True
        while repeat_calibration:
            amp_pts = gen_sweep_pts(center=old_z_amp, span=span, num=num)
            self.measure_grover_1Q_phase(amp_pts,
                                         correction_qubit,
                                         spectator_qubit,
                                         msmt_suffix=msmt_suffix,
                                         MC=MC)
            try:
                a = ma.CZ_1Q_phase_analysis(use_diff=False, meas_vals_idx=1)
            except RuntimeError as e:
                # Analysis returns a RuntimeError when the fit fails due to
                # bad range and it can't fix itself.
                print(e)
                return False
            except Exception as e:
                raise e
            new_z_amp = a.opt_z_amp

            if len(a.fit_data) < min_fit_pts:
                print('Bad measurement range: too large or too far from '
                      'minimum for parabolic model.\nRetrying...')
                old_z_amp = new_z_amp
                if a.del_indices[0] == 0 and a.del_indices[-1] == num - 1:
                    # Values larger than one found on both sides
                    # -> reduce range
                    span *= 0.5
                continue

            if new_z_amp < amp_pts[0]:
                print('Fitted minimum below scan range. Repeating scan '
                      'around lowest point {}.'.format(amp_pts[0]))
                old_z_amp = amp_pts[0]
            elif new_z_amp > amp_pts[-1]:
                print('Fitted minimum above scan range. Repeating scan '
                      'around hightest point {}.'.format(amp_pts[-1]))
                old_z_amp = amp_pts[-1]
            else:
                repeat_calibration = False
        # This has to be set in the qubit object.
        # the "prepare_for_fluxing" in turn should ensure the right vals
        # get updated.
        correction_qubit.flux_LutMan.get_instr().Z_amp_grover(new_z_amp)
        return True
Пример #6
0
    def calibrate_CZ_1Q_phase_fine(self,
                                   correction_qubit=None,
                                   spectator_qubit=None,
                                   span: float = 0.04,
                                   num: int = 31,
                                   min_fit_pts: int = 15,
                                   MC=None,
                                   msmt_suffix: str = None) -> bool:
        '''
        Measures a the Z-amp cost function in a small range around the value
        from the last calibration, fits a parabola, extracts a new minimum,
        and sets the new Z-amp in the flux lookup table manager of the
        correction qubit.

        Args:
            correction_qubit (Instr):
                    Qubit object representing the qubit for which the single
                    qubit phase correction should be calibrated.
            spectator_qubit (Instr):
                    Qubit object representing the other qubit involved in the
                    CZ.
            span (float):
                    Full span of the range around the last known value for
                    Z-amp in which the cost function is measured.
            num (int):
                    Number of points measured in the specified range.
            min_fit_pts (int):
                    Minimum number of points that should be used for the fit.
                    The measurement is repeated with an adapted range if
                    there are less points than left after discarding points
                    that are too far away from the minimum.

        Returns:
            success (bool):
                    True if calibration succeeded, False otherwise.
        '''
        if MC is None:
            MC = qc.station.components['MC']

        if correction_qubit is None:
            correction_qubit = self.qubits()[0]
        if spectator_qubit is None:
            spectator_qubit = self.qubits()[1]

        if msmt_suffix is None:
            msmt_suffix = '_' + correction_qubit.name

        old_z_amp = correction_qubit.flux_LutMan.get_instr().Z_amp()
        repeat_calibration = True

        while repeat_calibration:
            amp_pts = gen_sweep_pts(center=old_z_amp, span=span, num=num)
            CZ_cost_Z_amp(correction_qubit,
                          spectator_qubit,
                          MC,
                          Z_amps_q0=amp_pts)
            try:
                a = ma.CZ_1Q_phase_analysis()
            except RuntimeError as e:
                # Analysis returns a RuntimeError when the fit fails due to
                # bad range and it can't fix itself.
                print(e)
                return False
            except Exception as e:
                raise e
            new_z_amp = a.opt_z_amp

            if len(a.fit_data) < min_fit_pts:
                print('Bad measurement range: too large or too far from '
                      'minimum for parabolic model.\nRetrying...')
                if a.del_indices[0] == 0:
                    old_z_amp = amp_pts[-1]
                elif a.del_indices[-1] == num - 1:
                    old_z_amp = amp_pts[0]
                elif a.del_indices[0] == 0 and a.del_indices[-1] == num - 1:
                    # Values larger than one found on both sides
                    # -> reduce range
                    span *= 0.5
                continue

            if new_z_amp < amp_pts[0]:
                print('Fitted minimum below scan range. Repeating scan '
                      'around lowest point {}.'.format(amp_pts[0]))
                old_z_amp = amp_pts[0]
            elif new_z_amp > amp_pts[-1]:
                print('Fitted minimum above scan range. Repeating scan '
                      'around hightest point {}.'.format(amp_pts[-1]))
                old_z_amp = amp_pts[-1]
            else:
                repeat_calibration = False
        # This has to be set in the qubit object.
        # the "prepare_for_fluxing" in turn should ensure the right vals
        # get updated.
        correction_qubit.flux_LutMan.get_instr().Z_amp(new_z_amp)
        return True