Пример #1
0
def rooFit510():

    print ">>> create and fill workspace..."
    workspace = RooWorkspace("workspace")  # RooWorkspace
    fillWorkspace(workspace)

    print ">>>\n>>> retrieve model from workspace..."
    # Exploit convention encoded in named set "parameters" and "observables"
    # to use workspace contents w/o need for introspected
    model = workspace.pdf("model")  # RooAbsPdf

    print ">>> generate and fit data in given observables"
    data = model.generate(workspace.set("observables"), 1000)  # RooDataSet
    model.fitTo(data)

    print ">>> plot model and data of first observables..."
    frame1 = workspace.set("observables").first().frame()  # RooPlot
    data.plotOn(frame1, Name("data"), Binning(50))
    model.plotOn(frame1, Name("model"))

    print ">>> overlay plots with reference parameters as stored in snapshots..."
    workspace.loadSnapshot("reference_fit")
    model.plotOn(frame1, LineColor(kRed), Name("model_ref"))
    workspace.loadSnapshot("reference_fit_bkgonly")
    model.plotOn(frame1, LineColor(kRed), LineStyle(kDashed), Name("bkg_ref"))

    print "\n>>> draw on canvas..."
    canvas = TCanvas("canvas", "canvas", 100, 100, 800, 600)
    legend = TLegend(0.2, 0.8, 0.4, 0.6)
    legend.SetTextSize(0.032)
    legend.SetBorderSize(0)
    legend.SetFillStyle(0)
    gPad.SetLeftMargin(0.15)
    gPad.SetRightMargin(0.02)
    frame1.GetYaxis().SetLabelOffset(0.008)
    frame1.GetYaxis().SetTitleOffset(1.5)
    frame1.GetYaxis().SetTitleSize(0.045)
    frame1.GetXaxis().SetTitleSize(0.045)
    frame1.Draw()
    legend.AddEntry("data", "data", 'LEP')
    legend.AddEntry("model", "model", 'L')
    legend.AddEntry("model_ref", "model fit", 'L')
    legend.AddEntry("bkg_ref", "background only fit", 'L')
    legend.Draw()
    canvas.SaveAs("rooFit510.png")

    # Print workspace contents
    workspace.Print()

    # Workspace will remain in memory after macro finishes
    gDirectory.Add(workspace)
def rooFit511(compact=kFALSE):

    workspace = RooWorkspace("workspace")

    print ">>> creating and adding basic pdfs..."
    # Remake example pdf of tutorial rf502_wspacewrite.C:
    #
    # Basic pdf construction: ClassName::ObjectName(constructor arguments)
    # Variable construction:  VarName[x,xlo,xhi], VarName[xlo,xhi], VarName[x]
    # pdf addition:           SUM::ObjectName(coef1*pdf1,...coefM*pdfM,pdfN)

    if not compact:
        # Use object factory to build pdf of tutorial rooFit502_wspacewrite
        workspace.factory("Gaussian::sig1(x[-10,10],mean[5,0,10],0.5)")
        workspace.factory("Gaussian::sig2(x,mean,1)")
        workspace.factory("Chebychev::bkg(x,{a0[0.5,0.,1],a1[-0.2,0.,1.]})")
        workspace.factory("SUM::sig(sig1frac[0.8,0.,1.]*sig1,sig2)")
        workspace.factory("SUM::model(bkgfrac[0.5,0.,1.]*bkg,sig)")
    else:
        # Use object factory to build pdf of tutorial rf502_wspacewrite but
        #  - Contracted to a single line recursive expression,
        #  - Omitting explicit names for components that are not referred to explicitly later
        workspace.factory("SUM::model(bkgfrac[0.5,0.,1.]*Chebychev::bkg(x[-10,10],{a0[0.5,0.,1],a1[-0.2,0.,1.]}),"+\
                          "SUM(sig1frac[0.8,0.,1.]*Gaussian(x,mean[5,0,10],0.5),Gaussian(x,mean,1)))")

    print ">>> advanced pdf constructor arguments..."
    # pdf constructor arguments may by any type of RooAbsArg, but also the follow conversion are made:
    #   Double_t     -->  RooConst(...)
    #   {a,b,c}      -->  RooArgSet() or RooArgList() depending on required ctor arg
    #   dataset name -->  RooAbsData reference for any dataset residing in the workspace
    #   enum         -->  any enum label that belongs to an enum defined in the (base) class

    print ">>> generate a dummy dataset from 'model' pdf and import it in the workspace..."
    data = workspace.pdf("model").generate(RooArgSet(workspace.var("x")),
                                           1000)  # RooDataSet
    getattr(workspace, "import")(data, Rename("data"))

    print ">>> construct keys pdf..."
    # Construct a KEYS pdf passing a dataset name and an enum type defining the
    # mirroring strategy
    workspace.factory("KeysPdf::k(x,data,NoMirror,0.2)")

    print ">>> workspace contents:"
    workspace.Print()

    print ">>> save workspace in memory (gDirectory)..."
    gDirectory.Add(workspace)
Пример #3
0
def main(options, args):
    gROOT.Reset()

    #load our super special Polarization PDF
    gROOT.ProcessLine('.L RooPolarizationPdf.cxx+')
    gROOT.ProcessLine('.L RooPolarizationConstraint.cxx+')

    #setup integration
    intConf = ROOT.RooAbsReal.defaultIntegratorConfig()
    #intConf.Print('v')
    #    intConf.method1D().setLabel('RooAdaptiveGaussKronrodIntegrator1D')
    intConf.setEpsAbs(1e-13)
    intConf.setEpsRel(1e-13)
    print intConf.epsAbs()
    print intConf.epsRel()
    #    intConf.method2D().setLabel('RooMCIntegrator')
    #    intConf.methodND().setLabel('RooMCIntegrator')

    output = TFile.Open(options.workspaceName + '.root', 'RECREATE')

    theWS = RooWorkspace(options.workspaceName, 1)

    #save the polarization PDF code in the RooWorkspace
    theWS.importClassCode('RooPolarization*', True)

    buildDataAndCategories(theWS, options, args)

    buildMassAndLifetimePDF(theWS)

    #    if options.fitFrame is not None:
    #        buildPolarizationPDF(theWS,options)

    #root is stupid
    output.cd()

    theWS.Print('v')

    ROOT.RooMsgService.instance().Print()

    doFit(theWS, options)

    theWS.Write()
    output.Close()
Пример #4
0
def rooFit502():

    print ">>> setup model components..."
    x = RooRealVar("x", "x", 0, 10)
    mean = RooRealVar("mean", "mean of gaussians", 5, 0, 10)
    sigma1 = RooRealVar("sigma1", "width of gaussians", 0.5)
    sigma2 = RooRealVar("sigma2", "width of gaussians", 1)
    sig1 = RooGaussian("sig1", "Signal component 1", x, mean, sigma1)
    sig2 = RooGaussian("sig2", "Signal component 2", x, mean, sigma2)
    a0 = RooRealVar("a0", "a0", 0.5, 0., 1.)
    a1 = RooRealVar("a1", "a1", -0.2, 0., 1.)
    bkg = RooChebychev("bkg", "Background", x, RooArgList(a0, a1))

    print ">>> sum model components..."
    sig1frac = RooRealVar("sig1frac", "fraction of component 1 in signal", 0.8,
                          0., 1.)
    sig = RooAddPdf("sig", "Signal", RooArgList(sig1, sig2),
                    RooArgList(sig1frac))
    bkgfrac = RooRealVar("bkgfrac", "fraction of background", 0.5, 0., 1.)
    model = RooAddPdf("model", "g1+g2+a", RooArgList(bkg, sig),
                      RooArgList(bkgfrac))

    print ">>> generate data..."
    data = model.generate(RooArgSet(x), 1000)  # RooDataSet

    print ">>> create workspace, import data and model..."
    workspace = RooWorkspace("workspace", "workspace")  # empty RooWorkspace
    getattr(workspace, 'import')(model)  # import model and all its components
    getattr(workspace, 'import')(data)  # import data
    #workspace.import(model) # causes synthax error in python
    #workspace.import(data)  # causes synthax error in python

    print "\n>>> print workspace contents:"
    workspace.Print()

    print "\n>>> save workspace in file..."
    workspace.writeToFile("rooFit502_workspace.root")

    print ">>> save workspace in memory (gDirectory)..."
    gDirectory.Add(workspace)
Пример #5
0
key_COMB = []
hist_COMB = []
for i, bin in enumerate(decaytime_binnning):
    if i == 0:
        continue
    start = datetime.now()
    dataset_COMB_CORR_dtb_init = RooDataSet("dataset_COMB_CORR_dtb_init","Decaytime bin"+str(i),dataset_COMB_CORR,varset_small,"Dst_DTF_D0_CTAU>"+str(bin[0]*ctau)+"&&Dst_DTF_D0_CTAU<"+str(bin[1]*ctau))
    dataset_COMB_CORR_dtb = Subtract_Distribution(dataset_COMB_CORR_dtb_init, DTF_D0sPi_M, LOG_D0_IPCHI2_OWNPV, str(i)+"_comb", True)
    dataset_COMB_CORR_dtb.SetName("dataset_COMB_CORR_dtb")
    print "Background substraction from combinatorial tool  "+str(datetime.now()-start)+" \n"

    hist_COMB.append(RooDataHist("hist_COMB"+str(i),"hist_COMB", RooArgSet(LOG_D0_IPCHI2_OWNPV), dataset_COMB_CORR_dtb))
    key_COMB.append(RooKeysPdf("key_COMB_"+str(i), "key_COMB", LOG_D0_IPCHI2_OWNPV, dataset_COMB_CORR_dtb))

#We store shapes of Log(IPCHI2) for mathced candidates in for each decay time bins here.
wspace_2 = RooWorkspace("wspace_key_shapes")
wspace_2.Print("t")
wsfile = TFile("/afs/cern.ch/user/"+prefix+"/"+user+"/eos/lhcb/user/"+prefix+"/"+user+"/WrongSign/2015/Secondary_Key_Shapes.root", "recreate")
for k in key_COMB:
    wspace_2.rfimport(k) 
wspace_2.Write("wspace")

wspace_3 = RooWorkspace("wspace_hist_shapes")
wspace_3.Print("t")
wsfile = TFile("/afs/cern.ch/user/"+prefix+"/"+user+"/eos/lhcb/user/"+prefix+"/"+user+"/WrongSign/2015/Secondary_Hist_Shapes.root", "recreate")
for s in hist_COMB:
    wspace_3.rfimport(s) 
wspace_3.Write("wspace")

Пример #6
0
def main():
    # usage description
    usage = "Example: ./scripts/createDatacards.py --inputData inputs/rawhistV7_Run2015D_scoutingPFHT_UNBLINDED_649_838_JEC_HLTplusV7_Mjj_cor_smooth.root --dataHistname mjj_mjjcor_gev --inputSig inputs/ResonanceShapes_gg_13TeV_Scouting_Spring15.root -f gg -o datacards -l 1866 --lumiUnc 0.027 --massrange 1000 1500 50 --runFit --p1 5 --p2 7 --p3 0.4 --massMin 838 --massMax 2037 --fitStrategy 2"

    # input parameters
    parser = ArgumentParser(
        description=
        'Script that creates combine datacards and corresponding RooFit workspaces',
        epilog=usage)

    parser.add_argument("--inputData",
                        dest="inputData",
                        required=True,
                        help="Input data spectrum",
                        metavar="INPUT_DATA")

    parser.add_argument("--dataHistname",
                        dest="dataHistname",
                        required=True,
                        help="Data histogram name",
                        metavar="DATA_HISTNAME")

    parser.add_argument("--inputSig",
                        dest="inputSig",
                        required=True,
                        help="Input signal shapes",
                        metavar="INPUT_SIGNAL")

    parser.add_argument("-f",
                        "--final_state",
                        dest="final_state",
                        required=True,
                        help="Final state (e.g. qq, qg, gg)",
                        metavar="FINAL_STATE")

    parser.add_argument("-f2",
                        "--type",
                        dest="atype",
                        required=True,
                        help="Type (e.g. hG, lG, hR, lR)")

    parser.add_argument(
        "-o",
        "--output_path",
        dest="output_path",
        required=True,
        help="Output path where datacards and workspaces will be stored",
        metavar="OUTPUT_PATH")

    parser.add_argument(
        "-l",
        "--lumi",
        dest="lumi",
        required=True,
        default=1000.,
        type=float,
        help="Integrated luminosity in pb-1 (default: %(default).1f)",
        metavar="LUMI")

    parser.add_argument(
        "--massMin",
        dest="massMin",
        default=500,
        type=int,
        help=
        "Lower bound of the mass range used for fitting (default: %(default)s)",
        metavar="MASS_MIN")

    parser.add_argument(
        "--massMax",
        dest="massMax",
        default=1200,
        type=int,
        help=
        "Upper bound of the mass range used for fitting (default: %(default)s)",
        metavar="MASS_MAX")

    parser.add_argument(
        "--p1",
        dest="p1",
        default=5.0000e-03,
        type=float,
        help="Fit function p1 parameter (default: %(default)e)",
        metavar="P1")

    parser.add_argument(
        "--p2",
        dest="p2",
        default=9.1000e+00,
        type=float,
        help="Fit function p2 parameter (default: %(default)e)",
        metavar="P2")

    parser.add_argument(
        "--p3",
        dest="p3",
        default=5.0000e-01,
        type=float,
        help="Fit function p3 parameter (default: %(default)e)",
        metavar="P3")

    parser.add_argument(
        "--lumiUnc",
        dest="lumiUnc",
        required=True,
        type=float,
        help="Relative uncertainty in the integrated luminosity",
        metavar="LUMI_UNC")

    parser.add_argument("--jesUnc",
                        dest="jesUnc",
                        type=float,
                        help="Relative uncertainty in the jet energy scale",
                        metavar="JES_UNC")

    parser.add_argument(
        "--jerUnc",
        dest="jerUnc",
        type=float,
        help="Relative uncertainty in the jet energy resolution",
        metavar="JER_UNC")

    parser.add_argument(
        "--sqrtS",
        dest="sqrtS",
        default=13000.,
        type=float,
        help="Collision center-of-mass energy (default: %(default).1f)",
        metavar="SQRTS")

    parser.add_argument("--fixP3",
                        dest="fixP3",
                        default=False,
                        action="store_true",
                        help="Fix the fit function p3 parameter")

    parser.add_argument("--runFit",
                        dest="runFit",
                        default=False,
                        action="store_true",
                        help="Run the fit")

    parser.add_argument("--fitBonly",
                        dest="fitBonly",
                        default=False,
                        action="store_true",
                        help="Run B-only fit")

    parser.add_argument("--fixBkg",
                        dest="fixBkg",
                        default=False,
                        action="store_true",
                        help="Fix all background parameters")

    parser.add_argument("--decoBkg",
                        dest="decoBkg",
                        default=False,
                        action="store_true",
                        help="Decorrelate background parameters")

    parser.add_argument("--fitStrategy",
                        dest="fitStrategy",
                        type=int,
                        default=1,
                        help="Fit strategy (default: %(default).1f)")

    parser.add_argument("--debug",
                        dest="debug",
                        default=False,
                        action="store_true",
                        help="Debug printout")

    parser.add_argument(
        "--postfix",
        dest="postfix",
        default='',
        help="Postfix for the output file names (default: %(default)s)")

    parser.add_argument("--pyes",
                        dest="pyes",
                        default=False,
                        action="store_true",
                        help="Make files for plots")

    parser.add_argument("--jyes",
                        dest="jyes",
                        default=False,
                        action="store_true",
                        help="Make files for JES/JER plots")

    parser.add_argument(
        "--pdir",
        dest="pdir",
        default='testarea',
        help="Name a directory for the plots (default: %(default)s)")

    parser.add_argument("--chi2",
                        dest="chi2",
                        default=False,
                        action="store_true",
                        help="Compute chi squared")

    parser.add_argument("--widefit",
                        dest="widefit",
                        default=False,
                        action="store_true",
                        help="Fit with wide bin hist")

    mass_group = parser.add_mutually_exclusive_group(required=True)
    mass_group.add_argument(
        "--mass",
        type=int,
        nargs='*',
        default=1000,
        help=
        "Mass can be specified as a single value or a whitespace separated list (default: %(default)i)"
    )
    mass_group.add_argument(
        "--massrange",
        type=int,
        nargs=3,
        help="Define a range of masses to be produced. Format: min max step",
        metavar=('MIN', 'MAX', 'STEP'))
    mass_group.add_argument("--masslist",
                            help="List containing mass information")

    args = parser.parse_args()

    if args.atype == 'hG':
        fstr = "bbhGGBB"
        in2 = 'bcorrbin/binmodh.root'
    elif args.atype == 'hR':
        fstr = "bbhRS"
        in2 = 'bcorrbin/binmodh.root'
    elif args.atype == 'lG':
        fstr = "bblGGBB"
        in2 = 'bcorrbin/binmodl.root'
    else:
        fstr = "bblRS"
        in2 = 'bcorrbin/binmodl.root'

    # check if the output directory exists
    if not os.path.isdir(os.path.join(os.getcwd(), args.output_path)):
        os.mkdir(os.path.join(os.getcwd(), args.output_path))

    # mass points for which resonance shapes will be produced
    masses = []

    if args.massrange != None:
        MIN, MAX, STEP = args.massrange
        masses = range(MIN, MAX + STEP, STEP)
    elif args.masslist != None:
        # A mass list was provided
        print "Will create mass list according to", args.masslist
        masslist = __import__(args.masslist.replace(".py", ""))
        masses = masslist.masses
    else:
        masses = args.mass

    # sort masses
    masses.sort()

    # import ROOT stuff
    from ROOT import gStyle, TFile, TH1F, TH1D, TGraph, kTRUE, kFALSE, TCanvas, TLegend, TPad, TLine
    from ROOT import RooHist, RooRealVar, RooDataHist, RooArgList, RooArgSet, RooAddPdf, RooFit, RooGenericPdf, RooWorkspace, RooMsgService, RooHistPdf, RooExtendPdf

    if not args.debug:
        RooMsgService.instance().setSilentMode(kTRUE)
        RooMsgService.instance().setStreamStatus(0, kFALSE)
        RooMsgService.instance().setStreamStatus(1, kFALSE)

    # input data file
    inputData = TFile(args.inputData)
    # input data histogram
    hData = inputData.Get(args.dataHistname)

    inData2 = TFile(in2)
    hData2 = inData2.Get('h_data')

    # input sig file
    inputSig = TFile(args.inputSig)

    sqrtS = args.sqrtS

    # mass variable
    mjj = RooRealVar('mjj', 'mjj', float(args.massMin), float(args.massMax))

    # integrated luminosity and signal cross section
    lumi = args.lumi
    signalCrossSection = 1.  # set to 1. so that the limit on r can be interpreted as a limit on the signal cross section

    for mass in masses:

        print ">> Creating datacard and workspace for %s resonance with m = %i GeV..." % (
            args.final_state, int(mass))

        # get signal shape
        hSig = inputSig.Get("h_" + args.final_state + "_" + str(int(mass)))
        # normalize signal shape to the expected event yield (works even if input shapes are not normalized to unity)
        hSig.Scale(
            signalCrossSection * lumi / hSig.Integral()
        )  # divide by a number that provides roughly an r value of 1-10
        rooSigHist = RooDataHist('rooSigHist', 'rooSigHist', RooArgList(mjj),
                                 hSig)
        print 'Signal acceptance:', (rooSigHist.sumEntries() / hSig.Integral())
        signal = RooHistPdf('signal', 'signal', RooArgSet(mjj), rooSigHist)
        signal_norm = RooRealVar('signal_norm', 'signal_norm', 0, -1e+05,
                                 1e+05)
        signal_norm2 = RooRealVar('signal_norm2', 'signal_norm2', 0, -1e+05,
                                  1e+05)
        signal_norm3 = RooRealVar('signal_norm3', 'signal_norm3', 0, -1e+05,
                                  1e+05)
        signal_norm4 = RooRealVar('signal_norm4', 'signal_norm4', 0, -1e+05,
                                  1e+05)
        signal_norm5 = RooRealVar('signal_norm5', 'signal_norm5', 0, -1e+05,
                                  1e+05)

        if args.fitBonly:
            signal_norm.setConstant()
            signal_norm2.setConstant()
            signal_norm3.setConstant()
            signal_norm4.setConstant()
            signal_norm5.setConstant()

        p1 = RooRealVar('p1', 'p1', args.p1, 0., 100.)
        p2 = RooRealVar('p2', 'p2', args.p2, 0., 60.)
        p3 = RooRealVar('p3', 'p3', args.p3, -10., 10.)
        p4 = RooRealVar('p4', 'p4', 5.6, -50., 50.)
        p5 = RooRealVar('p5', 'p5', 10., -50., 50.)
        p6 = RooRealVar('p6', 'p6', .016, -50., 50.)
        p7 = RooRealVar('p7', 'p7', 8., -50., 50.)
        p8 = RooRealVar('p8', 'p8', .22, -50., 50.)
        p9 = RooRealVar('p9', 'p9', 14.1, -50., 50.)
        p10 = RooRealVar('p10', 'p10', 8., -50., 50.)
        p11 = RooRealVar('p11', 'p11', 4.8, -50., 50.)
        p12 = RooRealVar('p12', 'p12', 7., -50., 50.)
        p13 = RooRealVar('p13', 'p13', 7., -50., 50.)
        p14 = RooRealVar('p14', 'p14', 7., -50., 50.)
        p15 = RooRealVar('p15', 'p15', 1., -50., 50.)
        p16 = RooRealVar('p16', 'p16', 9., -50., 50.)
        p17 = RooRealVar('p17', 'p17', 0.6, -50., 50.)

        if args.fixP3: p3.setConstant()

        background = RooGenericPdf(
            'background',
            '(pow(1-@0/%.1f,@1)/pow(@0/%.1f,@2+@3*log(@0/%.1f)))' %
            (sqrtS, sqrtS, sqrtS), RooArgList(mjj, p1, p2, p3))
        dataInt = hData.Integral(hData.GetXaxis().FindBin(float(args.massMin)),
                                 hData.GetXaxis().FindBin(float(args.massMax)))
        background_norm = RooRealVar('background_norm', 'background_norm',
                                     dataInt, 0., 1e+08)

        background2 = RooGenericPdf(
            'background2',
            '(pow(@0/%.1f,-@1)*pow(1-@0/%.1f,@2))' % (sqrtS, sqrtS),
            RooArgList(mjj, p4, p5))
        dataInt2 = hData.Integral(
            hData.GetXaxis().FindBin(float(args.massMin)),
            hData.GetXaxis().FindBin(float(args.massMax)))
        background2_norm = RooRealVar('background2_norm', 'background2_norm',
                                      dataInt2, 0., 1e+08)

        background3 = RooGenericPdf('background3',
                                    '(1/pow(@1+@0/%.1f,@2))' % (sqrtS),
                                    RooArgList(mjj, p6, p7))
        dataInt3 = hData.Integral(
            hData.GetXaxis().FindBin(float(args.massMin)),
            hData.GetXaxis().FindBin(float(args.massMax)))
        background3_norm = RooRealVar('background3_norm', 'background3_norm',
                                      dataInt3, 0., 1e+08)

        background4 = RooGenericPdf(
            'background4',
            '(1/pow(@1+@2*@0/%.1f+pow(@0/%.1f,2),@3))' % (sqrtS, sqrtS),
            RooArgList(mjj, p8, p9, p10))
        dataInt4 = hData.Integral(
            hData.GetXaxis().FindBin(float(args.massMin)),
            hData.GetXaxis().FindBin(float(args.massMax)))
        background4_norm = RooRealVar('background4_norm', 'background4_norm',
                                      dataInt4, 0., 1e+08)

        background5 = RooGenericPdf(
            'background5',
            '(pow(@0/%.1f,-@1)*pow(1-pow(@0/%.1f,1/3),@2))' % (sqrtS, sqrtS),
            RooArgList(mjj, p11, p12))
        dataInt5 = hData.Integral(
            hData.GetXaxis().FindBin(float(args.massMin)),
            hData.GetXaxis().FindBin(float(args.massMax)))
        background5_norm = RooRealVar('background5_norm', 'background5_norm',
                                      dataInt5, 0., 1e+08)

        background6 = RooGenericPdf(
            'background6', '(pow(@0/%.1f,2)+@1*@0/%.1f+@2)' % (sqrtS, sqrtS),
            RooArgList(mjj, p13, p14))
        dataInt6 = hData.Integral(
            hData.GetXaxis().FindBin(float(args.massMin)),
            hData.GetXaxis().FindBin(float(args.massMax)))
        background_norm6 = RooRealVar('background_norm6', 'background_norm6',
                                      dataInt6, 0., 1e+08)

        background7 = RooGenericPdf(
            'background7',
            '((-1+@1*@0/%.1f)*pow(@0/%.1f,@2+@3*log(@0/%.1f)))' %
            (sqrtS, sqrtS, sqrtS), RooArgList(mjj, p15, p16, p17))
        dataInt7 = hData.Integral(
            hData.GetXaxis().FindBin(float(args.massMin)),
            hData.GetXaxis().FindBin(float(args.massMax)))
        background_norm7 = RooRealVar('background_norm7', 'background_norm7',
                                      dataInt7, 0., 1e+08)

        #Extend PDFs

        exts = RooExtendPdf('extsignal', 'Extended Signal Pdf', signal,
                            signal_norm)
        extb = RooExtendPdf('extbackground', 'Extended Background Pdf',
                            background, background_norm)
        exts2 = RooExtendPdf('extsignal2', 'Extended Signal Pdf2', signal,
                             signal_norm2)
        extb2 = RooExtendPdf('extbackground2', 'Extended Background Pdf2',
                             background2, background2_norm)
        exts3 = RooExtendPdf('extsignal3', 'Extended Signal Pdf3', signal,
                             signal_norm3)
        extb3 = RooExtendPdf('extbackground3', 'Extended Background Pdf3',
                             background3, background3_norm)
        exts4 = RooExtendPdf('extsignal4', 'Extended Signal Pdf4', signal,
                             signal_norm4)
        extb4 = RooExtendPdf('extbackground4', 'Extended Background Pdf4',
                             background4, background4_norm)
        exts5 = RooExtendPdf('extsignal5', 'Extended Signal Pdf5', signal,
                             signal_norm5)
        extb5 = RooExtendPdf('extbackground5', 'Extended Background Pdf5',
                             background5, background5_norm)

        # S+B model
        model = RooAddPdf("model", "s+b", RooArgList(extb, exts))
        model2 = RooAddPdf("model2", "s+b2", RooArgList(extb2, exts2))
        model3 = RooAddPdf("model3", "s+b3", RooArgList(extb3, exts3))
        model4 = RooAddPdf("model4", "s+b4", RooArgList(extb4, exts4))
        model5 = RooAddPdf("model5", "s+b5", RooArgList(extb5, exts5))

        #model6 = RooAddPdf("model6","s+b6",RooArgList(background6,signal),RooArgList(background_norm6,signal_norm))
        #model7 = RooAddPdf("model7","s+b7",RooArgList(background7,signal),RooArgList(background_norm7,signal_norm))

        rooDataHist = RooDataHist('rooDatahist', 'rooDathist', RooArgList(mjj),
                                  hData)

        if args.runFit:
            mframe = mjj.frame()
            rooDataHist.plotOn(mframe, ROOT.RooFit.Name("setonedata"))
            res = model.fitTo(rooDataHist, RooFit.Save(kTRUE),
                              RooFit.Extended(kTRUE),
                              RooFit.Strategy(args.fitStrategy))
            model.plotOn(mframe, ROOT.RooFit.Name("model1"),
                         ROOT.RooFit.LineStyle(1), ROOT.RooFit.LineWidth(1),
                         ROOT.RooFit.LineColor(ROOT.EColor.kRed))
            res2 = model2.fitTo(rooDataHist, RooFit.Save(kTRUE),
                                RooFit.Extended(kTRUE),
                                RooFit.Strategy(args.fitStrategy))
            #            model2.plotOn(mframe, ROOT.RooFit.Name("model2"), ROOT.RooFit.LineStyle(1), ROOT.RooFit.LineWidth(1), ROOT.RooFit.LineColor(ROOT.EColor.kOrange))
            res3 = model3.fitTo(rooDataHist, RooFit.Save(kTRUE),
                                RooFit.Extended(kTRUE),
                                RooFit.Strategy(args.fitStrategy))
            #            model3.plotOn(mframe, ROOT.RooFit.Name("model3"), ROOT.RooFit.LineStyle(1), ROOT.RooFit.LineWidth(1), ROOT.RooFit.LineColor(ROOT.EColor.kGreen))
            res4 = model4.fitTo(rooDataHist, RooFit.Save(kTRUE),
                                RooFit.Extended(kTRUE),
                                RooFit.Strategy(args.fitStrategy))
            #            model4.plotOn(mframe, ROOT.RooFit.Name("model4"), ROOT.RooFit.LineStyle(1), ROOT.RooFit.LineWidth(1), ROOT.RooFit.LineColor(ROOT.EColor.kBlue))
            res5 = model5.fitTo(rooDataHist, RooFit.Save(kTRUE),
                                RooFit.Extended(kTRUE),
                                RooFit.Strategy(args.fitStrategy))
            #            model5.plotOn(mframe, ROOT.RooFit.Name("model5"), ROOT.RooFit.LineStyle(1), ROOT.RooFit.LineWidth(1), ROOT.RooFit.LineColor(ROOT.EColor.kViolet))
            #	    res6 = model6.fitTo(rooDataHist, RooFit.Save(kTRUE), RooFit.Strategy(args.fitStrategy))
            #           model6.plotOn(mframe, ROOT.RooFit.Name("model6"), ROOT.RooFit.LineStyle(1), ROOT.RooFit.LineWidth(1), ROOT.RooFit.LineColor(ROOT.EColor.kPink))
            #	    res7 = model7.fitTo(rooDataHist, RooFit.Save(kTRUE), RooFit.Strategy(args.fitStrategy))
            #           model7.plotOn(mframe, ROOT.RooFit.Name("model7"), ROOT.RooFit.LineStyle(1), ROOT.RooFit.LineWidth(1), ROOT.RooFit.LineColor(ROOT.EColor.kAzure))

            rooDataHist2 = RooDataHist('rooDatahist2', 'rooDathist2',
                                       RooArgList(mjj), hData2)
            #	    rooDataHist2.plotOn(mframe, ROOT.RooFit.Name("data"))

            if args.pyes:
                c = TCanvas("c", "c", 800, 800)
                mframe.SetAxisRange(300., 1300.)
                c.SetLogy()
                #	    	mframe.SetMaximum(10)
                #	    	mframe.SetMinimum(1)
                mframe.Draw()
                fitname = args.pdir + '/5funcfit_m' + str(mass) + fstr + '.pdf'
                c.SaveAs(fitname)

#	        cpull = TCanvas("cpull","cpull",800,800)
#	    	pulls = mframe.pullHist("data","model1")
#	    	pulls.Draw("ABX")
#	   	pullname = args.pdir+'/pull_m'+str(mass)+fstr+'.pdf'
#	    	cpull.SaveAs(pullname)

#		cpull2 = TCanvas("cpull2","cpull2",800,800)
#               pulls2 = mframe.pullHist("setonedata","model1")
#              pulls2.Draw("ABX")
#             pull2name = args.pdir+'/pull2_m'+str(mass)+fstr+'.pdf'
#            cpull2.SaveAs(pull2name)

            if args.widefit:
                mframew = mjj.frame()
                rooDataHist2.plotOn(mframew, ROOT.RooFit.Name("data"))
                res6 = model.fitTo(rooDataHist2, RooFit.Save(kTRUE),
                                   RooFit.Strategy(args.fitStrategy))
                model.plotOn(mframew, ROOT.RooFit.Name("model1"),
                             ROOT.RooFit.LineStyle(1),
                             ROOT.RooFit.LineWidth(1),
                             ROOT.RooFit.LineColor(ROOT.EColor.kRed))
                res7 = model2.fitTo(rooDataHist2, RooFit.Save(kTRUE),
                                    RooFit.Strategy(args.fitStrategy))
                model2.plotOn(mframew, ROOT.RooFit.Name("model2"),
                              ROOT.RooFit.LineStyle(1),
                              ROOT.RooFit.LineWidth(1),
                              ROOT.RooFit.LineColor(ROOT.EColor.kOrange))
                res8 = model3.fitTo(rooDataHist2, RooFit.Save(kTRUE),
                                    RooFit.Strategy(args.fitStrategy))
                model3.plotOn(mframew, ROOT.RooFit.Name("model3"),
                              ROOT.RooFit.LineStyle(1),
                              ROOT.RooFit.LineWidth(1),
                              ROOT.RooFit.LineColor(ROOT.EColor.kGreen))
                res9 = model4.fitTo(rooDataHist2, RooFit.Save(kTRUE),
                                    RooFit.Strategy(args.fitStrategy))
                model4.plotOn(mframew, ROOT.RooFit.Name("model4"),
                              ROOT.RooFit.LineStyle(1),
                              ROOT.RooFit.LineWidth(1),
                              ROOT.RooFit.LineColor(ROOT.EColor.kBlue))
                res10 = model5.fitTo(rooDataHist2, RooFit.Save(kTRUE),
                                     RooFit.Strategy(args.fitStrategy))
                model5.plotOn(mframew, ROOT.RooFit.Name("model5"),
                              ROOT.RooFit.LineStyle(1),
                              ROOT.RooFit.LineWidth(1),
                              ROOT.RooFit.LineColor(ROOT.EColor.kViolet))

                if args.pyes:
                    c = TCanvas("c", "c", 800, 800)
                    mframew.SetAxisRange(300., 1300.)
                    c.SetLogy()
                    #                   mframew.SetMaximum(10)
                    #                   mframew.SetMinimum(1)
                    mframew.Draw()
                    fitname = args.pdir + '/5funcfittowide_m' + str(
                        mass) + fstr + '.pdf'
                    c.SaveAs(fitname)

                    cpull = TCanvas("cpull", "cpull", 800, 800)
                    pulls = mframew.pullHist("data", "model1")
                    pulls.Draw("ABX")
                    pullname = args.pdir + '/pullwidefit_m' + str(
                        mass) + fstr + '.pdf'
                    cpull.SaveAs(pullname)

            if args.chi2:
                fullInt = model.createIntegral(RooArgSet(mjj))
                norm = dataInt / fullInt.getVal()
                chi1 = 0.
                fullInt2 = model2.createIntegral(RooArgSet(mjj))
                norm2 = dataInt2 / fullInt2.getVal()
                chi2 = 0.
                fullInt3 = model3.createIntegral(RooArgSet(mjj))
                norm3 = dataInt3 / fullInt3.getVal()
                chi3 = 0.
                fullInt4 = model4.createIntegral(RooArgSet(mjj))
                norm4 = dataInt4 / fullInt4.getVal()
                chi4 = 0.
                fullInt5 = model5.createIntegral(RooArgSet(mjj))
                norm5 = dataInt5 / fullInt5.getVal()
                chi5 = 0.
                for i in range(args.massMin, args.massMax):
                    new = 0
                    new2 = 0
                    new3 = 0
                    new4 = 0
                    new5 = 0
                    height = hData.GetBinContent(i)
                    xLow = hData.GetXaxis().GetBinLowEdge(i)
                    xUp = hData.GetXaxis().GetBinLowEdge(i + 1)
                    obs = height * (xUp - xLow)
                    mjj.setRange("intrange", xLow, xUp)
                    integ = model.createIntegral(
                        RooArgSet(mjj), ROOT.RooFit.NormSet(RooArgSet(mjj)),
                        ROOT.RooFit.Range("intrange"))
                    exp = integ.getVal() * norm
                    new = pow(exp - obs, 2) / exp
                    chi1 = chi1 + new
                    integ2 = model2.createIntegral(
                        RooArgSet(mjj), ROOT.RooFit.NormSet(RooArgSet(mjj)),
                        ROOT.RooFit.Range("intrange"))
                    exp2 = integ2.getVal() * norm2
                    new2 = pow(exp2 - obs, 2) / exp2
                    chi2 = chi2 + new2
                    integ3 = model3.createIntegral(
                        RooArgSet(mjj), ROOT.RooFit.NormSet(RooArgSet(mjj)),
                        ROOT.RooFit.Range("intrange"))
                    exp3 = integ3.getVal() * norm3
                    new3 = pow(exp3 - obs, 2) / exp3
                    chi3 = chi3 + new3
                    integ4 = model4.createIntegral(
                        RooArgSet(mjj), ROOT.RooFit.NormSet(RooArgSet(mjj)),
                        ROOT.RooFit.Range("intrange"))
                    exp4 = integ4.getVal() * norm4
                    if exp4 != 0:
                        new4 = pow(exp4 - obs, 2) / exp4
                    else:
                        new4 = 0
                    chi4 = chi4 + new4
                    integ5 = model5.createIntegral(
                        RooArgSet(mjj), ROOT.RooFit.NormSet(RooArgSet(mjj)),
                        ROOT.RooFit.Range("intrange"))
                    exp5 = integ5.getVal() * norm5
                    new5 = pow(exp5 - obs, 2) / exp5
                    chi5 = chi5 + new5
                print "chi1 %d " % (chi1)
                print "chi2 %d " % (chi2)
                print "chi3 %d " % (chi3)
                print "chi4 %d " % (chi4)
                print "chi5 %d " % (chi5)

            if not args.decoBkg:
                print " "
                res.Print()
                res2.Print()
                res3.Print()
                res4.Print()
                res5.Print()


#		res6.Print()
#		res7.Print()

# decorrelated background parameters for Bayesian limits
            if args.decoBkg:
                signal_norm.setConstant()
                res = model.fitTo(rooDataHist, RooFit.Save(kTRUE),
                                  RooFit.Strategy(args.fitStrategy))
                res.Print()
                ## temp workspace for the PDF diagonalizer
                w_tmp = RooWorkspace("w_tmp")
                deco = PdfDiagonalizer("deco", w_tmp, res)
                # here diagonalizing only the shape parameters since the overall normalization is already decorrelated
                background_deco = deco.diagonalize(background)
                print "##################### workspace for decorrelation"
                w_tmp.Print("v")
                print "##################### original parameters"
                background.getParameters(rooDataHist).Print("v")
                print "##################### decorrelated parameters"
                # needed if want to evaluate limits without background systematics
                if args.fixBkg:
                    w_tmp.var("deco_eig1").setConstant()
                    w_tmp.var("deco_eig2").setConstant()
                    if not args.fixP3: w_tmp.var("deco_eig3").setConstant()
                background_deco.getParameters(rooDataHist).Print("v")
                print "##################### original pdf"
                background.Print()
                print "##################### decorrelated pdf"
                background_deco.Print()
                # release signal normalization
                signal_norm.setConstant(kFALSE)
                # set the background normalization range to +/- 5 sigma
                bkg_val = background_norm.getVal()
                bkg_error = background_norm.getError()
                background_norm.setMin(bkg_val - 5 * bkg_error)
                background_norm.setMax(bkg_val + 5 * bkg_error)
                background_norm.Print()
                # change background PDF names
                background.SetName("background_old")
                background_deco.SetName("background")

        # needed if want to evaluate limits without background systematics
        if args.fixBkg:
            background_norm.setConstant()
            p1.setConstant()
            p2.setConstant()
            p3.setConstant()

        # -----------------------------------------
        # dictionaries holding systematic variations of the signal shape
        hSig_Syst = {}
        hSig_Syst_DataHist = {}
        sigCDF = TGraph(hSig.GetNbinsX() + 1)

        # JES and JER uncertainties
        if args.jesUnc != None or args.jerUnc != None:

            sigCDF.SetPoint(0, 0., 0.)
            integral = 0.
            for i in range(1, hSig.GetNbinsX() + 1):
                x = hSig.GetXaxis().GetBinLowEdge(i + 1)
                integral = integral + hSig.GetBinContent(i)
                sigCDF.SetPoint(i, x, integral)

        if args.jesUnc != None:
            hSig_Syst['JESUp'] = copy.deepcopy(hSig)
            hSig_Syst['JESDown'] = copy.deepcopy(hSig)

        if args.jerUnc != None:
            hSig_Syst['JERUp'] = copy.deepcopy(hSig)
            hSig_Syst['JERDown'] = copy.deepcopy(hSig)

        # reset signal histograms
        for key in hSig_Syst.keys():
            hSig_Syst[key].Reset()
            hSig_Syst[key].SetName(hSig_Syst[key].GetName() + '_' + key)

        # produce JES signal shapes
        if args.jesUnc != None:
            for i in range(1, hSig.GetNbinsX() + 1):
                xLow = hSig.GetXaxis().GetBinLowEdge(i)
                xUp = hSig.GetXaxis().GetBinLowEdge(i + 1)
                jes = 1. - args.jesUnc
                xLowPrime = jes * xLow
                xUpPrime = jes * xUp
                hSig_Syst['JESUp'].SetBinContent(
                    i,
                    sigCDF.Eval(xUpPrime) - sigCDF.Eval(xLowPrime))
                jes = 1. + args.jesUnc
                xLowPrime = jes * xLow
                xUpPrime = jes * xUp
                hSig_Syst['JESDown'].SetBinContent(
                    i,
                    sigCDF.Eval(xUpPrime) - sigCDF.Eval(xLowPrime))
            hSig_Syst_DataHist['JESUp'] = RooDataHist('hSig_JESUp',
                                                      'hSig_JESUp',
                                                      RooArgList(mjj),
                                                      hSig_Syst['JESUp'])
            hSig_Syst_DataHist['JESDown'] = RooDataHist(
                'hSig_JESDown', 'hSig_JESDown', RooArgList(mjj),
                hSig_Syst['JESDown'])

            if args.jyes:
                c2 = TCanvas("c2", "c2", 800, 800)
                mframe2 = mjj.frame(ROOT.RooFit.Title("JES One Sigma Shifts"))
                mframe2.SetAxisRange(args.massMin, args.massMax)
                hSig_Syst_DataHist['JESUp'].plotOn(
                    mframe2, ROOT.RooFit.Name("JESUP"),
                    ROOT.RooFit.DrawOption("L"), ROOT.RooFit.DataError(2),
                    ROOT.RooFit.LineStyle(1),
                    ROOT.RooFit.MarkerColor(ROOT.EColor.kRed),
                    ROOT.RooFit.LineColor(ROOT.EColor.kRed))
                hSig_Syst_DataHist['JESDown'].plotOn(
                    mframe2, ROOT.RooFit.Name("JESDOWN"),
                    ROOT.RooFit.DrawOption("L"), ROOT.RooFit.DataError(2),
                    ROOT.RooFit.LineStyle(1),
                    ROOT.RooFit.MarkerColor(ROOT.EColor.kBlue),
                    ROOT.RooFit.LineColor(ROOT.EColor.kBlue))
                rooSigHist.plotOn(mframe2, ROOT.RooFit.DataError(2),
                                  ROOT.RooFit.Name("SIG"),
                                  ROOT.RooFit.DrawOption("L"),
                                  ROOT.RooFit.LineStyle(1),
                                  ROOT.RooFit.MarkerColor(ROOT.EColor.kGreen),
                                  ROOT.RooFit.LineColor(ROOT.EColor.kGreen))
                mframe2.Draw()
                mframe2.GetXaxis().SetTitle("Dijet Mass (GeV)")
                leg = TLegend(0.7, 0.8, 0.9, 0.9)
                leg.SetFillColor(0)
                leg.AddEntry(mframe2.findObject("SIG"), "Signal Model", "l")
                leg.AddEntry(mframe2.findObject("JESUP"), "+1 Sigma", "l")
                leg.AddEntry(mframe2.findObject("JESDOWN"), "-1 Sigma", "l")
                leg.Draw()
                jesname = args.pdir + '/jes_m' + str(mass) + fstr + '.pdf'
                c2.SaveAs(jesname)

        # produce JER signal shapes
        if args.jesUnc != None:
            for i in range(1, hSig.GetNbinsX() + 1):
                xLow = hSig.GetXaxis().GetBinLowEdge(i)
                xUp = hSig.GetXaxis().GetBinLowEdge(i + 1)
                jer = 1. - args.jerUnc
                xLowPrime = jer * (xLow - float(mass)) + float(mass)
                xUpPrime = jer * (xUp - float(mass)) + float(mass)
                hSig_Syst['JERUp'].SetBinContent(
                    i,
                    sigCDF.Eval(xUpPrime) - sigCDF.Eval(xLowPrime))
                jer = 1. + args.jerUnc
                xLowPrime = jer * (xLow - float(mass)) + float(mass)
                xUpPrime = jer * (xUp - float(mass)) + float(mass)
                hSig_Syst['JERDown'].SetBinContent(
                    i,
                    sigCDF.Eval(xUpPrime) - sigCDF.Eval(xLowPrime))
            hSig_Syst_DataHist['JERUp'] = RooDataHist('hSig_JERUp',
                                                      'hSig_JERUp',
                                                      RooArgList(mjj),
                                                      hSig_Syst['JERUp'])
            hSig_Syst_DataHist['JERDown'] = RooDataHist(
                'hSig_JERDown', 'hSig_JERDown', RooArgList(mjj),
                hSig_Syst['JERDown'])

            if args.jyes:
                c3 = TCanvas("c3", "c3", 800, 800)
                mframe3 = mjj.frame(ROOT.RooFit.Title("JER One Sigma Shifts"))
                mframe3.SetAxisRange(args.massMin, args.massMax)
                hSig_Syst_DataHist['JERUp'].plotOn(
                    mframe3, ROOT.RooFit.Name("JERUP"),
                    ROOT.RooFit.DrawOption("L"), ROOT.RooFit.DataError(2),
                    ROOT.RooFit.LineStyle(1),
                    ROOT.RooFit.MarkerColor(ROOT.EColor.kRed),
                    ROOT.RooFit.LineColor(ROOT.EColor.kRed))
                hSig_Syst_DataHist['JERDown'].plotOn(
                    mframe3, ROOT.RooFit.Name("JERDOWN"),
                    ROOT.RooFit.DrawOption("L"), ROOT.RooFit.DataError(2),
                    ROOT.RooFit.LineStyle(1),
                    ROOT.RooFit.MarkerColor(ROOT.EColor.kBlue),
                    ROOT.RooFit.LineColor(ROOT.EColor.kBlue))
                rooSigHist.plotOn(mframe3, ROOT.RooFit.DrawOption("L"),
                                  ROOT.RooFit.Name("SIG"),
                                  ROOT.RooFit.DataError(2),
                                  ROOT.RooFit.LineStyle(1),
                                  ROOT.RooFit.MarkerColor(ROOT.EColor.kGreen),
                                  ROOT.RooFit.LineColor(ROOT.EColor.kGreen))
                mframe3.Draw()
                mframe3.GetXaxis().SetTitle("Dijet Mass (GeV)")
                leg = TLegend(0.7, 0.8, 0.9, 0.9)
                leg.SetFillColor(0)
                leg.AddEntry(mframe3.findObject("SIG"), "Signal Model", "l")
                leg.AddEntry(mframe3.findObject("JERUP"), "+1 Sigma", "l")
                leg.AddEntry(mframe3.findObject("JERDOWN"), "-1 Sigma", "l")
                leg.Draw()
                jername = args.pdir + '/jer_m' + str(mass) + fstr + '.pdf'
                c3.SaveAs(jername)

        # -----------------------------------------
        # create a datacard and corresponding workspace
        postfix = (('_' + args.postfix) if args.postfix != '' else '')
        dcName = 'datacard_' + args.final_state + '_m' + str(
            mass) + postfix + '.txt'
        wsName = 'workspace_' + args.final_state + '_m' + str(
            mass) + postfix + '.root'

        w = RooWorkspace('w', 'workspace')
        getattr(w, 'import')(rooSigHist, RooFit.Rename("signal"))
        if args.jesUnc != None:
            getattr(w, 'import')(hSig_Syst_DataHist['JESUp'],
                                 RooFit.Rename("signal__JESUp"))
            getattr(w, 'import')(hSig_Syst_DataHist['JESDown'],
                                 RooFit.Rename("signal__JESDown"))
        if args.jerUnc != None:
            getattr(w, 'import')(hSig_Syst_DataHist['JERUp'],
                                 RooFit.Rename("signal__JERUp"))
            getattr(w, 'import')(hSig_Syst_DataHist['JERDown'],
                                 RooFit.Rename("signal__JERDown"))
        if args.decoBkg:
            getattr(w, 'import')(background_deco, ROOT.RooCmdArg())
        else:
            getattr(w, 'import')(background, ROOT.RooCmdArg(),
                                 RooFit.Rename("background"))
            getattr(w, 'import')(background2, ROOT.RooCmdArg(),
                                 RooFit.Rename("background2"))
            getattr(w, 'import')(background3, ROOT.RooCmdArg(),
                                 RooFit.Rename("background3"))
            getattr(w, 'import')(background4, ROOT.RooCmdArg(),
                                 RooFit.Rename("background4"))
            getattr(w, 'import')(background5, ROOT.RooCmdArg(),
                                 RooFit.Rename("background5"))
            getattr(w, 'import')(background_norm, ROOT.RooCmdArg(),
                                 RooFit.Rename("background_norm"))
            getattr(w, 'import')(background2_norm, ROOT.RooCmdArg(),
                                 RooFit.Rename("background2_norm"))
            getattr(w, 'import')(background3_norm, ROOT.RooCmdArg(),
                                 RooFit.Rename("background3_norm"))
            getattr(w, 'import')(background4_norm, ROOT.RooCmdArg(),
                                 RooFit.Rename("background4_norm"))
            getattr(w, 'import')(background5_norm, ROOT.RooCmdArg(),
                                 RooFit.Rename("background5_norm"))

        getattr(w, 'import')(res)
        getattr(w, 'import')(res2)
        getattr(w, 'import')(res3)
        getattr(w, 'import')(res4)
        getattr(w, 'import')(res5)
        getattr(w, 'import')(background_norm, ROOT.RooCmdArg())
        getattr(w, 'import')(signal_norm, ROOT.RooCmdArg())
        getattr(w, 'import')(rooDataHist, RooFit.Rename("data_obs"))
        w.Print()
        w.writeToFile(os.path.join(args.output_path, wsName))

        beffUnc = 0.3
        boffUnc = 0.06

        datacard = open(os.path.join(args.output_path, dcName), 'w')
        datacard.write('imax 1\n')
        datacard.write('jmax 1\n')
        datacard.write('kmax *\n')
        datacard.write('---------------\n')
        if args.jesUnc != None or args.jerUnc != None:
            datacard.write('shapes * * ' + wsName +
                           ' w:$PROCESS w:$PROCESS__$SYSTEMATIC\n')
        else:
            datacard.write('shapes * * ' + wsName + ' w:$PROCESS\n')
        datacard.write('---------------\n')
        datacard.write('bin 1\n')
        datacard.write('observation -1\n')
        datacard.write('------------------------------\n')
        datacard.write('bin          1          1\n')
        datacard.write('process      signal     background\n')
        datacard.write('process      0          1\n')
        datacard.write('rate         -1         1\n')
        datacard.write('------------------------------\n')
        datacard.write('lumi  lnN    %f         -\n' % (1. + args.lumiUnc))
        datacard.write('beff  lnN    %f         -\n' % (1. + beffUnc))
        datacard.write('boff  lnN    %f         -\n' % (1. + boffUnc))
        datacard.write('bkg   lnN     -         1.03\n')
        if args.jesUnc != None:
            datacard.write('JES  shape   1          -\n')
        if args.jerUnc != None:
            datacard.write('JER  shape   1          -\n')
        # flat parameters --- flat prior
        datacard.write('background_norm  flatParam\n')
        if args.decoBkg:
            datacard.write('deco_eig1  flatParam\n')
            datacard.write('deco_eig2  flatParam\n')
            if not args.fixP3: datacard.write('deco_eig3  flatParam\n')
        else:
            datacard.write('p1  flatParam\n')
            datacard.write('p2  flatParam\n')
            if not args.fixP3: datacard.write('p3  flatParam\n')
        datacard.close()

    print '>> Datacards and workspaces created and stored in %s/' % (
        os.path.join(os.getcwd(), args.output_path))
Пример #7
0
def DataFit(free=True, sim=True):

    w = RooWorkspace('w_data', 'w_data')

    samples = ['b0g', 'b0pi0', 'bsg', 'bspi0']

    # create the category
    w.factory('cat[%s]' % (','.join(samples)))

    files = {
        'b0g': path + "B0gamma/9_B2DstKpi_Dst2DgammTuple_BestCut.root",
        'b0pi0': path + "B0pi0/9_B2Dstpi0Tuple_BestCut.root",
        'bsg': path + "Bsgamma/9_Bs2DstKpi_Dst2DgammaTuple_BestCut.root",
        'bspi0': path + "Bspi0/9_Bs2Dstpi0Tuple_BestCut.root"
    }

    # Make the dsets
    w.factory("B_DTFDict_D0_B_M[5100,5900]")
    w.var("B_DTFDict_D0_B_M").setBins(80)
    for samp in samples:
        assert (os.path.exists(files[samp]))
        tf = TFile(files[samp])
        t = tf.Get('DecayTree')
        t.SetBranchStatus("*", 0)
        t.SetBranchStatus("B_DTFDict_D0_B_M", 1)
        dset = RooDataSet("data_%s" % (samp), "", t,
                          RooArgSet(w.var("B_DTFDict_D0_B_M")))
        getattr(w, 'import')(dset)
        tf.Close()

    # Make the total pdf

    # First try and merge the different bits from the different workspaces
    ImportMCShapes(w)

    # Then make combinatorial shape in each cateogry
    # let these be independent for now
    for samp in samples:
        w.factory("comb_mc_%s_p0[-0.001,-0.1,0.]" % samp)
        w.factory(
            "Exponential::comb_mc_pdf_%s( B_DTFDict_D0_B_M, comb_mc_%s_p0 )" %
            (samp, samp))
        w.factory("%s_comb_y[3000,0,12000]" % samp)

    # Now need to figure out what yields to restrict

    # sig yield first (require b0 / bs ratio consistent between g and pi0)
    w.factory("b0g_sig_y[3000,0,12000]")
    w.factory("b0pi0_sig_y[800,0,4000]")
    w.factory("bs2b0_rat[2.5,1.,4.]")
    w.factory("prod::bsg_sig_y(b0g_sig_y, bs2b0_rat)")
    w.factory("prod::bspi0_sig_y(b0pi0_sig_y, bs2b0_rat)")

    # now mis rec yield (ratio of this to sig should be the same for b0 and bs but will be different for g vs pi0)
    w.factory("misrec_to_sig_rat_g[0.2,0.001,0.6]")
    w.factory("misrec_to_sig_rat_pi0[0.2,0.001,0.6]")
    w.factory("prod::b0g_misrec_y( misrec_to_sig_rat_g, b0g_sig_y )")
    w.factory("prod::b0pi0_misrec_y( misrec_to_sig_rat_pi0, b0pi0_sig_y )")
    w.factory("prod::bsg_misrec_y( misrec_to_sig_rat_g, bsg_sig_y )")
    w.factory("prod::bspi0_misrec_y( misrec_to_sig_rat_pi0, bspi0_sig_y )")

    # the cases of B->D*pipi, B->D*KK, Lb->D*ph all involve a misID so will
    # be different for B0 and Bs (as they differ with a K or pi misID) however
    # for all of these the ratio of g -> pi0 should be the same
    # there is also Bs->D*KK which should scale the same for g and pi0 modes
    w.factory("misid_g2pi0_rat[0.1,0.0001,10.]")
    w.factory("b0g_bdstpp_y[1000,0,12000]")
    w.factory("bsg_bdstpp_y[1000,0,12000]")
    w.factory("prod::b0pi0_bdstpp_y( misid_g2pi0_rat, b0g_bdstpp_y )")
    w.factory("prod::bspi0_bdstpp_y( misid_g2pi0_rat, bsg_bdstpp_y )")
    w.factory("b0g_bdstkk_y[1000,0,12000]")
    w.factory("bsg_bdstkk_y[1000,0,12000]")
    w.factory("prod::b0pi0_bdstkk_y( misid_g2pi0_rat, b0g_bdstkk_y )")
    w.factory("prod::bspi0_bdstkk_y( misid_g2pi0_rat, bsg_bdstkk_y )")
    w.factory("b0g_lbdstph_y[1000,0,12000]")
    w.factory("bsg_lbdstph_y[1000,0,12000]")
    w.factory("prod::b0pi0_lbdstph_y( misid_g2pi0_rat, b0g_lbdstph_y )")
    w.factory("prod::bspi0_lbdstph_y( misid_g2pi0_rat, bsg_lbdstph_y )")
    w.factory("bsdstkk_to_bdstkk_rat[1.,0.1,2.]")
    w.factory("prod::b0g_bsdstkk_y( bsdstkk_to_bdstkk_rat, b0g_bdstkk_y )")
    w.factory("prod::b0pi0_bsdstkk_y( bsdstkk_to_bdstkk_rat, b0pi0_bdstkk_y )")
    w.factory("prod::bsg_bsdstkk_y( bsdstkk_to_bdstkk_rat, bsg_bdstkk_y )")
    w.factory("prod::bspi0_bsdstkk_y( bsdstkk_to_bdstkk_rat, bspi0_bdstkk_y )")

    # B -> DKpi same logic as misrec
    w.factory("bdkp_to_sig_rat_g[0.2,0.001,0.6]")
    w.factory("bdkp_to_sig_rat_pi0[0.2,0.001,0.6]")
    w.factory("prod::b0g_bdkp_y( bdkp_to_sig_rat_g, b0g_sig_y )")
    w.factory("prod::b0pi0_bdkp_y( bdkp_to_sig_rat_pi0, b0pi0_sig_y )")
    w.factory("prod::bsg_bdkp_y( bdkp_to_sig_rat_g, bsg_sig_y )")
    w.factory("prod::bspi0_bdkp_y( bdkp_to_sig_rat_pi0, bspi0_sig_y )")

    # B -> D* K / B -> D* pi (adding random pi- to B0 and random K- to Bs0)
    # so ratio to signal should be same for both g and pi0 modes but
    # different for B0 -> Bs
    w.factory("bdsth_to_sig_rat_addpi[0.2,0.001,0.6]")
    w.factory("bdsth_to_sig_rat_addk[0.2,0.001,0.6]")
    w.factory("prod::b0g_bdsth_y( bdsth_to_sig_rat_addpi, b0g_sig_y )")
    w.factory("prod::b0pi0_bdsth_y( bdsth_to_sig_rat_addpi, b0pi0_sig_y )")
    w.factory("prod::bsg_bdsth_y( bdsth_to_sig_rat_addk, bsg_sig_y )")
    w.factory("prod::bspi0_bdsth_y( bdsth_to_sig_rat_addk, bspi0_sig_y )")

    # Lb -> Dph (mid-ID k for p and pi for p and add random g or pi0) so will be different for all 4 really
    # express this ratio to the Lb -> D*ph one (they should be similar in magnitude?)
    w.factory("lbdph_to_lbdstph_b0g[1.,0.5,2.]")
    w.factory("lbdph_to_lbdstph_b0pi0[1.,0.5,2.]")
    w.factory("lbdph_to_lbdstph_bsg[1.,0.5,2.]")
    w.factory("lbdph_to_lbdstph_bspi0[1.,0.5,2.]")
    w.factory("prod::b0g_lbdph_y( lbdph_to_lbdstph_b0g, b0g_lbdstph_y )")
    w.factory("prod::b0pi0_lbdph_y( lbdph_to_lbdstph_b0pi0, b0pi0_lbdstph_y )")
    w.factory("prod::bsg_lbdph_y( lbdph_to_lbdstph_bsg, bsg_lbdstph_y )")
    w.factory("prod::bspi0_lbdph_y( lbdph_to_lbdstph_bspi0, bspi0_lbdstph_y )")

    # Part reco shape should have same Bs / B0 ratio
    w.factory("partrec_to_sig_rat_g[0.2,0.001,0.6]")
    w.factory("partrec_to_sig_rat_pi0[0.2,0.001,0.6]")
    w.factory("prod::b0g_partrec_y( partrec_to_sig_rat_g, b0g_sig_y )")
    w.factory("prod::b0pi0_partrec_y( partrec_to_sig_rat_pi0, b0pi0_sig_y )")
    w.factory("prod::bsg_partrec_y( partrec_to_sig_rat_g, bsg_sig_y )")
    w.factory("prod::bspi0_partrec_y( partrec_to_sig_rat_pi0, bspi0_sig_y )")

    components = [
        'sig', 'misrec', 'bdstpp', 'bdstkk', 'bsdstkk', 'bdkp', 'bdsth',
        'partrec', 'lbdph', 'lbdstph', 'comb'
    ]

    for samp in samples:
        fact_str = "SUM::data_pdf_%s(" % samp
        for comp in components:
            fact_str += "%s_%s_y*%s_mc_pdf_%s," % (samp, comp, comp, samp)
        fact_str = fact_str[:-1] + ")"
        w.factory(fact_str)
        w.pdf('data_pdf_%s' % samp).Print('v')

    CreateSimPdf(w, 'data')
    CreateSimData(w, 'data')

    # Now fix appropriate parameters
    # To start with we'll fix all shape parameters from MC and just float the yields (and exponential slope)
    for comp in components:
        if comp == 'comb': continue  # no pre-defined shape for combinatorial
        if comp == 'bsdstkk':
            continue  # this params for this piece are covered by bdstkk
        w.set('%s_mc_sim_pdf_pars' % comp).setAttribAll("Constant")

    # Now relax the constraints on a few important params
    w.var("b0g_mean").setConstant(False)
    w.var("b0g_sigma").setConstant(False)
    #w.var("dm_b02bs").setConstant(False)
    #w.var("dm_g2pi0").setConstant(False)
    #w.var("ssig_b02bs").setConstant(False)
    #w.var("ssig_g2pi0").setConstant(False)

    #w.var("b0g_misrec_mean").setConstant(False)
    #w.var("b0g_misrec_sigma").setConstant(False)
    #w.var("dm_missg2addg").setConstant(False)
    #w.var("ssig_missg2addg").setConstant(False)

    w.Print('v')
    w.pdf('data_sim_pdf').Print('v')
    w.data('data_sim_data').Print('v')

    # free fit first
    if free:
        for i, samp in enumerate(samples):
            pdfname = 'data_pdf_%s' % (samp)
            dsetname = 'data_%s' % (samp)
            w.pdf(pdfname).fitTo(
                w.data(dsetname))  # nothing to fit in this case
            pars = w.pdf(pdfname).getParameters(
                RooArgSet(w.var("B_DTFDict_D0_B_M")))
            w.saveSnapshot('data_free_fit_%s' % samp, pars)

    if sim:
        pdfname = 'data_sim_pdf'
        dsetname = 'data_sim_data'
        w.pdf(pdfname).fitTo(w.data(dsetname))
        pars = w.pdf(pdfname).getParameters(
            RooArgSet(w.var("B_DTFDict_D0_B_M")))
        w.saveSnapshot('data_sim_fit', pars)

    w.writeToFile('files/w_data.root')
    # dataHist.Print()
    # dataHist.Draw('colz')
    # gPad.Update()
    # gPad.WaitPrimitive()

    theWS = RooWorkspace()
    theWS.factory('%s[%f,%f]' %
                  (params.var[0], params.varRanges[params.var[0]][1],
                   params.varRanges[params.var[0]][2]))
    theWS.factory('%s[%f,%f]' %
                  (params.var[1], params.varRanges[params.var[1]][1],
                   params.varRanges[params.var[1]][2]))
    theWS.defineSet('obsSet', ','.join(params.var))

    #theWS.Print()
    # utils.Hist2Pdf(dataHist, "H250SignalHist", theWS)
    #theWS.Print()

    # dataset = utils.File2Dataset(params.MCDirectory + \
    #                                  'RD_mu_HWWMH250_CMSSW525_private.root',
    #                              "H250SignalData", theWS)
    # dataset.Print()

    print

    for model in range(10):
        utils.analyticPdf(theWS, params.var[0], model, 'pdf_%i' % model,
                          '%i_%s' % (model, params.var[0]))

    theWS.Print()
Пример #9
0
class MjjFit:
	def __init__(self, mass_range=[0., 2000.]):
		self.data_histogram_ = None
		self.data_roohistogram_ = None
		self.luminosity_ = 0.
		self.collision_energy_ = 8000.
		self.signal_histograms_ = {}
		self.signal_roohistograms_ = {}
		self.signal_names_ = []

		# Fit storage
		self.simple_fit_ = None
		self.mjj_ = RooRealVar('mjj','mjj',float(mass_range[0]),float(mass_range[1]))
		self.workspace_ = None

	def add_data(self, data_histogram):
		print "[MjFit.add_data] INFO : Adding data histogram"
		# Add a data histogram
		self.data_histogram_ = data_histogram.Clone()
		self.data_histogram_.SetDirectory(0)		
		self.data_roohistogram_ = RooDataHist('data_roohistogram','data_roohistogram',RooArgList(self.mjj_),self.data_histogram_)
		self.data_roohistogram_.Print()

	def add_signal(self, signal_name, signal_histogram):
		print "[MjjFit.add_signal] INFO : Adding signal histogram " + signal_name
		# Add a signal histogram. 
		# Scale to sigma=1 (in whatever units the data luminosity is given in), so the 'r' parameter corresponds to the limit on the cross section.
		if self.luminosity_ == 0:
			print "[MjjFit.add_signal] ERROR : Please set luminosity first (MjjFit.set_luminosity(###))."
			sys.exit(1)
		self.signal_names_.append(signal_name)
		self.signal_histograms_[signal_name] = signal_histogram.Clone()
		self.signal_histograms_[signal_name].SetDirectory(0)
		self.signal_histograms_[signal_name].Scale(1. * self.luminosity_ / self.signal_histograms_[signal_name].Integral())
		self.signal_roohistograms_[signal_name] = RooDataHist(signal_histogram.GetName() + "_rdh", signal_histogram.GetName() + "_rdh", RooArgList(self.mjj_), signal_histograms[signal_name])
		self.signal_roohistograms_[signal_name].Print()

	def simple_fit_B(self, fit_range=None):
		# Run a simple ROOT fit (B only)
		# - No S+B equivalent. This is done with RooFit.
		if fit_range:
			fit_min = fit_range[0]
			fit_max = fit_range[1]
		else:
			fit_min = data_histogram.GetXaxis().GetXmin()
			fit_max = data_histogram.GetXaxis().GetXmax()
		fit = TF1(data_histogram.GetName() + "_fit_B", BackgroundFit, fit_min, fit_max, 4)
		fit.SetParameter(0, 2.e-4)
		fit.SetParameter(1, 3)
		fit.SetParameter(2, 10)
		fit.SetParameter(3, 1)
		fit.SetParLimits(0, 1.e-6, 1.e2)
		fit.SetParLimits(1, -25., 25.)
		fit.SetParLimits(2, -25., 25.)
		fit.SetParLimits(3, -5., 5.)
		data_histogram.Fit(fit, "ER0I")
		fit_ratio = self.make_fit_pull_histogram(data_histogram, fit)
		print "Fit chi2/ndf = " + str(fit.GetChisquare()) + " / " + str(fit.GetNDF()) + " = " + str(fit.GetChisquare() / fit.GetNDF())
		self.simple_fit_ = {"fit":fit, "fit_ratio":fit_ratio}
		return self.simple_fit_

	def make_fit_pull_histogram(self, hist, fit):
		#print "Fit xmin = " + str(fit.GetXmin())
		hist_ratio = hist.Clone()
		hist_ratio.SetName(hist.GetName() + "_fit_ratio")
		for bin in xrange(1, hist_ratio.GetNbinsX() + 1):
			xmin = hist_ratio.GetXaxis().GetBinLowEdge(bin)
			xmax = hist_ratio.GetXaxis().GetBinUpEdge(bin)
			if xmax < fit.GetXmin() or xmin > fit.GetXmax():
				hist_ratio.SetBinContent(bin, 0.)
				hist_ratio.SetBinError(bin, 0.)
				continue
			fit_integral = fit.Integral(xmin, xmax)
			if hist.GetBinError(bin) > 0:
				hist_ratio.SetBinContent(bin, (hist.GetBinContent(bin) * hist.GetBinWidth(bin) - fit_integral) / (hist.GetBinError(bin) * hist.GetBinWidth(bin)))
				hist_ratio.SetBinError(bin, 0.)
			else:
				hist_ratio.SetBinContent(bin, 0.)
				hist_ratio.SetBinError(bin, 0.)
		return hist_ratio
		 
	def fit(self, save_to, signal_name=None, fix_p3=False, fit_range=[300., 1200.], fit_strategy=1):
		# Run a RooFit fit

		# Create background PDF
		p1 = RooRealVar('p1','p1',args.p1,0.,100.)
		p2 = RooRealVar('p2','p2',args.p2,0.,60.)
		p3 = RooRealVar('p3','p3',args.p3,-10.,10.)
		if args.fix_p3:
			p3.setConstant()
		background_pdf = RooGenericPdf('background_pdf','(pow(1-@0/%.1f,@1)/pow(@0/%.1f,@2+@3*log(@0/%.1f)))'%(self.collision_energy,self.collision_energy,self.collision_energy),RooArgList(self.mjj_,p1,p2,p3))
		background_pdf.Print()
		data_integral = data_histogram.Integral(data_histogram.GetXaxis().FindBin(float(fit_range[0])),data_histogram.GetXaxis().FindBin(float(fit_range[1])))
		background_norm = RooRealVar('background_norm','background_norm',data_integral,0.,1e+08)
		background_norm.Print()

		# Create signal PDF and fit model
		if signal_name:
			signal_pdf = RooHistPdf('signal_pdf', 'signal_pdf', RooArgSet(self.mjj_), self.signal_roohistograms_[signal_name])
			signal_pdf.Print()
			signal_norm = RooRealVar('signal_norm','signal_norm',0,-1e+05,1e+05)
			signal_norm.Print()
			model = RooAddPdf("model","s+b",RooArgList(background_pdf,signal_pdf),RooArgList(background_norm,signal_norm))
		else:
			model = RooAddPdf("model","b",RooArgList(background_pdf),RooArgList(background_norm))

		# Run fit
		res = model.fitTo(data_, RooFit.Save(kTRUE), RooFit.Strategy(fit_strategy))

		# Save to workspace
		self.workspace_ = RooWorkspace('w','workspace')
		#getattr(w,'import')(background,ROOT.RooCmdArg())
		getattr(self.workspace_,'import')(background_pdf,RooFit.Rename("background"))
		getattr(self.workspace_,'import')(background_norm,ROOT.RooCmdArg())
		getattr(self.workspace_,'import')(self.data_roohistogram_,RooFit.Rename("data_obs"))
		getattr(self.workspace_, 'import')(model, RooFit.Rename("model"))
		if signal_name:
			getattr(self.workspace_,'import')(signal_roohistogram,RooFit.Rename("signal"))
			getattr(self.workspace_,'import')(signal_pdf,RooFit.Rename("signal_pdf"))
			getattr(self.workspace_,'import')(signal_norm,ROOT.RooCmdArg())
	
		self.workspace_.Print()
		self.workspace_.writeToFile(save_to)
		if signal_name:
			roofit_results[signal_name] = save_to
		else:
			roofit_results["background"] = save_to

	# fitted_signal_shapes = list of fitted S(+B) shapes to plot.
	# expected_signal_shapes = list of S shapes to plot, scaled to cross sections taken from configuration file
	def plot(self, save_tag, fitted_signal_shapes=None, expected_signal_shapes=None, log=False, x_range=None):
		c = TCanvas("c_" + save_tag, "c_" + save_tag, 800, 1600)
		l = TLegend(0.55, 0.6, 0.88, 0.88)
		l.SetFillColor(0)
		l.SetBorderSize(0)
		top = TPad("top", "top", 0., 0.5, 1., 1.)
		top.SetBottomMargin(0.03)
		top.Draw()
		if log:
			top.SetLogy()
		c.cd()
		bottom = TPad("bottom", "bottom", 0., 0., 1., 0.5)
		bottom.SetTopMargin(0.02)
		bottom.SetBottomMargin(0.2)
		bottom.Draw()
		ROOT.SetOwnership(c, False)
		ROOT.SetOwnership(top, False)
		ROOT.SetOwnership(bottom, False)
		top.cd()

		# Frame from background fit
		if not roofit_results.has_key("background"):
			print "[MjjFit.plot] ERROR : Please run background-only fit before plotting (e.g. MjjFit.plot(\"bkgd_file.root\"))"
		f_background = TFile(roofit_results["background"], "READ")
		w_background = f_background.Get("w")
		data_rdh = w_background.data("data_obs")
		if x_range:
			x_min = x_range[0]
			x_max = x_range[1]
		else:
			x_min = self.mjj_.GetMin()
			x_max = self.mjj_.GetMax()
		frame_top = self.mjj_.frame(x_min, x_max)
		frame_top.GetYaxis().SetTitle("Events / " + str(int(data_histogram.GetXaxis().GetBinWidth(1))) + " GeV")
		frame_top.GetXaxis().SetTitleSize(0)
		frame_top.GetXaxis().SetLabelSize(0)
		#if log:
		#	frame_top.SetMaximum(y_max * 10.)
		#	frame_top.SetMinimum(y_min / 100.)
		#else:
		#	frame_top.SetMaximum(y_max * 1.3)
		#	frame_top.SetMinimum(0.)
		frame_top.Draw()
		data_rdh.plotOn(frame_top, RooFit.Name("Data"))
		l.AddEntry(frame_top.findObject("Data"), "Data", "pl")
		background_pdf = w_background.pdf("background")
		background_pdf.plotOn(frame_top, RooFit.Name("Background Fit"), RooFit.LineColor(seaborn.GetColorRoot("default", 0)), RooFit.LineStyle(1), RooFit.LineWidth(2))

		style_counter = 1
		if fitted_signal_shapes:
			for signal_name in fitted_signal_shapes:
				# Load from workspace
				if not roofit_results.has_key(signal_name):
					print "[MjjFit.plot] ERROR : Signal name " + signal_name + " does not exist in roofit_results. Did you run the fit first?"
					sys.exit(1)
				f_in = TFile(roofit_results[signal_name], "READ")
				w = f_in.Get("workspace")
				fit_pdf = w.pdf("model")
				fit_pdf_name = "Fit (" + signal_name + ")"
				fit_pdf.SetName(fit_pdf_name)
				fit_pdf.plotOn(frame_top, RooFit.Name(fit_pdf_name), RooFit.LineColor(seaborn.GetColorRoot("default", style_counter)), RooFit.LineStyle(1), RooFit.LineWidth(2))
				l.AddEntry(frame_top.findObject(signal_name), signal_name, "l")
				style_counter += 1
				f_in.Close()
		if expected_signal_shapes:
			for signal_name in expected_signal_shapes:
				self.signal_roohistograms_[signal_name].plotOn(frame_top, RooFit.Name(signal_name), RooFit.Rescale(cross_section * self.luminosity_ / self.signal_roohistograms_[signal_name].sum()), RooFit.LineColor(seaborn.GetColorRoot("pastel", style_counter)), RooFit.LineStyle(2), RooFit.LineWidth(2))
				l.AddEntry(frame_top.findObject(signal_name), signal_name, "l")
				style_counter += 1
		frame_top.Draw()
		l.Draw()
		
		# Pull histogram
		c.cd()
		bottom.cd()
		pull_histogram = frame_top.pullHist("Data", "Background Fit")
		frame_bottom = self.mjj_.frame(x_min, x_max)
		pull_histogram.plotOn(frame_bottom, RooFit.Name(fit_pdf_name))
		frame_bottom.GetXaxis().SetTitle("m_{jj} [GeV]")
		frame_bottom.GetYaxis().SetTitle("#frac{Data - Fit}{#sigma(Fit)}")
		frame_bottom.Draw()
		c.cd()

		c.SaveAs("/uscms/home/dryu/Dijets/data/EightTeeEeVeeBee/Results/figures/c_" + save_tag + ".pdf")
Пример #10
0
def shapeCards( process, isData, datahistosFile, histosFile, signalHistosFile, signalSample, hist, signalMass, minMass, maxMass, jesValue, jerValue, lumiUnc, outputName ):
	"""function to run Roofit and save workspace for RooStats"""
	warnings.filterwarnings( action='ignore', category=RuntimeWarning, message='.*class stack<RooAbsArg\*,deque<RooAbsArg\*> >' )
	
	hSignal = signalHistosFile.Get(hist+'_'+signalSample)
	hSignal.Rebin(10)
	htmpSignal = hSignal.Clone()
	#htmpSignal.Scale(100)
	signalXS = search(dictXS, 'RPVStopStopToJets_UDD312_M-'+str(signalMass) )
	#hSignal.Scale( lumi*signalXS / hSignal.Integral())

	massAve = RooRealVar( 'massAve', 'massAve', minMass, maxMass  )
	rooSigHist = RooDataHist( 'rooSigHist', 'rooSigHist', RooArgList(massAve), hSignal )
	rooSigHist.Print()

	signal = RooHistPdf('signal','signal',RooArgSet(massAve),rooSigHist)
        signal.Print()
        signal_norm = RooRealVar('signal_norm','signal_norm',0,-1e+04,1e+04)
        #if args.fitBonly: signal_norm.setConstant()
        signal_norm.Print()

	hBkg = datahistosFile.Get('massAve_prunedMassAsymVsdeltaEtaDijet_DATA_ABCDProj')
	#hBkg = histosFile.Get(hist+'_QCDPtAll_BCD')
	bkgAcc = round(hBkg.Integral( hBkg.GetXaxis().FindBin( minMass ), hBkg.GetXaxis().FindBin( maxMass )))
	#hBkg.Scale(1/hBkg.Integral())
	hPseudo = hBkg.Clone()
	hPseudo.Reset()
        #background_norm = RooRealVar('background_norm','background_norm',bkgAcc,0.,1e+07)
        background_norm = RooRealVar('background_norm','background_norm',1.,0.,1e+07)
        background_norm.Print()

	if 'template' in process:
		rooBkgHist = RooDataHist( 'rooBkgHist', 'rooBkgHist', RooArgList(massAve), hBkg )
		rooBkgHist.Print()
		background = RooHistPdf('background','background',RooArgSet(massAve),rooBkgHist)
		background.Print()

	else:
		p1 = RooRealVar('p1','p1', 1 ,0.,100.)
		p2 = RooRealVar('p2','p2', 1 ,0.,60.)
		p3 = RooRealVar('p3','p3', 1 , -10.,10.)

		background = RooGenericPdf('background','(pow(1-@0/%.1f,@1)/pow(@0/%.1f,@2+@3*log(@0/%.1f)))'%(1300,1300,1300),RooArgList(massAve,p1,p2,p3))
		background.Print()
		### S+B model

	if not isData:
		newNumEvents = random.randint( bkgAcc-round(TMath.Sqrt(bkgAcc)), bkgAcc+round(TMath.Sqrt(bkgAcc)) )
		print 'Events in MC:', bkgAcc, ', in PseudoExperiment:', newNumEvents
		hPseudo.FillRandom( hBkg, newNumEvents ) 
		#hPseudo.Scale(1/hPseudo.Integral())

	#hData = histosFile.Get('massAve_prunedMassAsymVsdeltaEtaDijet_ABCDProj')
	hData = datahistosFile.Get('massAve_prunedMassAsymVsdeltaEtaDijet_DATA_ABCDProj')
	#hData = histosFile.Get(hist+'_QCDPtAll_A')
	#hData.Add(htmpSignal)
	#hData.Scale(1/hData.Integral())
        rooDataHist = RooDataHist('rooDatahist','rooDatahist',RooArgList(massAve), hData if isData else hPseudo )
        rooDataHist.Print()

	#model = RooAddPdf("model","s+b",RooArgList(background,signal),RooArgList(background_norm,signal_norm))
	#res = model.fitTo(rooDataHist, RooFit.Save(kTRUE), RooFit.Strategy(0))
	#res.Print()

	############# JES and JER uncertainties
        hSigSyst = {}
        hSigSystDataHist = {}
        signalCDF = TGraph(hSignal.GetNbinsX()+1)

        # JES and JER uncertainties
	if args.jesUnc or args.jerUnc:
		signalCDF.SetPoint(0,0.,0.)
		integral = 0.
		for i in range(1, hSignal.GetNbinsX()+1):
			x = hSignal.GetXaxis().GetBinLowEdge(i+1)
			integral = integral + hSignal.GetBinContent(i)
			signalCDF.SetPoint(i,x,integral)

		if args.jesUnc:
			print ' |---> Adding JES'
			hSigSyst['JESUp'] = hSignal.Clone()
			hSigSyst['JESDown'] = hSignal.Clone()

		if args.jerUnc:
			print ' |---> Adding JER'
			hSigSyst['JERUp'] = hSignal.Clone()
			hSigSyst['JERDown'] = hSignal.Clone()

        # reset signal histograms
        for key in hSigSyst:
		hSigSyst[key].Reset()
		hSigSyst[key].SetName(hSigSyst[key].GetName() + '_' + key)

        # produce JES signal shapes
        if args.jesUnc:
		for q in range(1, hSignal.GetNbinsX()+1):
			xLow = hSignal.GetXaxis().GetBinLowEdge(q)
			xUp = hSignal.GetXaxis().GetBinLowEdge(q+1)
			jes = 1. - jesValue
			xLowPrime = jes*xLow
			xUpPrime = jes*xUp
			hSigSyst['JESUp'].SetBinContent(q, signalCDF.Eval(xUpPrime) - signalCDF.Eval(xLowPrime))
			jes = 1. + jesValue
			xLowPrime = jes*xLow
			xUpPrime = jes*xUp
			hSigSyst['JESDown'].SetBinContent(q, signalCDF.Eval(xUpPrime) - signalCDF.Eval(xLowPrime))
		hSigSystDataHist['JESUp'] = RooDataHist('hSignalJESUp','hSignalJESUp',RooArgList(massAve),hSigSyst['JESUp'])
		hSigSystDataHist['JESDown'] = RooDataHist('hSignalJESDown','hSignalJESDown',RooArgList(massAve),hSigSyst['JESDown'])

        # produce JER signal shapes
	if args.jerUnc:
		for i in range(1, hSignal.GetNbinsX()+1):
			xLow = hSignal.GetXaxis().GetBinLowEdge(i)
			xUp = hSignal.GetXaxis().GetBinLowEdge(i+1)
			jer = 1. - jerValue
			xLowPrime = jer*(xLow-float(signalMass))+float(signalMass)
			xUpPrime = jer*(xUp-float(signalMass))+float(signalMass)
			hSigSyst['JERUp'].SetBinContent(i, signalCDF.Eval(xUpPrime) - signalCDF.Eval(xLowPrime))
			jer = 1. + jerValue
			xLowPrime = jer*(xLow-float(signalMass))+float(signalMass)
			xUpPrime = jer*(xUp-float(signalMass))+float(signalMass)
			hSigSyst['JERDown'].SetBinContent(i, signalCDF.Eval(xUpPrime) - signalCDF.Eval(xLowPrime))
		hSigSystDataHist['JERUp'] = RooDataHist('hSignalJERUp','hSignalJERUp',RooArgList(massAve),hSigSyst['JERUp'])
		hSigSystDataHist['JERDown'] = RooDataHist('hSignalJERDown','hSignalJERDown',RooArgList(massAve),hSigSyst['JERDown'])

	myWS = RooWorkspace("myWS")
	getattr(myWS,'import')(rooSigHist,RooFit.Rename("signal"))
        getattr(myWS,'import')(rooBkgHist,RooFit.Rename("background"))
        #getattr(myWS,'import')(signal_norm)
        getattr(myWS,'import')(background_norm)
        if args.jesUnc:
		getattr(myWS,'import')(hSigSystDataHist['JESUp'],RooFit.Rename("signal__JESUp"))
		getattr(myWS,'import')(hSigSystDataHist['JESDown'],RooFit.Rename("signal__JESDown"))
        if args.jerUnc:
		getattr(myWS,'import')(hSigSystDataHist['JERUp'],RooFit.Rename("signal__JERUp"))
		getattr(myWS,'import')(hSigSystDataHist['JERDown'],RooFit.Rename("signal__JERDown"))
        getattr(myWS,'import')(rooDataHist,RooFit.Rename("data_obs"))
        myWS.Print()
	outputRootFile = currentDir+'/Rootfiles/workspace_'+outputName+'.root'
        myWS.writeToFile(outputRootFile, True)
	print ' |----> Workspace created in root file:\n', outputRootFile
 # -----------------------------------------
        # write a datacard

	dataCardName = currentDir+'/Datacards/datacard_'+outputName+'.txt'
        datacard = open( dataCardName ,'w')
        datacard.write('imax 1\n')
        datacard.write('jmax 1\n')
        datacard.write('kmax *\n')
        datacard.write('---------------\n')
        if args.jesUnc or args.jerUnc or args.lumiUnc or args.normUnc or args.unc: 
		datacard.write('shapes * * '+outputRootFile+' myWS:$PROCESS myWS:$PROCESS__$SYSTEMATIC\n')
	else: datacard.write("shapes * * "+outputRootFile+" myWS:$PROCESS \n")
        datacard.write('---------------\n')
        datacard.write('bin 1\n')
        datacard.write('observation -1\n')
        datacard.write('------------------------------\n')
        datacard.write('bin          1          1\n')
        datacard.write('process      signal     background\n')
        datacard.write('process      0          1\n')
        datacard.write('rate         -1         -1\n')
        datacard.write('------------------------------\n')
	if args.lumiUnc: datacard.write('lumi  lnN    %f         -\n'%(lumiUnc))
        if args.jesUnc: datacard.write('JES  shape   1          -\n')
	if args.jerUnc: datacard.write('JER  shape   1          -\n')
        #flat parameters --- flat prior
	if args.normUnc: datacard.write('background_norm  flatParam\n')
        #datacard.write('p1  flatParam\n')
        datacard.close()
	print ' |----> Datacard created:\n', dataCardName
Пример #11
0
def main():
    # usage description
    usage = "Example: ./scripts/createDatacards.py --inputData inputs/rawhistV7_Run2015D_scoutingPFHT_UNBLINDED_649_838_JEC_HLTplusV7_Mjj_cor_smooth.root --dataHistname mjj_mjjcor_gev --inputSig inputs/ResonanceShapes_gg_13TeV_Scouting_Spring15.root -f gg -o datacards -l 1866 --lumiUnc 0.027 --massrange 1000 1500 50 --runFit --p1 5 --p2 7 --p3 0.4 --massMin 838 --massMax 2037 --fitStrategy 2"

    # input parameters
    parser = ArgumentParser(
        description=
        'Script that creates combine datacards and corresponding RooFit workspaces',
        epilog=usage)
    parser.add_argument("analysis", type=str, help="Analysis name")
    parser.add_argument("model", type=str, help="Model (Hbb, RSG)")

    #parser.add_argument("--inputData", dest="inputData", required=True,
    #                    help="Input data spectrum",
    #                    metavar="INPUT_DATA")

    parser.add_argument("--dataHistname",
                        dest="dataHistname",
                        type=str,
                        default="h_data",
                        help="Data histogram name",
                        metavar="DATA_HISTNAME")

    #parser.add_argument("--inputSig", dest="inputSig", required=True,
    #                    help="Input signal shapes",
    #                    metavar="INPUT_SIGNAL")

    parser.add_argument("-f",
                        "--final_state",
                        dest="final_state",
                        default="qq",
                        help="Final state (e.g. qq, qg, gg)",
                        metavar="FINAL_STATE")
    parser.add_argument("--fit_functions",
                        dest="fit_functions",
                        default="f1,f2,f3,f4,f5",
                        help="List of fit functions")

    #parser.add_argument("-f2", "--type", dest="atype", required=True, help="Type (e.g. hG, lG, hR, lR)")

    parser.add_argument(
        "-o",
        "--output_path",
        dest="output_path",
        help=
        "Output path where datacards and workspaces will be stored. If not specified, this is derived from limit_configuration.",
        metavar="OUTPUT_PATH")

    parser.add_argument("--correctTrigger",
                        dest="correctTrigger",
                        action='store_true',
                        help="Include trigger correction in PDF")

    parser.add_argument(
        "-l",
        "--lumi",
        dest="lumi",
        default=19700.,
        type=float,
        help="Integrated luminosity in pb-1 (default: %(default).1f)",
        metavar="LUMI")

    parser.add_argument(
        "--massMin",
        dest="massMin",
        default=500,
        type=int,
        help=
        "Lower bound of the mass range used for fitting (default: %(default)s)",
        metavar="MASS_MIN")

    parser.add_argument(
        "--massMax",
        dest="massMax",
        default=1200,
        type=int,
        help=
        "Upper bound of the mass range used for fitting (default: %(default)s)",
        metavar="MASS_MAX")
    parser.add_argument(
        "--fitSignal",
        action="store_true",
        help=
        "Use signal fitted shapes (CB+Voigtian) instead of histogram templates"
    )
    #parser.add_argument("--lumiUnc", dest="lumiUnc",
    #                    required=True, type=float,
    #                    help="Relative uncertainty in the integrated luminosity",
    #                    metavar="LUMI_UNC")

    #parser.add_argument("--jesUnc", dest="jesUnc",
    #                    type=float,
    #                    help="Relative uncertainty in the jet energy scale",
    #                    metavar="JES_UNC")

    #parser.add_argument("--jerUnc", dest="jerUnc",
    #                    type=float,
    #                    help="Relative uncertainty in the jet energy resolution",
    #                    metavar="JER_UNC")

    parser.add_argument(
        "--sqrtS",
        dest="sqrtS",
        default=8000.,
        type=float,
        help="Collision center-of-mass energy (default: %(default).1f)",
        metavar="SQRTS")

    parser.add_argument("--fixP3",
                        dest="fixP3",
                        default=False,
                        action="store_true",
                        help="Fix the fit function p3 parameter")

    parser.add_argument("--runFit",
                        dest="runFit",
                        default=False,
                        action="store_true",
                        help="Run the fit")

    parser.add_argument("--fitBonly",
                        dest="fitBonly",
                        default=False,
                        action="store_true",
                        help="Run B-only fit")

    parser.add_argument("--fixBkg",
                        dest="fixBkg",
                        default=False,
                        action="store_true",
                        help="Fix all background parameters")

    parser.add_argument("--decoBkg",
                        dest="decoBkg",
                        default=False,
                        action="store_true",
                        help="Decorrelate background parameters")

    parser.add_argument("--fitStrategy",
                        dest="fitStrategy",
                        type=int,
                        default=1,
                        help="Fit strategy (default: %(default).1f)")

    parser.add_argument("--debug",
                        dest="debug",
                        default=False,
                        action="store_true",
                        help="Debug printout")

    parser.add_argument(
        "--postfix",
        dest="postfix",
        default='',
        help="Postfix for the output file names (default: %(default)s)")

    parser.add_argument("--pyes",
                        dest="pyes",
                        default=False,
                        action="store_true",
                        help="Make files for plots")

    parser.add_argument("--jyes",
                        dest="jyes",
                        default=False,
                        action="store_true",
                        help="Make files for JES/JER plots")

    parser.add_argument(
        "--pdir",
        dest="pdir",
        default='testarea',
        help="Name a directory for the plots (default: %(default)s)")

    parser.add_argument("--chi2",
                        dest="chi2",
                        default=False,
                        action="store_true",
                        help="Compute chi squared")

    parser.add_argument("--widefit",
                        dest="widefit",
                        default=False,
                        action="store_true",
                        help="Fit with wide bin hist")

    mass_group = parser.add_mutually_exclusive_group(required=True)
    mass_group.add_argument(
        "--mass",
        type=int,
        nargs='*',
        default=1000,
        help=
        "Mass can be specified as a single value or a whitespace separated list (default: %(default)i)"
    )
    mass_group.add_argument(
        "--massrange",
        type=int,
        nargs=3,
        help="Define a range of masses to be produced. Format: min max step",
        metavar=('MIN', 'MAX', 'STEP'))
    mass_group.add_argument("--masslist",
                            help="List containing mass information")

    args = parser.parse_args()

    fit_functions = args.fit_functions.split(",")

    # mass points for which resonance shapes will be produced
    masses = []

    if args.fitBonly:
        masses.append(750)
    else:
        if args.massrange != None:
            MIN, MAX, STEP = args.massrange
            masses = range(MIN, MAX + STEP, STEP)
        elif args.masslist != None:
            # A mass list was provided
            print "Will create mass list according to", args.masslist
            masslist = __import__(args.masslist.replace(".py", ""))
            masses = masslist.masses
        else:
            masses = args.mass

    # sort masses
    masses.sort()

    # import ROOT stuff
    from ROOT import gStyle, TFile, TH1F, TH1D, TGraph, kTRUE, kFALSE, TCanvas, TLegend, TPad, TLine
    from ROOT import RooHist, RooRealVar, RooDataHist, RooArgList, RooArgSet, RooAddPdf, RooProdPdf, RooEffProd, RooFit, RooGenericPdf, RooWorkspace, RooMsgService, RooHistPdf, RooExtendPdf

    if not args.debug:
        RooMsgService.instance().setSilentMode(kTRUE)
        RooMsgService.instance().setStreamStatus(0, kFALSE)
        RooMsgService.instance().setStreamStatus(1, kFALSE)

    # input data file
    #inputData = TFile(limit_config.get_data_input(args.analysis))
    # input data histogram
    #hData = inputData.Get(args.dataHistname)
    #hData.SetDirectory(0)
    data_file = TFile(
        analysis_config.get_b_histogram_filename(args.analysis,
                                                 "BJetPlusX_2012"))
    hData = data_file.Get("BHistograms/h_pfjet_mjj")
    hData.SetDirectory(0)

    # input sig file
    if not args.fitSignal:
        print "[create_datacards] INFO : Opening resonance shapes file at " + limit_config.get_resonance_shapes(
            args.analysis, args.model)
        inputSig = TFile(
            limit_config.get_resonance_shapes(args.analysis, args.model),
            "READ")

    sqrtS = args.sqrtS

    # mass variable
    mjj = RooRealVar('mjj', 'mjj', float(args.massMin), float(args.massMax))

    # integrated luminosity and signal cross section
    lumi = args.lumi
    signalCrossSection = 1.  # set to 1. so that the limit on r can be interpreted as a limit on the signal cross section

    if args.correctTrigger:
        trigger_efficiency_pdf = trigger_efficiency.get_pdf(args.analysis, mjj)
        trigger_efficiency_formula = trigger_efficiency.get_formula(
            args.analysis, mjj)
    else:
        trigger_efficiency_pdf = trigger_efficiency.get_trivial_pdf(mjj)
        trigger_efficiency_formula = trigger_efficiency.get_trivial_formula(
            mjj)

    for mass in masses:

        print ">> Creating datacard and workspace for %s resonance with m = %i GeV..." % (
            args.final_state, int(mass))

        rooDataHist = RooDataHist('rooDatahist', 'rooDathist', RooArgList(mjj),
                                  hData)

        if not args.fitSignal:
            hSig = inputSig.Get("h_" + args.final_state + "_" + str(int(mass)))
            if not hSig:
                raise Exception("Couldn't find histogram " + "h_" +
                                args.final_state + "_" + str(int(mass)) +
                                " in file " +
                                limit_config.get_resonance_shapes(
                                    args.analysis, args.model))
            # normalize signal shape to the expected event yield (works even if input shapes are not normalized to unity)
            hSig.Scale(
                signalCrossSection * lumi / hSig.Integral()
            )  # divide by a number that provides roughly an r value of 1-10
            rooSigHist = RooDataHist('rooSigHist', 'rooSigHist',
                                     RooArgList(mjj), hSig)
            print 'Signal acceptance:', (rooSigHist.sumEntries() /
                                         hSig.Integral())

        # If using fitted signal shapes, load the signal PDF
        if args.fitSignal:
            print "[create_datacards] Loading fitted signal PDFs from " + analysis_config.get_signal_fit_file(
                args.analysis,
                args.model,
                mass,
                "bukin",
                interpolated=(not mass
                              in analysis_config.simulation.simulated_masses))
            f_signal_pdfs = TFile(
                analysis_config.get_signal_fit_file(
                    args.analysis,
                    args.model,
                    mass,
                    "bukin",
                    interpolated=(
                        not mass
                        in analysis_config.simulation.simulated_masses)),
                "READ")
            w_signal = f_signal_pdfs.Get("w_signal")
            input_parameters = signal_fits.get_parameters(
                w_signal.pdf("signal"))

            # Make a new PDF with nuisance parameters
            signal_pdf_notrig, signal_vars = signal_fits.make_signal_pdf_systematic(
                "bukin", mjj, mass=mass)
            signal_pdf_name = signal_pdf_notrig.GetName()
            signal_pdf_notrig.SetName(signal_pdf_name + "_notrig")
            #signal_pdf = RooProdPdf(signal_pdf_name, signal_pdf_name, signal_pdf_notrig, trigger_efficiency_pdf)
            signal_pdf = RooEffProd(signal_pdf_name, signal_pdf_name,
                                    signal_pdf_notrig,
                                    trigger_efficiency_formula)

            # Copy input parameter values
            signal_vars["xp_0"].setVal(input_parameters["xp"][0])
            signal_vars["xp_0"].setError(input_parameters["xp"][1])
            signal_vars["xp_0"].setConstant()
            signal_vars["sigp_0"].setVal(input_parameters["sigp"][0])
            signal_vars["sigp_0"].setError(input_parameters["sigp"][1])
            signal_vars["sigp_0"].setConstant()
            signal_vars["xi_0"].setVal(input_parameters["xi"][0])
            signal_vars["xi_0"].setError(input_parameters["xi"][1])
            signal_vars["xi_0"].setConstant()
            signal_vars["rho1_0"].setVal(input_parameters["rho1"][0])
            signal_vars["rho1_0"].setError(input_parameters["rho1"][1])
            signal_vars["rho1_0"].setConstant()
            signal_vars["rho2_0"].setVal(input_parameters["rho2"][0])
            signal_vars["rho2_0"].setError(input_parameters["rho2"][1])
            signal_vars["rho2_0"].setConstant()
            f_signal_pdfs.Close()

        signal_parameters = {}
        signal_pdfs_notrig = {}
        signal_pdfs = {}
        signal_norms = {}
        background_pdfs = {}
        background_pdfs_notrig = {}
        background_parameters = {}
        background_norms = {}
        signal_epdfs = {}
        background_epdfs = {}
        models = {}
        fit_results = {}

        for fit_function in fit_functions:
            print "[create_datacards] INFO : On fit function {}".format(
                fit_function)

            if args.fitSignal:
                # Make a copy of the signal PDF, so that each fitTo call uses its own copy.
                # The copy should have all variables set constant.
                #signal_pdfs[fit_function], signal_parameters[fit_function] = signal_fits.copy_signal_pdf("bukin", signal_pdf, mjj, tag=fit_function, include_systematics=True)
                signal_pdfs_notrig[fit_function] = ROOT.RooBukinPdf(
                    signal_pdf_notrig,
                    signal_pdf_notrig.GetName() + "_" + fit_function)
                signal_pdfs[fit_function] = RooEffProd(
                    signal_pdf.GetName() + "_" + fit_function,
                    signal_pdf.GetName() + "_" + fit_function,
                    signal_pdfs_notrig[fit_function],
                    trigger_efficiency_formula)
                #signal_pdfs[fit_function] = RooProdPdf(signal_pdf.GetName() + "_" + fit_function, signal_pdf.GetName() + "_" + fit_function, signal_pdfs_notrig[fit_function], trigger_efficiency_pdf)
                iterator = signal_pdfs_notrig[fit_function].getVariables(
                ).createIterator()
                this_parameter = iterator.Next()
                while this_parameter:
                    this_parameter.setConstant()
                    this_parameter = iterator.Next()
            else:
                signal_pdfs[fit_function] = RooHistPdf(
                    'signal_' + fit_function, 'signal_' + fit_function,
                    RooArgSet(mjj), rooSigHist)
            signal_norms[fit_function] = RooRealVar(
                'signal_norm_' + fit_function, 'signal_norm_' + fit_function,
                0., 0., 1e+05)
            if args.fitBonly:
                signal_norms[fit_function].setConstant()
            background_pdfs_notrig[fit_function], background_parameters[
                fit_function] = make_background_pdf(fit_function,
                                                    mjj,
                                                    collision_energy=8000.)
            background_pdf_name = background_pdfs_notrig[fit_function].GetName(
            )
            background_pdfs_notrig[fit_function].SetName(background_pdf_name +
                                                         "_notrig")
            background_pdfs[fit_function] = RooEffProd(
                background_pdf_name, background_pdf_name,
                background_pdfs_notrig[fit_function],
                trigger_efficiency_formula)
            #background_pdfs[fit_function] = RooProdPdf(background_pdf_name, background_pdf_name, background_pdfs_notrig[fit_function], trigger_efficiency_pdf)
            #background_pdfs[fit_function] = background_pdfs_notrig[fit_function]
            #background_pdfs[fit_function].SetName(background_pdf_name)

            # Initial values
            if "trigbbh" in args.analysis:
                if fit_function == "f3":
                    background_parameters[fit_function]["p1"].setVal(55.)
                    background_parameters[fit_function]["p1"].setMin(20.)
                    background_parameters[fit_function]["p2"].setVal(8.)
                elif fit_function == "f4":
                    background_parameters[fit_function]["p1"].setVal(28.)
                    background_parameters[fit_function]["p2"].setVal(-22.)
                    background_parameters[fit_function]["p3"].setVal(10.)
            elif "trigbbl" in args.analysis:
                if fit_function == "f3":
                    background_parameters[fit_function]["p1"].setVal(82.)
                    background_parameters[fit_function]["p1"].setMin(60.)
                    background_parameters[fit_function]["p2"].setVal(8.)
                elif fit_function == "f4":
                    background_parameters[fit_function]["p1"].setVal(41.)
                    background_parameters[fit_function]["p2"].setVal(-45.)
                    background_parameters[fit_function]["p3"].setVal(10.)

            data_integral = hData.Integral(
                hData.GetXaxis().FindBin(float(args.massMin)),
                hData.GetXaxis().FindBin(float(args.massMax)))
            background_norms[fit_function] = RooRealVar(
                'background_' + fit_function + '_norm',
                'background_' + fit_function + '_norm', data_integral, 0.,
                1.e8)

            signal_epdfs[fit_function] = RooExtendPdf(
                'esignal_' + fit_function, 'esignal_' + fit_function,
                signal_pdfs[fit_function], signal_norms[fit_function])
            background_epdfs[fit_function] = RooExtendPdf(
                'ebackground_' + fit_function, 'ebackground_' + fit_function,
                background_pdfs[fit_function], background_norms[fit_function])

            models[fit_function] = RooAddPdf(
                'model_' + fit_function, 's+b',
                RooArgList(background_epdfs[fit_function],
                           signal_epdfs[fit_function]))

            if args.runFit:
                print "[create_datacards] INFO : Starting fit with function {}".format(
                    fit_function)
                fit_results[fit_function] = models[fit_function].fitTo(
                    rooDataHist, RooFit.Save(kTRUE), RooFit.Extended(kTRUE),
                    RooFit.Strategy(args.fitStrategy), RooFit.Verbose(0))
                print "[create_datacards] INFO : Done with fit {}. Printing results.".format(
                    fit_function)
                fit_results[fit_function].Print()
                print "[create_datacards] DEBUG : End args.runFit if block."

            # needed if want to evaluate limits without background systematics
            if args.fixBkg:
                background_norms[fit_function].setConstant()
                for par_name, par in background_parameters[
                        fit_function].iteritems():
                    par.setConstant()

        # -----------------------------------------
        #signal_pdfs_syst = {}
        # JES and JER uncertainties
        if args.fitSignal:
            print "[create_datacards] INFO : Getting signal PDFs from " + analysis_config.get_signal_fit_file(
                args.analysis,
                args.model,
                mass,
                "bukin",
                interpolated=(not mass
                              in analysis_config.simulation.simulated_masses))
            f_signal_pdfs = TFile(
                analysis_config.get_signal_fit_file(
                    args.analysis,
                    args.model,
                    mass,
                    "bukin",
                    interpolated=(
                        not mass
                        in analysis_config.simulation.simulated_masses)))
            w_signal = f_signal_pdfs.Get("w_signal")
            if "jes" in systematics:
                xp_central = signal_vars["xp_0"].getVal()
                #print w_signal.pdf("signal__JESUp")
                #print signal_fits.get_parameters(w_signal.pdf("signal__JESUp"))
                xp_up = signal_fits.get_parameters(
                    w_signal.pdf("signal__JESUp"))["xpJESUp"][0]
                xp_down = signal_fits.get_parameters(
                    w_signal.pdf("signal__JESDown"))["xpJESDown"][0]
                signal_vars["dxp"].setVal(
                    max(abs(xp_up - xp_central), abs(xp_down - xp_central)))
                if signal_vars["dxp"].getVal() > 2 * mass * 0.1:
                    print "[create_datacards] WARNING : Large dxp value. dxp = {}, xp_down = {}, xp_central = {}, xp_up = {}".format(
                        signal_vars["dxp"].getVal(), xp_down, xp_central,
                        xp_up)
                signal_vars["alpha_jes"].setVal(0.)
                signal_vars["alpha_jes"].setConstant(False)
            else:
                signal_vars["dxp"].setVal(0.)
                signal_vars["alpha_jes"].setVal(0.)
                signal_vars["alpha_jes"].setConstant()
            signal_vars["dxp"].setError(0.)
            signal_vars["dxp"].setConstant()

            if "jer" in systematics:
                sigp_central = signal_vars["sigp_0"].getVal()
                sigp_up = signal_fits.get_parameters(
                    w_signal.pdf("signal__JERUp"))["sigpJERUp"][0]
                sigp_down = signal_fits.get_parameters(
                    w_signal.pdf("signal__JERDown"))["sigpJERDown"][0]
                signal_vars["dsigp"].setVal(
                    max(abs(sigp_up - sigp_central),
                        abs(sigp_down - sigp_central)))
                signal_vars["alpha_jer"].setVal(0.)
                signal_vars["alpha_jer"].setConstant(False)
            else:
                signal_vars["dsigp"].setVal(0.)
                signal_vars["alpha_jer"].setVal(0.)
                signal_vars["alpha_jer"].setConstant()
            signal_vars["dsigp"].setError(0.)
            signal_vars["dsigp"].setConstant()
            #for variation in ["JERUp", "JERDown"]:
            #    signal_pdfs_syst[variation] = w_signal.pdf("signal__" + variation)
            #for variation, pdf in signal_pdfs_syst.iteritems():
            #    signal_parameters = pdf.getVariables()
            #    iter = signal_parameters.createIterator()
            #    var = iter.Next()
            #    while var:
            #        var.setConstant()
            #        var = iter.Next()
            f_signal_pdfs.Close()
        else:
            # dictionaries holding systematic variations of the signal shape
            hSig_Syst = {}
            hSig_Syst_DataHist = {}
            sigCDF = TGraph(hSig.GetNbinsX() + 1)

            if "jes" in systematics or "jer" in systematics:

                sigCDF.SetPoint(0, 0., 0.)
                integral = 0.
                for i in range(1, hSig.GetNbinsX() + 1):
                    x = hSig.GetXaxis().GetBinLowEdge(i + 1)
                    integral = integral + hSig.GetBinContent(i)
                    sigCDF.SetPoint(i, x, integral)

            if "jes" in systematics:
                hSig_Syst['JESUp'] = copy.deepcopy(hSig)
                hSig_Syst['JESDown'] = copy.deepcopy(hSig)

            if "jer" in systematics:
                hSig_Syst['JERUp'] = copy.deepcopy(hSig)
                hSig_Syst['JERDown'] = copy.deepcopy(hSig)

            # reset signal histograms
            for key in hSig_Syst.keys():
                hSig_Syst[key].Reset()
                hSig_Syst[key].SetName(hSig_Syst[key].GetName() + '_' + key)

            # produce JES signal shapes
            if "jes" in systematics:
                for i in range(1, hSig.GetNbinsX() + 1):
                    xLow = hSig.GetXaxis().GetBinLowEdge(i)
                    xUp = hSig.GetXaxis().GetBinLowEdge(i + 1)
                    jes = 1. - systematics["jes"]
                    xLowPrime = jes * xLow
                    xUpPrime = jes * xUp
                    hSig_Syst['JESUp'].SetBinContent(
                        i,
                        sigCDF.Eval(xUpPrime) - sigCDF.Eval(xLowPrime))
                    jes = 1. + systematics["jes"]
                    xLowPrime = jes * xLow
                    xUpPrime = jes * xUp
                    hSig_Syst['JESDown'].SetBinContent(
                        i,
                        sigCDF.Eval(xUpPrime) - sigCDF.Eval(xLowPrime))
                hSig_Syst_DataHist['JESUp'] = RooDataHist(
                    'hSig_JESUp', 'hSig_JESUp', RooArgList(mjj),
                    hSig_Syst['JESUp'])
                hSig_Syst_DataHist['JESDown'] = RooDataHist(
                    'hSig_JESDown', 'hSig_JESDown', RooArgList(mjj),
                    hSig_Syst['JESDown'])

            # produce JER signal shapes
            if "jer" in systematics:
                for i in range(1, hSig.GetNbinsX() + 1):
                    xLow = hSig.GetXaxis().GetBinLowEdge(i)
                    xUp = hSig.GetXaxis().GetBinLowEdge(i + 1)
                    jer = 1. - systematics["jer"]
                    xLowPrime = jer * (xLow - float(mass)) + float(mass)
                    xUpPrime = jer * (xUp - float(mass)) + float(mass)
                    hSig_Syst['JERUp'].SetBinContent(
                        i,
                        sigCDF.Eval(xUpPrime) - sigCDF.Eval(xLowPrime))
                    jer = 1. + systematics["jer"]
                    xLowPrime = jer * (xLow - float(mass)) + float(mass)
                    xUpPrime = jer * (xUp - float(mass)) + float(mass)
                    hSig_Syst['JERDown'].SetBinContent(
                        i,
                        sigCDF.Eval(xUpPrime) - sigCDF.Eval(xLowPrime))
                hSig_Syst_DataHist['JERUp'] = RooDataHist(
                    'hSig_JERUp', 'hSig_JERUp', RooArgList(mjj),
                    hSig_Syst['JERUp'])
                hSig_Syst_DataHist['JERDown'] = RooDataHist(
                    'hSig_JERDown', 'hSig_JERDown', RooArgList(mjj),
                    hSig_Syst['JERDown'])

        # -----------------------------------------
        # create a datacard and corresponding workspace
        postfix = (('_' + args.postfix) if args.postfix != '' else '')
        wsName = 'workspace_' + args.final_state + '_m' + str(
            mass) + postfix + '.root'

        w = RooWorkspace('w', 'workspace')
        if args.fitSignal:
            signal_pdf.SetName("signal")
            getattr(w, 'import')(signal_pdf, RooFit.Rename("signal"))
            # Create a norm variable "signal_norm" which normalizes the PDF to unity.
            norm = args.lumi
            #signal_norm = ROOT.RooRealVar("signal_norm", "signal_norm", 1. / norm, 0.1 / norm, 10. / norm)
            #if args.analysis == "trigbbh_CSVTM" and mass >= 1100:
            signal_norm = ROOT.RooRealVar("signal_norm", "signal_norm",
                                          norm / 100., norm / 100. / 10.,
                                          norm * 10.)
            #else:
            #    signal_norm = ROOT.RooRealVar("signal_norm", "signal_norm", norm, norm / 10., norm * 10.)
            print "[create_datacards] INFO : Set signal norm to {}".format(
                signal_norm.getVal())
            signal_norm.setConstant()
            getattr(w, 'import')(signal_norm, ROOT.RooCmdArg())
            #if "jes" in systematics:
            #    getattr(w,'import')(signal_pdfs_syst['JESUp'],RooFit.Rename("signal__JESUp"))
            #    getattr(w,'import')(signal_pdfs_syst['JESDown'],RooFit.Rename("signal__JESDown"))
            #if "jer" in systematics:
            #    getattr(w,'import')(signal_pdfs_syst['JERUp'],RooFit.Rename("signal__JERUp"))
            #    getattr(w,'import')(signal_pdfs_syst['JERDown'],RooFit.Rename("signal__JERDown"))
        else:
            getattr(w, 'import')(rooSigHist, RooFit.Rename("signal"))
            if "jes" in systematics:
                getattr(w, 'import')(hSig_Syst_DataHist['JESUp'],
                                     RooFit.Rename("signal__JESUp"))
                getattr(w, 'import')(hSig_Syst_DataHist['JESDown'],
                                     RooFit.Rename("signal__JESDown"))
            if "jer" in systematics:
                getattr(w, 'import')(hSig_Syst_DataHist['JERUp'],
                                     RooFit.Rename("signal__JERUp"))
                getattr(w, 'import')(hSig_Syst_DataHist['JERDown'],
                                     RooFit.Rename("signal__JERDown"))
        if args.decoBkg:
            getattr(w, 'import')(background_deco, ROOT.RooCmdArg())
        else:
            for fit_function in fit_functions:
                print "Importing background PDF"
                print background_pdfs[fit_function]
                background_pdfs[fit_function].Print()
                getattr(w,
                        'import')(background_pdfs[fit_function],
                                  ROOT.RooCmdArg(),
                                  RooFit.Rename("background_" + fit_function),
                                  RooFit.RecycleConflictNodes())
                w.pdf("background_" + fit_function).Print()
                getattr(w, 'import')(background_norms[fit_function],
                                     ROOT.RooCmdArg(),
                                     RooFit.Rename("background_" +
                                                   fit_function + "_norm"))
                getattr(w, 'import')(fit_results[fit_function])
                getattr(w, 'import')(signal_norms[fit_function],
                                     ROOT.RooCmdArg())
                if args.fitBonly:
                    getattr(w, 'import')(models[fit_function],
                                         ROOT.RooCmdArg(),
                                         RooFit.RecycleConflictNodes())
        getattr(w, 'import')(rooDataHist, RooFit.Rename("data_obs"))

        w.Print()
        print "Starting save"
        if args.output_path:
            if not os.path.isdir(os.path.join(os.getcwd(), args.output_path)):
                os.mkdir(os.path.join(os.getcwd(), args.output_path))
            print "[create_datacards] INFO : Writing workspace to file {}".format(
                os.path.join(args.output_path, wsName))
            w.writeToFile(os.path.join(args.output_path, wsName))
        else:
            print "[create_datacards] INFO : Writing workspace to file {}".format(
                limit_config.get_workspace_filename(
                    args.analysis,
                    args.model,
                    mass,
                    fitBonly=args.fitBonly,
                    fitSignal=args.fitSignal,
                    correctTrigger=args.correctTrigger))
            w.writeToFile(
                limit_config.get_workspace_filename(
                    args.analysis,
                    args.model,
                    mass,
                    fitBonly=args.fitBonly,
                    fitSignal=args.fitSignal,
                    correctTrigger=args.correctTrigger))

        # Clean up
        for name, obj in signal_norms.iteritems():
            if obj:
                obj.IsA().Destructor(obj)
        for name, obj in background_pdfs.iteritems():
            if obj:
                obj.IsA().Destructor(obj)
        for name, obj in background_pdfs_notrig.iteritems():
            if obj:
                obj.IsA().Destructor(obj)
        for name, obj in background_norms.iteritems():
            if obj:
                obj.IsA().Destructor(obj)
        for name, obj in signal_pdfs.iteritems():
            if obj:
                obj.IsA().Destructor(obj)
        for name, obj in signal_pdfs_notrig.iteritems():
            if obj:
                obj.IsA().Destructor(obj)
        for name, obj in signal_epdfs.iteritems():
            if obj:
                obj.IsA().Destructor(obj)
        for name, obj in background_epdfs.iteritems():
            if obj:
                obj.IsA().Destructor(obj)
        for name, obj in fit_results.iteritems():
            if obj:
                obj.IsA().Destructor(obj)
        for name, dict_l2 in background_parameters.iteritems():
            for name2, obj in dict_l2.iteritems():
                if obj:
                    obj.IsA().Destructor(obj)
        for name, obj in models.iteritems():
            if obj:
                obj.IsA().Destructor(obj)
        rooDataHist.IsA().Destructor(rooDataHist)
        w.IsA().Destructor(w)

        # Make datacards only if S+B fitted
        if not args.fitBonly:
            beffUnc = 0.3
            boffUnc = 0.06
            for fit_function in fit_functions:
                if args.output_path:
                    dcName = 'datacard_' + args.final_state + '_m' + str(
                        mass) + postfix + '_' + fit_function + '.txt'
                    print "[create_datacards] INFO : Writing datacard to file {}".format(
                        os.path.join(args.output_path, dcName))
                    datacard = open(os.path.join(args.output_path, dcName),
                                    'w')
                else:
                    print "[create_datacards] INFO : Writing datacard to file {}".format(
                        limit_config.get_datacard_filename(
                            args.analysis,
                            args.model,
                            mass,
                            fit_function,
                            fitSignal=args.fitSignal,
                            correctTrigger=args.correctTrigger))
                    datacard = open(
                        limit_config.get_datacard_filename(
                            args.analysis,
                            args.model,
                            mass,
                            fit_function,
                            fitSignal=args.fitSignal,
                            correctTrigger=args.correctTrigger), 'w')
                datacard.write('imax 1\n')
                datacard.write('jmax 1\n')
                datacard.write('kmax *\n')
                datacard.write('---------------\n')
                if ("jes" in systematics
                        or "jer" in systematics) and not args.fitSignal:
                    if args.output_path:
                        datacard.write('shapes * * ' + wsName +
                                       ' w:$PROCESS w:$PROCESS__$SYSTEMATIC\n')
                    else:
                        datacard.write('shapes * * ' + os.path.basename(
                            limit_config.get_workspace_filename(
                                args.analysis,
                                args.model,
                                mass,
                                fitSignal=args.fitSignal,
                                correctTrigger=args.correctTrigger)) +
                                       ' w:$PROCESS w:$PROCESS__$SYSTEMATIC\n')
                else:
                    if args.output_path:
                        datacard.write('shapes * * ' + wsName +
                                       ' w:$PROCESS\n')
                    else:
                        datacard.write('shapes * * ' + os.path.basename(
                            limit_config.get_workspace_filename(
                                args.analysis,
                                args.model,
                                mass,
                                fitSignal=args.fitSignal,
                                correctTrigger=args.correctTrigger)) +
                                       ' w:$PROCESS\n')
                datacard.write('---------------\n')
                datacard.write('bin 1\n')
                datacard.write('observation -1\n')
                datacard.write('------------------------------\n')
                datacard.write('bin          1          1\n')
                datacard.write('process      signal     background_' +
                               fit_function + '\n')
                datacard.write('process      0          1\n')
                if args.fitSignal:
                    datacard.write('rate         1         1\n')
                else:
                    datacard.write('rate         -1         1\n')
                datacard.write('------------------------------\n')
                datacard.write('lumi  lnN    %f         -\n' %
                               (1. + systematics["luminosity"]))
                datacard.write('beff  lnN    %f         -\n' % (1. + beffUnc))
                datacard.write('boff  lnN    %f         -\n' % (1. + boffUnc))
                #datacard.write('bkg   lnN     -         1.03\n')
                if args.fitSignal:
                    if "jes" in systematics:
                        datacard.write("alpha_jes  param  0.0  1.0\n")
                    if "jer" in systematics:
                        datacard.write("alpha_jer  param  0.0  1.0\n")
                else:
                    if "jes" in systematics:
                        datacard.write('JES  shape   1          -\n')
                    if "jer" in systematics:
                        datacard.write('JER  shape   1          -\n')
                # flat parameters --- flat prior
                datacard.write('background_' + fit_function +
                               '_norm  flatParam\n')
                if args.decoBkg:
                    datacard.write('deco_eig1  flatParam\n')
                    datacard.write('deco_eig2  flatParam\n')
                else:
                    for par_name, par in background_parameters[
                            fit_function].iteritems():
                        datacard.write(fit_function + "_" + par_name +
                                       '  flatParam\n')
                datacard.close()
                print "[create_datacards] INFO : Done with this datacard"

    #print '>> Datacards and workspaces created and stored in %s/'%( os.path.join(os.getcwd(),args.output_path) )
    print "All done."
Пример #12
0
def shapeCards(datahistosFile, histosFile, signalFile, signalSample, hist,
               signalMass, minMass, maxMass, outputName, outputFileTheta):
    """function to run Roofit and save workspace for RooStats"""
    warnings.filterwarnings(
        action='ignore',
        category=RuntimeWarning,
        message='.*class stack<RooAbsArg\*,deque<RooAbsArg\*> >')

    ############################################################# DATA
    #hData = histosFile.Get('massAve_deltaEtaDijet_QCDPtAll')
    #hData = datahistosFile.Get('massAve_prunedMassAsymVsdeltaEtaDijet_DATA_ABCDProj')
    dataFile = TFile(datahistosFile)
    hData = dataFile.Get(hist + '_DATA')
    hData.Rebin(args.reBin)
    #hData = hData.Rebin( len( boostedMassAveBins )-1, hData.GetName(), boostedMassAveBins )
    #hData = histosFile.Get(hist+'_QCDPtAll_A')
    #hData.Add(htmpSignal)
    #hData.Scale(1/hData.Integral())
    #maxMass = boostedMassAveBins[ hData.FindLastBinAbove( 0, 1) ]
    #minMass = signalMass-30
    #maxMass = signalMass+30
    massAve = RooRealVar('massAve', 'massAve', minMass, maxMass)
    #massAveData = RooRealVar( 'massAveData', 'massAveData', minMass, maxMass  )
    rooDataHist = RooDataHist('rooDatahist', 'rooDatahist',
                              RooArgList(massAve),
                              hData)  # if isData else hPseudo )
    rooDataHist.Print()
    ############################################################################################

    ####################### Signal
    if 'gaus' in args.job:
        hSignal = TH1F('massAve_RPVStop', 'massAve_RPVStop',
                       maxMass / args.reBin, minMass, maxMass)
        for q in range(hSignal.GetNbinsX() + 1):
            gausEval = signalFile.Eval(hSignal.GetXaxis().GetBinCenter(q))
            hSignal.SetBinContent(q, gausEval)

        #meanSig = RooRealVar( 'meanSig', 'mean of signal', sigGaus.GetParameter( 1 ) )
        #sigmaSig = RooRealVar( 'sigmaSig', 'sigma of signal', sigGaus.GetParameter( 2 ) )
        #signalPdf = RooGaussian( 'signal', 'signal', massAve, meanSig, sigmaSig )
        #signalPdf.Print()
    else:
        signalHistosFile = TFile(signalFile)
        hSignal = signalHistosFile.Get(hist + '_' + signalSample)
        hSignal.Rebin(args.reBin)
    hSignal.Scale(twoProngSF)

    signalXS = search(dictXS, 'RPVStopStopToJets_UDD312_M-' + str(signalMass))
    rooSigHist = RooDataHist('rooSigHist', 'rooSigHist', RooArgList(massAve),
                             hSignal)
    sigAcc = rooSigHist.sumEntries(
    )  #round(hSignal.Integral( hSignal.GetXaxis().FindBin( minMass ), hSignal.GetXaxis().FindBin( maxMass )), 2)
    rooSigHist.Print()

    #signal = RooHistPdf('signal','signal',RooArgSet(massAve),rooSigHist)
    #signal.Print()
    #signal_norm = RooRealVar('signal_norm','signal_norm',0,-1e+04,1e+04)
    #if args.fitBonly: signal_norm.setConstant()
    #signal_norm.Print()

    #####################################################################
    hSigSyst = signalUnc(hSignal, signalMass)
    hSigSystDataHist = {}
    if args.jesUnc:
        hSigSystDataHist['JESUp'] = RooDataHist('hSignalJESUp', 'hSignalJESUp',
                                                RooArgList(massAve),
                                                hSigSyst['JESUp'])
        hSigSystDataHist['JESDown'] = RooDataHist('hSignalJESDown',
                                                  'hSignalJESDown',
                                                  RooArgList(massAve),
                                                  hSigSyst['JESDown'])

    if args.jerUnc:
        hSigSystDataHist['JERUp'] = RooDataHist('hSignalJERUp', 'hSignalJERUp',
                                                RooArgList(massAve),
                                                hSigSyst['JERUp'])
        hSigSystDataHist['JERDown'] = RooDataHist('hSignalJERDown',
                                                  'hSignalJERDown',
                                                  RooArgList(massAve),
                                                  hSigSyst['JERDown'])

    #################################### Background
    if args.altBkg:
        newBkgHistoFile = datahistosFile.replace('DATA', 'DATA_ABCDBkg')
        newBkgFile = TFile(newBkgHistoFile)
        htmpBkg = newBkgFile.Get(
            'massAve_prunedMassAsymVsdeltaEtaDijet_DATA_ABCDProj')
        if (htmpBkg.GetBinWidth(1) != args.reBin):
            print '|----- Bin size in DATA_C histogram is different than rest.'
            sys.exit(0)
    else:
        htmpBkg = dataFile.Get(
            'massAve_prunedMassAsymVsdeltaEtaDijet_DATA_ABCDProj')
        htmpBkg.Rebin(args.reBin)
    #hBkg = histosFile.Get('massAve_prunedMassAsymVsdeltaEtaDijet_QCDPtAll_ABCDProj')
    #hBkg = histosFile.Get(hist+'_QCDPtAll_BCD')
    #htmpBkg = htmpBkg.Rebin( len( boostedMassAveBins )-1, htmpBkg.GetName(), boostedMassAveBins )
    hBkg = htmpBkg.Clone()
    hBkg.Reset()
    for ibin in range(htmpBkg.GetNbinsX()):
        binCont = htmpBkg.GetBinContent(ibin)
        binErr = htmpBkg.GetBinError(ibin)
        if binCont == 0:
            hBkg.SetBinContent(ibin, 0)
            hBkg.SetBinError(ibin, 1.8)
        else:
            hBkg.SetBinContent(ibin, binCont)
            hBkg.SetBinError(ibin, binErr)
    #hBkg.Scale(1/hBkg.Integral())

    hPseudo = createPseudoExperiment(hBkg, bkgAcc)

    ###### Adding statistical uncertanty
    hBkgStatUncUp = hBkg.Clone()
    hBkgStatUncUp.Reset()
    hBkgStatUncDown = hBkg.Clone()
    hBkgStatUncDown.Reset()
    for i in range(hBkg.GetNbinsX() + 1):
        cont = hBkg.GetBinContent(i)
        contErr = hBkg.GetBinError(i)
        hBkgStatUncUp.SetBinContent(i, cont + (1 * contErr))
        hBkgStatUncDown.SetBinContent(i, cont - (1 * contErr))
    hBkgStatUncUpDataHist = RooDataHist('hBkgStatUncUp', 'hBkgStatUncUp',
                                        RooArgList(massAve), hBkgStatUncUp)
    hBkgStatUncDownDataHist = RooDataHist('hBkgStatUncDown', 'hBkgStatUncDown',
                                          RooArgList(massAve), hBkgStatUncDown)

    if 'template' in args.job:
        rooBkgHist = RooDataHist('rooBkgHist', 'rooBkgHist',
                                 RooArgList(massAve), hBkg)
        bkgAcc = rooBkgHist.sumEntries()
        rooBkgHist.Print()
        background = RooHistPdf('background', 'background', RooArgSet(massAve),
                                rooBkgHist)
        background.Print()

    else:
        massAveBkg = RooRealVar('massAveBkg', 'massAveBkg', minMass, maxMass)
        p1 = RooRealVar('p1', 'p1', 1, 0., 100.)
        p2 = RooRealVar('p2', 'p2', 1, 0., 60.)
        p3 = RooRealVar('p3', 'p3', 1, -10., 10.)

        bkgAcc = round(
            hBkg.Integral(hBkg.GetXaxis().FindBin(minMass),
                          hBkg.GetXaxis().FindBin(maxMass)), 2)
        background = RooGenericPdf(
            'background',
            '(pow(1-@0/%.1f,@1)/pow(@0/%.1f,@2+@3*log(@0/%.1f)))' %
            (1300, 1300, 1300), RooArgList(massAveBkg, p1, p2, p3))
        background.Print()

    hBkgSyst = {}
    hBkgSystDataHist = {}

    if args.bkgUnc:
        print ' |---> Adding bkg unc'
        hBkgSyst['BkgUncUp'] = hBkg.Clone()
        hBkgSyst['BkgUncDown'] = hBkg.Clone()

        for key in hBkgSyst:
            hBkgSyst[key].Reset()
            hBkgSyst[key].SetName(hBkgSyst[key].GetName() + '_' + key)

        for q in range(0, hBkg.GetNbinsX()):
            binCont = hBkg.GetBinContent(q)
            bkgUncUp = 1. + (args.bkgUncValue / 100.)
            hBkgSyst['BkgUncUp'].SetBinContent(q, binCont * bkgUncUp)
            bkgUncDown = 1. - (args.bkgUncValue / 100.)
            hBkgSyst['BkgUncDown'].SetBinContent(q, binCont * bkgUncDown)
        hBkgSystDataHist['BkgUncUp'] = RooDataHist('hBkgBkgUncUp',
                                                   'hBkgBkgUncUp',
                                                   RooArgList(massAve),
                                                   hBkgSyst['BkgUncUp'])
        hBkgSystDataHist['BkgUncDown'] = RooDataHist('hBkgBkgUncDown',
                                                     'hBkgBkgUncDown',
                                                     RooArgList(massAve),
                                                     hBkgSyst['BkgUncDown'])

    ############################################################################################

    #model = RooAddPdf("model","s+b",RooArgList(background,signal),RooArgList(background_norm,signal_norm))
    #res = model.fitTo(rooDataHist, RooFit.Save(kTRUE), RooFit.Strategy(0))
    #res.Print()

    ############################ Create Workspace
    myWS = RooWorkspace("myWS")
    getattr(myWS, 'import')(rooBkgHist, RooFit.Rename("background"))
    #getattr(myWS,'import')(background,RooFit.Rename("background"))
    #getattr(myWS,'import')(signal_norm)
    #getattr(myWS,'import')(background_norm)
    '''
	if 'gaus' in args.job: 
		getattr(myWS,'import')(signalPdf,RooFit.Rename("signal")) 
		if args.jesUnc:
			getattr(myWS,'import')(signalPdfJESUp,RooFit.Rename("signal__JESUp")) 
			getattr(myWS,'import')(signalPdfJESDown,RooFit.Rename("signal__JESDown")) 
	else: 
	'''
    getattr(myWS, 'import')(rooSigHist, RooFit.Rename("signal"))
    if args.jesUnc:
        getattr(myWS, 'import')(hSigSystDataHist['JESUp'],
                                RooFit.Rename("signal__JESUp"))
        getattr(myWS, 'import')(hSigSystDataHist['JESDown'],
                                RooFit.Rename("signal__JESDown"))
    if args.jerUnc:
        getattr(myWS, 'import')(hSigSystDataHist['JERUp'],
                                RooFit.Rename("signal__JERUp"))
        getattr(myWS, 'import')(hSigSystDataHist['JERDown'],
                                RooFit.Rename("signal__JERDown"))
    if args.bkgUnc:
        getattr(myWS, 'import')(hBkgSystDataHist['BkgUncUp'],
                                RooFit.Rename("background__BkgUncUp"))
        getattr(myWS, 'import')(hBkgSystDataHist['BkgUncDown'],
                                RooFit.Rename("background__BkgUncDown"))
    getattr(myWS, 'import')(hBkgStatUncUpDataHist,
                            RooFit.Rename("background__BkgStatUncUp"))
    getattr(myWS, 'import')(hBkgStatUncDownDataHist,
                            RooFit.Rename("background__BkgStatUncDown"))
    getattr(myWS, 'import')(rooDataHist, RooFit.Rename("data_obs"))
    myWS.Print()
    outputRootFile = currentDir + '/Rootfiles/workspace_' + outputName + '.root'
    myWS.writeToFile(outputRootFile, True)
    print ' |----> Workspace created in root file:\n', outputRootFile
    '''
	c1 = TCanvas('c1', 'c1',  10, 10, 750, 500 )
#	c1.SetLogy()
	xframe = myWS.var("massAve").frame()
	signalPdf.plotOn( xframe )
	xframe.Draw()
	c1.SaveAs('test.png')
	del c1
	'''
    ############################################################################################

    ######################### write a datacard

    dataCardName = currentDir + '/Datacards/datacard_' + outputName + '.txt'
    datacard = open(dataCardName, 'w')
    datacard.write('imax 1\n')
    datacard.write('jmax 1\n')
    datacard.write('kmax *\n')
    datacard.write('---------------\n')
    if args.jesUnc or args.jerUnc or args.lumiUnc or args.bkgUnc or args.unc:
        datacard.write('shapes * * ' + outputRootFile +
                       ' myWS:$PROCESS myWS:$PROCESS__$SYSTEMATIC\n')
    else:
        datacard.write("shapes * * " + outputRootFile + " myWS:$PROCESS \n")
    datacard.write('---------------\n')
    datacard.write('bin ' + signalSample + '\n')
    datacard.write('observation -1\n')
    datacard.write('------------------------------\n')
    datacard.write('bin          ' + signalSample + '          ' +
                   signalSample + '\n')
    datacard.write('process      signal     background\n')
    datacard.write('process      0          1\n')
    #datacard.write('rate         -1         -1\n')
    datacard.write('rate         ' + str(sigAcc) + '         ' + str(bkgAcc) +
                   '\n')
    datacard.write('------------------------------\n')
    if args.lumiUnc:
        datacard.write('lumi  lnN    %f         -\n' % (lumiValue))
    if args.puUnc: datacard.write('pu  lnN    %f         -\n' % (puValue))
    if args.jesUnc: datacard.write('JES  shape   1          -\n')
    if args.jerUnc: datacard.write('JER  shape   1          -\n')
    #flat parameters --- flat prior
    #if args.bkgUnc: datacard.write('BkgUnc  shape   -	   '+str( round( 1/ (args.bkgUncValue/34.1), 2 ) )+'\n')
    if args.bkgUnc: datacard.write('BkgUnc  shape   -	   1 \n')
    #NcombineUnc = ( 1 / TMath.Sqrt( args.bkgUncValue / 100. ) ) - 1
    #datacard.write('background_norm  gmN '+str(int(round(NcombineUnc)))+'  -  '+str( round(bkgAcc/NcombineUnc,2) )+'\n')
    #datacard.write('p1  flatParam\n')
    datacard.write('BkgStatUnc  shape   -	   1 \n')
    datacard.close()
    print ' |----> Datacard created:\n', dataCardName
    ############################################################################################

    ########## Theta
    if args.theta:
        print ' |----> Creating Theta file\n', outputFileTheta
        outFile = TFile(outputFileTheta, 'update')
        tmpName = 'rpvstopjj' + str(signalMass)
        hSignal.SetName('massAve__' + tmpName)
        hSignal.Write()
        hSigSyst['JESDown'].SetName('massAve__' + tmpName + '__jes__down')
        hSigSyst['JESDown'].Write()
        hSigSyst['JESUp'].SetName('massAve__' + tmpName + '__jes__up')
        hSigSyst['JESUp'].Write()
        hSigSyst['JERDown'].SetName('massAve__' + tmpName + '__jer__down')
        hSigSyst['JERDown'].Write()
        hSigSyst['JERUp'].SetName('massAve__' + tmpName + '__jer__up')
        hSigSyst['JERUp'].Write()
        if (signalMass == 100):  #or (signalMass == 170):
            hBkg.SetName('massAve__background')
            hBkg.Write()
            hBkgSyst['BkgUncDown'].SetName('massAve__background__unc__down')
            hBkgSyst['BkgUncDown'].Write()
            hBkgSyst['BkgUncUp'].SetName('massAve__background__unc__up')
            hBkgSyst['BkgUncUp'].Write()
            hData.SetName('massAve__DATA')
            hData.Write()
        outFile.Close()
Пример #13
0
class Wjj2DFitter:

    def __init__ (self, pars):
        self.pars = pars
        self.ws = RooWorkspace('wjj2dfitter')
        self.utils = Wjj2DFitterUtils(self.pars)
        self.useImportPars = False

        self.rangeString = None
        obs = []
        for v in self.pars.var:

            try:
                vName = self.pars.varNames[v]
            except AttributeError:
                vName = v

            obs.append(vName)
            var1 = self.ws.factory('%s[%f,%f]' % (vName, 
                                                  self.pars.varRanges[v][1], 
                                                  self.pars.varRanges[v][2])
                                   )
            var1.setUnit('GeV')
            try:
                var1.SetTitle(self.pars.varTitles[v])
            except AttributeError:
                var1.SetTitle('m_{jj}')
            var1.setPlotLabel(var1.GetTitle())
            if len(self.pars.varRanges[v][3]) > 1:
                vbinning = RooBinning(len(self.pars.varRanges[v][3]) - 1, 
                                   array('d', self.pars.varRanges[v][3]),
                                   '%sBinning' % vName)
                var1.setBinning(vbinning)
            else:
                var1.setBins(self.pars.varRanges[v][0])
            var1.Print()
            if v in self.pars.exclude:
                var1.setRange('signalRegion', self.pars.exclude[v][0],
                              self.pars.exclude[v][1])
                var1.setRange('lowSideband', var1.getMin(), 
                              self.pars.exclude[v][0])
                var1.setRange('highSideband', self.pars.exclude[v][1],
                              var1.getMax())
                self.rangeString = 'lowSideband,highSideband'
        self.ws.defineSet('obsSet', ','.join(obs))

    def loadDataFromWorkspace(self, other, cut = None):
        #pull unbinned data from other workspace
        unbinnedData = other.data('data_unbinned')
        if not unbinnedData:
            unbinnedData = other.data('data_obs')

        if cut:
            unbinnedData = unbinnedData.reduce(cut)

        unbinnedData.Print()
        if self.pars.binData:
            #bin and import data
            unbinnedData.SetName('data_unbinned')
            getattr(self.ws, 'import')(unbinnedData)
            data = RooDataHist('data_obs', 'data_obs', other.set('obsSet'), 
                               unbinnedData)
            getattr(self.ws, 'import')(data)
        else:
            #just import data
            unbinnedData.SetName('data_obs')
            getattr(self.ws, 'import')(unbinnedData)

    def loadHistogramsFromWorkspace(self, other):
        #pull RooHist pdfs from other workspace
        pdfs = other.allPdfs()
        pdfIter = pdfs.createIterator()
        pdf = pdfIter.Next()
        while pdf:
            if pdf.IsA().InheritsFrom('RooHistPdf'):
                print 'importing',pdf.GetName(),'from old workspace'
                getattr(self.ws, 'import')(pdf)
            pdf = pdfIter.Next()

    def loadWorkspaceFromFile(self, filename, wsname = 'w', 
                              getFloatPars = True):
        print 'loading data workspace %s from file %s' % (wsname, filename)
        fin = TFile.Open(filename)
        if not fin:
            print 'failed to open the file',filename
            import os
            print 'cwd:',os.getcwd()
            print 'access of',filename,os.access(filename, os.R_OK)
            print 'list of root files in cwd'
            for f in os.listdir(os.getcwd()):
                if f[-5:] == '.root':
                    print f,len(f),len(filename)
            fin = TFile.Open(os.getcwd() + '/' + filename)
            assert(fin)

        other = fin.Get(wsname)

        #pull unbinned data from other workspace
        self.loadDataFromWorkspace(other)

        #pull in histogram pdfs to save time
        self.loadHistogramsFromWorkspace(other)

        if getFloatPars and other.loadSnapshot('fitPars'):
            self.useImportPars = True
            self.ws.saveSnapshot('importParams', other.set('floatingParams'), 
                                 True)

        # self.ws.Print()
    
    # put together a fitting model and return the pdf
    def makeFitter(self, useAlternateModels = False):
        if self.ws.pdf('total'):
            return self.ws.pdf('total')

        compPdfs = []

        for component in self.pars.backgrounds:
            # print 'getting compModels'
            compModels = getattr(self.pars, '%sModels' % component)
            if hasattr(self.pars, '%sConvModels' % component):
                convModels = getattr(self.pars, '%sConvModels' % component)
            else:
                convModels = None
            if useAlternateModels:
                print 'loading Alternate Models'
                compModels = getattr(self.pars, '%sModelsAlt' % component)
                convModels = getattr(self.pars, '%sConvModelsAlt' % component)
            # print 'compModels = %s' % compModels
            compFiles = getattr(self.pars, '%sFiles' % component)
            compPdf = self.makeComponentPdf(component, compFiles, compModels,
                                            useAlternateModels, convModels)
                
            norm = self.ws.factory('prod::f_%s_norm' % component + \
                                       '(n_%s[0.,1e6],' % component + \
                                       '%s_nrm[1.,-0.5,5.])' % component)
            self.ws.var('n_%s' % component).setConstant(True)
            if hasattr(self, '%sExpected' % component):
                self.ws.var('n_%s' % component).setVal(
                    getattr(self, '%sExpected' % component))
            compPdfs.append(
                self.ws.factory('RooExtendPdf::%s_extended(%s,%s)' % \
                                    (compPdf.GetName(), 
                                     compPdf.GetName(),
                                     norm.GetName())
                                )
                )
                                    
        self.ws.factory('r_signal[0., -200., 200.]')
        self.ws.var('r_signal').setConstant(False)

        try:
            obs = [ self.pars.varNames[x] for x in self.pars.var ]
        except AttributeError:
            obs = self.pars.var

        for component in self.pars.signals:
            compFile = getattr(self.pars, '%sFiles' % component)
            compModels = getattr(self.pars, '%sModels' % component)
            if hasattr(self.pars, '%sConvModels' % component):
                convModels = getattr(self.pars, '%sConvModels' % component)
            else:
                convModels = None
            compPdf = self.makeComponentPdf(component, compFiles, compModels,
                                            useAlternateModels, convModels)
            norm = self.ws.factory(
                "prod::f_%s_norm(n_%s[0., 1e6],r_signal)" % \
                    (component, component)
                )
            self.ws.var('n_%s' % component).setConstant(True)
            if hasattr(self, '%sExpected' % component):
                self.ws.var('n_%s' % component).setVal(
                    getattr(self, '%sExpected' % component))
            pdf = self.ws.factory('RooExtendPdf::%s_extended(%s,%s)' % \
                                      (compPdf.GetName(), 
                                       compPdf.GetName(),
                                       norm.GetName())
                                  )
            
            if (hasattr(self.pars, '%sInterference' % component)) and \
                    getattr(self.pars, '%sInterference' % component):
                getattr(self.ws, 'import') \
                    (pdf, RooFit.RenameAllNodes('interf_%sUp' % component),
                     RooFit.RenameAllVariablesExcept('interf_%sUp' % component,
                                                     ','.join(obs)),
                     RooFit.Silence()
                     )
                getattr(self.ws, 'import') \
                    (pdf, RooFit.RenameAllNodes('interf_%sDown' % component),
                     RooFit.RenameAllVariablesExcept('interf_%sDown'%component,
                                                     ','.join(obs)),
                     RooFit.Silence()
                     )
            if self.pars.includeSignal:
                compPdfs.append(pdf)

        #print compPdfs
        
        prodList = [ '%s' % (pdf.GetName()) \
                         for (idx, pdf) in enumerate(compPdfs) ]
        comps = RooArgList(self.ws.argSet(','.join(prodList)))
        getattr(self.ws, 'import')(RooAddPdf('total', 'total', comps))

        return self.ws.pdf('total')

    # define the constraints on the yields, etc that will be part of the fit.
    def makeConstraints(self):

        if self.ws.set('constraintSet'):
            return self.ws.set('constraintSet')

        constraints = []
        constrainedParameters = []
        for constraint in self.pars.yieldConstraints:
            theYield = self.ws.var('%s_nrm' % constraint)
            if not theYield.isConstant():
                self.ws.factory('RooGaussian::%s_const(%s, 1.0, %f)' % \
                                    (constraint, theYield.GetName(),
                                     self.pars.yieldConstraints[constraint])
                                )
                constraints.append('%s_const' % constraint)
                constrainedParameters.append(theYield.GetName())

        if hasattr(self.pars, 'constrainShapes'):
            for component in self.pars.constrainShapes:
                pc = self.ws.pdf(component).getParameters(self.ws.set('obsSet'))
                parIter = pc.createIterator()
                par = parIter.Next()
                while par:
                    if not par.isConstant():
                        theConst = self.ws.factory('RooGaussian::%s_const' % \
                                                       (par.GetName()) + \
                                                       '(%s, %f, %f)' % \
                                                       (par.GetName(),
                                                        par.getVal(),
                                                        par.getError())
                                                   )
                        constraints.append(theConst.GetName())
                        constrainedParameters.append(par.GetName())
                    par = parIter.Next()
                pc.IsA().Destructor(pc)

        self.ws.defineSet('constraintSet', ','.join(constraints))
        self.ws.defineSet('constrainedSet', ','.join(constrainedParameters))

        return self.ws.set('constraintSet')

    # fit the data using the pdf
    def fit(self, keepParameterValues = False):
        print 'construct fit pdf ...'
        fitter = self.makeFitter()

        print 'load data ...'
        data = self.loadData()

        self.resetYields()

        constraintSet = self.makeConstraints()

        if not keepParameterValues:
            self.readParametersFromFile()

        self.resetYields()
        # print constraints, self.pars.yieldConstraints
        print '\nfit constraints'
        constIter = constraintSet.createIterator()
        constraint = constIter.Next()
        constraints = []
        while constraint:
            constraint.Print()
            constraints.append(constraint.GetName())
            constraint = constIter.Next()
            
        constraintCmd = RooCmdArg.none()
        if constraintSet.getSize() > 0:
            constraints.append(fitter.GetName())
            fitter = self.ws.pdf('totalFit_const')
            if not fitter:
                fitter = self.ws.factory('PROD::totalFit_const(%s)' % \
                                             (','.join(constraints))
                                         )
            constraintCmd = RooFit.Constrained()
            # constraintCmd = RooFit.ExternalConstraints(self.ws.set('constraintSet'))

        if self.useImportPars:
            self.ws.loadSnapshot('importParams')
        self.ws.Print()

        # for constraint in pars.constraints:
        #     self.ws.pdf(constraint).Print()
        # print

        rangeCmd = RooCmdArg.none()
        if self.rangeString and self.pars.doExclude:
            rangeCmd = RooFit.Range(self.rangeString)

        print 'fitting ...'
        fr = fitter.fitTo(data, RooFit.Save(True),
                          RooFit.Extended(True),
                          RooFit.Minos(False),
                          RooFit.PrintEvalErrors(-1),
                          RooFit.Warnings(False),
                          constraintCmd,
                          rangeCmd)
        fr.Print()

        

        return fr

    # determine the fitting model for each component and return them
    def makeComponentPdf(self, component, files, models, useAlternateModels,
                         convModels):
        print 'making ComponentPdf %s' % component
        # print 'models = %s' % models
        # print 'files = %s' % files
        if convModels and not (convModels[0] == -1):
            thePdf = self.makeConvolvedPdf(component, files, models, useAlternateModels, convModels)
        elif (models[0] == -1):
            thePdf = self.makeComponentHistPdf(component, files)
        elif (models[0] == -2):
            thePdf = self.makeMorphingPdf(component, useAlternateModels, convModels)
        elif (models[0] == -3):
            pass
        else:
            thePdf = self.makeComponentAnalyticPdf(component, models, useAlternateModels)

        return thePdf

    #create a simple 2D histogram pdf
    def makeComponentHistPdf(self, component, files):
        if self.ws.pdf(component):
            return self.ws.pdf(component)

        compHist = self.utils.newEmptyHist('hist%s' % component)
        sumYields = 0.
        sumxsec = 0.
        sumExpected = 0.
        for (idx,fset) in enumerate(files):
            if hasattr(self.pars, '%scuts' % component):
                cutOverride = getattr(self.pars, '%scuts' % component)
            else:
                cutOverride = None
            filename = fset[0]
            tmpHist = self.utils.File2Hist(filename, 
                                           'hist%s_%i' % (component, idx),
                                           False,cutOverride,False,True,0)
            sumYields += tmpHist.Integral()
            sumxsec += fset[2]
            compHist.Add(tmpHist, self.pars.integratedLumi*fset[2]/fset[1])
            sumExpected += tmpHist.Integral()*fset[2]* \
                self.pars.integratedLumi/fset[1]
            print filename,'acc x eff: %.3g' % (tmpHist.Integral()/fset[1])
            print filename,'N_expected: %.1f' % \
                (tmpHist.Integral()*fset[2]*self.pars.integratedLumi/fset[1])
            #tmpHist.Print()

        #compHist.Print()
        print '%s acc x eff: %.3g' % \
            (component, sumExpected/sumxsec/self.pars.integratedLumi)
        print 'Number of expected %s events: %.1f' % (component, sumExpected)
        setattr(self, '%sExpected' % component, sumExpected)

        return self.utils.Hist2Pdf(compHist, component, 
                                   self.ws, self.pars.order)
    #create a pdf which is a convolution of any two pdf
    def makeConvolvedPdf(self, component, files, models, useAlternateModels, convModels):
        if self.ws.pdf(component):
            return self.ws.pdf(component)

        #If a morphing model is selected, then convolve each individual component first and then morph
        if (models[0] == -2):
            return self.makeMorphingPdf(component, useAlternateModels, convModels)

        basePdf = self.makeComponentPdf('%s_base' % component, files, models, useAlternateModels, [-1])
        convComponent = 'Global' ##Overwrite to use the same convolution model for all Pdfs
        convModel = getattr(self.pars, '%sConvModels' % convComponent)
        if useAlternateModels:
            convModel = getattr(self.pars, '%sConvModelsAlt' % convComponent)
        convPdf = self.makeComponentPdf('%s_conv' % convComponent, files, convModel, useAlternateModels, [-1])
        var = self.pars.var[0]
        try:
            vName = self.pars.varNames[var]
        except AttributeError:
            vName = var
        self.ws.factory('RooFFTConvPdf::%s(%s,%s,%s)' % \
                        (component, vName, basePdf.GetName(),
                         convPdf.GetName()))
        return self.ws.pdf(component)


    # create a pdf using the "template morphing" technique
    def makeMorphingPdf(self, component, useAlternateModels, convModels):
        if self.ws.pdf(component):
            return self.ws.pdf(component)
        
        filesNom = getattr(self.pars, '%s_NomFiles' % component)
        modelsNom = getattr(self.pars, '%s_NomModels' % component)
        filesMU = getattr(self.pars, '%s_MUFiles' % component)
        modelsMU = getattr(self.pars, '%s_MUModels' % component)
        filesMD = getattr(self.pars, '%s_MDFiles' % component)
        modelsMD = getattr(self.pars, '%s_MDModels' % component)
        filesSU = getattr(self.pars, '%s_SUFiles' % component)
        modelsSU = getattr(self.pars, '%s_SUModels' % component)
        filesSD = getattr(self.pars, '%s_SDFiles' % component)
        modelsSD = getattr(self.pars, '%s_SDModels' % component)
        if useAlternateModels:
            modelsNom = getattr(self.pars, '%s_NomModelsAlt' % component)
            modelsMU = getattr(self.pars, '%s_MUModelsAlt' % component)
            modelsMD = getattr(self.pars, '%s_MDModelsAlt' % component)
            modelsSU = getattr(self.pars, '%s_SUModelsAlt' % component)
            modelsSD = getattr(self.pars, '%s_SDModelsAlt' % component)

        # Adds five (sub)components for the component with suffixes Nom, MU, MD, SU, SD
        NomPdf = self.makeComponentPdf('%s_Nom' % component, filesNom, modelsNom, False, convModels)
        if hasattr(self, '%s_NomExpected' % component):
            setattr(self, '%sExpected' % component,
                    getattr(self, '%s_NomExpected' % component))
        MUPdf = self.makeComponentPdf('%s_MU' % component, filesMU, modelsMU, False, convModels)
        MDPdf = self.makeComponentPdf('%s_MD' % component, filesMD, modelsMD, False, convModels)
        SUPdf = self.makeComponentPdf('%s_SU' % component, filesSU, modelsSU, False, convModels)
        SDPdf = self.makeComponentPdf('%s_SD' % component, filesSD, modelsSD, False, convModels)

        fMU_comp = self.ws.factory("fMU_%s[0., -1., 1.]" % component)
        fSU_comp = self.ws.factory("fSU_%s[0., -1., 1.]" % component)

        fMU = RooFormulaVar("f_fMU_%s" % component, "1.0*@0*(@0 >= 0.)", 
                            RooArgList( fMU_comp ) )
        fMD = RooFormulaVar("f_fMD_%s" % component, "-1.0*@0*(@0 < 0.)", 
                            RooArgList( fMU_comp ) )
        fSU = RooFormulaVar("f_fSU_%s" % component, "@0*(@0 >= 0.)", 
                            RooArgList( fSU_comp ) )
        fSD = RooFormulaVar("f_fSD_%s" % component, "@0*(-1)*(@0 < 0.)", 
                            RooArgList( fSU_comp ) )
        fNom = RooFormulaVar("f_fNom_%s" % component, "(1.-abs(@0)-abs(@1))", 
                             RooArgList(fMU_comp,fSU_comp) )
        morphPdf = RooAddPdf(component,component, 
                             RooArgList(MUPdf,MDPdf,SUPdf,SDPdf,NomPdf),
                             RooArgList(fMU, fMD, fSU, fSD, fNom))
        morphPdf.SetName(component)
        getattr(self.ws, 'import')(morphPdf)
        return self.ws.pdf(component)

    # create a pdf using an analytic function.
    def makeComponentAnalyticPdf(self, component, models, useAlternateModels):
        if self.ws.pdf(component):
            return self.ws.pdf(component)

        pdfList = []
        for (idx,model) in enumerate(models):
            var = self.pars.var[idx]
            try:
                vName = self.pars.varNames[var]
            except AttributeError:
                vName = var

            auxModel = None
            if useAlternateModels:
                if hasattr(self.pars, '%sAuxModelsAlt' % component):
                    auxModel = getattr(self.pars, '%sAuxModelsAlt' % component)[idx]
            else:
                if hasattr(self.pars, '%sAuxModels' % component):
                    auxModel = getattr(self.pars, '%sAuxModels' % component)[idx]

            pdfList.append(self.utils.analyticPdf(self.ws, vName, model, 
                                                  '%s_%s'%(component,vName), 
                                                  '%s_%s'%(component,vName),
                                                  auxModel
                                                  )
                           )
        
        pdfListNames = [ pdf.GetName() for pdf in pdfList ]
        if len(pdfList) > 1:
            self.ws.factory('PROD::%s(%s)' % \
                                (component, ','.join(pdfListNames)))
        else:
            pdfList[0].SetName(component)
                        
        return self.ws.pdf(component)

    def loadData(self, weight = False):
        if self.ws.data('data_obs'):
            return self.ws.data('data_obs')

        unbinnedName = 'data_obs'
        if self.pars.binData:
            unbinnedName = 'data_unbinned'
        data = self.utils.File2Dataset(self.pars.DataFile, unbinnedName, 
                                       self.ws, weighted = weight)
        if self.pars.binData:
            data = RooDataHist('data_obs', 'data_obs', self.ws.set('obsSet'), 
                               data)
            getattr(self.ws, 'import')(data)
            data = self.ws.data('data_obs')

        return data

    def stackedPlot(self, var, logy = False, pdfName = None, Silent = False):
        if not pdfName:
            pdfName = 'total'

        xvar = self.ws.var(var)
        nbins = xvar.getBins()
        if hasattr(self.pars, 'plotRanges'):
            xvar.setRange('plotRange', self.pars.plotRanges[var][1],
                          self.pars.plotRanges[var][2])
            xvar.setBins(self.pars.plotRanges[var][0], 'plotBins')
        else:
            xvar.setRange('plotRange', xvar.getMin(), xvar.getMax())
            xvar.setBins(nbins, 'plotBins')

        sframe = xvar.frame()
        sframe.SetName("%s_stacked" % var)
        pdf = self.ws.pdf(pdfName)

        if isinstance(pdf, RooAddPdf):
            compList = RooArgList(pdf.pdfList())
        else:
            compList = None

        data = self.ws.data('data_obs')
        nexp = pdf.expectedEvents(self.ws.set('obsSet'))

        if not Silent:
            print pdf.GetName(),'expected: %.0f' % (nexp)
            print 'data events: %.0f' % (data.sumEntries())

        if nexp < 1:
            nexp = data.sumEntries()
        theComponents = [] 
        if self.pars.includeSignal:
            theComponents += self.pars.signals
        theComponents += self.pars.backgrounds
        data.plotOn(sframe, RooFit.Invisible(),
                    RooFit.Binning('plotBins'))
        # dataHist = RooAbsData.createHistogram(data,'dataHist_%s' % var, xvar,
        #                                       RooFit.Binning('%sBinning' % var))
        # #dataHist.Scale(1., 'width')
        # invData = RooHist(dataHist, 1., 1, RooAbsData.SumW2, 1.0, False)
        # #invData.Print('v')
        # sframe.addPlotable(invData, 'pe', True, True)
        for (idx,component) in enumerate(theComponents):
            if not Silent:
                print 'plotting',component,'...',
            if hasattr(self.pars, '%sPlotting' % (component)):
                plotCharacteristics = getattr(self.pars, '%sPlotting' % \
                                                  (component))
            else:
                plotCharacteristics = {'color' : colorwheel[idx%6],
                                       'title' : component }

            compCmd = RooCmdArg.none()
            if compList:
                compSet = RooArgSet(compList)
                if compSet.getSize() > 0:
                    compCmd = RooFit.Components(compSet)
                removals = compList.selectByName('%s*' % component)
                compList.remove(removals)

            if not Silent:
                print 'events', self.ws.function('f_%s_norm' % component).getVal()
                sys.stdout.flush()
            if abs(self.ws.function('f_%s_norm' % component).getVal()) >= 1.:
                pdf.plotOn(sframe, #RooFit.ProjWData(data),
                           RooFit.DrawOption('LF'), RooFit.FillStyle(1001),
                           RooFit.FillColor(plotCharacteristics['color']),
                           RooFit.LineColor(plotCharacteristics['color']),
                           RooFit.VLines(),
                           RooFit.Range('plotRange'),
                           RooFit.NormRange('plotRange'),
                           RooFit.Normalization(nexp, RooAbsReal.NumEvent),
                           compCmd
                           )
                tmpCurve = sframe.getCurve()
                tmpCurve.SetName(component)
                tmpCurve.SetTitle(plotCharacteristics['title'])
                if 'visible' in plotCharacteristics:
                    sframe.setInvisible(component, 
                                        plotCharacteristics['visible'])

        data.plotOn(sframe, RooFit.Name('theData'),
                    RooFit.Binning('plotBins'))
        sframe.getHist('theData').SetTitle('data')
        # theData = RooHist(dataHist, 1., 1, RooAbsData.SumW2, 1.0, True)
        # theData.SetName('theData')
        # theData.SetTitle('data')
        # sframe.addPlotable(theData, 'pe')

        if (logy):
            sframe.SetMinimum(0.01)
            sframe.SetMaximum(1.0e6)
        else:
            sframe.SetMaximum(sframe.GetMaximum()*1.35)
            pass

        excluded = (var in self.pars.exclude)
        bname = var
        if not excluded:
            for v in self.pars.exclude:
                if hasattr(self.pars, 'varNames') and \
                       (self.pars.varNames[v] == var):
                    excluded = True
                    bname = v
        if excluded:
            blinder = TBox(self.pars.exclude[bname][0], sframe.GetMinimum(),
                           self.pars.exclude[bname][1], sframe.GetMaximum())
            # blinder.SetName('blinder')
            # blinder.SetTitle('signal region')
            blinder.SetFillColor(kBlack)
            if self.pars.blind:  
                blinder.SetFillStyle(1001)
            else:
                blinder.SetFillStyle(0)
            blinder.SetLineStyle(2)
            sframe.addObject(blinder)
        elif self.pars.blind:
            if not Silent:
                print "blind but can't find exclusion region for", var
                print 'excluded',excluded,self.pars.exclude
                print 'hiding data points'
            sframe.setInvisible('theData', True)

        #sframe.GetYaxis().SetTitle('Events / GeV')
        # dataHist.IsA().Destructor(dataHist)
        if not Silent:
            print

        xvar.setBins(nbins)

        return sframe

    def readParametersFromFile(self, fname=None):
        if (not fname):
            fname = self.pars.initialParametersFile
        
        if isinstance(fname, str):
            flist = [ fname ]
        else:
            flist = fname

        for tmpName in flist:
            if len(tmpName) > 0:
                print 'loading parameters from file',tmpName
                self.ws.allVars().readFromFile(tmpName)

    def expectedFromPars(self):
        components = self.pars.signals + self.pars.backgrounds
        for component in components:
            theYield = self.ws.var('n_%s' % component)
            setattr(self, '%sExpected' % component, theYield.getVal())

    def initFromExplicitVals(self,opts):
        #,init_diboson= -1.0,init_WpJ=-1.0,init_top=-1.0,init_ZpJ=-1.0,init_QCD=-1.0
        components = ['diboson', 'top', 'WpJ', 'ZpJ', 'QCD', 'WHbb']
        for component in components:
            #double init
            init = getattr(opts, 'ext%s' % component)
            #init = -2.0
            #setattr(self,init, 'init_%s' % component)
            #init = init_%s % component
            #print "init=", init
            #init = self.ws.var('init_%s' % component)
            #init.setVal(100.0)
            #init.setVal('init_%s' % component)
            #init = theYield.getVal()
            if (init>0.):
                print 'setting initial value for ',component,' to ',init
                setattr(self, '%sInitial' % component, init)


    def resetYields(self):
        if self.ws.data('data_obs'):
            Ndata = self.ws.data('data_obs').sumEntries()
        else:
            Ndata = 10000.
        print 'resetting yields...'
        components = self.pars.signals + self.pars.backgrounds
        for component in components:
            theYield = self.ws.var('n_%s' % component)
            theNorm = self.ws.var('%s_nrm' % component)
            if hasattr(self, '%sInitial' % component):
                print 'explicitly setting initial value for ',component
                theYield.setVal(getattr(self, '%sInitial' % component))
                theNorm.setVal(1.0)
                theNorm.setConstant()
            else:
                fracofdata = -1.
                if hasattr(self.pars, '%sFracOfData' % component):
                    fracofdata = getattr(self.pars, '%sFracOfData' % component)
                if (fracofdata >= 0.):
                    print 'explicitly setting ', component,' yield to be', fracofdata,' of data'
                    theYield.setVal(fracofdata*Ndata)
                elif hasattr(self, '%sExpected' % component):
                    theYield.setVal(getattr(self, '%sExpected' % component))
                else:
                    print 'no expected value for',component
                    theYield.setVal(Ndata/len(components))
            if theNorm and not theNorm.isConstant():
                theNorm.setVal(1.0)
            if component in self.pars.yieldConstraints:
                theYield.setError(theYield.getVal() * \
                                  self.pars.yieldConstraints[component])
                if theNorm:
                    theNorm.setError(self.pars.yieldConstraints[component])
            else:
                theYield.setError(sqrt(theYield.getVal()))
            theYield.Print()

    def generateToyMCSet(self,var,inputPdf,outFileName,NEvts):
        fMC = TFile(outFileName, "RECREATE");
#        thevar = self.ws.var(var);
        print 'thevar='
        print var
#        print thevar
        print '...'
#        varList = RooArgList()
#        varList.add(self.ws.var(var))
        toymc = inputPdf.generate(RooArgSet(self.ws.var(var)),NEvts);
        tMC = toymc.tree();
        fMC.cd();
        tMC.Write();
        fMC.Close();

    


    def legend4Plot(plot, left = False):
        if left:
            theLeg = TLegend(0.2, 0.62, 0.55, 0.92, "", "NDC")
        else:
            theLeg = TLegend(0.60, 0.62, 0.92, 0.92, "", "NDC")
        theLeg.SetName('theLegend')

        theLeg.SetBorderSize(0)
        theLeg.SetLineColor(0)
        theLeg.SetFillColor(0)
        theLeg.SetFillStyle(0)
        theLeg.SetLineWidth(0)
        theLeg.SetLineStyle(0)
        theLeg.SetTextFont(42)
        theLeg.SetTextSize(.045)

        entryCnt = 0
        for obj in range(0, int(plot.numItems())):
            objName = plot.nameOf(obj)
            if (not plot.getInvisible(objName)):
                theObj = plot.getObject(obj)
                objTitle = theObj.GetTitle()
                if len(objTitle) < 1:
                    objTitle = objName
                dopts = plot.getDrawOptions(objName).Data()
                # print 'obj:',theObj,'title:',objTitle,'opts:',dopts,'type:',type(dopts)
                if theObj.IsA().InheritsFrom('TNamed'):
                    theLeg.AddEntry(theObj, objTitle, dopts)
                    entryCnt += 1
        theLeg.SetY1NDC(0.9 - 0.05*entryCnt - 0.005)
        theLeg.SetY1(theLeg.GetY1NDC())
        return theLeg

    legend4Plot = staticmethod(legend4Plot)
from ROOT import RooWorkspace

workspace = RooWorkspace("electron_channel_2orMoreBtags")

workspace.factory('lepton_AbsoluteEta[0]')
workspace.factory('lumi[0]')

workspace.factory('n_signal[2200,0,10000]')
workspace.factory('n_VPlusJets[200,0,10000]')
workspace.factory('n_QCD[10,0,10000]')
workspace.factory('sum::yield(n_signal,n_VPlusJets,n_QCD)')

workspace.factory("Poisson::model_core(n,yield)")

workspace.factory("lumi[0]")

# cross section - parameter of interest
workspace.factory("xsec[0,0,0.1]")

# selection efficiency * acceptance
workspace.factory("efficiency[0]")

# signal yield
workspace.factory("prod::nsig(lumi,xsec,efficiency)")
workspace.factory("Uniform::prior(xsec)")
workspace.Print()

workspace.SaveAs('electron_channel_2orMoreBtags.root')
Пример #15
0
                              RooFit.Strategy(args.fitStrategy))
            if not args.decoBkg: res.Print()

            # decorrelated background parameters for Bayesian limits
            if args.decoBkg:
                signal_norm.setConstant()
                res = model.fitTo(rooDataHist, RooFit.Save(kTRUE),
                                  RooFit.Strategy(args.fitStrategy))
                res.Print()
                ## temp workspace for the PDF diagonalizer
                w_tmp = RooWorkspace("w_tmp")
                deco = PdfDiagonalizer("deco", w_tmp, res)
                # here diagonalizing only the shape parameters since the overall normalization is already decorrelated
                background_deco = deco.diagonalize(background)
                print "##################### workspace for decorrelation"
                w_tmp.Print("v")
                print "##################### original parameters"
                background.getParameters(rooDataHist).Print("v")
                print "##################### decorrelated parameters"
                # needed if want to evaluate limits without background systematics
                if args.fixBkg:
                    w_tmp.var("deco_eig1").setConstant()
                    w_tmp.var("deco_eig2").setConstant()
                    if not args.fixP3: w_tmp.var("deco_eig3").setConstant()
                background_deco.getParameters(rooDataHist).Print("v")
                print "##################### original pdf"
                background.Print()
                print "##################### decorrelated pdf"
                background_deco.Print()
                # release signal normalization
                signal_norm.setConstant(kFALSE)
Пример #16
0
DTF_D0sPi_M = RooFormulaVar(
    "DTF_D0sPi_M", "DTF_D0sPi_M",
    "TMath::Sqrt(1865**2+sPi_M**2 + 2*(Dst_DTF_D0_PE*Dst_DTF_sPi_PE - (Dst_DTF_D0_PX*Dst_DTF_sPi_PX+Dst_DTF_D0_PY*Dst_DTF_sPi_PY+Dst_DTF_D0_PZ*Dst_DTF_sPi_PZ)))",
    RooArgList(sPi_M, Dst_DTF_D0_PE, Dst_DTF_sPi_PE, Dst_DTF_D0_PX,
               Dst_DTF_sPi_PX, Dst_DTF_D0_PY, Dst_DTF_sPi_PY, Dst_DTF_D0_PZ,
               Dst_DTF_sPi_PZ))
dataset_WS.addColumn(DTF_D0sPi_M).setRange(1700, 2100)
dataset_RS.addColumn(DTF_D0sPi_M).setRange(1700, 2100)

try:
    test_mode = sys.argv[2]
except:
    test_mode = False

wspace = RooWorkspace("wspace")
wspace.Print("t")
if not test_mode:
    #Here is address of output file
    wsfile = TFile(
        "/afs/cern.ch/user/" + prefix + "/" + user + "/eos/lhcb/user/" +
        prefix + "/" + user + "/WrongSign/2015/WorkSpaces/WorkSpace" +
        id_seed + ".root", "recreate")
else:
    wsfile = TFile("WorkSpace" + id_seed + ".root", "recreate")
wspace.rfimport(varset)
wspace.rfimport(varset_comb)
wspace.rfimport(dataset_COMB_OS)
wspace.rfimport(dataset_COMB_SS)
wspace.rfimport(dataset_WS)
wspace.rfimport(dataset_RS)
wspace.Write("wspace")
Пример #17
0
        pedDS.plotOn(xfped)
        if opts.sipm:
            ws.pdf('pedPlusOne').plotOn(xfped)
            ws.pdf('pedPlusOne').paramOn(xfped)
        else:
            ws.pdf('ped').plotOn(xfped)
            ws.pdf('ped').paramOn(xfped)

        c1 = TCanvas('c1', 'pedestal')
        xfped.Draw()

        makeHistPdf(ped_hist, ws, x)
        savePedWidth = ws.var('pedWidth').getVal()

    ws.Print()

dataTree.Draw(
    '{0}>>sig_hist({1},{2:0.1f},{3:0.1f})'.format(HOTower, Nbins, minMip,
                                                  maxMip), sigCut, 'goff')
sig_hist = gDirectory.Get('sig_hist')
x.setRange(minMip, maxMip)

if (sig_hist.GetEntries > 0):
    ## fpar = array('d', [0.]*7)
    ## fparerr = array('d', [0.]*7)
    ## fpar[6] = pedRms

    ## chisqr = Double(0.)
    ## ndf = Long(0)
Пример #18
0
def ControlDataFit(free=True, sim=True):

    w = RooWorkspace('w_ctrl', 'w_ctrl')

    samples = ['b0g', 'bsg', 'cg', 'b0pi0', 'bspi0', 'cpi0']

    # create the category
    w.factory('cat[%s]' % (','.join(samples)))

    files = {
        'b0g':
        path + "../New/Tuples/Data/9_B2DstKpi_Dst2DgammTuple_BestCut.root",
        'b0pi0':
        path + "../New/Tuples/Data/9_B2Dstpi0Tuple_BestCut.root",
        'bsg':
        path + "../New/Tuples/Data/9_Bs2DstKpi_Dst2DgammaTuple_BestCut.root",
        'bspi0':
        path + "../New/Tuples/Data/9_Bs2Dstpi0Tuple_BestCut.root",
        'cg':
        path + "../New/Tuples/Data/9_B2Dstpipi_Dst2DgammTuple_BestCut.root",
        'cpi0':
        path + "../New/Tuples/Data/9_B2Dstpipi_Dst2Dpi0Tuple_No16_BestCut.root"
    }

    # Make the dsets
    w.factory("B_DTFDict_D0_B_M[5100,5900]")
    w.var("B_DTFDict_D0_B_M").setBins(80)
    for samp in samples:
        assert (os.path.exists(files[samp]))
        tf = TFile(files[samp])
        t = tf.Get('DecayTree')
        t.SetBranchStatus("*", 0)
        t.SetBranchStatus("B_DTFDict_D0_B_M", 1)
        dset = RooDataSet("data_%s" % (samp), "", t,
                          RooArgSet(w.var("B_DTFDict_D0_B_M")))
        getattr(w, 'import')(dset)
        tf.Close()

    c = TCanvas('ctrl', 'ctrl', 2100, 1200)
    c.Divide(3, 2)
    for i, samp in enumerate(samples):
        pdfname = 'data_pdf_%s' % (samp)
        dsetname = 'data_%s' % (samp)
        plot(c.cd(i + 1), w, pdfname, dsetname)
    c.Update()
    c.Modified()
    c.Print("plots/ctrl.pdf")

    # Make the total pdf

    # First try and merge the different bits from the different workspaces
    ImportMCShapes(w)

    # now want to make the ctrl pdfs
    # signal and misrec are the same as b0
    sig_cg = w.pdf('sig_mc_pdf_b0g').Clone('sig_mc_pdf_cg')
    getattr(w, 'import')(sig_cg)
    sig_cpi0 = w.pdf('sig_mc_pdf_b0pi0').Clone('sig_mc_pdf_cpi0')
    getattr(w, 'import')(sig_cpi0)
    misrec_cg = w.pdf('misrec_mc_pdf_b0g').Clone('misrec_mc_pdf_cg')
    getattr(w, 'import')(misrec_cg)
    misrec_cpi0 = w.pdf('misrec_mc_pdf_b0pi0').Clone('misrec_mc_pdf_cpi0')
    getattr(w, 'import')(misrec_cpi0)
    # ignore the lambdas for now
    # there will be some Bs0 -> D*0 piK stuff with a misID'd K (I think this is the big bit which appears below the peak)
    # do 1CB for this
    w.factory('dm_ctrl_misidk2pi[-150,-450,-50]')
    w.factory('sum::bdstkp_cg_mean( b0g_mean, dm_ctrl_misidk2pi)')
    w.factory('sum::bdstkp_cpi0_mean( b0pi0_mean, dm_ctrl_misidk2pi)')
    w.factory('bdstkp_cg_sigma[40,5,200]')
    w.factory('bdstkp_cpi0_sigma[40,5,200]')
    w.factory('bdstkp_c_alpha1[-2.1,-4,0]')
    w.factory('bdstkp_c_n1[3]')
    w.factory(
        'CBShape::bdstkp_mc_pdf_cg( B_DTFDict_D0_B_M, bdstkp_cg_mean, bdstkp_cg_sigma, bdstkp_c_alpha1, bdstkp_c_n1 )'
    )
    w.factory(
        'CBShape::bdstkp_mc_pdf_cpi0( B_DTFDict_D0_B_M, bdstkp_cpi0_mean, bdstkp_cpi0_sigma, bdstkp_c_alpha1, bdstkp_c_n1 )'
    )

    # the stuff above the peak is probably mostly B- -> D*0 pi- with another random pi so could get this shape and shift it
    w.factory('dm_ctrl_dstpi[100,10,300]')
    w.factory('sum::bdsth_cg_mean( bdsth_b0g_mean, dm_ctrl_dstpi )')
    w.factory('sum::bdsth_cpi0_mean( bdsth_b0pi0_mean, dm_ctrl_dstpi )')
    w.factory(
        "CBShape::bdsth_cg_cb1( B_DTFDict_D0_B_M, bdsth_cg_mean, bdsth_b0g_sigma, bdsth_alpha1, bdsth_n1 )"
    )
    w.factory(
        "CBShape::bdsth_cg_cb2( B_DTFDict_D0_B_M, bdsth_cg_mean, bdsth_b0g_sigma, bdsth_alpha2, bdsth_n2 )"
    )
    w.factory("SUM::bdsth_mc_pdf_cg( bdsth_f1*bdsth_cg_cb1, bdsth_cg_cb2 )")
    w.factory(
        "CBShape::bdsth_cpi0_cb1( B_DTFDict_D0_B_M, bdsth_cpi0_mean, bdsth_b0pi0_sigma, bdsth_alpha1, bdsth_n1 )"
    )
    w.factory(
        "CBShape::bdsth_cpi0_cb2( B_DTFDict_D0_B_M, bdsth_cpi0_mean, bdsth_b0pi0_sigma, bdsth_alpha2, bdsth_n2 )"
    )
    w.factory(
        "SUM::bdsth_mc_pdf_cpi0( bdsth_f1*bdsth_cpi0_cb1, bdsth_cpi0_cb2 )")

    # Then make combinatorial shape in each cateogry
    # let these be independent for now
    for samp in samples:
        w.factory("comb_mc_%s_p0[-0.001,-0.1,0.]" % samp)
        w.factory(
            "Exponential::comb_mc_pdf_%s( B_DTFDict_D0_B_M, comb_mc_%s_p0 )" %
            (samp, samp))
        w.factory("%s_comb_y[3000,0,12000]" % samp)

    # Now need to figure out what yields to restrict

    # sig yield first (require b0 / bs ratio consistent between g and pi0)
    w.factory("b0g_sig_y[3000,0,12000]")
    w.factory("b0pi0_sig_y[800,0,4000]")
    w.factory("bs2b0_rat[2.5,1.,4.]")
    w.factory("prod::bsg_sig_y(b0g_sig_y, bs2b0_rat)")
    w.factory("prod::bspi0_sig_y(b0pi0_sig_y, bs2b0_rat)")
    w.factory("cg_sig_y[6000,0,32000]")
    w.factory("cpi0_sig_y[1000,0,8000]")

    # now mis rec yield (ratio of this to sig should be the same for b0 and bs but will be different for g vs pi0)
    w.factory("misrec_to_sig_rat_g[0.2,0.001,0.6]")
    w.factory("misrec_to_sig_rat_pi0[0.2,0.001,0.6]")
    w.factory("prod::b0g_misrec_y( misrec_to_sig_rat_g, b0g_sig_y )")
    w.factory("prod::b0pi0_misrec_y( misrec_to_sig_rat_pi0, b0pi0_sig_y )")
    w.factory("prod::bsg_misrec_y( misrec_to_sig_rat_g, bsg_sig_y )")
    w.factory("prod::bspi0_misrec_y( misrec_to_sig_rat_pi0, bspi0_sig_y )")
    w.factory("prod::cg_misrec_y( misrec_to_sig_rat_g, cg_sig_y )")
    w.factory("prod::cpi0_misrec_y( misrec_to_sig_rat_pi0, cpi0_sig_y )")

    # the cases of B->D*pipi, B->D*KK, Lb->D*ph all involve a misID so will
    # be different for B0 and Bs (as they differ with a K or pi misID) however
    # for all of these the ratio of g -> pi0 should be the same
    # there is also Bs->D*KK which should scale the same for g and pi0 modes
    w.factory("misid_g2pi0_rat[0.1,0.0001,10.]")
    w.factory("b0g_bdstpp_y[1000,0,12000]")
    w.factory("bsg_bdstpp_y[1000,0,12000]")
    w.factory("prod::b0pi0_bdstpp_y( misid_g2pi0_rat, b0g_bdstpp_y )")
    w.factory("prod::bspi0_bdstpp_y( misid_g2pi0_rat, bsg_bdstpp_y )")
    w.factory("b0g_bdstkk_y[1000,0,12000]")
    w.factory("bsg_bdstkk_y[1000,0,12000]")
    w.factory("prod::b0pi0_bdstkk_y( misid_g2pi0_rat, b0g_bdstkk_y )")
    w.factory("prod::bspi0_bdstkk_y( misid_g2pi0_rat, bsg_bdstkk_y )")
    w.factory("b0g_lbdstph_y[1000,0,12000]")
    w.factory("bsg_lbdstph_y[1000,0,12000]")
    w.factory("prod::b0pi0_lbdstph_y( misid_g2pi0_rat, b0g_lbdstph_y )")
    w.factory("prod::bspi0_lbdstph_y( misid_g2pi0_rat, bsg_lbdstph_y )")
    w.factory("bsdstkk_to_bdstkk_rat[1.,0.1,2.]")
    w.factory("prod::b0g_bsdstkk_y( bsdstkk_to_bdstkk_rat, b0g_bdstkk_y )")
    w.factory("prod::b0pi0_bsdstkk_y( bsdstkk_to_bdstkk_rat, b0pi0_bdstkk_y )")
    w.factory("prod::bsg_bsdstkk_y( bsdstkk_to_bdstkk_rat, bsg_bdstkk_y )")
    w.factory("prod::bspi0_bsdstkk_y( bsdstkk_to_bdstkk_rat, bspi0_bdstkk_y )")

    # B -> DKpi same logic as misrec
    w.factory("bdkp_to_sig_rat_g[0.2,0.001,0.6]")
    w.factory("bdkp_to_sig_rat_pi0[0.2,0.001,0.6]")
    w.factory("prod::b0g_bdkp_y( bdkp_to_sig_rat_g, b0g_sig_y )")
    w.factory("prod::b0pi0_bdkp_y( bdkp_to_sig_rat_pi0, b0pi0_sig_y )")
    w.factory("prod::bsg_bdkp_y( bdkp_to_sig_rat_g, bsg_sig_y )")
    w.factory("prod::bspi0_bdkp_y( bdkp_to_sig_rat_pi0, bspi0_sig_y )")

    # infact can be much more sophisitcated with efficiencies etc here
    # i.e. if the PID cut distinguishing B -> D0 Kpi from B -> D0 pipi is binary one knows the exact yield of the cross feed in each
    # the B -> DKp cross feed yield (float for now)
    w.factory("cg_bdstkp_y[3000,0,12000]")
    w.factory("cpi0_bdstkp_y[800,0,4000]")

    # B -> D* K / B -> D* pi (adding random pi- to B0 and random K- to Bs0)
    # so ratio to signal should be same for both g and pi0 modes but
    # different for B0 -> Bs
    w.factory("bdsth_to_sig_rat_addpi[0.2,0.001,0.6]")
    w.factory("bdsth_to_sig_rat_addk[0.2,0.001,0.6]")
    w.factory("prod::b0g_bdsth_y( bdsth_to_sig_rat_addpi, b0g_sig_y )")
    w.factory("prod::b0pi0_bdsth_y( bdsth_to_sig_rat_addpi, b0pi0_sig_y )")
    w.factory("prod::bsg_bdsth_y( bdsth_to_sig_rat_addk, bsg_sig_y )")
    w.factory("prod::bspi0_bdsth_y( bdsth_to_sig_rat_addk, bspi0_sig_y )")
    # the B- -> D* pi- (can probably constrain this better as well)
    w.factory("cg_bdsth_y[3000,0,12000]")
    w.factory("cpi0_bdsth_y[800,0,4000]")

    # Lb -> Dph (mid-ID k for p and pi for p and add random g or pi0) so will be different for all 4 really
    # express this ratio to the Lb -> D*ph one (they should be similar in magnitude?)
    w.factory("lbdph_to_lbdstph_b0g[1.,0.5,2.]")
    w.factory("lbdph_to_lbdstph_b0pi0[1.,0.5,2.]")
    w.factory("lbdph_to_lbdstph_bsg[1.,0.5,2.]")
    w.factory("lbdph_to_lbdstph_bspi0[1.,0.5,2.]")
    w.factory("prod::b0g_lbdph_y( lbdph_to_lbdstph_b0g, b0g_lbdstph_y )")
    w.factory("prod::b0pi0_lbdph_y( lbdph_to_lbdstph_b0pi0, b0pi0_lbdstph_y )")
    w.factory("prod::bsg_lbdph_y( lbdph_to_lbdstph_bsg, bsg_lbdstph_y )")
    w.factory("prod::bspi0_lbdph_y( lbdph_to_lbdstph_bspi0, bspi0_lbdstph_y )")

    # Part reco shape should have same Bs / B0 ratio
    w.factory("partrec_to_sig_rat_g[0.2,0.001,0.6]")
    w.factory("partrec_to_sig_rat_pi0[0.2,0.001,0.6]")
    w.factory("prod::b0g_partrec_y( partrec_to_sig_rat_g, b0g_sig_y )")
    w.factory("prod::b0pi0_partrec_y( partrec_to_sig_rat_pi0, b0pi0_sig_y )")
    w.factory("prod::bsg_partrec_y( partrec_to_sig_rat_g, bsg_sig_y )")
    w.factory("prod::bspi0_partrec_y( partrec_to_sig_rat_pi0, bspi0_sig_y )")

    # make the yields (different for ctrl and b0 / bs)

    b_components = [
        'sig', 'misrec', 'bdstpp', 'bdstkk', 'bsdstkk', 'bdkp', 'bdsth',
        'partrec', 'lbdph', 'lbdstph', 'comb'
    ]
    for samp in ['b0g', 'b0pi0', 'bsg', 'bspi0']:
        fact_str = "SUM::data_pdf_%s(" % samp
        for comp in b_components:
            fact_str += "%s_%s_y*%s_mc_pdf_%s," % (samp, comp, comp, samp)
        fact_str = fact_str[:-1] + ")"
        w.factory(fact_str)
        w.pdf('data_pdf_%s' % samp).Print('v')

    ctrl_components = ['sig', 'misrec', 'bdstkp', 'bdsth', 'comb']
    for samp in ['cg', 'cpi0']:
        fact_str = "SUM::data_pdf_%s(" % samp
        for comp in ctrl_components:
            fact_str += "%s_%s_y*%s_mc_pdf_%s," % (samp, comp, comp, samp)
        fact_str = fact_str[:-1] + ")"
        w.factory(fact_str)
        w.pdf('data_pdf_%s' % samp).Print('v')

    CreateSimPdf(w, 'data')
    CreateSimData(w, 'data')

    # Now fix appropriate parameters
    # To start with we'll fix all shape parameters from MC and just float the yields (and exponential slope)
    for comp in b_components:
        if comp == 'comb': continue  # no pre-defined shape for combinatorial
        if comp == 'bsdstkk':
            continue  # this params for this piece are covered by bdstkk
        w.set('%s_mc_sim_pdf_pars' % comp).setAttribAll("Constant")

    # Now relax the constraints on a few important params
    w.var("b0g_mean").setConstant(False)
    w.var("b0g_sigma").setConstant(False)
    #w.var("dm_b02bs").setConstant(False)
    #w.var("dm_g2pi0").setConstant(False)
    #w.var("ssig_b02bs").setConstant(False)
    #w.var("ssig_g2pi0").setConstant(False)

    #w.var("b0g_misrec_mean").setConstant(False)
    #w.var("b0g_misrec_sigma").setConstant(False)
    #w.var("dm_missg2addg").setConstant(False)
    #w.var("ssig_missg2addg").setConstant(False)

    w.Print('v')
    w.pdf('data_sim_pdf').Print('v')
    w.data('data_sim_data').Print('v')

    # free fit first
    if free:
        for i, samp in enumerate(samples):
            pdfname = 'data_pdf_%s' % (samp)
            dsetname = 'data_%s' % (samp)
            w.pdf(pdfname).fitTo(
                w.data(dsetname))  # nothing to fit in this case
            pars = w.pdf(pdfname).getParameters(
                RooArgSet(w.var("B_DTFDict_D0_B_M")))
            w.saveSnapshot('data_free_fit_%s' % samp, pars)

    if sim:
        pdfname = 'data_sim_pdf'
        dsetname = 'data_sim_data'
        w.pdf(pdfname).fitTo(w.data(dsetname))
        pars = w.pdf(pdfname).getParameters(
            RooArgSet(w.var("B_DTFDict_D0_B_M")))
        w.saveSnapshot('data_sim_fit', pars)

    w.writeToFile('files/w_ctrl.root')
Пример #19
0
    wsFN = outdir_datacards + 'Qstar' + str(
        mass) + '_workspace_' + name + '.root'

nObs = dataHist_data.sumEntries()
#nObs = roohistBkg.sumEntries();
#nBkg = roohistBkg.sumEntries();

w = RooWorkspace('w', 'workspace')
getattr(w, 'import')(signal)
getattr(w, 'import')(background)
getattr(w, 'import')(background_norm)
getattr(w, 'import')(roohistBkg, RooFit.Rename("data_obs"))
#getattr(w,'import')(dataHist_data,RooFit.Rename("data_obs"))
#getattr(w,'import')(background_f6)
#getattr(w,'import')(background_f6_norm)
w.Print()
w.writeToFile(wsFN)

# -----------------------------------------
# write a datacard
##not needed
#ExpectedSignalRate = signalCrossSection*LUMI*signalEfficiency

datacard = open(dcFN, 'w')
datacard.write('imax 1\n')
datacard.write('jmax 1\n')
datacard.write('kmax *\n')
datacard.write('---------------\n')
datacard.write('shapes * * ' + wsFN + ' w:$PROCESS\n')
datacard.write('---------------\n')
datacard.write('bin 1\n')
def rooFit502():

    print ">>> create workspace..."
    workspace = RooWorkspace("workspace", "workspace")

    print ">>> create typedef (shorthands)..."
    workspace.factory("$Typedef(Gaussian,Gaus)")
    workspace.factory("$Typedef(Chebychev,Cheby)")

    print ">>> operator pdf examples..."

    print ">>>   SUM (coef1*pdf1,pdf2)         - pdf addition"
    workspace.factory(
        "SUM::summodel( f[0,1]*Gaussian::gx(x[-10,10],m[0],1.0), Chebychev::ch(x,{0.1,0.2,-0.3}) )"
    )

    print ">>>   SUM (yield1*pdf1,yield2*pdf2) - extended pdf addition"
    workspace.factory("SUM::extsummodel( Nsig[0,1000]*gx, Nbkg[0,1000]*ch )")

    print ">>>   PROD ( pdf1, pdf2 )           - pdf multiplication"
    # PDF multiplication is done with PROD ( pdf1, pdf2 )
    workspace.factory("PROD::gxz( gx, Gaussian::gz(z[-10,10],0,1) )")

    print ">>>   PROD ( pdf1|obs, pdf2 )       - conditional p.d.f multiplication"
    workspace.factory("Gaussian::gy( y[-10,10], x, 1.0 )")
    workspace.factory("PROD::gxycond( gy|x, gx )")

    print ">>>   NCONV (obs,pdf1,pdf2)         - numeric convolution"
    print ">>>   FCONV (obs,pdf1,pdf2)         - fft convolution"
    workspace.factory(
        "FCONV::lxg( x, Gaussian::g(x,mg[0],1), Landau::lc(x,0,1) )")

    print ">>>   SIMUL( index, state1=pdf1, state2=pdf2,...) - simultaneous pdfs are constructed"
    workspace.factory(
        "SIMUL::smodel( c[A=0,B=1], A=Gaussian::gs(x,m,s[1]), B=Landau::ls(x,0,1) )"
    )

    print ">>> operator function examples..."

    print ">>>   prod (func1, func2,...)       - function multiplication"
    workspace.factory("prod::uv(u[10],v[10])")

    print ">>>   sum (func1, func2,...)        - function addition"
    workspace.factory("sum::uv2(u,v)")

    print ">>> interpreted and compiled expression based pdfs..."
    print ">>>   create a RooGenericPdf interpreted pdf by using single quotes to pass the expression string argument"
    workspace.factory("EXPR::G('x*x+1',x)")

    # Create a custom compiled p.d.f similar to the above interpreted p.d.f.
    # The code required to make this p.d.f. is automatically embedded in the workspace
    workspace.factory("CEXPR::GC('x*x+a',{x,a[1]})")

    # Compiled and interpreted functions (rather than pdfs) can be made with the lower case
    # 'expr' and 'cexpr' types

    print ">>> print workspace contents:"
    workspace.Print()

    print "\n>>> save workspace in memory..."
    gDirectory.Add(workspace)