def alpha(channel): nElec = channel.count('e') nMuon = channel.count('m') nLept = nElec + nMuon nBtag = channel.count('b') # Channel-dependent settings # Background function. Semi-working options are: EXP, EXP2, EXPN, EXPTAIL if nLept == 0: treeName = 'SR' signName = 'XZh' colorVjet = sample['DYJetsToNuNu']['linecolor'] triName = "HLT_PFMET" leptCut = "0==0" topVeto = selection["TopVetocut"] massVar = "X_cmass" binFact = 1 #fitFunc = "EXP" #fitFunc = "EXP2" #fitFunc = "EXPN" #fitFunc = "EXPTAIL" fitFunc = "EXPN" if nBtag < 2 else "EXP" fitAltFunc = "EXPTAIL" if nBtag < 2 else "EXPTAIL" fitFuncVjet = "ERFEXP" if nBtag < 2 else "ERFEXP" fitFuncVV = "EXPGAUS" fitFuncTop = "GAUS2" elif nLept == 1: treeName = 'WCR' signName = 'XWh' colorVjet = sample['WJetsToLNu']['linecolor'] triName = "HLT_Ele" if nElec > 0 else "HLT_Mu" leptCut = "isWtoEN" if nElec > 0 else "isWtoMN" topVeto = selection["TopVetocut"] massVar = "X_mass" binFact = 2 if nElec > 0: fitFunc = "EXP" if nBtag < 2 else "EXP" fitAltFunc = "EXPTAIL" if nBtag < 2 else "EXPTAIL" else: fitFunc = "EXPTAIL" if nBtag < 2 else "EXP" fitAltFunc = "EXPN" if nBtag < 2 else "EXPTAIL" fitFuncVjet = "ERFEXP" if nBtag < 2 else "ERFEXP" fitFuncVV = "EXPGAUS" fitFuncTop = "GAUS3" if nBtag < 2 else "GAUS2" else: treeName = 'XZh' signName = 'XZh' colorVjet = sample['DYJetsToLL']['linecolor'] triName = "HLT_Ele" if nElec > 0 else "HLT_Mu" leptCut = "isZtoEE" if nElec > 0 else "isZtoMM" topVeto = "0==0" massVar = "X_mass" binFact = 5 if nElec > 0: fitFunc = "EXP" if nBtag < 2 else "EXP" fitAltFunc = "POW" if nBtag < 2 else "POW" else: fitFunc = "EXP" if nBtag < 2 else "EXP" fitAltFunc = "POW" if nBtag < 2 else "POW" fitFuncVjet = "ERFEXP" if nBtag < 2 else "EXP" fitFuncVV = "EXPGAUS2" fitFuncTop = "GAUS" btagCut = selection["2Btag"] if nBtag == 2 else selection["1Btag"] print "--- Channel", channel, "---" print " number of electrons:", nElec, " muons:", nMuon, " b-tags:", nBtag print " read tree:", treeName, "and trigger:", triName if ALTERNATIVE: print " using ALTERNATIVE fit functions" print "-"*11*2 # Silent RooFit RooMsgService.instance().setGlobalKillBelow(RooFit.FATAL) #*******************************************************# # # # Variables and selections # # # #*******************************************************# # Define all the variables from the trees that will be used in the cuts and fits # this steps actually perform a "projection" of the entire tree on the variables in thei ranges, so be careful once setting the limits X_mass = RooRealVar( massVar, "m_{X}" if nLept > 0 else "m_{T}^{X}", XBINMIN, XBINMAX, "GeV") J_mass = RooRealVar( "fatjet1_prunedMassCorr", "corrected pruned mass", HBINMIN, HBINMAX, "GeV") CSV1 = RooRealVar( "fatjet1_CSVR1", "", -1.e99, 1.e4 ) CSV2 = RooRealVar( "fatjet1_CSVR2", "", -1.e99, 1.e4 ) nBtag = RooRealVar( "fatjet1_nBtag", "", 0., 4 ) CSVTop = RooRealVar( "bjet1_CSVR", "", -1.e99, 1.e4 ) isZtoEE = RooRealVar("isZtoEE", "", 0., 2 ) isZtoMM = RooRealVar("isZtoMM", "", 0., 2 ) isWtoEN = RooRealVar("isWtoEN", "", 0., 2 ) isWtoMN = RooRealVar("isWtoMN", "", 0., 2 ) weight = RooRealVar( "eventWeightLumi", "", -1.e9, 1. ) # Define the RooArgSet which will include all the variables defined before # there is a maximum of 9 variables in the declaration, so the others need to be added with 'add' variables = RooArgSet(X_mass, J_mass, CSV1, CSV2, nBtag, CSVTop) variables.add(RooArgSet(isZtoEE, isZtoMM, isWtoEN, isWtoMN, weight)) # Define the ranges in fatJetMass - these will be used to define SB and SR J_mass.setRange("LSBrange", LOWMIN, LOWMAX) J_mass.setRange("HSBrange", HIGMIN, HIGMAX) J_mass.setRange("VRrange", LOWMAX, SIGMIN) J_mass.setRange("SRrange", SIGMIN, SIGMAX) J_mass.setBins(54) # Define the selection for the various categories (base + SR / LSBcut / HSBcut ) baseCut = leptCut + " && " + btagCut + "&&" + topVeto massCut = massVar + ">%d" % XBINMIN baseCut += " && " + massCut # Cuts SRcut = baseCut + " && %s>%d && %s<%d" % (J_mass.GetName(), SIGMIN, J_mass.GetName(), SIGMAX) LSBcut = baseCut + " && %s>%d && %s<%d" % (J_mass.GetName(), LOWMIN, J_mass.GetName(), LOWMAX) HSBcut = baseCut + " && %s>%d && %s<%d" % (J_mass.GetName(), HIGMIN, J_mass.GetName(), HIGMAX) SBcut = baseCut + " && ((%s>%d && %s<%d) || (%s>%d && %s<%d))" % (J_mass.GetName(), LOWMIN, J_mass.GetName(), LOWMAX, J_mass.GetName(), HIGMIN, J_mass.GetName(), HIGMAX) VRcut = baseCut + " && %s>%d && %s<%d" % (J_mass.GetName(), LOWMAX, J_mass.GetName(), SIGMIN) # Binning binsJmass = RooBinning(HBINMIN, HBINMAX) binsJmass.addUniform(HBINS, HBINMIN, HBINMAX) binsXmass = RooBinning(XBINMIN, XBINMAX) binsXmass.addUniform(binFact*XBINS, XBINMIN, XBINMAX) #*******************************************************# # # # Input files # # # #*******************************************************# # Import the files using TChains (separately for the bkg "classes" that we want to describe: here DY and VV+ST+TT) treeData = TChain(treeName) treeMC = TChain(treeName) treeVjet = TChain(treeName) treeVV = TChain(treeName) treeTop = TChain(treeName) # treeSign = {} # nevtSign = {} # Read data pd = getPrimaryDataset(triName) if len(pd)==0: raw_input("Warning: Primary Dataset not recognized, continue?") for i, s in enumerate(pd): treeData.Add(NTUPLEDIR + s + ".root") # Read V+jets backgrounds for i, s in enumerate(["WJetsToLNu_HT", "DYJetsToNuNu_HT", "DYJetsToLL_HT"]): for j, ss in enumerate(sample[s]['files']): treeVjet.Add(NTUPLEDIR + ss + ".root") # Read VV backgrounds for i, s in enumerate(["VV"]): for j, ss in enumerate(sample[s]['files']): treeVV.Add(NTUPLEDIR + ss + ".root") # Read Top backgrounds for i, s in enumerate(["ST", "TTbar"]): for j, ss in enumerate(sample[s]['files']): treeTop.Add(NTUPLEDIR + ss + ".root") # Sum all background MC treeMC.Add(treeVjet) treeMC.Add(treeVV) treeMC.Add(treeTop) # create a dataset to host data in sideband (using this dataset we are automatically blind in the SR!) setDataSB = RooDataSet("setDataSB", "setDataSB", variables, RooFit.Cut(SBcut), RooFit.WeightVar(weight), RooFit.Import(treeData)) setDataLSB = RooDataSet("setDataLSB", "setDataLSB", variables, RooFit.Import(setDataSB), RooFit.Cut(LSBcut), RooFit.WeightVar(weight)) setDataHSB = RooDataSet("setDataHSB", "setDataHSB", variables, RooFit.Import(setDataSB), RooFit.Cut(HSBcut), RooFit.WeightVar(weight)) # Observed data (WARNING, BLIND!) setDataSR = RooDataSet("setDataSR", "setDataSR", variables, RooFit.Cut(SRcut), RooFit.WeightVar(weight), RooFit.Import(treeData)) setDataVR = RooDataSet("setDataVR", "setDataVR", variables, RooFit.Cut(VRcut), RooFit.WeightVar(weight), RooFit.Import(treeData)) # Observed in the VV mass, just for plotting purposes # same for the bkg datasets from MC, where we just apply the base selections (not blind) setVjet = RooDataSet("setVjet", "setVjet", variables, RooFit.Cut(baseCut), RooFit.WeightVar(weight), RooFit.Import(treeVjet)) setVjetSB = RooDataSet("setVjetSB", "setVjetSB", variables, RooFit.Import(setVjet), RooFit.Cut(SBcut), RooFit.WeightVar(weight)) setVjetSR = RooDataSet("setVjetSR", "setVjetSR", variables, RooFit.Import(setVjet), RooFit.Cut(SRcut), RooFit.WeightVar(weight)) setVV = RooDataSet("setVV", "setVV", variables, RooFit.Cut(baseCut), RooFit.WeightVar(weight), RooFit.Import(treeVV)) setVVSB = RooDataSet("setVVSB", "setVVSB", variables, RooFit.Import(setVV), RooFit.Cut(SBcut), RooFit.WeightVar(weight)) setVVSR = RooDataSet("setVVSR", "setVVSR", variables, RooFit.Import(setVV), RooFit.Cut(SRcut), RooFit.WeightVar(weight)) setTop = RooDataSet("setTop", "setTop", variables, RooFit.Cut(baseCut), RooFit.WeightVar(weight), RooFit.Import(treeTop)) setTopSB = RooDataSet("setTopSB", "setTopSB", variables, RooFit.Import(setTop), RooFit.Cut(SBcut), RooFit.WeightVar(weight)) setTopSR = RooDataSet("setTopSR", "setTopSR", variables, RooFit.Import(setTop), RooFit.Cut(SRcut), RooFit.WeightVar(weight)) print " Data events SB: %.2f" % setDataSB.sumEntries() print " V+jets entries: %.2f" % setVjet.sumEntries() print " VV, VH entries: %.2f" % setVV.sumEntries() print " Top,ST entries: %.2f" % setTop.sumEntries() # the relative normalization of the varius bkg is taken from MC by counting all the events in the full fatJetMass range #coef = RooRealVar("coef", "coef", setVV.sumEntries()/setVjet.sumEntries(),0.,1.) coef_VV_Vjet = RooRealVar("coef2_1", "coef2_1", setVV.sumEntries()/setVjet.sumEntries(), 0., 1.) coef_Top_VVVjet = RooRealVar("coef3_21", "coef3_21", setTop.sumEntries()/(setVjet.sumEntries()+setVV.sumEntries()),0.,1.); coef_VV_Vjet.setConstant(True) coef_Top_VVVjet.setConstant(True) # Define entries entryVjet = RooRealVar("entryVjets", "V+jets normalization", setVjet.sumEntries(), 0., 1.e6) entryVV = RooRealVar("entryVV", "VV normalization", setVV.sumEntries(), 0., 1.e6) entryTop = RooRealVar("entryTop", "Top normalization", setTop.sumEntries(), 0., 1.e6) entrySB = RooRealVar("entrySB", "Data SB normalization", setDataSB.sumEntries(SBcut), 0., 1.e6) entrySB.setError(math.sqrt(entrySB.getVal())) entryLSB = RooRealVar("entryLSB", "Data LSB normalization", setDataSB.sumEntries(LSBcut), 0., 1.e6) entryLSB.setError(math.sqrt(entryLSB.getVal())) entryHSB = RooRealVar("entryHSB", "Data HSB normalization", setDataSB.sumEntries(HSBcut), 0., 1.e6) entryHSB.setError(math.sqrt(entryHSB.getVal())) #*******************************************************# # # # NORMALIZATION # # # #*******************************************************# # set reasonable ranges for J_mass and X_mass # these are used in the fit in order to avoid ROOFIT to look in regions very far away from where we are fitting J_mass.setRange("h_reasonable_range", LOWMIN, HIGMAX) X_mass.setRange("X_reasonable_range", XBINMIN, XBINMAX) # Set RooArgSets once for all, see https://root.cern.ch/phpBB3/viewtopic.php?t=11758 jetMassArg = RooArgSet(J_mass) #*******************************************************# # # # V+jets normalization # # # #*******************************************************# # Variables for V+jets constVjet = RooRealVar("constVjet", "slope of the exp", -0.020, -1., 0.) offsetVjet = RooRealVar("offsetVjet", "offset of the erf", 30., -50., 200.) widthVjet = RooRealVar("widthVjet", "width of the erf", 100., 1., 200.) offsetVjet.setConstant(True) a0Vjet = RooRealVar("a0Vjet", "width of the erf", -0.1, -5, 0) a1Vjet = RooRealVar("a1Vjet", "width of the erf", 0.6, 0, 5) a2Vjet = RooRealVar("a2Vjet", "width of the erf", -0.1, -1, 1) # Define V+jets model if fitFuncVjet == "ERFEXP": modelVjet = RooErfExpPdf("modelVjet", "error function for V+jets mass", J_mass, constVjet, offsetVjet, widthVjet) elif fitFuncVjet == "EXP": modelVjet = RooExponential("modelVjet", "exp for V+jets mass", J_mass, constVjet) elif fitFuncVjet == "POL": modelVjet = RooChebychev("modelVjet", "polynomial for V+jets mass", J_mass, RooArgList(a0Vjet, a1Vjet, a2Vjet)) elif fitFuncVjet == "POW": modelVjet = RooGenericPdf("modelVjet", "powerlaw for X mass", "@0^@1", RooArgList(J_mass, a0Vjet)) else: print " ERROR! Pdf", fitFuncVjet, "is not implemented for Vjets" exit() # fit to main bkg in MC (whole range) frVjet = modelVjet.fitTo(setVjet, RooFit.SumW2Error(True), RooFit.Range("h_reasonable_range"), RooFit.Strategy(2), RooFit.Minimizer("Minuit2"), RooFit.Save(1), RooFit.PrintLevel(1 if VERBOSE else -1)) # integrals and number of events iSBVjet = modelVjet.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg), RooFit.Range("LSBrange,HSBrange")) iLSBVjet = modelVjet.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg), RooFit.Range("LSBrange")) iHSBVjet = modelVjet.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg), RooFit.Range("HSBrange")) iSRVjet = modelVjet.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg), RooFit.Range("SRrange")) iVRVjet = modelVjet.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg), RooFit.Range("VRrange")) # Do not remove the following lines, integrals are computed here iALVjet = modelVjet.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg)) nSBVjet = iSBVjet.getVal()/iALVjet.getVal()*setVjet.sumEntries(SBcut) nLSBVjet = iLSBVjet.getVal()/iALVjet.getVal()*setVjet.sumEntries(LSBcut) nHSBVjet = iHSBVjet.getVal()/iALVjet.getVal()*setVjet.sumEntries(HSBcut) nSRVjet = iSRVjet.getVal()/iALVjet.getVal()*setVjet.sumEntries(SRcut) drawPlot("JetMass_Vjet", channel, J_mass, modelVjet, setVjet, binsJmass, frVjet) if VERBOSE: print "********** Fit result [JET MASS Vjets] *"+"*"*40, "\n", frVjet.Print(), "\n", "*"*80 #*******************************************************# # # # VV, VH normalization # # # #*******************************************************# # Variables for VV # Error function and exponential to model the bulk constVV = RooRealVar("constVV", "slope of the exp", -0.030, -0.1, 0.) offsetVV = RooRealVar("offsetVV", "offset of the erf", 90., 1., 300.) widthVV = RooRealVar("widthVV", "width of the erf", 50., 1., 100.) erfrVV = RooErfExpPdf("baseVV", "error function for VV jet mass", J_mass, constVV, offsetVV, widthVV) expoVV = RooExponential("baseVV", "error function for VV jet mass", J_mass, constVV) # gaussian for the V mass peak meanVV = RooRealVar("meanVV", "mean of the gaussian", 90., 60., 100.) sigmaVV = RooRealVar("sigmaVV", "sigma of the gaussian", 10., 6., 30.) fracVV = RooRealVar("fracVV", "fraction of gaussian wrt erfexp", 3.2e-1, 0., 1.) gausVV = RooGaussian("gausVV", "gaus for VV jet mass", J_mass, meanVV, sigmaVV) # gaussian for the H mass peak meanVH = RooRealVar("meanVH", "mean of the gaussian", 125., 100., 150.) sigmaVH = RooRealVar("sigmaVH", "sigma of the gaussian", 30., 5., 40.) fracVH = RooRealVar("fracVH", "fraction of gaussian wrt erfexp", 1.5e-2, 0., 1.) gausVH = RooGaussian("gausVH", "gaus for VH jet mass", J_mass, meanVH, sigmaVH) # Define VV model if fitFuncVV == "ERFEXPGAUS": modelVV = RooAddPdf("modelVV", "error function + gaus for VV jet mass", RooArgList(gausVV, erfrVV), RooArgList(fracVV)) elif fitFuncVV == "ERFEXPGAUS2": modelVV = RooAddPdf("modelVV", "error function + gaus + gaus for VV jet mass", RooArgList(gausVH, gausVV, erfrVV), RooArgList(fracVH, fracVV)) elif fitFuncVV == "EXPGAUS": modelVV = RooAddPdf("modelVV", "error function + gaus for VV jet mass", RooArgList(gausVV, expoVV), RooArgList(fracVV)) elif fitFuncVV == "EXPGAUS2": modelVV = RooAddPdf("modelVV", "error function + gaus + gaus for VV jet mass", RooArgList(gausVH, gausVV, expoVV), RooArgList(fracVH, fracVV)) else: print " ERROR! Pdf", fitFuncVV, "is not implemented for VV" exit() # fit to secondary bkg in MC (whole range) frVV = modelVV.fitTo(setVV, RooFit.SumW2Error(True), RooFit.Range("h_reasonable_range"), RooFit.Strategy(2), RooFit.Minimizer("Minuit2"), RooFit.Save(1), RooFit.PrintLevel(1 if VERBOSE else -1)) # integrals and number of events iSBVV = modelVV.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg), RooFit.Range("LSBrange,HSBrange")) iLSBVV = modelVV.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg), RooFit.Range("LSBrange")) iHSBVV = modelVV.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg), RooFit.Range("HSBrange")) iSRVV = modelVV.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg), RooFit.Range("SRrange")) iVRVV = modelVV.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg), RooFit.Range("VRrange")) # Do not remove the following lines, integrals are computed here iALVV = modelVV.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg)) nSBVV = iSBVV.getVal()/iALVV.getVal()*setVV.sumEntries(SBcut) nLSBVV = iLSBVV.getVal()/iALVV.getVal()*setVV.sumEntries(LSBcut) nHSBVV = iHSBVV.getVal()/iALVV.getVal()*setVV.sumEntries(HSBcut) nSRVV = iSRVV.getVal()/iALVV.getVal()*setVV.sumEntries(SRcut) rSBSRVV = nSRVV/nSBVV drawPlot("JetMass_VV", channel, J_mass, modelVV, setVV, binsJmass, frVV) if VERBOSE: print "********** Fit result [JET MASS VV] ****"+"*"*40, "\n", frVV.Print(), "\n", "*"*80 #*******************************************************# # # # Top, ST normalization # # # #*******************************************************# # Variables for Top # Error Function * Exponential to model the bulk constTop = RooRealVar("constTop", "slope of the exp", -0.030, -1., 0.) offsetTop = RooRealVar("offsetTop", "offset of the erf", 175.0, 50., 250.) widthTop = RooRealVar("widthTop", "width of the erf", 100.0, 1., 300.) gausTop = RooGaussian("baseTop", "gaus for Top jet mass", J_mass, offsetTop, widthTop) erfrTop = RooErfExpPdf("baseTop", "error function for Top jet mass", J_mass, constTop, offsetTop, widthTop) # gaussian for the W mass peak meanW = RooRealVar("meanW", "mean of the gaussian", 80., 70., 90.) sigmaW = RooRealVar("sigmaW", "sigma of the gaussian", 10., 2., 20.) fracW = RooRealVar("fracW", "fraction of gaussian wrt erfexp", 0.1, 0., 1.) gausW = RooGaussian("gausW", "gaus for W jet mass", J_mass, meanW, sigmaW) # gaussian for the Top mass peak meanT = RooRealVar("meanT", "mean of the gaussian", 175., 150., 200.) sigmaT = RooRealVar("sigmaT", "sigma of the gaussian", 12., 5., 50.) fracT = RooRealVar("fracT", "fraction of gaussian wrt erfexp", 0.1, 0., 1.) gausT = RooGaussian("gausT", "gaus for T jet mass", J_mass, meanT, sigmaT) # Define Top model if fitFuncTop == "ERFEXPGAUS2": modelTop = RooAddPdf("modelTop", "error function + gaus + gaus for Top jet mass", RooArgList(gausW, gausT, erfrTop), RooArgList(fracW, fracT)) elif fitFuncTop == "ERFEXPGAUS": modelTop = RooAddPdf("modelTop", "error function + gaus for Top jet mass", RooArgList(gausT, erfrTop), RooArgList(fracT)) elif fitFuncTop == "GAUS3": modelTop = RooAddPdf("modelTop", "gaus + gaus + gaus for Top jet mass", RooArgList(gausW, gausT, gausTop), RooArgList(fracW, fracT)) elif fitFuncTop == "GAUS2": modelTop = RooAddPdf("modelTop", "gaus + gaus for Top jet mass", RooArgList(gausT, gausTop), RooArgList(fracT)) elif fitFuncTop == "GAUS": modelTop = RooGaussian("modelTop", "gaus for Top jet mass", J_mass, offsetTop, widthTop) else: print " ERROR! Pdf", fitFuncTop, "is not implemented for Top" exit() # fit to secondary bkg in MC (whole range) frTop = modelTop.fitTo(setTop, RooFit.SumW2Error(True), RooFit.Range("h_reasonable_range"), RooFit.Strategy(2), RooFit.Minimizer("Minuit2"), RooFit.Save(1), RooFit.PrintLevel(1 if VERBOSE else -1)) # integrals and number of events iSBTop = modelTop.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg), RooFit.Range("LSBrange,HSBrange")) iLSBTop = modelTop.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg), RooFit.Range("LSBrange")) iHSBTop = modelTop.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg), RooFit.Range("HSBrange")) iSRTop = modelTop.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg), RooFit.Range("SRrange")) iVRTop = modelTop.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg), RooFit.Range("VRrange")) # Do not remove the following lines, integrals are computed here iALTop = modelTop.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg)) nSBTop = iSBTop.getVal()/iALTop.getVal()*setTop.sumEntries(SBcut) nLSBTop = iLSBTop.getVal()/iALTop.getVal()*setTop.sumEntries(LSBcut) nHSBTop = iHSBTop.getVal()/iALTop.getVal()*setTop.sumEntries(HSBcut) nSRTop = iSRTop.getVal()/iALTop.getVal()*setTop.sumEntries(SRcut) drawPlot("JetMass_Top", channel, J_mass, modelTop, setTop, binsJmass, frTop) if VERBOSE: print "********** Fit result [JET MASS TOP] ***"+"*"*40, "\n", frTop.Print(), "\n", "*"*80 #*******************************************************# # # # All bkg normalization # # # #*******************************************************# constVjet.setConstant(True) offsetVjet.setConstant(True) widthVjet.setConstant(True) a0Vjet.setConstant(True) a1Vjet.setConstant(True) a2Vjet.setConstant(True) constVV.setConstant(True) offsetVV.setConstant(True) widthVV.setConstant(True) meanVV.setConstant(True) sigmaVV.setConstant(True) fracVV.setConstant(True) meanVH.setConstant(True) sigmaVH.setConstant(True) fracVH.setConstant(True) constTop.setConstant(True) offsetTop.setConstant(True) widthTop.setConstant(True) meanW.setConstant(True) sigmaW.setConstant(True) fracW.setConstant(True) meanT.setConstant(True) sigmaT.setConstant(True) fracT.setConstant(True) # Final background model by adding the main+secondary pdfs (using 'coef': ratio of the secondary/main, from MC) model = RooAddPdf("model", "model", RooArgList(modelTop, modelVV, modelVjet), RooArgList(coef_Top_VVVjet, coef_VV_Vjet))#FIXME model.fixAddCoefRange("h_reasonable_range") # Extended fit model to data in SB # all the 3 sidebands (Low / High / the 2 combined) could be used # currently using the LOW+HIGH (the others are commented out) yieldLSB = RooRealVar("yieldLSB", "Lower SB normalization", 10, 0., 1.e6) yieldHSB = RooRealVar("yieldHSB", "Higher SB normalization", 10, 0., 1.e6) yieldSB = RooRealVar("yieldSB", "All SB normalization", 10, 0., 1.e6) #model_ext = RooExtendPdf("model_ext", "extended p.d.f", model, yieldLSB) #model_ext = RooExtendPdf("model_ext", "extended p.d.f", model, yieldHSB) model_ext = RooExtendPdf("model_ext", "extended p.d.f", model, yieldSB) #frMass = model_ext.fitTo(setDataSB, RooFit.ConditionalObservables(RooArgSet(J_mass)),RooFit.SumW2Error(True),RooFit.Extended(True),RooFit.Range("LSBrange"),RooFit.PrintLevel(-1)) #frMass = model_ext.fitTo(setDataSB, RooFit.ConditionalObservables(RooArgSet(J_mass)),RooFit.SumW2Error(True),RooFit.Extended(True),RooFit.Range("HSBrange"),RooFit.PrintLevel(-1)) #frMass = model_ext.fitTo(setDataSB, RooFit.ConditionalObservables(RooArgSet(J_mass)), RooFit.SumW2Error(True), RooFit.Extended(True), RooFit.Range("LSBrange,HSBrange"), RooFit.Strategy(2), RooFit.Minimizer("Minuit2"), RooFit.PrintLevel(1 if VERBOSE else -1)) #print "********** Fit result [JET MASS DATA] **"+"*"*40 #print frMass.Print() #print "*"*80 # Calculate integral of the model obtained from the fit to data (fraction of PDF that is within a given region) #nSB = model_ext.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg), RooFit.Range("LSBrange,HSBrange")) #nSB = model_ext.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg), RooFit.Range("LSBrange")) #nSB = model_ext.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg), RooFit.Range("HSBrange")) #nSR = model_ext.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg), RooFit.Range("SRrange")) #nVR = model_ext.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg), RooFit.Range("VRrange")) # scale the yieldSB from SB to SR using the ratio of the PDFs defined by the two integrals SRyield = RooFormulaVar("SRyield", "extrapolation to SR","(@0-@1*@3-@2*@4) * @5/@6 +@1*@7+@2*@8", RooArgList(entrySB, entryVV, entryTop, iSBVV, iSBTop, iSRVjet, iSBVjet, iSRVV, iSRTop)) VRyield = RooFormulaVar("VRyield", "extrapolation to VR","(@0-@1*@3-@2*@4) * @5/@6 +@1*@7+@2*@8", RooArgList(entrySB, entryVV, entryTop, iSBVV, iSBTop, iVRVjet, iSBVjet, iVRVV, iVRTop)) HSByield = RooFormulaVar("SRyield", "extrapolation to SR","(@0-@1*@3-@2*@4) * @5/@6 +@1*@7+@2*@8", RooArgList(entryLSB, entryVV, entryTop, iLSBVV, iLSBTop, iHSBVjet, iLSBVjet, iHSBVV, iHSBTop)) # RooFormulaVar SRyield("SRyield","extrapolation to SR","(@0/@1)*@2",RooArgList(*nSR,*nSB,yieldLowerSB)) # RooFormulaVar SRyield("SRyield","extrapolation to SR","(@0/@1)*@2",RooArgList(*nSR,*nSB,yieldHigherSB)) #SRyield = RooFormulaVar("SRyield", "extrapolation to SR","(@0/@1)*@2", RooArgList(nSR, nSB, entrySB)) bkgYield = SRyield.getVal() bkgYield_error = math.sqrt(SRyield.getPropagatedError(frVjet)**2 + SRyield.getPropagatedError(frVV)**2 + SRyield.getPropagatedError(frTop)**2 + (entrySB.getError()*rSBSRVV)**2) bkgNorm = entrySB.getVal() + SRyield.getVal() + VRyield.getVal() bkgYield_eig_norm = RooRealVar("predSR_eig_norm", "expected yield in SR", bkgYield, 0., 1.e6) bkgYieldExt = HSByield.getVal() drawPlot("JetMass", channel, J_mass, model, setDataSB, binsJmass, None, None, "", bkgNorm, True) print channel, "normalization = %.3f +/- %.3f, observed = %.0f" % (bkgYield, bkgYield_error, setDataSR.sumEntries() if not BLIND else -1) if VERBOSE: raw_input("Press Enter to continue...")
def alpha(channel): nElec = channel.count("e") nMuon = channel.count("m") nLept = nElec + nMuon nBtag = channel.count("b") # Channel-dependent settings # Background function. Semi-working options are: EXP, EXP2, EXPN, EXPTAIL if nLept == 0: treeName = "SR" signName = "XZh" colorVjet = sample["DYJetsToNuNu"]["linecolor"] triName = "HLT_PFMET" leptCut = "0==0" topVeto = selection["TopVetocut"] massVar = "X_cmass" binFact = 1 fitFunc = "EXPN" if nBtag < 2 else "EXPN" fitAltFunc = "EXPTAIL" if nBtag < 2 else "EXPTAIL" fitFuncVjet = "ERFEXP" if nBtag < 2 else "EXP" fitAltFuncVjet = "POL" if nBtag < 2 else "POL" fitFuncVV = "EXPGAUS" if nBtag < 2 else "EXPGAUS" fitFuncTop = "GAUS2" elif nLept == 1: treeName = "WCR" signName = "XWh" colorVjet = sample["WJetsToLNu"]["linecolor"] triName = "HLT_Ele" if nElec > 0 else "HLT_Mu" leptCut = "isWtoEN" if nElec > 0 else "isWtoMN" topVeto = selection["TopVetocut"] massVar = "X_mass" binFact = 2 if nElec > 0: fitFunc = "EXPTAIL" if nBtag < 2 else "EXPN" fitAltFunc = "EXPN" if nBtag < 2 else "POW" else: fitFunc = "EXPN" if nBtag < 2 else "EXPN" fitAltFunc = "EXPTAIL" if nBtag < 2 else "POW" fitFuncVjet = "ERFEXP" if nBtag < 2 else "EXP" fitAltFuncVjet = "POL" if nBtag < 2 else "POL" fitFuncVV = "EXPGAUS" if nBtag < 2 else "EXPGAUS" fitFuncTop = "GAUS3" if nBtag < 2 else "GAUS2" else: treeName = "XZh" signName = "XZh" colorVjet = sample["DYJetsToLL"]["linecolor"] triName = "HLT_Ele" if nElec > 0 else "HLT_Mu" leptCut = "isZtoEE" if nElec > 0 else "isZtoMM" topVeto = "X_dPhi>2.5" massVar = "X_mass" binFact = 2 if nElec > 0: fitFunc = "EXPTAIL" if nBtag < 2 else "EXPTAIL" fitAltFunc = "POW" if nBtag < 2 else "POW" else: fitFunc = "EXPTAIL" if nBtag < 2 else "EXPTAIL" fitAltFunc = "POW" if nBtag < 2 else "POW" fitFuncVjet = "ERFEXP" if nBtag < 2 and nElec < 1 else "EXP" fitAltFuncVjet = "POL" if nBtag < 2 else "POL" fitFuncVV = "EXPGAUS2" if nBtag < 2 else "EXPGAUS2" fitFuncTop = "GAUS" btagCut = selection["2Btag"] if nBtag == 2 else selection["1Btag"] print "--- Channel", channel, "---" print " number of electrons:", nElec, " muons:", nMuon, " b-tags:", nBtag print " read tree:", treeName, "and trigger:", triName if ALTERNATIVE: print " using ALTERNATIVE fit functions" print "-" * 11 * 2 # Silent RooFit RooMsgService.instance().setGlobalKillBelow(RooFit.FATAL) # *******************************************************# # # # Variables and selections # # # # *******************************************************# # Define all the variables from the trees that will be used in the cuts and fits # this steps actually perform a "projection" of the entire tree on the variables in thei ranges, so be careful once setting the limits X_mass = RooRealVar(massVar, "m_{X}" if nLept > 0 else "m_{T}^{X}", XBINMIN, XBINMAX, "GeV") J_mass = RooRealVar("fatjet1_prunedMassCorr", "jet corrected pruned mass", HBINMIN, HBINMAX, "GeV") CSV1 = RooRealVar("fatjet1_CSVR1", "", -1.0e99, 1.0e4) CSV2 = RooRealVar("fatjet1_CSVR2", "", -1.0e99, 1.0e4) nB = RooRealVar("fatjet1_nBtag", "", 0.0, 4) CSVTop = RooRealVar("bjet1_CSVR", "", -1.0e99, 1.0e4) X_dPhi = RooRealVar("X_dPhi", "", 0.0, 3.15) isZtoEE = RooRealVar("isZtoEE", "", 0.0, 2) isZtoMM = RooRealVar("isZtoMM", "", 0.0, 2) isWtoEN = RooRealVar("isWtoEN", "", 0.0, 2) isWtoMN = RooRealVar("isWtoMN", "", 0.0, 2) weight = RooRealVar("eventWeightLumi", "", -1.0e9, 1.0) # Define the RooArgSet which will include all the variables defined before # there is a maximum of 9 variables in the declaration, so the others need to be added with 'add' variables = RooArgSet(X_mass, J_mass, CSV1, CSV2, nB, CSVTop, X_dPhi) variables.add(RooArgSet(isZtoEE, isZtoMM, isWtoEN, isWtoMN, weight)) # set reasonable ranges for J_mass and X_mass # these are used in the fit in order to avoid ROOFIT to look in regions very far away from where we are fitting # (honestly, it is not clear to me why it is necessary, but without them the fit often explodes) J_mass.setRange("h_reasonable_range", LOWMIN, HIGMAX) X_mass.setRange("X_reasonable_range", XBINMIN, XBINMAX) # Set RooArgSets once for all, see https://root.cern.ch/phpBB3/viewtopic.php?t=11758 jetMassArg = RooArgSet(J_mass) # Define the ranges in fatJetMass - these will be used to define SB and SR J_mass.setRange("LSBrange", LOWMIN, LOWMAX) J_mass.setRange("HSBrange", HIGMIN, HIGMAX) J_mass.setRange("VRrange", LOWMAX, SIGMIN) J_mass.setRange("SRrange", SIGMIN, SIGMAX) # Set binning for plots J_mass.setBins(HBINS) X_mass.setBins(binFact * XBINS) # Define the selection for the various categories (base + SR / LSBcut / HSBcut ) baseCut = leptCut + " && " + btagCut + "&&" + topVeto massCut = massVar + ">%d" % XBINMIN baseCut += " && " + massCut # Cuts SRcut = baseCut + " && %s>%d && %s<%d" % (J_mass.GetName(), SIGMIN, J_mass.GetName(), SIGMAX) LSBcut = baseCut + " && %s>%d && %s<%d" % (J_mass.GetName(), LOWMIN, J_mass.GetName(), LOWMAX) HSBcut = baseCut + " && %s>%d && %s<%d" % (J_mass.GetName(), HIGMIN, J_mass.GetName(), HIGMAX) SBcut = baseCut + " && ((%s>%d && %s<%d) || (%s>%d && %s<%d))" % ( J_mass.GetName(), LOWMIN, J_mass.GetName(), LOWMAX, J_mass.GetName(), HIGMIN, J_mass.GetName(), HIGMAX, ) VRcut = baseCut + " && %s>%d && %s<%d" % (J_mass.GetName(), LOWMAX, J_mass.GetName(), SIGMIN) # Binning binsJmass = RooBinning(HBINS, HBINMIN, HBINMAX) # binsJmass.addUniform(HBINS, HBINMIN, HBINMAX) binsXmass = RooBinning(binFact * XBINS, XBINMIN, XBINMAX) # binsXmass.addUniform(binFact*XBINS, XBINMIN, XBINMAX) # *******************************************************# # # # Input files # # # # *******************************************************# # Import the files using TChains (separately for the bkg "classes" that we want to describe: here DY and VV+ST+TT) treeData = TChain(treeName) treeMC = TChain(treeName) treeVjet = TChain(treeName) treeVV = TChain(treeName) treeTop = TChain(treeName) treeSign = {} nevtSign = {} for i, m in enumerate(massPoints): treeSign[m] = TChain(treeName) # Read data pd = getPrimaryDataset(triName) if len(pd) == 0: raw_input("Warning: Primary Dataset not recognized, continue?") for i, s in enumerate(pd): treeData.Add(NTUPLEDIR + s + ".root") # Read V+jets backgrounds for i, s in enumerate(["WJetsToLNu_HT", "DYJetsToNuNu_HT", "DYJetsToLL_HT"]): for j, ss in enumerate(sample[s]["files"]): treeVjet.Add(NTUPLEDIR + ss + ".root") # Read VV backgrounds for i, s in enumerate(["VV"]): for j, ss in enumerate(sample[s]["files"]): treeVV.Add(NTUPLEDIR + ss + ".root") # Read Top backgrounds for i, s in enumerate(["ST", "TTbar"]): for j, ss in enumerate(sample[s]["files"]): treeTop.Add(NTUPLEDIR + ss + ".root") # Read signals for i, m in enumerate(massPoints): for j, ss in enumerate(sample["%s_M%d" % (signName, m)]["files"]): treeSign[m].Add(NTUPLEDIR + ss + ".root") sfile = TFile(NTUPLEDIR + ss + ".root", "READ") shist = sfile.Get("Counters/Counter") nevtSign[m] = shist.GetBinContent(1) sfile.Close() # Sum all background MC treeMC.Add(treeVjet) treeMC.Add(treeVV) treeMC.Add(treeTop) # create a dataset to host data in sideband (using this dataset we are automatically blind in the SR!) setDataSB = RooDataSet( "setDataSB", "setDataSB", variables, RooFit.Cut(SBcut), RooFit.WeightVar(weight), RooFit.Import(treeData) ) setDataLSB = RooDataSet( "setDataLSB", "setDataLSB", variables, RooFit.Import(setDataSB), RooFit.Cut(LSBcut), RooFit.WeightVar(weight) ) setDataHSB = RooDataSet( "setDataHSB", "setDataHSB", variables, RooFit.Import(setDataSB), RooFit.Cut(HSBcut), RooFit.WeightVar(weight) ) # Observed data (WARNING, BLIND!) setDataSR = RooDataSet( "setDataSR", "setDataSR", variables, RooFit.Cut(SRcut), RooFit.WeightVar(weight), RooFit.Import(treeData) ) setDataVR = RooDataSet( "setDataVR", "setDataVR", variables, RooFit.Cut(VRcut), RooFit.WeightVar(weight), RooFit.Import(treeData) ) # Observed in the VV mass, just for plotting purposes setDataSRSB = RooDataSet( "setDataSRSB", "setDataSRSB", variables, RooFit.Cut("(" + SRcut + ") || (" + SBcut + ")"), RooFit.WeightVar(weight), RooFit.Import(treeData), ) # same for the bkg datasets from MC, where we just apply the base selections (not blind) setVjet = RooDataSet( "setVjet", "setVjet", variables, RooFit.Cut(baseCut), RooFit.WeightVar(weight), RooFit.Import(treeVjet) ) setVjetSB = RooDataSet( "setVjetSB", "setVjetSB", variables, RooFit.Import(setVjet), RooFit.Cut(SBcut), RooFit.WeightVar(weight) ) setVjetSR = RooDataSet( "setVjetSR", "setVjetSR", variables, RooFit.Import(setVjet), RooFit.Cut(SRcut), RooFit.WeightVar(weight) ) setVV = RooDataSet( "setVV", "setVV", variables, RooFit.Cut(baseCut), RooFit.WeightVar(weight), RooFit.Import(treeVV) ) setVVSB = RooDataSet( "setVVSB", "setVVSB", variables, RooFit.Import(setVV), RooFit.Cut(SBcut), RooFit.WeightVar(weight) ) setVVSR = RooDataSet( "setVVSR", "setVVSR", variables, RooFit.Import(setVV), RooFit.Cut(SRcut), RooFit.WeightVar(weight) ) setTop = RooDataSet( "setTop", "setTop", variables, RooFit.Cut(baseCut), RooFit.WeightVar(weight), RooFit.Import(treeTop) ) setTopSB = RooDataSet( "setTopSB", "setTopSB", variables, RooFit.Import(setTop), RooFit.Cut(SBcut), RooFit.WeightVar(weight) ) setTopSR = RooDataSet( "setTopSR", "setTopSR", variables, RooFit.Import(setTop), RooFit.Cut(SRcut), RooFit.WeightVar(weight) ) print " Data events SB: %.2f" % setDataSB.sumEntries() print " V+jets entries: %.2f" % setVjet.sumEntries() print " VV, VH entries: %.2f" % setVV.sumEntries() print " Top,ST entries: %.2f" % setTop.sumEntries() nVV = RooRealVar("nVV", "VV normalization", setVV.sumEntries(SBcut), 0.0, 2 * setVV.sumEntries(SBcut)) nTop = RooRealVar("nTop", "Top normalization", setTop.sumEntries(SBcut), 0.0, 2 * setTop.sumEntries(SBcut)) nVjet = RooRealVar("nVjet", "Vjet normalization", setDataSB.sumEntries(), 0.0, 2 * setDataSB.sumEntries(SBcut)) nVjet2 = RooRealVar("nVjet2", "Vjet2 normalization", setDataSB.sumEntries(), 0.0, 2 * setDataSB.sumEntries(SBcut)) # Apply Top SF nTop.setVal(nTop.getVal() * topSF[nLept][nBtag]) nTop.setError(nTop.getVal() * topSFErr[nLept][nBtag]) # Define entries entryVjet = RooRealVar("entryVjets", "V+jets normalization", setVjet.sumEntries(), 0.0, 1.0e6) entryVV = RooRealVar("entryVV", "VV normalization", setVV.sumEntries(), 0.0, 1.0e6) entryTop = RooRealVar("entryTop", "Top normalization", setTop.sumEntries(), 0.0, 1.0e6) entrySB = RooRealVar("entrySB", "Data SB normalization", setDataSB.sumEntries(SBcut), 0.0, 1.0e6) entrySB.setError(math.sqrt(entrySB.getVal())) entryLSB = RooRealVar("entryLSB", "Data LSB normalization", setDataSB.sumEntries(LSBcut), 0.0, 1.0e6) entryLSB.setError(math.sqrt(entryLSB.getVal())) entryHSB = RooRealVar("entryHSB", "Data HSB normalization", setDataSB.sumEntries(HSBcut), 0.0, 1.0e6) entryHSB.setError(math.sqrt(entryHSB.getVal())) ################################################################################### # _ _ # # | \ | | | (_) | | (_) # # | \| | ___ _ __ _ __ ___ __ _| |_ ___ __ _| |_ _ ___ _ __ # # | . ` |/ _ \| '__| '_ ` _ \ / _` | | / __|/ _` | __| |/ _ \| '_ \ # # | |\ | (_) | | | | | | | | (_| | | \__ \ (_| | |_| | (_) | | | | # # |_| \_|\___/|_| |_| |_| |_|\__,_|_|_|___/\__,_|\__|_|\___/|_| |_| # # # ################################################################################### # fancy ASCII art thanks to, I guess, Jose # start by creating the fit models to get the normalization: # * MAIN and SECONDARY bkg are taken from MC by fitting the whole J_mass range # * The two PDFs are added together using the relative normalizations of the two bkg from MC # * DATA is then fit in the sidebands only using the combined bkg PDF # * The results of the fit are then estrapolated in the SR and the integral is evaluated. # * This defines the bkg normalization in the SR # *******************************************************# # # # V+jets normalization # # # # *******************************************************# # Variables for V+jets constVjet = RooRealVar("constVjet", "slope of the exp", -0.020, -1.0, 0.0) offsetVjet = RooRealVar("offsetVjet", "offset of the erf", 30.0, -50.0, 400.0) widthVjet = RooRealVar("widthVjet", "width of the erf", 100.0, 1.0, 200.0) # 0, 400 a0Vjet = RooRealVar("a0Vjet", "width of the erf", -0.1, -5, 0) a1Vjet = RooRealVar("a1Vjet", "width of the erf", 0.6, 0, 5) a2Vjet = RooRealVar("a2Vjet", "width of the erf", -0.1, -1, 1) if channel == "XZhnnb": offsetVjet = RooRealVar("offsetVjet", "offset of the erf", 500.0, 200.0, 1000.0) if channel == "XZhnnbb": offsetVjet = RooRealVar("offsetVjet", "offset of the erf", 350.0, 200.0, 500.0) # if channel == "XWhenb" or channel == "XZheeb": # offsetVjet.setVal(120.) # offsetVjet.setConstant(True) if channel == "XWhenb": offsetVjet = RooRealVar("offsetVjet", "offset of the erf", 120.0, 80.0, 155.0) if channel == "XWhenbb" or channel == "XZhmmb": offsetVjet = RooRealVar("offsetVjet", "offset of the erf", 67.0, 50.0, 100.0) if channel == "XWhmnb": offsetVjet = RooRealVar("offsetVjet", "offset of the erf", 30.0, -50.0, 600.0) if channel == "XZheeb": offsetVjet.setMin(-400) offsetVjet.setVal(0.0) offsetVjet.setMax(1000) widthVjet.setVal(1.0) # Define V+jets model if fitFuncVjet == "ERFEXP": VjetMass = RooErfExpPdf("VjetMass", fitFuncVjet, J_mass, constVjet, offsetVjet, widthVjet) elif fitFuncVjet == "EXP": VjetMass = RooExponential("VjetMass", fitFuncVjet, J_mass, constVjet) elif fitFuncVjet == "GAUS": VjetMass = RooGaussian("VjetMass", fitFuncVjet, J_mass, offsetVjet, widthVjet) elif fitFuncVjet == "POL": VjetMass = RooChebychev("VjetMass", fitFuncVjet, J_mass, RooArgList(a0Vjet, a1Vjet, a2Vjet)) elif fitFuncVjet == "POW": VjetMass = RooGenericPdf("VjetMass", fitFuncVjet, "@0^@1", RooArgList(J_mass, a0Vjet)) else: print " ERROR! Pdf", fitFuncVjet, "is not implemented for Vjets" exit() if fitAltFuncVjet == "POL": VjetMass2 = RooChebychev("VjetMass2", "polynomial for V+jets mass", J_mass, RooArgList(a0Vjet, a1Vjet, a2Vjet)) else: print " ERROR! Pdf", fitAltFuncVjet, "is not implemented for Vjets" exit() # fit to main bkg in MC (whole range) frVjet = VjetMass.fitTo( setVjet, RooFit.SumW2Error(True), RooFit.Range("h_reasonable_range"), RooFit.Strategy(2), RooFit.Minimizer("Minuit2"), RooFit.Save(1), RooFit.PrintLevel(1 if VERBOSE else -1), ) frVjet2 = VjetMass2.fitTo( setVjet, RooFit.SumW2Error(True), RooFit.Range("h_reasonable_range"), RooFit.Strategy(2), RooFit.Minimizer("Minuit2"), RooFit.Save(1), RooFit.PrintLevel(1 if VERBOSE else -1), ) if VERBOSE: print "********** Fit result [JET MASS Vjets] *" + "*" * 40, "\n", frVjet.Print(), "\n", "*" * 80 # likelihoodScan(VjetMass, setVjet, [constVjet, offsetVjet, widthVjet]) # *******************************************************# # # # VV, VH normalization # # # # *******************************************************# # Variables for VV # Error function and exponential to model the bulk constVV = RooRealVar("constVV", "slope of the exp", -0.030, -0.1, 0.0) offsetVV = RooRealVar("offsetVV", "offset of the erf", 90.0, 1.0, 300.0) widthVV = RooRealVar("widthVV", "width of the erf", 50.0, 1.0, 100.0) erfrVV = RooErfExpPdf("baseVV", "error function for VV jet mass", J_mass, constVV, offsetVV, widthVV) expoVV = RooExponential("baseVV", "error function for VV jet mass", J_mass, constVV) # gaussian for the V mass peak meanVV = RooRealVar("meanVV", "mean of the gaussian", 90.0, 60.0, 100.0) sigmaVV = RooRealVar("sigmaVV", "sigma of the gaussian", 10.0, 6.0, 30.0) fracVV = RooRealVar("fracVV", "fraction of gaussian wrt erfexp", 3.2e-1, 0.0, 1.0) gausVV = RooGaussian("gausVV", "gaus for VV jet mass", J_mass, meanVV, sigmaVV) # gaussian for the H mass peak meanVH = RooRealVar("meanVH", "mean of the gaussian", 125.0, 100.0, 150.0) sigmaVH = RooRealVar("sigmaVH", "sigma of the gaussian", 10.0, 5.0, 50.0) fracVH = RooRealVar("fracVH", "fraction of gaussian wrt erfexp", 1.5e-2, 0.0, 1.0) gausVH = RooGaussian("gausVH", "gaus for VH jet mass", J_mass, meanVH, sigmaVH) # Define VV model if fitFuncVV == "ERFEXPGAUS": VVMass = RooAddPdf("VVMass", fitFuncVV, RooArgList(gausVV, erfrVV), RooArgList(fracVV)) elif fitFuncVV == "ERFEXPGAUS2": VVMass = RooAddPdf("VVMass", fitFuncVV, RooArgList(gausVH, gausVV, erfrVV), RooArgList(fracVH, fracVV)) elif fitFuncVV == "EXPGAUS": VVMass = RooAddPdf("VVMass", fitFuncVV, RooArgList(gausVV, expoVV), RooArgList(fracVV)) elif fitFuncVV == "EXPGAUS2": VVMass = RooAddPdf("VVMass", fitFuncVV, RooArgList(gausVH, gausVV, expoVV), RooArgList(fracVH, fracVV)) else: print " ERROR! Pdf", fitFuncVV, "is not implemented for VV" exit() # fit to secondary bkg in MC (whole range) frVV = VVMass.fitTo( setVV, RooFit.SumW2Error(True), RooFit.Range("h_reasonable_range"), RooFit.Strategy(2), RooFit.Minimizer("Minuit2"), RooFit.Save(1), RooFit.PrintLevel(1 if VERBOSE else -1), ) if VERBOSE: print "********** Fit result [JET MASS VV] ****" + "*" * 40, "\n", frVV.Print(), "\n", "*" * 80 # *******************************************************# # # # Top, ST normalization # # # # *******************************************************# # Variables for Top # Error Function * Exponential to model the bulk constTop = RooRealVar("constTop", "slope of the exp", -0.030, -1.0, 0.0) offsetTop = RooRealVar("offsetTop", "offset of the erf", 175.0, 50.0, 250.0) widthTop = RooRealVar("widthTop", "width of the erf", 100.0, 1.0, 300.0) gausTop = RooGaussian("baseTop", "gaus for Top jet mass", J_mass, offsetTop, widthTop) erfrTop = RooErfExpPdf("baseTop", "error function for Top jet mass", J_mass, constTop, offsetTop, widthTop) # gaussian for the W mass peak meanW = RooRealVar("meanW", "mean of the gaussian", 80.0, 70.0, 90.0) sigmaW = RooRealVar("sigmaW", "sigma of the gaussian", 10.0, 2.0, 20.0) fracW = RooRealVar("fracW", "fraction of gaussian wrt erfexp", 0.1, 0.0, 1.0) gausW = RooGaussian("gausW", "gaus for W jet mass", J_mass, meanW, sigmaW) # gaussian for the Top mass peak meanT = RooRealVar("meanT", "mean of the gaussian", 175.0, 150.0, 200.0) sigmaT = RooRealVar("sigmaT", "sigma of the gaussian", 12.0, 5.0, 30.0) fracT = RooRealVar("fracT", "fraction of gaussian wrt erfexp", 0.1, 0.0, 1.0) gausT = RooGaussian("gausT", "gaus for T jet mass", J_mass, meanT, sigmaT) if channel == "XZheeb" or channel == "XZheebb" or channel == "XZhmmb" or channel == "XZhmmbb": offsetTop = RooRealVar("offsetTop", "offset of the erf", 200.0, -50.0, 450.0) widthTop = RooRealVar("widthTop", "width of the erf", 100.0, 1.0, 1000.0) # Define Top model if fitFuncTop == "ERFEXPGAUS2": TopMass = RooAddPdf("TopMass", fitFuncTop, RooArgList(gausW, gausT, erfrTop), RooArgList(fracW, fracT)) elif fitFuncTop == "ERFEXPGAUS": TopMass = RooAddPdf("TopMass", fitFuncTop, RooArgList(gausT, erfrTop), RooArgList(fracT)) elif fitFuncTop == "GAUS3": TopMass = RooAddPdf("TopMass", fitFuncTop, RooArgList(gausW, gausT, gausTop), RooArgList(fracW, fracT)) elif fitFuncTop == "GAUS2": TopMass = RooAddPdf("TopMass", fitFuncTop, RooArgList(gausT, gausTop), RooArgList(fracT)) elif fitFuncTop == "GAUS": TopMass = RooGaussian("TopMass", fitFuncTop, J_mass, offsetTop, widthTop) else: print " ERROR! Pdf", fitFuncTop, "is not implemented for Top" exit() # fit to secondary bkg in MC (whole range) frTop = TopMass.fitTo( setTop, RooFit.SumW2Error(True), RooFit.Range("h_reasonable_range"), RooFit.Strategy(2), RooFit.Minimizer("Minuit2"), RooFit.Save(1), RooFit.PrintLevel(1 if VERBOSE else -1), ) if VERBOSE: print "********** Fit result [JET MASS TOP] ***" + "*" * 40, "\n", frTop.Print(), "\n", "*" * 80 # likelihoodScan(TopMass, setTop, [offsetTop, widthTop]) # *******************************************************# # # # All bkg normalization # # # # *******************************************************# # nVjet.setConstant(False) # nVjet2.setConstant(False) # # constVjet.setConstant(False) # offsetVjet.setConstant(False) # widthVjet.setConstant(False) # a0Vjet.setConstant(False) # a1Vjet.setConstant(False) # a2Vjet.setConstant(False) constVV.setConstant(True) offsetVV.setConstant(True) widthVV.setConstant(True) meanVV.setConstant(True) sigmaVV.setConstant(True) fracVV.setConstant(True) meanVH.setConstant(True) sigmaVH.setConstant(True) fracVH.setConstant(True) constTop.setConstant(True) offsetTop.setConstant(True) widthTop.setConstant(True) meanW.setConstant(True) sigmaW.setConstant(True) fracW.setConstant(True) meanT.setConstant(True) sigmaT.setConstant(True) fracT.setConstant(True) nVV.setConstant(True) nTop.setConstant(True) nVjet.setConstant(False) nVjet2.setConstant(False) # Final background model by adding the main+secondary pdfs (using 'coef': ratio of the secondary/main, from MC) TopMass_ext = RooExtendPdf("TopMass_ext", "extended p.d.f", TopMass, nTop) VVMass_ext = RooExtendPdf("VVMass_ext", "extended p.d.f", VVMass, nVV) VjetMass_ext = RooExtendPdf("VjetMass_ext", "extended p.d.f", VjetMass, nVjet) VjetMass2_ext = RooExtendPdf("VjetMass_ext", "extended p.d.f", VjetMass, nVjet2) BkgMass = RooAddPdf( "BkgMass", "BkgMass", RooArgList(TopMass_ext, VVMass_ext, VjetMass_ext), RooArgList(nTop, nVV, nVjet) ) BkgMass2 = RooAddPdf( "BkgMass2", "BkgMass2", RooArgList(TopMass_ext, VVMass_ext, VjetMass2_ext), RooArgList(nTop, nVV, nVjet2) ) BkgMass.fixAddCoefRange("h_reasonable_range") BkgMass2.fixAddCoefRange("h_reasonable_range") # Extended fit model to data in SB frMass = BkgMass.fitTo( setDataSB, RooFit.SumW2Error(True), RooFit.Extended(True), RooFit.Range("LSBrange,HSBrange"), RooFit.Strategy(2), RooFit.Minimizer("Minuit"), RooFit.Save(1), RooFit.PrintLevel(1 if VERBOSE else -1), ) # , RooFit.NumCPU(10) if VERBOSE: print "********** Fit result [JET MASS DATA] **" + "*" * 40, "\n", frMass.Print(), "\n", "*" * 80 frMass2 = BkgMass2.fitTo( setDataSB, RooFit.SumW2Error(True), RooFit.Extended(True), RooFit.Range("LSBrange,HSBrange"), RooFit.Strategy(2), RooFit.Minimizer("Minuit"), RooFit.Save(1), RooFit.PrintLevel(1 if VERBOSE else -1), ) if VERBOSE: print "********** Fit result [JET MASS DATA] **" + "*" * 40, "\n", frMass2.Print(), "\n", "*" * 80 # if SCAN: # likelihoodScan(VjetMass, setVjet, [constVjet, offsetVjet, widthVjet]) # Fix normalization and parameters of V+jets after the fit to data nVjet.setConstant(True) nVjet2.setConstant(True) constVjet.setConstant(True) offsetVjet.setConstant(True) widthVjet.setConstant(True) a0Vjet.setConstant(True) a1Vjet.setConstant(True) a2Vjet.setConstant(True) # integrals for global normalization # do not integrate the composte model: results have no sense # integral for normalization in the SB iSBVjet = VjetMass.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg), RooFit.Range("LSBrange,HSBrange")) iSBVV = VVMass.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg), RooFit.Range("LSBrange,HSBrange")) iSBTop = TopMass.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg), RooFit.Range("LSBrange,HSBrange")) # integral for normalization in the SR iSRVjet = VjetMass.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg), RooFit.Range("SRrange")) iSRVV = VVMass.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg), RooFit.Range("SRrange")) iSRTop = TopMass.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg), RooFit.Range("SRrange")) # integral for normalization in the VR iVRVjet = VjetMass.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg), RooFit.Range("VRrange")) iVRVV = VVMass.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg), RooFit.Range("VRrange")) iVRTop = TopMass.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg), RooFit.Range("VRrange")) # formual vars SByield = RooFormulaVar( "SByield", "extrapolation to SR", "@0*@1 + @2*@3 + @4*@5", RooArgList(iSBVjet, nVjet, iSBVV, nVV, iSBTop, nTop) ) VRyield = RooFormulaVar( "VRyield", "extrapolation to VR", "@0*@1 + @2*@3 + @4*@5", RooArgList(iVRVjet, nVjet, iVRVV, nVV, iVRTop, nTop) ) SRyield = RooFormulaVar( "SRyield", "extrapolation to SR", "@0*@1 + @2*@3 + @4*@5", RooArgList(iSRVjet, nVjet, iSRVV, nVV, iSRTop, nTop) ) # fractions fSBVjet = RooRealVar( "fVjet", "Fraction of Vjet events in SB", iSBVjet.getVal() * nVjet.getVal() / SByield.getVal(), 0.0, 1.0 ) fSBVV = RooRealVar( "fSBVV", "Fraction of VV events in SB", iSBVV.getVal() * nVV.getVal() / SByield.getVal(), 0.0, 1.0 ) fSBTop = RooRealVar( "fSBTop", "Fraction of Top events in SB", iSBTop.getVal() * nTop.getVal() / SByield.getVal(), 0.0, 1.0 ) fSRVjet = RooRealVar( "fSRVjet", "Fraction of Vjet events in SR", iSRVjet.getVal() * nVjet.getVal() / SRyield.getVal(), 0.0, 1.0 ) fSRVV = RooRealVar( "fSRVV", "Fraction of VV events in SR", iSRVV.getVal() * nVV.getVal() / SRyield.getVal(), 0.0, 1.0 ) fSRTop = RooRealVar( "fSRTop", "Fraction of Top events in SR", iSRTop.getVal() * nTop.getVal() / SRyield.getVal(), 0.0, 1.0 ) # final normalization values bkgYield = SRyield.getVal() bkgYield2 = ( (VjetMass2.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg), RooFit.Range("SRrange"))).getVal() * nVjet2.getVal() + iSRVV.getVal() * nVV.getVal() + iSRTop.getVal() * nTop.getVal() ) bkgYield_syst = math.sqrt(SRyield.getPropagatedError(frVV) ** 2 + SRyield.getPropagatedError(frTop) ** 2) bkgYield_stat = math.sqrt(SRyield.getPropagatedError(frMass) ** 2) bkgYield_alte = abs(bkgYield - bkgYield2) # /bkgYield bkgYield_eig_norm = RooRealVar("predSR_eig_norm", "expected yield in SR", bkgYield, 0.0, 1.0e6) print "Events in channel", channel, ": V+jets %.3f (%.1f%%), VV %.3f (%.1f%%), Top %.3f (%.1f%%)" % ( iSRVjet.getVal() * nVjet.getVal(), fSRVjet.getVal() * 100, iSRVV.getVal() * nVV.getVal(), fSRVV.getVal() * 100, iSRTop.getVal() * nTop.getVal(), fSRTop.getVal() * 100, ) print "Events in channel", channel, ": Integral = $%.3f$ & $\pm %.3f$ & $\pm %.3f$ & $\pm %.3f$, observed = %.0f" % ( bkgYield, bkgYield_stat, bkgYield_syst, bkgYield_alte, setDataSR.sumEntries() if not False else -1, )
def alpha(channel): nElec = channel.count('e') nMuon = channel.count('m') nLept = nElec + nMuon nBtag = channel.count('b') # Channel-dependent settings # Background function. Semi-working options are: EXP, EXP2, EXPN, EXPTAIL if nLept == 0: treeName = 'SR' signName = 'XZh' colorVjet = sample['DYJetsToNuNu']['linecolor'] triName = "HLT_PFMET" leptCut = "0==0" topVeto = selection["TopVetocut"] massVar = "X_cmass" binFact = 1 #fitFunc = "EXP" #fitFunc = "EXP2" #fitFunc = "EXPN" #fitFunc = "EXPTAIL" fitFunc = "EXPN" if nBtag < 2 else "EXP" fitAltFunc = "EXPTAIL" if nBtag < 2 else "EXPTAIL" fitFuncVjet = "ERFEXP" if nBtag < 2 else "ERFEXP" fitFuncVV = "EXPGAUS" fitFuncTop = "GAUS2" elif nLept == 1: treeName = 'WCR' signName = 'XWh' colorVjet = sample['WJetsToLNu']['linecolor'] triName = "HLT_Ele" if nElec > 0 else "HLT_Mu" leptCut = "isWtoEN" if nElec > 0 else "isWtoMN" topVeto = selection["TopVetocut"] massVar = "X_mass" binFact = 2 if nElec > 0: fitFunc = "EXP" if nBtag < 2 else "EXP" fitAltFunc = "EXPTAIL" if nBtag < 2 else "EXPTAIL" else: fitFunc = "EXPTAIL" if nBtag < 2 else "EXP" fitAltFunc = "EXPN" if nBtag < 2 else "EXPTAIL" fitFuncVjet = "ERFEXP" if nBtag < 2 else "ERFEXP" fitFuncVV = "EXPGAUS" fitFuncTop = "GAUS3" if nBtag < 2 else "GAUS2" else: treeName = 'XZh' signName = 'XZh' colorVjet = sample['DYJetsToLL']['linecolor'] triName = "HLT_Ele" if nElec > 0 else "HLT_Mu" leptCut = "isZtoEE" if nElec > 0 else "isZtoMM" topVeto = "0==0" massVar = "X_mass" binFact = 5 if nElec > 0: fitFunc = "EXP" if nBtag < 2 else "EXP" fitAltFunc = "POW" if nBtag < 2 else "POW" else: fitFunc = "EXP" if nBtag < 2 else "EXP" fitAltFunc = "POW" if nBtag < 2 else "POW" fitFuncVjet = "ERFEXP" if nBtag < 2 else "EXP" fitFuncVV = "EXPGAUS2" fitFuncTop = "GAUS" btagCut = selection["2Btag"] if nBtag == 2 else selection["1Btag"] print "--- Channel", channel, "---" print " number of electrons:", nElec, " muons:", nMuon, " b-tags:", nBtag print " read tree:", treeName, "and trigger:", triName if ALTERNATIVE: print " using ALTERNATIVE fit functions" print "-"*11*2 # Silent RooFit RooMsgService.instance().setGlobalKillBelow(RooFit.FATAL) #*******************************************************# # # # Variables and selections # # # #*******************************************************# # Define all the variables from the trees that will be used in the cuts and fits # this steps actually perform a "projection" of the entire tree on the variables in thei ranges, so be careful once setting the limits X_mass = RooRealVar( massVar, "m_{X}" if nLept > 0 else "m_{T}^{X}", XBINMIN, XBINMAX, "GeV") J_mass = RooRealVar( "fatjet1_prunedMassCorr", "corrected pruned mass", HBINMIN, HBINMAX, "GeV") CSV1 = RooRealVar( "fatjet1_CSVR1", "", -1.e99, 1.e4 ) CSV2 = RooRealVar( "fatjet1_CSVR2", "", -1.e99, 1.e4 ) nBtag = RooRealVar( "fatjet1_nBtag", "", 0., 4 ) CSVTop = RooRealVar( "bjet1_CSVR", "", -1.e99, 1.e4 ) isZtoEE = RooRealVar("isZtoEE", "", 0., 2 ) isZtoMM = RooRealVar("isZtoMM", "", 0., 2 ) isWtoEN = RooRealVar("isWtoEN", "", 0., 2 ) isWtoMN = RooRealVar("isWtoMN", "", 0., 2 ) weight = RooRealVar( "eventWeightLumi", "", -1.e9, 1. ) # Define the RooArgSet which will include all the variables defined before # there is a maximum of 9 variables in the declaration, so the others need to be added with 'add' variables = RooArgSet(X_mass, J_mass, CSV1, CSV2, nBtag, CSVTop) variables.add(RooArgSet(isZtoEE, isZtoMM, isWtoEN, isWtoMN, weight)) # Define the ranges in fatJetMass - these will be used to define SB and SR J_mass.setRange("LSBrange", LOWMIN, LOWMAX) J_mass.setRange("HSBrange", HIGMIN, HIGMAX) J_mass.setRange("VRrange", LOWMAX, SIGMIN) J_mass.setRange("SRrange", SIGMIN, SIGMAX) J_mass.setBins(54) # Define the selection for the various categories (base + SR / LSBcut / HSBcut ) baseCut = leptCut + " && " + btagCut + "&&" + topVeto massCut = massVar + ">%d" % XBINMIN baseCut += " && " + massCut # Cuts SRcut = baseCut + " && %s>%d && %s<%d" % (J_mass.GetName(), SIGMIN, J_mass.GetName(), SIGMAX) LSBcut = baseCut + " && %s>%d && %s<%d" % (J_mass.GetName(), LOWMIN, J_mass.GetName(), LOWMAX) HSBcut = baseCut + " && %s>%d && %s<%d" % (J_mass.GetName(), HIGMIN, J_mass.GetName(), HIGMAX) SBcut = baseCut + " && ((%s>%d && %s<%d) || (%s>%d && %s<%d))" % (J_mass.GetName(), LOWMIN, J_mass.GetName(), LOWMAX, J_mass.GetName(), HIGMIN, J_mass.GetName(), HIGMAX) VRcut = baseCut + " && %s>%d && %s<%d" % (J_mass.GetName(), LOWMAX, J_mass.GetName(), SIGMIN) # Binning binsJmass = RooBinning(HBINMIN, HBINMAX) binsJmass.addUniform(HBINS, HBINMIN, HBINMAX) binsXmass = RooBinning(XBINMIN, XBINMAX) binsXmass.addUniform(binFact*XBINS, XBINMIN, XBINMAX) #*******************************************************# # # # Input files # # # #*******************************************************# # Import the files using TChains (separately for the bkg "classes" that we want to describe: here DY and VV+ST+TT) treeData = TChain(treeName) treeMC = TChain(treeName) treeVjet = TChain(treeName) treeVV = TChain(treeName) treeTop = TChain(treeName) # treeSign = {} # nevtSign = {} # Read data print "read data start" pd = getPrimaryDataset(triName) if len(pd)==0: raw_input("Warning: Primary Dataset not recognized, continue?") for i, s in enumerate(pd): treeData.Add(NTUPLEDIR + s + ".root") # Read V+jets backgrounds print "read V+jet start" for i, s in enumerate(["WJetsToLNu_HT", "DYJetsToNuNu_HT", "DYJetsToLL_HT"]): for j, ss in enumerate(sample[s]['files']): treeVjet.Add(NTUPLEDIR + ss + ".root") # Read VV backgrounds print "read VV start" for i, s in enumerate(["VV"]): for j, ss in enumerate(sample[s]['files']): treeVV.Add(NTUPLEDIR + ss + ".root") # Read Top backgrounds print "read Top start" for i, s in enumerate(["ST", "TTbar"]): for j, ss in enumerate(sample[s]['files']): treeTop.Add(NTUPLEDIR + ss + ".root") # Sum all background MC treeMC.Add(treeVjet) treeMC.Add(treeVV) treeMC.Add(treeTop) # print "prepare SB dataset" # create a dataset to host data in sideband (using this dataset we are automatically blind in the SR!) # setDataSB = RooDataSet("setDataSB", "setDataSB", variables, RooFit.Cut(SBcut), RooFit.WeightVar(weight), RooFit.Import(treeData)) # setDataLSB = RooDataSet("setDataLSB", "setDataLSB", variables, RooFit.Import(setDataSB), RooFit.Cut(LSBcut), RooFit.WeightVar(weight)) # setDataHSB = RooDataSet("setDataHSB", "setDataHSB", variables, RooFit.Import(setDataSB), RooFit.Cut(HSBcut), RooFit.WeightVar(weight)) # print "prepare SR dataset" # Observed data (WARNING, BLIND!) # setDataSR = RooDataSet("setDataSR", "setDataSR", variables, RooFit.Cut(SRcut), RooFit.WeightVar(weight), RooFit.Import(treeData)) # setDataVR = RooDataSet("setDataVR", "setDataVR", variables, RooFit.Cut(VRcut), RooFit.WeightVar(weight), RooFit.Import(treeData)) # Observed in the VV mass, just for plotting purposes print "prepare MC dataset" # same for the bkg datasets from MC, where we just apply the base selections (not blind) setVjet = RooDataSet("setVjet", "setVjet", variables, RooFit.Cut(baseCut), RooFit.WeightVar(weight), RooFit.Import(treeVjet)) setVjetSB = RooDataSet("setVjetSB", "setVjetSB", variables, RooFit.Import(setVjet), RooFit.Cut(SBcut), RooFit.WeightVar(weight)) setVjetSR = RooDataSet("setVjetSR", "setVjetSR", variables, RooFit.Import(setVjet), RooFit.Cut(SRcut), RooFit.WeightVar(weight)) print "finish Vjet dataset" # setVV = RooDataSet("setVV", "setVV", variables, RooFit.Cut(baseCut), RooFit.WeightVar(weight), RooFit.Import(treeVV)) # setVVSB = RooDataSet("setVVSB", "setVVSB", variables, RooFit.Import(setVV), RooFit.Cut(SBcut), RooFit.WeightVar(weight)) # setVVSR = RooDataSet("setVVSR", "setVVSR", variables, RooFit.Import(setVV), RooFit.Cut(SRcut), RooFit.WeightVar(weight)) # print "finish VV dataset" # setTop = RooDataSet("setTop", "setTop", variables, RooFit.Cut(baseCut), RooFit.WeightVar(weight), RooFit.Import(treeTop)) # setTopSB = RooDataSet("setTopSB", "setTopSB", variables, RooFit.Import(setTop), RooFit.Cut(SBcut), RooFit.WeightVar(weight)) # setTopSR = RooDataSet("setTopSR", "setTopSR", variables, RooFit.Import(setTop), RooFit.Cut(SRcut), RooFit.WeightVar(weight)) # print "finish Top dataset" # print " Data events SB: %.2f" % setDataSB.sumEntries() print " V+jets entries: %.2f" % setVjet.sumEntries() # print " VV, VH entries: %.2f" % setVV.sumEntries() # print " Top,ST entries: %.2f" % setTop.sumEntries() # the relative normalization of the varius bkg is taken from MC by counting all the events in the full fatJetMass range #coef = RooRealVar("coef", "coef", setVV.sumEntries()/setVjet.sumEntries(),0.,1.) # coef_VV_Vjet = RooRealVar("coef2_1", "coef2_1", setVV.sumEntries()/setVjet.sumEntries(), 0., 1.) # coef_Top_VVVjet = RooRealVar("coef3_21", "coef3_21", setTop.sumEntries()/(setVjet.sumEntries()+setVV.sumEntries()),0.,1.); # coef_VV_Vjet.setConstant(True) # coef_Top_VVVjet.setConstant(True) # Define entries entryVjet = RooRealVar("entryVjets", "V+jets normalization", setVjet.sumEntries(), 0., 1.e6) # entryVV = RooRealVar("entryVV", "VV normalization", setVV.sumEntries(), 0., 1.e6) # entryTop = RooRealVar("entryTop", "Top normalization", setTop.sumEntries(), 0., 1.e6) # entrySB = RooRealVar("entrySB", "Data SB normalization", setDataSB.sumEntries(SBcut), 0., 1.e6) # entrySB.setError(math.sqrt(entrySB.getVal())) # entryLSB = RooRealVar("entryLSB", "Data LSB normalization", setDataSB.sumEntries(LSBcut), 0., 1.e6) # entryLSB.setError(math.sqrt(entryLSB.getVal())) # entryHSB = RooRealVar("entryHSB", "Data HSB normalization", setDataSB.sumEntries(HSBcut), 0., 1.e6) # entryHSB.setError(math.sqrt(entryHSB.getVal())) #*******************************************************# # # # NORMALIZATION # # # #*******************************************************# # set reasonable ranges for J_mass and X_mass # these are used in the fit in order to avoid ROOFIT to look in regions very far away from where we are fitting J_mass.setRange("h_reasonable_range", LOWMIN, HIGMAX) X_mass.setRange("X_reasonable_range", XBINMIN, XBINMAX) # Set RooArgSets once for all, see https://root.cern.ch/phpBB3/viewtopic.php?t=11758 jetMassArg = RooArgSet(J_mass) ############################## # # # Yu-hsiang test region # # # ############################## # test it in the channel "XZhnnb" print "the channel is", channel if channel == "XZhnnb": # ------------------------------------------------------------------- # draw the setVjet Jmass_frame = J_mass.frame(RooFit.Title("test frame")) setVjet.plotOn(Jmass_frame) # ------------------------------------------------------------------- # use a PDF to fit the dataset print "fitFuncVjet is", fitFuncVjet constVjet_value_initial = -0.020 offsetVjet_value_initial = 30. widthVjet_value_initial = 100. constVjet_test = RooRealVar("constVjet_test", "slope of the exp", constVjet_value_initial , -1., 0.) offsetVjet_test = RooRealVar("offsetVjet_test", "offset of the erf", offsetVjet_value_initial, -50., 200.) widthVjet_test = RooRealVar("widthVjet_test", "width of the erf", widthVjet_value_initial, 1., 200.) modelVjet_test = RooErfExpPdf("modelVjet_test", "error function for V+jets mass", J_mass, constVjet_test, offsetVjet_test, widthVjet_test) # constVjet_test.Print() # offsetVjet_test.Print() # widthVjet_test.Print() # constVjet_test.setConstant(True) # offsetVjet_test.setConstant(True) # widthVjet_test.setConstant(True) frVjet_test = modelVjet_test.fitTo(setVjet, RooFit.SumW2Error(True), RooFit.Range("h_reasonable_range"), RooFit.Strategy(2), RooFit.Minimizer("Minuit2"), RooFit.Save(1), RooFit.PrintLevel(1 if VERBOSE else -1)) # constVjet_test.Print() # offsetVjet_test.Print() # widthVjet_test.Print() constVjet_value_fit_MC = constVjet_test.getVal() offsetVjet_value_fit_MC = offsetVjet_test.getVal() widthVjet_value_fit_MC = widthVjet_test.getVal() print "constVjet_value_fit_MC:", constVjet_value_fit_MC, "offsetVjet_value_fit_MC:",offsetVjet_value_fit_MC,"widthVjet_value_fit_MC:",widthVjet_value_fit_MC modelVjet_test.plotOn(Jmass_frame,RooFit.LineColor(4)) # ------------------------------------------------------------------- # use the shape of fit to generate the psudo-data Entries_pseudo_data = setVjet.sumEntries() # Entries_pseudo_data = 502 # Entries_pseudo_data = 5021 pseudo_data = modelVjet_test.generate(RooArgSet(J_mass),Entries_pseudo_data ) # pseudo_data = modelVjet_test.generate(RooArgSet(J_mass),setVjet.sumEntries()) # pseudo_data = modelVjet_test.generate(RooArgSet(J_mass),502 ) # pseudo_data = modelVjet_test.generate(RooArgSet(J_mass),5021 ) # pseudo_data.Print("v") Jmass_frame2 = J_mass.frame(RooFit.Title("test frame2")) pseudo_data.plotOn(Jmass_frame2) modelVjet_test.plotOn(Jmass_frame2,RooFit.LineColor(4)) # ------------------------------------------------------------------- # make another dataset that remove the signal region pseudo_data_SB = RooDataSet("pseudo_data_SB", "pseudo_data_SB", RooArgSet(J_mass), RooFit.Import(pseudo_data), RooFit.Cut("fatjet1_prunedMassCorr<65 || fatjet1_prunedMassCorr>135") ) pseudo_data_SB.plotOn(Jmass_frame2,RooFit.LineColor(2)) # ------------------------------------------------------------------- # use another PDF to fit the pseudo-data in SB only constVjet_test2 = RooRealVar("constVjet_test2", "slope of the exp", constVjet_value_fit_MC , -1., 0.) offsetVjet_test2 = RooRealVar("offsetVjet_test2", "offset of the erf", offsetVjet_value_fit_MC , -50., 200.) widthVjet_test2 = RooRealVar("widthVjet_test2", "width of the erf", widthVjet_value_fit_MC , 1., 200.) modelVjet_test2 = RooErfExpPdf("modelVjet_test2", "error function for V+jets mass", J_mass, constVjet_test2, offsetVjet_test2, widthVjet_test2) frVjet_test2 = modelVjet_test2.fitTo(pseudo_data_SB, RooFit.SumW2Error(True), RooFit.Range("LSBrange,HSBrange"), RooFit.Strategy(2), RooFit.Minimizer("Minuit2"), RooFit.Save(1), RooFit.PrintLevel(1 if VERBOSE else -1)) # frVjet_test2 = modelVjet_test2.fitTo(pseudo_data_SB, RooFit.SumW2Error(True), RooFit.Range("h_reasonable_range"), RooFit.Strategy(2), RooFit.Minimizer("Minuit2"), RooFit.Save(1), RooFit.PrintLevel(1 if VERBOSE else -1)) constVjet_value_fit_pseudo_data_SB = constVjet_test2.getVal() offsetVjet_value_fit_pseudo_data_SB = offsetVjet_test2.getVal() widthVjet_value_fit_pseudo_data_SB = widthVjet_test2.getVal() print "constVjet_value_fit_pseudo_data_SB:", constVjet_value_fit_pseudo_data_SB, "offsetVjet_value_fit_pseudo_data_SB:",offsetVjet_value_fit_pseudo_data_SB,"widthVjet_value_fit_pseudo_data_SB:",widthVjet_value_fit_pseudo_data_SB Jmass_frame3 = J_mass.frame(RooFit.Title("test frame3, fit the pseudo-data in SB only")) pseudo_data_SB.plotOn(Jmass_frame3) modelVjet_test2.plotOn(Jmass_frame3,RooFit.LineColor(4),RooFit.Range("h_reasonable_range")) # ------------------------------------------------------------------- # calculate the Gen_value, the Fit_value and the Bias= ( Fit_value - Gen_value)/Gen_value iGen_value = modelVjet_test.createIntegral(RooArgSet(J_mass), RooFit.Range("VRrange,SRrange")) print "iGen_value:", iGen_value.getVal() iFit_value = modelVjet_test2.createIntegral(RooArgSet(J_mass), RooFit.Range("VRrange,SRrange")) print "iFit_value:", iFit_value.getVal() Bias_value = ( iFit_value.getVal() - iGen_value.getVal() ) / iGen_value.getVal() print "Bias_value of VR+SR:", Bias_value # -------------- iGen_value = modelVjet_test.createIntegral(RooArgSet(J_mass), RooFit.Range("SRrange")) print "iGen_value:", iGen_value.getVal() iFit_value = modelVjet_test2.createIntegral(RooArgSet(J_mass), RooFit.Range("SRrange")) print "iFit_value:", iFit_value.getVal() Bias_value = ( iFit_value.getVal() - iGen_value.getVal() ) / iGen_value.getVal() print "Bias_value of SR:", Bias_value # iGen_value = modelVjet_test.createIntegral(RooArgSet(J_mass),RooFit.NormSet(RooArgSet(J_mass)), RooFit.Range("VRrange,SRrange")) # print "iGen_value:", iGen_value.getVal() # iGen_value = modelVjet_test.createIntegral(RooArgSet(J_mass),RooFit.NormSet(RooArgSet(J_mass)), RooFit.Range("VRrange,SRrange")) # print "iGen_value:", iGen_value.getVal() # iGen_value = modelVjet_test.createIntegral(RooArgSet(J_mass), RooFit.Range("h_reasonable_range")) # print "iGen_value:", iGen_value.getVal() # iGen_value = modelVjet_test.createIntegral(RooArgSet(J_mass)) # print "iGen_value:", iGen_value.getVal() # ------------------------------------------------------------------- # repeat thousand times to see bias distribution h_Bias = TH1D("h_Bias","h_Bias",80,-1,1); Jmass_frame4 = J_mass.frame(RooFit.Title("test frame4")) times_max = 50000 constVjet_test.setConstant(True) offsetVjet_test.setConstant(True) widthVjet_test.setConstant(True) constVjet_test3 = RooRealVar("constVjet_test3", "slope of the exp", constVjet_value_fit_MC , -1., 0.) offsetVjet_test3 = RooRealVar("offsetVjet_test3", "offset of the erf", offsetVjet_value_fit_MC , -50., 200.) widthVjet_test3 = RooRealVar("widthVjet_test3", "width of the erf", widthVjet_value_fit_MC , 1., 200.) for times in range(0,times_max): # inside loop # print "times:", times if times % 10 == 0 : print "Processing times:", times+1 ,"of", times_max # generate pseudo-data # n_1_prime = gRandom->Poisson(n_1); Entries_pseudo_data_fluc = gRandom.Poisson( Entries_pseudo_data ) # print "Entries_pseudo_data:", Entries_pseudo_data # print "Entries_pseudo_data_fluc:", Entries_pseudo_data_fluc # pseudo_data2 = modelVjet_test.generate(RooArgSet(J_mass),Entries_pseudo_data ) pseudo_data2 = modelVjet_test.generate(RooArgSet(J_mass),Entries_pseudo_data_fluc ) # pseudo_data2.plotOn(Jmass_frame3,RooFit.LineColor(4),RooFit.Range("h_reasonable_range")) # take out VR+SR pseudo_data_SB2 = RooDataSet("pseudo_data_SB2", "pseudo_data_SB2", RooArgSet(J_mass), RooFit.Import(pseudo_data2), RooFit.Cut("fatjet1_prunedMassCorr<65 || fatjet1_prunedMassCorr>135") ) # use other PDF to fit # print "constVjet_value_fit_MC:",constVjet_value_fit_MC constVjet_test3.setVal(constVjet_value_fit_MC) offsetVjet_test3.setVal(offsetVjet_value_fit_MC) widthVjet_test3.setVal(widthVjet_value_fit_MC) modelVjet_test3 = RooErfExpPdf("modelVjet_test3", "error function for V+jets mass", J_mass, constVjet_test3, offsetVjet_test3, widthVjet_test3) frVjet_test3 = modelVjet_test3.fitTo(pseudo_data_SB2, RooFit.SumW2Error(True), RooFit.Range("LSBrange,HSBrange"), RooFit.Strategy(2), RooFit.Minimizer("Minuit2"), RooFit.Save(1), RooFit.PrintLevel(1 if VERBOSE else -1)) # calculate the bias iGen_value2 = modelVjet_test.createIntegral(jetMassArg,RooFit.NormSet(jetMassArg), RooFit.Range("SRrange")) # print "iGen_value2:", iGen_value2.getVal() iFit_value2 = modelVjet_test3.createIntegral(jetMassArg,RooFit.NormSet(jetMassArg), RooFit.Range("SRrange")) # print "iFit_value2:", iFit_value2.getVal() Bias_value2 = ( iFit_value2.getVal() - iGen_value2.getVal() ) / iGen_value2.getVal() # print "Bias_value2 of VR+SR:", Bias_value2 h_Bias.Fill(Bias_value2) # ------------------------------------------------------------------- # plot and save Save_Dir = "/afs/cern.ch/user/y/yuchang/www/jacopo_plotsAlpha/yu_hsiang_bias_study" c_test = TCanvas("test","test draw",800,600) c_test.cd() Jmass_frame.Draw() c_test.SaveAs(Save_Dir+"/"+"VJet_MC_fit_get_shape.pdf") c_test2 = TCanvas("test2","test draw 2",800,600) c_test2.cd() Jmass_frame2.Draw() c_test2.SaveAs(Save_Dir+"/"+"use_shape_to_generate_pseudo_data.pdf") # c_test2.SaveAs(Save_Dir+"/"+"use_shape_to_generate_pseudo_data_test.pdf") c_test3 = TCanvas("test3","test draw 3",800,600) c_test3.cd() Jmass_frame3.Draw() c_test3.SaveAs(Save_Dir+"/"+"fit_pseudo_data_in_SB_only.pdf") c_test4 = TCanvas("test4","test draw 4",800,600) c_test4.cd() h_Bias.Draw() c_test4.SaveAs(Save_Dir+"/"+"h_Bias.pdf")
#diJetMass_5 = RooGenericPdf('diJetMass_5', "@1+@2*pow(@0,1)+@3*pow(@0,2)+@4*pow(@0,3)+@5*pow(@0,4)+@6*pow(@0,5)",RooArgList(J_Mass,p1mod,p2mod,p3mod,p4mod,p5mod,p6mod)) #diJetMass_5 = RooGenericPdf('diJetMass_5', "@1*pow(@0,1)+@2*pow(@0,2)+@3*pow(@0,3)+@4*pow(@0,4)+@5*pow(@0,5)",RooArgList(J_Mass,p2mod,p3mod,p4mod,p5mod,p6mod)) #x= RooRealVar("x","x", 500,1500) #x.setRange(520,1500) #diJetMass_5 = RooBernstein ("diJetMass_5","diJetMass_5",x,RooArgList(p1mod,p2mod,p3mod,p4mod,p5mod,p6mod)) #diJetMass_2 = RooGenericPdf('diJetMass_2', "1.0/pow(@0,@2)", RooArgList(x,p3mod)) #diJetMass_3 = RooGenericPdf('diJetMass_3', "pow(1-@0,@2)/pow(@0,@3)",RooArgList(x,p1mod,p2mod,p3mod)) #diJetMass_4 = RooGenericPdf('diJetMass_4', "pow(1-@0,@2)/pow(@0, @3+@4*log(@0))", RooArgList(x, p1mod, p2mod,p3mod,p4mod)) #diJetMass_5 = RooGenericPdf('diJetMass_5', "pow(1-@0,@2)/pow(@0, @3+@4*log(@0)+@5*pow(log(@0),2))", RooArgList(x, p1mod, p2mod,p3mod,p4mod,p5mod)) #diJetMass_4 = RooGenericPdf('diJetMass_4', "pow(1-@0, @2)/pow(@0, @1+@3*log(@0))", RooArgList(x, p1mod, p2mod,p3mod)) ## Erf x Exp constQCD = RooRealVar('constQCD', 'constQCD', -0.02, -1., 0.) offsetQCD = RooRealVar('offsetQCD', 'offsetQCD', 70., -0., 200.) widthQCD = RooRealVar('widthQCD', 'widthQCD', 30., 0.1, 100.) ErfExpQCD = RooErfExpPdf("ErfExpQCD", "error function for Z+jets mass", J_Mass, constQCD, offsetQCD, widthQCD) ########################################## # # ##### ##### ####### #### # # # # # # # # # # # # # # # ##### #### ####### # # # # # # # # # # # # # # # # # # # # # #### ########################################## ## fraction parameters ## for signal signalfrac = RooRealVar('signalfrac', 'signalfrac', 0.01, 0, 0.1)