def getErrorGraphs(self): numErrorGraphs = 0 totalConstantUncertainty = 0 errorGraphs = [] for iError, error in enumerate(self.errors): if (error.size != None): if (error.add): log.logInfo( "Quadractically adding error '%s' with size %f" % (error.name, error.size)) totalConstantUncertainty = (totalConstantUncertainty**2 + error.size**2)**0.5 #~ xCenter = 0.5 * (error.xMin + error.xMax) #~ xWidth = 0.5 * (error.xMax - error.xMin) #~ graph = ROOT.TGraphErrors(1, array("d", [xCenter]), array("d", [1.0]), array("d", [xWidth]), array("d", [error.size])) #~ graph.SetFillColor(error.color) #~ errorGraphsToAdd.Add(graph) else: log.logInfo("Adding error '%s' with size %f" % (error.name, error.size)) xCenter = 0.5 * (error.xMin + error.xMax) xWidth = 0.5 * (error.xMax - error.xMin) graph = ROOT.TGraphErrors(1, array("d", [xCenter]), array("d", [1.0]), array("d", [xWidth]), array("d", [error.size])) graph.SetFillColor(error.color) graph.SetFillStyle(error.fillStyle) errorGraphs.append(graph) elif (error.hasHistograms): log.logInfo("Adding error '%s' given as histograms" % (error.name)) errorsUp = error.errorsUp errorsDown = error.errorsDown xs = [] ys = [] widths = [] upErrors = [] downErrors = [] for (errorUp, errorDown) in zip(errorsUp, errorsDown): if (errorUp.ratio >= 0.0 and errorDown.ratio >= 0.0): xs.append(errorUp.xCenter) ys.append(1.0) widths.append(errorUp.errorX) if (errorUp.ratio > 1.0): if (errorDown.ratio > 1.0): upErrors.append( max(errorUp.ratio - 1.0, errorDown.ratio - 1.0)) downErrors.append(0.0) else: upErrors.append(errorUp.ratio - 1.0) downErrors.append(1.0 - errorDown.ratio) else: if (errorDown.ratio > 1.0): upErrors.append(errorDown.ratio - 1.0) downErrors.append(1.0 - errorUp.ratio) else: upErrors.append(0.0) downErrors.append( max(1.0 - errorUp.ratio, 1.0 - errorDown.ratio)) #~ if (iError + 1 < len(self.errors) and self.errors[iError + 1].add): if (iError - 1 is not -1): #~ print iError #~ if (self.errors[iError + 1].size != None): log.logHighlighted( "Found uncertainty to be added. Will do so, now.") #~ size = self.errors[iError -1].size #~ upErrors = [math.sqrt(prev ** 2 + errorGraphs[numErrorGraphs-1].GetErrorYhigh(index) ** 2 + totalConstantUncertainty**2) for index, prev in enumerate(upErrors)] #~ downErrors = [math.sqrt(prev ** 2 + errorGraphs[numErrorGraphs-1].GetErrorYlow(index) ** 2 + totalConstantUncertainty**2) for index, prev in enumerate(downErrors)] upErrors = [ math.sqrt(prev**2 + errorGraphs[numErrorGraphs - 1].GetErrorYhigh(index)**2 + totalConstantUncertainty**2) for index, prev in enumerate(upErrors) ] downErrors = [ math.sqrt(prev**2 + errorGraphs[numErrorGraphs - 1].GetErrorYlow(index)**2 + totalConstantUncertainty**2) for index, prev in enumerate(downErrors) ] #~ else: #~ log.logError("Uncertainty to be added does not have fixed size. Adding not implemented, yet.") graph = ROOT.TGraphAsymmErrors(len(xs), array("d", xs), array("d", ys), array("d", widths), array("d", widths), array("d", downErrors), array("d", upErrors)) graph.SetFillColor(error.color) graph.SetFillStyle(error.fillStyle) errorGraphs.append(graph) #~ print downErrors #~ print upErrors numErrorGraphs = numErrorGraphs + 1 #~ num = errorGraphs[-1].Merge(errorGraphsToAdd) #~ print num return errorGraphs
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
def addResult(self, result): if (self.histogram == None): log.logWarning("Adding to empty result!") if (result.histogram == None): log.logWarning("... also adding empty result!") return result if (result.histogram == None): log.logWarning("Adding empty result!") return self if (not self.scaled == result.scaled): log.logError("Cannot add scaled and unscaled results") return None if (self.dataType != result.dataType): log.logError("Cannot add results of different data types (%d, %d)" % (self.dataType, results.dataType)) return None # lumi info if (self.luminosity > 0 and result.luminosity > 0): if (self.dataType == InfoHolder.DataTypes.Data): self.luminosity += result.luminosity # for data else: pass # for MC and Unknown else: log.logWarning("Adding results without complete luminosity information (%f, %f)" % (self.luminosity, result.luminosity)) self.luminosity = -1 # xSection info if (self.xSection > 0 and result.xSection > 0): self.xSection += result.xSection else: if (self.dataType != InfoHolder.DataTypes.Data): log.logWarning("Adding results without complete xSection information (%f, %f)" % (self.xSection, result.xSection)) self.xSection = -1 # xSection info if (self.kFactor > 0 and result.kFactor > 0): if (self.kFactor != result.kFactor): log.logHighlighted("Adding results with different kFactors (%f, %f). Will not be able to track this any more." % (self.kFactor, result.kFactor)) self.kFactor = -1 else: log.logInfo("Adding results without complete kFactor information (%f, %f)" % (self.kFactor, result.kFactor)) self.kFactor = -1 if (not self.scaled): self.histogram.Add(result.histogram) return self if (self.scalingFactor == result.scalingFactor): self.unscaledIntegral += result.unscaledIntegral self.histogram.Add(result.histogram) return self log.logDebug("Combining results: %s, %s" % (str(self), str(result))) # first calculate new error self.currentIntegralError = sqrt(self.integralError() * self.integralError() + result.integralError() * result.integralError()) # then change histogram self.histogram.Add(result.histogram) self.unscaledIntegral += result.unscaledIntegral self.scalingFactor = -1 # finally mark result as scaled and added self.__scaledAndAdded = True log.logDebug("... to: %s" % (str(self))) return self
def main(): parser = argparse.ArgumentParser( description='Trigger efficiency measurements.') 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( "-n", "--new", action="store_true", dest="new", default=False, help="new approach, using single lepton for dependencies.") parser.add_argument("-s", "--selection", dest="selection", action="append", default=[], help="selection which to apply.") parser.add_argument("-p", "--plot", dest="plots", action="append", default=[], help="select dependencies to study, default is all.") parser.add_argument("-r", "--runRange", dest="runRange", action="append", default=[], help="name of run range.") parser.add_argument("-c", "--centralValues", action="store_true", dest="central", default=False, help="calculate effinciecy central values") parser.add_argument("-b", "--backgrounds", dest="backgrounds", action="append", default=[], help="backgrounds to plot.") parser.add_argument("-d", "--dependencies", action="store_true", dest="dependencies", default=False, help="make dependency plots") 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 len(args.backgrounds) == 0: args.backgrounds = backgroundLists.trigger if len(args.plots) == 0: args.plots = plotLists.trigger if len(args.selection) == 0: args.selection.append(regionsToUse.triggerEfficiencies.central.name) args.selection.append(regionsToUse.triggerEfficiencies.forward.name) args.selection.append(regionsToUse.triggerEfficiencies.inclusive.name) if len(args.runRange) == 0: args.runRange.append(runRanges.name) path = locations.triggerDataSetPath if args.mc: path = locations.dataSetPath source = baselineTrigger.name log.logHighlighted( "Calculating trigger efficiencies on %s triggered dataset" % source) log.logHighlighted("Using trees from %s " % path) cmsExtra = "" if args.private: cmsExtra = "Private Work" if args.mc: cmsExtra = "#splitline{Private Work}{Simulation}" elif args.mc: cmsExtra = "Simulation" else: cmsExtra = "Preliminary" for runRangeName in args.runRange: runRange = getRunRange(runRangeName) for selectionName in args.selection: selection = getRegion(selectionName) if args.central: centralVal = centralValues(source, path, selection, runRange, args.mc, args.backgrounds) if args.mc: outFilePkl = open( "shelves/triggerEff_%s_%s_%s_MC.pkl" % (selection.name, source, runRange.label), "w") else: outFilePkl = open( "shelves/triggerEff_%s_%s_%s.pkl" % (selection.name, source, runRange.label), "w") pickle.dump(centralVal, outFilePkl) outFilePkl.close() if args.dependencies: dependencies(source, path, selection, args.plots, runRange, args.mc, args.backgrounds, cmsExtra) if args.write: import subprocess if args.mc: bashCommand = "cp shelves/triggerEff_%s_%s_%s_MC.pkl %s/shelves" % ( selection.name, source, runRange.label, pathes.basePath) else: bashCommand = "cp shelves/triggerEff_%s_%s_%s.pkl %s/shelves" % ( selection.name, source, runRange.label, pathes.basePath) process = subprocess.Popen(bashCommand.split())
def getErrorGraphs(self): numErrorGraphs=0 totalConstantUncertainty = 0 errorGraphs = [] for iError, error in enumerate(self.errors): if (error.size != None): if (error.add): log.logInfo("Quadractically adding error '%s' with size %f" % (error.name, error.size)) totalConstantUncertainty = (totalConstantUncertainty**2+error.size**2)**0.5 #~ xCenter = 0.5 * (error.xMin + error.xMax) #~ xWidth = 0.5 * (error.xMax - error.xMin) #~ graph = ROOT.TGraphErrors(1, array("d", [xCenter]), array("d", [1.0]), array("d", [xWidth]), array("d", [error.size])) #~ graph.SetFillColor(error.color) #~ errorGraphsToAdd.Add(graph) else: log.logInfo("Adding error '%s' with size %f" % (error.name, error.size)) xCenter = 0.5 * (error.xMin + error.xMax) xWidth = 0.5 * (error.xMax - error.xMin) graph = ROOT.TGraphErrors(1, array("d", [xCenter]), array("d", [1.0]), array("d", [xWidth]), array("d", [error.size])) graph.SetFillColor(error.color) graph.SetFillStyle(error.fillStyle) errorGraphs.append(graph) elif (error.hasHistograms): log.logInfo("Adding error '%s' given as histograms" % (error.name)) errorsUp = error.errorsUp errorsDown = error.errorsDown xs = [] ys = [] widths = [] upErrors = [] downErrors = [] for (errorUp, errorDown) in zip(errorsUp, errorsDown): if (errorUp.ratio >= 0.0 and errorDown.ratio >= 0.0): xs.append(errorUp.xCenter) ys.append(1.0) widths.append(errorUp.errorX) if (errorUp.ratio > 1.0): if (errorDown.ratio > 1.0): upErrors.append(max(errorUp.ratio - 1.0, errorDown.ratio - 1.0)) downErrors.append(0.0) else: upErrors.append(errorUp.ratio - 1.0) downErrors.append(1.0 - errorDown.ratio) else: if (errorDown.ratio > 1.0): upErrors.append(errorDown.ratio - 1.0) downErrors.append(1.0 - errorUp.ratio) else: upErrors.append(0.0) downErrors.append(max(1.0 - errorUp.ratio, 1.0 - errorDown.ratio)) #~ if (iError + 1 < len(self.errors) and self.errors[iError + 1].add): if (iError -1 is not -1 ): #~ print iError #~ if (self.errors[iError + 1].size != None): log.logHighlighted("Found uncertainty to be added. Will do so, now.") #~ size = self.errors[iError -1].size #~ upErrors = [math.sqrt(prev ** 2 + errorGraphs[numErrorGraphs-1].GetErrorYhigh(index) ** 2 + totalConstantUncertainty**2) for index, prev in enumerate(upErrors)] #~ downErrors = [math.sqrt(prev ** 2 + errorGraphs[numErrorGraphs-1].GetErrorYlow(index) ** 2 + totalConstantUncertainty**2) for index, prev in enumerate(downErrors)] upErrors = [math.sqrt(prev ** 2 + errorGraphs[numErrorGraphs-1].GetErrorYhigh(index) ** 2 + totalConstantUncertainty**2) for index, prev in enumerate(upErrors)] downErrors = [math.sqrt(prev ** 2 + errorGraphs[numErrorGraphs-1].GetErrorYlow(index) ** 2 + totalConstantUncertainty**2) for index, prev in enumerate(downErrors)] #~ else: #~ log.logError("Uncertainty to be added does not have fixed size. Adding not implemented, yet.") graph = ROOT.TGraphAsymmErrors(len(xs), array("d", xs), array("d", ys), array("d", widths), array("d", widths), array("d", downErrors), array("d", upErrors)) graph.SetFillColor(error.color) graph.SetFillStyle(error.fillStyle) errorGraphs.append(graph) #~ print downErrors #~ print upErrors numErrorGraphs = numErrorGraphs+1 #~ num = errorGraphs[-1].Merge(errorGraphsToAdd) #~ print num return errorGraphs