# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: Python 3
#     language: python
#     name: python3
# ---

# # Finding the error bar when interpolating the measurements

# The RF losses in the T-resonator, due to the metal resistivities of the coaxial lines, is relatively unknown as the resisitivity that one can find in textbooks is in practice never achieved in real-life. 
#
# In this notebook, the measured return loss of the propely matched T-resonator is compared to the RF model. The short-circuit lengths and resistivity and eventually the total RF losses in the model are adjusted to fit the measurement. This gives a estimation of the RF losses achieved in real-life.

# +
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import minimize
from ipywidgets import interact, interactive, fixed, interact_manual
import ipywidgets as widgets

import tresonator as T

# %matplotlib notebook
# -

# Below we import the return loss measurements.

# +
# Load a matched configuration - S-parameter measurements
filename = 'data/RES2.ASC'

exp_freq,reS11,imS11 = np.loadtxt(filename, skiprows=14, delimiter=';', unpack=True)

exp_mag = np.sqrt(reS11**2 + imS11**2)
exp_mag_dB = 20*np.log10(exp_mag)
# -

#  The match frequency found in practice is:  

# find the match frequency 
exp_freq_match = exp_freq[np.argmin(exp_mag)]
print('Match frequency : {} MHz'.format(exp_freq_match/1e6))


# Then we define an optimization function. The goal of this function is to minimize the error between the measured S11 and the simulated one, for the whole frequency band.

def optim_fun_impedance(short_properties, use_add_loss):
    L_DUT, Z_DUT, L_CEA, Z_CEA, add_loss = short_properties
    # calculates the resonator S11 vs freq
    S11dB = []
    for f in exp_freq:
        if not use_add_loss: # force no additional loss is requested
            add_loss = 1
        _cfg = T.Configuration(f, P_in=1, L_DUT=L_DUT, L_CEA=L_CEA, 
                               Z_short_DUT=Z_DUT, Z_short_CEA=Z_CEA, 
                               additional_losses=add_loss)
        S11dB.append(_cfg.S11dB())
    
    crit = np.sum( (np.array(S11dB) - exp_mag_dB)**2) #least square 
    print(short_properties, crit)
    return crit  


# Below we launch the minimization process, starting from first guess.
#
# Two minimization are launches: one taking into account a multiplicative loss coefficient, and one without.

# first guess
d_DUT_0 = 0.035 # m
d_CEA_0 = 0.035 # m
Z_DUT_0 = 0.01 # Ohm
Z_CEA_0 = 0.01 # Ohm
add_loss = 1.0 # multiplicative coefficient on total RF loss

# find a optimum taking into account additional losses
bounds_pties = ((20e-3, 63e-3), (1e-3, 1), # d,Z DUT
                (5e-3, 200e-3), (1e-3, 1), # d,Z CEA
                (0.1, 2)) # add losses
opt_res = minimize(optim_fun_impedance, (d_DUT_0, Z_DUT_0, d_CEA_0, Z_CEA_0, add_loss),
                  bounds=bounds_pties, args=(True))

# find a optimum taking into account additional losses
bounds_pties = ((20e-3, 63e-3), (1e-3, 1), # d,Z DUT
                (5e-3, 200e-3), (1e-3, 1), # d,Z CEA
                (0.1, 2)) # add losses
opt_res_noloss = minimize(optim_fun_impedance, (d_DUT_0, Z_DUT_0, d_CEA_0, Z_CEA_0, add_loss),
                  bounds=bounds_pties, args=(False))


# Now the results:

# +
print(f'With losses: \t\t d_DUT_0={opt_res.x[0]:.3}, Z_DUT_0={opt_res.x[1]:.3}',
        f' d_CEA_0={opt_res.x[2]:.3}, Z_CEA_0={opt_res.x[3]:.3}, add_loss={opt_res.x[4]:.3}')

print(f'Without losses: \t d_DUT_0={opt_res_noloss.x[0]:.3}, Z_DUT_0={opt_res_noloss.x[1]:.3},', 
      f'd_CEA_0={opt_res_noloss.x[2]:.3}, Z_CEA_0={opt_res_noloss.x[3]:.3}')

# -

# Graphically:

# +
P_in = 20e3 # W

S11dB = []
S11dB_noloss = []

L_DUT_opt, Z_DUT_opt, L_CEA_opt, Z_CEA_opt, add_loss_opt = opt_res.x
L_DUT_opt_nl, Z_DUT_opt_nl, L_CEA_opt_nl, Z_CEA_opt_nl, add_loss_opt_nl = opt_res_noloss.x

for f in exp_freq:
    _cfg = T.Configuration(f, P_in, L_DUT_opt, L_CEA_opt, 
                           Z_short_DUT = Z_DUT_opt, Z_short_CEA = Z_CEA_opt, 
                           additional_losses=add_loss_opt)
    S11dB.append(_cfg.S11dB())
    
    _cfg = T.Configuration(f, P_in, L_DUT_opt_nl, L_CEA_opt_nl, 
                           Z_short_DUT = Z_DUT_opt_nl, Z_short_CEA = Z_CEA_opt_nl, 
                           additional_losses=add_loss_opt_nl)
    S11dB_noloss.append(_cfg.S11dB())    
    

fig,ax=plt.subplots()
ax.plot(exp_freq/1e6, exp_mag_dB, lw=2)
ax.plot(exp_freq/1e6, S11dB, lw=2)
ax.plot(exp_freq/1e6, S11dB_noloss, lw=2, ls='--')
ax.legend(('Measurement', 'TL model - with add. losses', 'TL model - no add. losses'))
plt.grid(True)
ax.set_xlabel('f [MHz]')
ax.set_ylabel('S11 [dB]')
ax.set_xlim(62.5, 62.8)

StarcoderdataJupyterScriptsDedupFiltered