def PowersvsT(Chipnum, KIDnum, density=False, phnum=False, fig=None, axs=None): """Plots the internal and absorbed powers over temperature, for different read powers (color). Options: Density -- the powers are devided by the superconductor volume phnum -- the powers are expressed in resonator photon occupations""" if axs is None or fig is None: fig, axs = plt.subplots(1, 2, figsize=(10, 4)) Preadar = io.get_S21Pread(Chipnum, KIDnum) cmap = matplotlib.cm.get_cmap("plasma") norm = matplotlib.colors.Normalize(-1.05 * Preadar.max(), -0.95 * Preadar.min()) clb = fig.colorbar(matplotlib.cm.ScalarMappable(norm=norm, cmap=cmap)) clb.ax.set_title(r"$P_{read}$ (dBm)") for Pread in Preadar: S21data = io.get_S21data(Chipnum, KIDnum, Pread) Q = S21data[:, 2] Qc = S21data[:, 3] Qi = S21data[:, 4] T = S21data[:, 1] * 1e3 Pabs = 10**(S21data[0, 7] / 10) / 2 * 4 * Q**2 / (Qi * Qc) * 1e-3 / const.e Pint = 10**(S21data[:, 8] / 10) * 1e-3 / const.e if phnum: Pabs /= const.Planck / const.e * 1e12 * (S21data[:, 5] * 1e-6)**2 Pint /= onst.Planck / const.e * 1e12 * (S21data[:, 5] * 1e-6)**2 if density: Pabs /= S21data[0, 14] Pint /= S21data[0, 14] axs[1].plot(T, Pabs, color=cmap(norm(-1 * Pread))) axs[0].plot(T, Pint, color=cmap(norm(-1 * Pread))) title0 = "Internal Power" title1 = "Absorbed Power" if phnum: ylabel = "$N_{\gamma}^{res}$" else: ylabel = "$eV~s^{-1}$" if density: ylabel += " $\mu m^{-3}$" title0 += " Density" title1 += " Density" axs[0].set_title(title0) axs[1].set_title(title1) axs[0].set_ylabel(ylabel) axs[0].set_yscale("log") axs[1].set_yscale("log") return fig, axs
def tesc(Chipnum, KIDnum, Pread='max', minTemp=200, maxTemp=400, taunonkaplan=2e2, taures=1e1, relerrthrs=.2, pltfit=False, pltkaplan=False, reterr=False, t0=.44, kb=86.17, tpb=.28e-3, N0=1.72e4, kbTD=37312.0, defaulttesc=0): '''Calculates the phonon escape time from the GR noise lifetimes and Kaplan. Uses data at Pread (default max), and temperatures between minTemp,maxTemp (default (300,400)). Only lifetimes between taunonkaplan and taures, and with a relative error threshold of relerrthrs are considered. The remaining lifetimes, tesc is calculated and averaged. The error (optional return) is the variance of the remaining lifetimes. If this fails, defaulttesc is returned.''' TDparam = io.get_grTDparam(Chipnum) Pread = _selectPread(Pread, io.get_grPread(TDparam, KIDnum))[0] kbTc = io.get_S21data(Chipnum, KIDnum, io.get_S21Pread(Chipnum, KIDnum)[0])[0, 21] * kb Temp = io.get_grTemp(TDparam, KIDnum, Pread) Temp = Temp[np.logical_and(Temp < maxTemp, Temp > minTemp)] tescar, tescarerr, tqpstar, tqpstarerr = np.zeros((4, len(Temp))) for i in range(len(Temp)): if pltfit: print('{} KID{} -{} dBm T={} mK'.format(Chipnum, KIDnum, Pread, Temp[i])) freq, SPR = io.get_grdata(TDparam, KIDnum, Pread, Temp[i]) tqpstar[i], tqpstarerr[i] = tau(freq, SPR, plot=pltfit) if tqpstarerr[i]/tqpstar[i] > relerrthrs or \ (tqpstar[i] > taunonkaplan or tqpstar[i] < taures): tescar[i] = np.nan else: tescar[i] = kidcalc.tesc(kb * Temp[i] * 1e-3, tqpstar[i], t0, tpb, N0, kbTc, kbTD) tescarerr[i] = np.abs( kidcalc.tesc(kb * Temp[i] * 1e-3, tqpstarerr[i], t0, tpb, N0, kbTc, kbTD) + tpb) if tescar[~np.isnan(tescar)].size > 0: tesc1 = np.mean(tescar[~np.isnan(tescar)]) tescerr = np.sqrt( np.std(tescar[~np.isnan(tescar)])**2 + ((tescarerr[~np.isnan(tescar)] / (~np.isnan(tescar)).sum())**2).sum()) else: tesc1 = np.nan if tesc1 < 0 or np.isnan(tesc1) or tesc1 > 1e-2: warnings.warn( 'tesc ({}) is not valid and set to {} µs. {}, KID{}'.format( tesc1, defaulttesc, Chipnum, KIDnum)) tesc1 = defaulttesc if pltkaplan: plt.figure() plt.errorbar(Temp, tqpstar, yerr=tqpstarerr, capsize=5., fmt='o') mask = ~np.isnan(tescar) plt.errorbar(Temp[mask], tqpstar[mask], fmt='o') try: T = np.linspace(Temp[~np.isnan(tqpstar)].min(), Temp[~np.isnan(tqpstar)].max(), 100) except ValueError: T = np.linspace(minTemp, maxTemp, 100) taukaplan = kidcalc.tau_kaplan(T * 1e-3, tesc=tesc1, kbTc=kbTc) plt.plot(T, taukaplan) plt.yscale('log') plt.ylim(None, 1e4) plt.xlabel('T (mK)') plt.ylabel(r'$\tau_{qp}^*$ (µs)') plt.legend(['Kaplan', 'GR Noise Data', 'Selected Data']) plt.show() plt.close() if reterr: return tesc1, tescerr else: return tesc1
def Qif0( Chipnum, KIDnum, color="Pread", Tmax=0.5, pltPread="all", fracfreq=False, fig=None, ax12=None, xaxis="T", **kwargs, ): """Plot the internal quality factor and resonance frequency from S21-measurement. The color gives different read powers, but can be set to Pint as well. If fracfreq is True, the y-axis is df/f0, instead of f0.""" dfld = io.get_datafld() if fig is None or ax12 is None: fig, axs = plt.subplots(1, 2, figsize=(12, 4)) fig.suptitle(f"{Chipnum}, KID{KIDnum}") else: axs = ax12 Preadar = _selectPread(pltPread, io.get_S21Pread(Chipnum, KIDnum)) if color == "Pread": cmap = matplotlib.cm.get_cmap("plasma") norm = matplotlib.colors.Normalize(-1.05 * Preadar.max(), -0.95 * Preadar.min()) clb = fig.colorbar(matplotlib.cm.ScalarMappable(norm=norm, cmap=cmap)) clb.ax.set_title(r"$P_{read}$ (dBm)") elif color == "Pint": Pint = np.array(io.get_Pintdict(Chipnum)[KIDnum]) cmap = matplotlib.cm.get_cmap("plasma") norm = matplotlib.colors.Normalize(Pint.min() * 1.05, Pint.max() * 0.95) clb = fig.colorbar(matplotlib.cm.ScalarMappable(norm=norm, cmap=cmap)) clb.ax.set_title(r"$P_{int}$ (dBm)") for Pread in Preadar: S21data = io.get_S21data(Chipnum, KIDnum, Pread) if color == "Pread": clr = cmap(norm(-Pread)) elif color == "Pint": clr = cmap(norm(Pint[Preadar == Pread][0])) else: clr = color T = S21data[:, 1] # set what will be on the x and y axis if xaxis == "T": xvalues = T * 1e3 yvaluesQ = S21data[:, 4] elif xaxis == "Nqp": xvalues = S21data[:, 12] yvaluesQ = 1 / S21data[:, 4] else: raise ValueError("Not a valid xaxis argument") axs[0].plot(xvalues[T < Tmax], yvaluesQ[T < Tmax], color=clr, **kwargs) if fracfreq: axs[1].plot( xvalues[T < Tmax], (S21data[T < Tmax, 5] - S21data[0, 5]) / S21data[0, 5], color=clr, **kwargs, ) else: axs[1].plot(xvalues[T < Tmax], S21data[T < Tmax, 5] * 1e-9, color=clr, **kwargs) for ax in axs: if xaxis == "T": ax.set_xlabel("Temperature (mK)") elif xaxis == "Nqp": ax.set_xlabel("$N_{qp}$") ax.ticklabel_format(axis="x", style="sci", scilimits=(0, 0)) if xaxis == "T": axs[0].set_ylabel("$Q_i$") axs[0].set_yscale("log") elif xaxis == "Nqp": axs[0].set_ylabel("$1/Q_i$") if fracfreq: axs[1].set_ylabel("$\delta f_{res}/f_0$") else: axs[1].set_ylabel("f0 (GHz)") fig.tight_layout()
def Nqp( Chipnum, KIDnum, pltPread="all", spec="cross", startstopf=(None, None), delampNoise=False, del1fNoise=False, del1fnNoise=False, Tminmax=None, relerrthrs=0.3, pltThrm=True, pltNqpQi=False, splitT=0, pltNqptau=False, SCvol=None, SCkwargs={}, nqpaxis=True, fig=None, ax=None, label=None, color=None, fmt="-o", ): """Plots the number of quasiparticle calculated from the noise levels and lifetimes from PSDs. options similar to options in ltnlvl. pltThrm -- also plot thermal line (needs constants) pltNqpQi -- plot Nqp from Qi as well (needs constants) splitT -- makes NqpQi line dashed below this T pltNqptau -- plot Nqp from lifetime only (need constants) nqpaxis -- also shows density on right axis.""" TDparam = io.get_grTDparam(Chipnum) if ax is None: fig, ax = plt.subplots() Preadar = _selectPread(pltPread, io.get_grPread(TDparam, KIDnum)) if Preadar.size > 1: cmap = matplotlib.cm.get_cmap("plasma") norm = matplotlib.colors.Normalize(-1.05 * Preadar.max(), -0.95 * Preadar.min()) clb = fig.colorbar(matplotlib.cm.ScalarMappable(norm=norm, cmap=cmap), ax=ax) clb.ax.set_title(r"$P_{read}$ (dBm)") if SCvol is None: SCvol = SuperCond.init_SCvol(Chipnum, KIDnum, set_tesc=pltNqptau, **SCkwargs) for Pread in Preadar: S21data = io.get_S21data(Chipnum, KIDnum, Pread) Respspl = calc.Respspl(Chipnum, KIDnum, Pread, var=spec) Temp = io.get_grTemp(TDparam, KIDnum, Pread) if Tminmax is not None: if Tminmax[0] is not None: Temp = Temp[Temp > Tminmax[0]] if Tminmax[1] is not None: Temp = Temp[Temp < Tminmax[1]] Nqp, Nqperr, taut = np.zeros((3, len(Temp))) for i in range(len(Temp)): freq, SPR = io.get_grdata(TDparam, KIDnum, Pread, Temp[i], spec=spec) if delampNoise: freq, SPR = filters.del_ampNoise(freq, SPR) if del1fNoise: freq, SPR = filters.del_1fNoise(freq, SPR) if del1fnNoise: freq, SPR = filters.del_1fnNoise(freq, SPR) taut[i], tauterr, lvl, lvlerr = calc.tau(freq, SPR, retfnl=True, startf=startstopf[0], stopf=startstopf[1]) lvl = lvl / interpolate.splev(Temp[i] * 1e-3, Respspl)**2 lvlerr = lvlerr / interpolate.splev(Temp[i] * 1e-3, Respspl)**2 Nqp[i] = lvl / (4 * taut[i] * 1e-6) Nqperr[i] = np.sqrt((lvlerr / (4 * taut[i] * 1e-6))**2 + (-lvl * tauterr * 1e-6 / (4 * (taut[i] * 1e-6)**2))**2) mask = ~np.isnan(Nqp) mask[mask] = Nqperr[mask] / Nqp[mask] <= relerrthrs if color is None: if Preadar.size > 1: color = cmap(norm(-1 * Pread)) elif pltPread == "min": color = "purple" elif pltPread == "max": color = "gold" dataline = ax.errorbar( Temp[mask], Nqp[mask], yerr=Nqperr[mask], color=color, fmt=fmt, mec="k", capsize=2.0, label=label, ) if pltNqptau: Nqp_ = SCvol.V * kidcalc.nqpfromtau(taut, SCvol) (tauline, ) = ax.plot( Temp[mask], Nqp_[mask], color=color, zorder=len(ax.lines) + 1, label="$\\tau_{qp}^*$", ) if pltNqpQi: Preadar = io.get_S21Pread(Chipnum, KIDnum) for Pread in Preadar: S21data = io.get_S21data(Chipnum, KIDnum, Pread) T, Nqp = calc.NqpfromQi(S21data, SC=SCvol.SC) mask = np.logical_and(T * 1e3 > ax.get_xlim()[0], T * 1e3 < ax.get_xlim()[1]) totalT = T[mask] totalNqp = Nqp[mask] if len(Preadar) == 1: color = "g" else: color = cmap(norm(closestPread)) (Qline, ) = ax.plot( totalT[totalT > splitT] * 1e3, totalNqp[totalT > splitT], linestyle="-", color=color, zorder=len(ax.lines) + 1, label="$Q_i$", ) ax.plot( totalT[totalT < splitT] * 1e3, totalNqp[totalT < splitT], linestyle="--", color=color, zorder=len(ax.lines) + 1, ) if pltThrm: T = np.linspace(*ax.get_xlim(), 100) NqpT = np.zeros(100) for i in range(len(T)): D_ = kidcalc.D(const.Boltzmann / const.e * 1e6 * T[i] * 1e-3, SCvol.SC) NqpT[i] = SCvol.V * kidcalc.nqp( const.Boltzmann / const.e * 1e6 * T[i] * 1e-3, D_, SCvol.SC) (Thline, ) = ax.plot(T, NqpT, color="k", zorder=len(ax.lines) + 1, label="Thermal $N_{qp}$") handles, labels = ax.get_legend_handles_labels() by_label = dict(zip(labels, handles)) ax.legend(by_label.values(), by_label.keys()) ax.set_ylabel("$N_{qp}$") ax.set_xlabel("Temperature (mK)") ax.set_yscale("log") if nqpaxis: def nqptoNqp(x): return x * SCvol.V def Nqptonqp(x): return x / SCvol.V ax2 = ax.secondary_yaxis("right", functions=(Nqptonqp, nqptoNqp)) ax2.set_ylabel("$n_{qp}$ ($\\mu m^{-3}$)") if Preadar.size > 1: l, b, w, h = clb.ax.get_position().bounds clb.ax.set_position([l + 0.12, b, w, h])