1. Getting started
1.1. Defining a calibration
1.1.1. Exopy template
Typical usage:
Set
default_path = $my_default_pathincalib_name_template.meas.iniand definemy_default_pathvalue inassumptions.py
1.1.2. Jupyter notebook template
[ ]:
# Calibration name ({TYPE})
## {PLACEHOLDER}
[ ]:
file = h5py.File('HDF5_PATH', 'r', swmr=True)
xdata = file['data']['x'][()]
ydata = file['data']['y'][()]
[ ]:
popt, pcov = opt.curve_fit(function, xdata, ydata, guesses=(0, 1, 2))
f'a, b, c = {popt}'
[ ]:
fig, ax = plt.subplots()
ax.plot(xdata, ydata, '.-', label='Data')
ax.plot(xdata, function(xdata, *popt), label=f'Fit: a = {popt[0]:f}')
ax.legend();
[ ]:
# optional
_opt = popt
_cov = pcov
# optional
_err = {'Custom error', _opt[0] < 0}
# mandatory
_results = {'a': popt[0]}
_results
This Jupyter notebook should be saved as
calib_name_template.ipynb under qualib/calibrations/calib_name.1.1.3. Python script
Template:
from .default import DefaultCalibration
class Calibration(DefaultCalibration):
def handle_substitutions(self) -> None:
# Define substitutions here
super().handle_substitutions()
def pre_process(self) -> None:
super().pre_process(mapping = {})
def process(self) -> None:
super().process()
# Update assumptions here
def post_process(self) -> None:
super().post_process(mapping = {})
Example (“Rabi” calibration):
from ..default import DefaultCalibration
class Calibration(DefaultCalibration):
def handle_substitutions(self) -> None:
super().handle_substitutions()
def pre_process(self) -> None:
super().pre_process({
'LINEARITY_AMP_LIMIT': str(self.assumptions['rabi'][f'{self.substitutions["PULSE"]}_linearity_amp_limit'])
})
def process(self) -> None:
super().process()
self.assumptions['qubit'][f'{self.substitutions["PULSE"]}_amp'] = self.results['a_rabi']
def post_process(self) -> None:
factor = 1
if '_pi_' in self.substitutions['PULSE']: factor = 2
if '_pi2_' in self.substitutions['PULSE']: factor = 4
super().post_process({
'TYPE': self.assumptions['TYPE'],
'PULSE_AMP': f'{self.results["a_rabi"]/factor:f}',
'PULSE_LENGTH': str(self.assumptions['qubit'][f'{self.substitutions["PULSE"]}_length'])
})
1.2. Defining a calibration sequence
Example:
[
{"name": "spectro_ro",
"substitutions": {"NAME": "phase_only",
"TYPE": "phase only"}},
{"name": "spectro_ro",
"substitutions": {"NAME": "circle_fit",
"TYPE": "circle fit"}},
{"name": "spectro_qubit"},
{"name": "rabi_probe"},
{"name": "rabi",
"substitutions": {"NAME": "uncond_pi2",
"PULSE": "unconditional_pi2_pulse",
"TYPE": "unconditional pi/2 pulse"}},
{"name": "rabi",
"substitutions": {"NAME": "uncond_pi",
"PULSE": "unconditional_pi_pulse",
"TYPE": "unconditional pi pulse"}},
{"name": "rabi",
"substitutions": {"NAME": "cond_pi",
"PULSE": "conditional_pi_pulse",
"TYPE": "conditional pi pulse"}},
{"name": "ramsey"},
{"name": "t1_qubit"}
]
1.3. Installation/usage
1.3.1. CLI/module usage
First, install Qualib locally from https://github.com/bastienvoirin/qualib.git
Then, open a terminal and run
python -m qualib.main calibration_scheme.py
1.3.2. Package usage
pip install qualib
from qualib.main import Qualib
qualib = Qualib()
qualib.run_all('calibration_scheme.py')