def lamb_shifted_transmon_energy(Ej, Ec, m, mult, f0, K2, Np): Em=-Ej+sqrt(8.0*Ej*Ec)*(m+0.5) - (Ec/12.0)*(6.0*m**2+6.0*m+3.0) if m==0: return Em Emm1=-Ej+sqrt(8.0*Ej*Ec)*(m-1+0.5) - (Ec/12.0)*(6.0*(m-1)**2+6.0*(m-1)+3.0) fq=(Em-Emm1)/h fls=Lamb_shift(fq, mult, f0, K2, Np) return Em+h*fls
def _get_lamb_shifted_transmon_energy(self, Ej, Ec, m, couple_mult, f0, K2, Np): Em=-Ej+sqrt(8.0*Ej*Ec)*(m+0.5) - (Ec/12.0)*(6.0*m**2+6.0*m+3.0) if m==0: return Em Emm1=-Ej+sqrt(8.0*Ej*Ec)*(m-1+0.5) - (Ec/12.0)*(6.0*(m-1)**2+6.0*(m-1)+3.0) fq=(Em-Emm1)/h fls=self._get_Lamb_shift(f=fq, couple_mult=couple_mult, f0=f0, K2=K2, Np=Np) return Em+h*fls
def lamb_shifted_transmon_energy(Ej, Ec, m, ft, Np, f0, epsinf, W, Dvv): Em=-Ej+sqrt(8.0*Ej*Ec)*(m+0.5) - (Ec/12.0)*(6.0*m**2+6.0*m+3.0) if m==0: return Em Emm1=-Ej+sqrt(8.0*Ej*Ec)*(m-1+0.5) - (Ec/12.0)*(6.0*(m-1)**2+6.0*(m-1)+3.0) fq=(Em-Emm1)/h fls=calc_Lamb_shift(fq, ft, Np, f0, epsinf, W, Dvv) return Em+h*fls
def _get_lamb_shifted_transmon_energy(self, Ej, Ec, m, f0, ft_mult, eta, epsinf, W, Dvv, Np, Ct_mult): Em=-Ej+sqrt(8.0*Ej*Ec)*(m+0.5) - (Ec/12.0)*(6.0*m**2+6.0*m+3.0) if m==0: return Em Emm1=-Ej+sqrt(8.0*Ej*Ec)*(m-1+0.5) - (Ec/12.0)*(6.0*(m-1)**2+6.0*(m-1)+3.0) fq=(Em-Emm1)/h fls=self._get_Lamb_shift(f=fq, f0=f0, ft_mult=ft_mult, eta=eta, epsinf=epsinf, W=W, Dvv=Dvv, Np=Np, Ct_mult=Ct_mult) return Em+h*fls
def _get_ls_f(self, f, couple_mult, f0, K2, Np): try: return array([ sqrt(qf * (qf - 2 * self._get_Lamb_shift( f=qf, couple_mult=couple_mult, f0=f0, K2=K2, Np=Np))) for qf in f ]) except TypeError: return sqrt(f * (f - 2 * self._get_Lamb_shift( f=f, couple_mult=couple_mult, f0=f0, K2=K2, Np=Np)))
def lamb_shifted_transmon_energy(Ej, Ec, m, ft, Np, f0, epsinf, W, Dvv): Em = -Ej + sqrt( 8.0 * Ej * Ec) * (m + 0.5) - (Ec / 12.0) * (6.0 * m**2 + 6.0 * m + 3.0) if m == 0: return Em Emm1 = -Ej + sqrt( 8.0 * Ej * Ec) * (m - 1 + 0.5) - (Ec / 12.0) * (6.0 * (m - 1)**2 + 6.0 * (m - 1) + 3.0) fq = (Em - Emm1) / h fls = calc_Lamb_shift(fq, ft, Np, f0, epsinf, W, Dvv) return Em + h * fls
def _get_lamb_shifted_transmon_energy(self, Ej, Ec, m, couple_mult, f0, K2, Np): Em = -Ej + sqrt(8.0 * Ej * Ec) * (m + 0.5) - (Ec / 12.0) * ( 6.0 * m**2 + 6.0 * m + 3.0) if m == 0: return Em Emm1 = -Ej + sqrt( 8.0 * Ej * Ec) * (m - 1 + 0.5) - (Ec / 12.0) * (6.0 * (m - 1)**2 + 6.0 * (m - 1) + 3.0) fq = (Em - Emm1) / h fls = self._get_Lamb_shift(f=fq, couple_mult=couple_mult, f0=f0, K2=K2, Np=Np) return Em + h * fls
def _get_fq0(self, f, f0, ft_mult, eta, epsinf, Ct_mult, Dvv, Np, W): ls = self._get_Lamb_shift(f=f, f0=f0, ft_mult=ft_mult, eta=eta, epsinf=epsinf, W=W, Dvv=Dvv, Np=Np, Ct_mult=Ct_mult) return sqrt(f * (f - 2.0 * ls))
def sweepEc(): Ecarr=Ej/EjoverEc E01a=sqrt(8*Ej*Ecarr)-Ecarr data=[] for Ec in Ecarr: d1, d2, d3= EkdivEc(ng=ng, Ec=Ec, Ej=Ej, N=50) E12=d3[0]-d2[0] E01=d2[0]-d1[0] anharm2=(E12-E01)#/E01 data.append(anharm2) Ctr=e**2/(2.0*Ecarr*h*1e9) return E01a, Ctr, data, d1, d2, d3
def _get_lamb_shifted_transmon_energy(self, Ej, Ec, m, f0, ft_mult, eta, epsinf, W, Dvv, Np, Ct_mult): Em = -Ej + sqrt(8.0 * Ej * Ec) * (m + 0.5) - (Ec / 12.0) * ( 6.0 * m**2 + 6.0 * m + 3.0) if m == 0: return Em Emm1 = -Ej + sqrt( 8.0 * Ej * Ec) * (m - 1 + 0.5) - (Ec / 12.0) * (6.0 * (m - 1)**2 + 6.0 * (m - 1) + 3.0) fq = (Em - Emm1) / h fls = self._get_Lamb_shift(f=fq, f0=f0, ft_mult=ft_mult, eta=eta, epsinf=epsinf, W=W, Dvv=Dvv, Np=Np, Ct_mult=Ct_mult) return Em + h * fls
def sweepEc(): Ecarr = Ej / EjoverEc E01a = sqrt(8 * Ej * Ecarr) - Ecarr data = [] for Ec in Ecarr: d1, d2, d3 = EkdivEc(ng=ng, Ec=Ec, Ej=Ej, N=50) E12 = d3[0] - d2[0] E01 = d2[0] - d1[0] anharm2 = (E12 - E01) #/E01 data.append(anharm2) Ctr = e**2 / (2.0 * Ecarr * h * 1e9) return E01a, Ctr, data, d1, d2, d3
def _get_fFWHM(self, f, f0, ft_mult, eta, epsinf, Ct_mult, Dvv, Np, W, dephasing, dephasing_slope): ls = self._get_Lamb_shift(f=f, f0=f0, ft_mult=ft_mult, eta=eta, epsinf=epsinf, W=W, Dvv=Dvv, Np=Np, Ct_mult=Ct_mult) gamma = self._get_coupling(f=f, f0=f0, ft_mult=ft_mult, eta=eta, epsinf=epsinf, W=W, Dvv=Dvv, Np=Np, Ct_mult=Ct_mult) fplus = sqrt(f * (f - 2.0 * ls + 2.0 * gamma)) fminus = sqrt(f * (f - 2.0 * ls - 2.0 * gamma)) return fplus, fminus, fplus - fminus + dephasing + dephasing_slope * f
def _get_S13(self, f, couple_mult, f0, K2, Np, C, L, GL): Ga = self._get_Ga(f=f, couple_mult=couple_mult, f0=f0, K2=K2, Np=Np, C=C) Ba = self._get_Ba(f=f, couple_mult=couple_mult, f0=f0, K2=K2, Np=Np, C=C) w = 2 * pi * f return 1j * sqrt(2.0 * Ga * GL) / (Ga + 1j * Ba + 1j * w * C + 1.0 / (1j * w * L))
def rh(x): m=int(2*x/(lbda0)) if absolute(2*x/lbda0-m)<1.0/4.0: theta=4*pi*x/lbda0 return 2/lbda0*2*sqrt(2.0)*((1.0)**m)/sqrt(cos(theta)-cos(pieta))*trapz(sin(pi*s)*cos((s-1/2)*theta)/rho.lgf1.Pv(-s),s) if absolute(2*x/lbda0-m-1)<1.0/4.0: theta=4*pi*x/lbda0 return 2/lbda0*2*sqrt(2.0)*((1.0)**m)/sqrt(cos(theta)-cos(pieta))*trapz(sin(pi*s)*cos((s-1/2)*theta)/rho.lgf1.Pv(-s),s) if absolute(2*x/lbda0-m+1)<1.0/4.0: theta=4*pi*x/lbda0 return 2/lbda0*2*sqrt(2.0)*((1.0)**m)/sqrt(cos(theta)-cos(pieta))*trapz(sin(pi*s)*cos((s-1/2)*theta)/rho.lgf1.Pv(-s),s) return 0.0
def rh(x): m = int(2 * x / (lbda0)) if absolute(2 * x / lbda0 - m) < 1.0 / 4.0: theta = 4 * pi * x / lbda0 return 2 / lbda0 * 2 * sqrt(2.0) * ( (1.0)**m) / sqrt(cos(theta) - cos(pieta)) * trapz( sin(pi * s) * cos( (s - 1 / 2) * theta) / rho.lgf1.Pv(-s), s) if absolute(2 * x / lbda0 - m - 1) < 1.0 / 4.0: theta = 4 * pi * x / lbda0 return 2 / lbda0 * 2 * sqrt(2.0) * ( (1.0)**m) / sqrt(cos(theta) - cos(pieta)) * trapz( sin(pi * s) * cos( (s - 1 / 2) * theta) / rho.lgf1.Pv(-s), s) if absolute(2 * x / lbda0 - m + 1) < 1.0 / 4.0: theta = 4 * pi * x / lbda0 return 2 / lbda0 * 2 * sqrt(2.0) * ( (1.0)**m) / sqrt(cos(theta) - cos(pieta)) * trapz( sin(pi * s) * cos( (s - 1 / 2) * theta) / rho.lgf1.Pv(-s), s) return 0.0
class Rho(Agent): base_name = "rho" material = Enum('LiNbYZ', 'GaAs', 'LiNb128', 'LiNbYZX', 'STquartz').tag(label="material", expression="Substrate") def _default_material(self): return 'LiNbYZ' def _observe_material(self, change): if change["type"] == "update": self.Dvv = None self.vf = None self.epsinf = None @t_property(desc="coupling strength (relative speed difference)", unit="%", tex_str=r"$\Delta v/v$", expression=r"$\Delta v/v=(v_f-v_m)/v_f$", label="piezoelectric coupling") def Dvv(self, material): return { "STquartz": 0.06e-2, 'GaAs': 0.035e-2, 'LiNbYZ': 2.4e-2, 'LiNb128': 2.7e-2, 'LiNbYZX': 0.8e-2 }[material] K2 = SProperty().tag(desc="coupling strength", unit="%", tex_str=r"K$^2$", expression=r"K$^2=2\Delta v/v$", label="piezoelectric coupling") @K2.getter def _get_K2(self, Dvv): r"""Coupling strength. K$^2=2\Delta v/v$""" return Dvv * 2.0 @K2.setter def _get_Dvv(self, K2): """other coupling strength. free speed minus metal speed all over free speed""" return K2 / 2.0 @t_property(desc="speed of SAW on free surface", unit="m/s", expression=r"$v_f$", format_str=r"{0:.4g} m/s", label="free SAW speed") def vf(self, material): return { "STquartz": 3159.0, 'GaAs': 2900.0, 'LiNbYZ': 3488.0, 'LiNb128': 3979.0, 'LiNbYZX': 3770.0 }[material] @t_property(desc="Capacitance of one finger pair per unit length", expression=r"$\epsilon_\infty=C_S$", label="SAW permittivity") def epsinf(self, material): return { "STquartz": 5.6 * eps0, 'GaAs': 1.2e-10, 'LiNbYZ': 46.0 * eps0, 'LiNb128': 56.0 * eps0, 'LiNbYZX': 46.0 * eps0 }[material] ft = Enum("double", "single").tag(desc="finger type of IDT", label="Finger type") def _observe_ft(self, change): if change["type"] == "update": self.ft_mult = None self.Ct_mult = None def _default_ft(self): return "double" @t_property(desc=r"single : 1, double : 2", label="finger type multiplier", expression=r"$c_{ft}$") def ft_mult(self, ft): return {"double": 2.0, "single": 1.0}[ft] @t_property(dictify={ "single": 1.0, "double": sqrt(2) }, label="Capacitance multiplier", expression=r"$c_c$", desc=r"single : $1$, double : $\sqrt{2}$") def Ct_mult(self, ft): return get_tag(self, "Ct_mult", "dictify")[ft] f = Float().tag(desc="what frequency is being stimulated/measured", unit="GHz", label="Operating frequency", expression=r"$f$") def _default_f(self): """default f is 1Hz off from f0""" return self.f0 #-1.0 f0 = Float(5.0000001e9).tag(unit="GHz", desc="Center frequency of IDT", reference="", expression=r"$f_0$", label="Center frequency") lbda = SProperty().tag(unit="um", desc="wavelength", reference="", label="wavelength", expression=r"$\lambda=v_f/f$") @lbda.getter def _get_lbda(self, f, vf): """wavelength relationship to speed and frequency""" return vf / f @lbda.setter def _get_f(self, lbda, vf): """frequency relationship to speed and wavelength""" return vf / lbda lbda0 = SProperty().tag(unit="um", desc="Center wavelength", reference="", label="center wavelength", expression=r"$\lambda_0=v_f/f_0$") @lbda0.getter def _get_lbda0(self, f0, vf): return vf / f0 @lbda0.setter def _get_f0(self, lbda0, vf): return vf / lbda0 k = SProperty().tag(label="Wavenumber", expression=r"$k=2\pi/\lambda$") @k.getter def _get_k(self, lbda): return 2 * pi / lbda @k.setter def _get_lbda_get_k(self, k): return 2 * pi / k k0 = SProperty().tag(label="Center wavenumber", expression=r"$k_0=2\pi/\lambda_0$") @k0.getter def _get_k0(self, lbda0): return 2 * pi / lbda0 @k0.setter def _get_lbda0_get_k0(self, k0): return 2 * pi / k0 eta = Float(0.5).tag(desc="metalization ratio", label="metallization ratio", expression=r"$\eta$") @log_func def _get_eta(self, a, g): """metalization ratio""" return a / (a + g) g = SProperty().tag(desc="gap between fingers", unit="um", label="finger gap", expression=r"$g$") @g.getter def _get_g(self, a, eta): """gap given metalization and finger width eta=a/(a+g) => a=(a+g)*eta => (1-eta)*a=g*eta => g=a*(1/eta-1)""" return a * (1.0 / eta - 1.0) @g.setter def _get_a_get_g(self, g, eta): """finger width given gap and metalization ratio eta=a/(a+g) => a=(a+g)*eta => (1-eta)*a=g*eta => a=g*eta/(1-eta)""" return g * eta / (1.0 - eta) a = SProperty().tag(desc="width of fingers", unit="um", label="finger width", expression=r"$a$") @a.getter def _get_a(self, eta, lbda0, ft_mult): """finger width from lbda0""" return eta * lbda0 / (2.0 * ft_mult) @a.setter def _get_lbda0_get_a(self, a, eta, ft_mult): return a / eta * 2.0 * ft_mult p = SProperty().tag(desc="periodicity", unit="um", label="finger periodicity", expression=r"$p=a+g$") @p.getter def _get_p(self, a, g): """periodicity from a and g""" return a + g @p.setter def _get_lbda0_get_p(self, p, ft_mult): return 2 * ft_mult * p @private_property def fixed_freq(self): return linspace(self.fixed_freq_min, self.fixed_freq_max, self.N_fixed).astype(float64) N_fixed = Int(10000) fixed_freq_max = Float() fixed_freq_min = Float(0.01) def _default_fixed_freq_max(self): return 200.0 * self.f0 def _default_fixed_freq_min(self): return 0.0001 #*self.f0 lgf1 = Typed(Legendre) #.tag(sub=True) lgf2 = Typed(Legendre) #.tag(sub=True) def _default_lgf1(self): return Legendre(x=-cos(pi * self.eta), Nmult=0) def _default_lgf2(self): return Legendre(x=cos(pi * self.eta), v=self._get_m(f=self.fixed_freq_max)) def _observe_eta(self, change): if change["type"] == "update": if self.fixed_update: self.fixed_reset() fixed_update = Bool(False).tag( desc= "if True, changing eta will trigger an update of fixed values (slow computation)" ) #@log_callable() def fixed_reset(self): self.lgf1.Pv(0.0, -cos(pi * self.eta), 0) self.lgf2.Pv(self.fixed_freq_max / (2 * self.ft_mult * self.f0), cos(pi * self.eta)) self.get_member("fixed_freq").reset(self) self.get_member("fixed_alpha").reset(self) self.get_member("surface_x").reset(self) self.get_member("surface_charge").reset(self) self.get_member("surface_voltage").reset(self) @private_property def fixed_alpha(self): return self._get_alpha(f=self.fixed_freq) @private_property def fixed_m(self): return self._get_m(f=self.fixed_freq) @private_property def fixed_s(self): return self._get_s(f=self.fixed_freq) m = SProperty().tag(desc="integer number of wavelengths") @m.getter def _get_m(self, f, f0, ft_mult): fs = self._get_fs(f=f, f0=f0, ft_mult=ft_mult) if isinstance(f, float): return int(fs) return fs.astype(int64) s = SProperty() @s.getter def _get_s(self, f, f0, ft_mult): fs = self._get_fs(f=f, f0=f0, ft_mult=ft_mult) m = self._get_m(f=f, f0=f0, ft_mult=ft_mult) return fs - m fs = SProperty() @fs.getter def _get_fs(self, f, f0, ft_mult): return f / (2.0 * ft_mult * f0) alpha = SProperty().tag(desc="single : 1.694, double : 1.247", label="mu multiplier", expression=r"$\alpha$") @alpha.getter def _get_alpha(self, f, f0, ft_mult, eta, epsinf): m = self._get_m(f=f, f0=f0, ft_mult=ft_mult) s = self._get_s(f=f, f0=f0, ft_mult=ft_mult) return 2 * sin(pi * s) / self.lgf1.Pv(-s) * self.lgf2.Pv(m) alpha0 = SProperty() @alpha0.getter def _get_alpha0(self, f0, ft_mult, eta, epsinf): return self._get_alpha(f=f0, f0=f0, ft_mult=ft_mult, eta=eta, epsinf=epsinf) @private_property def surface_x(self): fs = self._get_fs(f=self.fixed_freq) df = 1.0 / (fs[1] - fs[0]) / 2.0 #*self.lbda0/2 return linspace(-df / 2.0, df / 2.0, self.N_fixed) @private_property def surface_charge(self): return fft.fftshift(real(ifft(self.fixed_alpha * self.epsinf))) @private_property def surface_voltage(self): lbda = self._get_lbda(f=self.fixed_freq) kCs = self._get_k(lbda) #*self.epsinf return fft.fftshift(real(fft.ifft(self.fixed_alpha / kCs))).astype(float64) @private_property def view_window(self): return SurfaceChargeView(agent=self) @private_property def plot_func_dict(self): return OrderedDict([ ("legendre test", dict(code=self.lgf1.lgf_test_plot)), ("plot_alpha", dict(code=self.plot_alpha)), ("plot surface charge", dict(code=self.plot_surface_charge)), ("plot surface voltage", dict(code=self.plot_surface_voltage)), ]) def plot_alpha(self, pl=None, **kwargs): if pl is None: pl = "alpha_" + self.name f, alpha = self.fixed_freq, self.fixed_alpha pl = line(f / self.f0, alpha, plotter=pl, plot_name=self.name, color="blue", label=self.name, **kwargs) pl.xlabel = "frequency/center frequency" pl.ylabel = "element factor" pl.set_ylim(-1.0, 2.0) return pl def plot_surface_charge(self, pl=None, **kwargs): if pl is None: pl = "surface_charge_" + self.name x, charge = self.surface_x, self.surface_charge pl = line(x, charge, plotter=pl, plot_name=self.name, color="blue", label=self.name, **kwargs) pl.xlabel = "x/center wavelength" pl.ylabel = "surface charge" #pl.set_ylim(-1.0, 2.0) return pl def plot_surface_voltage(self, pl=None, **kwargs): if pl is None: pl = "surface_voltage_" + self.name x, voltage = self.surface_x, self.surface_voltage pl = line(x, voltage, plotter=pl, plot_name=self.name, color="blue", label=self.name, **kwargs) pl.xlabel = "x/center wavelength" pl.ylabel = "surface voltage" #pl.set_ylim(-1.0, 2.0) return pl
def anharm(self, Ej, Ec): E0 = sqrt(8.0*Ej*Ec)*0.5 - Ec/4.0 E1 = sqrt(8.0*Ej*Ec)*1.5 - (Ec/12.0)*(6.0+6.0+3.0) E2 = sqrt(8.0*Ej*Ec)*2.5 - (Ec/12.0)*(6.0*2**2+6.0*2+3.0) return (E2-E1)-(E1-E0)
def _get_fq(self, Ej, Ec): E0 = sqrt(8.0*Ej*Ec)*0.5 - Ec/4.0 E1 = sqrt(8.0*Ej*Ec)*1.5 - (Ec/12.0)*(6.0+6.0+3.0) return (E1-E0)/h
def _get_ls_f(self, f, couple_mult, f0, K2, Np): try: return array([sqrt(qf*(qf-2*self._get_Lamb_shift(f=qf, couple_mult=couple_mult, f0=f0, K2=K2, Np=Np))) for qf in f]) except TypeError: return sqrt(f*(f-2*self._get_Lamb_shift(f=f, couple_mult=couple_mult, f0=f0, K2=K2, Np=Np)))
def _update_fq(self, Ej, Ec): E0 = sqrt(8.0 * Ej * Ec) * 0.5 - Ec / 4.0 E1 = sqrt(8.0 * Ej * Ec) * 1.5 - (Ec / 12.0) * (6.0 + 6.0 + 3.0) return (E1 - E0) / h
def MagAbsFit(self): return sqrt(self.fitter.reconstruct_fit(self.fixed_fq[self.flat_flux_indices]/1e9, self.fit_params)).transpose()
return Np*pi*(f-f0)/f0 def Ga(Ga0, X): return Ga0*(sin(X)/X)**2.0 def Ba(Ga0, X): return Ga0*(sin(2.0*X)-2.0*X)/(2.0*X**2.0) def coupling(Ga, C): return Ga/(2.0*C)/(2.0*pi) def Lamb_shift(Ba, C): """returns Lamb shift""" return -Ba/(2.0*C)/(2.0*pi) Ct_mult={"double" : sqrt(2), "single" : 1.0} def calc_Lamb_shift(fq, ft, Np, f0, epsinf, W, Dvv): """returns Lamb shift in Hz""" X=Np*pi*(fq-f0)/f0 Ga0=Ga0_mult[ft]*2*pi*f0*epsinf*W*Dvv*(Np**2) C=Ct_mult[ft]*Np*W*epsinf Ba=Ga0*(sin(2.0*X)-2.0*X)/(2.0*X**2.0) return -Ba/(2.0*C)/(2.0*pi) def calc_freq_shift(fq, ft, Np, f0, epsinf, W, Dvv): """returns Lamb shift in Hz""" X=Np*pi*(fq-f0)/f0 Ga0=Ga0_mult[ft]*2*pi*f0*epsinf*W*Dvv*(Np**2) C=Ct_mult[ft]*Np*W*epsinf Ba=Ga0*(sin(2.0*X)-2.0*X)/(2.0*X**2.0) return Ba/C/(2.0*pi)
def _get_fq0(self, f, f0, ft_mult, eta, epsinf, Ct_mult, Dvv, Np, W): ls=self._get_Lamb_shift(f=f, f0=f0, ft_mult=ft_mult, eta=eta, epsinf=epsinf, W=W, Dvv=Dvv, Np=Np, Ct_mult=Ct_mult) return sqrt(f*(f-2.0*ls))
class QDT(IDT, Qubit): base_name="QDT" couple_mult=Float(0.55) Ga0_mult=Float(3.111) coupling_mult_dict={"single" : 0.71775, "double" : 0.54995} Ga0_mult_dict={"single":2.871, "double":3.111} Ct_mult_dict={"double" : sqrt(2), "single" : 1.0} def _observe_ft(self, change): if change["type"]=="update": self.couple_mult=self.coupling_mult_dict[self.ft] self.Ga0_mult=self.Ga0_mult_dict[self.ft] @tagged_property def coupling_approx(self, couple_mult, Np, K2, f0): """approximate coupling at center frequency of QDT, in Hz (double finger)""" return couple_mult*Np*K2*f0 @tagged_property def Ga0(self, Ga0_mult, f0, epsinf, W, Dvv, Np): """Ga0 from morgan""" return Ga0_mult*2*pi*f0*epsinf*W*Dvv*(Np**2) @tagged_property def Ga0div2C(self, couple_mult, f0, K2, Np): """coupling at center frequency, in Hz (2 pi removed)""" return couple_mult*f0*K2*Np @tagged_property def X(self, Np, f, f0): """standard frequency dependence""" return Np*pi*(f-f0)/f0 @tagged_property def Ga(self, f, couple_mult, f0, K2, Np, C): return self.coupling(f, couple_mult, f0, K2, Np)*2*C*2*pi @tagged_property def Ba(self, f, mult, f0, K2, Np, C): return -self.Lamb_shift(f, mult, f0, K2, Np)*2*C*2*pi @tagged_property def coupling(self, f, couple_mult, f0, K2, Np): gamma0=self.Ga0div2C(couple_mult, f0, K2, Np) gX=self.X(Np, f, f0) return gamma0*(sin(gX)/gX)**2.0 @tagged_property def Lamb_shift(self, f, mult, f0, K2, Np): """returns Lamb shift""" gamma0=self.Ga0div2C(mult, f0, K2, Np) gX=self.X(Np, f, f0) return -gamma0*(sin(2.0*gX)-2.0*gX)/(2.0*gX**2.0) def lamb_shifted_transmon_energy(Ej, Ec, m, mult, f0, K2, Np): Em=-Ej+sqrt(8.0*Ej*Ec)*(m+0.5) - (Ec/12.0)*(6.0*m**2+6.0*m+3.0) if m==0: return Em Emm1=-Ej+sqrt(8.0*Ej*Ec)*(m-1+0.5) - (Ec/12.0)*(6.0*(m-1)**2+6.0*(m-1)+3.0) fq=(Em-Emm1)/h fls=Lamb_shift(fq, mult, f0, K2, Np) return Em+h*fls def lamb_shifted_transmon_energy_levels(EjdivEc, n, mult, f0, K2, Np, C): Ec=e**2/(2.0*C) Ej=EjdivEc*Ec return [lamb_shifted_transmon_energy(Ej, Ec, m, mult, f0, K2, Np) for m in range(n)] @tagged_property() def Ga0(self, ft, f0, epsinf, W, Dvv, Np): """Ga0 from morgan""" return Ga0(Ga0_mult[ft], f0, epsinf, W, Dvv, Np) @tagged_property(desc="""Coupling at IDT center frequency""", unit="GHz", label="Coupling at center frequency", tex_str=r"$\gamma_{f0}$") def coupling_approx(self, Np, K2, f0): return coupling_approx(Np, K2, f0) @tagged_property() def max_coupling(self, couple_mult, f0, K2, Np): return Ga0div2C(couple_mult, f0, K2, Np) @tagged_property(desc="""Coupling adjusted by sinc sq""", unit="GHz", tex_str=r"$G_f$", label="frequency adjusted coupling") def coupling(self, f, couple_mult, f0, K2, Np): return coupling(f, couple_mult, f0, K2, Np) @tagged_property(desc="""Lamb shift""", unit="GHz", tex_str=r"$G_f$", label="frequency adjusted lamb_shift") def Lamb_shift(self, f, couple_mult, f0, K2, Np): return Lamb_shift(f, couple_mult, f0, K2, Np) #@log_callable(sub=True) #def calc_Lamb_shift(self, fqq, ft, Np, f0, epsinf, W, Dvv): # return calc_Lamb_shift(fqq, ft, Np, f0, epsinf, W, Dvv)#ft=self.ft, Np=self.Np, f0=self.f0, epsinf=self.epsinf, W=self.W, Dvv=self.Dvv) #@log_callable(sub=True) #def calc_coupling(self, fqq, ft, Np, f0, Dvv, epsinf, W): # return calc_coupling(fqq, ft, Np, f0, Dvv, epsinf, W) #ft=self.ft, Np=self.Np, f0=self.f0, Dvv=self.Dvv, epsinf=self.epsinf, W=self.W) @log_callable(sub=True) def lamb_shifted_transmon_energy_levels(self, EjdivEc, n_energy, couple_mult, f0, K2, Np, Cq): return lamb_shifted_transmon_energy_levels(EjdivEc, n_energy, couple_mult, f0, K2, Np, Cq)#ft=self.ft, Np=self.Np, f0=self.f0, epsinf=self.epsinf, #W=self.W, Dvv=self.Dvv) #@log_callable(sub=True) #def lamb_shifted_anharm(self, EjdivEc, ft, Np, f0, epsinf, W, Dvv): # return lamb_shifted_anharm(EjdivEc, ft, Np, f0, epsinf, W, Dvv) #@log_callable(sub=True) #def lamb_shifted_fq(self, EjdivEc, ft, Np, f0, epsinf, W, Dvv): # return lamb_shifted_fq(EjdivEc, ft, Np, f0, epsinf, W, Dvv) #@log_callable(sub=True) #def lamb_shifted_fq2(self, EjdivEc, ft, Np, f0, epsinf, W, Dvv): # return lamb_shifted_fq2(EjdivEc, ft, Np, f0, epsinf, W, Dvv) @tagged_property(desc="shunt capacitance of QDT", unit="fF") def Cq(self, Ct): return Ct @Cq.fget.setter def _get_Ct(self, Cq): return Cq
def _get_fFWHM(self, f, f0, ft_mult, eta, epsinf, Ct_mult, Dvv, Np, W, dephasing, dephasing_slope): ls=self._get_Lamb_shift(f=f, f0=f0, ft_mult=ft_mult, eta=eta, epsinf=epsinf, W=W, Dvv=Dvv, Np=Np, Ct_mult=Ct_mult) gamma=self._get_coupling(f=f, f0=f0, ft_mult=ft_mult, eta=eta, epsinf=epsinf, W=W, Dvv=Dvv, Np=Np, Ct_mult=Ct_mult) fplus=sqrt(f*(f-2.0*ls+2.0*gamma)) fminus=sqrt(f*(f-2.0*ls-2.0*gamma)) return fplus, fminus, fplus-fminus+dephasing+dephasing_slope*f
def _get_S13(self, f, couple_mult, f0, K2, Np, C, L, GL): Ga=self._get_Ga(f=f, couple_mult=couple_mult, f0=f0, K2=K2, Np=Np, C=C) Ba=self._get_Ba(f=f, couple_mult=couple_mult, f0=f0, K2=K2, Np=Np, C=C) w=2*pi*f return 1j*sqrt(2.0*Ga*GL)/(Ga+1j*Ba+1j*w*C+1.0/(1j*w*L))
def _update_fq_max(self, Ejmax, Ec): return sqrt(8.0*Ejmax*Ec)
def _update_fq_max(self, Ejmax, Ec): return sqrt(8.0 * Ejmax * Ec)
def fq_max(self, Ejmax, Ec): return sqrt(8.0*Ejmax*Ec)
def Ba(Ga0, X): return Ga0 * (sin(2.0 * X) - 2.0 * X) / (2.0 * X**2.0) def coupling(Ga, C): return Ga / (2.0 * C) / (2.0 * pi) def Lamb_shift(Ba, C): """returns Lamb shift""" return -Ba / (2.0 * C) / (2.0 * pi) Ct_mult = {"double": sqrt(2), "single": 1.0} def calc_Lamb_shift(fq, ft, Np, f0, epsinf, W, Dvv): """returns Lamb shift in Hz""" X = Np * pi * (fq - f0) / f0 Ga0 = Ga0_mult[ft] * 2 * pi * f0 * epsinf * W * Dvv * (Np**2) C = Ct_mult[ft] * Np * W * epsinf Ba = Ga0 * (sin(2.0 * X) - 2.0 * X) / (2.0 * X**2.0) return -Ba / (2.0 * C) / (2.0 * pi) def calc_freq_shift(fq, ft, Np, f0, epsinf, W, Dvv): """returns Lamb shift in Hz""" X = Np * pi * (fq - f0) / f0 Ga0 = Ga0_mult[ft] * 2 * pi * f0 * epsinf * W * Dvv * (Np**2)
def MagAbsFit(self): return sqrt( self.fitter.reconstruct_fit( self.fixed_fq[self.flat_flux_indices] / 1e9, self.fit_params)).transpose()