Skip to content

Commit 46e7eec

Browse files
Rework of Stark module and workflow (#1236)
### Summary This PR moves all Stark experiments to new module `qiskit_experiments.library.driven_freq_tuning` to define a module-wise utility file. This util file contains the `StarkCoefficients` dataclass to combine all seven coefficients from third-order polynomial fit characterizing the Stark shift. This object is shared among all experiments and analyses in new module. In addition to this, `StarkP1Spectroscopy` allows users to scan xval in units of either amplitude or frequency (previously only amplitude was allowed). These two domains are mutually convertible with the `StarkCoefficients` object. The domain conversion functions are also included in the util file. ### Details and comments Experiment option names are updated to be more general, namely `amp` -> `xval` and new option `xval_type` is added. `xval_type` is either `amplitude` or `frequency`. Experimentalist can directly specify the target Stark shift by ```python exp = StarkP1Spectroscopy((0,), backend=backend) freqs = np.linspace(-70e6, 70e6, 31) exp.set_experiment_options( xvals=freqs, xval_type="frequency", ) ``` Note that this requires pre-calibration of Stark shift coefficients with `StarkRamseyXYAmpScan` experiment to convert specified frequencies into tone amplitudes, and one must save the calibration results in the experiment service. If the service is not available, one can also directly provide these coefficients instead of providing a service through the backend. ```python exp.set_experiment_options( xvals=test_freqs, xval_type="frequency", stark_coefficients=StarkCoefficients(...), ) ``` When the coefficients are already calibrated, one can estimate the maximum Stark shift available within the power budget. ```python min_freq, max_freq = util.find_min_max_frequency(-0.9, 0.9, coeffs) ``` --------- Co-authored-by: Will Shanks <[email protected]> Co-authored-by: Will Shanks <[email protected]>
1 parent 3247438 commit 46e7eec

23 files changed

+2368
-1607
lines changed

docs/apidocs/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ Experiment Modules
3030

3131
mod_calibration
3232
mod_characterization
33+
mod_driven_freq_tuning
3334
mod_randomized_benchmarking
3435
mod_tomography
3536
mod_quantum_volume
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
.. _qiskit-experiments-driven-freq-tuning:
2+
3+
.. automodule:: qiskit_experiments.library.driven_freq_tuning
4+
:no-members:
5+
:no-inherited-members:
6+
:no-special-members:

docs/manuals/characterization/stark_experiment.rst

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,110 @@ In Qiskit Experiments, the experiment option ``stark_amp`` usually refers to
211211
the height of this GaussianSquare flat-top.
212212

213213

214+
Workflow
215+
--------
216+
217+
In this example, you'll learn how to measure a spectrum of qubit relaxation versus
218+
frequency with fixed frequency transmons.
219+
As you already know, we give an offset to the qubit frequency with a Stark tone,
220+
and the workflow starts from characterizing the amount of the Stark shift against
221+
the Stark amplitude :math:`\bar{\Omega}` that you can experimentally control.
222+
223+
.. jupyter-input::
224+
225+
from qiskit_experiments.library.driven_freq_tuning import StarkRamseyXYAmpScan
226+
227+
exp = StarkRamseyXYAmpScan((0,), backend=backend)
228+
exp_data = exp.run().block_for_results()
229+
coefficients = exp_data.analysis_results("stark_coefficients").value
230+
231+
You first need to run the :class:`.StarkRamseyXYAmpScan` experiment that scans :math:`\bar{\Omega}`
232+
and estimates the amount of the resultant frequency shift.
233+
This experiment fits the frequency shift to a polynomial model which is a function of :math:`\bar{\Omega}`.
234+
You can obtain the :class:`.StarkCoefficients` object that contains
235+
all polynomial coefficients to map and reverse-map the :math:`\bar{\Omega}` to a corresponding frequency value.
236+
237+
This object may be necessary for the following spectroscopy experiment.
238+
Since Stark coefficients are stable for a relatively long time,
239+
you may want to save the coefficient values and load them later when you run the experiment.
240+
If you have an access to the Experiment service, you can just save the experiment result.
241+
242+
.. jupyter-input::
243+
244+
exp_data.save()
245+
246+
.. jupyter-output::
247+
248+
You can view the experiment online at https://quantum.ibm.com/experiments/23095777-be28-4036-9c98-89d3a915b820
249+
250+
251+
Otherwise, you can dump the coefficient object into a file with JSON format.
252+
253+
.. jupyter-input::
254+
255+
import json
256+
from qiskit_experiments.framework import ExperimentEncoder
257+
258+
with open("coefficients.json", "w") as fp:
259+
json.dump(ret_coeffs, fp, cls=ExperimentEncoder)
260+
261+
The saved object can be retrieved either from the service or file, as follows.
262+
263+
.. jupyter-input::
264+
265+
# When you have access to Experiment service
266+
from qiskit_experiments.library.driven_freq_tuning import retrieve_coefficients_from_backend
267+
268+
coefficients = retrieve_coefficients_from_backend(backend, 0)
269+
270+
# Alternatively you can load from file
271+
from qiskit_experiments.framework import ExperimentDecoder
272+
273+
with open("coefficients.json", "r") as fp:
274+
coefficients = json.load(fp, cls=ExperimentDecoder)
275+
276+
Now you can measure the qubit relaxation spectrum.
277+
The :class:`.StarkP1Spectroscopy` experiment also scans :math:`\bar{\Omega}`,
278+
but instead of measuring the frequency shift, it measures the excited state population P1
279+
after certain delay, :code:`t1_delay` in the experiment options, following the state population.
280+
You can scan the :math:`\bar{\Omega}` values either in the "frequency" or "amplitude" domain,
281+
but the :code:`stark_coefficients` option must be set to perform the frequency sweep.
282+
283+
.. jupyter-input::
284+
285+
from qiskit_experiments.library.driven_freq_tuning import StarkP1Spectroscopy
286+
287+
exp = StarkP1Spectroscopy((0,), backend=backend)
288+
289+
exp.set_experiment_options(
290+
t1_delay=20e-6,
291+
min_xval=-20e6,
292+
max_xval=20e6,
293+
xval_type="frequency",
294+
spacing="linear",
295+
stark_coefficients=coefficients,
296+
)
297+
298+
exp_data = exp.run().block_for_results()
299+
300+
You may find notches in the P1 spectrum, which may indicate the existence of TLS's
301+
in the vicinity of your qubit drive frequency.
302+
303+
.. jupyter-input::
304+
305+
exp_data.figure(0)
306+
307+
.. image:: ./stark_experiment_example.png
308+
309+
Note that this experiment doesn't yield any analysis result because the landscape of a P1 spectrum
310+
can not be predicted due to the random occurrences of the TLS and frequency collisions.
311+
If you have your own protocol to extract meaningful quantities from the data,
312+
you can write a custom analysis subclass and give it to the experiment instance before execution.
313+
See :class:`.StarkP1SpectAnalysis` for more details.
314+
315+
This protocol can be parallelized among many qubits unless crosstalk matters.
316+
317+
214318
References
215319
----------
216320

1.15 MB
Loading

qiskit_experiments/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
5050
- :mod:`qiskit_experiments.library.calibration`
5151
- :mod:`qiskit_experiments.library.characterization`
52+
- :mod:`qiskit_experiments.library.driven_freq_tuning`
5253
- :mod:`qiskit_experiments.library.randomized_benchmarking`
5354
- :mod:`qiskit_experiments.library.tomography`
5455
"""

qiskit_experiments/library/__init__.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,9 @@
7676
~characterization.FineXDrag
7777
~characterization.FineSXDrag
7878
~characterization.MultiStateDiscrimination
79-
~characterization.StarkRamseyXY
80-
~characterization.StarkRamseyXYAmpScan
79+
~driven_freq_tuning.StarkRamseyXY
80+
~driven_freq_tuning.StarkRamseyXYAmpScan
81+
~driven_freq_tuning.StarkP1Spectroscopy
8182
8283
.. _characterization two qubits:
8384
@@ -160,7 +161,6 @@ class instance to manage parameters and pulse schedules.
160161
)
161162
from .characterization import (
162163
T1,
163-
StarkP1Spectroscopy,
164164
T2Hahn,
165165
T2Ramsey,
166166
Tphi,
@@ -187,8 +187,6 @@ class instance to manage parameters and pulse schedules.
187187
CorrelatedReadoutError,
188188
ZZRamsey,
189189
MultiStateDiscrimination,
190-
StarkRamseyXY,
191-
StarkRamseyXYAmpScan,
192190
)
193191
from .randomized_benchmarking import StandardRB, InterleavedRB
194192
from .tomography import (
@@ -199,6 +197,11 @@ class instance to manage parameters and pulse schedules.
199197
MitigatedProcessTomography,
200198
)
201199
from .quantum_volume import QuantumVolume
200+
from .driven_freq_tuning import (
201+
StarkRamseyXY,
202+
StarkRamseyXYAmpScan,
203+
StarkP1Spectroscopy,
204+
)
202205

203206
# Experiment Sub-modules
204207
from . import calibration

qiskit_experiments/library/characterization/__init__.py

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
:template: autosummary/experiment.rst
2525
2626
T1
27-
StarkP1Spectroscopy
2827
T2Ramsey
2928
T2Hahn
3029
Tphi
@@ -50,8 +49,6 @@
5049
ResonatorSpectroscopy
5150
MultiStateDiscrimination
5251
ZZRamsey
53-
StarkRamseyXY
54-
StarkRamseyXYAmpScan
5552
5653
5754
Analysis
@@ -63,15 +60,13 @@
6360
6461
T1Analysis
6562
T1KerneledAnalysis
66-
StarkP1SpectAnalysis
6763
T2RamseyAnalysis
6864
T2HahnAnalysis
6965
TphiAnalysis
7066
CrossResonanceHamiltonianAnalysis
7167
DragCalAnalysis
7268
FineAmplitudeAnalysis
7369
RamseyXYAnalysis
74-
StarkRamseyXYAmpScanAnalysis
7570
ReadoutAngleAnalysis
7671
ResonatorSpectroscopyAnalysis
7772
LocalReadoutErrorAnalysis
@@ -85,8 +80,6 @@
8580
DragCalAnalysis,
8681
FineAmplitudeAnalysis,
8782
RamseyXYAnalysis,
88-
StarkRamseyXYAmpScanAnalysis,
89-
StarkP1SpectAnalysis,
9083
T2RamseyAnalysis,
9184
T1Analysis,
9285
T1KerneledAnalysis,
@@ -101,7 +94,7 @@
10194
MultiStateDiscriminationAnalysis,
10295
)
10396

104-
from .t1 import T1, StarkP1Spectroscopy
97+
from .t1 import T1
10598
from .qubit_spectroscopy import QubitSpectroscopy
10699
from .ef_spectroscopy import EFSpectroscopy
107100
from .t2ramsey import T2Ramsey
@@ -111,7 +104,7 @@
111104
from .rabi import Rabi, EFRabi
112105
from .half_angle import HalfAngle
113106
from .fine_amplitude import FineAmplitude, FineXAmplitude, FineSXAmplitude, FineZXAmplitude
114-
from .ramsey_xy import RamseyXY, StarkRamseyXY, StarkRamseyXYAmpScan
107+
from .ramsey_xy import RamseyXY
115108
from .fine_frequency import FineFrequency
116109
from .drag import RoughDrag
117110
from .readout_angle import ReadoutAngle

qiskit_experiments/library/characterization/analysis/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@
1414

1515
from .drag_analysis import DragCalAnalysis
1616
from .fine_amplitude_analysis import FineAmplitudeAnalysis
17-
from .ramsey_xy_analysis import RamseyXYAnalysis, StarkRamseyXYAmpScanAnalysis
17+
from .ramsey_xy_analysis import RamseyXYAnalysis
1818
from .t2ramsey_analysis import T2RamseyAnalysis
1919
from .t2hahn_analysis import T2HahnAnalysis
20-
from .t1_analysis import T1Analysis, T1KerneledAnalysis, StarkP1SpectAnalysis
20+
from .t1_analysis import T1Analysis, T1KerneledAnalysis
2121
from .tphi_analysis import TphiAnalysis
2222
from .cr_hamiltonian_analysis import CrossResonanceHamiltonianAnalysis
2323
from .readout_angle_analysis import ReadoutAngleAnalysis

0 commit comments

Comments
 (0)