Exemple #1
0
def main_singleCategory(options, args):

    if options.category in [19, 23]:  # ggH_0J_Cen is 0
        print 'Error! This category has been merged away.'
        return

    cans = []

    options.outdir = ''

    if options.analysis == 'couplings2017':
        category_name = Tools.categories_couplings2017[options.category]
        category_title = Tools.CategoryNames_couplings2017[category_name]
        fcns['selected'] = [Tools.selected_couplings2017[category_name]]
        fcns['ftest'] = ChiSquareTools.ftest[category_name]
        background_label = '#gamma#gamma'
        lumi = 36.1
    elif options.analysis == 'ysy':
        category_name = Tools.categories_ysy[options.category]
        category_title = Tools.CategoryNames_ysy[category_name]
        fcns['selected'] = [Tools.selected_ysy[category_name]]
        fcns['ftest'] = ChiSquareTools.ftest[category_name]
        background_label = 'll#gamma'
        lumi = 139
    else:
        print('Error - do not understand analysis name %s' %
              (options.analysis))
        import sys
        sys.exit()

    family_name = {
        'official': 'official_functions',
        'selected': 'selected_function',
    }.get(options.family, options.family + '_family')

    # A list of options is provided
    if options.functions:
        flist = options.functions.split(',')
        options.outdir += '_'.join(flist)

    # Otherwise a family must be provided:
    else:
        flist = fcns.get(options.family)
        options.outdir += family_name

    options.outdir += '_c%02d_%s' % (options.category, category_name)

    functions = []
    FunctionsModule.PopulateFunctionList(functions, flist, options.lower,
                                         options.upper)
    ChiSquareTools.LinkFunctionsForFtest(functions)
    if len(functions) == 0:
        print 'Error! no functions loaded!'
        import sys
        sys.exit()

    for f in functions:
        f.SetAnalysis(options.analysis)
        f.SetCategory(options.category)
        f.SetFileName(options.file)
        f.Initialize()

    #  rebin = 5
    # if options.category > 16 :
    #     rebin = 1
    # if options.category > 23 : # ttH categories
    #     rebin = 10

    # Rebin to get 1 bin per GeV
    rebin = int(functions[0].datahist.GetNbinsX() / 55)

    print 'Proceeding with Data histogram:', functions[0].datahist
    functions[0].datahist.Rebin(rebin)
    for i, f in enumerate(functions):
        if i:
            f.datahist.Rebin(rebin)
        f.datasb_rebinned = ROOT.RooDataHist('data_real_rebinned', '',
                                             ROOT.RooArgList(f.obsVar),
                                             f.datahist, 1.)

    if not os.path.exists(options.outdir):
        os.makedirs(options.outdir)

    ftest_text = ''

    cans.append(
        plotfunc.RatioCanvas(
            "Ftests_%02d_%s" % (options.category, category_name), "main plot",
            600, 500))
    functions[0].datahist.SetBinErrorOption(ROOT.TH1.kPoisson)
    plotfunc.AddHistogram(cans[-1], functions[0].datahist)
    ##
    ## Ftests to sideband
    ##
    for f in functions:
        if not hasattr(f, 'ftest_function'):
            continue

        nbins_blind = int(f.datasb_rebinned.numEntries() - 10)
        print 'Sideband numEntries:', f.datasb_rebinned.numEntries(
        ), 'nbins:', nbins_blind
        # ndof_bins = nbins_blind-f.ndof-1
        # ndof_bins_2 = nbins_blind-f.ftest_function.ndof-1
        ndof_bins = nbins_blind - f.ndof
        ndof_bins_2 = nbins_blind - f.ftest_function.ndof

        #
        # Fitting data sidebands - first function
        #
        print 'Fitting data sidebands'
        print f.PrintParameters()
        ChiSquareTools.FitForChi2_DataSidebands(f)
        print f.PrintParameters()
        print 'Fitting data sidebands done'
        ftest_text += f.PrintParameters() + '\n'
        chi2 = ROOT.GetChiSquare(f.obsVar, f.function_ext, f.datasb_rebinned,
                                 ndof_bins)
        pvalue_chi2 = ROOT.TMath.Prob(chi2 * (ndof_bins), ndof_bins)

        #
        # Plotting stuff - first function
        #
        Tools.ClearRooPlot(f.frame)
        ChiSquareTools.NormalizeToSideband(f)
        f.datasb_rebinned.plotOn(
            f.frame, ROOT.RooFit.DataError(ROOT.RooAbsData.Poisson))
        print 'about to plot'
        #f.workspace.var('a1').setVal(-1.6)
        print f.PrintParameters()
        f.function_ext.plotOn(f.frame, *(Tools.plotOptions_sb_all))
        print f.PrintParameters()
        print 'about to plot done'
        curve = f.frame.getCurve()
        curve.SetMarkerSize(0)
        curve.SetLineWidth(2)
        curve.SetTitle('%s, p(#chi^{2}) = %2.1f%%' %
                       (f.name, pvalue_chi2 * 100.))
        curve.SetLineColor(ROOT.kRed + 1)
        curve.SetFillColor(0)
        pull = f.frame.pullHist()
        pull.SetMarkerSize(0.7)
        pull.SetLineColor(ROOT.kRed + 1)
        pull.SetMarkerColor(ROOT.kRed + 1)
        plotfunc.AddRatioManual(cans[-1],
                                curve,
                                pull,
                                drawopt1='l',
                                drawopt2='p')

        #
        # Fitting data sidebands - first function
        #
        print 'Fitting data sidebands (other function)'
        print f.ftest_function.PrintParameters()
        ChiSquareTools.FitForChi2_DataSidebands(f.ftest_function)
        print f.ftest_function.PrintParameters()
        print 'Fitting data sidebands (other function) done'
        ftest_text += f.ftest_function.PrintParameters() + '\n'
        chi2_2 = ROOT.GetChiSquare(f.obsVar, f.ftest_function.function_ext,
                                   f.datasb_rebinned, ndof_bins_2)
        pvalue_chi2_2 = ROOT.TMath.Prob(chi2_2 * (ndof_bins_2), ndof_bins_2)

        #
        # Plotting stuff - other function
        #
        Tools.ClearRooPlot(f.frame)
        ChiSquareTools.NormalizeToSideband(f.ftest_function)
        f.datasb_rebinned.plotOn(f.frame)
        f.ftest_function.function_ext.plotOn(f.frame,
                                             *(Tools.plotOptions_sb_all))
        curve = f.frame.getCurve()
        curve.SetMarkerSize(0)
        curve.SetLineWidth(2)
        curve.SetTitle('%s, p(#chi^{2}) = %2.1f%%' %
                       (f.ftest_function.name, pvalue_chi2_2 * 100.))
        curve.SetLineColor(ROOT.kAzure - 2)
        curve.SetFillColor(0)
        pull = f.frame.pullHist()
        pull.SetMarkerSize(0.7)
        pull.SetLineColor(ROOT.kAzure - 2)
        pull.SetMarkerColor(ROOT.kAzure - 2)
        plotfunc.AddRatioManual(cans[-1],
                                curve,
                                pull,
                                drawopt1='l',
                                drawopt2='p')

        ftest = ChiSquareTools.GetF(chi2, chi2_2, ndof_bins, ndof_bins_2)

        ftest_text += 'chi2/ndf: %2.5f\n' % (chi2)
        ftest_text += 'chi2_2/ndf: %2.5f\n' % (chi2_2)
        ftest_text += 'chi2: %2.5f\n' % (chi2 * ndof_bins)
        ftest_text += 'chi2_2: %2.5f\n' % (chi2_2 * ndof_bins_2)
        ftest_text += 'ftest: %2.5f\n' % (ftest)
        #p_ftest = 1.0 - ROOT.TMath.FDistI(ftest,1,ndof_bins_2)
        p_ftest = 1.0 - ROOT.TMath.FDistI(ftest, ndof_bins - ndof_bins_2,
                                          ndof_bins_2)
        ftest_text += 'p_ftest: %2.5f\n' % (p_ftest)

        #
        # Throw Toys
        #
        print 'Running toy Ftests'
        fisher_dist = ChiSquareTools.ToyFtest(f, f.ftest_function, ftest,
                                              options.outdir, options.ntoys)
        print 'Running toy Ftests done'

        if fisher_dist.Integral(0, 100000):
            ftest_text += 'p_ftest_toys: %2.5f\n' % (
                fisher_dist.Integral(fisher_dist.FindBin(ftest), 100000) /
                float(fisher_dist.Integral(0, 100000)))


#         chi2_lowerSideBand = ROOT.RooChi2Var("chi2_low","chi2_low",f.function_ext,f.data_realdata,ROOT.RooFit.DataError(ROOT.RooAbsData.Poisson),ROOT.RooFit.Range("lower"));
#         chi2_upperSideBand = ROOT.RooChi2Var("chi2_upp","chi2_upp",f.function_ext,f.data_realdata,ROOT.RooFit.DataError(ROOT.RooAbsData.Poisson),ROOT.RooFit.Range("upper"));
# chi2_all           = ROOT.RooChi2Var("chi2_all","chi2_all",f.function_ext,f.data_realdata,ROOT.RooFit.Range("lower,upper"));
# chi2_lowerSideBand = ROOT.RooChi2Var("chi2_low","chi2_low",f.function_ext,f.data_realdata,ROOT.RooFit.Range("lower"));
# chi2_upperSideBand = ROOT.RooChi2Var("chi2_upp","chi2_upp",f.function_ext,f.data_realdata,ROOT.RooFit.Range("upper"));
# print 'chi2_all          .getValV()',chi2_all.getValV()
# print 'chi2_lowerSideBand.getValV()',chi2_lowerSideBand.getValV()
# print 'chi2_upperSideBand.getValV()',chi2_upperSideBand.getValV()
# print 'total:',(chi2_lowerSideBand.getValV()+chi2_upperSideBand.getValV()) / float(f.bins-1-f.ndof)

# Get the chi2 from the background-only fit
# print 'f.frame.chiSquare(1+f.ndof-10)',f.frame.chiSquare(1+f.ndof)*(f.bins-1-f.ndof)
# f.chisquare_sb = f.frame.chiSquare(1+f.ndof-10) # n-1 bins MINUS 10 BINS
# f.pvalue_chi2_sb = ROOT.TMath.Prob(f.chisquare_sb*(f.bins-1-f.ndof-10),f.bins-1-f.ndof-10)
# print 'chisquare:',f.chisquare_sb,f.pvalue_chi2_sb

        continue

        curve = f.frame.getCurve()
        curve.SetMarkerSize(0)
        curve.SetLineWidth(1)
        curve.SetTitle(f.name)
        curve.SetLineWidth(2)
        #         resid = f.frame.residHist(); resid.SetMarkerSize(0)
        #         plotfunc.AddRatioManual(cans[-1],curve,resid,drawopt1='l',drawopt2='l')
        pull = f.frame.pullHist()
        pull.SetMarkerSize(0.7)

        # for special
        if options.family == 'selected':
            color = {
                'Pow': ROOT.kBlack + 0,
                'Exponential': ROOT.kRed + 1,
                'ExpPoly2': ROOT.kBlue + 1,
                'Bern3': ROOT.kGreen + 1,
                'Bern4': ROOT.kMagenta + 1,
                'Bern5': ROOT.kOrange + 1,
            }.get(f.name)
            pull.SetMarkerColor(color)
            pull.SetLineColor(color)
            curve.SetLineColor(color)
            curve.SetFillColor(0)

        plotfunc.AddRatioManual(cans[-1],
                                curve,
                                pull,
                                drawopt1='l',
                                drawopt2='p')

    plotfunc.SetAxisLabels(cans[-1], 'm_{#gamma#gamma} [GeV]', 'entries',
                           'pull')
    the_text = [
        plotfunc.GetAtlasInternalText(),
        plotfunc.GetSqrtsText(13) + ', ' + plotfunc.GetLuminosityText(36.1),
        category_title,
        '1-p(F_{%d%d}) = %2.1f%%' %
        (functions[0].ndof, functions[0].ftest_function.ndof, p_ftest * 100)
    ]
    plotfunc.DrawText(cans[-1],
                      the_text,
                      0.19,
                      0.63,
                      0.59,
                      0.91,
                      totalentries=4)
    plotfunc.MakeLegend(cans[-1], 0.57, 0.63, 0.90, 0.91, totalentries=4)
    plotfunc.SetYaxisRanges(plotfunc.GetBotPad(cans[-1]), -4, 4)
    plotfunc.SetXaxisRanges(cans[-1], functions[0].lower_range,
                            functions[0].upper_range)
    taxisfunc.AutoFixYaxis(plotfunc.GetTopPad(cans[-1]), forcemin=0.001)

    print ftest_text
    a = open('%s/ftests.txt' % (options.outdir), 'w')
    a.write(options.file + '\n')
    a.write(ftest_text + '\n')
    a.close()

    for can in cans:
        plotfunc.FormatCanvasAxes(can)

    anaplot.UpdateCanvases(cans, options)
    if not options.batch:
        raw_input('Press enter to exit')
    anaplot.doSaving(options, cans)

    return
Exemple #2
0
def main_singleCategory(options, args):

    if options.category in [30, 31]:
        print 'Error! Too few AF2 stats. Not going to do it.'
        return

    cans = []

    options.outdir = ''

    if options.functions:
        flist = options.functions.split(',')
        options.outdir += '_'.join(flist)

    elif options.family == 'official':
        #flist = ['Exponential','ExpPoly2','ExpPoly3','Bern4','Bern5','Pow','Pow2','Laurent0','Laurent1','Laurent2']
        flist = [
            'Exponential', 'ExpPoly2', 'Bern4', 'Bern5', 'Pow', 'Pow2',
            'Laurent1', 'Laurent2'
        ]
        options.outdir += 'official_functions'

    elif options.family == 'selected':
        flist = [Tools.selected[Tools.categories[options.category]]]
        options.outdir += 'selected_functions'
        print flist

    elif options.family == 'ExpPoly':
        flist = ['Exponential'] + list('ExpPoly%d' % (d) for d in range(2, 4))
        options.outdir += 'exppoly_family'

    elif options.family == 'Laurent':
        flist = list('Laurent%d' % (d) for d in range(0, 3))
        options.outdir += 'Laurent_family'

    elif options.family == 'PolyOverX4':
        flist = ['1/x^4'] + list('poly%d/x^4' % (d) for d in range(1, 6))
        options.outdir += 'PolyOverX4_family'

    elif options.family == 'Bernstein':
        flist = list('Bern%d' % (d) for d in range(4, 6))
        options.outdir += 'Bern_family'

    elif options.family == 'PowerSum':
        flist = ['Pow', 'Pow2']
        options.outdir += 'PowerSum_family'

    else:
        flist = [
            'Exponential',  # bad
            'ExpPoly2',
            'ExpPoly3',
        ]
        options.outdir += '_'.join(flist)

    options.outdir += '_c%02d_%s' % (options.category,
                                     Tools.categories[options.category])

    functions = []
    Tools.PopulateFunctionList(functions, flist)
    Tools.LinkFunctionsForFtest(functions)
    if len(functions) == 0:
        print 'Error! no functions loaded!'
        import sys
        sys.exit()

    for f in functions:
        f.SetCategory(options.category)
        f.SetFileName(options.file)
        f.SetSignalWS(options.signalws)
        f.Initialize()

    ##
    ## Plot the data and af2 (fit bkg-only just before this.) SpuriousSignal_05_M17_ggH_1J_BSM
    ##
    for f in functions:
        f.function.fitTo(f.data, *(Tools.args_bkgonly))
    cans.append(
        plotfunc.RatioCanvas(
            "TemplateFit_%02d_%s" %
            (options.category, Tools.categories[options.category]),
            "main plot", 600, 500))
    functions[0].af2hist.SetMarkerSize(0)
    #rebin = Tools.RebinUntilSmallErrors(functions[0].af2hist,0,Tools.lower_range,Tools.upper_range,errormax=0.3)
    rebin = 5
    functions[0].af2hist.Rebin(rebin)
    binwidth = functions[0].af2hist.GetBinWidth(1)
    bins = int((Tools.upper_range - Tools.lower_range) / float(binwidth))
    functions[0].af2hist.SetTitle('#gamma#gamma MC')
    functions[0].af2hist.SetLineWidth(2)
    if options.family == 'selected':
        functions[0].af2hist.SetLineColor(ROOT.kGray + 2)
        functions[0].af2hist.SetFillColor(0)
    plotfunc.AddHistogram(cans[-1], functions[0].af2hist, drawopt='')
    for i, f in enumerate(functions):
        f.obsVar.setBins(int(bins))
        f.bins = bins
        f.frame = f.obsVar.frame()
        if i:
            f.af2hist.Rebin(rebin)
        f.af2_rebinned = ROOT.RooDataHist('af2_rebinned', '',
                                          ROOT.RooArgList(f.obsVar), f.af2hist,
                                          1.)
        #f.af2_rebinned.plotOn(f.frame,ROOT.RooFit.Range("lower,upper"))
        #f.function.plotOn(f.frame,ROOT.RooFit.NormRange("lower,upper"),ROOT.RooFit.Range("all"))
        f.chisquare = Tools.GetChiSquare_ForSpuriousSignal(
            f.frame, f.af2_rebinned, f.function, f.ndof)
        f.pvalue_chi2 = ROOT.TMath.Prob(f.chisquare * (f.bins - 1 - f.ndof),
                                        f.bins - 1 - f.ndof)
        print 'Original chi2: %2.6f p-value: %2.6f' % (f.chisquare,
                                                       f.pvalue_chi2)
        f.minNll = 0
        curve = f.frame.getCurve()
        curve.SetMarkerSize(0)
        curve.SetLineWidth(1)
        curve.SetTitle(f.name)
        curve.SetLineWidth(2)
        #         resid = f.frame.residHist(); resid.SetMarkerSize(0)
        #         plotfunc.AddRatioManual(cans[-1],curve,resid,drawopt1='l',drawopt2='l')
        pull = f.frame.pullHist()
        pull.SetMarkerSize(0.7)

        # for special
        if options.family == 'selected':
            color = {
                'Pow': ROOT.kBlack + 0,
                'Exponential': ROOT.kRed + 1,
                'ExpPoly2': ROOT.kBlue + 1,
                'Bern3': ROOT.kGreen + 1,
                'Bern4': ROOT.kMagenta + 1,
                'Bern5': ROOT.kOrange + 1,
            }.get(f.name)
            pull.SetMarkerColor(color)
            pull.SetLineColor(color)
            curve.SetLineColor(color)
            curve.SetFillColor(0)

        plotfunc.AddRatioManual(cans[-1],
                                curve,
                                pull,
                                drawopt1='l',
                                drawopt2='p')

        f.chisquare_toy = Tools.ChiSquareToys_ForSpuriousSignal(
            f, options.outdir)

    if not options.family == 'selected':
        plotfunc.SetColors(cans[-1])
    plotfunc.FormatCanvasAxes(cans[-1])
    plotfunc.SetXaxisRanges(cans[-1], Tools.lower_range, Tools.upper_range)
    plotfunc.SetAxisLabels(cans[-1], 'm_{#gamma#gamma} [GeV]', 'entries',
                           'pull')
    the_text = [
        plotfunc.GetAtlasInternalText(),
        plotfunc.GetSqrtsText(13) + ', ' + plotfunc.GetLuminosityText(36.1),
        Tools.CategoryNames[Tools.categories[options.category]]
    ]
    plotfunc.DrawText(cans[-1],
                      the_text,
                      0.19,
                      0.70,
                      0.59,
                      0.91,
                      totalentries=3)
    plotfunc.MakeLegend(cans[-1], 0.60, 0.70, 0.90, 0.91, totalentries=3)
    #plotfunc.GetTopPad(cans[-1]).GetPrimitive('legend').AddEntry(0,'^{ }background-only fit','')
    #list(plotfunc.GetTopPad(cans[-1]).GetPrimitive('legend').GetListOfPrimitives())[-1].SetLabel('^{ }background-only fit')
    plotfunc.SetYaxisRanges(plotfunc.GetBotPad(cans[-1]), -4, 4)
    taxisfunc.AutoFixYaxis(plotfunc.GetTopPad(cans[-1]),
                           ignorelegend=False,
                           minzero=True)

    for can in cans[:-1]:
        plotfunc.FormatCanvasAxes(can)

    anaplot.UpdateCanvases(cans, options)
    if not options.batch:
        raw_input('Press enter to exit')
    anaplot.doSaving(options, cans)

    return