toUncorrelate = [ 'ttcrosscheck', 'zllcrosscheck', 'btagcrosscheckmr', 'btagcrosscheckrsq', 'btaginvcrosscheck', 'vetolepetacrosscheck', 'vetotauetacrosscheck', 'vetolepptcrosscheck', 'vetotauptcrosscheck' ] toUncorrelate += ['stat' + curBox + sample for sample in samples] for sys in toUncorrelate: if 'stat' in sys: if args.noStat: continue suppressLevel = 0.1 else: if args.noSys: continue suppressLevel = 0.0 uncorrelate(backgroundHists, sys, suppressLevel=suppressLevel) #scale factor uncertainties are correlated according to the bin they are in toUncorrelateSF = ['sfstatttjets', 'sfstatwjets', 'sfstatzinv'] cfg = Config.Config(config) for sys in toUncorrelateSF: uncorrelateSFs(backgroundHists, sys, sfHists, cfg, curBox, unrollBins=unrollBins) #call SMS template maker dirToUse = SIGNAL_DIR if args.noPathologies:
def makeSMSTemplates(box, inFile, uncertainties=[], debugLevel=0, tag="Razor2016_MoriondRereco", opts=None, boostCuts=True, doUncorrelate=True): """Returns a dictionary of histograms representing predicted yields for the indicated signal sample. 'opts' should be an SMSOpts instance containing desired values for configurable parameters.""" print '\nInput file is %s' % inFile uncerts = copy.copy(uncertainties) # process configuration options if opts is None: opts = SMSOpts() xBR = opts.xBR yBR = opts.yBR doMCStat = True if opts.doNPVExtrap: uncerts.append('npvextrap') doMCStat = False if opts.doGenMetVsPFMet: uncerts.append('genmetvspfmet') # get mass point information model, m1, m2 = getModelInfoFromFilename(inFile, xBR, yBR) isGluinos = ("T1" in model or "T5" in model) if isGluinos: thyXsec, _ = getTheoryCrossSectionAndError( mGluino=m1) else: thyXsec, _ = getTheoryCrossSectionAndError( mStop=m1) print "\n--- %s %s %s ---\n"%(model, m1, m2) print "Theory cross section: %.3f pb"%thyXsec minBtags = 0 maxBtags = getMaxBtags(box) # special case: 1L control regions if box == "TTJetsSingleLeptonForSignal": minBtags = maxBtags = 1 elif box == "WJetsSingleLeptonForSignal": minBtags = maxBtags = 0 hists = [] unrollBins = [] for nb in range(minBtags, maxBtags+1): # get analysis info nbMax = nb if nb == maxBtags: nbMax = -1 # special case: 1L control regions if box == "WJetsSingleLeptonForSignal": nbMax = 0 analysis = Analysis(box, tag, nbMin=nb, nbMax=nbMax, boostCuts=boostCuts) unrollBins.append(analysis.unrollBins) # modify for signal sample analysis.filenames = { 'Signal':inFile } analysis.samples = ['Signal'] analysis.samplesReduced = analysis.samples # scale according to cross section f = rt.TFile.Open(inFile) nEvents = f.Get('NEvents').Integral() globalScaleFactor = thyXsec/nEvents nisrFactor = getGlobalNISRScaleFactor(f) globalScaleFactor *= nisrFactor print "Number of events: %d"%nEvents print "Integrated luminosity: %d /pb"%analysis.lumi print "Overall NISR scale factor: {}".format(nisrFactor) print "Overall scale factor: %.3f"%( analysis.lumi * globalScaleFactor) # fill the histograms hists.append(makeControlSampleHistsForAnalysis(analysis, treeName="RazorInclusive", shapeErrors=uncerts, boxName=box, btags=nb, makePlots=False, exportShapeErrs=True, propagateScaleFactorErrs=False, lumiMC=1./globalScaleFactor, debugLevel=debugLevel)) makeRazor2DTable(pred=None, boxName='{}-{}-{}-{}-'.format(box, model, m1, m2), mcNames=['{} {} {}'.format(model, m1, m2)], mcHists=[hists[-1]['Signal'][('MR','Rsq')]], btags=nb, unrollBins=unrollBins[-1], listAllMC=True) signalHists = unrollAndStitch(hists, box, samples=analysis.samples, debugLevel=debugLevel, unrollBins=unrollBins, addStatUnc=doMCStat) # apply pileup weight extrapolation procedure if 'Signal_npvextrapUp' in signalHists: npvLowHighHist = getNPVLowHighHist(analysis) npvHist = getNPVHist(tag) doNPVExtrapolation(signalHists, npvHist, npvLowHighHist, scale=analysis.lumi*globalScaleFactor) # need this extrapolation to be uncorrelated across bins & boxes for sysName in ['Signal_npvextrapUp', 'Signal_npvextrapDown']: signalHists[sysName.replace( 'npvextrap','npvextrap'+box)] = signalHists[sysName] del signalHists[sysName] if doUncorrelate: uncorrelate(signalHists, 'npvextrap'+box, suppressLevel=0.1) # apply gen-MET vs PF MET systematic if 'Signal_genmetvspfmetUp' in signalHists: doGenMetVsPFMetSystematic(signalHists) return signalHists
backgroundHists = unrollAndStitch(curBox, samples=samples, inDir=BACKGROUND_DIR, outDir=outDir, unrollBins=unrollBins, noSys=args.noSys, addStatUnc=(not args.noStat), addMCVsFit=args.addMCVsFit, debugLevel=debugLevel, signalContaminationHists=contamHistsToUse, sfHistsForSignalContamination=sfHists) if args.noCombine: continue #if not setting a limit, we are done #treat appropriate uncertainties as uncorrelated bin to bin toUncorrelate = ['ttcrosscheck','zllcrosscheck','btagcrosscheckmr','btagcrosscheckrsq','btaginvcrosscheck','vetolepetacrosscheck','vetotauetacrosscheck','vetolepptcrosscheck','vetotauptcrosscheck'] toUncorrelate += ['stat'+curBox+sample for sample in samples] for sys in toUncorrelate: if 'stat' in sys: if args.noStat: continue suppressLevel = 0.1 else: if args.noSys: continue suppressLevel = 0.0 uncorrelate(backgroundHists, sys, suppressLevel=suppressLevel) #scale factor uncertainties are correlated according to the bin they are in toUncorrelateSF = ['sfstatttjets','sfstatwjets','sfstatzinv'] cfg = Config.Config(config) for sys in toUncorrelateSF: uncorrelateSFs(backgroundHists, sys, sfHists, cfg, curBox, unrollBins=unrollBins) #call SMS template maker dirToUse = SIGNAL_DIR if args.noPathologies: dirToUse = NOPATHOLOGIES_SIGNAL_DIR elif args.noPileupWeights: dirToUse = NOPILEUPWEIGHTS_SIGNAL_DIR if 'T1' in args.model or 'T5' in args.model: modelName = 'SMS-'+args.model+'_'+str(args.mGluino)+'_'+str(args.mLSP)
# for bx in range(1,ds[0].GetNbinsX()+1): # if pdfEnvelopeDown.GetBinContent(bx) < 0: # pdfEnvelopeDown.SetBinContent(bx,0) # #normalize # pdfEnvelopeUp.Scale(ds[0].Integral()*1.0/pdfEnvelopeUp.Integral()) # pdfEnvelopeDown.Scale(ds[0].Integral()*1.0/pdfEnvelopeDown.Integral()) # #append # ds.append(pdfEnvelopeUp) # ds.append(pdfEnvelopeDown) #convert dataset list to dict for d in ds: dsDict[d.GetName()] = d #perform uncorrelation procedure (for MC stat and pdf uncertainty) if 'pdf%s'%box.lower() in shapes: uncorrelate(dsDict, 'pdf%s'%box.lower()) # remove empty bins for bx in range(1,ds[0].GetNbinsX()+1): if ds[0].GetBinContent(bx) == 0 or ds[0].GetBinError(bx) == 0: print 'Removing empty PDF uncertainty bin %i'%(bx) del dsDict['%s_pdf%s%iUp'%(ds[0].GetName(),box.lower(),bx)] del dsDict['%s_pdf%s%iDown'%(ds[0].GetName(),box.lower(),bx)] if 'mcstat%s'%box.lower() in shapes: uncorrelate(dsDict, 'mcstat%s'%box.lower()) # for now: don't remove unncessary MC stat bins # remove unnecessary MC stat bins (relative uncertainty < 10%) see htt recommendation # https://indico.cern.ch/event/373752/session/6/contribution/14/attachments/744534/1021298/bbb-HCG.pdf #for bx in range(1,ds[0].GetNbinsX()+1): # if ds[0].GetBinContent(bx) == 0 or ds[0].GetBinError(bx) == 0: # print 'Relative MC stat uncertainty bin %i = %.1f%% is less than 10%%'%(bx,0.) # print 'Removing histogram: %s_mcstat%s%iUp'%(ds[0].GetName(),box.lower(),bx)
'sfstatttjetsNJetsTTJets', 'sfstatwjetsNJetsWJets', 'sfstatzinvNJetsInv'] for unc in jet_closure_uncs: hists = addHistSuffix(hists, unc, jets) # treat appropriate uncertainties as uncorrelated bin to bin toUncorrelate = ['stat'+curBox+sample for sample in samples if sample != 'QCD'] for sys in toUncorrelate: if 'stat' in sys: if args.noStat: continue suppressLevel = 0.1 else: if args.noSys: continue suppressLevel = 0.0 uncorrelate(hists, sys, suppressLevel=suppressLevel) # scale factor uncertainties are correlated according to # the bin they are in toUncorrelateSF = ['sfstatttjets','sfstatwjets','sfstatzinv'] for sys in toUncorrelateSF: uncorrelateSFs(hists, sys, sfHists, cfg, curBox, unrollBins=unrollBins) toUncorrelateSF1D = ['btaginvcrosscheck', 'btagcrosscheckrsq'] for sys in toUncorrelateSF1D: uncorrelateSFs1D(hists, sys, sfHistsForUncorrSFs1D, unrollBins) toUncorrelateSF1DMR = ['sfstatttjetsMR', 'sfstatwjetsMR', 'sfstatzinvMRInv'] for sys in toUncorrelateSF1DMR: uncorrelateSFs1D(hists, sys, sfHistsForUncorrSFs1DMR, unrollBins, useRsq=False)
# if pdfEnvelopeDown.GetBinContent(bx) < 0: # pdfEnvelopeDown.SetBinContent(bx,0) # #normalize # pdfEnvelopeUp.Scale(ds[0].Integral()*1.0/pdfEnvelopeUp.Integral()) # pdfEnvelopeDown.Scale(ds[0].Integral()*1.0/pdfEnvelopeDown.Integral()) # #append # ds.append(pdfEnvelopeUp) # ds.append(pdfEnvelopeDown) #convert dataset list to dict for d in ds: dsDict[d.GetName()] = d #perform uncorrelation procedure (for MC stat and pdf uncertainty) if 'pdf%s' % box.lower() in shapes: uncorrelate(dsDict, 'pdf%s' % box.lower()) # remove empty bins for bx in range(1, ds[0].GetNbinsX() + 1): if ds[0].GetBinContent(bx) == 0 or ds[0].GetBinError( bx) == 0: print 'Removing empty PDF uncertainty bin %i' % (bx) del dsDict['%s_pdf%s%iUp' % (ds[0].GetName(), box.lower(), bx)] del dsDict['%s_pdf%s%iDown' % (ds[0].GetName(), box.lower(), bx)] if 'mcstat%s' % box.lower() in shapes: uncorrelate(dsDict, 'mcstat%s' % box.lower()) # for now: don't remove unncessary MC stat bins # remove unnecessary MC stat bins (relative uncertainty < 10%) see htt recommendation # https://indico.cern.ch/event/373752/session/6/contribution/14/attachments/744534/1021298/bbb-HCG.pdf #for bx in range(1,ds[0].GetNbinsX()+1):