Exemplo n.º 1
0
def signalfit(data_hist, signalfunction, signalname, process):

    binning = HistBinsToList(data_hist)
    data_x = HistToList(data_hist)
    data_error = HistErrorList(data_hist)

    parfunction = signalfunction.GetNumberFreeParameters()
    partot = signalfunction.GetNumberFreeParameters()
    print partot

    ### the fucntion used for TMinuit
    def fcn(npar, gin, f, par, ifag):
        L = 0

        # calculate likelihood, input par[0] is the N_B, par[1] is N_C, par[2] is N_L
        for ibin in range(len(binning)):
            #if (data_x[ibin] ==0):
            #    continue

            bincen = binning[ibin]

            mu_x = 0
            data = data_x[ibin]
            if data_error[ibin] == 0:
                continue
            #if data<0.1:
            #    continue

            if signalname == "CrystalBall":

                if par[3] < 0:
                    mu_x = 0

                else:
                    t = (bincen - par[2]) / (par[3])
                    if (par[0] < 0):
                        t = -t

                    absAlpha = abs(par[0])

                    if (t >= -absAlpha):
                        mu_x = par[4] * exp(-0.5 * t * t)

                    else:

                        nDivAlpha = par[1] / absAlpha
                        AA = exp(-0.5 * absAlpha * absAlpha)
                        B = nDivAlpha - absAlpha
                        arg = nDivAlpha / (B - t)

                        mu_x = par[4] * (arg**par[1])

            if signalname == "CrystalBallGaus":

                if par[3] < 0:
                    mu_x = 0

                else:
                    t = (bincen - par[2]) / (par[3])
                    if (par[0] < 0):
                        t = -t

                    absAlpha = abs(par[0])

                    if (t >= -absAlpha):
                        mu_x = par[4] * exp(-0.5 * t * t +
                                            exp(-(bincen - par[5])**2 /
                                                (2 * par[6]**2)))

                    else:

                        nDivAlpha = par[1] / absAlpha
                        AA = exp(-0.5 * absAlpha * absAlpha)
                        B = nDivAlpha - absAlpha
                        arg = nDivAlpha / (B - t)

                        mu_x = par[4] * (arg**par[1] +
                                         exp(-(bincen - par[5])**2 /
                                             (2 * par[6]**2)))

            #print mu_x, data, data_error[ibin]
            #L = L + mu_x - data*log(mu_x)
            L = L + ((mu_x - data) / data_error[ibin])**2

        f[0] = L

    # initialize the TMinuit object
    arglist_p = 10 * [0]

    arglist = array.array('d')
    arglist.fromlist(arglist_p)
    ierflag = Long(0)
    maxiter = 1000000000

    arglist_p = [1]
    gMinuit = TMinuit(partot)
    gMinuit.mnexcm('SET PRIntout', arglist, 0, ierflag)

    gMinuit.SetPrintLevel(1)
    gMinuit.SetErrorDef(1.0)
    gMinuit.SetFCN(fcn)

    arglist_p = [2]
    arglist = array.array('d')
    arglist.fromlist(arglist_p)
    gMinuit.mnexcm('SET STRategy', arglist, 1, ierflag)

    arglist_p = [maxiter, 0.0000001]
    arglist = array.array('d')
    arglist.fromlist(arglist_p)
    gMinuit.mnexcm('MIGrad', arglist, 2, ierflag)
    gMinuit.SetMaxIterations(maxiter)

    # initialize fitting the variables
    vstart = [125.0] * partot

    step = [0.1] * partot
    upper = [1000000] * partot
    lower = [-100] * partot
    varname = []

    lower[3] = 0
    lower[4] = 0
    lower[1] = 0
    vstart[4] = data_hist.Integral()

    if process == "signal":
        vstart[2] = 125
        lower[2] = 110
        upper[2] = 140

        vstart[3] = 10
        lower[3] = 2
        upper[3] = 25

        if len(vstart) > 5:
            vstart[5] = 125
            lower[5] = 110
            upper[5] = 140

            vstart[6] = 10
            lower[6] = 5
            upper[6] = 20

    if process == "z":
        vstart[2] = 90
        lower[2] = 70
        upper[2] = 110

        vstart[3] = 10
        lower[3] = 2
        upper[3] = 30

        if len(vstart) > 5:
            vstart[5] = 90
            lower[5] = 70
            upper[5] = 110

            vstart[6] = 10
            lower[6] = 2
            upper[6] = 30

    for i in range(parfunction):
        varname.append("p" + str(i))

    for i in range(partot):
        gMinuit.mnparm(i, varname[i], vstart[i], step[i], lower[i], upper[i],
                       ierflag)

    # fitting procedure
    migradstat = gMinuit.Command('MIGrad ' + str(maxiter) + ' ' + str(0.001))
    #improvestat = gMinuit.Command('IMProve ' + str(maxiter) + ' ' + str(0.01))

    for i in range(partot):
        arglist_p.append(i + 1)

    arglist = array.array('d')
    arglist.fromlist(arglist_p)

    gMinuit.mnmnos()

    # get fitting parameters
    fitval_p = [Double(0)] * partot
    fiterr_p = [Double(0)] * partot
    errup_p = [Double(0)] * partot
    errdown_p = [Double(0)] * partot
    eparab_p = [Double(0)] * partot
    gcc_p = [Double(0)] * partot

    fmin_p = [Double(0)]
    fedm_p = [Double(0)]
    errdef_p = [Double(0)]
    npari_p = Long(0)
    nparx_p = Long(0)
    istat_p = Long(0)

    fitval = array.array('d')
    fiterr = array.array('d')
    errup = array.array('d')
    errdown = array.array('d')
    eparab = array.array('d')
    gcc = array.array('d')

    for i in range(partot):
        gMinuit.GetParameter(i, fitval_p[i], fiterr_p[i])
        fitval.append(fitval_p[i])
        fiterr.append(fiterr_p[i])
        errup.append(errup_p[i])
        errdown.append(errdown_p[i])
        eparab.append(eparab_p[i])
        gcc.append(gcc_p[i])

    gMinuit.mnstat(fmin_p[0], fedm_p[0], errdef_p[0], npari_p, nparx_p,
                   istat_p)

    for p in range(signalfunction.GetNumberFreeParameters()):
        signalfunction.SetParameter(p, fitval[p])
        print "fit uncert", fiterr_p[p]

    signalfunction.SetChisquare(fmin_p[0])
    print fmin_p[0]
    return fitval[partot - 1], fitval[partot - 2]
Exemplo n.º 2
0
    def fit(self):
        numberOfParameters = len(self.samples)
        gMinuit = TMinuit(numberOfParameters)
        if self.method == 'logLikelihood':  # set function for minimisation
            gMinuit.SetFCN(self.logLikelihood)

        gMinuit.SetMaxIterations(1000000000000)

        # set Minuit print level
        # printlevel  = -1  quiet (also suppress all warnings)
        #            =  0  normal
        #            =  1  verbose
        #            =  2  additional output giving intermediate results.
        #            =  3  maximum output, showing progress of minimizations.
        gMinuit.SetPrintLevel(-1)

        # Error definition: 1 for chi-squared, 0.5 for negative log likelihood
        # SETERRDEF<up>: Sets the value of UP (default value= 1.), defining parameter errors.
        # Minuit defines parameter errors as the change in parameter value required to change the function value by UP.
        # Normally, for chisquared fits UP=1, and for negative log likelihood, UP=0.5.
        gMinuit.SetErrorDef(0.5)

        # error flag for functions passed as reference.set to as 0 is no error
        errorFlag = Long(2)

        N_min = 0
        N_max = self.fit_data_collection.max_n_data() * 2

        param_index = 0

        # MNPARM
        # Implements one parameter definition:
        # mnparm(k, cnamj, uk, wk, a, b, ierflg)
        #     K     (external) parameter number
        #     CNAMK parameter name
        #     UK    starting value
        #     WK    starting step size or uncertainty
        #     A, B  lower and upper physical parameter limits
        # and sets up (updates) the parameter lists.
        # Output: IERFLG  =0 if no problems
        #                >0 if MNPARM unable to implement definition
        for sample in self.samples:  # all samples but data
            if self.n_distributions > 1:
                gMinuit.mnparm(
                    param_index, sample,
                    self.normalisation[self.distributions[0]][sample], 10.0,
                    N_min, N_max, errorFlag)
            else:
                gMinuit.mnparm(param_index, sample, self.normalisation[sample],
                               10.0, N_min, N_max, errorFlag)
            param_index += 1

        arglist = array('d', 10 * [0.])

        # minimisation strategy: 1 standard, 2 try to improve minimum (a bit slower)
        arglist[0] = 2

        # minimisation itself
        # SET STRategy<level>: Sets the strategy to be used in calculating first and second derivatives and in certain minimization methods.
        # In general, low values of <level> mean fewer function calls and high values mean more reliable minimization.
        # Currently allowed values are 0, 1 (default), and 2.
        gMinuit.mnexcm("SET STR", arglist, 1, errorFlag)

        gMinuit.Migrad()
        gMinuit.mnscan(
        )  # class for minimization using a scan method to find the minimum; allows for user interaction: set/change parameters, do minimization, change parameters, re-do minimization etc.

        gMinuit.mnmatu(1)  # prints correlation matrix (always needed)

        self.module = gMinuit
        self.performedFit = True

        if not self.module:
            raise Exception(
                'No fit results available. Please run fit method first')

        results = {}
        param_index = 0
        for sample in self.samples:
            temp_par = Double(0)
            temp_err = Double(0)
            self.module.GetParameter(param_index, temp_par, temp_err)
            if (math.isnan(temp_err)):
                self.logger.warning(
                    'Template fit error is NAN, setting to sqrt(N).')
                temp_err = math.sqrt(temp_par)

#             gMinuit.Command("SCAn %i %i %i %i" % ( param_index, 100, N_min, N_total ) );
#             scan = gMinuit.GetPlot()
#             results[sample] = ( temp_par, temp_err, scan )
            results[sample] = (temp_par, temp_err)
            param_index += 1

# #         gMinuit.Command("CONtour 1 2 3 50")
#         gMinuit.SetErrorDef(1)
#         results['contour'] = [gMinuit.Contour(100, 0, 1)]
#         gMinuit.SetErrorDef(4)
#         results['contour'].append(gMinuit.Contour(100, 0, 1))

        self.results = results
Exemplo n.º 3
0
def bkgfit(data_hist,
           bkgfunction,
           bkgname,
           doFloatZ=False,
           signal_hist=None,
           z_hist=None):
    isBkgPlusZFit = False
    isSpuriousFit = False

    binning = HistBinsToList(data_hist)
    data_x = HistToList(data_hist)
    data_error = HistErrorList(data_hist)

    z_x = []
    signal_x = []

    if z_hist != None:
        isBkgPlusZFit = True
        z_x = HistToList(z_hist)

    if signal_hist != None:
        isSpuriousFit = True
        signal_x = HistToList(signal_hist)

    parfunction = bkgfunction.GetNumberFreeParameters()
    partot = bkgfunction.GetNumberFreeParameters() + 2

    ### the fucntion used for TMinuit
    def fcn(npar, gin, f, par, ifag):
        L = 0

        # calculate likelihood, input par[0] is the N_B, par[1] is N_C, par[2] is N_L
        for ibin in range(len(binning)):
            if (data_x[ibin] < 0.5):
                continue

            bincen = binning[ibin]

            bkg = 0
            data = data_x[ibin]

            if bkgname == "BernsteinO2":
                bkg = (par[0] * (1 - (bincen - fit_start) / fit_range)**2 +
                       2 * par[1] * (1 - (bincen - fit_start) / fit_range) *
                       ((bincen - fit_start) / fit_range) + par[2] *
                       ((bincen - fit_start) / fit_range)**2)

            if bkgname == "BernsteinO3":
                bkg = par[0] * (1 - (
                    (bincen - fit_start) / fit_range))**3 + par[1] * (
                        3 * ((bincen - fit_start) / fit_range) *
                        (1 -
                         ((bincen - fit_start) / fit_range))**2) + par[2] * (
                             3 * ((bincen - fit_start) / fit_range)**2 *
                             (1 -
                              ((bincen - fit_start) / fit_range))) + par[3] * (
                                  (bincen - fit_start) / fit_range)**3

            if bkgname == "BernsteinO4":
                bkg = par[0] * (1 - (
                    (bincen - fit_start) / fit_range))**4 + par[1] * (
                        4 * ((bincen - fit_start) / fit_range) *
                        (1 -
                         ((bincen - fit_start) / fit_range))**3) + par[2] * (
                             6 * ((bincen - fit_start) / fit_range)**2 *
                             (1 - ((bincen - fit_start) / fit_range))**2
                         ) + par[3] * (
                             4 * ((bincen - fit_start) / fit_range)**3 *
                             (1 -
                              ((bincen - fit_start) / fit_range))) + par[4] * (
                                  (bincen - fit_start) / fit_range)**4

            if bkgname == "BernsteinO5":
                bkg = par[0] * (1 - (
                    (bincen - fit_start) / fit_range))**5 + par[1] * (5 * (
                        (bincen - fit_start) / fit_range) * (1 - (
                            (bincen - fit_start) / fit_range))**4) + par[2] * (
                                10 * ((bincen - fit_start) / fit_range)**2 *
                                (1 - ((bincen - fit_start) / fit_range))**3
                            ) + par[3] * (10 * (
                                (bincen - fit_start) / fit_range)**3 * (1 - (
                                    (bincen - fit_start) / fit_range
                                ))**2) + par[4] * (5 * (
                                    (bincen - fit_start) / fit_range)**4 *
                                                   (1 -
                                                    ((bincen - fit_start) /
                                                     fit_range))) + par[5] * (
                                                         (bincen - fit_start) /
                                                         fit_range)**5

            if bkgname == "BernsteinO6":
                bkg = (par[0] * (1 - ((bincen - fit_start) / fit_range))**6 +
                       par[1] * (6 * ((bincen - fit_start) / fit_range)**1 *
                                 (1 - ((bincen - fit_start) / fit_range))**5) +
                       par[2] * (15 * ((bincen - fit_start) / fit_range)**2 *
                                 (1 - ((bincen - fit_start) / fit_range))**4) +
                       par[3] * (20 * ((bincen - fit_start) / fit_range)**3 *
                                 (1 - ((bincen - fit_start) / fit_range))**3) +
                       par[4] * (15 * ((bincen - fit_start) / fit_range)**4 *
                                 (1 - ((bincen - fit_start) / fit_range))**2) +
                       par[5] * (6 * ((bincen - fit_start) / fit_range)**5 *
                                 (1 - ((bincen - fit_start) / fit_range))**1) +
                       par[6] * ((bincen - fit_start) / fit_range)**6)

            if bkgname == "ExpoBernsteinO2":
                try:
                    bkg = exp(par[0] * (bincen - fit_start) / fit_range) * (
                        par[1] *
                        (1 -
                         (bincen - fit_start) / fit_range)**2 + 2 * par[2] *
                        (1 - (bincen - fit_start) / fit_range) *
                        ((bincen - fit_start) / fit_range) + par[3] *
                        ((bincen - fit_start) / fit_range)**2)
                except OverflowError:
                    bkg = 0

            if bkgname == "ExpoBernsteinO3":
                try:
                    bkg = exp(par[0] * (bincen - fit_start) / fit_range) * (
                        par[1] *
                        (1 - ((bincen - fit_start) / fit_range))**3 + par[2] *
                        (3 * ((bincen - fit_start) / fit_range) *
                         (1 -
                          ((bincen - fit_start) / fit_range))**2) + par[3] *
                        (3 * ((bincen - fit_start) / fit_range)**2 *
                         (1 - ((bincen - fit_start) / fit_range))) + par[4] *
                        ((bincen - fit_start) / fit_range)**3)
                except OverflowError:
                    bkg = 0

            if bkgname == "ExpoBernsteinO4":
                try:
                    bkg = exp(par[0] * (bincen - fit_start) / fit_range) * (
                        par[1] *
                        (1 - ((bincen - fit_start) / fit_range))**4 + par[2] *
                        (4 * ((bincen - fit_start) / fit_range) *
                         (1 -
                          ((bincen - fit_start) / fit_range))**3) + par[3] *
                        (6 * ((bincen - fit_start) / fit_range)**2 *
                         (1 -
                          ((bincen - fit_start) / fit_range))**2) + par[4] *
                        (4 * ((bincen - fit_start) / fit_range)**3 *
                         (1 - ((bincen - fit_start) / fit_range))) + par[5] *
                        ((bincen - fit_start) / fit_range)**4)
                except OverflowError:
                    bkg = 0

            if bkgname == "ExpoBernsteinO5":
                try:
                    bkg = exp(par[0] * (bincen - fit_start) / fit_range) * (
                        par[1] *
                        (1 - ((bincen - fit_start) / fit_range))**5 + par[2] *
                        (5 * ((bincen - fit_start) / fit_range) *
                         (1 -
                          ((bincen - fit_start) / fit_range))**4) + par[3] *
                        (10 * ((bincen - fit_start) / fit_range)**2 *
                         (1 -
                          ((bincen - fit_start) / fit_range))**3) + par[4] *
                        (10 * ((bincen - fit_start) / fit_range)**3 *
                         (1 -
                          ((bincen - fit_start) / fit_range))**2) + par[5] *
                        (5 * ((bincen - fit_start) / fit_range)**4 *
                         (1 - ((bincen - fit_start) / fit_range))) + par[6] *
                        ((bincen - fit_start) / fit_range)**5)
                except OverflowError:
                    bkg = 0

            if bkgname == "ExpoPolO2":
                bkg = exp(-(par[0] + par[1] *
                            ((bincen - fit_start) / fit_range) + par[2] *
                            ((bincen - fit_start) / fit_range)**2))

            if bkgname == "ExpoPolO3":
                bkg = exp(-(par[0] + par[1] *
                            ((bincen - fit_start) / fit_range) + par[2] *
                            ((bincen - fit_start) / fit_range)**2 + par[3] *
                            ((bincen - fit_start) / fit_range)**3))

            if bkgname == "ExpoPolO4":
                bkg = exp(-(par[0] + par[1] *
                            ((bincen - fit_start) / fit_range) + par[2] *
                            ((bincen - fit_start) / fit_range)**2 + par[3] *
                            ((bincen - fit_start) / fit_range)**3 + par[4] *
                            ((bincen - fit_start) / fit_range)**4))

            mu_x = bkg

            #if isBkgPlusZFit:
            #    mu_x = mu_x + (par[partot-1] *z_x[ibin])

            if isSpuriousFit:
                mu_x = mu_x + par[partot - 2] * signal_x[ibin]

            #L = L + mu_x - data*log(mu_x)

            L = L + ((mu_x - data) / data_error[ibin])**2

        f[0] = L

    # initialize the TMinuit object
    arglist_p = 10 * [0]

    arglist = array.array('d')
    arglist.fromlist(arglist_p)
    ierflag = Long(0)
    maxiter = 1000000000

    arglist_p = [1]
    gMinuit = TMinuit(partot)
    gMinuit.mnexcm('SET PRIntout', arglist, 0, ierflag)

    gMinuit.SetPrintLevel(1)
    gMinuit.SetErrorDef(1.0)
    gMinuit.SetFCN(fcn)

    arglist_p = [2]
    arglist = array.array('d')
    arglist.fromlist(arglist_p)
    gMinuit.mnexcm('SET STRategy', arglist, 1, ierflag)

    arglist_p = [maxiter, 0.0000001]
    arglist = array.array('d')
    arglist.fromlist(arglist_p)
    gMinuit.mnexcm('MIGrad', arglist, 2, ierflag)
    gMinuit.SetMaxIterations(maxiter)

    # initialize fitting the variables
    vstart = [100.0] * partot
    # start alpha_z with 1
    vstart[partot - 1] = 1.0
    vstart[partot - 2] = 0

    step = [0.1] * partot
    upper = [100000] * partot
    lower = [0.1] * partot
    varname = []

    if "ExpoPol" in bkgname:
        upper = [1000] * partot
        lower = [-1000] * partot

    if "ExpoBernstein" in bkgname:
        vstart[0] = -1
        upper[0] = 0
        lower[0] = -10

    for i in range(parfunction):
        varname.append("p" + str(i))

    varname.append("alpha_sig")
    varname.append("alpha_z")

    if doFloatZ:
        vstart[partot - 1] = 1.0
        upper[partot - 1] = 2
        lower[partot - 1] = 0
        step[partot - 1] = 0.01

    if isSpuriousFit:
        upper[partot - 2] = 10.0
        lower[partot - 2] = -10.0
        step[partot - 2] = 0.1
        vstart[partot - 2] = 1

    for i in range(partot):
        gMinuit.mnparm(i, varname[i], vstart[i], step[i], lower[i], upper[i],
                       ierflag)

    if not isSpuriousFit:
        vstart[partot - 2] = 0
        gMinuit.FixParameter(partot - 2)

    if not doFloatZ:
        lower[partot - 1] = 1
        upper[partot - 1] = 1
        gMinuit.FixParameter(partot - 1)

    if not isBkgPlusZFit:
        vstart[partot - 1] = 0.0
        gMinuit.FixParameter(partot - 1)

    # fitting procedure
    migradstat = gMinuit.Command('MIGrad ' + str(maxiter) + ' ' + str(0.001))
    improvestat = gMinuit.Command('IMProve ' + str(maxiter) + ' ' + str(0.01))

    for i in range(partot):
        arglist_p.append(i + 1)

    arglist = array.array('d')
    arglist.fromlist(arglist_p)

    #gMinuit.mnmnos()

    # get fitting parameters
    fitval_p = [Double(0)] * partot
    fiterr_p = [Double(0)] * partot
    errup_p = [Double(0)] * partot
    errdown_p = [Double(0)] * partot
    eparab_p = [Double(0)] * partot
    gcc_p = [Double(0)] * partot

    fmin_p = [Double(0)]
    fedm_p = [Double(0)]
    errdef_p = [Double(0)]
    npari_p = Long(0)
    nparx_p = Long(0)
    istat_p = Long(0)

    fitval = array.array('d')
    fiterr = array.array('d')
    errup = array.array('d')
    errdown = array.array('d')
    eparab = array.array('d')
    gcc = array.array('d')

    for i in range(partot):
        gMinuit.GetParameter(i, fitval_p[i], fiterr_p[i])
        fitval.append(fitval_p[i])
        fiterr.append(fiterr_p[i])
        errup.append(errup_p[i])
        errdown.append(errdown_p[i])
        eparab.append(eparab_p[i])
        gcc.append(gcc_p[i])

    gMinuit.mnstat(fmin_p[0], fedm_p[0], errdef_p[0], npari_p, nparx_p,
                   istat_p)

    for p in range(bkgfunction.GetNumberFreeParameters()):
        bkgfunction.SetParameter(p, fitval[p])
        print "fit uncert", fiterr_p[p]

    bkgfunction.SetChisquare(fmin_p[0])

    return fitval[partot - 1], fitval[partot - 2]