示例#1
0
def fit_gaussian_experiments_variable_mean_and_std(
        means: np.array,
        stds: np.array,
        exps: np.array,
        bins: int = 50,
        n_sigma: int = 3) -> Iterable[List[float]]:
    l = len(stds)
    SEED = []
    MU = []
    STD = []
    AVG = []
    RMS = []
    CHI2 = []
    for i, mean in enumerate(means):
        for j, std in enumerate(stds):
            k = i * l + j
            e = exps[k]
            r = mean - n_sigma * std, mean + n_sigma * std
            bin_size = (r[1] - r[0]) / bins
            gp = gaussian_parameters(e, range=r, bin_size=bin_size)
            fc = fit_energy(e, nbins=bins, range=r, n_sigma=n_sigma)
            SEED.append(Measurement(mean, std))
            MU.append(Measurement(fc.fr.par[1], fc.fr.err[1]))
            STD.append(Measurement(fc.fr.par[2], fc.fr.err[2]))
            AVG.append(gp.mu)
            RMS.append(gp.std)
            CHI2.append(fc.fr.chi2)

    return SEED, MU, STD, AVG, RMS, CHI2
示例#2
0
def fit_lifetimes_from_profile(kre: KrEvent,
                               kR: KrRanges,
                               kNB: KrNBins,
                               kB: KrBins,
                               kL: KrRanges,
                               min_entries=1e2):

    nbins = kNB.XY, kNB.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 = kL.Z

    #print(zrange)
    #print(kNB.Z)

    for i in range(kNB.XY):
        #print(f' i = {i}')
        xr = kB.XY[i:i + 2]
        #print(f'range x = {xr}')

        sel_x = in_range(kre.X, *kB.XY[i:i + 2])
        xxx = np.count_nonzero([x for x in sel_x if x == True])
        #print(xxx)
        for j in range(kNB.XY):
            #print(f' j = {j}')
            yr = kB.XY[j:j + 2]
            #print(f'range y = {yr}')

            sel_y = in_range(kre.Y, *kB.XY[j:j + 2])
            xxx = np.count_nonzero([x for x in sel_y if x == True])
            #print(xxx)

            sel = sel_x & sel_y
            mine = np.count_nonzero(sel)
            #print(f'min entries = {mine}')
            if mine < min_entries: continue
            #print('trying to fit')
            try:
                f = fit_profile_1d_expo(kre.Z[sel],
                                        kre.E[sel],
                                        kNB.Z,
                                        xrange=zrange)
                #print(f' f = {f}')
                const[i, j] = f.values[0]
                constu[i, j] = f.errors[0]
                slope[i, j] = abs(f.values[1])
                slopeu[i, j] = f.errors[1]
                chi2[i, j] = f.chi2
                valid[i, j] = True
            except:
                print('error')
                pass

    return Measurement(const, constu), Measurement(slope, slopeu), chi2, valid
示例#3
0
def s1_means_and_vars(dst):

    hr = divide_np_arrays(dst.S1h.values, dst.S1e.values)
    return S1D(
        E=Measurement(
            *weighted_mean_and_std(dst.S1e.values, np.ones(len(dst)))),
        W=Measurement(*weighted_mean_and_std(dst.S1w, np.ones(len(dst)))),
        H=Measurement(*weighted_mean_and_std(dst.S1h, np.ones(len(dst)))),
        R=Measurement(*weighted_mean_and_std(hr, np.ones(len(dst)))),
        T=Measurement(*weighted_mean_and_std(dst.S1t, np.ones(len(dst)))))
示例#4
0
def s1d_from_dst(
    dst: DataFrame,
    range_s1e: Tuple[float, float] = (0, 40),
    range_s1w: Tuple[float, float] = (0, 500),
    range_s1h: Tuple[float, float] = (0, 10),
    range_s1t: Tuple[float, float] = (0, 600)
) -> S1D:

    hr = divide_np_arrays(dst.S1h.values, dst.S1e.values)
    return S1D(E=Measurement(*mean_and_std(dst.S1e.values, range_s1e)),
               W=Measurement(*mean_and_std(dst.S1w.values, range_s1w)),
               H=Measurement(*mean_and_std(dst.S1h.values, range_s1h)),
               R=Measurement(*mean_and_std(hr, (0, 1))),
               T=Measurement(*mean_and_std(dst.S1t.values, range_s1t)))
示例#5
0
def fit_slices_1d_gauss(xdata, ydata, xbins, ybins, min_entries=1e2):
    """
    Slice the data in x, histogram each slice, fit it to a gaussian
    and return the relevant values.

    Parameters
    ----------
    xdata, ydata: array_likes
        Values of each coordinate.
    xbins: array_like
        The bins in the x coordinate.
    ybins: array_like
        The bins in the y coordinate for histograming the data.
    min_entries: int (optional)
        Minimum amount of entries to perform the fit.

    Returns
    -------
    mean: Measurement(np.ndarray, np.ndarray)
        Values of mean with errors.
    sigma: Measurement(np.ndarray, np.ndarray)
        Values of sigma with errors.
    chi2: np.ndarray
        Chi2 from each fit.
    valid: boolean np.ndarray
        Where the fit has been succesfull.
    """
    nbins = np.size(xbins) - 1
    mean = np.zeros(nbins)
    sigma = np.zeros(nbins)
    meanu = np.zeros(nbins)
    sigmau = np.zeros(nbins)
    chi2 = np.zeros(nbins)
    valid = np.zeros(nbins, dtype=bool)

    for i in range(nbins):
        sel = in_range(xdata, *xbins[i:i + 2])
        if np.count_nonzero(sel) < min_entries: continue

        try:
            f = quick_gauss_fit(ydata[sel], ybins)
            mean[i] = f.values[1]
            meanu[i] = f.errors[1]
            sigma[i] = f.values[2]
            sigmau[i] = f.errors[2]
            chi2[i] = f.chi2
            valid[i] = True
        except:
            pass
    return Measurement(mean, meanu), Measurement(sigma, sigmau), chi2, valid
示例#6
0
def s2d_from_dst(dst: DataFrame) -> S2D:
    return S2D(E=Measurement(*mean_and_std(dst.S2e.values, (0, 20000))),
               W=Measurement(*mean_and_std(dst.S2w.values, (0, 30))),
               Q=Measurement(*mean_and_std(dst.S2q.values, (0, 1000))),
               N=Measurement(*mean_and_std(dst.Nsipm.values, (0, 40))),
               X=Measurement(*mean_and_std(dst.X.values, (-200, 200))),
               Y=Measurement(*mean_and_std(dst.Y.values, (-200, 200))))
示例#7
0
def gaussian_parameters(x : np.array, range : Tuple[Number], bin_size : float = 1)->GaussPar:
    """
    Return the parameters defining a Gaussian
    g = N * exp(x - mu)**2 / (2 * std**2)
    where N is the normalization: N = 1 / (sqrt(2 * np.pi) * std)
    The parameters returned are the mean (mu), standard deviation (std)
    and the amplitude (inverse of N).
    """
    mu, std = mean_and_std(x, range)
    ff     = np.sqrt(2 * np.pi) * std

    amp     = len(x) * bin_size / ff

    sel  = in_range(x, *range)
    N = len(x[sel])              # number of samples in range
    mu_u  = std / np.sqrt(N)
    std_u = std / np.sqrt(2 * (N -1))
    amp_u = np.sqrt(2 * np.pi) * std_u

    return GaussPar(mu  = Measurement(mu, mu_u),
                    std = Measurement(std, std_u),
                    amp = Measurement(amp, amp_u))
示例#8
0
def s2_means_and_vars(dst):

    return S2D(
        E=Measurement(
            *weighted_mean_and_std(dst.S2e.values, np.ones(len(dst)))),
        W=Measurement(*weighted_mean_and_std(dst.S2w, np.ones(len(dst)))),
        Q=Measurement(*weighted_mean_and_std(dst.S2q, np.ones(len(dst)))),
        N=Measurement(*weighted_mean_and_std(dst.Nsipm, np.ones(len(dst)))),
        X=Measurement(*weighted_mean_and_std(dst.X, np.ones(len(dst)))),
        Y=Measurement(*weighted_mean_and_std(dst.Y, np.ones(len(dst)))))
示例#9
0
def h1n(n,
        nx,
        ny,
        names,
        h1ds,
        bins,
        ranges,
        xlabels,
        ylabels,
        titles=None,
        legends=None,
        figsize=(10, 10)):

    fig = plt.figure(figsize=figsize)
    stats = {}
    for i in range(n):
        ax = fig.add_subplot(nx, ny, i + 1)
        x = h1ds[i]
        r = ranges[i]

        x1 = loc_elem_1d(x, find_nearest(x, r[0]))
        x2 = loc_elem_1d(x, find_nearest(x, r[1]))
        xmin = min(x1, x2)
        xmax = max(x1, x2)
        x2 = x[xmin:xmax]
        o = np.ones(len(x2))
        mu, std = weighted_mean_and_std(x2, o)
        stats[names[i]] = Measurement(mu, std)

        ax.set_xlabel(xlabels[i], fontsize=11)
        ax.set_ylabel(ylabels[i], fontsize=11)
        ax.hist(x,
                bins=bins[i],
                range=r,
                histtype='step',
                edgecolor='black',
                linewidth=1.5,
                label=r'$\mu={:7.2f},\ \sigma={:7.2f}$'.format(mu, std))
        ax.legend(fontsize=10, loc=legends[i])
        plt.grid(True)
        if titles:
            plt.title(titles[i])

    plt.tight_layout()
    return stats
示例#10
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)
示例#11
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)
示例#12
0
def fit_slices_2d_expo(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.

    """

    xbins = krb.XY
    ybins = krb.XY
    nbins_x = np.size(xbins) - 1
    nbins_y = np.size(ybins) - 1
    nbins_z = krnb.Z
    nbins = nbins_x, nbins_y
    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_x):
        sel_x = in_range(kre.X, *xbins[i:i + 2])
        for j in range(nbins_y):
            sel_y = in_range(kre.Y, *ybins[j:j + 2])
            sel = sel_x & sel_y
            if np.count_nonzero(sel) < 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]

                f = fit_profile_1d_expo(z, t, nbins_z, xrange=zrange)
                re = np.abs(f.errors[1] / f.values[1])

                if re > 0.5:
                    print(
                        f'Relative error to large, re ={re} for bin (i,j) =({i},{j})'
                    )
                    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:
                pass
    return KrLTSlices(Ez0=Measurement(const, constu),
                      LT=Measurement(slope, slopeu),
                      chi2=chi2,
                      valid=valid)
示例#13
0
def histo_fit_fb_pars(
    fp: FitParTS,
    fpf: Optional[FitParTS] = None,
    fpb: Optional[FitParTS] = None,
    range_chi2: Tuple[float, float] = (0, 3),
    range_e0: Tuple[float, float] = (10000, 12500),
    range_lt: Tuple[float, float] = (2000, 3000)
) -> FitParFB:

    fig = plt.figure(figsize=(14, 6))

    ax = fig.add_subplot(1, 3, 1)
    _, _, c2_mu, c2_std = h1(fp.c2,
                             bins=20,
                             range=range_chi2,
                             color='black',
                             stats=True)
    plot_histo(PlotLabels('chi2', 'Entries', ''), ax)
    if fpf:
        _, _, c2f_mu, c2f_std = h1(fpf.c2,
                                   bins=20,
                                   range=range_chi2,
                                   color='red',
                                   stats=True)
        plot_histo(PlotLabels('chi2', 'Entries', ''), ax)
    if fpb:
        _, _, c2b_mu, c2b_std = h1(fpb.c2,
                                   bins=20,
                                   range=range_chi2,
                                   color='blue',
                                   stats=True)
        plot_histo(PlotLabels('chi2', 'Entries', ''), ax)

    ax = fig.add_subplot(1, 3, 2)
    _, _, e0_mu, e0_std = h1(fp.e0,
                             bins=20,
                             range=range_e0,
                             color='black',
                             stats=True)
    plot_histo(PlotLabels('E0', 'Entries', ''), ax)
    if fpf:
        _, _, e0f_mu, e0f_std = h1(fpf.e0,
                                   bins=20,
                                   range=range_e0,
                                   color='red',
                                   stats=True)
        plot_histo(PlotLabels('E0', 'Entries', ''), ax)
    if fpb:
        _, _, e0b_mu, e0b_std = h1(fpb.e0,
                                   bins=20,
                                   range=range_e0,
                                   color='blue',
                                   stats=True)
        plot_histo(PlotLabels('E0', 'Entries', ''), ax)

    ax = fig.add_subplot(1, 3, 3)
    _, _, lt_mu, lt_std = h1(fp.lt,
                             bins=20,
                             range=range_lt,
                             color='black',
                             stats=True)
    plot_histo(PlotLabels('LT', 'Entries', ''), ax)
    if fpf:
        _, _, ltf_mu, ltf_std = h1(fpf.lt,
                                   bins=20,
                                   range=range_lt,
                                   color='red',
                                   stats=True)
        plot_histo(PlotLabels('LT', 'Entries', ''), ax)
    if fpb:
        _, _, ltb_mu, ltb_std = h1(fpb.lt,
                                   bins=20,
                                   range=range_lt,
                                   color='blue',
                                   stats=True)
        plot_histo(PlotLabels('LT', 'Entries', ''), ax)

    plt.tight_layout()

    return FitParFB(Measurement(c2_mu, c2_std), Measurement(c2f_mu, c2f_std),
                    Measurement(c2b_mu, c2b_std), Measurement(e0_mu, e0_std),
                    Measurement(e0f_mu, e0f_std), Measurement(e0b_mu, e0b_std),
                    Measurement(lt_mu, lt_std), Measurement(ltf_mu, ltf_std),
                    Measurement(ltb_mu, ltb_std))