def findBinning(variables=variables, selection=('(1)', []), prefix=""): #take first variable var = variables[0] remainder = variables[1:] #descend the list of thresholds upperCut=-1 for t in reversed(var['thresholds']): bin = ( t, upperCut ) # print selection print prefix+"%s (cut: %s). Now Looking into %s %s."%(", ".join([s['name']+":"+str(s['cut']) for s in selection[1]]), selection[0], var['name'], repr(bin)) cut_str = cutString(var['name'], bin) cut = "&&".join([lowestCuts, preselection, selection[0], cut_str]) signalYields = {s['name']:lumiFac*getYieldFromChain(s['chain'], cut, 'weight') for s in signals} bkgYield = max(0, lumiFac*getYieldFromChain(c_bkg, cut, 'weight')) thisSelection=(selection[0]+"&&"+cut_str,selection[1]+[{'name':var['name'], 'cut': (t, upperCut)}]) #Is the region large enough? # print " "*len(prefix)+"Cut:", cut print " "*len(prefix)+"Found bkg",bkgYield, "sig.:", signalYields.values() if regionCondition(bkgYield, signalYields): #Yes -> split it with the next variable if len(remainder)>0: print prefix+"Splitting up-->" findBinning(variables=remainder, selection = thisSelection, prefix="--> "+prefix) else: print " "*len(prefix)+"Adding: "+", ".join([s['name']+":"+str(s['cut']) for s in thisSelection[1]]) regions.append({'cuts':thisSelection[1], 'sigYields':signalYields,'bkgYield':bkgYield}) upperCut = t else: #No->merge pass if not regionCondition(bkgYield, signalYields): print " "*len(prefix)+"Loop done. Adding region: "+", ".join([s['name']+":"+str(s['cut']) for s in thisSelection[1]]) regions.append({'cuts':thisSelection[1], 'sigYields':signalYields,'bkgYield':bkgYield})
def findBinning(variables=variables, selection=('(1)', []), prefix=""): #take first variable var = variables[0] remainder = variables[1:] #descend the list of thresholds upperCut = -1 for t in reversed(var['thresholds']): bin = (t, upperCut) # print selection print prefix + "%s (cut: %s). Now Looking into %s %s." % (", ".join( [s['name'] + ":" + str(s['cut']) for s in selection[1]]), selection[0], var['name'], repr(bin)) cut_str = cutString(var['name'], bin) cut = "&&".join([lowestCuts, preselection, selection[0], cut_str]) signalYields = { s['name']: lumiFac * getYieldFromChain(s['chain'], cut, 'weight') for s in signals } bkgYield = max(0, lumiFac * getYieldFromChain(c_bkg, cut, 'weight')) thisSelection = (selection[0] + "&&" + cut_str, selection[1] + [{ 'name': var['name'], 'cut': (t, upperCut) }]) #Is the region large enough? # print " "*len(prefix)+"Cut:", cut print " " * len( prefix) + "Found bkg", bkgYield, "sig.:", signalYields.values() if regionCondition(bkgYield, signalYields): #Yes -> split it with the next variable if len(remainder) > 0: print prefix + "Splitting up-->" findBinning(variables=remainder, selection=thisSelection, prefix="--> " + prefix) else: print " " * len(prefix) + "Adding: " + ", ".join([ s['name'] + ":" + str(s['cut']) for s in thisSelection[1] ]) regions.append({ 'cuts': thisSelection[1], 'sigYields': signalYields, 'bkgYield': bkgYield }) upperCut = t else: #No->merge pass if not regionCondition(bkgYield, signalYields): print " " * len(prefix) + "Loop done. Adding region: " + ", ".join( [s['name'] + ":" + str(s['cut']) for s in thisSelection[1]]) regions.append({ 'cuts': thisSelection[1], 'sigYields': signalYields, 'bkgYield': bkgYield })
def _estimate(self, region, channel, setup): printHeader("DD DY prediction for %s channel %s" %(self.name, channel)) #Sum of all channels for 'all' if channel=='all': return sum( [ self.cachedEstimate(region, c, setup) for c in ['MuMu', 'EE', 'EMu'] ], u_float(0.,0.) ) #MC based for 'EMu' elif channel=='EMu': preSelection = setup.preselection('MC', zWindow="allZ", channel=channel) cut = "&&".join([region.cutString(setup.sys['selectionModifier']), preSelection['cut'] ]) weight = preSelection['weightStr'] if setup.verbose: print "Using cut %s and weight %s"%(cut, weight) return setup.lumi[channel]/1000. * u_float( getYieldFromChain(setup.sample['DY'][channel]['chain'], cutString = cut, weight=weight, returnError = True) ) #Data driven for EE and MuMu else: preSelection = setup.preselection('MC', zWindow="offZ", channel=channel) weight = preSelection['weightStr'] assert abs(1.-setup.lumi[channel]/setup.sample['Data'][channel]['lumi'])<0.01, "Lumi specified in setup %f does not match lumi in data sample %f in channel %s"%(setup.lumi[channel], setup.sample['Data'][channel]['lumi'], channel) cut_offZ_1b = "&&".join([region.cutString(setup.sys['selectionModifier']), setup.selection('MC', channel=channel, zWindow = 'offZ', **setup.defaultParameters(update={'nBTags':(1,-1)}))['cut'] ]) cut_onZ_1b = "&&".join([region.cutString(setup.sys['selectionModifier']), setup.selection('MC', channel=channel, zWindow = 'onZ', **setup.defaultParameters(update={'nBTags':(1,-1)}))['cut'] ]) cut_onZ_0b = "&&".join([region.cutString(setup.sys['selectionModifier']), setup.selection('MC', channel=channel, zWindow = 'onZ', **setup.defaultParameters(update={'nBTags':(0,0)}))['cut'] ]) cut_data_onZ_0b = "&&".join([region.cutString(setup.sys['selectionModifier']), setup.selection('Data', channel=channel, zWindow = 'onZ', **setup.defaultParameters(update={'nBTags':(0,0)}) )['cut'] ]) # R1 = DY-MC (offZ, 1b) / DY-MC (onZ, 1b) # R2 = DY-MC (onZ, 1b) / DY-MC (onZ, 0b) # DY-est = R1*R2*(Data(2l, onZ, 0b) - EWK(onZ, 0b)) = DY-MC (offZ, 1b) / DY-MC (onZ, 0b) *( Data(2l, onZ, 0b) - EWK(onZ, 0b)) yield_offZ_1b = setup.lumi[channel]/1000.*u_float( getYieldFromChain(setup.sample['DY'][channel]['chain'], cutString = cut_offZ_1b, weight=weight, returnError = True)) if setup.verbose: print "yield_offZ_1b: %s"%yield_offZ_1b yield_onZ_0b = setup.lumi[channel]/1000.*u_float( getYieldFromChain(setup.sample['DY'][channel]['chain'], cutString = cut_onZ_0b, weight=weight, returnError = True)) if setup.verbose: print "yield_onZ_0b: %s"%yield_onZ_0b yield_data = u_float( getYieldFromChain(setup.sample['Data'][channel]['chain'], cutString = cut_data_onZ_0b, weight=weight, returnError = True)) if setup.verbose: print "yield_data: %s (for cut: %s \n with weight: %s)"%(yield_data, cut_data_onZ_0b, weight) #electroweak subtraction print "\n Substracting electroweak backgrounds from data: \n" yield_other = u_float(0., 0.) for s in ['TTJets' , 'TTZ' , 'other']: yield_other += setup.lumi[channel]/1000.*u_float(getYieldFromChain(setup.sample[s][channel]['chain'], cutString = cut_onZ_0b, weight=weight, returnError=True)) if setup.verbose: print "yield_other_onZ_0b %s added, now: %s"%(s, yield_other) normRegYield = yield_data - yield_other if normRegYield.val<0: print "\n !!!Warning!!! \n Negative normalization region yield data: (%s), MC: (%s) \n"%(yield_data, yield_other) mcRatio = yield_offZ_1b / yield_onZ_0b res = mcRatio * normRegYield print "mcRatio is: ", mcRatio return res
def _estimate(self, region, channel, setup): if setup.verbose: printHeader("MC prediction for %s channel %s" % (self.name, channel)) if channel == 'all': return sum([ self.cachedEstimate(region, c, setup) for c in ['MuMu', 'EE', 'EMu'] ], u_float(0., 0.)) else: preSelection = setup.preselection('MC', channel=channel) cut = "&&".join([ region.cutString(setup.sys['selectionModifier']), preSelection['cut'] ]) weight = preSelection['weightStr'] if setup.verbose: print "Using cut %s and weight %s" % (cut, weight) if not self.sample[channel].has_key('chain'): loadChain(self.sample[channel]) return setup.lumi[channel] / 1000. * u_float( getYieldFromChain(self.sample[channel]['chain'], cutString=cut, weight=weight, returnError=True))
def _estimate(self, region, channel, setup): if setup.verbose: printHeader("MC prediction for %s channel %s" %(self.name, channel)) if channel=='all': return sum( [ self.cachedEstimate(region, c, setup) for c in ['MuMu', 'EE', 'EMu'] ], u_float(0., 0.) ) else: preSelection = setup.preselection('MC', channel=channel) cut = "&&".join([region.cutString(setup.sys['selectionModifier']), preSelection['cut']]) weight = preSelection['weightStr'] if setup.verbose: print "Using cut %s and weight %s"%(cut, weight) if not self.sample[channel].has_key('chain'): loadChain(self.sample[channel]) return setup.lumi[channel]/1000.*u_float(getYieldFromChain(self.sample[channel]['chain'], cutString = cut, weight=weight, returnError = True) )
("==2 leptons", "nGoodMuons+nGoodElectrons==2"), ("opposite sign","isOS==1"), ("m(ll)>20", "dl_mass>20"), ("|m(ll) - mZ|>15 for SF","( (isMuMu==1||isEE==1)&&abs(dl_mass-91.2)>=15 || isEMu==1 )"), (">=2 jets", "(Sum$(JetGood_pt>30&&abs(JetGood_eta)<2.4&&JetGood_id))>=2"), (">=1 b-tags (CSVv2)", "Sum$(JetGood_pt>30&&abs(JetGood_eta)<2.4&&JetGood_id&&JetGood_btagCSV>0.890)>=1"), ("MET>80", "met_pt>80"), ("MET/sqrt(HT)>5", "met_pt/sqrt(Sum$(JetGood_pt*(JetGood_pt>30&&abs(JetGood_eta)<2.4&&JetGood_id)))>5"), ("dPhi(JetGood_1,2|MET)>0.25", "cos(met_phi-JetGood_phi[0])<cos(0.25)&&cos(met_phi-JetGood_phi[1])<cos(0.25)"), ("MT2(ll) > 140", "dl_mt2ll>140"), # ("looseLeptonVeto", "Sum$(LepGood_pt>15&&LepGood_miniRelIso<0.4)==2"), # ("multiIso M(Mu), T(Ele)", multiIsoWPMT), # ("multiIso VT(Mu), VT(Ele)", multiIsoWPVTVT), # ("filterCut", "Flag_HBHENoiseIsoFilter&&Flag_HBHENoiseFilter&&Flag_CSCTightHaloFilter&&Flag_goodVertices&&Flag_eeBadScFilter&&Flag_EcalDeadCellTriggerPrimitiveFilter" ), # ("relIso04<0.12", relIso04sm12Cut), # ("MT2(ll) > 240", "dl_mt2ll>240"), ] lumiFac=10 print 30*" "+ "".join([ "%13s"%s.name for s in samples ] ) for i in reversed(range(len(cuts))): r=[] for s in samples: selection = "&&".join(c[1] for c in cuts[:i+1]) if selection=="":selection="(1)" y = lumiFac*getYieldFromChain(s.chain, selection, 'weight') n = getYieldFromChain(s.chain, selection, '(1)') r.append(y) print "%30s"%cuts[i][0]+ "".join([ " %12.1f"%r[j] for j in range(len(r))] )
def _estimate(self, region, channel, setup): printHeader("DD TTZ prediction for '%s' channel %s" %(self.name, channel)) #Sum of all channels for 'all' if channel=='all': return sum( [ self.cachedEstimate(region, c, channel, setup) for c in ['MuMu', 'EE', 'EMu'] ] ) else: #Data driven for EE, EMu and MuMu. preSelection = setup.preselection('MC', channel=channel) #check lumi consistency assert abs(1.-setup.lumi[channel]/setup.sample['Data'][channel]['lumi'])<0.01, "Lumi specified in setup %f does not match lumi in data sample %f in channel %s"%(setup.lumi[channel], setup.sample['Data'][channel]['lumi'], channel) selection_MC_2l = "&&".join([region.cutString(setup.sys['selectionModifier']), preSelection['cut']]) weight = preSelection['weightStr'] yield_MC_2l = setup.lumi[channel]/1000.*u_float(getYieldFromChain(setup.sample['TTZ'][channel]['chain'], cutString = selection_MC_2l, weight=weight, returnError = True) ) if setup.verbose: print "yield_MC_2l: %s"%yield_MC_2l muonSelection_loosePt = looseMuIDString(ptCut=10) electronSelection_loosePt = looseEleIDString(ptCut=10) #mu_mu_mu MuMuMuSelection = "nGoodMuons>=2" + '&&' + muonSelection_loosePt + "==3" if setup.parameters['useTriggers']: MuMuMuSelection += '&&HLT_3mu' #e_e_e EEESelection = "nGoodElectrons>=2" + '&&' + electronSelection_loosePt + "==3" if setup.parameters['useTriggers']: EEESelection += '&&HLT_3e' #e_e_mu EEMuSelection = "(nGoodMuons+nGoodElectrons)>=2" + "&&" + electronSelection_loosePt + "==2&&" + muonSelection_loosePt + "==1" if setup.parameters['useTriggers']: EEMuSelection += '&&HLT_2e1mu' #mu_mu_e MuMuESelection = "(nGoodMuons+nGoodElectrons)>=2" + "&&" + electronSelection_loosePt + "==1&&" + muonSelection_loosePt + "==2" if setup.parameters['useTriggers']: MuMuESelection += '&&HLT_2mu1e' MC_hadronSelection = setup.selection('MC', hadronicSelection = True, **setup.defaultParameters(update={'nJets': self.nJets, 'nBTags':self.nMediumBTags, 'metMin': 0., 'metSigMin':0., 'dPhiJetMet':0. }) )['cut'] data_hadronSelection = setup.selection('Data', hadronicSelection = True, **setup.defaultParameters(update={'nJets': self.nJets, 'nBTags':self.nMediumBTags, 'metMin': 0., 'metSigMin':0., 'dPhiJetMet':0. }) )['cut'] #loose bjet selection added here if self.nLooseBTags[0]>=0: MC_hadronSelection += '&&Sum$(Jet_pt>30&&abs(Jet_eta)<2.4&&Jet_id&&Jet_btagCSV>0.605)>='+str(self.nLooseBTags[0]) data_hadronSelection += '&&Sum$(Jet_pt>30&&abs(Jet_eta)<2.4&&Jet_id&&Jet_btagCSV>0.605)>='+str(self.nLooseBTags[0]) if self.nLooseBTags[1]>=0: MC_hadronSelection += '&&Sum$(Jet_pt>30&&abs(Jet_eta)<2.4&&Jet_id&&Jet_btagCSV>0.605)<='+str(self.nLooseBTags[1]) data_hadronSelection += '&&Sum$(Jet_pt>30&&abs(Jet_eta)<2.4&&Jet_id&&Jet_btagCSV>0.605)<='+str(self.nLooseBTags[1]) MC_MuMuMu = "&&".join([ MC_hadronSelection, MuMuMuSelection, "abs(mlmZ_mass-91.2)<10" ]) MC_EEE = "&&".join([ MC_hadronSelection, EEESelection, "abs(mlmZ_mass-91.2)<10" ]) MC_EEMu = "&&".join([ MC_hadronSelection, EEMuSelection, "abs(mlmZ_mass-91.2)<10" ]) MC_MuMuE = "&&".join([ MC_hadronSelection, MuMuESelection, "abs(mlmZ_mass-91.2)<10" ]) MC_3l = "(("+MC_MuMuMu+")||("+MC_EEE+")||("+MC_EEMu+")||("+MC_MuMuE+"))" data_MuMuMu = "&&".join([ data_hadronSelection, MuMuMuSelection, "abs(mlmZ_mass-91.2)<10" ]) data_EEE = "&&".join([ data_hadronSelection, EEESelection, "abs(mlmZ_mass-91.2)<10" ]) data_EEMu = "&&".join([ data_hadronSelection, EEMuSelection, "abs(mlmZ_mass-91.2)<10" ]) data_MuMuE = "&&".join([ data_hadronSelection, MuMuESelection, "abs(mlmZ_mass-91.2)<10" ]) ######yield_MC_3l computed for ALL channels but lumi changes slightly here depending on channel yield_MC_3l = setup.lumi[channel]/1000.*u_float( getYieldFromChain(setup.sample['TTZ'][channel]['chain'], cutString = MC_3l, weight=weight, returnError = True)) if setup.verbose: print "yield_MC_looseSelection_3l: %s"%yield_MC_3l yield_data_MuMuMu = u_float( getYieldFromChain(setup.sample['Data']['MuMu']['chain'], cutString = data_MuMuMu, weight=weight, returnError = True)) if setup.verbose: print "yield_data_looseSelection_MuMuMu: %s"%yield_data_MuMuMu yield_data_EEE = u_float( getYieldFromChain(setup.sample['Data']['EE']['chain'], cutString = data_EEE, weight=weight, returnError = True)) if setup.verbose: print "yield_data_looseSelection_EEE: %s"%yield_data_EEE yield_data_EMu = u_float( getYieldFromChain(setup.sample['Data']['EMu']['chain'], cutString = "(("+data_MuMuE+')||('+data_EEMu+'))', weight=weight, returnError = True)) if setup.verbose: print "yield_data_looseSelection_EMu: %s"%yield_data_EMu yield_data_3l = yield_data_MuMuMu+yield_data_EEE+yield_data_EMu if setup.verbose: print "yield_data_3l: %s"%yield_data_3l #electroweak subtraction print "\n Substracting electroweak backgrounds from data: \n" yield_other = u_float(0., 0.) for s in ['TTJets' , 'DY', 'other']: yield_other+= setup.lumi[channel]/1000.* u_float(getYieldFromChain(setup.sample[s][channel]['chain'], cutString = MC_3l, weight=weight, returnError=True)) if setup.verbose: print "yield_looseSelection_other %s added, now: %s"%(s, yield_other) normRegYield = yield_data_3l - yield_other if normRegYield.val<0: print "\n !!!Warning!!! \n Negative normalization region yield data: (%s), MC: (%s) \n"%(yield_data_3l, yield_other) print "normRegYield", normRegYield print "\n Control Region predictys ", normRegYield, " TTZ events in data; ", yield_MC_3l, " TTZ events in MC. Ratio ---> ", (normRegYield/yield_MC_3l) print "DD-TTZ ---> ", (normRegYield/yield_MC_3l)*yield_MC_2l return (normRegYield/yield_MC_3l)*yield_MC_2l
), ("MET>80", "met_pt>80"), ("MET/sqrt(HT)>5", "met_pt/sqrt(Sum$(JetGood_pt*(JetGood_pt>30&&abs(JetGood_eta)<2.4&&JetGood_id)))>5" ), ("dPhi(JetGood_1,2|MET)>0.25", "cos(met_phi-JetGood_phi[0])<cos(0.25)&&cos(met_phi-JetGood_phi[1])<cos(0.25)" ), ("MT2(ll) > 140", "dl_mt2ll>140"), # ("looseLeptonVeto", "Sum$(LepGood_pt>15&&LepGood_miniRelIso<0.4)==2"), # ("multiIso M(Mu), T(Ele)", multiIsoWPMT), # ("multiIso VT(Mu), VT(Ele)", multiIsoWPVTVT), # ("filterCut", "Flag_HBHENoiseIsoFilter&&Flag_HBHENoiseFilter&&Flag_CSCTightHaloFilter&&Flag_goodVertices&&Flag_eeBadScFilter&&Flag_EcalDeadCellTriggerPrimitiveFilter" ), # ("relIso04<0.12", relIso04sm12Cut), # ("MT2(ll) > 240", "dl_mt2ll>240"), ] lumiFac = 10 print 30 * " " + "".join(["%13s" % s.name for s in samples]) for i in reversed(range(len(cuts))): r = [] for s in samples: selection = "&&".join(c[1] for c in cuts[:i + 1]) if selection == "": selection = "(1)" y = lumiFac * getYieldFromChain(s.chain, selection, 'weight') n = getYieldFromChain(s.chain, selection, '(1)') r.append(y) print "%30s" % cuts[i][0] + "".join( [" %12.1f" % r[j] for j in range(len(r))])
'3l':{\ 'dl_mt2ll':{'title':'MT2ll (GeV)', 'name':'MT2ll_3l', 'binning': mt2llbinning, 'histo':{'totalbkg':0.,}}, 'dl_mass':{'title':'M_{ll} (GeV)', 'name':'Mll_3l', 'binning': mllbinning, 'histo':{'totalbkg':0.,}}, 'met_pt':{'title':'MET (GeV)', 'name':'MET_3l', 'binning': metbinning, 'histo':{'totalbkg':0.,}}, 'LepGood_pt[0]':{'title':'l1 p_{T} (GeV)', 'name':'l1pt_3l', 'binning': lepbinning, 'histo':{'totalbkg':0.,}}, 'LepGood_pt[1]':{'title':'l2 p_{T} (GeV)', 'name':'l2pt_3l', 'binning': lepbinning, 'histo':{'totalbkg':0.,}}, 'LepGood_pt[2]':{'title':'l3 p_{T} (GeV)', 'name':'l3pt_3l', 'binning': lepbinning, 'histo':{'totalbkg':0.,}}, }, } weight = str(luminosity / 1000.) + '*weightPU' #+'*reweightTopPt' MuMuMudatayield = getYieldFromChain( getChain(data[0], histname=""), cutString="&&".join([preselection, datacut, presel_flavour_MuMuMu]), weight="1.") EEEdatayield = getYieldFromChain( getChain(data[1], histname=""), cutString="&&".join([preselection, datacut, presel_flavour_EEE]), weight="1.") MuMuEdatayield = getYieldFromChain( getChain(data[2], histname=""), cutString="&&".join([preselection, datacut, presel_flavour_MuMuE]), weight="1.") EEMudatayield = getYieldFromChain( getChain(data[2], histname=""), cutString="&&".join([preselection, datacut, presel_flavour_EEMu]), weight="1.") datayield = MuMuMudatayield + EEEdatayield + MuMuEdatayield + EEMudatayield
if os.path.exists(outDir) and options.overwrite: #not options.update: print "Directory %s exists. Delete it."%outDir shutil.rmtree(outDir) if not os.path.exists(outDir): os.makedirs(outDir) if not os.path.exists(tmpDir): os.makedirs(tmpDir) if options.signal: signalDir = os.path.join(options.targetDir, options.skim, "T2tt") if not os.path.exists(signalDir): os.makedirs(signalDir) if doTopPtReweighting: print "Computing top pt average weight...", c = ROOT.TChain("tree") for chunk in chunks: c.Add(chunk['file']) # print getTopPtDrawString() topScaleF = getYieldFromChain(c, cutString = "(1)", weight=getTopPtDrawString()) topScaleF/=c.GetEntries() c.IsA().Destructor(c) del c print "found a top pt average correction factor of %f"%topScaleF if options.signal: from StopsDilepton.tools.xSecSusy import xSecSusy xSecSusy_ = xSecSusy() channel='stop13TeV' signalWeight={} c = ROOT.TChain("tree") for chunk in chunks: c.Add(chunk['file']) print "Fetching signal weights..." mMax = 1500 bStr = str(mMax)+','+str(mMax)
def _estimate(self, region, channel, setup): printHeader("DD DY prediction for %s channel %s" % (self.name, channel)) #Sum of all channels for 'all' if channel == 'all': return sum([ self.cachedEstimate(region, c, setup) for c in ['MuMu', 'EE', 'EMu'] ], u_float(0., 0.)) #MC based for 'EMu' elif channel == 'EMu': preSelection = setup.preselection('MC', zWindow="allZ", channel=channel) cut = "&&".join([ region.cutString(setup.sys['selectionModifier']), preSelection['cut'] ]) weight = preSelection['weightStr'] if setup.verbose: print "Using cut %s and weight %s" % (cut, weight) return setup.lumi[channel] / 1000. * u_float( getYieldFromChain(setup.sample['DY'][channel]['chain'], cutString=cut, weight=weight, returnError=True)) #Data driven for EE and MuMu else: preSelection = setup.preselection('MC', zWindow="offZ", channel=channel) weight = preSelection['weightStr'] assert abs( 1. - setup.lumi[channel] / setup.sample['Data'][channel]['lumi'] ) < 0.01, "Lumi specified in setup %f does not match lumi in data sample %f in channel %s" % ( setup.lumi[channel], setup.sample['Data'][channel]['lumi'], channel) cut_offZ_1b = "&&".join([ region.cutString(setup.sys['selectionModifier']), setup.selection( 'MC', channel=channel, zWindow='offZ', **setup.defaultParameters(update={'nBTags': (1, -1)}))['cut'] ]) cut_onZ_1b = "&&".join([ region.cutString(setup.sys['selectionModifier']), setup.selection( 'MC', channel=channel, zWindow='onZ', **setup.defaultParameters(update={'nBTags': (1, -1)}))['cut'] ]) cut_onZ_0b = "&&".join([ region.cutString(setup.sys['selectionModifier']), setup.selection( 'MC', channel=channel, zWindow='onZ', **setup.defaultParameters(update={'nBTags': (0, 0)}))['cut'] ]) cut_data_onZ_0b = "&&".join([ region.cutString(setup.sys['selectionModifier']), setup.selection( 'Data', channel=channel, zWindow='onZ', **setup.defaultParameters(update={'nBTags': (0, 0)}))['cut'] ]) # R1 = DY-MC (offZ, 1b) / DY-MC (onZ, 1b) # R2 = DY-MC (onZ, 1b) / DY-MC (onZ, 0b) # DY-est = R1*R2*(Data(2l, onZ, 0b) - EWK(onZ, 0b)) = DY-MC (offZ, 1b) / DY-MC (onZ, 0b) *( Data(2l, onZ, 0b) - EWK(onZ, 0b)) yield_offZ_1b = setup.lumi[channel] / 1000. * u_float( getYieldFromChain(setup.sample['DY'][channel]['chain'], cutString=cut_offZ_1b, weight=weight, returnError=True)) if setup.verbose: print "yield_offZ_1b: %s" % yield_offZ_1b yield_onZ_0b = setup.lumi[channel] / 1000. * u_float( getYieldFromChain(setup.sample['DY'][channel]['chain'], cutString=cut_onZ_0b, weight=weight, returnError=True)) if setup.verbose: print "yield_onZ_0b: %s" % yield_onZ_0b yield_data = u_float( getYieldFromChain(setup.sample['Data'][channel]['chain'], cutString=cut_data_onZ_0b, weight=weight, returnError=True)) if setup.verbose: print "yield_data: %s (for cut: %s \n with weight: %s)" % ( yield_data, cut_data_onZ_0b, weight) #electroweak subtraction print "\n Substracting electroweak backgrounds from data: \n" yield_other = u_float(0., 0.) for s in ['TTJets', 'TTZ', 'other']: yield_other += setup.lumi[channel] / 1000. * u_float( getYieldFromChain(setup.sample[s][channel]['chain'], cutString=cut_onZ_0b, weight=weight, returnError=True)) if setup.verbose: print "yield_other_onZ_0b %s added, now: %s" % ( s, yield_other) normRegYield = yield_data - yield_other if normRegYield.val < 0: print "\n !!!Warning!!! \n Negative normalization region yield data: (%s), MC: (%s) \n" % ( yield_data, yield_other) mcRatio = yield_offZ_1b / yield_onZ_0b res = mcRatio * normRegYield print "mcRatio is: ", mcRatio return res
# 'LepGood_pt[2]':{'title':'l3 p_{T} (GeV)', 'name':'l3pt_2l', 'binning': lepbinning, 'histo':{'totalbkg':0.,}}, # }, '3l':{\ 'dl_mt2ll':{'title':'MT2ll (GeV)', 'name':'MT2ll_3l', 'binning': mt2llbinning, 'histo':{'totalbkg':0.,}}, 'dl_mass':{'title':'M_{ll} (GeV)', 'name':'Mll_3l', 'binning': mllbinning, 'histo':{'totalbkg':0.,}}, 'met_pt':{'title':'MET (GeV)', 'name':'MET_3l', 'binning': metbinning, 'histo':{'totalbkg':0.,}}, 'LepGood_pt[0]':{'title':'l1 p_{T} (GeV)', 'name':'l1pt_3l', 'binning': lepbinning, 'histo':{'totalbkg':0.,}}, 'LepGood_pt[1]':{'title':'l2 p_{T} (GeV)', 'name':'l2pt_3l', 'binning': lepbinning, 'histo':{'totalbkg':0.,}}, 'LepGood_pt[2]':{'title':'l3 p_{T} (GeV)', 'name':'l3pt_3l', 'binning': lepbinning, 'histo':{'totalbkg':0.,}}, }, } weight = str(luminosity/1000.)+'*weightPU'#+'*reweightTopPt' MuMuMudatayield = getYieldFromChain(getChain(data[0],histname=""), cutString = "&&".join([preselection, datacut, presel_flavour_MuMuMu]), weight="1.") EEEdatayield = getYieldFromChain(getChain(data[1],histname=""), cutString = "&&".join([preselection, datacut, presel_flavour_EEE]), weight="1.") MuMuEdatayield = getYieldFromChain(getChain(data[2],histname=""), cutString = "&&".join([preselection, datacut, presel_flavour_MuMuE]), weight="1.") EEMudatayield = getYieldFromChain(getChain(data[2],histname=""), cutString = "&&".join([preselection, datacut, presel_flavour_EEMu]), weight="1.") datayield = MuMuMudatayield+EEEdatayield+MuMuEdatayield+EEMudatayield bkgyield = 0. for s in backgrounds: bkgyield_temp = getYieldFromChain(getChain(s,histname=""), cutString = '&&'.join([preselection,"(("+presel_flavour_MuMuMu+")||("+presel_flavour_EEE+")||("+presel_flavour_EEMu+")||("+presel_flavour_MuMuE+"))"]), weight=weight) bkgyield+= bkgyield_temp print s['name'], ": ", bkgyield_temp print "datayield: ", datayield, " , bkgyield: ", bkgyield print "MuMuMu", MuMuMudatayield
print '\n', "Looping over %s" % s["name"] #for MC weight = str(luminosity/1000.)+'*weightPU'+'*reweightTopPt' for cut in piechart.keys(): for flavor in piechart[cut].keys(): if flavor == "EE": flavourcut = 'isEE==1&&nGoodElectrons==2&&nGoodMuons==0&&HLT_ee_DZ' elif flavor == "EMu": flavourcut = 'isEMu==1&&nGoodElectrons==1&&nGoodMuons==1&&HLT_mue' elif flavor == "MuMu": flavourcut = 'isMuMu==1&&nGoodElectrons==0&&nGoodMuons==2&&HLT_mumuIso' yield_ = getYieldFromChain(getChain(s,histname=""), cutString = '&&'.join([preselection,flavourcut]),weight=weight) yield_0j_0bj = getYieldFromChain(getChain(s,histname=""), cutString = '&&'.join([preselection,"nGoodJets==0","nBTags==0","dl_mt2ll>="+cut,flavourcut]),weight=weight) yield_1j_0bj = getYieldFromChain(getChain(s,histname=""), cutString = '&&'.join([preselection,"nGoodJets==1","nBTags==0","dl_mt2ll>="+cut,flavourcut]),weight=weight) yield_1j_1bj = getYieldFromChain(getChain(s,histname=""), cutString = '&&'.join([preselection,"nGoodJets==1","nBTags==1","dl_mt2ll>="+cut,flavourcut]),weight=weight) yield_2mj_0bj = getYieldFromChain(getChain(s,histname=""), cutString = '&&'.join([preselection,"nGoodJets>=2","nBTags==0","dl_mt2ll>="+cut,flavourcut]),weight=weight) yield_2mj_1mbj = getYieldFromChain(getChain(s,histname=""), cutString = '&&'.join([preselection,"nGoodJets>=2","nBTags>=1","dl_mt2ll>="+cut,flavourcut]),weight=weight) piechart[cut][flavor]["(0,0)"][s["name"]] == yield_0j_0bj piechart[cut][flavor]["(1,0)"][s["name"]] == yield_1j_0bj piechart[cut][flavor]["(1,1)"][s["name"]] == yield_1j_1bj piechart[cut][flavor]["(>=2,0)"][s["name"]] == yield_2mj_0bj piechart[cut][flavor]["(>=2,>=1)"][s["name"]] == yield_2mj_1mbj print piechart
}, 'met':{\ '_onZ_0b': {'title':'MET (GeV)', 'name':'MET_onZ_b==0b', "legend":"(onZ,0 b-tag)",'binning': mllbinning, 'histo':{}}, '_offZ_0b': {'title':'MET (GeV)', 'name':'MET_offZ_b==0b', "legend":"(offZ,0 b-tag)", 'binning': mllbinning, 'histo':{}}, '_onZ_1mb': {'title':'MET (GeV)', 'name':'MET_onZ_b>=1', "legend":"(onZ,>0 b-tag)", 'binning': mllbinning, 'histo':{}}, '_offZ_1mb': {'title':'MET (GeV)', 'name':'MET_offZ_b>=1', "legend":"(offZ,>0 b-tag)", 'binning': mllbinning, 'histo':{}}, }, } ####################################################### # Start filling in the histograms # ####################################################### weight = str(luminosity/1000.)+'*weight'#+'*reweightTopPt' datayield_onZ_0b = getYieldFromChain(getChain(data[0],histname=""), cutString = "&&".join([preselection, datacut,'abs(dl_mass-91.2)<=15&&nBTags==0']), weight="1.") bkgyield_onZ_0b = 0. print "&&".join([preselection,'abs(dl_mass-91.2)<=15&&nBTags==0']) for s in backgrounds: bkgyield_onZ_0b_tmp = getYieldFromChain(getChain(s,histname=""), "&&".join([preselection,'abs(dl_mass-91.2)<=15&&nBTags==0']), weight=weight) bkgyield_onZ_0b += bkgyield_onZ_0b_tmp print s['name'], ": ", bkgyield_onZ_0b_tmp datayield_offZ_0b = getYieldFromChain(getChain(data[0],histname=""), cutString = "&&".join([preselection, datacut,'abs(dl_mass-91.2)>15&&nBTags==0']), weight="1.") bkgyield_offZ_0b = 0. for s in backgrounds: bkgyield_offZ_0b+= getYieldFromChain(getChain(s,histname=""), "&&".join([preselection,'abs(dl_mass-91.2)>15&&nBTags==0']), weight=weight)
def _estimate(self, region, channel, setup): #Sum of all channels for 'all' if channel == 'all': return sum([ self.cachedEstimate(region, c, channel, setup) for c in ['MuMu', 'EE', 'EMu'] ]) else: #Data driven for EE, EMu and MuMu. zWindow = 'allZ' if channel == 'EMu' else 'offZ' preSelection = setup.preselection('MC', zWindow=zWindow, channel=channel) #check lumi consistency assert abs( 1. - setup.lumi[channel] / setup.sample['Data'][channel]['lumi'] ) < 0.01, "Lumi specified in setup %f does not match lumi in data sample %f in channel %s" % ( setup.lumi[channel], setup.sample['Data'][channel]['lumi'], channel) MC_2l = "&&".join([ region.cutString(setup.sys['selectionModifier']), preSelection['cut'] ]) weight = preSelection['weightStr'] logger.debug("weight: %s", weight) yield_MC_2l = setup.lumi[channel] / 1000. * u_float( getYieldFromChain(setup.sample['TTZ'][channel]['chain'], cutString=selection_MC_2l, weight=weight, returnError=True)) if setup.verbose: print "yield_MC_2l: %s" % yield_MC_2l # pt leptons > 30, 20, 10 GeV useTrigger = False # setup.parameters['useTriggers'] # better not to use three lepton triggers, seems to be too inefficient mumumuSelection = "&&".join([ getLeptonString(3, 0), getPtThresholdString(30, 20, 10) ]) + ("&&HLT_3mu" if useTrigger else "") mumueSelection = "&&".join([ getLeptonString(2, 1), getPtThresholdString(30, 20, 10) ]) + ("&&HLT_2mu1e" if useTrigger else "") mueeSelection = "&&".join([ getLeptonString(1, 2), getPtThresholdString(30, 20, 10) ]) + ("&&HLT_2e1mu" if useTrigger else "") eeeSelection = "&&".join([ getLeptonString(0, 3), getPtThresholdString(30, 20, 10) ]) + ("&&HLT_3e" if useTrigger else "") lllSelection = "((" + ")||(".join([ mumumuSelection, mumueSelection, mueeSelection, eeeSelection ]) + "))" bJetSelectionM = "(Sum$(JetGood_pt>30&&abs(JetGood_eta)<2.4&&JetGood_id&&JetGood_btagCSV>0.890))" bJetSelectionL = "(Sum$(JetGood_pt>30&&abs(JetGood_eta)<2.4&&JetGood_id&&JetGood_btagCSV>0.605))" zMassSelection = "abs(mlmZ_mass-91.1876)<10" # Start from base hadronic selection and add loose b-tag and Z-mass requirement selection = {} for dataOrMC in ["Data", "MC"]: selection[dataOrMC] = setup.selection( dataOrMC, hadronicSelection=True, **setup.defaultParameters( update={ 'nJets': self.nJets, 'nBTags': self.nMediumBTags, 'metMin': 0., 'metSigMin': 0., 'dPhiJetMet': 0. }))['cut'] selection[dataOrMC] += bJetSelectionL + ">=" + str( self.nLooseBTags[0]) selection[dataOrMC] += zMassSelection MC_3l = lllSelection + "&&" + selection["MC"] data_mumumu = mumumuSelection + "&&" + selection["Data"] data_mumue = mumueSelection + "&&" + selection["Data"] data_muee = mueeSelection + "&&" + selection["Data"] data_eee = eeeSelection + "&&" + selection["Data"] # Calculate yields (take together) yield_ttZ_2l = setup.lumi[channel] / 1000. * u_float( getYieldFromChain(setup.sample['TTZ'][channel]['chain'], cutString=MC_2l, weight=weight, returnError=True)) yield_ttZ_3l = setup.lumi[channel] / 1000. * u_float( getYieldFromChain(setup.sample['TTZ'][channel]['chain'], cutString=MC_3l, weight=weight, returnError=True)) yield_data_mumumu = u_float( getYieldFromChain(setup.sample['Data']['MuMu']['chain'], cutString=data_mumumu, weight=weight, returnError=True)) yield_data_eee = u_float( getYieldFromChain(setup.sample['Data']['EE']['chain'], cutString=data_eee, weight=weight, returnError=True)) yield_data_mue = u_float( getYieldFromChain(setup.sample['Data']['EMu']['chain'], cutString="((" + data_mumue + ')||(' + data_muee + '))', weight=weight, returnError=True)) yield_data_3l = yield_data_mumumu + yield_data_mue + yield_data_eee #electroweak subtraction yield_other = u_float(0., 0.) for s in ['TTJets', 'DY', 'other']: yield_other += setup.lumi[channel] / 1000. * u_float( getYieldFromChain(setup.sample[s][channel]['chain'], cutString=MC_3l, weight=weight, returnError=True)) yield_ttZ_data = yield_data_3l - yield_other if normRegYield.val < 0: logger.warn("Data-driven estimate is negative!") logger.info("Control region predictions: ") logger.info(" data: " + str(yield_data_3l)) logger.info(" MC other: " + str(yield_other)) logger.info(" TTZ (MC): " + str(yield_ttZ_3l)) logger.info(" TTZ (data): " + str(yield_ttZ_data)) logger.info(" TTZ (ratio): " + str(yield_ttZ_data / yield_ttZ_3l)) return (yield_ttZ_data / yield_ttZ_3l) * yield_MC_2l
QCDSample = QCD_Mu5 if opts.mode=="doubleEle": cutString = "&&".join(["isEE==1&&nGoodMuons==0&&nGoodElectrons==2", triggerEleEle, getZCut(opts.zMode)] + preselCuts) dataCut = "&&".join([filterCut]) dataSample = DoubleEG_Run2015D QCDSample = QCD_EMbcToE if opts.mode=="muEle": cutString = "&&".join(["isEMu==1&&nGoodMuons==1&&nGoodElectrons==1",triggerMuEle, getZCut(opts.zMode)] + preselCuts) dataCut = "&&".join([filterCut]) dataSample = MuonEG_Run2015D QCDSample = QCD_Mu5EMbcToE cutFunc = None lumiScaleFac = dataSample["lumi"]/1000. backgrounds = [TTJets, WJetsToLNu, DY, singleTop, QCDSample, TTX, diBoson] data = getYieldFromChain(getChain(dataSample,histname="",maxN=maxN), cutString = "&&".join([cutString, dataCut]), weight='weight') bkg = 0. for s in backgrounds: bkg+= getYieldFromChain(getChain(s,histname="", maxN=maxN), cutString, weight='weight') scaleFac = data/(bkg*lumiScaleFac) print "After lumiscale %3.3f there is bkg %7.1f and data %7.1f: re-normalizing scaleFac by %3.3f"%(lumiScaleFac, lumiScaleFac*bkg, data, scaleFac) ratioOps = {'yLabel':'Data/MC', 'numIndex':1, 'denIndex':0 ,'yRange':None, 'logY':False, 'color':ROOT.kBlack, 'yRange':(0.1, 2.1)} #ratioOps = None def getStack(labels, var, binning, cut, options={}): style_Data = {'legendText':dataSample['name'], 'style':"e", 'lineThickness':0, 'errorBars':True, 'color':ROOT.kBlack, 'markerStyle':20, 'markerSize':1} style_WJets = {'legendText':'W + Jets', 'style':"f", 'lineThickness':0, 'errorBars':False, 'color':42, 'markerStyle':None, 'markerSize':None}
'dl_mass':{\ '_onZ_0b': {'title':'m_{ll} (GeV)', 'name':'Mll_onZ_b==0b', "legend":"(onZ,0 b-tag)",'binning': mllbinning, 'histo':{}}, '_offZ_0b': {'title':'m_{ll} (GeV)', 'name':'Mll_offZ_b==0b', "legend":"(offZ,0 b-tag)", 'binning': mllbinning, 'histo':{}}, '_onZ_1mb': {'title':'m_{ll} (GeV)', 'name':'Mll_onZ_b>=1', "legend":"(onZ,>0 b-tag)", 'binning': mllbinning, 'histo':{}}, '_offZ_1mb': {'title':'m_{ll} (GeV)', 'name':'Mll_offZ_b>=1', "legend":"(offZ,>0 b-tag)", 'binning': mllbinning, 'histo':{}}, }, } ####################################################### # Start filling in the histograms # ####################################################### weight = str(luminosity / 1000.) + '*weightPU' + '*reweightTopPt' datayield_onZ_0b = getYieldFromChain(getChain(data[0], histname=""), cutString="&&".join([ preselection, datacut, 'abs(dl_mass-91.2)<=15&&nBTags==0' ]), weight="1.") bkgyield_onZ_0b = 0. for s in backgrounds: bkgyield_onZ_0b += getYieldFromChain( getChain(s, histname=""), "&&".join([preselection, 'abs(dl_mass-91.2)<=15&&nBTags==0']), weight=weight) datayield_offZ_0b = getYieldFromChain(getChain(data[0], histname=""), cutString="&&".join([ preselection, datacut, 'abs(dl_mass-91.2)>15&&nBTags==0' ]), weight="1.")
def _estimate(self, region, channel, setup): printHeader("DD TTZ prediction for '%s' channel %s" % (self.name, channel)) #Sum of all channels for 'all' if channel == 'all': return sum([ self.cachedEstimate(region, c, channel, setup) for c in ['MuMu', 'EE', 'EMu'] ]) else: #Data driven for EE, EMu and MuMu. preSelection = setup.preselection('MC', channel=channel) #check lumi consistency assert abs( 1. - setup.lumi[channel] / setup.sample['Data'][channel]['lumi'] ) < 0.01, "Lumi specified in setup %f does not match lumi in data sample %f in channel %s" % ( setup.lumi[channel], setup.sample['Data'][channel]['lumi'], channel) selection_MC_2l = "&&".join([ region.cutString(setup.sys['selectionModifier']), preSelection['cut'] ]) weight = preSelection['weightStr'] yield_MC_2l = setup.lumi[channel] / 1000. * u_float( getYieldFromChain(setup.sample['TTZ'][channel]['chain'], cutString=selection_MC_2l, weight=weight, returnError=True)) if setup.verbose: print "yield_MC_2l: %s" % yield_MC_2l muonSelection_loosePt = looseMuIDString(ptCut=10) electronSelection_loosePt = looseEleIDString(ptCut=10) #mu_mu_mu MuMuMuSelection = "nGoodMuons>=2" + '&&' + muonSelection_loosePt + "==3" if setup.parameters['useTriggers']: MuMuMuSelection += '&&HLT_3mu' #e_e_e EEESelection = "nGoodElectrons>=2" + '&&' + electronSelection_loosePt + "==3" if setup.parameters['useTriggers']: EEESelection += '&&HLT_3e' #e_e_mu EEMuSelection = "(nGoodMuons+nGoodElectrons)>=2" + "&&" + electronSelection_loosePt + "==2&&" + muonSelection_loosePt + "==1" if setup.parameters['useTriggers']: EEMuSelection += '&&HLT_2e1mu' #mu_mu_e MuMuESelection = "(nGoodMuons+nGoodElectrons)>=2" + "&&" + electronSelection_loosePt + "==1&&" + muonSelection_loosePt + "==2" if setup.parameters['useTriggers']: MuMuESelection += '&&HLT_2mu1e' MC_hadronSelection = setup.selection( 'MC', hadronicSelection=True, **setup.defaultParameters( update={ 'nJets': self.nJets, 'nBTags': self.nMediumBTags, 'metMin': 0., 'metSigMin': 0., 'dPhiJetMet': 0. }))['cut'] data_hadronSelection = setup.selection( 'Data', hadronicSelection=True, **setup.defaultParameters( update={ 'nJets': self.nJets, 'nBTags': self.nMediumBTags, 'metMin': 0., 'metSigMin': 0., 'dPhiJetMet': 0. }))['cut'] #loose bjet selection added here if self.nLooseBTags[0] >= 0: MC_hadronSelection += '&&Sum$(Jet_pt>30&&abs(Jet_eta)<2.4&&Jet_id&&Jet_btagCSV>0.605)>=' + str( self.nLooseBTags[0]) data_hadronSelection += '&&Sum$(Jet_pt>30&&abs(Jet_eta)<2.4&&Jet_id&&Jet_btagCSV>0.605)>=' + str( self.nLooseBTags[0]) if self.nLooseBTags[1] >= 0: MC_hadronSelection += '&&Sum$(Jet_pt>30&&abs(Jet_eta)<2.4&&Jet_id&&Jet_btagCSV>0.605)<=' + str( self.nLooseBTags[1]) data_hadronSelection += '&&Sum$(Jet_pt>30&&abs(Jet_eta)<2.4&&Jet_id&&Jet_btagCSV>0.605)<=' + str( self.nLooseBTags[1]) MC_MuMuMu = "&&".join([ MC_hadronSelection, MuMuMuSelection, "abs(mlmZ_mass-91.2)<10" ]) MC_EEE = "&&".join( [MC_hadronSelection, EEESelection, "abs(mlmZ_mass-91.2)<10"]) MC_EEMu = "&&".join( [MC_hadronSelection, EEMuSelection, "abs(mlmZ_mass-91.2)<10"]) MC_MuMuE = "&&".join( [MC_hadronSelection, MuMuESelection, "abs(mlmZ_mass-91.2)<10"]) MC_3l = "((" + MC_MuMuMu + ")||(" + MC_EEE + ")||(" + MC_EEMu + ")||(" + MC_MuMuE + "))" data_MuMuMu = "&&".join([ data_hadronSelection, MuMuMuSelection, "abs(mlmZ_mass-91.2)<10" ]) data_EEE = "&&".join( [data_hadronSelection, EEESelection, "abs(mlmZ_mass-91.2)<10"]) data_EEMu = "&&".join([ data_hadronSelection, EEMuSelection, "abs(mlmZ_mass-91.2)<10" ]) data_MuMuE = "&&".join([ data_hadronSelection, MuMuESelection, "abs(mlmZ_mass-91.2)<10" ]) ######yield_MC_3l computed for ALL channels but lumi changes slightly here depending on channel yield_MC_3l = setup.lumi[channel] / 1000. * u_float( getYieldFromChain(setup.sample['TTZ'][channel]['chain'], cutString=MC_3l, weight=weight, returnError=True)) if setup.verbose: print "yield_MC_looseSelection_3l: %s" % yield_MC_3l yield_data_MuMuMu = u_float( getYieldFromChain(setup.sample['Data']['MuMu']['chain'], cutString=data_MuMuMu, weight=weight, returnError=True)) if setup.verbose: print "yield_data_looseSelection_MuMuMu: %s" % yield_data_MuMuMu yield_data_EEE = u_float( getYieldFromChain(setup.sample['Data']['EE']['chain'], cutString=data_EEE, weight=weight, returnError=True)) if setup.verbose: print "yield_data_looseSelection_EEE: %s" % yield_data_EEE yield_data_EMu = u_float( getYieldFromChain(setup.sample['Data']['EMu']['chain'], cutString="((" + data_MuMuE + ')||(' + data_EEMu + '))', weight=weight, returnError=True)) if setup.verbose: print "yield_data_looseSelection_EMu: %s" % yield_data_EMu yield_data_3l = yield_data_MuMuMu + yield_data_EEE + yield_data_EMu if setup.verbose: print "yield_data_3l: %s" % yield_data_3l #electroweak subtraction print "\n Substracting electroweak backgrounds from data: \n" yield_other = u_float(0., 0.) for s in ['TTJets', 'DY', 'other']: yield_other += setup.lumi[channel] / 1000. * u_float( getYieldFromChain(setup.sample[s][channel]['chain'], cutString=MC_3l, weight=weight, returnError=True)) if setup.verbose: print "yield_looseSelection_other %s added, now: %s" % ( s, yield_other) normRegYield = yield_data_3l - yield_other if normRegYield.val < 0: print "\n !!!Warning!!! \n Negative normalization region yield data: (%s), MC: (%s) \n" % ( yield_data_3l, yield_other) print "normRegYield", normRegYield print "\n Control Region predictys ", normRegYield, " TTZ events in data; ", yield_MC_3l, " TTZ events in MC. Ratio ---> ", ( normRegYield / yield_MC_3l) print "DD-TTZ ---> ", (normRegYield / yield_MC_3l) * yield_MC_2l return (normRegYield / yield_MC_3l) * yield_MC_2l
print '\n', "Looping over %s" % s["name"] #for MC weight = str(luminosity / 1000.) + '*weightPU' + '*reweightTopPt' for cut in piechart.keys(): for flavor in piechart[cut].keys(): if flavor == "EE": flavourcut = 'isEE==1&&nGoodElectrons==2&&nGoodMuons==0&&HLT_ee_DZ' elif flavor == "EMu": flavourcut = 'isEMu==1&&nGoodElectrons==1&&nGoodMuons==1&&HLT_mue' elif flavor == "MuMu": flavourcut = 'isMuMu==1&&nGoodElectrons==0&&nGoodMuons==2&&HLT_mumuIso' yield_ = getYieldFromChain(getChain(s, histname=""), cutString='&&'.join( [preselection, flavourcut]), weight=weight) yield_0j_0bj = getYieldFromChain(getChain(s, histname=""), cutString='&&'.join([ preselection, "nGoodJets==0", "nBTags==0", "dl_mt2ll>=" + cut, flavourcut ]), weight=weight) yield_1j_0bj = getYieldFromChain(getChain(s, histname=""), cutString='&&'.join([ preselection, "nGoodJets==1", "nBTags==0", "dl_mt2ll>=" + cut, flavourcut ]),
SMS_T2tt_2J_mStop650_mLSP325, SMS_T2tt_2J_mStop850_mLSP100, ] for s in samples: s["chain"] = getChain(s, histname="") cuts = [ ("lepVeto", "nGoodMuons+nGoodElectrons==2"), ("njet2", "(Sum$(Jet_pt>30&&abs(Jet_eta)<2.4&&Jet_id))>=2"), ("nbtag1", "Sum$(Jet_pt>30&&abs(Jet_eta)<2.4&&Jet_id&&Jet_btagCSV>0.890)>=1"), ("mll20", "dl_mass>20"), ("met80", "met_pt>80"), ("metSig5", "met_pt/sqrt(Sum$(Jet_pt*(Jet_pt>30&&abs(Jet_eta)<2.4&&Jet_id)))>5"), ("dPhiJet0-dPhiJet1", "cos(met_phi-Jet_phi[0])<cos(0.25)&&cos(met_phi-Jet_phi[1])<cos(0.25)"), ("isOS", "isOS==1"), ("SFZVeto", "( (isMuMu==1||isEE==1)&&abs(dl_mass-90.2)>=15 || isEMu==1 )"), ] lumiFac = 10 for s in samples: print "\nSample: %s" % s["name"] for i in range(len(cuts) + 1): selection = "&&".join(c[1] for c in cuts[:i]) if selection == "": selection = "(1)" name = "-".join(c[0] for c in cuts[:i]) y = lumiFac * getYieldFromChain(s["chain"], selection, "weight") n = getYieldFromChain(s["chain"], selection, "(1)") print "%10.3f %10i %s" % (y, n, name) # print "%10.3f %10i %s %s"%(y,n,name,selection)
print "Directory %s exists. Delete it." % outDir shutil.rmtree(outDir) if not os.path.exists(outDir): os.makedirs(outDir) if not os.path.exists(tmpDir): os.makedirs(tmpDir) if options.signal: signalDir = os.path.join(options.targetDir, options.skim, "T2tt") if not os.path.exists(signalDir): os.makedirs(signalDir) if doTopPtReweighting: print "Computing top pt average weight...", c = ROOT.TChain("tree") for chunk in chunks: c.Add(chunk['file']) # print getTopPtDrawString() topScaleF = getYieldFromChain(c, cutString="(1)", weight=getTopPtDrawString()) topScaleF /= c.GetEntries() c.IsA().Destructor(c) del c print "found a top pt average correction factor of %f" % topScaleF if options.signal: from StopsDilepton.tools.xSecSusy import xSecSusy xSecSusy_ = xSecSusy() channel = 'stop13TeV' signalWeight = {} c = ROOT.TChain("tree") for chunk in chunks: c.Add(chunk['file']) print "Fetching signal weights..." mMax = 1500
def _estimate(self, region, channel, setup): #Sum of all channels for 'all' if channel=='all': return sum( [ self.cachedEstimate(region, c, channel, setup) for c in ['MuMu', 'EE', 'EMu'] ] ) else: #Data driven for EE, EMu and MuMu. zWindow= 'allZ' if channel=='EMu' else 'offZ' preSelection = setup.preselection('MC', zWindow=zWindow, channel=channel) #check lumi consistency assert abs(1.-setup.lumi[channel]/setup.sample['Data'][channel]['lumi'])<0.01, "Lumi specified in setup %f does not match lumi in data sample %f in channel %s"%(setup.lumi[channel], setup.sample['Data'][channel]['lumi'], channel) MC_2l = "&&".join([region.cutString(setup.sys['selectionModifier']), preSelection['cut']]) weight = preSelection['weightStr'] logger.debug("weight: %s", weight) yield_MC_2l = setup.lumi[channel]/1000.*u_float(getYieldFromChain(setup.sample['TTZ'][channel]['chain'], cutString = selection_MC_2l, weight=weight, returnError = True) ) if setup.verbose: print "yield_MC_2l: %s"%yield_MC_2l # pt leptons > 30, 20, 10 GeV useTrigger = False # setup.parameters['useTriggers'] # better not to use three lepton triggers, seems to be too inefficient mumumuSelection = "&&".join([getLeptonString(3, 0), getPtThresholdString(30, 20, 10)]) + ("&&HLT_3mu" if useTrigger else "") mumueSelection = "&&".join([getLeptonString(2, 1), getPtThresholdString(30, 20, 10)]) + ("&&HLT_2mu1e" if useTrigger else "") mueeSelection = "&&".join([getLeptonString(1, 2), getPtThresholdString(30, 20, 10)]) + ("&&HLT_2e1mu" if useTrigger else "") eeeSelection = "&&".join([getLeptonString(0, 3), getPtThresholdString(30, 20, 10)]) + ("&&HLT_3e" if useTrigger else "") lllSelection = "((" + ")||(".join([mumumuSelection, mumueSelection, mueeSelection, eeeSelection]) + "))" bJetSelectionM = "(Sum$(JetGood_pt>30&&abs(JetGood_eta)<2.4&&JetGood_id&&JetGood_btagCSV>0.890))" bJetSelectionL = "(Sum$(JetGood_pt>30&&abs(JetGood_eta)<2.4&&JetGood_id&&JetGood_btagCSV>0.605))" zMassSelection = "abs(mlmZ_mass-91.1876)<10" # Start from base hadronic selection and add loose b-tag and Z-mass requirement selection = {} for dataOrMC in ["Data", "MC"]: selection[dataOrMC] = setup.selection(dataOrMC, hadronicSelection = True, **setup.defaultParameters(update={'nJets': self.nJets, 'nBTags':self.nMediumBTags, 'metMin': 0., 'metSigMin':0., 'dPhiJetMet':0. }))['cut'] selection[dataOrMC] += bJetSelectionL+">="+str(self.nLooseBTags[0]) selection[dataOrMC] += zMassSelection MC_3l = lllSelection + "&&" + selection["MC"] data_mumumu = mumumuSelection + "&&" + selection["Data"] data_mumue = mumueSelection + "&&" + selection["Data"] data_muee = mueeSelection + "&&" + selection["Data"] data_eee = eeeSelection + "&&" + selection["Data"] # Calculate yields (take together) yield_ttZ_2l = setup.lumi[channel]/1000.*u_float(getYieldFromChain(setup.sample['TTZ'][channel]['chain'], cutString = MC_2l, weight=weight, returnError = True)) yield_ttZ_3l = setup.lumi[channel]/1000.*u_float(getYieldFromChain(setup.sample['TTZ'][channel]['chain'], cutString = MC_3l, weight=weight, returnError = True)) yield_data_mumumu = u_float(getYieldFromChain(setup.sample['Data']['MuMu']['chain'], cutString = data_mumumu, weight=weight, returnError = True)) yield_data_eee = u_float(getYieldFromChain(setup.sample['Data']['EE']['chain'], cutString = data_eee, weight=weight, returnError = True)) yield_data_mue = u_float(getYieldFromChain(setup.sample['Data']['EMu']['chain'], cutString = "(("+data_mumue+')||('+data_muee+'))', weight=weight, returnError = True)) yield_data_3l = yield_data_mumumu + yield_data_mue + yield_data_eee #electroweak subtraction yield_other = u_float(0., 0.) for s in ['TTJets' , 'DY', 'other']: yield_other+= setup.lumi[channel]/1000.* u_float(getYieldFromChain(setup.sample[s][channel]['chain'], cutString = MC_3l, weight=weight, returnError=True)) yield_ttZ_data = yield_data_3l - yield_other if normRegYield.val<0: logger.warn("Data-driven estimate is negative!") logger.info("Control region predictions: ") logger.info(" data: " + str(yield_data_3l)) logger.info(" MC other: " + str(yield_other)) logger.info(" TTZ (MC): " + str(yield_ttZ_3l)) logger.info(" TTZ (data): " + str(yield_ttZ_data)) logger.info(" TTZ (ratio): " + str(yield_ttZ_data/yield_ttZ_3l)) return (yield_ttZ_data/yield_ttZ_3l)*yield_MC_2l