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 tesc( Chipnum, KIDnum, SCvol=None, usePread="max", minTemp=200, maxTemp=400, taunonkaplan=2e2, taures=1e1, relerrthrs=0.2, pltfit=False, pltkaplan=False, reterr=False, 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 (200,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(usePread, io.get_grPread(TDparam, KIDnum))[0] if SCvol is None: S21data = io.get_S21data(Chipnum, KIDnum) SCvol = SuperCond.Volume(SuperCond.Al(Tc=S21data[0, 21]), V=S21data[0, 14], d=S21data[0, 25]) 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( const.Boltzmann / const.e * 1e6 * Temp[i] * 1e-3, tqpstar[i], SCvol.SC) tescarerr[i] = np.abs( kidcalc.tesc(const.Boltzmann / const.e * 1e6 * Temp[i] * 1e-3, tqpstarerr[i], SCvol.SC) + SCvol.SC.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 tescerr = 0 SCvol.tesc = tesc1 if pltkaplan: plt.figure() plt.errorbar(Temp, tqpstar, yerr=tqpstarerr, capsize=5.0, 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, SCvol) 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 spec( Chipnum, KIDlist=None, pltPread="all", spec="all", lvlcomp="", SCvol=None, SCkwargs={}, clbar=True, cmap=None, norm=None, del1fNoise=False, delampNoise=False, del1fnNoise=False, suboffres=False, plttres=False, Tminmax=(0, 500), ax12=None, xlim=(None, None), ylim=(None, None), ): """Plots PSDs of multiple KIDs, read powers and temperatures (indicated by color). Every KID has a new figure, which is returned if only one KID is plotted. lvlcomp specifies how the noise levels should be compensated (will be a different function in the future). Use Resp to divide by responsivity and obtain quasiparticle fluctuations. Use Resptres to compensate for the factor (1+(omega*taures)^2) and get the quasiparticle fluctuations. plttres will plot arrow at the frequencies corresponding to the resonator ring time.""" TDparam = io.get_grTDparam(Chipnum) if suboffres: TDparamoffres = io.get_grTDparam(Chipnum, offres=True) if KIDlist is None: KIDlist = io.get_grKIDs(TDparam) elif type(KIDlist) is int: KIDlist = [KIDlist] if spec == "all": specs = ["cross", "amp", "phase"] elif type(spec) == list: specs = spec else: raise ValueError("Invalid Spectrum Selection") for KIDnum in KIDlist: if lvlcomp != "": if SCvol is None: SCvol = SuperCond.init_SCvol(Chipnum, KIDnum, **SCkwargs) else: SCvol = SuperCond.Vol(SuperCond.Al(), np.nan, np.nan) Preadar = _selectPread(pltPread, io.get_grPread(TDparam, KIDnum)) if ax12 is None: fig, axs = plt.subplots( len(Preadar), len(specs), figsize=(4 * len(specs), 4 * len(Preadar)), sharex=True, sharey=True, squeeze=False, ) fig.suptitle(f"{Chipnum}, KID{KIDnum}") else: axs = ax12 for ax1, Pread in zip(range(len(Preadar)), Preadar): axs[ax1, 0].set_ylabel("PSD (dBc/Hz)") Temp = io.get_grTemp(TDparam, KIDnum, Pread) if suboffres: Temp = np.intersect1d( Temp, io.get_grTemp(TDparamoffres, KIDnum, Pread)) Temp = Temp[np.logical_and(Temp < Tminmax[1], Temp > Tminmax[0])] if cmap is None or norm is None: cmap = matplotlib.cm.get_cmap("viridis") norm = matplotlib.colors.Normalize(Temp.min(), Temp.max()) if clbar: clb = plt.colorbar(matplotlib.cm.ScalarMappable(norm=norm, cmap=cmap), ax=axs[ax1, -1]) clb.ax.set_title("T (mK)") if plttres: S21data = io.get_S21data(Chipnum, KIDnum, Pread) for i in range(len(Temp)): for (ax2, spec) in zip(range(len(specs)), specs): lvlcompspl = calc.NLcomp(Chipnum, KIDnum, Pread, SCvol=SCvol, method=lvlcomp, var=spec) freq, SPR = io.get_grdata(TDparam, KIDnum, Pread, Temp[i], spec=spec) if suboffres: orfreq, orSPR = io.get_grdata(TDparamoffres, KIDnum, Pread, Temp[i], spec=spec) freq, SPR = filters.subtr_spec(freq, SPR, orfreq, orSPR) 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) SPR[SPR == -140] = np.nan SPR[SPR == -np.inf] = np.nan SPR = 10 * np.log10(10**(SPR / 10) / interpolate.splev( Temp[i] * 1e-3, lvlcompspl)) axs[ax1, ax2].plot(freq, SPR, color=cmap(norm(Temp[i]))) axs[ax1, ax2].set_xscale("log") axs[ax1, ax2].set_title(spec + ", -{} dBm".format(Pread)) axs[-1, ax2].set_xlabel("Freq. (Hz)") if plttres: Tind = np.abs(S21data[:, 1] - Temp[i] * 1e-3).argmin() fres = S21data[Tind, 5] / (2 * S21data[Tind, 2]) axs[ax1, ax2].annotate("", (fres, 1), (fres, 1.25), arrowprops=dict(arrowstyle="simple", color=cmap( norm(Temp[i])), ec="k"), annotation_clip=False, xycoords=('data', 'axes fraction')) axs[0, 0].set_xlim(*xlim) axs[0, 0].set_ylim(*ylim) # plt.tight_layout() if ax12 is None and len(KIDlist) == 1: return fig, axs
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])
def ltnlvl( Chipnum, KIDlist=None, pltPread="all", spec="cross", Tminmax=None, startstopf=(None, None), lvlcomp="", pltTTc=False, delampNoise=False, del1fNoise=False, del1fnNoise=False, suboffres=False, relerrthrs=0.1, pltKIDsep=True, pltthlvl=False, pltkaplan=False, pltthmlvl=False, plttres=False, plttscat=False, fig=None, ax12=None, color="Pread", pltclrbar=True, fmt="-o", label=None, SCvol=None, SCkwargs={}, showfit=False, savefig=False, ): """Plots the results from a Lorentzian fit to the PSDs of multiple KIDs, read powers and temperatures. Two axes: 0: lifetimes 1: noise levels, both with temperature on the x-axis. The color can be specified and is Pread by default. Options: startstopf -- defines the fitting window lvlcomp -- defines how the levels are compensated. Use Resp for responsivity compensation. (will be moved in the future) del{}Noise -- filter spectrum before fitting. relerrthrs -- only plot fits with a relative error threshold in lifetime less than this. pltKIDsep -- if True, different KIDs get a new figure. pltthlvl -- expected noise level is plotted as dashed line pltkaplan -- a kaplan fit (tesc as parameter) is plotted in the lifetime axis. pltthmfnl -- a noise level from the fitted lifetime and theoretical Nqp is plotted as well plttres -- the resonator ring time is plotted in the lifetime axis. ... multiple figure handling options ... ... options for the tesc deteremination ... showfit -- the fits are displayed in numerous new figures, for manual checking.""" def _make_fig(): fig, axs = plt.subplots(1, 2, figsize=(8, 3)) return fig, axs def _get_cmap(**kwargs): if color == "Pread": cmap = matplotlib.cm.get_cmap("plasma") norm = matplotlib.colors.Normalize(-1.05 * kwargs["Preadar"].max(), -0.95 * kwargs["Preadar"].min()) if pltclrbar: clb = fig.colorbar( matplotlib.cm.ScalarMappable(norm=norm, cmap=cmap)) clb.ax.set_title(r"$P_{read}$ (dBm)") elif color == "Pint": cmap = matplotlib.cm.get_cmap("plasma") norm = matplotlib.colors.Normalize(kwargs["Pintar"].min() * 1.05, kwargs["Pintar"].max() * 0.95) if pltclrbar: clb = fig.colorbar( matplotlib.cm.ScalarMappable(norm=norm, cmap=cmap)) clb.ax.set_title(r"$P_{int}$ (dBm)") elif color == "V": cmap = matplotlib.cm.get_cmap("cividis") norm = matplotlib.colors.Normalize( np.array(list(Vdict.values())).min(), np.array(list(Vdict.values())).max(), ) if pltclrbar: clb = fig.colorbar( matplotlib.cm.ScalarMappable(norm=norm, cmap=cmap)) clb.ax.set_title(r"Al Vol. ($\mu m^3$)") elif color == "KIDnum": cmap = matplotlib.cm.get_cmap("Paired") norm = matplotlib.colors.Normalize( np.array(KIDlist).min(), np.array(KIDlist).max()) if pltclrbar: clb = fig.colorbar( matplotlib.cm.ScalarMappable(norm=norm, cmap=cmap)) clb.ax.set_title("KID nr.") else: raise ValueError( "{} is not a valid variable as color".format(color)) return cmap, norm TDparam = io.get_grTDparam(Chipnum) if suboffres: TDparamoffres = io.get_grTDparam(Chipnum, offres=True) if KIDlist is None: KIDlist = io.get_grKIDs(TDparam) elif type(KIDlist) is int: KIDlist = [KIDlist] if color == "Pint": Pintdict = io.get_Pintdict(Chipnum) if not pltKIDsep: if ax12 is None: fig, axs = _make_fig() else: axs = ax12 if color == "Pint": Pintar = np.array([Pintdict[k] for k in KIDlist]) cmap, norm = _get_cmap(Pintar=Pintar) elif color == "V": Vdict = io.get_Vdict(Chipnum) cmap, norm = _get_cmap(Vdict=Vdict) elif color == "Pread": Preaddict = io.get_Preaddict(Chipnum) Preadar = np.array([Preaddict[k] for k in KIDlist]) cmap, norm = _get_cmap(Preadar=Preadar) elif color == "KIDnum": cmap, norm = _get_cmap(KIDlist=KIDlist) for KIDnum in KIDlist: Preadar = _selectPread(pltPread, io.get_grPread(TDparam, KIDnum)) if pltKIDsep: if ax12 is None: fig, axs = _make_fig() else: axs = ax12 if len(KIDlist) > 1: fig.suptitle(f"KID{KIDnum}") if color == "Pread": cmap, norm = _get_cmap(Preadar=Preadar) elif color == "Pint": cmap, norm = _get_cmap(Pintar=np.array(Pintdict[KIDnum])) if lvlcomp != "" or pltkaplan or pltthmlvl or pltthlvl or pltTTc: if SCvol is None: SCvol = SuperCond.init_SCvol(Chipnum, KIDnum, **SCkwargs) else: SCvol = SuperCond.Vol(SuperCond.Al(), np.nan, np.nan) for Pread in Preadar: Temp = np.trim_zeros(io.get_grTemp(TDparam, KIDnum, Pread)) lvlcompspl = calc.NLcomp(Chipnum, KIDnum, Pread, SCvol=SCvol, method=lvlcomp, var=spec) if suboffres: Temp = np.intersect1d( Temp, io.get_grTemp(TDparamoffres, 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]] taut = np.zeros((len(Temp))) tauterr = np.zeros((len(Temp))) lvl = np.zeros((len(Temp))) lvlerr = np.zeros((len(Temp))) for i in range(len(Temp)): freq, SPR = io.get_grdata(TDparam, KIDnum, Pread, Temp[i], spec) if suboffres: orfreq, orSPR = io.get_grdata(TDparamoffres, KIDnum, Pread, Temp[i], spec) freq, SPR = filters.subtr_spec(freq, SPR, orfreq, orSPR) 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) if showfit: print("{}, KID{}, -{} dBm, T={}, {}".format( Chipnum, KIDnum, Pread, Temp[i], spec)) taut[i], tauterr[i], lvl[i], lvlerr[i] = calc.tau( freq, SPR, plot=showfit, retfnl=True, startf=startstopf[0], stopf=startstopf[1], ) if showfit: print(tauterr[i] / taut[i]) lvl[i] = lvl[i] / interpolate.splev(Temp[i] * 1e-3, lvlcompspl) lvlerr[i] = lvlerr[i] / interpolate.splev( Temp[i] * 1e-3, lvlcompspl) # Deleting bad fits and plotting: mask = ~np.isnan(taut) mask[mask] = tauterr[mask] / taut[mask] <= relerrthrs if color == "Pread": clr = cmap(norm(-1 * Pread)) elif color == "Pint": clr = cmap(norm(Pint)) elif color == "V": clr = cmap(norm(Vdict[KIDnum])) elif color == "KIDnum": clr = cmap(norm(KIDnum)) else: clr = color if pltTTc: Temp = Temp / (SCvol.SC.kbTc / (const.Boltzmann / const.e * 1e6) * 1e3) axs[0].errorbar( Temp[mask], taut[mask], yerr=tauterr[mask], fmt=fmt, capsize=3.0, color=clr, mec="k", label=label if Pread == Preadar[-1] else "", ) axs[1].errorbar( Temp[mask], 10 * np.log10(lvl[mask]), yerr=10 * np.log10((lvlerr[mask] + lvl[mask]) / lvl[mask]), fmt=fmt, capsize=3.0, color=clr, mec="k", label=label if Pread == Preadar[-1] else "", ) if pltthlvl: if Tminmax is not None and not pltTTc: Tstartstop = Tminmax else: Tstartstop = (Temp[mask].min(), Temp[mask].max()) Ttemp = np.linspace(*Tstartstop, 100) if pltTTc: Ttemp = Ttemp * (SCvol.SC.kbTc / (const.Boltzmann / const.e * 1e6) * 1e3) explvl = (interpolate.splev( Ttemp * 1e-3, calc.Respspl(Chipnum, KIDnum, Pread, var=spec))**2) explvl *= (4 * SCvol.SC.t0 * 1e-6 * SCvol.V * SCvol.SC.N0 * (SCvol.SC.kbTc)**3 / (2 * (SCvol.SC.D0)**2) * (1 + SCvol.tesc / SCvol.SC.tpb) / 2) explvl /= interpolate.splev(Ttemp * 1e-3, lvlcompspl) if pltTTc: Ttemp = Ttemp / (SCvol.SC.kbTc / (const.Boltzmann / const.e * 1e6) * 1e3) (thlvlplot, ) = axs[1].plot( Ttemp, 10 * np.log10(explvl), color=clr, linestyle="--", linewidth=2.0, ) axs[1].legend((thlvlplot, ), (r"Expected noise level", )) if pltkaplan and Temp[mask].size != 0: if Tminmax is not None and not pltTTc: Tstartstop = Tminmax else: Tstartstop = (Temp[mask].min(), Temp[mask].max()) T = np.linspace(*Tstartstop, 100) if pltTTc: T = T * (SCvol.SC.kbTc / (const.Boltzmann / const.e * 1e6)) else: T = T * 1e-3 taukaplan = kidcalc.tau_kaplan(T, SCvol) if pltTTc: T = T / (SCvol.SC.kbTc / (const.Boltzmann / const.e * 1e6)) else: T = T * 1e3 axs[0].plot( T, taukaplan, color=clr, linestyle="--", linewidth=2.0, label="Kaplan, $\\tau_{qp}$", ) if plttscat: if Tminmax is not None: Tstartstop = Tminmax else: Tstartstop = (Temp[mask].min(), Temp[mask].max()) T = np.linspace(*Tstartstop, 100) if pltTTc: T = T * (SCvol.SC.kbTc / (const.Boltzmann / const.e * 1e6)) else: T = T * 1e-3 tscat = SCvol.SC.t0 / ( 2.277 * (SCvol.SC.kbTc / (2 * SCvol.SC.D0))**0.5 * (T / (SCvol.SC.kbTc / (const.Boltzmann / const.e * 1e6)))**(7 / 2)) if pltTTc: T = T / (SCvol.SC.kbTc / (const.Boltzmann / const.e * 1e6)) else: T = T * 1e3 axs[0].plot( T, tscat, color=clr, linestyle="-.", linewidth=2.0, label="Kaplan, $\\tau_s$", ) if pltthmlvl: try: if pltTTc: Temp = Temp * (SCvol.SC.kbTc / (const.Boltzmann / const.e * 1e6) * 1e3) tauspl = interpolate.splrep(Temp[mask], taut[mask], s=0) T = np.linspace(Temp[mask].min(), Temp[mask].max(), 100) Nqp = np.zeros(len(T)) for i in range(len(T)): Nqp[i] = SCvol.V * kidcalc.nqp( T[i] * 1e-3 * const.Boltzmann / const.e * 1e6, SCvol.D0, SCvol.SC, ) thmfnl = ( 4 * interpolate.splev(T, tauspl) * 1e-6 * Nqp * interpolate.splev( T * 1e-3, calc.Respspl(Chipnum, KIDnum, Pread, var=spec))**2) thmfnl /= interpolate.splev(T * 1e-3, lvlcompspl) if pltTTc: T = T / (SCvol.SC.kbTc / (const.Boltzmann / const.e * 1e6) * 1e3) (thmfnlplot, ) = axs[1].plot( T, 10 * np.log10(thmfnl), color=clr, linestyle="--", linewidth=3.0, ) axs[1].legend( (thmfnlplot, ), ("Thermal Noise Level \n with measured $\\tau_{qp}^*$", ), ) except: warnings.warn( "Could not make Thermal Noise Level, {},KID{},-{} dBm,{}" .format(Chipnum, KIDnum, Pread, spec)) if plttres: S21data = io.get_S21data(Chipnum, KIDnum, Pread) (tresline, ) = axs[0].plot( S21data[:, 1] / S21data[0, 21] if pltTTc else S21data[:, 1] * 1e3, S21data[:, 2] / (np.pi * S21data[:, 5]) * 1e6, color=clr, linestyle=":", ) axs[0].legend((tresline, ), ("$\\tau_{res}$", )) axs[0].set_yscale("log") for i in range(2): if pltTTc: axs[i].set_xlabel("$T/T_c$") else: axs[i].set_xlabel("Temperature (mK)") axs[0].set_ylabel(r"$\tau_{qp}^*$ (µs)") if lvlcomp == "Resp": axs[1].set_ylabel(r"Noise Level/$\mathcal{R}^2(T)$ (dB/Hz)") elif lvlcomp == "RespV": axs[1].set_ylabel(r"Noise Level/$(\mathcal{R}^2(T)V)$ (dB/Hz)") elif lvlcomp == "RespVtescTc": axs[1].set_ylabel(r"Noise Level/$(\mathcal{R}^2(T)\chi)$ (dB/Hz)") elif lvlcomp == "": axs[1].set_ylabel(r"Noise Level (dB/Hz)") elif lvlcomp == "RespLowT": axs[1].set_ylabel(r"Noise Level/$\mathcal{R}^2(T=50 mK)$ (dB/Hz)") else: axs[1].set_ylabel(r"comp. Noise Level (dB/Hz)") plt.tight_layout() if savefig: plt.savefig("GR_{}_KID{}_{}.pdf".format(Chipnum, KIDnum, spec)) plt.close() if ax12 is None: return fig, axs