Skip to content

Commit

Permalink
Rework of Stark module and workflow (#1236)
Browse files Browse the repository at this point in the history
### 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]>
  • Loading branch information
3 people authored Jan 31, 2024
1 parent 3247438 commit 46e7eec
Show file tree
Hide file tree
Showing 23 changed files with 2,368 additions and 1,607 deletions.
1 change: 1 addition & 0 deletions docs/apidocs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ Experiment Modules

mod_calibration
mod_characterization
mod_driven_freq_tuning
mod_randomized_benchmarking
mod_tomography
mod_quantum_volume
6 changes: 6 additions & 0 deletions docs/apidocs/mod_driven_freq_tuning.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.. _qiskit-experiments-driven-freq-tuning:

.. automodule:: qiskit_experiments.library.driven_freq_tuning
:no-members:
:no-inherited-members:
:no-special-members:
104 changes: 104 additions & 0 deletions docs/manuals/characterization/stark_experiment.rst
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,110 @@ In Qiskit Experiments, the experiment option ``stark_amp`` usually refers to
the height of this GaussianSquare flat-top.


Workflow
--------

In this example, you'll learn how to measure a spectrum of qubit relaxation versus
frequency with fixed frequency transmons.
As you already know, we give an offset to the qubit frequency with a Stark tone,
and the workflow starts from characterizing the amount of the Stark shift against
the Stark amplitude :math:`\bar{\Omega}` that you can experimentally control.

.. jupyter-input::

from qiskit_experiments.library.driven_freq_tuning import StarkRamseyXYAmpScan

exp = StarkRamseyXYAmpScan((0,), backend=backend)
exp_data = exp.run().block_for_results()
coefficients = exp_data.analysis_results("stark_coefficients").value

You first need to run the :class:`.StarkRamseyXYAmpScan` experiment that scans :math:`\bar{\Omega}`
and estimates the amount of the resultant frequency shift.
This experiment fits the frequency shift to a polynomial model which is a function of :math:`\bar{\Omega}`.
You can obtain the :class:`.StarkCoefficients` object that contains
all polynomial coefficients to map and reverse-map the :math:`\bar{\Omega}` to a corresponding frequency value.

This object may be necessary for the following spectroscopy experiment.
Since Stark coefficients are stable for a relatively long time,
you may want to save the coefficient values and load them later when you run the experiment.
If you have an access to the Experiment service, you can just save the experiment result.

.. jupyter-input::

exp_data.save()

.. jupyter-output::

You can view the experiment online at https://quantum.ibm.com/experiments/23095777-be28-4036-9c98-89d3a915b820


Otherwise, you can dump the coefficient object into a file with JSON format.

.. jupyter-input::

import json
from qiskit_experiments.framework import ExperimentEncoder

with open("coefficients.json", "w") as fp:
json.dump(ret_coeffs, fp, cls=ExperimentEncoder)

The saved object can be retrieved either from the service or file, as follows.

.. jupyter-input::

# When you have access to Experiment service
from qiskit_experiments.library.driven_freq_tuning import retrieve_coefficients_from_backend

coefficients = retrieve_coefficients_from_backend(backend, 0)

# Alternatively you can load from file
from qiskit_experiments.framework import ExperimentDecoder

with open("coefficients.json", "r") as fp:
coefficients = json.load(fp, cls=ExperimentDecoder)

Now you can measure the qubit relaxation spectrum.
The :class:`.StarkP1Spectroscopy` experiment also scans :math:`\bar{\Omega}`,
but instead of measuring the frequency shift, it measures the excited state population P1
after certain delay, :code:`t1_delay` in the experiment options, following the state population.
You can scan the :math:`\bar{\Omega}` values either in the "frequency" or "amplitude" domain,
but the :code:`stark_coefficients` option must be set to perform the frequency sweep.

.. jupyter-input::

from qiskit_experiments.library.driven_freq_tuning import StarkP1Spectroscopy

exp = StarkP1Spectroscopy((0,), backend=backend)

exp.set_experiment_options(
t1_delay=20e-6,
min_xval=-20e6,
max_xval=20e6,
xval_type="frequency",
spacing="linear",
stark_coefficients=coefficients,
)

exp_data = exp.run().block_for_results()

You may find notches in the P1 spectrum, which may indicate the existence of TLS's
in the vicinity of your qubit drive frequency.

.. jupyter-input::

exp_data.figure(0)

.. image:: ./stark_experiment_example.png

Note that this experiment doesn't yield any analysis result because the landscape of a P1 spectrum
can not be predicted due to the random occurrences of the TLS and frequency collisions.
If you have your own protocol to extract meaningful quantities from the data,
you can write a custom analysis subclass and give it to the experiment instance before execution.
See :class:`.StarkP1SpectAnalysis` for more details.

This protocol can be parallelized among many qubits unless crosstalk matters.


References
----------

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions qiskit_experiments/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
- :mod:`qiskit_experiments.library.calibration`
- :mod:`qiskit_experiments.library.characterization`
- :mod:`qiskit_experiments.library.driven_freq_tuning`
- :mod:`qiskit_experiments.library.randomized_benchmarking`
- :mod:`qiskit_experiments.library.tomography`
"""
Expand Down
13 changes: 8 additions & 5 deletions qiskit_experiments/library/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,9 @@
~characterization.FineXDrag
~characterization.FineSXDrag
~characterization.MultiStateDiscrimination
~characterization.StarkRamseyXY
~characterization.StarkRamseyXYAmpScan
~driven_freq_tuning.StarkRamseyXY
~driven_freq_tuning.StarkRamseyXYAmpScan
~driven_freq_tuning.StarkP1Spectroscopy
.. _characterization two qubits:
Expand Down Expand Up @@ -160,7 +161,6 @@ class instance to manage parameters and pulse schedules.
)
from .characterization import (
T1,
StarkP1Spectroscopy,
T2Hahn,
T2Ramsey,
Tphi,
Expand All @@ -187,8 +187,6 @@ class instance to manage parameters and pulse schedules.
CorrelatedReadoutError,
ZZRamsey,
MultiStateDiscrimination,
StarkRamseyXY,
StarkRamseyXYAmpScan,
)
from .randomized_benchmarking import StandardRB, InterleavedRB
from .tomography import (
Expand All @@ -199,6 +197,11 @@ class instance to manage parameters and pulse schedules.
MitigatedProcessTomography,
)
from .quantum_volume import QuantumVolume
from .driven_freq_tuning import (
StarkRamseyXY,
StarkRamseyXYAmpScan,
StarkP1Spectroscopy,
)

# Experiment Sub-modules
from . import calibration
Expand Down
11 changes: 2 additions & 9 deletions qiskit_experiments/library/characterization/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
:template: autosummary/experiment.rst
T1
StarkP1Spectroscopy
T2Ramsey
T2Hahn
Tphi
Expand All @@ -50,8 +49,6 @@
ResonatorSpectroscopy
MultiStateDiscrimination
ZZRamsey
StarkRamseyXY
StarkRamseyXYAmpScan
Analysis
Expand All @@ -63,15 +60,13 @@
T1Analysis
T1KerneledAnalysis
StarkP1SpectAnalysis
T2RamseyAnalysis
T2HahnAnalysis
TphiAnalysis
CrossResonanceHamiltonianAnalysis
DragCalAnalysis
FineAmplitudeAnalysis
RamseyXYAnalysis
StarkRamseyXYAmpScanAnalysis
ReadoutAngleAnalysis
ResonatorSpectroscopyAnalysis
LocalReadoutErrorAnalysis
Expand All @@ -85,8 +80,6 @@
DragCalAnalysis,
FineAmplitudeAnalysis,
RamseyXYAnalysis,
StarkRamseyXYAmpScanAnalysis,
StarkP1SpectAnalysis,
T2RamseyAnalysis,
T1Analysis,
T1KerneledAnalysis,
Expand All @@ -101,7 +94,7 @@
MultiStateDiscriminationAnalysis,
)

from .t1 import T1, StarkP1Spectroscopy
from .t1 import T1
from .qubit_spectroscopy import QubitSpectroscopy
from .ef_spectroscopy import EFSpectroscopy
from .t2ramsey import T2Ramsey
Expand All @@ -111,7 +104,7 @@
from .rabi import Rabi, EFRabi
from .half_angle import HalfAngle
from .fine_amplitude import FineAmplitude, FineXAmplitude, FineSXAmplitude, FineZXAmplitude
from .ramsey_xy import RamseyXY, StarkRamseyXY, StarkRamseyXYAmpScan
from .ramsey_xy import RamseyXY
from .fine_frequency import FineFrequency
from .drag import RoughDrag
from .readout_angle import ReadoutAngle
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@

from .drag_analysis import DragCalAnalysis
from .fine_amplitude_analysis import FineAmplitudeAnalysis
from .ramsey_xy_analysis import RamseyXYAnalysis, StarkRamseyXYAmpScanAnalysis
from .ramsey_xy_analysis import RamseyXYAnalysis
from .t2ramsey_analysis import T2RamseyAnalysis
from .t2hahn_analysis import T2HahnAnalysis
from .t1_analysis import T1Analysis, T1KerneledAnalysis, StarkP1SpectAnalysis
from .t1_analysis import T1Analysis, T1KerneledAnalysis
from .tphi_analysis import TphiAnalysis
from .cr_hamiltonian_analysis import CrossResonanceHamiltonianAnalysis
from .readout_angle_analysis import ReadoutAngleAnalysis
Expand Down
Loading

0 comments on commit 46e7eec

Please sign in to comment.