Skip to content

Commit

Permalink
Measuring T1 of TLSs
Browse files Browse the repository at this point in the history
  • Loading branch information
msamiotis committed Jul 10, 2024
1 parent 14ffda0 commit 623e925
Show file tree
Hide file tree
Showing 6 changed files with 327 additions and 76 deletions.
1 change: 1 addition & 0 deletions pycqed/analysis/fitting_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1313,6 +1313,7 @@ def sum_int(x, y):
CosModel2 = lmfit.Model(CosFunc2)
ResonatorArch = lmfit.Model(resonator_flux)
ExpDecayModel = lmfit.Model(ExpDecayFunc)
DoubleExpDecayModel = lmfit.Model(DoubleExpDecayFunc)
TripleExpDecayModel = lmfit.Model(TripleExpDecayFunc)
ExpDecayModel.guess = exp_dec_guess # todo: fix
ExpDampOscModel = lmfit.Model(ExpDampOscFunc)
Expand Down
244 changes: 180 additions & 64 deletions pycqed/analysis/measurement_analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -1099,7 +1099,7 @@ class TD_Analysis(MeasurementAnalysis):
def __init__(self, NoCalPoints=4, center_point=31, make_fig=True,
zero_coord=None, one_coord=None, cal_points=None,
rotate_and_normalize=True, plot_cal_points=True,
for_ef=False, qb_name=None, **kw):
for_ef=False, qb_name=None, fit_double_exp = False, **kw):
kw['cal_points'] = cal_points
self.NoCalPoints = NoCalPoints
self.normalized_values = []
Expand All @@ -1113,6 +1113,7 @@ def __init__(self, NoCalPoints=4, center_point=31, make_fig=True,
self.center_point = center_point
self.plot_cal_points = plot_cal_points
self.for_ef = for_ef
self.fit_double_exp = fit_double_exp

# Always call parent class constructor before assigning attributes.
super(TD_Analysis, self).__init__(qb_name=qb_name, **kw)
Expand Down Expand Up @@ -4664,27 +4665,62 @@ def __init__(self, label='T1', **kw):

def fit_T1(self, **kw):

# Guess for params
fit_mods.ExpDecayModel.set_param_hint('amplitude',
value=1,
min=0,
max=2)
fit_mods.ExpDecayModel.set_param_hint('tau',
value=self.sweep_points[1] * 50,
min=self.sweep_points[1],
max=self.sweep_points[-1] * 1000)
fit_mods.ExpDecayModel.set_param_hint('offset',
value=0,
vary=False)
fit_mods.ExpDecayModel.set_param_hint('n',
value=1,
vary=False)
self.params = fit_mods.ExpDecayModel.make_params()
if self.fit_double_exp == True:
# Guess for params
from pycqed.analysis.fitting_models import DoubleExpDecayFunc
DoubleExpDecayModel = lmfit.Model(DoubleExpDecayFunc)

DoubleExpDecayModel.set_param_hint('amp1',
value=0.5,
min=0,
max=1)
DoubleExpDecayModel.set_param_hint('amp2',
value=0.5,
min=0,
max=1)
DoubleExpDecayModel.set_param_hint('tau1',
value=self.sweep_points[1] * 50,
min=self.sweep_points[1],
max=self.sweep_points[-1] * 1000)
DoubleExpDecayModel.set_param_hint('tau2',
value=self.sweep_points[3] * 50,
min=self.sweep_points[1],
max=self.sweep_points[-1] * 1000)
DoubleExpDecayModel.set_param_hint('offset',
value=0,
vary=False)
DoubleExpDecayModel.set_param_hint('n',
value=1,
vary=False)
self.params = DoubleExpDecayModel.make_params()

fit_res = DoubleExpDecayModel.fit(data=self.normalized_data_points,
t=self.sweep_points[:-
self.NoCalPoints],
params=self.params)

fit_res = fit_mods.ExpDecayModel.fit(data=self.normalized_data_points,
t=self.sweep_points[:-
self.NoCalPoints],
params=self.params)
else:
# Guess for params
fit_mods.ExpDecayModel.set_param_hint('amplitude',
value=1,
min=0,
max=2)
fit_mods.ExpDecayModel.set_param_hint('tau',
value=self.sweep_points[1] * 50,
min=self.sweep_points[1],
max=self.sweep_points[-1] * 1000)
fit_mods.ExpDecayModel.set_param_hint('offset',
value=0,
vary=False)
fit_mods.ExpDecayModel.set_param_hint('n',
value=1,
vary=False)
self.params = fit_mods.ExpDecayModel.make_params()

fit_res = fit_mods.ExpDecayModel.fit(data=self.normalized_data_points,
t=self.sweep_points[:-
self.NoCalPoints],
params=self.params)

if kw.get('print_fit_results', False):
print(fit_res.fit_report())
Expand All @@ -4707,61 +4743,123 @@ def run_default_analysis(self, show=False, close_file=False, **kw):
self.fit_res = self.fit_T1(**kw)
self.save_fitted_parameters(fit_res=self.fit_res, var_name='F|1>')

# Create self.T1 and self.T1_stderr and save them
self.get_measured_T1() # in seconds
self.save_computed_parameters(
self.T1_dict, var_name=self.value_names[0])
if self.fit_double_exp == True:
self.get_measured_double_T1() # in seconds
self.save_computed_parameters(
self.T1_dict, var_name=self.value_names[0])

T1_micro_sec = self.T1_dict['T1'] * 1e6
T1_err_micro_sec = self.T1_dict['T1_stderr'] * 1e6
# Print T1 and error on screen
if kw.get('print_parameters', False):
print('T1 = {:.5f} ('.format(T1_micro_sec) + 'μs) \t '
'T1 StdErr = {:.5f} ('.format(
T1_err_micro_sec) + 'μs)')
T1_1_micro_sec = self.fit_res.uvars['tau1'].n * 1e6
T1_1_err_micro_sec = self.fit_res.uvars['tau1'].s * 1e6
T1_2_micro_sec = self.fit_res.uvars['tau2'].n * 1e6
T1_2_err_micro_sec = self.fit_res.uvars['tau2'].s * 1e6
# Print T1 and error on screen
if kw.get('print_parameters', False):
print('T1_1 = {:.5f} ('.format(T1_1_micro_sec) + 'μs) \t '
'T1_1 StdErr = {:.5f} ('.format(
T1_1_err_micro_sec) + 'μs)')
print('T1_2 = {:.5f} ('.format(T1_2_micro_sec) + 'μs) \t '
'T1_2 StdErr = {:.5f} ('.format(
T1_2_err_micro_sec) + 'μs)')

# Plot best fit and initial fit + data
if self.make_fig:

units = SI_prefix_and_scale_factor(val=max(abs(self.ax.get_xticks())),
unit=self.sweep_unit[0])[1]
# We will not bother retrieving old T1 values from dataset
old_vals = ''

# Plot best fit and initial fit + data
if self.make_fig:
best_vals = self.fit_res.best_values

textstr = ('$T1_1$ = {:.3f} '.format(T1_1_micro_sec) +
units +
' $\pm$ {:.3f} '.format(T1_1_err_micro_sec) +
units +
'\n$T1_2$ = {:.3f} '.format(T1_2_micro_sec) +
units +
' $\pm$ {:.3f} '.format(T1_2_err_micro_sec) +
units + old_vals)

self.fig.text(0.5, 0.9, textstr, transform=self.ax.transAxes,
fontsize=self.font_size,
verticalalignment='top',
horizontalalignment='center',
bbox=self.box_props)

units = SI_prefix_and_scale_factor(val=max(abs(self.ax.get_xticks())),
unit=self.sweep_unit[0])[1]
# We will not bother retrieving old T1 values from dataset
old_vals = ''
if show_guess:
self.ax.plot(self.sweep_points[:-self.NoCalPoints],
self.fit_res.init_fit, 'k--', linewidth=self.line_width)

best_vals = self.fit_res.best_values
t = np.linspace(self.sweep_points[0],
self.sweep_points[-self.NoCalPoints], 1000)

y = fit_mods.DoubleExpDecayFunc(
t,
tau1=best_vals['tau1'],
tau2=best_vals['tau2'],
n=best_vals['n'],
amp1=best_vals['amp1'],
amp2=best_vals['amp2'],
offset=best_vals['offset'])

else:

# Create self.T1 and self.T1_stderr and save them
self.get_measured_T1() # in seconds
self.save_computed_parameters(
self.T1_dict, var_name=self.value_names[0])

T1_micro_sec = self.T1_dict['T1'] * 1e6
T1_err_micro_sec = self.T1_dict['T1_stderr'] * 1e6
# Print T1 and error on screen
if kw.get('print_parameters', False):
print('T1 = {:.5f} ('.format(T1_micro_sec) + 'μs) \t '
'T1 StdErr = {:.5f} ('.format(
T1_err_micro_sec) + 'μs)')

textstr = ('$T_1$ = {:.3f} '.format(T1_micro_sec) +
units +
' $\pm$ {:.3f} '.format(T1_err_micro_sec) +
units + old_vals)
# Plot best fit and initial fit + data
if self.make_fig:

self.fig.text(0.5, 0, textstr, transform=self.ax.transAxes,
fontsize=self.font_size,
verticalalignment='top',
horizontalalignment='center',
bbox=self.box_props)
units = SI_prefix_and_scale_factor(val=max(abs(self.ax.get_xticks())),
unit=self.sweep_unit[0])[1]
# We will not bother retrieving old T1 values from dataset
old_vals = ''

if show_guess:
self.ax.plot(self.sweep_points[:-self.NoCalPoints],
self.fit_res.init_fit, 'k--', linewidth=self.line_width)
textstr = ('$T_1$ = {:.3f} '.format(T1_micro_sec) +
units +
' $\pm$ {:.3f} '.format(T1_err_micro_sec) +
units + old_vals)

best_vals = self.fit_res.best_values
t = np.linspace(self.sweep_points[0],
self.sweep_points[-self.NoCalPoints], 1000)
self.fig.text(0.5, 0, textstr, transform=self.ax.transAxes,
fontsize=self.font_size,
verticalalignment='top',
horizontalalignment='center',
bbox=self.box_props)

y = fit_mods.ExpDecayFunc(
t, tau=best_vals['tau'],
n=best_vals['n'],
amplitude=best_vals['amplitude'],
offset=best_vals['offset'])
if show_guess:
self.ax.plot(self.sweep_points[:-self.NoCalPoints],
self.fit_res.init_fit, 'k--', linewidth=self.line_width)

self.ax.plot(t, y, 'r-', linewidth=self.line_width)
best_vals = self.fit_res.best_values
t = np.linspace(self.sweep_points[0],
self.sweep_points[-self.NoCalPoints], 1000)

self.ax.locator_params(axis='x', nbins=6)
y = fit_mods.ExpDecayFunc(
t, tau=best_vals['tau'],
n=best_vals['n'],
amplitude=best_vals['amplitude'],
offset=best_vals['offset'])

if show:
plt.show()
self.ax.plot(t, y, 'r-', linewidth=self.line_width)

self.save_fig(
self.fig, figname=self.measurementstring + '_Fit', **kw)
self.ax.locator_params(axis='x', nbins=6)

if show:
plt.show()

self.save_fig(
self.fig, figname=self.measurementstring + '_Fit', **kw)

if close_file:
self.data_file.close()
Expand All @@ -4782,6 +4880,24 @@ def get_measured_T1(self):

return self.T1, T1_stderr

def get_measured_double_T1(self):
fitted_pars = self.data_file['Analysis']['Fitted Params F|1>']

self.T1_1 = fitted_pars['tau1'].attrs['value']
T1_1_stderr = fitted_pars['tau1'].attrs['stderr']

self.T1_2 = fitted_pars['tau2'].attrs['value']
T1_2_stderr = fitted_pars['tau2'].attrs['stderr']
# T1 = self.fit_res.params['tau'].value
# T1_stderr = self.fit_res.params['tau'].stderr

# return as dict for use with "save_computed_parameters"; units are
# seconds
self.T1_dict = {'T1_1': self.T1_1, 'T1_1_stderr': T1_1_stderr,
'T1_2': self.T1_2, 'T1_2_stderr': T1_2_stderr}

return self.T1_1, self.T1_2


class Ramsey_Analysis(TD_Analysis):
"""
Expand Down
8 changes: 5 additions & 3 deletions pycqed/analysis_v2/multi_analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,8 @@ def process_data(self):
self.proc_data_dict['{}_nor_data'.format(q)] = nor_data

### fit to normalized data ###
times = self.proc_data_dict['{}_times'.format(q)]
# times = self.proc_data_dict['{}_times'.format(q)]
times = self.times

fit_mods.ExpDecayModel.set_param_hint('amplitude',
value=1,
Expand Down Expand Up @@ -502,18 +503,19 @@ def prepare_plots(self):
'plotfn': plot_Multi_T1,
'data': self.proc_data_dict,
'qubit': q,
'times': self.times,
'title': 'T1_'+q+'_'
+self.raw_data_dict['timestamps'][0],
'plotsize': (10,10)
}


def plot_Multi_T1(qubit, data,title, ax=None, **kwargs):
def plot_Multi_T1(qubit, times, data,title, ax=None, **kwargs):
if ax is None:
fig, ax = plt.subplots(figsize=(15,15))

q = qubit
times = data['{}_times'.format(q)]*1e6
# times = data['{}_times'.format(q)]*1e6
nor_data = data['{}_nor_data'.format(q)]
fit_data = data['{}_fitted_data'.format(q)]
T1 = data['quantities_of_interest'][q]['tau']*1e6
Expand Down
Loading

0 comments on commit 623e925

Please sign in to comment.