def test_end_to_end(self, freq_shift): """Test the experiment end to end.""" exp_helper = FineFreqHelper(sx_duration=self.sx_duration, freq_shift=freq_shift) backend = MockIQBackend(exp_helper) exp_helper.dt = backend.configuration().dt freq_exp = FineFrequency(0, 160, backend) freq_exp.set_transpile_options(inst_map=self.inst_map) expdata = freq_exp.run(shots=100) self.assertExperimentDone(expdata) result = expdata.analysis_results(1) d_theta = result.value.n dt = backend.configuration().dt d_freq = d_theta / (2 * np.pi * self.sx_duration * dt) tol = 0.01e6 self.assertAlmostEqual(d_freq, freq_shift, delta=tol) self.assertEqual(result.quality, "good")
def test_calibration_version(self): """Test the calibration version of the experiment.""" exp_helper = FineFreqHelper(sx_duration=self.sx_duration, freq_shift=0.1e6) backend = MockIQBackend(exp_helper) exp_helper.dt = backend.configuration().dt fine_freq = FineFrequencyCal(0, self.cals, backend) armonk_freq = FakeArmonk().defaults().qubit_freq_est[0] freq_before = self.cals.get_parameter_value(self.cals.__drive_freq_parameter__, 0) self.assertAlmostEqual(freq_before, armonk_freq) expdata = fine_freq.run() self.assertExperimentDone(expdata) freq_after = self.cals.get_parameter_value(self.cals.__drive_freq_parameter__, 0) # Test equality up to 10kHz on a 100 kHz shift self.assertAlmostEqual(freq_after, armonk_freq + exp_helper.freq_shift, delta=1e4)
class TestFineAmplitudeCal(QiskitExperimentsTestCase): """A class to test the fine amplitude calibration experiments.""" def setUp(self): """Setup the tests""" super().setUp() library = FixedFrequencyTransmon() self.backend = MockIQBackend(FineAmpHelper(-np.pi * 0.07, np.pi, "xp")) self.backend.configuration().basis_gates.append("sx") self.backend.configuration().basis_gates.append("x") self.cals = Calibrations.from_backend(self.backend, libraries=[library]) def test_cal_options(self): """Test that the options are properly propagated.""" # Test the X gate cal amp_cal = FineXAmplitudeCal(0, self.cals, "x") exp_opt = amp_cal.experiment_options self.assertEqual(exp_opt.gate.name, "x") self.assertTrue(exp_opt.add_cal_circuits) self.assertEqual(exp_opt.result_index, -1) self.assertEqual(exp_opt.group, "default") self.assertTrue(np.allclose(exp_opt.target_angle, np.pi)) # Test the SX gate cal amp_cal = FineSXAmplitudeCal(0, self.cals, "sx") exp_opt = amp_cal.experiment_options self.assertEqual(exp_opt.gate.name, "sx") self.assertFalse(exp_opt.add_cal_circuits) self.assertEqual(exp_opt.result_index, -1) self.assertEqual(exp_opt.group, "default") self.assertTrue(np.allclose(exp_opt.target_angle, np.pi / 2)) def test_run_x_cal(self): """Test that we can transpile in the calibrations before and after update. If this test passes then we were successful in running a calibration experiment, updating a pulse parameter, having this parameter propagated to the schedules for use the next time the experiment is run. """ # Initial pulse amplitude init_amp = 0.5 amp_cal = FineXAmplitudeCal(0, self.cals, "x") circs = transpile(amp_cal.circuits(), self.backend, inst_map=self.cals.default_inst_map) with pulse.build(name="x") as expected_x: pulse.play(pulse.Drag(160, 0.5, 40, 0), pulse.DriveChannel(0)) with pulse.build(name="sx") as expected_sx: pulse.play(pulse.Drag(160, 0.25, 40, 0), pulse.DriveChannel(0)) self.assertEqual(circs[5].calibrations["x"][((0,), ())], expected_x) self.assertEqual(circs[5].calibrations["sx"][((0,), ())], expected_sx) # run the calibration experiment. This should update the amp parameter of x which we test. exp_data = amp_cal.run(self.backend) self.assertExperimentDone(exp_data) d_theta = exp_data.analysis_results(1).value.n new_amp = init_amp * np.pi / (np.pi + d_theta) circs = transpile(amp_cal.circuits(), self.backend, inst_map=self.cals.default_inst_map) x_cal = circs[5].calibrations["x"][((0,), ())] # Requires allclose due to numerical precision. self.assertTrue(np.allclose(x_cal.blocks[0].pulse.amp, new_amp)) self.assertFalse(np.allclose(x_cal.blocks[0].pulse.amp, init_amp)) self.assertEqual(circs[5].calibrations["sx"][((0,), ())], expected_sx) def test_run_sx_cal(self): """Test that we can transpile in the calibrations before and after update. If this test passes then we were successful in running a calibration experiment, updating a pulse parameter, having this parameter propagated to the schedules for use the next time the experiment is run. """ # Initial pulse amplitude init_amp = 0.25 amp_cal = FineSXAmplitudeCal(0, self.cals, "sx") circs = transpile(amp_cal.circuits(), self.backend, inst_map=self.cals.default_inst_map) with pulse.build(name="sx") as expected_sx: pulse.play(pulse.Drag(160, 0.25, 40, 0), pulse.DriveChannel(0)) self.assertEqual(circs[5].calibrations["sx"][((0,), ())], expected_sx) # run the calibration experiment. This should update the amp parameter of x which we test. exp_data = amp_cal.run(MockIQBackend(FineAmpHelper(-np.pi * 0.07, np.pi / 2, "sx"))) self.assertExperimentDone(exp_data) d_theta = exp_data.analysis_results(1).value.n new_amp = init_amp * (np.pi / 2) / (np.pi / 2 + d_theta) circs = transpile(amp_cal.circuits(), self.backend, inst_map=self.cals.default_inst_map) sx_cal = circs[5].calibrations["sx"][((0,), ())] # Requires allclose due to numerical precision. self.assertTrue(np.allclose(sx_cal.blocks[0].pulse.amp, new_amp)) self.assertFalse(np.allclose(sx_cal.blocks[0].pulse.amp, init_amp)) def test_experiment_config(self): """Test converting to and from config works""" exp = FineSXAmplitudeCal(0, self.cals, "sx") loaded_exp = FineSXAmplitudeCal.from_config(exp.config()) self.assertNotEqual(exp, loaded_exp) self.assertTrue(self.json_equiv(exp, loaded_exp)) def test_roundtrip_serializable(self): """Test round trip JSON serialization""" exp = FineSXAmplitudeCal(0, self.cals, "sx") self.assertRoundTripSerializable(exp, self.json_equiv)