def checkSignalContamination(config, outDir, lumi, box, model, mLSP, mGluino=-1, mStop=-1, mergeBins=False, treeName="RazorInclusive"): cfg = Config.Config(config) x = array('d', cfg.getBinning(box)[0]) # MR binning y = array('d', cfg.getBinning(box)[1]) # Rsq binning z = array('d', cfg.getBinning(box)[2]) # nBtag binning unrollBins = None if mergeBins: btagBins = cfg.getBinning(box)[2][:-1] unrollBins = [(xbinsSignal[box][str(int(btags))+'B'], colsSignal[box][str(int(btags))+'B']) for btags in btagBins] mergeBinsString = '' if mergeBins: mergeBinsString = '--merge-bins' brString = "" if 'T1x' in model: xBR = float(model[model.find('x')+1:model.find('y')].replace('p','.')) yBR = float(model[model.find('y')+1:].replace('p','.')) brString = '--xBR %.2f --yBR %.2f'%(xBR,yBR) modelName = 'SMS-%s_%i_%i'%(model,mGluino,mLSP) fileName = SIGNAL_DIR+'/SMS-T1ttbb_%i_%i.root'%(mGluino,mLSP) elif 'T2' in model: modelName = 'SMS-%s_%i_%i'%(model,mStop,mLSP) fileName = SIGNAL_DIR+'/%s.root'%(modelName) else: modelName = 'SMS-%s_%i_%i'%(model,mGluino,mLSP) fileName = SIGNAL_DIR+'/%s.root'%(modelName) os.system('python python/SMSTemplates.py %s -c %s -d %s/ --lumi %s --box %s --no-signal-sys %s %s'%(mergeBinsString,config,outDir,lumi,box,brString,fileName)) signalFile = rt.TFile.Open('%s/%s_lumi-%.3f_%i-%ibtag_%s.root'%(outDir,modelName,lumi*1./1000.,z[0],z[-1]-1,box)) sigTH1 = signalFile.Get('%s_%s'%(box,model)) bkgdHistDict = importHists('%s/controlHistograms%s.root'%(BACKGROUND_DIR,box.replace('ControlRegion','').replace('WJet','WJetsSingleLepton'))) tempTH2 = bkgdHistDict['Data'][('MR','Rsq')] #unroll into TH1F if unrollBins is None: nBins = (len(x)-1)*(len(y)-1) maxBins = nBins myTH1 = rt.TH1F(treeName,treeName,maxBins,0,maxBins) myTH1.SetDirectory(0) #prevent it from going out of scope myTH1.Sumw2() i = 0 for ix in range(1,len(x)): for iy in range(1,len(y)): i += 1 myTH1.SetBinContent(i,tempTH2.GetBinContent(ix,iy)) myTH1.SetBinError(i,tempTH2.GetBinError(ix,iy)) else: print "Merging bins according to custom (MR-dependent) binning" layers = [] #turn it into a TH2Poly with the reduced binning unrollRows = unrollBins[0][0] unrollCols = unrollBins[0][1] poly = makeTH2PolyFromColumns(tempTH2.GetName()+"poly", 'poly', unrollRows, unrollCols) fillTH2PolyFromTH2(tempTH2, poly) numbins = poly.GetNumberOfBins() unrolledSlice = rt.TH1D(tempTH2.GetName()+"Unroll", "slice", numbins, 0, numbins) for bn in range(1, numbins+1): unrolledSlice.SetBinContent(bn, poly.GetBinContent(bn)) unrolledSlice.SetBinError(bn, poly.GetBinError(bn)) layers.append(unrolledSlice) poly.Delete() myTH1 = stitch(layers) myTH1.SetName(treeName) myTH1.SetTitle(treeName) sigTH1.Sumw2() myTH1.Sumw2() sigTH1.Divide(myTH1) return sigTH1
### INPUT: ROOT file produced by RazorAnalyzer python macro code import sys import argparse import ROOT as rt from macro import macro, plotting parser = argparse.ArgumentParser() parser.add_argument("fname", help="input ROOT file name") parser.add_argument("--all", action='store_true', dest="print_all", help="Print all MC histograms") args = parser.parse_args() hists = macro.importHists(args.fname) var = ('MR', 'Rsq') tmp = plotting.unroll2DHistograms([hists[hists.iterkeys().next()][var]])[0] tot = tmp.Clone("tot") tot.Reset() sys_dict = {} qcdHist = None for proc in hists: if proc == 'Sys': for sys_proc in hists[proc]: if sys_proc == 'Data': continue for sys in hists[proc][sys_proc]: if sys not in sys_dict: tmp = plotting.unroll2DHistograms([hists['Data'][var]])[0] sys_dict[sys] = tmp.Clone(sys)
1:args.model.find('y')].replace('p', '.')) yBR = float(args.model[args.model.find('y') + 1:].replace( 'p', '.')) brString = '--xBR %.2f --yBR %.2f' % (xBR, yBR) signalFilename = dirToUse + '/SMS-T1ttbb_' + str( args.mGluino) + '_' + str(args.mLSP) + '.root' exec_me( 'python python/SMSTemplates.py --merge-bins -c %s -d %s --lumi %d --box %s %s %s %s --max-events %d' % (config, outDir, LUMI, curBox, ((args.noSys) * ('--no-signal-sys')), signalFilename, brString, args.maxSignalEvents), False) #load SMS template histograms signalHistFilename = '%s/%s_lumi-%.3f_0-3btag_%s.root' % ( outDir, modelName, LUMI * 1.0 / 1000, curBox) signalHists = macro.importHists(signalHistFilename) #update with correct names for x, h in signalHists.items(): h.SetName(h.GetName().replace(curBox + '_' + args.model, modelName)) signalHists[h.GetName()] = signalHists.pop(x) #apply reduced efficiency method to correct for the presence of signal in the control regions if args.reducedEff: macro.doDeltaBForReducedEfficiencyMethod(backgroundHists, signalHists, contamHists, sfHists, unrollBins=unrollBins, debugLevel=debugLevel)
else: modelName = 'SMS-'+args.model+'_'+str(args.mStop)+'_'+str(args.mLSP) signalFilename=dirToUse+'/'+modelName+'.root' #to modify branching ratios in T1ttbb sample brString = "" if 'T1x' in args.model: xBR = float(args.model[args.model.find('x')+1:args.model.find('y')].replace('p','.')) yBR = float(args.model[args.model.find('y')+1:].replace('p','.')) brString = '--xBR %.2f --yBR %.2f'%(xBR,yBR) signalFilename = dirToUse+'/SMS-T1ttbb_'+str(args.mGluino)+'_'+str(args.mLSP)+'.root' exec_me('python python/SMSTemplates.py --merge-bins -c %s -d %s --lumi %d --box %s %s %s %s --max-events %d'%(config, outDir, LUMI, curBox, ((args.noSys)*('--no-signal-sys')), signalFilename, brString, args.maxSignalEvents), False) #load SMS template histograms signalHistFilename = '%s/%s_lumi-%.3f_0-3btag_%s.root'%(outDir,modelName,LUMI*1.0/1000,curBox) signalHists = macro.importHists(signalHistFilename) #update with correct names for x,h in signalHists.items(): h.SetName(h.GetName().replace(curBox+'_'+args.model,modelName)) signalHists[h.GetName()] = signalHists.pop(x) #apply reduced efficiency method to correct for the presence of signal in the control regions if args.reducedEff: macro.doDeltaBForReducedEfficiencyMethod(backgroundHists, signalHists, contamHists, sfHists, unrollBins=unrollBins, debugLevel=debugLevel) #combine signal and background dictionaries hists = backgroundHists.copy() hists.update(signalHists) #write histograms to ROOT file outFileName = outDir+'/RazorInclusiveMADD_lumi-%.1f_%s.root'%(LUMI*1.0/1000.,curBox)
for nb in btags: if box == 'DiJet' and nb == 3: continue hist_dir = 'Plots/{}/{}{}BFineGrainedSuper/'.format( tag, box, nb) hist_file = 'razorHistograms{}{}BFineGrainedSuper.root'.format( box, nb) super_fname = hist_dir + hist_file standard_fname = super_fname.replace('Super', '') # Create a backup of the histogram file old_super_fname = super_fname.replace('.root', '_BKP.root') sp.call(['cp', super_fname, old_super_fname]) # Get both super and non-super region histograms super_hists = macro.importHists(super_fname) standard_hists = macro.importHists(standard_fname) # First do the nominal QCD histogram var = ('MR', 'Rsq') proc = 'QCD' fix_super_hist( super_hists[proc][var], standard_hists[proc][var]) # Then do all systematic histograms for syst in super_hists['Sys'][proc]: fix_super_hist( super_hists['Sys'][proc][syst][var], standard_hists['Sys'][proc][syst][var]) # Output file
import sys import argparse import ROOT as rt from ast import literal_eval from macro import macro parser = argparse.ArgumentParser() parser.add_argument("fname",help="input ROOT file name") parser.add_argument("varname", help="variable to print") parser.add_argument("--all", dest="print_all", action='store_true', help="Print individual MC histograms") parser.add_argument("--debug", action="store_true", help="print debug info") args = parser.parse_args() hists = macro.importHists(args.fname, debugLevel=args.debug) # parse variable name if tuple try: parsed_var = literal_eval(args.varname) except ValueError: parsed_var = args.varname tot = hists["Data"][parsed_var].Clone("tot") tot.Reset() for proc in hists: if args.print_all or proc == "Data": print proc hists[proc][parsed_var].Print("all") else: tot.Add(hists[proc][parsed_var]) print "Total MC"
import argparse import ROOT as rt from ast import literal_eval from macro import macro parser = argparse.ArgumentParser() parser.add_argument("fname", help="input ROOT file name") parser.add_argument("varname", help="variable to print") parser.add_argument("--all", dest="print_all", action='store_true', help="Print individual MC histograms") parser.add_argument("--debug", action="store_true", help="print debug info") args = parser.parse_args() hists = macro.importHists(args.fname, debugLevel=args.debug) # parse variable name if tuple try: parsed_var = literal_eval(args.varname) except ValueError: parsed_var = args.varname tot = hists["Data"][parsed_var].Clone("tot") tot.Reset() for proc in hists: if args.print_all or proc == "Data": print proc hists[proc][parsed_var].Print("all") else: tot.Add(hists[proc][parsed_var]) print "Total MC"
def checkSignalContamination(config, outDir, lumi, box, model, mLSP, mGluino=-1, mStop=-1, mergeBins=False, debugLevel=0, treeName="RazorInclusive", tag='Razor2016_MoriondRereco'): cfg = Config.Config(config) x = array('d', cfg.getBinning(box)[0]) # MR binning y = array('d', cfg.getBinning(box)[1]) # Rsq binning z = array('d', cfg.getBinning(box)[2]) # nBtag binning dirToUse = razorSignalDirs[tag] unrollBins = [] analyses = [] if mergeBins: btagBins = cfg.getBinning(box)[2][:-1] for btags in btagBins: analyses.append(Analysis(box, tag, nbMin=btags)) unrollBins.append(analyses[-1].unrollBins) xBR = yBR = -1 if 'T1x' in model: xBR, yBR = getBranchingFracsFromModelName(model) fileName = dirToUse + '/SMS-T1ttbb_%i_%i.root' % (mGluino, mLSP) elif 'T2' in model: modelName = getModelName(model, mStop, mLSP) fileName = dirToUse + '/%s.root' % (modelName) else: modelName = getModelName(model, mGluino, mLSP) fileName = dirToUse + '/%s.root' % (modelName) smsOpts = SMSOpts(xBR=xBR, yBR=yBR, doNPVExtrap=False, doGenMetVsPFMet=False) sigTH1 = makeSMSTemplates(box, fileName, opts=smsOpts, debugLevel=debugLevel, tag=tag)['Signal'] bkgdHistDict = importHists('%s/controlHistograms%s.root' % (BACKGROUND_DIR, box)) tempTH2 = bkgdHistDict['Data'][('MR', 'Rsq')] #unroll into TH1F if unrollBins is None: nBins = (len(x) - 1) * (len(y) - 1) maxBins = nBins myTH1 = rt.TH1F(treeName, treeName, maxBins, 0, maxBins) myTH1.SetDirectory(0) #prevent it from going out of scope myTH1.Sumw2() i = 0 for ix in range(1, len(x)): for iy in range(1, len(y)): i += 1 myTH1.SetBinContent(i, tempTH2.GetBinContent(ix, iy)) myTH1.SetBinError(i, tempTH2.GetBinError(ix, iy)) else: print "Merging bins according to custom (MR-dependent) binning" layers = [] #turn it into a TH2Poly with the reduced binning unrollRows = unrollBins[0][0] unrollCols = unrollBins[0][1] poly = makeTH2PolyFromColumns(tempTH2.GetName() + "poly", 'poly', unrollRows, unrollCols) fillTH2PolyFromTH2(tempTH2, poly) numbins = poly.GetNumberOfBins() unrolledSlice = rt.TH1D(tempTH2.GetName() + "Unroll", "slice", numbins, 0, numbins) for bn in range(1, numbins + 1): unrolledSlice.SetBinContent(bn, poly.GetBinContent(bn)) unrolledSlice.SetBinError(bn, poly.GetBinError(bn)) layers.append(unrolledSlice) poly.Delete() myTH1 = stitch(layers) myTH1.SetName(treeName) myTH1.SetTitle(treeName) sigTH1.Sumw2() myTH1.Sumw2() sigTH1.Divide(myTH1) return sigTH1
def checkSignalContamination(config, outDir, lumi, box, model, mLSP, mGluino=-1, mStop=-1, mergeBins=False, treeName="RazorInclusive"): cfg = Config.Config(config) x = array('d', cfg.getBinning(box)[0]) # MR binning y = array('d', cfg.getBinning(box)[1]) # Rsq binning z = array('d', cfg.getBinning(box)[2]) # nBtag binning unrollBins = None if mergeBins: btagBins = cfg.getBinning(box)[2][:-1] unrollBins = [(xbinsSignal[box][str(int(btags)) + 'B'], colsSignal[box][str(int(btags)) + 'B']) for btags in btagBins] mergeBinsString = '' if mergeBins: mergeBinsString = '--merge-bins' brString = "" if 'T1x' in model: xBR = float(model[model.find('x') + 1:model.find('y')].replace( 'p', '.')) yBR = float(model[model.find('y') + 1:].replace('p', '.')) brString = '--xBR %.2f --yBR %.2f' % (xBR, yBR) modelName = 'SMS-%s_%i_%i' % (model, mGluino, mLSP) fileName = SIGNAL_DIR + '/SMS-T1ttbb_%i_%i.root' % (mGluino, mLSP) elif 'T2' in model: modelName = 'SMS-%s_%i_%i' % (model, mStop, mLSP) fileName = SIGNAL_DIR + '/%s.root' % (modelName) else: modelName = 'SMS-%s_%i_%i' % (model, mGluino, mLSP) fileName = SIGNAL_DIR + '/%s.root' % (modelName) os.system( 'python python/SMSTemplates.py %s -c %s -d %s/ --lumi %s --box %s --no-signal-sys %s %s' % (mergeBinsString, config, outDir, lumi, box, brString, fileName)) signalFile = rt.TFile.Open( '%s/%s_lumi-%.3f_%i-%ibtag_%s.root' % (outDir, modelName, lumi * 1. / 1000., z[0], z[-1] - 1, box)) sigTH1 = signalFile.Get('%s_%s' % (box, model)) bkgdHistDict = importHists( '%s/controlHistograms%s.root' % (BACKGROUND_DIR, box.replace('ControlRegion', '').replace( 'WJet', 'WJetsSingleLepton'))) tempTH2 = bkgdHistDict['Data'][('MR', 'Rsq')] #unroll into TH1F if unrollBins is None: nBins = (len(x) - 1) * (len(y) - 1) maxBins = nBins myTH1 = rt.TH1F(treeName, treeName, maxBins, 0, maxBins) myTH1.SetDirectory(0) #prevent it from going out of scope myTH1.Sumw2() i = 0 for ix in range(1, len(x)): for iy in range(1, len(y)): i += 1 myTH1.SetBinContent(i, tempTH2.GetBinContent(ix, iy)) myTH1.SetBinError(i, tempTH2.GetBinError(ix, iy)) else: print "Merging bins according to custom (MR-dependent) binning" layers = [] #turn it into a TH2Poly with the reduced binning unrollRows = unrollBins[0][0] unrollCols = unrollBins[0][1] poly = makeTH2PolyFromColumns(tempTH2.GetName() + "poly", 'poly', unrollRows, unrollCols) fillTH2PolyFromTH2(tempTH2, poly) numbins = poly.GetNumberOfBins() unrolledSlice = rt.TH1D(tempTH2.GetName() + "Unroll", "slice", numbins, 0, numbins) for bn in range(1, numbins + 1): unrolledSlice.SetBinContent(bn, poly.GetBinContent(bn)) unrolledSlice.SetBinError(bn, poly.GetBinError(bn)) layers.append(unrolledSlice) poly.Delete() myTH1 = stitch(layers) myTH1.SetName(treeName) myTH1.SetTitle(treeName) sigTH1.Sumw2() myTH1.Sumw2() sigTH1.Divide(myTH1) return sigTH1
# Input directory baseDir = "Plots/%s" % args.tag if args.inDir is not None: baseDir = args.inDir # Fit file fitFile = razorFitFiles[args.tag][args.box] if args.fitFile is not None: fitFile = args.fitFile for btags in range(btagsMax + 1): inDir = "%s/%s%dB" % (baseDir, args.box, btags) if args.noSys: inDir += 'NoSys' inFile = "razorHistograms%s%dB.root" % (args.box, btags) if args.noSys: inFile = inFile.replace(".root", "NoSys.root") hists = macro.importHists(inDir + '/' + inFile) import2DRazorFitHistograms(hists, bins, fitFile, c, "Data", btags, btagsMax, noStat=True, force=args.force) macro.exportHists(hists, outFileName=inFile, outDir=inDir)