def calc_linresp(self, Nqp, hwread, D_0): s_0 = kidcalc.cinduct(hwread, D_0, self.kbT) Qi_0 = kidcalc.Qi(s_0[0], s_0[1], self.ak, self.kbT, D_0, SC.Sheet(self.SC, self.d)) Q = Qi_0 * self.Qc / (Qi_0 + self.Qc) beta = kidcalc.beta(self.kbT, D_0, SC.Sheet(self.SC, self.d)) kbTeff = kidcalc.kbTeff(Nqp / self.V, self.SC) D = kidcalc.D(kbTeff, self.SC) s1, s2 = kidcalc.cinduct(hwread, D, kbTeff) lindA = self.ak * beta * Q * (s1 - s_0[0]) / s_0[1] lintheta = -self.ak * beta * Q * (s2 - s_0[1]) / s_0[1] return lindA, lintheta
def calc_S21(self, Nqp, hwread, s20, dhw=0): kbTeff = kidcalc.kbTeff(Nqp / self.V, self.SC) D = kidcalc.D(kbTeff, self.SC) s1, s2 = kidcalc.cinduct(hwread + dhw, D, kbTeff) Qi = interpolate.splev(kbTeff, self.Qispl) hwres = kidcalc.hwres(s2, self.hw0, s20, self.ak, self.kbT, D, SC.Sheet(self.SC, self.d)) return kidcalc.S21(Qi, self.Qc, hwread, dhw, hwres)
def calc_resp(self, Nqp, hwread, s20, D_0, dhw=0): # Calculate S21 S21 = self.calc_S21(Nqp, hwread, s20, dhw) # Define circle at this temperature: s_0 = kidcalc.cinduct(hwread, D_0, self.kbT) Qi_0 = kidcalc.Qi(s_0[0], s_0[1], self.ak, self.kbT, D_0, SC.Sheet(self.SC, self.d)) S21min = self.Qc / (self.Qc + Qi_0) # Q/Qi xc = (1 + S21min) / 2 # translate S21 into this circle: dA = 1 - np.sqrt((np.real(S21) - xc) ** 2 + np.imag(S21) ** 2) / (1 - xc) theta = np.arctan2(np.imag(S21), (xc - np.real(S21))) return S21, dA, theta
def plot_freqsweep(self, start=None, stop=None, points=200): hwread = self.hwread D_0 = self.D_0 s20 = self.s20 s_0 = kidcalc.cinduct(hwread, D_0, self.kbT) Qi_0 = kidcalc.Qi(s_0[0], s_0[1], self.ak, self.kbT, D_0, SC.Sheet(self.SC, self.d)) Q = Qi_0 * self.Qc / (Qi_0 + self.Qc) S21min = self.Qc / (self.Qc + Qi_0) # Q/Qi xc = (1 + S21min) / 2 if start is None: start = -self.hw0 / Q * 2 if stop is None: stop = self.hw0 / Q * 2 for dhw in np.linspace(start, stop, points): S21_0 = self.calc_S21(self.Nqp_0, hwread, s20, dhw=dhw) plt.plot(np.real(S21_0), np.imag(S21_0), "r.") plt.plot(xc, 0, "kx") plt.plot(S21min, 0, "gx")
def minfunc(kbT, s2s1, hw, N0, kbTc, kbTD): D_ = D(kbT, N0, kbTc, kbTD) s1, s2 = cinduct(hw, D_, kbT) return np.abs(s2s1 - s2 / s1)
def ak(S21data, lbd0=0.092, N0=1.72e4, kbTD=37312.0, plot=False, reterr=False, method='df'): '''Calculates the kinetic induction fraction, based on Goa2008, PhD Thesis. Arguments: S21data -- the content of the .csv from the S21-analysis. lbd0 -- penetration depth at T=0 in µm (default: 0.092, Al) N0 -- Density of states in µeV^{-1}µm^{-3} (default: 1.72e4, Al) kbTD -- Debye Energy in µeV (default 37312.0, Al) plot -- boolean to plot the fit over temperature. reterr -- boolean to return fitting error. method -- either df or Qi, which is fitted linearly over temperature. Returns: ak optionally: the error as well.''' # Extract relevant data hw = S21data[:, 5] * 2 * np.pi * 0.6582 * 1e-9 #µeV kbT = S21data[:, 1] * 86.17 #µeV # Set needed constants hw0 = hw[0] d = S21data[0, 25] kbTc = S21data[0, 21] * 86.17 D0 = 1.76 * kbTc # define y to fit: if method == 'df': y = (hw - hw0) / hw0 elif method == 'Qi': y = 1 / S21data[:, 4] - 1 / S21data[0, 4] # Mask the double measured temperatures, and only fit from 250 mK mask1 = np.zeros(len(y), dtype="bool") mask1[np.unique(np.round(S21data[:, 1], decimals=2), return_index=True)[1]] = True mask = np.logical_and(mask1, (kbT >= .25 * 86.17)) if mask.sum() > 3: y = y[mask] else: warnings.warn( 'Not enough high temperature S21data, taking the last 10 points') y = y[mask1][-10:] # define x to fit: x = np.zeros(len(y)) i = 0 s0 = cinduct(hw0, D(kbT[0], N0, kbTc, kbTD), kbT[0]) for kbTi in kbT[mask]: D_0 = D(kbTi, N0, kbTc, kbTD) s = cinduct(hw[i], D_0, kbTi) if method == 'df': x[i] = (s[1] - s0[1]) / s0[1] * beta(lbd0, d, D_0, D0, kbTi) / 4 elif method == 'Qi': x[i] = (s[0] - s0[0]) / s0[1] * beta(lbd0, d, D_0, D0, kbTi) / 2 i += 1 #do the fit: fit = curve_fit(lambda t, ak: ak * t, x, y) if plot: plt.figure() plt.plot(x, y, 'o') plt.plot(x, fit[0] * x) plt.legend(['Data', 'Fit']) if method == 'df': plt.ylabel(r'$\delta f/f_0$') plt.xlabel(r'$\beta \delta \sigma_2/4\sigma_2 $') elif method == 'Qi': plt.ylabel(r'$\delta(1/Q_i)$') plt.xlabel(r'$\beta \delta \sigma_1/2\sigma_2 $') if reterr: return fit[0][0], np.sqrt(fit[1][0]) else: return fit[0][0]
def minfunc(kbT, s2s1, hw, SC): D_ = kidcalc.D(kbT, SC) s1, s2 = kidcalc.cinduct(hw, D_, kbT) return np.abs(s2s1 - s2 / s1)
def ak(S21data, SC=None, plot=False, reterr=False, method="df", Tmin=.25): """Calculates the kinetic induction fraction, based on Goa2008, PhD Thesis. Arguments: S21data -- the content of the .csv from the S21-analysis. SC -- Superconductor object, from SC module, default: Al plot -- boolean to plot the fit over temperature. reterr -- boolean to return fitting error. method -- either df or Qi, which is fitted linearly over temperature. Returns: ak optionally: the error in ak from fitting.""" if SC is None: SC = SuperCond.Al(Tc=S21data[0, 21]) # Extract relevant data hw = S21data[:, 5] * const.Planck / const.e * 1e6 # µeV kbT = S21data[:, 1] * const.Boltzmann / const.e * 1e6 # µeV hw0 = hw[0] # define y to fit: if method == "df": y = (hw - hw0) / hw0 elif method == "Qi": y = 1 / S21data[:, 4] - 1 / S21data[0, 4] # Mask the double measured temperatures, and only fit from 250 mK mask1 = np.zeros(len(y), dtype="bool") mask1[np.unique(np.round(S21data[:, 1], decimals=2), return_index=True)[1]] = True mask = np.logical_and(mask1, (kbT >= Tmin * const.Boltzmann / const.e * 1e6)) if mask.sum() > 3: y = y[mask] else: warnings.warn( "Not enough high temperature S21data, taking the last 10 points") y = y[mask1][-10:] # define x to fit: x = np.zeros(len(y)) i = 0 s0 = kidcalc.cinduct(hw0, kidcalc.D(kbT[0], SC), kbT[0]) for kbTi in kbT[mask]: D_0 = kidcalc.D(kbTi, SC) s = kidcalc.cinduct(hw[i], D_0, kbTi) if method == "df": x[i] = (s[1] - s0[1]) / s0[1] * kidcalc.beta( kbTi, D_0, SuperCond.Sheet(SC, d=S21data[0, 25])) / 4 elif method == "Qi": x[i] = (s[0] - s0[0]) / s0[1] * kidcalc.beta( kbTi, D_0, SuperCond.Sheet(SC, d=S21data[0, 25])) / 2 i += 1 # do the fit: fit = curve_fit(lambda t, ak: ak * t, x, y) if plot: plt.figure() plt.plot(x, y, "o") plt.plot(x, fit[0] * x) plt.legend(["Data", "Fit"]) if method == "df": plt.ylabel(r"$\delta f/f_0$") plt.xlabel(r"$\beta \delta \sigma_2/4\sigma_2 $") elif method == "Qi": plt.ylabel(r"$\delta(1/Q_i)$") plt.xlabel(r"$\beta \delta \sigma_1/2\sigma_2 $") if reterr: return fit[0][0], np.sqrt(fit[1][0]) else: return fit[0][0]
def s20(self): D_0 = kidcalc.D(self.kbT0, self.SC) return kidcalc.cinduct(self.hw0, D_0, self.kbT0)[1]
def Qi_0(self): hwread = self.hwread s_0 = kidcalc.cinduct(hwread, self.D_0, self.kbT) return kidcalc.Qi(s_0[0], s_0[1], self.ak, self.kbT, self.D_0, SC.Sheet(self.SC, self.d))