示例#1
0
def init_KID(
    Chipnum, KIDnum, Pread, Tbath, Teffmethod="GR", wvl=None, S21=False, SC_class=SC.Al
):
    """This returns an KID object, with the parameters initialized by 
    measurements on a physical KID. The effective temperature is set with an 
    lifetime measurement, either from GR noise (GR) or pulse (pulse)"""
    TDparam = io.get_grTDparam(Chipnum)
    S21data = io.get_S21data(Chipnum, KIDnum, Pread)
    Qc = S21data[0, 3]
    hw0 = S21data[0, 5] * const.Planck / const.e * 1e12 * 1e-6
    kbT0 = const.Boltzmann / const.e * 1e6 * S21data[0, 1]
    SC_inst = SC.init_SC(Chipnum, KIDnum, Pread, SC_class=SC_class)

    ak1 = calc.ak(S21data, SC_inst)

    if Teffmethod == "GR":
        Temp = io.get_grTemp(TDparam, KIDnum, Pread)
        taut = np.zeros(len(Temp))
        for i in range(len(Temp)):
            freq, SPR = io.get_grdata(TDparam, KIDnum, Pread, Temp[i])
            taut[i] = calc.tau(freq, SPR)[0]
        tauspl = interpolate.splrep(Temp[~np.isnan(taut)], taut[~np.isnan(taut)])
        tau1 = interpolate.splev(Tbath, tauspl)
        kbT = kidcalc.kbTbeff(tau1, SC_inst)
    elif Teffmethod == "pulse":
        peakdata_ph, peakdata_amp = io.get_pulsedata(Chipnum, KIDnum, Pread, Tbath, wvl)
        tau1 = calc.tau_pulse(peakdata_ph)
        kbT = kidcalc.kbTbeff(tau1, SC_inst)
    elif Teffmethod == "Tbath":
        kbT = Tbath * 1e-3 * const.Boltzmann / const.e * 1e6

    if S21:
        return S21KID(S21data, Qc=Qc, hw0=hw0, kbT0=kbT0, kbT=kbT, ak=ak1, SC=SC_inst)
    else:
        return KID(Qc=Qc, hw0=hw0, kbT0=kbT0, kbT=kbT, ak=ak1, SC=SC_inst)
示例#2
0
def rej_pulses(data,
               nrsgm=6,
               nrseg=32,
               sfreq=50e3,
               smoothdata=False,
               plot=False):
    '''Pulse rejection algorithm. It devides the time stream into segments and rejects segments based on a threshold. Based on PdV's pulse rejection algorithm.
    
    Arguments:
    data -- the time stream to be analyzed
    nrsgm -- number of times the minimal standard deviation to use as threshold (default 6)
    nrseg -- number of segments to divide the time stream in (default 32)
    sfreq -- sample frequency (default 50 kHz), only needed when plot or smoothdata.
    smoothdata -- boolean to determine to smooth the timestream first. If True, the lifetime is estimated on a Lorenzian fit on the non-rejected full time stream and given to the smooth function. if the fit fails, the lifetime is set to 1 µs. 
    plot -- boolean to plot time stream with rejection indication.
    
    Returns:
    The splitted input data and a list of booleans which segments are rejected.'''

    if smoothdata:
        #estimate lifetime via initial PSD and Lorentzian fit.
        freq, PSD = welch(data, sfreq, 'hamming', nperseg=.5 * sfreq)
        tau, tauerr = calc.tau(freq, 10 * np.log10(PSD))
        if tauerr / tau >= .1:
            tau = 1
            warnings.warn('Could not estimate lifetime from PSD, 1 µs is used')
        tau *= 1e-6  #convert to seconds
        smdata = smooth(data, tau, sfreq)
    else:
        smdata = data

    corrdata = subtr_offset(smdata)
    spdata = np.array(np.array_split(corrdata, nrseg))
    thrshld = nrsgm * spdata.std(1).min()
    reject = np.abs(spdata).max(1) > thrshld

    if plot:
        fig, ax = plt.subplots()
        t0 = 0
        for ind in range(nrseg):
            ax.plot((t0 + np.arange(len(spdata[ind]))) / sfreq,
                    spdata[ind],
                    color='b',
                    alpha=.5 if reject[ind] else 1)
            t0 += len(spdata[ind])
        ax.plot(np.arange(len(data)) / sfreq,
                thrshld * np.ones(len(data)),
                'r',
                label=f'{nrsgm}$\sigma_{{min}}$-threshold')
        ax.plot(
            np.arange(len(data)) / sfreq, -1 * thrshld * np.ones(len(data)),
            'r')
        ax.legend()
        ax.set_xlabel('Time (s)')
        plt.show()
        plt.close()

    return np.array(np.array_split(data, nrseg)), reject
示例#3
0
    def calc_ltnlvl(self,
                    Tmin,
                    Tmax,
                    *args,
                    lvlcal=1,
                    points=20,
                    plotspec=False,
                    plotnumrates=False,
                    PSDs='NN'):
        tau = np.full(points, np.nan)
        tauerr = np.full(points, np.nan)
        lvl = np.full(points, np.nan)
        lvlerr = np.full(points, np.nan)
        Temp = np.linspace(Tmin, Tmax, points)

        cmap = matplotlib.cm.get_cmap('viridis')
        norm = matplotlib.colors.Normalize(vmin=Temp.min(), vmax=Temp.max())
        for i in range(len(Temp)):
            if plotnumrates:
                freq, swdB, nums, rates = self.calc_spec(*args,
                                                         Temp[i] * self.kb,
                                                         lvlcal=lvlcal,
                                                         retnumrates=True,
                                                         PSDs=PSDs)
                plt.figure('Nums')
                numcol = ['b', 'g', 'r', 'c', 'm', 'y', 'k']
                for val in nums.values():
                    plt.plot(Temp[i], val, numcol.pop(0) + '.')

                plt.figure('Rates')
                ratecol = ['b', 'g', 'r', 'c', 'm', 'y', 'k']
                for val in rates.values():
                    plt.plot(Temp[i], val, ratecol.pop(0) + '.')

            else:
                freq, swdB = self.calc_spec(*args,
                                            Temp[i] * self.kb,
                                            lvlcal=lvlcal,
                                            PSDs=PSDs)

            tau[i], tauerr[i], lvl[i], lvlerr[i] = calc.tau(freq,
                                                            swdB,
                                                            startf=1e0,
                                                            stopf=1e5,
                                                            plot=False,
                                                            retfnl=True)
            if plotspec:
                plt.figure('Spectra')
                plt.plot(freq, swdB, color=cmap(norm(Temp[i])))
        if plotspec:
            plt.figure('Spectra')
            plt.xscale('log')
            plt.ylabel('Noise level (dBc/Hz)')
            plt.xlabel('Frequency (Hz)')
            clb = plt.colorbar(
                matplotlib.cm.ScalarMappable(norm=norm, cmap=cmap))
            clb.ax.set_title('T (K)')

        if plotnumrates:
            plt.figure('Nums')
            plt.title('Numbers')
            plt.yscale('log')
            plt.xlabel('Temperature (K)')
            plt.ylabel('Number')
            plt.legend(list(nums.keys()))
            plt.figure('Rates')
            plt.title('Rates')
            plt.yscale('log')
            plt.legend(list(rates.keys()))
            plt.ylabel(r'Rate ($\mu s^{-1}$)')
            plt.xlabel('Temperature (K)')
        return Temp, tau, tauerr, lvl, lvlerr
示例#4
0
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])
示例#5
0
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
示例#6
0
    def calc_ltnlvl(self,
                    Tmin,
                    Tmax,
                    *args,
                    lvlcal=1,
                    points=20,
                    plotspec=False,
                    plotnumrates=False,
                    PSDs="NN"):
        tau = np.full(points, np.nan)
        tauerr = np.full(points, np.nan)
        lvl = np.full(points, np.nan)
        lvlerr = np.full(points, np.nan)
        Temp = np.linspace(Tmin, Tmax, points)

        cmap = matplotlib.cm.get_cmap("viridis")
        norm = matplotlib.colors.Normalize(vmin=Temp.min(), vmax=Temp.max())
        for i in range(len(Temp)):
            if plotnumrates:
                freq, swdB, nums, rates = self.calc_spec(
                    *args,
                    Temp[i] * const.Boltzmann / const.e * 1e6,
                    lvlcal=lvlcal,
                    retnumrates=True,
                    PSDs=PSDs)
                plt.figure("Nums")
                numcol = ["b", "g", "r", "c", "m", "y", "k"]
                for val in nums.values():
                    plt.plot(Temp[i], val, numcol.pop(0) + ".")

                plt.figure("Rates")
                ratecol = ["b", "g", "r", "c", "m", "y", "k"]
                for val in rates.values():
                    plt.plot(Temp[i], val, ratecol.pop(0) + ".")

            else:
                freq, swdB = self.calc_spec(*args,
                                            Temp[i] * const.Boltzmann /
                                            const.e * 1e6,
                                            lvlcal=lvlcal,
                                            PSDs=PSDs)

            tau[i], tauerr[i], lvl[i], lvlerr[i] = calc.tau(freq,
                                                            swdB,
                                                            startf=1e0,
                                                            stopf=1e5,
                                                            plot=False,
                                                            retfnl=True)
            if plotspec:
                plt.figure("Spectra")
                plt.plot(freq, swdB, color=cmap(norm(Temp[i])))
        if plotspec:
            plt.figure("Spectra")
            plt.xscale("log")
            plt.ylabel("Noise level (dBc/Hz)")
            plt.xlabel("Frequency (Hz)")
            clb = plt.colorbar(
                matplotlib.cm.ScalarMappable(norm=norm, cmap=cmap))
            clb.ax.set_title("T (K)")

        if plotnumrates:
            plt.figure("Nums")
            plt.title("Numbers")
            plt.yscale("log")
            plt.xlabel("Temperature (K)")
            plt.ylabel("Number")
            plt.legend(list(nums.keys()))
            plt.figure("Rates")
            plt.title("Rates")
            plt.yscale("log")
            plt.legend(list(rates.keys()))
            plt.ylabel(r"Rate ($\mu s^{-1}$)")
            plt.xlabel("Temperature (K)")
        return Temp, tau, tauerr, lvl, lvlerr
示例#7
0
def Nqp(Chipnum,
        KIDnum,
        pltPread='all',
        spec='cross',
        startstopf=(None, None),
        delampNoise=False,
        del1fNoise=False,
        del1fnNoise=False,
        Tmax=500,
        relerrthrs=.3,
        pltThrm=True,
        pltNqpQi=False,
        splitT=0,
        pltNqptau=False,
        tescPread='max',
        nqpaxis=True,
        fig=None,
        ax=None,
        label=None,
        clr=None,
        N0=1.72e4,
        kbTD=37312.0,
        kb=86.17):
    '''Plots the number of quasiparticle calculated from the noise levels and lifetimes from PSDs.
    options similar to options in ltnlvl.
    TODO: delete double code in ltnlvl and Nqp
    
    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 or fig 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(),
                                           -.95 * Preadar.min())
        clb = fig.colorbar(matplotlib.cm.ScalarMappable(norm=norm, cmap=cmap),
                           ax=ax)
        clb.ax.set_title(r'$P_{read}$ (dBm)')

    for Pread in Preadar:
        S21data = io.get_S21data(Chipnum, KIDnum, Pread)

        if spec == 'cross':
            Respspl = interpolate.splrep(S21data[:, 1] * 1e3,
                                         np.sqrt(S21data[:, 10] *
                                                 S21data[:, 18]),
                                         s=0)
        elif spec == 'amp':
            Respspl = interpolate.splrep(S21data[:, 1] * 1e3,
                                         S21data[:, 18],
                                         s=0)
        elif spec == 'phase':
            Respspl = interpolate.splrep(S21data[:, 1] * 1e3,
                                         S21data[:, 10],
                                         s=0)

        Temp = io.get_grTemp(TDparam, KIDnum, Pread)
        Temp = Temp[Temp < Tmax]
        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], Respspl)**2
            lvlerr = lvlerr / interpolate.splev(Temp[i], 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 Preadar.size > 1:
            clr = cmap(norm(-1 * Pread))
        elif pltPread == 'min':
            clr = 'purple'
        elif pltPread == 'max':
            clr = 'gold'

        dataline = ax.errorbar(Temp[mask],
                               Nqp[mask],
                               yerr=Nqperr[mask],
                               color=clr,
                               marker='o',
                               mec='k',
                               capsize=2.,
                               label=label)
        if pltNqptau:
            tesc = calc.tesc(Chipnum, KIDnum, Pread=tescPread)
            Nqp_ = S21data[0, 14] * kidcalc.nqpfromtau(taut, tesc,
                                                       kb * S21data[0, 21])
            tauline, = ax.plot(Temp[mask],
                               Nqp_[mask],
                               color=clr,
                               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)
            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:
                clr = 'g'
            else:
                clr = cmap(norm(closestPread))
            Qline, = ax.plot(totalT[totalT > splitT] * 1e3,
                             totalNqp[totalT > splitT],
                             linestyle='-',
                             color=clr,
                             zorder=len(ax.lines) + 1,
                             label='$Q_i$')
            ax.plot(totalT[totalT < splitT] * 1e3,
                    totalNqp[totalT < splitT],
                    linestyle='--',
                    color=clr,
                    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(kb * T[i] * 1e-3, N0, kb * S21data[0, 21], kbTD)
            NqpT[i] = S21data[0, 14] * kidcalc.nqp(kb * T[i] * 1e-3, D_, N0)
        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 * S21data[0, 14]

        def Nqptonqp(x):
            return x / S21data[0, 14]

        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 + .12, b, w, h])
示例#8
0
def ltnlvl(Chipnum,
           KIDlist=None,
           pltPread='all',
           spec='cross',
           Tminmax=None,
           startstopf=(None, None),
           decades=3,
           minfreq=1e2,
           lvlcomp='',
           delampNoise=False,
           del1fNoise=False,
           del1fnNoise=False,
           suboffres=False,
           relerrthrs=.2,
           pltKIDsep=True,
           pltthlvl=False,
           pltkaplan=False,
           pltthmfnl=False,
           plttres=False,
           fig=None,
           ax12=None,
           color='Pread',
           pltclrbar=True,
           fmt='-o',
           label=None,
           defaulttesc=0,
           tescPread='max',
           tescpltkaplan=False,
           tescTminmax=(300, 400),
           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
    decades,minfreq -- fitting options, see kidata.calc.tau method
    lvlcomp -- defines how the levels are compensated. Use Resp for responsivity compensation.
        (will be moved in the future)
    del{}Noise -- filter options {amp,1f,1fn} spectrum before fitting, see kidata.filters module.
    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(),
                                               -.95 * kwargs['Preadar'].min())
            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() * .95)
            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())
            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())
            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 pltthlvl or 'tesc' in lvlcomp or pltkaplan:
            tesc_ = calc.tesc(Chipnum,
                              KIDnum,
                              defaulttesc=defaulttesc,
                              minTemp=tescTminmax[0],
                              maxTemp=tescTminmax[1],
                              relerrthrs=relerrthrs,
                              Pread=tescPread,
                              pltkaplan=tescpltkaplan)

        for Pread in Preadar:
            Temp = np.trim_zeros(io.get_grTemp(TDparam, KIDnum, Pread))
            if lvlcomp != '':

                S21data = io.get_S21data(Chipnum, KIDnum, Pread)
                if 'ak' in lvlcomp:
                    akin = calc.ak(S21data)
                V = S21data[0, 14]
                if spec == 'cross':
                    Respspl = interpolate.splrep(S21data[:, 1] * 1e3,
                                                 np.sqrt(S21data[:, 10] *
                                                         S21data[:, 18]),
                                                 s=0)
                elif spec == 'amp':
                    Respspl = interpolate.splrep(S21data[:, 1] * 1e3,
                                                 S21data[:, 18],
                                                 s=0)
                elif spec == 'phase':
                    Respspl = interpolate.splrep(S21data[:, 1] * 1e3,
                                                 S21data[:, 10],
                                                 s=0)

                if lvlcomp == 'QakV':
                    sqrtlvlcompspl = interpolate.splrep(S21data[:, 1] * 1e3,
                                                        S21data[:, 2] * akin /
                                                        V,
                                                        s=0)
                elif lvlcomp == 'QaksqrtV':
                    sqrtlvlcompspl = interpolate.splrep(S21data[:, 1] * 1e3,
                                                        S21data[:, 2] * akin /
                                                        np.sqrt(V),
                                                        s=0)
                elif lvlcomp == 'QaksqrtVtesc':
                    sqrtlvlcompspl = interpolate.splrep(
                        S21data[:,1]*1e3,
                        S21data[:,2]*akin/np.sqrt(V*\
                                                  (1+tesc_/.28e-3)),s=0)
                elif lvlcomp == 'QaksqrtVtescTc':
                    sqrtlvlcompspl = interpolate.splrep(
                        S21data[:,1]*1e3,
                        S21data[:,2]*akin/np.sqrt(V*\
                                                   (1+tesc_/.28e-3)*\
                                                (86.17*S21data[0,21])**3/\
                                                   (S21data[0,15]/1.6e-19*1e6)**2),s=0)
                elif lvlcomp == 'Resp':
                    sqrtlvlcompspl = Respspl

                elif lvlcomp == 'RespPulse':
                    pulsePreadar = io.get_pulsePread(Chipnum, KIDnum)
                    pulsePreadselect = pulsePreadar[np.abs(pulsePreadar -
                                                           Pread).argmin()]
                    pulseTemp = io.get_pulseTemp(Chipnum, KIDnum,
                                                 pulsePreadselect).min()
                    pulsewvl = io.get_pulsewvl(Chipnum, KIDnum,
                                               pulsePreadselect,
                                               pulseTemp).min()
                    phasepulse, amppulse = io.get_pulsedata(
                        Chipnum, KIDnum, pulsePreadselect, pulseTemp, pulsewvl)

                    phtau = calc.tau_pulse(phasepulse)
                    amptau = calc.tau_pulse(amppulse)
                    assert np.abs(
                        1 - phtau / amptau
                    ) < .1, 'Amp and Phase lifetimes differ by more than 10%'
                    dAdTheta = -1 * (amppulse / phasepulse
                                     )[600:int(600 + 2 * phtau)].mean()

                    if spec == 'cross':
                        Respspl = interpolate.splrep(
                            S21data[:, 1] * 1e3,
                            np.sqrt(S21data[:, 10]**2 * dAdTheta),
                            s=0)
                    elif spec == 'amp':
                        Respspl = interpolate.splrep(S21data[:, 1] * 1e3,
                                                     S21data[:, 10] * dAdTheta,
                                                     s=0)
                    elif spec == 'phase':
                        Respspl = interpolate.splrep(S21data[:, 1] * 1e3,
                                                     S21data[:, 10],
                                                     s=0)
                    sqrtlvlcompspl = Respspl

                elif lvlcomp == 'RespPint':
                    Pint = 10**(-Pread / 10) * S21data[:, 2]**2 / (
                        S21data[:, 3] * np.pi)
                    Pint /= Pint[0]
                    sqrtlvlcompspl = interpolate.splrep(
                        S21data[:, 1] * 1e3,
                        interpolate.splev(S21data[:, 1] * 1e3, Respspl) /
                        Pint**(1 / 4),
                        s=0)
                elif lvlcomp == 'RespV':
                    sqrtlvlcompspl = interpolate.splrep(
                        S21data[:, 1] * 1e3,
                        interpolate.splev(S21data[:, 1] * 1e3, Respspl) *
                        np.sqrt(V),
                        s=0)
                elif lvlcomp == 'RespVtescTc':
                    kbTc = 86.17 * S21data[0, 21]
                    sqrtlvlcompspl = interpolate.splrep(
                        S21data[:,1]*1e3,
                        interpolate.splev(S21data[:,1]*1e3,
                                          Respspl)*\
                        np.sqrt(V*(1+tesc_/.28e-3)*\
                                (kbTc)**3/\
                                (kidcalc.D(86.17*S21data[:,1],1.72e4,kbTc,37312.))**2),s=0)
                elif lvlcomp == 'RespLowT':
                    sqrtlvlcompspl = interpolate.splrep(
                        S21data[:,1]*1e3,np.ones(len(S21data[:,1]))*\
                    interpolate.splev(S21data[0,1]*1e3,Respspl))
                else:
                    raise ValueError(
                        '{} is an invalid compensation method'.format(lvlcomp))

                Pint = 10 * np.log10(10**(-1 * Pread / 10) * S21data[0, 2]**2 /
                                     S21data[0, 3] / np.pi)
            else:
                sqrtlvlcompspl = interpolate.splrep(Temp, np.ones(len(Temp)))

            if suboffres:
                Temp = np.intersect1d(
                    Temp, io.get_grTemp(TDparamoffres, KIDnum, Pread))

            if Tminmax != None:
                if Tminmax[0] != None:
                    Temp = Temp[Temp > Tminmax[0]]
                if Tminmax[1] != 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],
                             decades=decades,minfreq=minfreq)
                if showfit:
                    print(tauterr[i] / taut[i])

                lvl[i] = lvl[i] / interpolate.splev(Temp[i], sqrtlvlcompspl)**2
                lvlerr[i] = lvlerr[i] / interpolate.splev(
                    Temp[i], sqrtlvlcompspl)**2

            #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

            axs[0].errorbar(Temp[mask],
                            taut[mask],
                            yerr=tauterr[mask],
                            fmt=fmt,
                            capsize=3.,
                            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.,
                            color=clr,
                            mec='k',
                            label=label if Pread == Preadar[-1] else '')
            if pltthlvl:
                if Tminmax is not None:
                    Tstartstop = Tminmax
                else:
                    Tstartstop = (Temp[mask].min(), Temp[mask].max())
                Ttemp = np.linspace(*Tstartstop, 100)
                explvl = interpolate.splev(Ttemp, Respspl)**2
                explvl *= 4*.44e-6*S21data[0,14]*1.72e4*(86.17*S21data[0,21])**3/\
                (2*(S21data[0,15]/1.602e-19*1e6)**2)*(1+tesc_/.28e-3)/2
                explvl /= interpolate.splev(Ttemp, sqrtlvlcompspl)**2
                thlvlplot, = axs[1].plot(Ttemp,
                                         10 * np.log10(explvl),
                                         color=clr,
                                         linestyle='--',
                                         linewidth=2.)
                axs[1].legend((thlvlplot, ), (r'Expected noise level', ))

            if pltkaplan and Temp[mask].size != 0 and Pread == Preadar.max():
                if Tminmax is not None:
                    Tstartstop = Tminmax
                else:
                    Tstartstop = (Temp[mask].min(), Temp[mask].max())
                T = np.linspace(*Tstartstop, 100) * 1e-3
                taukaplan = kidcalc.tau_kaplan(T,
                                               tesc=tesc_,
                                               kbTc=86.17 * S21data[0, 21])
                kaplanfit, = axs[0].plot(T * 1e3,
                                         taukaplan,
                                         color=clr,
                                         linestyle='--',
                                         linewidth=2.)
                axs[0].legend((kaplanfit, ), ('Kaplan', ))

            if pltthmfnl:
                try:
                    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] = V * nqp(T[i] * 86.17 * 1e-3, S21data[0, 15] /
                                         1.602e-19 * 1e6, 1.72e4)
                    thmfnl = 4*interpolate.splev(T,tauspl)*1e-6*\
                        Nqp*interpolate.splev(T,Respspl)**2
                    thmfnl /= interpolate.splev(T, sqrtlvlcompspl)**2
                    thmfnlplot, = axs[1].plot(T,
                                              10 * np.log10(thmfnl),
                                              color=clr,
                                              linestyle='--',
                                              linewidth=3.)
                    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:
                tresline, = axs[0].plot(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):
            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