示例#1
0
def lifetimes_in_TRange(kre: KrEvent, krnb: KrNBins, krb: KrBins,
                        krr: KrRanges, TL) -> List[KrFit]:
    """ Plots lifetime fitted to a range of T values"""

    # Specify the range and number of bins in Z
    Znbins = krnb.Z
    Zrange = krr.Z

    kfs = []
    for tlim in TL:

        # select data
        kre_t = select_in_TRange(kre, *tlim)
        z, e = kre_t.Z, kre_t.E

        x, y, yu = fitf.profileX(z, e, Znbins, Zrange)
        # Fit profile to an exponential
        seed = expo_seed(x, y)
        f = fitf.fit(fitf.expo, x, y, seed, sigma=yu)

        kf = KrFit(par=np.array(f.values),
                   err=np.array(f.errors),
                   chi2=chi2(f, x, y, yu))

        #krf.print_fit(kf)
        kfs.append(kf)

    return kfs
示例#2
0
def fit_lifetime(kB, kf, title="Lifetime Fit"):
    x = shift_to_bin_centers(kB.Z)
    y = kf.par
    yu = kf.err
    plt.errorbar(x, y, yu, np.diff(x)[0] / 2, fmt="kp", ms=7, lw=3)
    seed = expo_seed(x, y)
    f = fitf.fit(fitf.expo, x, y, seed, sigma=yu)
    plt.plot(x, f.fn(x), "r-", lw=4)
    print_fit(f)
    print('chi2 = {}'.format(chi2(f, x, y, yu)))
示例#3
0
def lifetimes_in_XYRange(kre: KrEvent,
                         krnb: KrNBins,
                         krb: KrBins,
                         krr: KrRanges,
                         xyr: XYRanges,
                         XL=[(-125, -75), (-125, -75), (75, 125), (75, 125)],
                         YL=[(-125, -75), (75, 125), (75, 125), (-125, -75)],
                         nx=2,
                         ny=2,
                         figsize=(8, 8)) -> KrFit:
    """ Plots lifetime fitted to a range of XY values"""

    # Specify the range and number of bins in Z
    Znbins = krnb.Z
    Zrange = krr.Z

    fig = plt.figure(figsize=figsize)

    # XL = [(-125, -75), (-125, -75), (75, 125),(75, 125)]
    # YL = [(-125, -75), (75, 125), (75, 125),(-125, -75)]
    KF = []
    for i, pair in enumerate(zip(XL, YL)):
        xlim = pair[0]
        ylim = pair[1]
        print(f'xlim = {xlim}, ylim ={ylim}')

        # select data in region defined by xyr
        xyr = XYRanges(X=xlim, Y=ylim)
        kre_xy = select_in_XYRange(kre, xyr)
        z, e = kre_xy.Z, kre_xy.E

        ax = fig.add_subplot(nx, ny, i + 1)
        x, y, yu = fitf.profileX(z, e, Znbins, Zrange)
        plt.errorbar(x, y, yu, np.diff(x)[0] / 2, fmt="kp", ms=7, lw=3)

        # Fit profile to an exponential
        seed = expo_seed(x, y)
        f = fitf.fit(fitf.expo, x, y, seed, sigma=yu)

        # plot fitted value
        plt.plot(x, f.fn(x), "r-", lw=4)

        labels("", "Energy (pes)", "Lifetime fit")

        kf = KrFit(par=np.array(f.values),
                   err=np.array(f.errors),
                   chi2=chi2(f, x, y, yu))
        KF.append(kf)
    return KF
示例#4
0
def lifetime_in_XYRange(kre: KrEvent, krnb: KrNBins, krb: KrBins,
                        krr: KrRanges, xyr: XYRanges) -> KrFit:
    """ Fits lifetime to a range of XY values"""

    # select data in region defined by xyr
    kre_xy = select_in_XYRange(kre, xyr)
    z, e = kre_xy.Z, kre_xy.E

    # Specify the range and number of bins in Z
    Znbins = krnb.Z
    Zrange = krr.Z

    # create a figure and plot 2D histogram and profile
    frame_data = plt.gcf().add_axes((.1, .3, .8, .6))
    plt.hist2d(z, e, (krb.Z, krb.E))
    x, y, yu = fitf.profileX(z, e, Znbins, Zrange)
    plt.errorbar(x, y, yu, np.diff(x)[0] / 2, fmt="kp", ms=7, lw=3)

    # Fit profile to an exponential
    seed = expo_seed(x, y)
    f = fitf.fit(fitf.expo, x, y, seed, sigma=yu)

    # plot fitted value
    plt.plot(x, f.fn(x), "r-", lw=4)

    # labels and ticks
    frame_data.set_xticklabels([])
    labels("", "Energy (pes)", "Lifetime fit")

    # add a second frame

    lims = plt.xlim()
    frame_res = plt.gcf().add_axes((.1, .1, .8, .2))
    # Plot (y - f(x)) / sigma(y) as a function of x
    plt.errorbar(x, (f.fn(x) - y) / yu, 1, np.diff(x)[0] / 2, fmt="p", c="k")
    plt.plot(lims, (0, 0), "g--")
    plt.xlim(*lims)
    plt.ylim(-5, +5)
    labels("Drift time (µs)", "Standarized residual")

    return KrFit(par=np.array(f.values),
                 err=np.array(f.errors),
                 chi2=chi2(f, x, y, yu))
示例#5
0
def fit_lifetime_from_profile(kre: KrEvent,
                              kR: KrRanges,
                              kNB: KrNBins,
                              kB: KrBins,
                              kL: KrRanges,
                              title="Lifetime Fit") -> KrFit:

    sel = in_range(kre.X, *kL.XY) & in_range(kre.Y, *kL.XY)
    z, e = kre.Z[sel], kre.E[sel]

    frame_data = plt.gcf().add_axes((.1, .35, .8, .6))
    plt.hist2d(z, e, (kB.Z, kB.E))

    x, y, yu = fitf.profileX(z, e, kNB.Z, kR.Z, kR.E)
    plt.errorbar(x, y, yu, np.diff(x)[0] / 2, fmt="kp", ms=7, lw=3)

    seed = expo_seed(x, y)
    f = fitf.fit(fitf.expo, x, y, seed, sigma=yu)

    plt.plot(x, f.fn(x), "r-", lw=4)

    frame_data.set_xticklabels([])
    labels("", "Energy (pes)", title)
    lims = plt.xlim()

    frame_res = plt.gcf().add_axes((.1, .1, .8, .2))
    plt.errorbar(x, (f.fn(x) - y) / yu, 1, np.diff(x)[0] / 2, fmt="p", c="k")
    plt.plot(lims, (0, 0), "g--")
    plt.xlim(*lims)
    plt.ylim(-5, +5)
    labels("Drift time (µs)", "Standarized residual")
    print_fit(f)
    print('chi2 = {}'.format(chi2(f, x, y, yu)))

    return KrFit(par=np.array(f.values[1]),
                 err=np.array(f.errors[1]),
                 chi2=np.array(chi2(f, x, y, yu)),
                 valid=np.ones(1))
示例#6
0
def fit_lifetime_slices(kre: KrEvent,
                        krnb: KrNBins,
                        krb: KrBins,
                        krr: KrRanges,
                        fit_var="E",
                        min_entries=1e2) -> KrLTSlices:
    """
    Slice the data in x and y, make the profile in z of E,
    fit it to a exponential and return the relevant values.

    """

    xybins = krb.XY
    nbins_xy = np.size(xybins) - 1
    nbins_z = krnb.Z
    nbins = nbins_xy, nbins_xy
    const = np.zeros(nbins)
    slope = np.zeros(nbins)
    constu = np.zeros(nbins)
    slopeu = np.zeros(nbins)
    chi2 = np.zeros(nbins)
    valid = np.zeros(nbins, dtype=bool)
    zrange = krr.Z

    for i in range(nbins_xy):
        sel_x = in_range(kre.X, *xybins[i:i + 2])
        for j in range(nbins_xy):
            #print(f' bin =({i},{j});  index = {index}')
            sel_y = in_range(kre.Y, *xybins[j:j + 2])
            sel = sel_x & sel_y
            entries = np.count_nonzero(sel)
            if entries < min_entries:
                #print(f'entries ={entries} not enough  to fit bin (i,j) =({i},{j})')
                valid[i, j] = False
                continue

            try:
                z = kre.Z[sel]
                t = kre.E[sel]
                if fit_var == "Q":
                    t = kre.Q[sel]

                x, y, yu = fitf.profileX(z, t, nbins_z, zrange)

                seed = expo_seed(x, y)
                f = fitf.fit(fitf.expo, x, y, seed, sigma=yu)
                re = np.abs(f.errors[1] / f.values[1])
                #print(f' E +- Eu = {f.values[0]} +- {f.errors[0]}')
                #print(f' LT +- LTu = {-f.values[1]} +- {f.errors[1]}')
                #print(f' LTu/LT = {re} chi2 = {f.chi2}')

                const[i, j] = f.values[0]
                constu[i, j] = f.errors[0]
                slope[i, j] = -f.values[1]
                slopeu[i, j] = f.errors[1]
                chi2[i, j] = f.chi2
                valid[i, j] = True

                if re > 0.5:
                    # print(f'Relative error to large, re ={re} for bin (i,j) =({i},{j})')
                    # print(f' LT +- LTu = {-f.values[1]} +- {f.errors[1]}')
                    # print(f' LTu/LT = {re} chi2 = {f.chi2}')
                    valid[i, j] = False

            except:
                print(f'fit failed for bin (i,j) =({i},{j})')
                pass

    return KrLTSlices(Es=Measurement(const, constu),
                      LT=Measurement(slope, slopeu),
                      chi2=chi2,
                      valid=valid)
示例#7
0
def fit_and_plot_slices_2d_expo(
    kre: KrEvent,
    krnb: KrNBins,
    krb: KrBins,
    krr: KrRanges,
    fit_var="E",
    min_entries=1e2,
    figsize=(12, 12)) -> KrLTSlices:
    """
    Slice the data in x and y, make the profile in z of E,
    fit it to a exponential and return the relevant values.

    """

    xybins = krb.XY
    nbins_xy = np.size(xybins) - 1
    nbins_z = krnb.Z
    nbins = nbins_xy, nbins_xy
    const = np.zeros(nbins)
    slope = np.zeros(nbins)
    constu = np.zeros(nbins)
    slopeu = np.zeros(nbins)
    chi2 = np.zeros(nbins)
    valid = np.zeros(nbins, dtype=bool)
    zrange = krr.Z

    fig = plt.figure(figsize=figsize)  # Creates a new figure
    k = 0
    index = 0
    for i in range(nbins_xy):
        sel_x = in_range(kre.X, *xybins[i:i + 2])
        for j in range(nbins_xy):
            index += 1
            #print(f' bin =({i},{j});  index = {index}')
            if k % 25 == 0:
                k = 0
                fig = plt.figure(figsize=figsize)
            ax = fig.add_subplot(5, 5, k + 1)
            k += 1
            sel_y = in_range(kre.Y, *xybins[j:j + 2])
            sel = sel_x & sel_y
            entries = np.count_nonzero(sel)
            if entries < min_entries:
                print(
                    f'entries ={entries} not enough  to fit bin (i,j) =({i},{j})'
                )
                valid[i, j] = False
                continue

            try:
                z = kre.Z[sel]
                t = kre.E[sel]
                if fit_var == "Q":
                    t = kre.Q[sel]

                x, y, yu = fitf.profileX(z, t, nbins_z, zrange)
                ax.errorbar(x, y, yu, np.diff(x)[0] / 2, fmt="kp", ms=7, lw=3)
                seed = expo_seed(x, y)
                f = fitf.fit(fitf.expo, x, y, seed, sigma=yu)
                plt.plot(x, f.fn(x), "r-", lw=4)
                plt.grid(True)
                re = np.abs(f.errors[1] / f.values[1])
                #print(f' E +- Eu = {f.values[0]} +- {f.errors[0]}')
                #print(f' LT +- LTu = {-f.values[1]} +- {f.errors[1]}')
                #print(f' LTu/LT = {re} chi2 = {f.chi2}')

                if re > 0.5:
                    print(
                        f'Relative error to large, re ={re} for bin (i,j) =({i},{j})'
                    )
                    print(f' LT +- LTu = {-f.values[1]} +- {f.errors[1]}')
                    print(f' LTu/LT = {re} chi2 = {f.chi2}')
                    valid[i, j] = False

                const[i, j] = f.values[0]
                constu[i, j] = f.errors[0]
                slope[i, j] = -f.values[1]
                slopeu[i, j] = f.errors[1]
                chi2[i, j] = f.chi2
                valid[i, j] = True
            except:
                print(f'fit failed for bin (i,j) =({i},{j})')
                pass
    plt.tight_layout()

    return KrLTSlices(Ez0=Measurement(const, constu),
                      LT=Measurement(slope, slopeu),
                      chi2=chi2,
                      valid=valid)