def getTrees(theConfig, datasets, central=True): import dataInterface #~ theDataInterface = dataInterface.dataInterface(dataVersion=dataVersion) theDataInterface = dataInterface.DataInterface(theConfig.dataSetPath,theConfig.dataVersion) treePathOFOS = "/EMuDileptonTree" treePathEE = "/EEDileptonTree" treePathMM = "/MuMuDileptonTree" treesMCOFOS = ROOT.TList() treesMCEE = ROOT.TList() treesMCMM = ROOT.TList() if central: cut = theConfig.selection.cut + " && abs(eta1) < 1.4 && abs(eta2) < 1.4" else: cut = theConfig.selection.cut + " && 1.6 <= TMath::Max(abs(eta1),abs(eta2)) && !(abs(eta1) > 1.4 && abs(eta1) < 1.6) && !(abs(eta2) > 1.4 && abs(eta2) < 1.6)" for dataset in datasets: scale = 0.0 # dynamic scaling jobs = dataInterface.InfoHolder.theDataSamples[theConfig.dataVersion][dataset] if (len(jobs) > 1): log.logDebug("Scaling and adding more than one job: %s" % (jobs)) for job in jobs: treeMCOFOSraw = theDataInterface.getTreeFromJob(theConfig.flag, theConfig.task, job, treePathOFOS, dataVersion=theConfig.dataVersion, cut=theConfig.selection.cut) treeMCEEraw = theDataInterface.getTreeFromJob(theConfig.flag, theConfig.task, job, treePathEE, dataVersion=theConfig.dataVersion, cut=theConfig.selection.cut) treeMCMMraw = theDataInterface.getTreeFromJob(theConfig.flag, theConfig.task, job, treePathMM, dataVersion=theConfig.dataVersion, cut=theConfig.selection.cut) dynNTotal = theDataInterface.getEventCount(job, theConfig.flag, theConfig.task) dynXsection = theDataInterface.getCrossSection(job) dynScale = dynXsection * theConfig.runRange.lumi / dynNTotal if (dynScale != scale): log.logInfo("dyn scale for %s (%s): n = %d, x = %f => %f" % (job, dataset, dynNTotal, dynXsection, dynScale)) scale = dynScale else: log.logError("No dynamic scale applied. This should never happen!") # convert trees treesMCOFOS.Add(dataInterface.DataInterface.convertDileptonTree(treeMCOFOSraw, weight=scale)) treesMCEE.Add(dataInterface.DataInterface.convertDileptonTree(treeMCEEraw, weight=scale)) treesMCMM.Add(dataInterface.DataInterface.convertDileptonTree(treeMCMMraw, weight=scale)) treeMCOFOStotal = ROOT.TTree.MergeTrees(treesMCOFOS) treeMCEEtotal = ROOT.TTree.MergeTrees(treesMCEE) treeMCMMtotal = ROOT.TTree.MergeTrees(treesMCMM) return (treeMCOFOStotal, treeMCEEtotal, treeMCMMtotal)
def getSignalTrees(theConfig, signals, useNLL=False): import dataInterface treesMCEM = ROOT.TList() treesMCEE = ROOT.TList() treesMCMM = ROOT.TList() runRanges = theConfig.runRanges cut = theConfig.selection.cut for runRange in runRanges: scale = 0.0 theDataInterface = dataInterface.DataInterface([ runRange, ]) for signal in signals: treeMCEMraw = theDataInterface.getSignalTreeFromJob(signal, "EMu", cut=cut, useNLL=useNLL) treeMCEEraw = theDataInterface.getSignalTreeFromJob(signal, "EE", cut=cut, useNLL=useNLL) treeMCMMraw = theDataInterface.getSignalTreeFromJob(signal, "MuMu", cut=cut, useNLL=useNLL) from helpers import getSignalGenEvents, getSignalXsec dynXsection = getSignalXsec(signal, runRange) dynNTotal = getSignalGenEvents(signal, runRange) dynScale = dynXsection * runRange.lumi / (dynNTotal) if (dynScale != scale): log.logInfo("dyn scale for %s: n = %d, x = %f => %f" % (signal, dynNTotal, dynXsection, dynScale)) scale = dynScale else: log.logError( "No dynamic scale applied. This should never happen!") if not treeMCEMraw == None: treesMCEM.Add( dataInterface.DataInterface.convertDileptonTree( treeMCEMraw, weight=scale)) if not treeMCEEraw == None: treesMCEE.Add( dataInterface.DataInterface.convertDileptonTree( treeMCEEraw, weight=scale)) if not treeMCMMraw == None: treesMCMM.Add( dataInterface.DataInterface.convertDileptonTree( treeMCMMraw, weight=scale)) treeMCEMtotal = ROOT.TTree.MergeTrees(treesMCEM) treeMCEEtotal = ROOT.TTree.MergeTrees(treesMCEE) treeMCMMtotal = ROOT.TTree.MergeTrees(treesMCMM) return (treeMCEMtotal, treeMCEEtotal, treeMCMMtotal)
def getTrees(theConfig, datasets, useNLL=False): import dataInterface treesMCEM = ROOT.TList() treesMCEE = ROOT.TList() treesMCMM = ROOT.TList() runRanges = theConfig.runRanges cut = theConfig.selection.cut for runRange in runRanges: theDataInterface = dataInterface.DataInterface([ runRange, ]) for dataset in datasets: scale = 0.0 # dynamic scaling eventCounts = totalNumberOfGeneratedEvents( locations[runRange.era].dataSetPath) proc = Process(getattr(Backgrounds[runRange.era], dataset), eventCounts) if (len(proc.samples) > 1): log.logDebug("Scaling and adding more than one job: %s" % (proc.samples)) for job, dynNTotal, dynXsection, dynNegWeightFraction in zip( proc.samples, proc.nEvents, proc.xsecs, proc.negWeightFractions): treeMCEMraw = theDataInterface.getTreeFromJob(job, "EMu", cut=cut, useNLL=useNLL) treeMCEEraw = theDataInterface.getTreeFromJob(job, "EE", cut=cut, useNLL=useNLL) treeMCMMraw = theDataInterface.getTreeFromJob(job, "MuMu", cut=cut, useNLL=useNLL) #~ dynScale = dynXsection * theConfig.runRange.lumi / dynNTotal print runRange.lumi dynScale = dynXsection * runRange.lumi / ( dynNTotal * (1 - 2 * dynNegWeightFraction)) if (dynScale != scale): log.logInfo( "dyn scale for %s (%s): n = %d, x = %f => %f" % (job, dataset, dynNTotal, dynXsection, dynScale)) scale = dynScale else: log.logError( "No dynamic scale applied. This should never happen!") # convert trees if not treeMCEMraw == None: treesMCEM.Add( dataInterface.DataInterface.convertDileptonTree( treeMCEMraw, weight=scale)) if not treeMCEEraw == None: treesMCEE.Add( dataInterface.DataInterface.convertDileptonTree( treeMCEEraw, weight=scale)) if not treeMCMMraw == None: treesMCMM.Add( dataInterface.DataInterface.convertDileptonTree( treeMCMMraw, weight=scale)) treeMCEMtotal = ROOT.TTree.MergeTrees(treesMCEM) treeMCEEtotal = ROOT.TTree.MergeTrees(treesMCEE) treeMCMMtotal = ROOT.TTree.MergeTrees(treesMCMM) return (treeMCEMtotal, treeMCEEtotal, treeMCMMtotal)
def main(): parser = argparse.ArgumentParser(description='edge fitter reloaded.') parser.add_argument("-v", "--verbose", action="store_true", dest="verbose", default=False, help="Verbose mode.") parser.add_argument("-m", "--mc", action="store_true", dest="mc", default=False, help="use MC, default is to use data.") parser.add_argument( "-u", "--use", action="store_true", dest="useExisting", default=False, help="use existing datasets from pickle, default is false.") ### MT2 changes the mll shape, but the effect on the Z shape is small ### Used a control region definition with MT2 cut in my thesis, but ### the plots do not look well when using MC due to lacking statistics ### or a missing sample. You have to check which CR to use. The impact ### on the fit results is negligible. Adapt y-range accordingly parser.add_argument( "-s", "--selection", dest="selection", action="store", default="DrellYanControl", #parser.add_argument("-s", "--selection", dest = "selection" , action="store", default="DrellYanControlNoMT2Cut", help="selection which to apply.") parser.add_argument("-r", "--runRange", dest="runRanges", action="append", default=[], help="name of run range.") parser.add_argument("-c", "--combine", dest="combine", action="store_true", default=False, help="combined runRanges or not") parser.add_argument("-x", "--private", action="store_true", dest="private", default=False, help="plot is private work.") parser.add_argument("-w", "--write", action="store_true", dest="write", default=False, help="write results to central repository") args = parser.parse_args() if not args.verbose: ROOT.RooMsgService.instance().setGlobalKillBelow(ROOT.RooFit.WARNING) ROOT.RooMsgService.instance().setSilentMode(ROOT.kTRUE) cmsExtra = "" if args.private: cmsExtra = "Private Work" if args.mc: cmsExtra = "#splitline{Private Work}{Simulation}" elif args.mc: cmsExtra = "Simulation" else: #~ cmsExtra = "Preliminary" cmsExtra = "Supplementary" useExistingDataset = args.useExisting lumi = 0 runRangeName = "_".join(args.runRanges) lumis = [] for runRange in args.runRanges: lumis.append(getRunRange(runRange).printval) #lumi = "+".join(lumis) lumi = "137" from edgeConfig import edgeConfig theConfig = edgeConfig(region=args.selection, runNames=args.runRanges, useMC=args.mc) if args.private: theConfig.ownWork = True # init ROOT # uncomment this if you want a segmentation violation #gROOT.Reset() gROOT.SetStyle("Plain") setTDRStyle() ROOT.gROOT.SetStyle("tdrStyle") # get data theDataInterface = dataInterface.DataInterface(theConfig.runRanges) treeOFOS = None treeEE = None treeMM = None #print ROOT.gDirectory.GetList() if not useExistingDataset: w = ROOT.RooWorkspace("w", ROOT.kTRUE) inv = ROOT.RooRealVar("inv", "inv", (theConfig.maxInv - theConfig.minInv) / 2, theConfig.minInv, theConfig.maxInv) getattr(w, 'import')(inv, ROOT.RooCmdArg()) w.factory("weight[1.,0.,10.]") vars = ROOT.RooArgSet(inv, w.var('weight')) if (theConfig.useMC): log.logHighlighted("Using MC instead of data.") datasets = theConfig.mcdatasets # ["TTJets", "ZJets", "DibosonMadgraph", "SingleTop"] (treeEM, treeEE, treeMM) = tools.getTrees(theConfig, datasets) else: treeMMraw = theDataInterface.getTreeFromDataset( "MergedData", "MuMu", cut=theConfig.selection.cut) treeEMraw = theDataInterface.getTreeFromDataset( "MergedData", "EMu", cut=theConfig.selection.cut) treeEEraw = theDataInterface.getTreeFromDataset( "MergedData", "EE", cut=theConfig.selection.cut) # convert trees treeEM = dataInterface.DataInterface.convertDileptonTree(treeEMraw) treeEE = dataInterface.DataInterface.convertDileptonTree(treeEEraw) treeMM = dataInterface.DataInterface.convertDileptonTree(treeMMraw) print "EM", treeEM.GetEntries() print "EE", treeEE.GetEntries() print "MM", treeMM.GetEntries() histEM = createFitHistoFromTree( treeEM, "inv", "weight", int((theConfig.maxInv - theConfig.minInv) / 2), theConfig.minInv, theConfig.maxInv) histEE = createFitHistoFromTree( treeEE, "inv", "weight", int((theConfig.maxInv - theConfig.minInv) / 2), theConfig.minInv, theConfig.maxInv) histMM = createFitHistoFromTree( treeMM, "inv", "weight", int((theConfig.maxInv - theConfig.minInv) / 2), theConfig.minInv, theConfig.maxInv) dataHistEE = ROOT.RooDataHist("dataHistEE", "dataHistEE", ROOT.RooArgList(w.var('inv')), histEE) dataHistMM = ROOT.RooDataHist("dataHistMM", "dataHistMM", ROOT.RooArgList(w.var('inv')), histMM) getattr(w, 'import')(dataHistEE, ROOT.RooCmdArg()) getattr(w, 'import')(dataHistMM, ROOT.RooCmdArg()) if theConfig.useMC: w.writeToFile("workspaces/dyControl_%s_MC.root" % (runRangeName)) else: w.writeToFile("workspaces/dyControl_%s_Data.root" % (runRangeName)) else: if theConfig.useMC: f = ROOT.TFile("workspaces/dyControl_%s_MC.root" % (runRangeName)) else: f = ROOT.TFile("workspaces/dyControl_%s_Data.root" % (runRangeName)) w = f.Get("w") #~ vars = ROOT.RooArgSet(w.var("inv"), w.var('weight'), w.var('genWeight')) vars = ROOT.RooArgSet(w.var("inv"), w.var('weight')) ### For some reason we never switched from the hard coded maximum. ### Might want to change this in the future yMaximum = 5 * 10000 ### 2016+2017+2018 data with MT2 cut yMinimum = 0.1 ### 2016+2017+2018 data with MT2 cut #yMaximum = histEE.GetMaximum()*1e10 #yMinimum = 10 global nBinsDY nBinsDY = 240 # global histoytitle histoytitle = 'Events / %.1f GeV' % ( (theConfig.maxInv - theConfig.minInv) / float(nBinsDY)) #histoytitle = 'Events / 4 GeV' ROOT.gSystem.Load("shapes/RooDoubleCB_cxx.so") ROOT.gSystem.Load("libFFTW.so") ## 2 GeV binning for DY compared to 5 GeV in main fit w.var('inv').setBins(nBinsDY) #~ w.var('inv').setBins(140) # We know the z mass # z mass and width # mass resolution in electron and muon channels #w.factory("zmean[91.1876, 90.1876, 92.1876]") w.factory("zmean[91.1876]") #w.factory("zmean[91.1876,89,93]") w.factory("cbmeanMM[3.0,-5,5]") w.factory("cbmeanEE[3.0,-5,5]") w.factory("zwidthMM[2.4952]") w.factory("zwidthEE[2.4952]") w.factory("sMM[1.6.,0.,20.]") w.factory("BreitWigner::zShapeMM(inv,zmean,zwidthMM)") w.factory("sEE[1.61321382563436089e+00,0,20.]") w.factory("BreitWigner::zShapeEE(inv,zmean,zwidthEE)") w.factory("nMML[3.,0.,10]") w.factory("alphaMML[1.15,0,10]") w.factory("nMMR[1.,0,10]") w.factory("alphaMMR[2.5,0,10]") w.factory( "DoubleCB::cbShapeMM(inv,cbmeanMM,sMM,alphaMML,nMML,alphaMMR,nMMR)") w.factory("nEEL[2.903,0.,10]") w.factory("alphaEEL[1.1598,0,5]") w.factory("nEER[1.0,0,10]") w.factory("alphaEER[2.508,0,5]") w.factory( "DoubleCB::cbShapeEE(inv,cbmeanEE,sEE,alphaEEL,nEEL,alphaEER,nEER)") Abkg = ROOT.RooRealVar("Abkg", "Abkg", 1, 0.01, 10) getattr(w, 'import')(Abkg, ROOT.RooCmdArg()) #~ w.var("inv").setBins(250,"cache") w.factory("cContinuumEE[%f,%f,%f]" % (-0.02, -0.1, 0)) w.factory("nZEE[100000.,500.,%s]" % (2000000)) #~ w.factory("nZEE[100000.,300.,%s]" % (2000000)) w.factory("Exponential::offShellEE(inv,cContinuumEE)") convEE = ROOT.RooFFTConvPdf("peakModelEE", "zShapeEE (x) cbShapeEE", w.var("inv"), w.pdf("zShapeEE"), w.pdf("cbShapeEE")) getattr(w, 'import')(convEE, ROOT.RooCmdArg()) w.pdf("peakModelEE").setBufferFraction(5.0) w.factory("zFractionEE[0.9,0,1]") expFractionEE = ROOT.RooFormulaVar('expFractionEE', '1-@0', ROOT.RooArgList(w.var('zFractionEE'))) getattr(w, 'import')(expFractionEE, ROOT.RooCmdArg()) w.factory( "SUM::modelEE1(zFractionEE*peakModelEE,expFractionEE*offShellEE)") w.factory("SUM::modelEE(nZEE*modelEE1)") w.factory("cContinuumMM[%f,%f,%f]" % (-0.02, -0.1, 0)) w.factory("Exponential::offShellMM(inv,cContinuumMM)") w.factory("nZMM[100000.,500.,%s]" % (2000000)) w.factory("nOffShellMM[100000.,500.,%s]" % (2000000)) #~ w.factory("nZMM[100000.,300.,%s]" % (2000000)) #~ w.factory("nOffShellMM[100000.,300.,%s]" % (2000000)) convMM = ROOT.RooFFTConvPdf("peakModelMM", "zShapeMM (x) cbShapeMM", w.var("inv"), w.pdf("zShapeMM"), w.pdf("cbShapeMM")) getattr(w, 'import')(convMM, ROOT.RooCmdArg()) w.pdf("peakModelMM").setBufferFraction(5.0) w.factory("zFractionMM[0.9,0,1]") expFractionMM = ROOT.RooFormulaVar('expFractionMM', '1-@0', ROOT.RooArgList(w.var('zFractionMM'))) getattr(w, 'import')(expFractionMM, ROOT.RooCmdArg()) w.factory( "SUM::modelMM1(zFractionMM*peakModelMM,expFractionMM*offShellMM)") w.factory("SUM::modelMM(nZMM*modelMM1)") print "3" fitEE = w.pdf('modelEE').fitTo( w.data('dataHistEE'), #ROOT.RooFit.Save(), ROOT.RooFit.SumW2Error(ROOT.kFALSE), ROOT.RooFit.Minos(2.0)) ROOT.RooFit.Save(), ROOT.RooFit.SumW2Error(ROOT.kFALSE), ROOT.RooFit.Minos(ROOT.kFALSE), ROOT.RooFit.Extended(ROOT.kTRUE)) parametersToSave["nParEE"] = fitEE.floatParsFinal().getSize() print "3.1" fitMM = w.pdf('modelMM').fitTo( w.data('dataHistMM'), #ROOT.RooFit.Save(), ROOT.RooFit.SumW2Error(ROOT.kFALSE), ROOT.RooFit.Minos(2.0)) ROOT.RooFit.Save(), ROOT.RooFit.SumW2Error(ROOT.kFALSE), ROOT.RooFit.Minos(ROOT.kTRUE), ROOT.RooFit.Extended(ROOT.kTRUE)) parametersToSave["nParMM"] = fitMM.floatParsFinal().getSize() print "3.2" w.var("inv").setRange("zPeak", 81, 101) w.var("inv").setRange("fullRange", 20, 500) #~ w.var("inv").setRange("fullRange",20,300) w.var("inv").setRange("lowMass", 20, 70) argSet = ROOT.RooArgSet(w.var("inv")) peakIntEE = w.pdf("modelEE").createIntegral(argSet, ROOT.RooFit.NormSet(argSet), ROOT.RooFit.Range("zPeak")) peakEE = peakIntEE.getVal() lowMassIntEE = w.pdf("modelEE").createIntegral( argSet, ROOT.RooFit.NormSet(argSet), ROOT.RooFit.Range("lowMass")) lowMassEE = lowMassIntEE.getVal() peakIntMM = w.pdf("modelMM").createIntegral(argSet, ROOT.RooFit.NormSet(argSet), ROOT.RooFit.Range("zPeak")) peakMM = peakIntMM.getVal() lowMassIntMM = w.pdf("modelMM").createIntegral( argSet, ROOT.RooFit.NormSet(argSet), ROOT.RooFit.Range("lowMass")) lowMassMM = lowMassIntMM.getVal() log.logHighlighted("Peak: %.3f LowMass: %.3f (ee)" % (peakEE, lowMassEE)) log.logHighlighted("Peak: %.3f LowMass: %.3f (mm)" % (peakMM, lowMassMM)) log.logHighlighted("R(out,in): %.3f (ee) %.3f (mm)" % (lowMassEE / peakEE, lowMassMM / peakMM)) frameEE = w.var('inv').frame( ROOT.RooFit.Title('Invariant mass of ee lepton pairs')) frameEE.GetXaxis().SetTitle('m_{ee} [GeV]') frameEE.GetYaxis().SetTitle("Events / 2.5 GeV") #ROOT.RooAbsData.plotOn(w.data('dataHistEE'), frameEE, ROOT.RooFit.Binning(120)) ROOT.RooAbsData.plotOn(w.data('dataHistEE'), frameEE) w.pdf('modelEE').plotOn(frameEE) sizeCanvas = 800 #~ parametersToSave["chi2EE"] = 1.1*frameEE.chiSquare(int(parametersToSave["nParEE"])) parametersToSave["chi2EE"] = frameEE.chiSquare( int(parametersToSave["nParEE"])) parametersToSave["chi2ProbEE"] = TMath.Prob( parametersToSave["chi2EE"] * (nBinsDY - int(parametersToSave["nParEE"])), nBinsDY - int(parametersToSave["nParEE"])) log.logHighlighted("Floating parameters EE: %f" % parametersToSave["nParEE"]) log.logHighlighted("Chi2 EE: %f" % parametersToSave["chi2EE"]) log.logHighlighted("Chi2 probability EE: %f" % parametersToSave["chi2ProbEE"]) cEE = ROOT.TCanvas("ee distribtution", "ee distribution", sizeCanvas, int(1.25 * sizeCanvas)) cEE.cd() pads = formatAndDrawFrame(w, theConfig, frameEE, title="EE", pdf=w.pdf("modelEE"), yMin=0, yMax=0.05 * yMaximum) dLeg = ROOT.TH1F() dLeg.SetMarkerStyle(ROOT.kFullCircle) dLeg.SetMarkerColor(ROOT.kBlack) dLeg.SetLineWidth(2) fullModelLeg = dLeg.Clone() fullModelLeg.SetLineColor(ROOT.kBlue) expLeg = dLeg.Clone() expLeg.SetLineColor(ROOT.kGreen + 2) peakLeg = dLeg.Clone() peakLeg.SetLineColor(ROOT.kRed) nLegendEntries = 4 leg = tools.myLegend(0.35, 0.89 - 0.07 * nLegendEntries, 0.92, 0.91, borderSize=0) leg.SetTextAlign(22) if (theConfig.useMC): leg.AddEntry(dLeg, 'Simulation', "pe") else: leg.AddEntry(dLeg, 'Data', "pe") leg.AddEntry(fullModelLeg, 'Full Z/#gamma* model', "l") leg.AddEntry(expLeg, 'Exponential component', "l") leg.AddEntry(peakLeg, 'DSCB #otimes BW component', "l") leg.Draw("same") goodnessOfFitEE = '#chi^{2}-prob. = %.3f' % parametersToSave["chi2ProbEE"] annotationsTitle = [ (0.92, 0.47, "%s" % (theConfig.selection.latex)), #~ (0.92, 0.52, "%s" % (theConfig.selection.latex)), (0.92, 0.44, "%s" % goodnessOfFitEE), ] tools.makeCMSAnnotation(0.18, 0.88, lumi, mcOnly=theConfig.useMC, preliminary=theConfig.isPreliminary, year=theConfig.year, ownWork=theConfig.ownWork) tools.makeAnnotations(annotationsTitle, color=tools.myColors['AnnBlue'], textSize=0.04, align=31) tools.storeParameter("expofit", "dyExponent_EE", "expo", w.var('cContinuumEE').getVal(), basePath="dyShelves/" + runRangeName + "/") tools.storeParameter("expofit", "dyExponent_EE", "cbMean", w.var('cbmeanEE').getVal(), basePath="dyShelves/" + runRangeName + "/") tools.storeParameter("expofit", "dyExponent_EE", "nL", w.var('nEEL').getVal(), basePath="dyShelves/" + runRangeName + "/") tools.storeParameter("expofit", "dyExponent_EE", "nR", w.var('nEER').getVal(), basePath="dyShelves/" + runRangeName + "/") tools.storeParameter("expofit", "dyExponent_EE", "alphaL", w.var('alphaEEL').getVal(), basePath="dyShelves/" + runRangeName + "/") tools.storeParameter("expofit", "dyExponent_EE", "alphaR", w.var('alphaEER').getVal(), basePath="dyShelves/" + runRangeName + "/") tools.storeParameter("expofit", "dyExponent_EE", "nZ", w.var('nZEE').getVal(), basePath="dyShelves/" + runRangeName + "/") tools.storeParameter("expofit", "dyExponent_EE", "zFraction", w.var('zFractionEE').getVal(), basePath="dyShelves/" + runRangeName + "/") tools.storeParameter("expofit", "dyExponent_EE", "s", w.var('sEE').getVal(), basePath="dyShelves/" + runRangeName + "/") tools.storeParameter("expofit", "dyExponent_EE", "sErr", w.var('sEE').getError(), basePath="dyShelves/" + runRangeName + "/") tools.storeParameter("expofit", "dyExponent_EE", "chi2", parametersToSave["chi2EE"], basePath="dyShelves/" + runRangeName + "/") tools.storeParameter("expofit", "dyExponent_EE", "chi2Prob", parametersToSave["chi2ProbEE"], basePath="dyShelves/" + runRangeName + "/") eeName = "fig/expoFitEE_%s" % (runRangeName) if theConfig.useMC: eeName = "fig/expoFitEE_%s_MC" % (runRangeName) cEE.Print(eeName + ".pdf") cEE.Print(eeName + ".root") for pad in pads: pad.Close() pads = formatAndDrawFrame(w, theConfig, frameEE, title="EE", pdf=w.pdf("modelEE"), yMin=yMinimum, yMax=yMaximum) leg.Draw("same") tools.makeCMSAnnotation(0.18, 0.88, lumi, mcOnly=theConfig.useMC, preliminary=theConfig.isPreliminary, year=theConfig.year, ownWork=theConfig.ownWork) tools.makeAnnotations(annotationsTitle, color=tools.myColors['AnnBlue'], textSize=0.04, align=31) pads[0].SetLogy(1) eeName = "fig/expoFitEE_Log_%s" % (runRangeName) if theConfig.useMC: eeName = "fig/expoFitEE_Log_%s_MC" % (runRangeName) cEE.Print(eeName + ".pdf") cEE.Print(eeName + ".root") for pad in pads: pad.Close() frameMM = w.var('inv').frame( ROOT.RooFit.Title('Invariant mass of #mu#mu lepton pairs')) frameMM.GetXaxis().SetTitle('m_{#mu#mu} [GeV]') frameMM.GetYaxis().SetTitle("Events / 2.5 GeV") ROOT.RooAbsData.plotOn(w.data("dataHistMM"), frameMM) #ROOT.RooAbsData.plotOn(w.data("dataHistMM"), frameMM, ROOT.RooFit.Binning(120)) w.pdf('modelMM').plotOn(frameMM) sizeCanvas = 800 #~ parametersToSave["chi2MM"] = 1.1*frameMM.chiSquare(int(parametersToSave["nParMM"])) parametersToSave["chi2MM"] = frameMM.chiSquare( int(parametersToSave["nParMM"])) parametersToSave["chi2ProbMM"] = TMath.Prob( parametersToSave["chi2MM"] * (nBinsDY - int(parametersToSave["nParMM"])), nBinsDY - int(parametersToSave["nParMM"])) log.logHighlighted("Chi2 MM: %f" % parametersToSave["chi2MM"]) log.logHighlighted("Chi2 probability MM: %f" % parametersToSave["chi2ProbMM"]) goodnessOfFitMM = '#chi^{2}-prob. = %.3f' % parametersToSave["chi2ProbMM"] annotationsTitle = [ (0.92, 0.47, "%s" % (theConfig.selection.latex)), #~ (0.92, 0.52, "%s" % (theConfig.selection.latex)), (0.92, 0.44, "%s" % goodnessOfFitMM), ] residualMode = "pull" cMM = ROOT.TCanvas("#mu#mu distribtution", "#mu#mu distribution", sizeCanvas, int(1.25 * sizeCanvas)) cMM.cd() pads = formatAndDrawFrame(w, theConfig, frameMM, title="MM", pdf=w.pdf("modelMM"), yMin=0, yMax=0.05 * yMaximum) leg.Draw("same") tools.makeCMSAnnotation(0.18, 0.88, lumi, mcOnly=theConfig.useMC, preliminary=theConfig.isPreliminary, year=theConfig.year, ownWork=theConfig.ownWork) tools.makeAnnotations(annotationsTitle, color=tools.myColors['AnnBlue'], textSize=0.04, align=31) tools.storeParameter("expofit", "dyExponent_MM", "expo", w.var('cContinuumMM').getVal(), basePath="dyShelves/" + runRangeName + "/") tools.storeParameter("expofit", "dyExponent_MM", "cbMean", w.var('cbmeanMM').getVal(), basePath="dyShelves/" + runRangeName + "/") tools.storeParameter("expofit", "dyExponent_MM", "cbMeanErr", w.var('cbmeanMM').getError(), basePath="dyShelves/" + runRangeName + "/") tools.storeParameter("expofit", "dyExponent_MM", "nL", w.var('nMML').getVal(), basePath="dyShelves/" + runRangeName + "/") tools.storeParameter("expofit", "dyExponent_MM", "nR", w.var('nMMR').getVal(), basePath="dyShelves/" + runRangeName + "/") tools.storeParameter("expofit", "dyExponent_MM", "alphaL", w.var('alphaMML').getVal(), basePath="dyShelves/" + runRangeName + "/") tools.storeParameter("expofit", "dyExponent_MM", "alphaR", w.var('alphaMMR').getVal(), basePath="dyShelves/" + runRangeName + "/") tools.storeParameter("expofit", "dyExponent_MM", "nZ", w.var('nZMM').getVal(), basePath="dyShelves/" + runRangeName + "/") tools.storeParameter("expofit", "dyExponent_MM", "zFraction", w.var('zFractionMM').getVal(), basePath="dyShelves/" + runRangeName + "/") tools.storeParameter("expofit", "dyExponent_MM", "s", w.var('sMM').getVal(), basePath="dyShelves/" + runRangeName + "/") tools.storeParameter("expofit", "dyExponent_MM", "sErr", w.var('sMM').getError(), basePath="dyShelves/" + runRangeName + "/") tools.storeParameter("expofit", "dyExponent_MM", "chi2", parametersToSave["chi2MM"], basePath="dyShelves/" + runRangeName + "/") tools.storeParameter("expofit", "dyExponent_MM", "chi2Prob", parametersToSave["chi2ProbMM"], basePath="dyShelves/" + runRangeName + "/") mmName = "fig/expoFitMM_%s" % (runRangeName) if theConfig.useMC: mmName = "fig/expoFitMM_%s_MC" % (runRangeName) cMM.Print(mmName + ".pdf") cMM.Print(mmName + ".root") for pad in pads: pad.Close() pads = formatAndDrawFrame(w, theConfig, frameMM, title="MM", pdf=w.pdf("modelMM"), yMin=yMinimum, yMax=yMaximum) legend = ROOT.TLegend(0.5, 0.6, 0.95, 0.94) legend.SetFillStyle(0) legend.SetBorderSize(0) entryHist = ROOT.TH1F() entryHist.SetFillColor(ROOT.kWhite) legend.AddEntry(entryHist, "Drell-Yan enriched region", "h") dataHist = ROOT.TH1F() entryHist.SetFillColor(ROOT.kWhite) legend.AddEntry(dataHist, "data", "p") fitHist = ROOT.TH1F() fitHist.SetLineColor(ROOT.kBlue) legend.AddEntry(fitHist, "Full Z model", "l") expoHist = ROOT.TH1F() expoHist.SetLineColor(ROOT.kGreen) legend.AddEntry(expoHist, "Exponential component", "l") bwHist = ROOT.TH1F() bwHist.SetLineColor(ROOT.kRed) legend.AddEntry(bwHist, "DSCB #otimes BW component", "l") leg.Draw("same") tools.makeCMSAnnotation(0.18, 0.88, lumi, mcOnly=theConfig.useMC, preliminary=theConfig.isPreliminary, year=theConfig.year, ownWork=theConfig.ownWork) tools.makeAnnotations(annotationsTitle, color=tools.myColors['AnnBlue'], textSize=0.04, align=31) pads[0].SetLogy(1) mmName = "fig/expoFitMM_Log_%s" % (runRangeName) if theConfig.useMC: mmName = "fig/expoFitMM_Log_%s_MC" % (runRangeName) cMM.Print(mmName + ".pdf") cMM.Print(mmName + ".root") for pad in pads: pad.Close() if theConfig.useMC: w.writeToFile("dyWorkspace_MC.root") else: w.writeToFile("dyWorkspace.root") return w