This repository has been archived by the owner on Dec 15, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 26
/
allxy.py
126 lines (96 loc) · 4.91 KB
/
allxy.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
from typing import Dict, Any, List, Union, Optional
import numpy as np
import matplotlib.pyplot as plt
from lmfit import Model
from qcodes.data.data_set import DataSet
from qcodes.data.data_array import DataArray
from qtt.utilities.visualization import plot_vertical_line
def generate_allxy_combinations() -> List[Any]:
""" Generate all combinations of the AllXY sequence from Reed 2013 """
xymapping = {'I': 'I', 'x': 'X90', 'y': 'Y90', 'X': 'X180', 'Y': 'Y180'}
ground_state_rotations = ['II', 'XX', 'YY', 'XY', 'YX']
equator_state_rotations = ['xI', 'yI', 'xy', 'yx', 'xY', 'yX', 'Xy', 'Yx', 'xX', 'Xx', 'yY', 'Yy']
excited_state_rotations = ['XI', 'YI', 'xx', 'yy']
allxy_combinations_input = ground_state_rotations + equator_state_rotations + excited_state_rotations
allxy_combinations = [(xymapping[x[0]], xymapping[x[1]]) for x in allxy_combinations_input]
return allxy_combinations
def allxy_model(indices: Union[float, np.ndarray], offset0: float, slope0: float, offset1: float, slope1: float, offset2: float, slope2: float) -> Union[float, np.ndarray]:
""" Model for AllXY experiment
The model consists of three linear segments. The segments correspond to the pairs of gates that result in
fraction 0, 0.5 and 1 in the AllXY experiment.
Args:
index: Indices of the allxy pairs or a single index
offset0: Offset of first segment
slope0: Slope of first segment
offset1: Offset of second segment
slope1: Slope of second segment
offset2: Offset of last segment
slope2: Slope of last segment
Returns:
Fractions for the allxy pairs
"""
indices = np.array(indices)
x0 = indices < 4.5
x1 = np.logical_and(indices >= 4.5, indices < 16.5)
x2 = (indices >= 16.5)
v1 = x0 * (offset0 + (indices - 2.) * slope0)
v2 = x1 * (offset1 + (indices - 10.5) * slope1)
v3 = x2 * (offset2 + (indices - 19.) * slope2)
return v1 + v2 + v3
def _estimate_allxy_parameters(allxy_data: np.ndarray) -> List[float]:
""" Return estimate of allxy model parameters """
p = [np.mean(allxy_data[0:5]), 0, np.mean(allxy_data[5:17]), 0, np.mean(allxy_data[17:]), 0]
return p
def _default_measurement_array(dataset: DataSet) -> DataArray:
mm = [name for (name, a) in dataset.arrays.items() if not a.is_setpoint]
return dataset.arrays[mm[0]]
def fit_allxy(dataset: DataSet, initial_parameters: Optional[np.ndarray] = None) -> Dict[str, Any]:
""" Fit AllXY measurement to piecewise linear model
Args:
dataset: Dataset containing the AllXY measurement
initial_parameters: Optional set of initialization parameters
Returns:
Dictionary with the fitting results
"""
allxy_data = _default_measurement_array(dataset)
x_data = np.arange(21)
lmfit_model = Model(allxy_model)
if initial_parameters is None:
initial_parameters = _estimate_allxy_parameters(allxy_data)
param_names = lmfit_model.param_names
result = lmfit_model.fit(allxy_data, indices=x_data, **dict(zip(param_names, initial_parameters)), verbose=0)
fitted_parameters = np.array([result.best_values[p] for p in param_names])
fitted_parameters_covariance = np.diag(result.covar)
chi_squared = result.chisqr
return {'fitted_parameters': fitted_parameters, 'description': 'allxy fit', 'initial_parameters': initial_parameters, 'fitted_parameters_covariance': fitted_parameters_covariance, 'chi_squared': chi_squared}
def plot_allxy(dataset: DataSet, result: Dict[str, Any], fig: int = 1, plot_initial_estimate: bool = False):
""" Plot the results of an AllXY fit
Args:
dataset: Dataset containing the measurement data
result: Fitting result of fit_allxy
int: Figure handle
plot_initial_guess: If True, then plot the initial estimate of the model
"""
allxy_data = _default_measurement_array(dataset)
xy_pairs = generate_allxy_combinations()
x_data = np.arange(21)
plt.figure(fig)
plt.clf()
fitted_parameters = result['fitted_parameters']
xfine = np.arange(0, 21, 1e-3)
plt.plot(xfine, allxy_model(xfine, *fitted_parameters), 'm', label='fitted allxy', alpha=.5)
plt.plot(x_data, allxy_data, '.b', label='allxy data')
if plot_initial_estimate:
p = [0, 0, .5, 0, 1, 0]
plt.plot(xfine, allxy_model(xfine, *p), 'c', label='baseline', alpha=.5)
initial_params = _estimate_allxy_parameters(allxy_data)
plt.plot(xfine, allxy_model(xfine, *initial_params), 'g', label='initial estimate', alpha=.35)
initial_parameters = result['initial_parameters']
plt.plot(xfine, allxy_model(xfine, *initial_parameters), ':g', label='initial estimate', alpha=.35)
plt.xticks(x_data, [v[0] + "," + v[1] for v in xy_pairs], rotation='vertical')
vl = plot_vertical_line(4.5)
vl.set_linestyle(':')
vl = plot_vertical_line(16.5)
vl.set_linestyle(':')
plt.title('AllXY')
plt.legend()